@@ -105,12 +105,27 @@ static IBusConfig *config = NULL;
105105static gboolean is_special_notify ;
106106static gboolean is_special_only ;
107107static gboolean is_output_simplified ;
108+ static gboolean is_use_shift ;
109+ static gboolean is_english_mode ;
110+ static gboolean is_fullwidth_mode ;
108111static gboolean is_aux_shown = FALSE;
112+ static gint prev_pressed_key = IBUS_VoidSymbol ;
109113static ArrayContext * array_context = NULL ;
110114#ifdef HAVE_OPENCC
111115static opencc_t cc_handle = NULL ;;
112116#endif
113117
118+ static char * sFullWidthTable [] = {
119+ " " , "!" , """ , "#" , "$" , "%" , "&" , "'" , "(" , ")" , "*" , "+" ,
120+ "," , "-" , "." , "/" , "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" ,
121+ "8" , "9" , ":" , ";" , "<" , "=" , ">" , "?" , "@" , "A" , "B" , "C" ,
122+ "D" , "E" , "F" , "G" , "H" , "I" , "J" , "K" , "L" , "M" , "N" , "O" ,
123+ "P" , "Q" , "R" , "S" , "T" , "U" , "V" , "W" , "X" , "Y" , "Z" , "[" ,
124+ "\" , "]" , "^" , "_" , "`" , "a" , "b" , "c" , "d" , "e" , "f" , "g" ,
125+ "h" , "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" ,
126+ "t" , "u" , "v" , "w" , "x" , "y" , "z" , "{" , "|" , "}" , "~" ,
127+ };
128+
114129GType ibus_array_engine_get_type (void ) {
115130 static GType type = 0 ;
116131
@@ -144,6 +159,9 @@ void ibus_array_init (IBusBus *bus) {
144159 is_special_notify = FALSE;
145160 is_special_only = FALSE;
146161 is_output_simplified = FALSE;
162+ is_use_shift = FALSE;
163+ is_english_mode = FALSE;
164+ is_fullwidth_mode = FALSE;
147165
148166 /* load config */
149167 GVariant * value ;
@@ -160,6 +178,18 @@ void ibus_array_init (IBusBus *bus) {
160178 if (value && g_variant_classify (value ) == G_VARIANT_CLASS_BOOLEAN )
161179 is_output_simplified = g_variant_get_boolean (value );
162180
181+ value = ibus_config_get_value (config , "engine/Array" , "UseShift" );
182+ if (value && g_variant_classify (value ) == G_VARIANT_CLASS_BOOLEAN )
183+ is_use_shift = g_variant_get_boolean (value );
184+
185+ value = ibus_config_get_value (config , "engine/Array" , "Mode" );
186+ if (value && g_variant_classify (value ) == G_VARIANT_CLASS_BOOLEAN )
187+ is_english_mode = g_variant_get_boolean (value );
188+
189+ value = ibus_config_get_value (config , "engine/Array" , "FullWidth" );
190+ if (value && g_variant_classify (value ) == G_VARIANT_CLASS_BOOLEAN )
191+ is_fullwidth_mode = g_variant_get_boolean (value );
192+
163193 /* gettext preparation */
164194 setlocale (LC_ALL , "" );
165195 bindtextdomain (PACKAGE , LOCALEDIR );
@@ -206,6 +236,14 @@ static void ibus_array_engine_class_init (IBusArrayEngineClass *klass)
206236
207237static void ibus_array_engine_init (IBusArrayEngine * arrayeng )
208238{
239+ IBusProperty * mode_prop ;
240+ IBusText * mode_label ;
241+ IBusText * mode_tooltip ;
242+
243+ IBusProperty * fullwidth_prop ;
244+ IBusText * fullwidth_label ;
245+ IBusText * fullwidth_tooltip ;
246+
209247 IBusProperty * setup_prop ;
210248 IBusText * setup_label ;
211249 IBusText * setup_tooltip ;
@@ -217,6 +255,27 @@ static void ibus_array_engine_init (IBusArrayEngine *arrayeng)
217255
218256 arrayeng -> table = ibus_lookup_table_new (10 , 0 , FALSE, TRUE);
219257 g_object_ref_sink (arrayeng -> table );
258+
259+ mode_label = is_english_mode ?
260+ ibus_text_new_from_string (_ ("English mode" )):
261+ ibus_text_new_from_string (_ ("Chinese mode" ));
262+ mode_tooltip = is_english_mode ?
263+ ibus_text_new_from_string (_ ("Switch to Chinese mode" )):
264+ ibus_text_new_from_string (_ ("Switch to English mode" ));
265+ mode_prop = ibus_property_new ("mode" , PROP_TYPE_NORMAL , mode_label ,
266+ "gtk-convert" , mode_tooltip , TRUE, TRUE, 0 , NULL );
267+ g_object_ref_sink (mode_prop );
268+
269+ fullwidth_label = is_fullwidth_mode ?
270+ ibus_text_new_from_string (_ ("Full width mode" )):
271+ ibus_text_new_from_string (_ ("Half width mode" ));
272+ fullwidth_tooltip = is_fullwidth_mode ?
273+ ibus_text_new_from_string (_ ("Switch to Half width mode" )):
274+ ibus_text_new_from_string (_ ("Switch to Full width mode" ));
275+ fullwidth_prop = ibus_property_new ("fullwidth" , PROP_TYPE_NORMAL ,fullwidth_label ,
276+ "gtk-convert" , fullwidth_tooltip , TRUE, TRUE, 0 , NULL );
277+ g_object_ref_sink (fullwidth_prop );
278+
220279 setup_label = ibus_text_new_from_string (_ ("Setup" ));
221280 setup_tooltip = ibus_text_new_from_string (_ ("Configure Array 30 engine" ));
222281 setup_prop = ibus_property_new ("setup" , PROP_TYPE_NORMAL , setup_label , "gtk-preferences" , setup_tooltip , TRUE, TRUE, 0 , NULL );
@@ -225,6 +284,8 @@ static void ibus_array_engine_init (IBusArrayEngine *arrayeng)
225284 arrayeng -> prop_list = ibus_prop_list_new ();
226285 g_object_ref_sink (arrayeng -> prop_list );
227286
287+ ibus_prop_list_append (arrayeng -> prop_list , mode_prop );
288+ ibus_prop_list_append (arrayeng -> prop_list , fullwidth_prop );
228289 ibus_prop_list_append (arrayeng -> prop_list , setup_prop );
229290
230291 g_signal_connect (config , "value-changed" , G_CALLBACK (ibus_config_value_changed_cb ), NULL );
@@ -511,15 +572,53 @@ static gboolean ibus_array_engine_process_key_event (IBusEngine *engine, guint
511572 is_aux_shown = FALSE;
512573 }
513574
514- if (modifiers & IBUS_RELEASE_MASK )
575+ if (modifiers & IBUS_RELEASE_MASK ) {
576+ gboolean triggered = FALSE;
577+
578+ /* The keyval must be the same */
579+ if (prev_pressed_key == keyval ) {
580+ if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R )
581+ triggered = TRUE;
582+ }
583+
584+ if (triggered ) {
585+ if (is_use_shift ) {
586+ ibus_array_engine_property_activate ((IBusEngine * ) engine ,
587+ "mode" ,
588+ PROP_STATE_UNCHECKED );
589+ return TRUE;
590+ }
591+ }
592+
515593 return FALSE;
594+ }
595+
596+ prev_pressed_key = keyval ;
597+
598+ if ((modifiers & IBUS_SHIFT_MASK ) && keyval == IBUS_space ) {
599+ ibus_array_engine_property_activate ((IBusEngine * ) engine ,
600+ "fullwidth" ,
601+ PROP_STATE_UNCHECKED );
602+ return TRUE;
603+ }
516604
517605 if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R )
518606 return FALSE;
519607
520608 if (modifiers & (IBUS_CONTROL_MASK | IBUS_MOD1_MASK ))
521609 return FALSE;
522610
611+ if (is_english_mode ) {
612+ if (is_fullwidth_mode ) {
613+ if (keyval >= 32 && keyval - 32 < sizeof (sFullWidthTable )) {
614+ IBusText * newtext = ibus_text_new_from_string (sFullWidthTable [keyval - 32 ]);
615+ ibus_engine_commit_text ((IBusEngine * )arrayeng , newtext );
616+ return TRUE;
617+ }
618+ }
619+
620+ return FALSE;
621+ }
523622
524623 switch (keyval ) {
525624 case IBUS_space :
@@ -619,7 +718,7 @@ static gboolean ibus_array_engine_process_key_event (IBusEngine *engine, guint
619718 if (arrayeng -> preedit -> len >= 5 )
620719 return TRUE;
621720
622- if (is_wildcard (keyval ))
721+ if (is_wildcard (keyval ))
623722 arrayeng -> wildcard_char_count ++ ;
624723
625724 g_string_insert_c (arrayeng -> preedit , arrayeng -> cursor_pos , keyval );
@@ -630,6 +729,14 @@ static gboolean ibus_array_engine_process_key_event (IBusEngine *engine, guint
630729 return TRUE;
631730 }
632731
732+ if (is_fullwidth_mode ) {
733+ if (keyval >= 32 && keyval - 32 < sizeof (sFullWidthTable )) {
734+ IBusText * newtext = ibus_text_new_from_string (sFullWidthTable [keyval - 32 ]);
735+ ibus_engine_commit_text ((IBusEngine * )arrayeng , newtext );
736+ return TRUE;
737+ }
738+ }
739+
633740 return FALSE;
634741}
635742
@@ -756,6 +863,8 @@ static void ibus_array_engine_show_special_code_for_char (IBusArrayEngine *array
756863}
757864
758865static void ibus_array_engine_property_activate (IBusEngine * engine , const gchar * prop_name , guint prop_state ) {
866+ IBusArrayEngine * arrayeng = (IBusArrayEngine * )engine ;
867+
759868 if (g_strcmp0 (prop_name , "setup" ) == 0 ) {
760869 GError * error = NULL ;
761870 gchar * argv [2 ] = { NULL , };
@@ -772,6 +881,56 @@ static void ibus_array_engine_property_activate (IBusEngine *engine, const gchar
772881 g_spawn_async (NULL , argv , NULL , 0 , NULL , NULL , NULL , & error );
773882
774883 g_free (path );
884+ } else if (g_strcmp0 (prop_name , "mode" ) == 0 ) {
885+ int i = 0 ;
886+ IBusProperty * prop ;
887+ while ((prop = ibus_prop_list_get (arrayeng -> prop_list , i )) != NULL ) {
888+ if (g_strcmp0 (ibus_property_get_key (prop ), prop_name ) == 0 ) {
889+ is_english_mode = !is_english_mode ;
890+
891+ ibus_property_set_label (prop , is_english_mode ?
892+ ibus_text_new_from_string (_ ("English mode" )):
893+ ibus_text_new_from_string (_ ("Chinese mode" )));
894+ ibus_property_set_tooltip (prop , is_english_mode ?
895+ ibus_text_new_from_string (_ ("Switch to Chinese mode" )):
896+ ibus_text_new_from_string (_ ("Switch to English mode" )));
897+
898+ ibus_engine_update_property (engine , prop );
899+
900+ ibus_config_set_value (config , "engine/Array" , "Mode" ,
901+ g_variant_new_boolean (is_english_mode ));
902+
903+ ibus_array_engine_reset ((IBusEngine * )arrayeng );
904+ break ;
905+ }
906+
907+ i ++ ;
908+ }
909+ } else if (g_strcmp0 (prop_name , "fullwidth" ) == 0 ) {
910+ int i = 0 ;
911+ IBusProperty * prop ;
912+ while ((prop = ibus_prop_list_get (arrayeng -> prop_list , i )) != NULL ) {
913+ if (g_strcmp0 (ibus_property_get_key (prop ), prop_name ) == 0 ) {
914+ is_fullwidth_mode = !is_fullwidth_mode ;
915+
916+ ibus_property_set_label (prop , is_fullwidth_mode ?
917+ ibus_text_new_from_string (_ ("Full width mode" )):
918+ ibus_text_new_from_string (_ ("Half width mode" )));
919+ ibus_property_set_tooltip (prop , is_fullwidth_mode ?
920+ ibus_text_new_from_string (_ ("Switch to Half width mode" )):
921+ ibus_text_new_from_string (_ ("Switch to Full width mode" )));
922+
923+ ibus_engine_update_property (engine , prop );
924+
925+ ibus_config_set_value (config , "engine/Array" , "FullWidth" ,
926+ g_variant_new_boolean (is_fullwidth_mode ));
927+
928+ ibus_array_engine_reset ((IBusEngine * )arrayeng );
929+ break ;
930+ }
931+
932+ i ++ ;
933+ }
775934 }
776935}
777936
@@ -783,5 +942,7 @@ static void ibus_config_value_changed_cb (IBusConfig *config, const gchar *secti
783942 is_special_only = g_variant_get_boolean (value );
784943 else if (g_strcmp0 (name , "outputsimplified" ) == 0 )
785944 is_output_simplified = g_variant_get_boolean (value );
945+ else if (g_strcmp0 (name , "useshift" ) == 0 )
946+ is_use_shift = g_variant_get_boolean (value );
786947}
787948
0 commit comments