Initial check-in
[him-cellwriter] / src / him_cellwriter.c
1 #include "hildon-im-plugin.h"
2 #include "hildon-im-ui.h"
3
4 #include <string.h>
5 #include <glib.h>
6 #include <gdk/gdk.h>
7 #include <gdk/gdkx.h>
8 #include <gtk/gtk.h>
9 #include <hildon/hildon.h>
10
11 #include <stdarg.h>
12 #include <stdio.h>
13
14 #include "common.h"
15
16 #define HILDON_IM_CELLWRITER_TYPE hildon_im_cellwriter_get_type()
17 #define HILDON_IM_CELLWRITER(obj) GTK_CHECK_CAST(obj, hildon_im_cellwriter_get_type(), HildonIMCellwriter)
18 #define HILDON_IM_CELLWRITER_CLASS(klass) \
19         GTK_CHECK_CLASS_CAST(klass, hildon_im_cellwriter_get_type, \
20                              HildonIMCellwriterClass)
21 #define HILDON_IS_IM_CELLWRITER(obj) \
22         GTK_CHECK_TYPE(obj, hildon_im_cellwriter_get_type())
23 #define HILDON_IM_CELLWRITER_GET_PRIVATE(obj) \
24         (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_IM_CELLWRITER_TYPE,\
25                                       HildonIMCellwriterPrivate))
26
27 typedef struct
28 {
29   GtkContainerClass parent;
30 }
31 HildonIMCellwriterClass;
32
33 typedef struct
34 {
35   GtkContainer parent;
36
37 }
38 HildonIMCellwriter;
39
40 typedef struct
41 {
42   HildonIMUI *ui;
43   GtkWidget *window;
44
45 }
46 HildonIMCellwriterPrivate;
47
48 HildonIMUI * ui = NULL;
49
50 static GType hildon_im_cellwriter_type = 0;
51 static GtkWidgetClass *parent_class = NULL;
52
53 GType hildon_im_cellwriter_get_type (void);
54 GtkWidget *hildon_im_cellwriter_new (HildonIMUI *kbd);
55
56 /*
57  * HildonIMPlugin interface
58  */
59
60 static void hildon_im_cellwriter_iface_init (HildonIMPluginIface *iface);
61
62 static void hildon_im_cellwriter_enable (HildonIMPlugin *plugin, gboolean init);
63 static void hildon_im_cellwriter_disable                   (HildonIMPlugin *plugin);
64 static void hildon_im_cellwriter_surrounding_received      (HildonIMPlugin *plugin,
65                                                              const gchar *surrounding,
66                                                              gint offset);
67 /*
68  * GObject functions
69  */
70 static void hildon_im_cellwriter_finalize     (GObject *obj);
71 static void hildon_im_cellwriter_get_property (GObject *object,
72                                                 guint prop_id,
73                                                 GValue *value,
74                                                 GParamSpec *pspec);
75 static void hildon_im_cellwriter_set_property (GObject *object,
76                                                 guint prop_id,
77                                                 const GValue *value,
78                                                 GParamSpec *pspec);
79
80 static void hildon_im_cellwriter_class_init (HildonIMCellwriterClass *klass);
81 static void hildon_im_cellwriter_init       (HildonIMCellwriter *self);
82
83 /*
84  * Internal functions
85  */
86 static void populate_window (HildonIMCellwriter *self);
87 static void cellwriter_init (HildonIMCellwriter *self);
88
89 /*
90  * Logging functions
91  */
92 #define LOG_FILE "/tmp/hildon-im-cellwriter.log"
93
94 int log_indent = 0;
95
96 void Log(char *format, ...){
97         va_list args;
98         static FILE *fp = NULL;
99
100         va_start(args, format);
101         
102         if(!fp){
103                 fp = fopen(LOG_FILE, "a");
104         }
105         
106         int i;
107         for(i = 0; i < log_indent; i++)
108           fprintf(fp, "  ");
109         vfprintf(fp, format, args);
110         fputc('\n', fp);
111         fflush(fp);
112
113         va_end(args);
114 }
115
116
117 /*
118  * Module functions
119  */
120
121 HildonIMPlugin*
122 module_create (HildonIMUI *keyboard)
123 {
124   Log("module_create(%x)", keyboard); log_indent ++;
125   HildonIMPlugin *plugin = HILDON_IM_PLUGIN (hildon_im_cellwriter_new (keyboard));
126   log_indent --;
127   Log("module_create = %x", plugin);
128   return plugin;
129 }
130
131 void
132 module_exit(void)
133 {
134   Log("module_exit()");
135   /* empty */
136 }
137
138 void
139 module_init(GTypeModule *module)
140 {
141   Log("module_init(%x)", module); log_indent ++;
142
143   static const GTypeInfo type_info = {
144     sizeof(HildonIMCellwriterClass),
145     NULL, /* base_init */
146     NULL, /* base_finalize */
147     (GClassInitFunc) hildon_im_cellwriter_class_init,
148     NULL, /* class_finalize */
149     NULL, /* class_data */
150     sizeof(HildonIMCellwriter),
151     0, /* n_preallocs */
152     (GInstanceInitFunc) hildon_im_cellwriter_init,
153   };
154
155   static const GInterfaceInfo plugin_info = {
156     (GInterfaceInitFunc) hildon_im_cellwriter_iface_init,
157     NULL, /* interface_finalize */
158     NULL, /* interface_data */
159   };
160
161   hildon_im_cellwriter_type =
162           g_type_module_register_type(module,
163                                       GTK_TYPE_CONTAINER, "HildonIMCellwriter",
164                                       &type_info,
165                                       0);
166
167   g_type_module_add_interface(module,
168                               HILDON_IM_CELLWRITER_TYPE,
169                               HILDON_IM_TYPE_PLUGIN,
170                               &plugin_info);
171   log_indent --;
172 }
173
174 /*
175  * This is used to know the plugin's information when loading the module
176  */
177 const HildonIMPluginInfo *
178 hildon_im_plugin_get_info(void)
179 {
180   Log("hildon_im_plugin_get_info()"); log_indent ++;
181   static const HildonIMPluginInfo info =
182   {
183     "HIM Cellwriter",                   /* description */
184     "him_cellwriter",                   /* name */
185     NULL,                               /* menu title */
186     NULL,                               /* gettext domain */
187     TRUE,                               /* visible in menu */
188     FALSE,                              /* cached TODO make it TRUE */
189     HILDON_IM_TYPE_FULLSCREEN,          /* UI type */
190     HILDON_IM_GROUP_LATIN,              /* group */
191     HILDON_IM_DEFAULT_PLUGIN_PRIORITY,  /* priority */
192     NULL,                               /* special character plugin */
193     NULL,                               /* help page */
194     TRUE,                               /* disable common UI buttons */
195     0,                                  /* plugin height */
196     HILDON_IM_TRIGGER_FINGER            /* trigger */
197   };
198
199   log_indent --;
200
201   return &info;
202 }
203
204 /*
205  * This function returns the list of available languages supported
206  * by the plugin.
207  */
208 gchar **
209 hildon_im_plugin_get_available_languages (gboolean *free)
210 {
211   Log("hildon_im_plugin_get_available_langauges()");
212   static gchar *list[] = { "en_GB", NULL };
213   *free = FALSE;
214
215   return list;
216 }
217
218 GType
219 hildon_im_cellwriter_get_type (void)
220 {
221   // Log("hildon_im_plugin_fkb_get_type()");
222   return hildon_im_cellwriter_type;
223 }
224
225 /*
226  * Implement the interface.
227  */
228 static void
229 hildon_im_cellwriter_iface_init (HildonIMPluginIface *iface)
230 {
231   Log("hildon_im_cellwriter_iface_init()");
232   iface->enable = hildon_im_cellwriter_enable;
233   iface->disable = hildon_im_cellwriter_disable;
234   iface->surrounding_received = hildon_im_cellwriter_surrounding_received;
235   // preedit_commited ?
236 }
237
238 static void
239 hildon_im_cellwriter_class_init (HildonIMCellwriterClass *klass)
240 {
241   Log("hildon_im_cellwriter_class_init(%x)", klass); log_indent ++;
242   GObjectClass *object_class;
243   GtkObjectClass *gtk_object_class;
244   GtkWidgetClass *widget_class;
245   GtkContainerClass *container_class;
246
247   parent_class = g_type_class_peek_parent(klass);
248   g_type_class_add_private(klass, sizeof(HildonIMCellwriterPrivate));
249
250   object_class = G_OBJECT_CLASS(klass);
251   gtk_object_class = GTK_OBJECT_CLASS(klass);
252   widget_class = GTK_WIDGET_CLASS(klass);
253   container_class = GTK_CONTAINER_CLASS(klass);
254
255   object_class->set_property  = hildon_im_cellwriter_set_property;
256   object_class->get_property  = hildon_im_cellwriter_get_property;
257   object_class->finalize      = hildon_im_cellwriter_finalize;
258
259   /* install properties and signals as needed */
260
261   g_object_class_install_property(object_class, HILDON_IM_PROP_UI,
262                                   g_param_spec_object (HILDON_IM_PROP_UI_DESCRIPTION,
263                                                        HILDON_IM_PROP_UI_DESCRIPTION,
264                                                        "UI that uses plugin",
265                                                        HILDON_IM_TYPE_UI,
266                                                        G_PARAM_READWRITE
267                                                        | G_PARAM_CONSTRUCT_ONLY));
268
269   log_indent --;
270 }
271
272 static void
273 hildon_im_cellwriter_init (HildonIMCellwriter *self)
274 {
275   Log("hildon_im_cellwriter_init(%x)", self);
276
277   HildonIMCellwriterPrivate *priv;
278  
279   g_return_if_fail (HILDON_IS_IM_CELLWRITER (self));
280   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(self);
281
282   priv->window = NULL;
283 }
284
285 static void
286 hildon_im_cellwriter_finalize(GObject *obj)
287 {
288   Log("hildon_im_cellwriter_finalize(%x)", obj);
289   if (G_OBJECT_CLASS(parent_class)->finalize)
290   {
291     G_OBJECT_CLASS(parent_class)->finalize(obj);
292   }
293 }
294
295 GtkWidget *
296 hildon_im_cellwriter_new (HildonIMUI *kbd)
297 {
298   Log("hildon_im_cellwriter_new(%x)", kbd); log_indent ++;
299   GtkWidget *widget =  g_object_new (HILDON_IM_CELLWRITER_TYPE,
300                        HILDON_IM_PROP_UI_DESCRIPTION, kbd, NULL);
301   log_indent --;
302   return widget;
303 }
304
305 static void
306 hildon_im_cellwriter_get_property (GObject *object,
307                                     guint prop_id,
308                                     GValue *value,
309                                     GParamSpec *pspec)
310 {
311   Log("hildon_im_cellwriter_get_property(%x, %d, %x, %x)", object, prop_id, value, pspec); log_indent ++;
312   HildonIMCellwriterPrivate *priv;
313
314   g_return_if_fail (HILDON_IS_IM_CELLWRITER(object));
315   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(object);
316
317   switch (prop_id)
318   {
319     case HILDON_IM_PROP_UI:
320       g_value_set_object(value, priv->ui);
321       break;
322
323     default:
324       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
325       break;
326   }
327   log_indent ++;
328 }
329
330 static void
331 hildon_im_cellwriter_set_property (GObject *object,
332                                     guint prop_id,
333                                     const GValue *value,
334                                     GParamSpec *pspec)
335 {
336   Log("hildon_im_cellwriter_set_property(%x, %d, %x, %x)", object, prop_id, value, pspec); log_indent ++;
337   HildonIMCellwriterPrivate *priv;
338
339   g_return_if_fail (HILDON_IS_IM_CELLWRITER (object));
340   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(object);
341
342   switch (prop_id)
343   {
344     case HILDON_IM_PROP_UI:
345       ui = priv->ui = g_value_get_object(value);
346       break;
347     default:
348       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
349       break;
350   }
351   log_indent --;
352 }
353
354 static void
355 hildon_im_cellwriter_enable (HildonIMPlugin *plugin, gboolean init)
356 {
357   Log("hildon_im_cellwriter_enable(%x, %s)", plugin, init ? "true" : "false" ); log_indent ++;
358
359   HildonIMCellwriter *self;
360   HildonIMCellwriterPrivate *priv;
361   gboolean window_is_new;
362
363   g_return_if_fail (HILDON_IS_IM_CELLWRITER (plugin));
364   self = HILDON_IM_CELLWRITER(plugin);
365   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(self);
366
367   window_is_new = (priv->window == NULL);
368
369   if (window_is_new)
370   {
371     priv->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
372   }
373
374   gtk_window_set_type_hint(GTK_WINDOW(priv->window), GDK_WINDOW_TYPE_HINT_DIALOG);
375   gtk_window_set_decorated(GTK_WINDOW(priv->window), FALSE);
376   // hildon_gtk_window_set_portrait_flags (GTK_WINDOW(priv->window), HILDON_PORTRAIT_MODE_SUPPORT);
377
378   hildon_im_ui_send_communication_message(priv->ui, HILDON_IM_CONTEXT_REQUEST_SURROUNDING);
379
380   gtk_window_fullscreen(GTK_WINDOW(priv->window));
381   gtk_widget_show_all(priv->window);
382
383   gdk_window_set_transient_for(GTK_WIDGET(priv->window)->window, gtk_widget_get_root_window(GTK_WIDGET(priv->window)));
384
385   if (window_is_new)
386   {
387     cellwriter_init(self);
388     populate_window(self);
389     gtk_widget_show_all(priv->window);
390   }
391
392   window_show();
393
394   log_indent --;
395 }
396
397 static void
398 hildon_im_cellwriter_disable (HildonIMPlugin *plugin)
399 {
400   Log("hildon_im_cellwriter_disable(%x)", plugin); log_indent ++;
401
402   HildonIMCellwriter *self;
403   HildonIMCellwriterPrivate *priv;
404
405   g_return_if_fail (HILDON_IS_IM_CELLWRITER(plugin));
406   self = HILDON_IM_CELLWRITER(plugin);
407   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(self);
408
409   if (GTK_WIDGET_VISIBLE(GTK_WIDGET(priv->window)))
410   {
411     gtk_widget_hide(GTK_WIDGET(priv->window));
412   }
413
414   log_indent --;
415 }
416
417 void cell_widget_load_string(const gchar *str);
418
419 static void
420 hildon_im_cellwriter_surrounding_received(HildonIMPlugin *plugin,
421                                            const gchar *surrounding,
422                                            gint offset)
423 {
424   Log("hildon_im_cellwriter_surrounding_received(%x, '%s', %d)", plugin, surrounding, offset); log_indent ++;
425
426   HildonIMCellwriter *self;
427   HildonIMCellwriterPrivate *priv;
428
429   if(hildon_im_ui_get_commit_mode(ui) == HILDON_IM_COMMIT_REDIRECT)
430     cell_widget_load_string(surrounding);
431
432   log_indent --;
433 }
434
435 static void
436 close_fkb (GtkButton *button, gpointer user_data)
437 {
438   HildonIMCellwriter *self;
439   HildonIMCellwriterPrivate *priv;
440
441   g_return_if_fail (HILDON_IS_IM_CELLWRITER (user_data));
442   self = HILDON_IM_CELLWRITER(user_data);
443   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(self);
444
445   hildon_im_ui_restore_previous_mode(priv->ui);
446 }
447
448 void read_profile();
449
450 static void cellwriter_init(HildonIMCellwriter *self){
451
452   HildonIMCellwriterPrivate *priv;
453   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(self);
454
455   key_event_init(priv->ui);
456   recognize_init();
457   read_profile();
458   update_enabled_samples();
459   
460 }
461
462 static void
463 populate_window (HildonIMCellwriter *self)
464 {
465   Log("populate_window(%x)", self); log_indent ++;
466
467   HildonIMCellwriterPrivate *priv;
468   GtkWidget *parea, *hbox;
469   gint screen_width = gdk_screen_width();
470
471   priv = HILDON_IM_CELLWRITER_GET_PRIVATE(self);
472
473   window_create(priv->window);
474
475   log_indent --;
476 }
477
478
479 /*
480 typedef enum
481 {
482   HILDON_IM_COMMIT_DIRECT,
483   HILDON_IM_COMMIT_REDIRECT,
484   HILDON_IM_COMMIT_SURROUNDING,
485   HILDON_IM_COMMIT_BUFFERED,
486   HILDON_IM_COMMIT_PREEDIT
487 } HildonIMCommitMode;
488
489 hildon_im_ui_Send_event(ui, Window window, XEvent event)
490
491 */