This commit was manufactured by cvs2svn to create branch 'uc'.
[gnokii.git] / xgnokii / xgnokii_xkeyb.c
1 /*
2
3   X G N O K I I
4
5   A Linux/Unix GUI for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8
9 */
10
11 #include <string.h>
12 #include <gtk/gtk.h>
13 #include "misc.h"
14 #include "xgnokii_common.h"
15 #include "xgnokii.h"
16 #include "xgnokii_lowlevel.h"
17 #include "xgnokii_xkeyb.h"
18
19 typedef struct {
20   int top_left_x, top_left_y;
21   int bottom_right_x, bottom_right_y;
22   int code;
23 } ButtonT;
24
25
26 static GtkWidget *GUI_XkeybWindow;
27 static GtkWidget *pixArea;
28 static GtkWidget *phonePixmap = NULL;
29 static ErrorDialog errorDialog = {NULL, NULL};
30 static ButtonT *button = NULL;
31
32 static ButtonT button_6110[30] = {
33   { 103,  91, 114, 107, PHONEKEY_POWER          }, /* Power */
34   {  28, 240,  54, 263, PHONEKEY_MENU           }, /* Menu */
35   {  84, 240, 110, 263, PHONEKEY_NAMES          }, /* Names */
36   {  58, 245,  82, 258, PHONEKEY_UP             }, /* Up */
37   {  55, 263,  85, 276, PHONEKEY_DOWN           }, /* Down */
38   {  22, 271,  50, 289, PHONEKEY_GREEN          }, /* Green */
39   {  91, 271, 115, 289, PHONEKEY_RED            }, /* Red */
40   {  18, 294,  44, 310, PHONEKEY_1              }, /* 1 */
41   {  56, 294,  85, 310, PHONEKEY_2              }, /* 2 */
42   {  98, 294, 121, 310, PHONEKEY_3              }, /* 3 */
43   {  18, 317,  44, 333, PHONEKEY_4              }, /* 4 */
44   {  56, 317,  85, 333, PHONEKEY_5              }, /* 5 */
45   {  98, 317, 121, 333, PHONEKEY_6              }, /* 6 */
46   {  18, 342,  44, 356, PHONEKEY_7              }, /* 7 */
47   {  56, 342,  85, 356, PHONEKEY_8              }, /* 8 */
48   {  98, 342, 121, 356, PHONEKEY_9              }, /* 9 */
49   {  18, 365,  44, 380, PHONEKEY_ASTERISK       }, /* * */
50   {  56, 365,  85, 380, PHONEKEY_0              }, /* 0 */
51   {  98, 365, 121, 380, PHONEKEY_HASH           }, /* # */
52   {   1, 138,  10, 150, PHONEKEY_INCREASEVOLUME }, /* Volume + */
53   {   1, 165,  10, 176, PHONEKEY_DECREASEVOLUME }, /* Volume - */
54   {   0,   0,   0,   0, 0x00 }
55 };
56
57 static ButtonT button_6150[30] = {
58   {  99,  78, 114,  93, PHONEKEY_POWER          }, /* Power */
59   {  20, 223,  49, 245, PHONEKEY_MENU           }, /* Menu */
60   {  90, 223, 120, 245, PHONEKEY_NAMES          }, /* Names */
61   {  59, 230,  83, 247, PHONEKEY_UP             }, /* Up */
62   {  56, 249,  84, 265, PHONEKEY_DOWN           }, /* Down */
63   {  14, 254,  51, 273, PHONEKEY_GREEN          }, /* Green */
64   {  90, 255, 126, 273, PHONEKEY_RED            }, /* Red */
65   {  18, 281,  53, 299, PHONEKEY_1              }, /* 1 */
66   {  55, 280,  86, 299, PHONEKEY_2              }, /* 2 */
67   {  90, 281, 122, 299, PHONEKEY_3              }, /* 3 */
68   {  18, 303,  53, 323, PHONEKEY_4              }, /* 4 */
69   {  55, 303,  87, 323, PHONEKEY_5              }, /* 5 */
70   {  90, 303, 122, 323, PHONEKEY_6              }, /* 6 */
71   {  18, 327,  53, 346, PHONEKEY_7              }, /* 7 */
72   {  53, 327,  87, 346, PHONEKEY_8              }, /* 8 */
73   {  90, 327, 122, 346, PHONEKEY_9              }, /* 9 */
74   {  18, 349,  53, 370, PHONEKEY_ASTERISK       }, /* * */
75   {  56, 349,  87, 370, PHONEKEY_0              }, /* 0 */
76   {  98, 349, 122, 370, PHONEKEY_HASH           }, /* # */
77   {   2, 131,  10, 147, PHONEKEY_INCREASEVOLUME }, /* Volume + */
78   {   2, 155,  10, 173, PHONEKEY_DECREASEVOLUME }, /* Volume - */
79   {   0,   0,   0,   0, 0x00 }
80 };
81
82 static ButtonT button_5110[30] = {
83   { 100,  85, 114,  99, PHONEKEY_POWER    }, /* Power */
84   {  50, 240,  85, 265, PHONEKEY_MENU     }, /* Menu */
85   {  20, 240,  45, 260, PHONEKEY_NAMES    }, /* Names */
86   { 100, 240, 117, 258, PHONEKEY_UP       }, /* Up */
87   {  93, 267, 112, 287, PHONEKEY_DOWN     }, /* Down */
88   {  14, 294,  44, 312, PHONEKEY_1        }, /* 1 */
89   {  54, 294,  83, 312, PHONEKEY_2        }, /* 2 */
90   {  94, 294, 122, 312, PHONEKEY_3        }, /* 3 */
91   {  14, 320,  44, 338, PHONEKEY_4        }, /* 4 */
92   {  54, 320,  83, 338, PHONEKEY_5        }, /* 5 */
93   {  94, 320, 122, 338, PHONEKEY_6        }, /* 6 */
94   {  14, 345,  44, 363, PHONEKEY_7        }, /* 7 */
95   {  54, 345,  83, 363, PHONEKEY_8        }, /* 8 */
96   {  94, 345, 122, 363, PHONEKEY_9        }, /* 9 */
97   {  18, 374,  49, 389, PHONEKEY_ASTERISK }, /* * */
98   {  53, 371,  82, 387, PHONEKEY_0        }, /* 0 */
99   {  96, 374, 119, 389, PHONEKEY_HASH     }, /* # */
100   {   0,   0,   0,   0, 0x00 }
101 };
102
103 static inline void Help1 (GtkWidget *w, gpointer data)
104 {
105   gchar *indx = g_strdup_printf ("/%s/gnokii/xgnokii/xkeyb/index.htm", xgnokiiConfig.locale);
106   Help (w, indx);
107   g_free (indx);
108 }
109
110
111 static GtkWidget *GetPixmap (void)
112 {
113   GtkWidget *wpixmap;
114   GdkPixmap *pixmap;
115   GdkBitmap *mask;
116   gchar *file;
117
118   if (!strcmp (phoneMonitor.phone.model, "6110") ||
119       !strcmp (phoneMonitor.phone.model, "6120"))
120   {
121     button = button_6110;
122     file = g_strdup_printf ("%s%s", xgnokiiConfig.xgnokiidir, "/xpm/6110.xpm");
123   }
124   else if (!strcmp (phoneMonitor.phone.model, "6130") ||
125            !strcmp (phoneMonitor.phone.model, "6150") ||
126            !strcmp (phoneMonitor.phone.model, "616x") ||
127            !strcmp (phoneMonitor.phone.model, "6185") ||
128            !strcmp (phoneMonitor.phone.model, "6190"))
129   {
130     button = button_6150;
131     file = g_strdup_printf ("%s%s", xgnokiiConfig.xgnokiidir, "/xpm/6150.xpm");
132   }
133   else if (!strcmp (phoneMonitor.phone.model, "5110") ||
134            !strcmp (phoneMonitor.phone.model, "5130") ||
135            !strcmp (phoneMonitor.phone.model, "5160") ||
136            !strcmp (phoneMonitor.phone.model, "5190"))
137   {
138     button = button_5110;
139     file = g_strdup_printf ("%s%s", xgnokiiConfig.xgnokiidir, "/xpm/5110.xpm");
140   }
141   else
142     return NULL;
143
144   pixmap = gdk_pixmap_create_from_xpm (pixArea->window, &mask,
145                                        &pixArea->style->bg[GTK_STATE_NORMAL],
146                                        file);
147   g_free (file);
148
149   if (pixmap == NULL)
150     return NULL;
151     
152   wpixmap = gtk_pixmap_new (pixmap, mask);
153   
154   return wpixmap;
155 }
156
157
158 static inline void CloseXkeyb (GtkWidget *w, gpointer data)
159 {
160   gtk_widget_hide (GUI_XkeybWindow);
161 }
162
163
164 void GUI_ShowXkeyb (void)
165 {
166   if (phonePixmap == NULL)
167   {
168     phonePixmap = GetPixmap ();
169     if (phonePixmap != NULL)
170     {
171       gtk_fixed_put (GTK_FIXED (pixArea), phonePixmap, 0 , 0);
172       gtk_widget_show (phonePixmap);
173     }
174     else
175     {
176       gtk_label_set_text (GTK_LABEL (errorDialog.text),
177                           _("Cannot load background pixmap!"));
178       gtk_widget_show (errorDialog.dialog);
179     }
180   }
181   gtk_widget_show (GUI_XkeybWindow);
182 }
183
184
185 static gint ButtonEvent (GtkWidget *widget, GdkEventButton *event)
186 {
187   unsigned char req[] = {0x00,0x00};
188   register gint i = 0;
189
190   if (button == NULL)
191     return TRUE;
192
193   if (event->button != 1)
194     return TRUE;
195
196   if (event->type == GDK_BUTTON_PRESS) 
197     req[0] = PRESSPHONEKEY;
198   else if (event->type == GDK_BUTTON_RELEASE)
199     req[0] = RELEASEPHONEKEY;
200   else
201     return TRUE;
202
203 //  g_print ("%f %f\n", event->x, event->y);
204
205   while (button[i].top_left_x != 0) {
206     if (button[i].top_left_x <= event->x &&
207         event->x <= button[i].bottom_right_x &&
208         button[i].top_left_y <= event->y &&
209         event->y <= button[i].bottom_right_y)
210     {
211       PhoneEvent *e = g_malloc (sizeof (PhoneEvent));
212       
213       req[1]=button[i].code;
214       e->event = Event_SendKeyStroke;
215       e->data = g_memdup (req, sizeof (req));
216       GUI_InsertEvent (e);
217     }
218
219     i++;
220   }
221
222   return TRUE;
223 }
224
225
226 static GtkItemFactoryEntry menu_items[] = {
227   {NULL,        NULL,           NULL, 0, "<Branch>"},
228   {NULL,        "<control>W",   CloseXkeyb, 0, NULL},
229   {NULL,        NULL,           NULL, 0, "<LastBranch>"},
230   {NULL,        NULL,           Help1, 0, NULL},
231   {NULL,        NULL,           GUI_ShowAbout, 0, NULL},
232 };
233
234 static void InitMainMenu (void)
235 {
236   menu_items[0].path = g_strdup (_("/_File"));
237   menu_items[1].path = g_strdup (_("/File/_Close"));
238   menu_items[2].path = g_strdup (_("/_Help"));
239   menu_items[3].path = g_strdup (_("/Help/_Help"));
240   menu_items[4].path = g_strdup (_("/Help/_About"));
241 }
242
243
244 void GUI_CreateXkeybWindow (void)
245 {
246   int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
247   GtkItemFactory *item_factory;
248   GtkAccelGroup *accel_group;
249   GtkWidget *menubar;
250   GtkWidget *main_vbox;
251
252   InitMainMenu ();
253   GUI_XkeybWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
254   gtk_window_set_title (GTK_WINDOW (GUI_XkeybWindow), _("XGnokii Keyboard"));
255   //gtk_widget_set_usize (GTK_WIDGET (GUI_XkeybWindow), 436, 220);
256   gtk_signal_connect (GTK_OBJECT (GUI_XkeybWindow), "delete_event",
257                       GTK_SIGNAL_FUNC (DeleteEvent), NULL);
258   gtk_widget_realize (GUI_XkeybWindow);
259
260   accel_group = gtk_accel_group_new ();
261   item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", 
262                                        accel_group);
263
264   gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
265
266   gtk_accel_group_attach (accel_group, GTK_OBJECT (GUI_XkeybWindow));
267
268   /* Finally, return the actual menu bar created by the item factory. */ 
269   menubar = gtk_item_factory_get_widget (item_factory, "<main>");
270
271   main_vbox = gtk_vbox_new (FALSE, 1);
272   gtk_container_border_width (GTK_CONTAINER (main_vbox), 1);
273   gtk_container_add (GTK_CONTAINER (GUI_XkeybWindow), main_vbox);
274   gtk_widget_show (main_vbox);
275
276   gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0);
277   gtk_widget_show (menubar);
278
279   pixArea = gtk_fixed_new ();
280   gtk_signal_connect (GTK_OBJECT (pixArea), "button_press_event",
281                       (GtkSignalFunc) ButtonEvent, NULL);
282   gtk_signal_connect (GTK_OBJECT (pixArea), "button_release_event",
283                       (GtkSignalFunc) ButtonEvent, NULL);
284   gtk_widget_set_events (pixArea, GDK_EXPOSURE_MASK
285                          | GDK_LEAVE_NOTIFY_MASK
286                          | GDK_BUTTON_PRESS_MASK
287                          | GDK_BUTTON_RELEASE_MASK
288                          | GDK_POINTER_MOTION_MASK
289                          | GDK_POINTER_MOTION_HINT_MASK);
290
291   gtk_box_pack_start (GTK_BOX (main_vbox), pixArea, FALSE, FALSE, 3);
292   gtk_widget_show (pixArea);
293
294   CreateErrorDialog (&errorDialog, GUI_XkeybWindow);
295 }