http://marcin-wiacek.fkn.pl/english/zips/mygnokii.tar.gz
[gnokii.git] / xgnokii / xgnokii_xring.c
1 #include <stdlib.h>
2 #include <fcntl.h>
3 #include <signal.h>
4 #include <sys/types.h>
5 #include <string.h>
6 #include <gtk/gtk.h>
7 #include <stdio.h>
8 #include <assert.h>
9
10 #include "misc.h"
11 #include "gsm-common.h"
12 #include "gsm-api.h"
13 #include "gsm-ringtones.h"
14
15 #include "xgnokii_xring.h"
16 #include "xgnokii_common.h"
17 #include "xgnokii_lowlevel.h"
18 #include "xgnokii.h"
19
20 #include "xpm/Send.xpm"
21
22 static GtkWidget *GUI_RingtonesWindow;
23
24 GtkWidget * blacks[WHITE_COUNT - 1];
25 GtkWidget * whites[WHITE_COUNT];
26
27 int pressed;
28
29 PixmapAndMask pam[KIE_COUNT];
30
31 GSM_Ringtone ringtone;
32
33 char xwhi[] = { 6, 4, 2, 6, 4, 4, 2 };
34
35 /* Bitmaps for keyboard */
36 static
37   char * blackparts[] = {
38      ".+@@@@@@@@@@@@+.",
39      "+.+@@@@@@@@@@+.+",
40      "@+.+@@@@@@@@+.+@",
41      "@@+.+@@@@@@+.+@@",
42      "@@@+........+@@@",
43      "@@@@........@@@@"
44   };
45
46 static 
47   char * whitestarts[][3] = {
48     { "        ++++++++++++++++",
49       "        +..............+",
50       "+++++++++..............+" },
51     {
52       "        ++++++++        ",
53       "        +......+        ",
54       "+++++++++......+++++++++" },
55     {
56       "++++++++++++++++        ",
57       "+..............+        ",
58       "+..............+++++++++" }};
59
60
61 static
62   char * whiteend[] = {
63      "+......................+",
64      "+@....................@+",
65      "+@@..................@@+",
66      "++@@@..............@@@++",
67      "++++++++++++++++++++++++"
68   };
69
70 static inline void CloseRingtonesWindow (void) {
71   gtk_widget_hide(GUI_RingtonesWindow);
72 }
73   
74 static GtkItemFactoryEntry ringtonesMenuItems[] = {
75   { NULL,       NULL,           NULL,                    0, "<Branch>"},
76   { NULL,       "<control>O",   NULL,                    0, NULL},
77   { NULL,       "<control>S",   NULL,                    0, NULL},
78   { NULL,       NULL,           NULL,                    0, NULL},
79   { NULL,       NULL,           NULL,                    0, "<Separator>"},
80   { NULL,       "<control>T",   NULL,                    0, NULL},
81   { NULL,       NULL,           NULL,                    0, "<Separator>"},
82   { NULL,       "<control>C",   CloseRingtonesWindow,    0, NULL},
83   { NULL,       NULL,           NULL,                    0, "<Branch>"},
84   { NULL,       "<control>S",   NULL,                    0, NULL},
85   { NULL,       "<control>H",   NULL,                    0, NULL},
86 };
87
88 static void InitRingtonesMenu (void) {
89  ringtonesMenuItems[0].path = g_strdup(_("/_File"));
90  ringtonesMenuItems[1].path = g_strdup(_("/File/_Open"));
91  ringtonesMenuItems[2].path = g_strdup(_("/File/_Save"));
92  ringtonesMenuItems[3].path = g_strdup(_("/File/Save _as ..."));
93  ringtonesMenuItems[4].path = g_strdup(_("/File/Sep1"));
94  ringtonesMenuItems[5].path = g_strdup(_("/File/Se_t ringtone"));
95  ringtonesMenuItems[6].path = g_strdup(_("/File/Sep2"));
96  ringtonesMenuItems[7].path = g_strdup(_("/File/_Close"));
97  ringtonesMenuItems[8].path = g_strdup(_("/_Edit"));
98  ringtonesMenuItems[9].path = g_strdup(_("/Edit/_Set ringtone name"));
99  ringtonesMenuItems[10].path = g_strdup(_("/Edit/S_how in Composer"));
100 }
101
102 /* Add created pixmap to widget */
103 static int createpixmap(GtkWidget * widget, PixmapAndMask * pam, char ** a)
104 {
105   GtkStyle * style = gtk_widget_get_default_style();
106   pam->pixmap = gdk_pixmap_create_from_xpm_d(widget->window,
107                                              &pam->mask,
108                                              &style->bg[GTK_STATE_NORMAL],
109                                              a);
110   return (int)pam->pixmap; /* (to) NULL or not (to) NULL */
111 }
112
113 static void writecolors(char * buf0, char * col0,
114                         char * buf1, char * col1,
115                         char * buf2, char * col2)
116 {
117   sprintf(buf0, ".      c #%s", col0);
118   sprintf(buf1, "+      c #%s", col1);
119   sprintf(buf2, "@      c #%s", col2);
120 }
121
122 /* Creates white pixmap in the keyboard */
123 int KeyboardCreateWhitePixmap(GtkWidget * window, PixmapAndMask * pam,
124                               char * start[], char * color0, char * color1, char * color2)
125 {
126   int i = 0, j = 0;
127   char * a[160 + 5];
128   char col0[20];
129   char col1[20];
130   char col2[20];
131
132   a[i++] = "24 160 4 1";
133   a[i++] = "    c None";
134   writecolors(col0, color0, col1, color1, col2, color2);
135   a[i++] = col0;
136   a[i++] = col1;
137   a[i++] = col2;
138   
139   a[i++] = start[0];
140   for (j = 0; j < 99; j++)
141     a[i++] = start[1];
142   a[i++] = start[2];
143
144   for (j = 0; j < 54; j++)
145     a[i++] = whiteend[0];
146
147   a[i++] = whiteend[1];
148   a[i++] = whiteend[1];
149   a[i++] = whiteend[2];
150   a[i++] = whiteend[3];
151   a[i++] = whiteend[4];
152
153   assert(i == 165);
154
155   return createpixmap(window, pam, a);
156   
157 }
158
159 /* Creates black pixmap in the keyboard */
160 int KeyboardCreateBlackPixmap(GtkWidget * window, PixmapAndMask * pam,
161                               char * color0, char * color1, char * color2)
162 {
163   int i = 0, j = 0;
164   char * a[160 + 4];
165   char col0[20];
166   char col1[20];
167   char col2[20];
168
169   a[i++] = "16 100 3 1";
170   writecolors(col0, color0, col1, color1, col2, color2);
171   a[i++] = col0;
172   a[i++] = col1;
173   a[i++] = col2;
174
175   for (j = 0; j < 5; j++)    a[i++] = blackparts[j];
176   for (j = 0; j < 90; j++)   a[i++] = blackparts[5];
177   for (j = 4; j >= 0; j--)   a[i++] = blackparts[j];
178
179   assert(i == 104);
180
181   return createpixmap(window, pam, a);
182 }
183
184 static void KeyboardSetPixmap(int flag)
185 {
186   int i = pressed & ~(BLACK_PRESSED|WHITE_PRESSED);
187   int j;
188
189   if (pressed & BLACK_PRESSED)
190   {
191     j = flag? KIE_BLACKSEL: KIE_BLACK;
192     gtk_pixmap_set(GTK_PIXMAP(blacks[i]),pam[j].pixmap, pam[j].mask);
193   }
194   else
195   {
196     j = xwhi[i % 7] + (flag? 1: 0);
197     gtk_pixmap_set(GTK_PIXMAP(whites[i]),pam[j].pixmap, pam[j].mask);
198   }
199 }
200
201 static void KeyboardSendTune()
202 {
203   /* frequencies generated with:
204      perl -e 'print int(4400 * (2 **($_/12)) + .5)/10, "\n" for(3..14)'
205   */
206   struct {
207   float wf;
208   float bf;
209   } notefreq[7] = {
210     { 523.3, 554.4 },  //C
211     { 587.3, 622.3 },  //D
212     { 659.3, 0 },      //E
213     { 698.5, 740   },  //F
214     { 784  , 830.6 },  //G
215     { 880  , 932.3 },  //A
216     { 987.8, 0 }       //H
217   };
218
219   int i=pressed;
220   
221   int j, r;
222   float freq;
223
224   if (i) {
225     j = (i & BLACK_PRESSED)? 1: 0;
226
227     i &= ~(BLACK_PRESSED|WHITE_PRESSED);
228
229     freq = j? notefreq[i % 7].bf: notefreq[i % 7].wf;
230
231     switch (i / 7)
232     {
233       case  0: r = (int)(freq / 2.0); break;
234       case  2: r = (int)(freq * 2.0); break;
235       default: r = (int)(freq); break;
236     }
237
238     GSM->PlayTone(r,100);
239
240   } else {
241
242     GSM->PlayTone(0,0);
243
244   }
245 }
246
247 /* One drawn key was released */
248 static gint KeyboardButtonRelease(GtkWidget *widget, GdkEvent *event, gpointer data)
249 {
250   KeyboardSetPixmap(FALSE);
251   
252   pressed = 0;
253
254   KeyboardSendTune();
255
256   return TRUE;
257 }
258
259 /* One drawn key was pressed */
260 static gint KeyboardButtonPress(GtkWidget *widget, GdkEvent *event, gpointer data)
261 {
262   GdkEventButton * e = (GdkEventButton *)event;
263   int i;
264
265   if (!pressed)
266   {
267     guint x = e->x;
268     guint y = e->y;
269     
270     if (y < 100) /* possible black pressed... */
271       for ( i = 0; i < WHITE_COUNT - 1; i++)
272         if (blacks[i] && x - 16 - 24 * i < 16)
273         {
274           pressed = i | BLACK_PRESSED;
275           KeyboardSetPixmap(TRUE);
276           KeyboardSendTune();
277           return TRUE;
278         }
279     for ( i = 0; i < WHITE_COUNT; i++) /* whites ? */
280       if (x - 24 * i < 24)
281       {
282         pressed = i | WHITE_PRESSED;
283         KeyboardSetPixmap(TRUE);
284         KeyboardSendTune();
285         return TRUE;
286       }
287   }
288   return TRUE;
289 }
290
291 void GUI_CreateRingtonesWindow (void)
292 {
293   int nMenuItems = sizeof (ringtonesMenuItems) / sizeof (ringtonesMenuItems[0]);
294   GtkAccelGroup *accelGroup;
295   GtkItemFactory *itemFactory;
296   GtkWidget *menuBar;
297   GtkWidget *vbox;
298   GtkWidget *hbox, *hbox2;
299   GtkWidget *melody;
300   GtkWidget *buttons, *buttons2;
301   GtkWidget *separator;
302   GtkWidget *toolBar;
303   GtkWidget *label, *note1, *note2, *note3, *note4, *note5;
304   GtkWidget *label2, *button, *button2, *button3, *button4, *button5,
305             *button6, *button7, *button8, *button9, *button10, *button11, *button12;
306   
307   GtkWidget *keyboard;  
308
309   int i;
310   
311   InitRingtonesMenu();
312
313   /* realize top level window for logos */
314   GUI_RingtonesWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
315   gtk_window_set_policy(GTK_WINDOW(GUI_RingtonesWindow),1,1,1);
316   gtk_window_set_title(GTK_WINDOW(GUI_RingtonesWindow),_("Ringtones"));
317   gtk_signal_connect(GTK_OBJECT(GUI_RingtonesWindow),"delete_event",
318                      GTK_SIGNAL_FUNC(DeleteEvent),NULL);
319   gtk_widget_set_usize(GUI_RingtonesWindow,630,320);
320   gtk_widget_realize(GUI_RingtonesWindow);
321
322   accelGroup = gtk_accel_group_new();
323   gtk_accel_group_attach(accelGroup,GTK_OBJECT(GUI_RingtonesWindow));
324
325   /* create main vbox */
326   vbox = gtk_vbox_new(FALSE,1);
327   gtk_container_add(GTK_CONTAINER(GUI_RingtonesWindow),vbox);
328   gtk_widget_show(vbox);
329
330   itemFactory = gtk_item_factory_new(GTK_TYPE_MENU_BAR,"<main>",accelGroup);
331   gtk_item_factory_create_items(itemFactory,nMenuItems,ringtonesMenuItems,NULL);
332   menuBar = gtk_item_factory_get_widget(itemFactory,"<main>");
333
334   gtk_box_pack_start(GTK_BOX(vbox),menuBar,FALSE,FALSE,0);
335   gtk_widget_show(menuBar);
336
337   /* toolbar */
338   toolBar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,GTK_TOOLBAR_ICONS);
339   gtk_toolbar_set_button_relief(GTK_TOOLBAR(toolBar),GTK_RELIEF_NORMAL);
340   gtk_toolbar_set_style(GTK_TOOLBAR(toolBar),GTK_TOOLBAR_ICONS);
341
342   gtk_toolbar_append_item(GTK_TOOLBAR(toolBar),NULL,"Set ringtone",NULL,
343                  NewPixmap(Send_xpm,GUI_RingtonesWindow->window,
344                  &GUI_RingtonesWindow->style->bg[GTK_STATE_NORMAL]),
345                  (GtkSignalFunc)NULL,toolBar);
346
347   gtk_box_pack_start(GTK_BOX(vbox),toolBar,FALSE,FALSE,0);
348   gtk_widget_show(toolBar);  
349
350   /* vertical separator */
351   separator = gtk_hseparator_new();
352   gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(separator),FALSE,FALSE,0);
353
354   /* Melody drawing area */  
355   melody = gtk_drawing_area_new();
356   gtk_drawing_area_size(GTK_DRAWING_AREA(melody), 20,100);
357     
358   gtk_box_pack_start(GTK_BOX(vbox),melody,FALSE,FALSE,0);
359   gtk_widget_show(melody);
360   
361   /* create horizontal box for keyboard and buttons area */
362   hbox = gtk_hbox_new(FALSE,5);
363   gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
364   gtk_widget_show(hbox);
365
366   /* Box for buttons */
367   hbox2 = gtk_hbox_new(FALSE,5);
368   gtk_box_pack_start(GTK_BOX(hbox),hbox2,FALSE,FALSE,0);
369   gtk_widget_set_usize( hbox2, 120, 160 );
370   gtk_widget_show(hbox2);
371
372   /* Buttons with notes length */
373   buttons = gtk_vbox_new(FALSE,3);
374   gtk_box_pack_start(GTK_BOX(hbox2),buttons,FALSE,FALSE,0);
375
376   label = gtk_label_new (_("Length"));
377   gtk_box_pack_start (GTK_BOX(buttons), label, FALSE, FALSE, 3);
378
379   note1 = gtk_radio_button_new_with_label (NULL, _("1"));
380   gtk_box_pack_end (GTK_BOX (buttons), note1, TRUE, FALSE, 2);
381   gtk_widget_show (note1);
382
383   note2 = gtk_radio_button_new_with_label (NULL, _("1/2"));
384   gtk_box_pack_end (GTK_BOX (buttons), note2, TRUE, FALSE, 2);
385   gtk_widget_show (note2);
386
387   note3 = gtk_radio_button_new_with_label (NULL, _("1/4"));
388   gtk_box_pack_end (GTK_BOX (buttons), note3, TRUE, FALSE, 2);
389   gtk_widget_show (note3);  
390   gtk_widget_show(buttons);
391
392   note4 = gtk_radio_button_new_with_label (NULL, _("1/16"));
393   gtk_box_pack_end (GTK_BOX (buttons), note4, TRUE, FALSE, 2);
394   gtk_widget_show (note4);
395
396   note5 = gtk_radio_button_new_with_label (NULL, _("1/32"));
397   gtk_box_pack_end (GTK_BOX (buttons), note5, TRUE, FALSE, 2);
398   gtk_widget_show (note5);
399   
400   gtk_widget_show (buttons);
401
402   /* Buttons with notes length */
403   buttons2 = gtk_vbox_new(FALSE,3);
404   gtk_box_pack_start(GTK_BOX(hbox2),buttons2,FALSE,FALSE,0);    
405
406   label2 = gtk_label_new (_("Note"));
407   gtk_box_pack_start (GTK_BOX(buttons2), label2, FALSE, FALSE, 3);
408
409   button = gtk_button_new_with_label (_("C"));
410   gtk_box_pack_start (GTK_BOX (buttons2), button, TRUE, FALSE, 0);
411 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
412 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
413 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
414 //  gtk_widget_grab_default (button);
415   gtk_widget_show (button);
416
417   button3 = gtk_button_new_with_label (_("D"));
418   gtk_box_pack_start (GTK_BOX (buttons2), button3, TRUE, FALSE, 0);
419 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
420 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
421 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
422 //  gtk_widget_grab_default (button3);
423   gtk_widget_show (button);
424
425   button5 = gtk_button_new_with_label (_("E"));
426   gtk_box_pack_start (GTK_BOX (buttons2), button5, TRUE, FALSE, 0);
427 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
428 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
429 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
430 //  gtk_widget_grab_default (button);
431   gtk_widget_show (button5);
432   
433   button6 = gtk_button_new_with_label (_("F"));
434   gtk_box_pack_start (GTK_BOX (buttons2), button6, TRUE, FALSE, 0);
435 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
436 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
437 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
438 //  gtk_widget_grab_default (button);
439   gtk_widget_show (button6);
440
441   button8 = gtk_button_new_with_label (_("G"));
442   gtk_box_pack_start (GTK_BOX (buttons2), button8, TRUE, FALSE, 0);
443 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
444 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
445 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
446 //  gtk_widget_grab_default (button);
447   gtk_widget_show (button8);
448   
449   button10 = gtk_button_new_with_label (_("A"));
450   gtk_box_pack_start (GTK_BOX (buttons2), button10, TRUE, FALSE, 0);
451 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
452 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
453 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
454 //  gtk_widget_grab_default (button);
455   gtk_widget_show (button10);
456   
457   button12 = gtk_button_new_with_label (_("H"));
458   gtk_box_pack_start (GTK_BOX (buttons2), button12, TRUE, FALSE, 0);
459 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
460 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
461 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
462 //  gtk_widget_grab_default (button);
463   gtk_widget_show (button12);
464   
465   gtk_widget_show (label2);
466       
467   button2 = gtk_button_new_with_label (_("Cis"));
468   gtk_box_pack_start (GTK_BOX (buttons2), button2, TRUE, FALSE, 0);
469 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
470 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
471 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
472 //  gtk_widget_grab_default (button);
473   gtk_widget_show (button2);  
474   
475   button4 = gtk_button_new_with_label (_("Dis"));
476   gtk_box_pack_start (GTK_BOX (buttons2), button4, TRUE, FALSE, 0);
477 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
478 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
479 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
480 //  gtk_widget_grab_default (button);
481   gtk_widget_show (button4);
482
483   button7 = gtk_button_new_with_label (_("Fis"));
484   gtk_box_pack_start (GTK_BOX (buttons2), button7, TRUE, FALSE, 0);
485 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
486 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
487 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
488 //  gtk_widget_grab_default (button);
489   gtk_widget_show (button7);  
490
491   button9 = gtk_button_new_with_label (_("Gis"));
492   gtk_box_pack_start (GTK_BOX (buttons2), button9, TRUE, FALSE, 0);
493 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
494 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
495 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
496 //  gtk_widget_grab_default (button);
497   gtk_widget_show (button9);
498
499   button11 = gtk_button_new_with_label (_("Ais"));
500   gtk_box_pack_start (GTK_BOX (buttons2), button11, TRUE, FALSE, 0);
501 //  gtk_signal_connect (GTK_OBJECT (button), "clicked",
502 //                      GTK_SIGNAL_FUNC (HideCallDialog), (gpointer) inCallDialog.dialog);
503 //  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
504 //  gtk_widget_grab_default (button);
505   gtk_widget_show (button11);
506   
507   gtk_widget_show (buttons2);
508   
509   /* Keyboard */
510   keyboard = gtk_fixed_new();
511   gtk_widget_set_usize( keyboard, 504, 160 );
512   gtk_box_pack_start(GTK_BOX(hbox),keyboard,FALSE,FALSE,0);
513
514   gtk_signal_connect(GTK_OBJECT (keyboard), "button_press_event",
515                       GTK_SIGNAL_FUNC (KeyboardButtonPress), &hbox);
516   gtk_signal_connect(GTK_OBJECT (keyboard), "button_release_event",
517                       GTK_SIGNAL_FUNC (KeyboardButtonRelease), &hbox);
518
519   gtk_widget_add_events(keyboard, GDK_FOCUS_CHANGE_MASK|
520                         GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK);
521   
522   KeyboardCreateBlackPixmap(hbox, &pam[KIE_BLACK], "333333", "666666", "999999");
523   KeyboardCreateBlackPixmap(hbox, &pam[KIE_BLACKSEL], "000000", "333333", "666666");
524
525   for (i = 0; i < 6; i += 2)
526   {
527     KeyboardCreateWhitePixmap(hbox, &pam[KIE_WHITEL + i],
528                               whitestarts[i / 2], "FFFFFF", "999999", "CCCCCC");
529     KeyboardCreateWhitePixmap(hbox, &pam[KIE_WHITELSEL + i],
530                               whitestarts[i / 2], "CCCCCC", "666666", "999999");
531   }
532   
533   for (i = 0; i < WHITE_COUNT - 1; i++)
534   {
535     PixmapAndMask * b = &pam[KIE_BLACK];
536     if (xwhi[i % 7] == 2) continue;
537     blacks[i] = gtk_pixmap_new( b->pixmap, b->mask );
538     gtk_fixed_put( GTK_FIXED(keyboard), blacks[i], 16 + 24 * i, 0 );
539   }
540
541   for (i = 0; i < WHITE_COUNT; i++)
542   {
543     int j = xwhi[i % 7];
544     whites[i] = gtk_pixmap_new( pam[j].pixmap, pam[j].mask );
545     gtk_fixed_put( GTK_FIXED(keyboard), whites[i], 24 * i, 0 );
546   }
547
548   gtk_widget_show(keyboard);
549 }
550
551 void GUI_ShowRingtonesWindow (void)
552 {
553   gtk_widget_show_all(GUI_RingtonesWindow);
554 }