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