This commit was generated by cvs2svn to compensate for changes in r164,
[gnokii.git] / xgnokii / xgnokii_logos.c
1 /*
2
3    $Id$
4    
5   X G N O K I I
6
7   A Linux/Unix GUI for Nokia mobile phones.
8   Copyright (C) 1999 Pavel Janík ml., Hugh Blemings
9   & Ján Derfiòák <ja@mail.upjs.sk>.
10
11   Released under the terms of the GNU GPL, see file COPYING for more details.
12
13    $Log$
14    Revision 1.1.1.5  2002/04/03 00:08:33  short
15    Found in "gnokii-working" directory, some November-patches version
16
17    Revision 1.9  2001/09/14 12:53:00  pkot
18    New preview logos.
19    Localization fixes.
20    Set valid operator on logos xgnokii screen.
21
22    Revision 1.8  2001/05/24 20:47:31  chris
23    More updating of 7110 code and some of xgnokii_lowlevel changed over.
24
25    Revision 1.7  2001/03/23 08:24:56  ja
26    New preview for 6210 in xgnokii's logos module.
27
28          
29 */
30           
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <fcntl.h>
34 #include <signal.h>
35 #include <sys/types.h>
36 #include <string.h>
37 #include <gtk/gtk.h>
38
39 #include "misc.h"
40 #include "gsm-common.h"
41 #include "gsm-api.h"
42 #include "cfgreader.h"
43 #include "gsm-networks.h"
44 #include "gsm-filetypes.h"
45 #include "gsm-bitmaps.h"
46
47 #include "xgnokii_logos.h"
48 #include "xgnokii_common.h"
49 #include "xgnokii_lowlevel.h"
50 #include "xgnokii.h"
51
52 #include "xpm/Operator_logo.xpm"
53 #include "xpm/Startup_logo.xpm"
54 #include "xpm/Caller_logo.xpm"
55
56 #include "xpm/Black_point.xpm"
57 #include "xpm/Green_point.xpm"
58 #include "xpm/Green_pixel.xpm"
59
60 #include "xpm/New.xpm"
61 #include "xpm/Send.xpm"
62 #include "xpm/SendSMS.xpm"
63 #include "xpm/Read.xpm"
64 #include "xpm/Open.xpm"
65 #include "xpm/Save.xpm"
66
67 #include "xpm/Edit_invert.xpm"
68 #include "xpm/Edit_flip_horizontal.xpm"
69 #include "xpm/Edit_flip_vertical.xpm"
70
71 #include "xpm/Tool_brush.xpm"
72 #include "xpm/Tool_line.xpm"
73 #include "xpm/Tool_rectangle.xpm"
74 #include "xpm/Tool_filled_rectangle.xpm"
75
76 extern GSM_Network GSM_Networks[];
77 extern GSM_Statemachine xgnokii_statemachine;   /* from xgnokii_lowlevel.c */
78
79 GtkWidget *GUI_LogosWindow;
80
81 ErrorDialog errorDialog = {NULL, NULL};
82 InfoDialog infoDialog = {NULL, NULL};
83
84 /* stuff for drawingArea */
85 GtkWidget *drawingArea = NULL;
86 GdkPixmap *drawingPixmap = NULL;
87 GdkPixmap *greenPointPixmap, *blackPointPixmap;
88 int drawingAreaWidth, drawingAreaHeight; /* in pixels */
89 int mouseButtonPushed = 0;
90
91 /* stuff for previewArea */
92 GtkWidget *previewArea = NULL;
93 GdkPixmap *previewPixmap = NULL;
94 GdkPixmap *greenPixelPixmap;
95 int previewPixmapWidth, previewPixmapHeight;
96 int previewAvailable = 1, showPreviewErrorDialog = 1;
97 int previewPixmapNumber = 0;
98
99 GSM_Bitmap bitmap, oldBitmap;
100 GSM_NetworkInfo networkInfo;
101
102 /* widgets for toolbar - some, need global variables */
103 GtkWidget *buttonStartup, *buttonOperator, *buttonCaller;
104 GtkWidget *networkCombo, *callerCombo;
105
106 int activeTool = TOOL_BRUSH;
107 int toolStartX, toolStartY, toolLastX, toolLastY;
108
109 /* tools for drawing */
110 static GtkWidget *buttonBrush, *buttonLine, *buttonRectangle;
111 static GtkWidget *buttonFilledRectangle;
112
113 /* Contains fileName for Export dialog. */
114 typedef struct {
115   gchar *fileName;
116 } ExportDialogData;
117
118 static ExportDialogData exportDialogData = {NULL};
119
120 GtkWidget *FileSelection;
121
122 static int callersGroupsInitialized = 0;
123
124 /* returns lowest number from three numbers */
125 int GetMinFrom3(int a, int b, int c) {
126   if (a > b) {
127     if (b > c)
128       return c;
129     else
130       return b;
131   } else {
132     if (a > c)
133       return c;
134     else
135       return a;    
136   }
137 }
138
139 /* returns highest number from three numbers */
140 int GetMaxFrom3(int a, int b, int c) {
141   if (a > b) {
142     if (c > a)
143       return c;
144     else
145       return a;
146   } else {
147     if (c > b)
148       return c;
149     else
150       return b;
151   }
152 }
153
154 /* load preview pixmap from file */
155 GdkPixmap *GetPreviewPixmap (GtkWidget *widget) {
156   GdkPixmap *pixmap;
157   GdkBitmap *mask;
158   gchar *file;
159
160   if (previewPixmapNumber == 0)
161   {
162     if (!strcmp (xgnokiiConfig.model, "6110") ||
163         !strcmp (xgnokiiConfig.model, "6120"))
164     {
165       file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
166                              "/xpm/Preview_6110.xpm");
167       previewPixmapNumber = 1;
168     }
169     else if (!strcmp (xgnokiiConfig.model, "6130") ||
170              !strcmp (xgnokiiConfig.model, "6150") ||
171              !strcmp (xgnokiiConfig.model, "616x") ||
172              !strcmp (xgnokiiConfig.model, "6185") ||
173              !strcmp (xgnokiiConfig.model, "6190"))
174     {
175       file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
176                              "/xpm/Preview_6150.xpm");
177       previewPixmapNumber = 2;
178     }
179     else if (!strcmp (xgnokiiConfig.model, "3210"))
180     {
181       file = g_strdup_printf("%s%s", xgnokiiConfig.xgnokiidir,
182                              "/xpm/Preview_3210.xpm");
183       previewPixmapNumber = 3;
184     }
185     else if (!strcmp (xgnokiiConfig.model, "3310") ||
186              !strcmp (xgnokiiConfig.model, "3330"))
187     {
188       file = g_strdup_printf("%s%s", xgnokiiConfig.xgnokiidir,
189                              "/xpm/Preview_3310.xpm");
190       previewPixmapNumber = 4;
191     }
192     else if (!strcmp (xgnokiiConfig.model, "5110") ||
193              !strcmp (xgnokiiConfig.model, "5130"))
194     {
195       file = g_strdup_printf("%s%s", xgnokiiConfig.xgnokiidir,
196                              "/xpm/Preview_5110.xpm");
197       previewPixmapNumber = 5;
198     }
199     else if (!strcmp (xgnokiiConfig.model, "6250"))
200     {
201       file = g_strdup_printf("%s%s", xgnokiiConfig.xgnokiidir,
202                              "/xpm/Preview_6250.xpm");
203       previewPixmapNumber = 6;
204     }
205     else if (!strcmp (xgnokiiConfig.model, "7110"))
206     {
207       file = g_strdup_printf("%s%s", xgnokiiConfig.xgnokiidir,
208                              "/xpm/Preview_7110.xpm");
209       previewPixmapNumber = 7;
210     }
211     else
212     {
213       file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
214                              "/xpm/Preview_6210.xpm");
215       previewPixmapNumber = 8;
216     }
217   }
218   else
219     switch (previewPixmapNumber)
220     {
221       case 1: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
222                                      "/xpm/Preview_6110.xpm"); 
223               break;
224       case 2: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
225                                      "/xpm/Preview_6150.xpm"); 
226               break;
227       case 3: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
228                                      "/xpm/Preview_3210.xpm"); 
229               break;
230       case 4: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
231                                      "/xpm/Preview_3310.xpm"); 
232               break;
233       case 5: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
234                                      "/xpm/Preview_5110.xpm"); 
235               break;
236       case 6: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
237                                      "/xpm/Preview_6250.xpm"); 
238               break;
239       case 7: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
240                                      "/xpm/Preview_7110.xpm"); 
241               break;
242       default: file = g_strdup_printf("%s%s",xgnokiiConfig.xgnokiidir,
243                                       "/xpm/Preview_6210.xpm");
244               break;
245     }
246
247   pixmap = gdk_pixmap_create_from_xpm(widget->window,&mask,
248                                       &widget->style->bg[GTK_STATE_NORMAL],
249                                       file);
250
251   g_free(file);
252
253   return pixmap;
254 }
255
256 /* ********************************************************
257  * ** SET/CLEAR POINTS ************************************
258  * ********************************************************
259  */
260 void SetPreviewPoint(GtkWidget *widget, int x, int y, int update) {
261   if (!previewAvailable) return;
262   
263   /* there is difference between positiong of startupLogo and others */
264   if (bitmap.type != GSM_StartupLogo) {
265     x += PREVIEWJUMPX;
266     y += PREVIEWJUMPY;
267   }
268
269   /* draw point to pixmap */
270   if (previewPixmap)
271     gdk_draw_point(previewPixmap,widget->style->black_gc,
272                    x+PREVIEWSTARTX,y+PREVIEWSTARTY);
273
274   if (update) {
275     GdkRectangle updateRect;
276
277     /* update point on screen */
278     updateRect.width = 1;
279     updateRect.height = 1;
280     updateRect.x = PREVIEWSTARTX+x;
281     updateRect.y = PREVIEWSTARTY+y;
282
283     gtk_widget_draw(previewArea,&updateRect);
284   }  
285 }
286
287 void ClearPreviewPoint(GtkWidget *widget, int x, int y, int update) {
288   if (!previewAvailable) return;
289   
290   /* there is difference between positiong of startupLogo and others */
291   if (bitmap.type != GSM_StartupLogo) {
292     x += PREVIEWJUMPX;
293     y += PREVIEWJUMPY;
294   }
295
296   /* clean point from pixmap - any idea how to draw green point without pixmap? */
297   if (previewPixmap)
298     gdk_draw_pixmap(previewPixmap,
299                     widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
300                     greenPixelPixmap,0,0,x+PREVIEWSTARTX,y+PREVIEWSTARTY,1,1);
301   if (update) {
302     GdkRectangle updateRect;
303
304     /* clean from screen too */
305     updateRect.width = 1;
306     updateRect.height = 1;
307     updateRect.x = PREVIEWSTARTX+x;
308     updateRect.y = PREVIEWSTARTY+y;
309
310     gtk_widget_draw(previewArea,&updateRect);
311   }
312 }
313
314 int IsPoint(int x, int y) {
315   return GSM_IsPointBitmap(&bitmap,x,y);
316 }
317
318 void SetPoint(GtkWidget *widget, int x, int y, int update) {
319   /* difference between settings points in startupLogo and others */
320   GSM_SetPointBitmap(&bitmap,x,y);
321
322   /* draw point to pixmap */
323   gdk_draw_pixmap(drawingPixmap,widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
324           blackPointPixmap,0,0,x*(POINTSIZE+1),y*(POINTSIZE+1),-1,-1);
325
326   if (update) {
327     GdkRectangle updateRect;
328
329     /* calculate update rectangle */
330     updateRect.width = POINTSIZE+2;
331     updateRect.height = POINTSIZE+2;
332     updateRect.x = x * (POINTSIZE+1);
333     updateRect.y = y * (POINTSIZE+1);
334
335     /* update on screen */
336     gtk_widget_draw(drawingArea,&updateRect);
337   }
338
339   /* draw preview point too */
340   if (previewAvailable) SetPreviewPoint(widget,x,y,update); 
341 }
342
343 void ClearPoint(GtkWidget *widget, int x, int y, int update) {
344   /* difference between settings points in startupLogo and others */
345   GSM_ClearPointBitmap(&bitmap,x,y);
346
347   /* clear point from pixmap */
348   gdk_draw_pixmap(drawingPixmap,widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
349           greenPointPixmap,0,0,x*(POINTSIZE+1),y*(POINTSIZE+1),-1,-1);
350
351   if (update) {
352     GdkRectangle updateRect;
353
354     /* calculate update rectangle */
355     updateRect.width = POINTSIZE+2;
356     updateRect.height = POINTSIZE+2;
357     updateRect.x = x * (POINTSIZE+1);
358     updateRect.y = y * (POINTSIZE+1);
359           
360     /* update on screen */
361     gtk_widget_draw(drawingArea,&updateRect);
362   }
363
364   /* clear point from previewArea too */
365   if (previewAvailable) ClearPreviewPoint(widget,x,y,update); 
366 }
367
368 /* ****************************************************
369  * *** UPDATES - PREVIEW & DRAWING AREAS **************
370  * ****************************************************
371  */
372
373 /* this redraw all logo points - preview & drawing area */
374 void UpdatePointsRectangle(GtkWidget *widget, int x1, int y1, int x2, int y2) {
375   GdkRectangle updateRect;
376   int x, y, dx = 0, dy = 0;
377
378   if (bitmap.type != GSM_StartupLogo) {
379     dx = PREVIEWJUMPX;
380     dy = PREVIEWJUMPY;
381   }
382
383   if (x1 > x2) {
384     x = x1;
385     x1 = x2;
386     x2 = x;
387   }
388
389   if (y1 > y2) {
390     y = y1;
391     y1 = y2;
392     y2 = y;
393   }
394   
395   for (y = y1;y <= y2;y++)
396     for (x = x1;x <= x2;x++) {
397       if (IsPoint(x,y)) {
398         /* set on drawing area */
399         gdk_draw_pixmap(drawingPixmap,
400                         drawingArea->style->fg_gc[GTK_WIDGET_STATE(drawingArea)],
401                         blackPointPixmap,0,0,x*(POINTSIZE+1),y*(POINTSIZE+1),-1,-1);
402
403         /* set on preview */
404         if (previewAvailable && previewPixmap) 
405           gdk_draw_point(previewPixmap,previewArea->style->black_gc,
406                          x+PREVIEWSTARTX+dx,y+PREVIEWSTARTY+dy);
407       } else {
408         /* clear from drawing */
409         gdk_draw_pixmap(drawingPixmap,
410                         drawingArea->style->fg_gc[GTK_WIDGET_STATE(drawingArea)],
411                         greenPointPixmap,0,0,x*(POINTSIZE+1),y*(POINTSIZE+1),-1,-1);
412
413         /* clear from preview */
414         if (previewAvailable && previewPixmap) 
415           gdk_draw_pixmap(previewPixmap,
416                           previewArea->style->fg_gc[GTK_WIDGET_STATE(previewArea)],
417                           greenPixelPixmap,0,0,x+PREVIEWSTARTX+dx,y+PREVIEWSTARTY+dy,
418                           1,1);
419       }
420     }
421      
422   if (previewAvailable) {  
423     updateRect.x = PREVIEWSTARTX+dx+x1;
424     updateRect.y = PREVIEWSTARTY+dy+y1;
425     updateRect.width = x2-x1+1;
426     updateRect.height = y2-y1+1;
427     gtk_widget_draw(previewArea,&updateRect);
428   }  
429
430   updateRect.x = x1*(POINTSIZE+1);
431   updateRect.y = y1*(POINTSIZE+1);
432   updateRect.width = (x2-x1+1)*(POINTSIZE+1)+1;
433   updateRect.height = (y2-y1+1)*(POINTSIZE+1)+1;
434   gtk_widget_draw(drawingArea,&updateRect); 
435 }
436
437 void UpdatePoints(GtkWidget *widget) {
438   UpdatePointsRectangle(widget,0,0,bitmap.width-1,bitmap.height-1);
439 }
440
441 /* this redraw all logo points in previewArea, NO DRAWING AREA */
442 void UpdatePreviewPoints (void) {
443   GdkRectangle updateRect;
444   int x, y, dx = 0, dy = 0;
445
446   if (!previewPixmap || !previewAvailable) return;  
447   
448   if (bitmap.type != GSM_StartupLogo) {
449     dx = PREVIEWJUMPX;
450     dy = PREVIEWJUMPY;
451   }
452
453   for (y = 0;y < bitmap.height;y++)
454     for (x = 0;x < bitmap.width;x++) {
455       if (IsPoint(x,y)) {
456         gdk_draw_point(previewPixmap,previewArea->style->black_gc,
457                        x+PREVIEWSTARTX+dx,y+PREVIEWSTARTY+dy);
458       } else {
459         gdk_draw_pixmap(previewPixmap,
460                         previewArea->style->fg_gc[GTK_WIDGET_STATE(previewArea)],
461                         greenPixelPixmap,0,0,
462                         x+PREVIEWSTARTX+dx,y+PREVIEWSTARTY+dy,1,1);
463       }
464     }
465               
466   updateRect.x = dx; 
467   updateRect.y = dy;
468   updateRect.width = bitmap.width;
469   updateRect.height = bitmap.height;
470   gtk_widget_draw(previewArea,&updateRect);
471 }
472
473 /* ******************************************************
474  * **** DRAWING TOOLS ***********************************
475  * ******************************************************
476  */
477
478 /* TOOL - BRUSH */
479 void ToolBrush(GtkWidget *widget, int column, int row, int button) {
480   /* only this tool directly update bitmap & screen */
481   if (button > 1) 
482     ClearPoint(widget,column,row,1);
483   else
484     SetPoint(widget,column,row,1);
485 }
486
487 /* TOOL - LINE */
488
489 /* this function clear or draw a line on the screen  USED BY TOOLLINEUPDATE */
490 void ToolLine(GtkWidget *widget, int x1, int y1, int x2, int y2, int draw) {
491         int udx, udy, dx, dy, error, loop, xadd, yadd;
492
493         dx = x2 - x1;  /* x delta */
494         dy = y2 - y1;  /* y delta */
495
496         udx = abs(dx); /* unsigned x delta */
497         udy = abs(dy); /* unsigned y delta */
498
499         if (dx < 0) { xadd = -1; } else { xadd = 1; } /* set directions */
500         if (dy < 0) { yadd = -1; } else { yadd = 1; }
501
502         error = 0;
503         loop = 0;
504         if (udx > udy) { /* delta X > delta Y */
505                 do {
506                         error += udy;
507
508                         if (error >= udx) {  /* is time to move up or down? */
509                                 error -= udx;
510                                 y1 += yadd;
511                         }
512                         loop++;
513                         if (draw == 1) {
514                                 SetPoint(widget,x1,y1,0);
515                         } else {
516                                 /* now clearing line before drawing new one, we must check */
517                                 /* if there is a point in oldBitmap which saves bitmap before */
518                                 /* we starting drawing new line */
519                                 if (!GSM_IsPointBitmap(&oldBitmap,x1,y1)) {
520                                         ClearPoint(widget,x1,y1,0);
521                                 }
522                         }
523                         x1 += xadd;         /* move horizontally */
524                 } while (loop < udx); /* repeat for x length */
525         } else {
526                 do {
527                         error += udx;
528                         if (error >= udy) {  /* is time to move left or right? */
529                                 error -= udy;
530                                 x1 += xadd;
531                         }
532                         loop++;
533                         if (draw == 1) {
534                                 SetPoint(widget,x1,y1,0);
535                         } else {
536                                 /* check comment in delta X > delta Y */
537                                 if (!GSM_IsPointBitmap(&oldBitmap,x1,y1)) {
538                                         ClearPoint(widget,x1,y1,0);
539                                 }
540                         }
541                         y1 += yadd;         /* move vertically */
542                 } while (loop < udy); /* repeat for y length */
543         }
544 }
545
546 /* going to rewrite to Bresenham algorithm */ 
547 void ToolLineUpdate(GtkWidget *widget, int column, int row) {
548         /* clear old line */
549         ToolLine(widget,toolStartX,toolStartY,toolLastX,toolLastY,0);
550         /* draw new one */
551         ToolLine(widget,toolStartX,toolStartY,column,row,1);
552 }
553
554 /* TOOL - FILLED RECT */
555
556 /* FIXME - going to rewrite for optimalized version, clearing and */
557 /*         drawing new parts only before clearing and drawing whole */
558 /*         filled rectangle - it's too slow on diskless terminal ;(( */
559 void ToolFilledRectangleUpdate(GtkWidget *widget, int column, int row) {
560   int i, j, x1, y1, x2, y2;
561
562         /* swap Xs to x1 < x2 */
563   if (toolStartX > toolLastX) {
564     x1 = toolLastX;
565     x2 = toolStartX;
566   } else {
567     x1 = toolStartX;
568     x2 = toolLastX;
569   }
570
571         /* swap Ys to y1 < y2 */
572   if (toolStartY > toolLastY) {
573     y1 = toolLastY;
574     y2 = toolStartY;
575   } else {
576     y1 = toolStartY;
577     y2 = toolLastY;
578   }
579
580         /* clear one now */
581   for (j = y1;j <= y2;j++)
582     for (i = x1;i <= x2;i++)
583       if (!GSM_IsPointBitmap(&oldBitmap,i,j)) ClearPoint(widget,i,j,0);
584
585         /* swap Xs to x1 < x2 */
586   if (toolStartX > column) {
587     x1 = column;
588     x2 = toolStartX;
589   } else {
590     x1 = toolStartX;
591     x2 = column;
592   }
593
594         /* swap Ys to y1 < y2 */
595   if (toolStartY > row) {
596     y1 = row;
597     y2 = toolStartY;
598   } else {
599     y1 = toolStartY;
600     y2 = row;
601   }
602
603         /* draw new one */
604   for (j = y1;j <= y2;j++)
605     for (i = x1;i <= x2;i++)
606       SetPoint(widget,i,j,0);
607 }
608
609 /* TOOL - RECTANGLE */
610 void ToolRectangleUpdate(GtkWidget *widget, int column, int row) {
611   int i, j, x1, y1, x2, y2;
612
613   /* clear old rectangle */
614         /* swap Xs to x1 < x2 */
615   if (toolStartX > toolLastX) {
616     x1 = toolLastX;
617     x2 = toolStartX;
618   } else {
619     x1 = toolStartX;
620     x2 = toolLastX;
621   }
622
623         /* swap Ys to y1 < y2 */
624   if (toolStartY > toolLastY) {
625     y1 = toolLastY;
626     y2 = toolStartY;
627   } else {
628     y1 = toolStartY;
629     y2 = toolLastY;
630   }
631
632         /* clear old one */
633   for (i = x1;i <= x2;i++) {
634     if (!GSM_IsPointBitmap(&oldBitmap,i,y1)) ClearPoint(widget,i,y1,0);
635     if (!GSM_IsPointBitmap(&oldBitmap,i,y2)) ClearPoint(widget,i,y2,0);                
636   }
637
638   for (j = y1;j <= y2;j++) {
639     if (!GSM_IsPointBitmap(&oldBitmap,x1,j)) ClearPoint(widget,x1,j,0);
640     if (!GSM_IsPointBitmap(&oldBitmap,x2,j)) ClearPoint(widget,x2,j,0);
641   }
642
643   /* draw new rectangle */
644         /* swap Xs to x1 < x2 */
645   if (toolStartX > column) {
646     x1 = column;
647     x2 = toolStartX;
648   } else {
649     x1 = toolStartX;
650     x2 = column;
651   }
652
653         /* swap Ys to y1 < y2 */
654   if (toolStartY > row) {
655     y1 = row;
656     y2 = toolStartY;
657   } else {
658     y1 = toolStartY;
659     y2 = row;
660   }
661
662         /* draw new one */
663   for (i = x1;i <= x2;i++) {
664     if (!IsPoint(i,y1)) SetPoint(widget,i,y1,0);
665     if (!IsPoint(i,y2)) SetPoint(widget,i,y2,0);
666   }
667
668   for (j = y1;j <= y2;j++) {
669     if (!IsPoint(x1,j)) SetPoint(widget,x1,j,0);
670     if (!IsPoint(x2,j)) SetPoint(widget,x2,j,0);
671   }
672 }
673
674 /* this update tools actions on the screen - this is for optimalization */
675 /* eg. for faster redrawing tools actions - we do not need redraw pixel */
676 /* by pixel. Faster is redraw whole rectangle which contains all changes */
677 void UpdateToolScreen(GtkWidget *widget, int x1, int y1, int x2, int y2) {
678   GdkRectangle updateRect;
679
680   /* update preview area */
681         if (previewAvailable) {
682           updateRect.x = PREVIEWSTARTX+x1;
683         updateRect.y = PREVIEWSTARTY+y1;
684           if (bitmap.type != GSM_StartupLogo) {
685           updateRect.x += PREVIEWJUMPX;
686             updateRect.y += PREVIEWJUMPY;
687         }
688           updateRect.width = x2-x1+1;
689         updateRect.height = y2-y1+1;
690         gtk_widget_draw(previewArea,&updateRect);
691         }
692
693   /* update drawing area */
694   updateRect.x = x1 * (POINTSIZE+1);
695   updateRect.y = y1 * (POINTSIZE+1);
696   updateRect.width = (x2-x1+1)*(POINTSIZE+2);
697   updateRect.height = (y2-y1+1)*(POINTSIZE+2);
698   gtk_widget_draw(drawingArea,&updateRect);
699 }
700
701 /* *************************************
702  * ** PREVIEW AREA EVENTS **************
703  * *************************************
704  */
705
706 gint PreviewAreaButtonPressEvent(GtkWidget *widget, GdkEventButton *event) {
707   previewPixmapNumber = (previewPixmapNumber % 8) + 1;
708
709   gtk_drawing_area_size(GTK_DRAWING_AREA(previewArea),
710                         previewPixmapWidth,previewPixmapHeight);
711
712   return TRUE;
713 }
714
715 gint PreviewAreaConfigureEvent(GtkWidget *widget, GdkEventConfigure *event) {
716   if (previewPixmap) gdk_pixmap_unref(previewPixmap);
717   previewPixmap = GetPreviewPixmap(widget);
718
719   UpdatePreviewPoints();
720         
721   return TRUE;
722 }
723
724 gint PreviewAreaExposeEvent(GtkWidget *widget, GdkEventExpose *event) {
725   /* got previewPixmap? */
726   if (previewPixmap)
727     /* yes - simply redraw some rectangle */      
728     gdk_draw_pixmap(widget->window,widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
729                     previewPixmap,event->area.x,event->area.y,event->area.x,
730                     event->area.y,event->area.width,event->area.height);
731
732   return FALSE;
733 }
734
735 /* ********************************
736  * ** DRAWING AREA EVENTS *********
737  * ********************************
738  */
739
740 gint DrawingAreaButtonPressEvent(GtkWidget *widget, GdkEventButton *event) {
741   /* got drawingPixmap? */
742   if (drawingPixmap == NULL) return TRUE;
743
744   if (!mouseButtonPushed) {
745     if ((event->button == 1 && activeTool != TOOL_BRUSH) || 
746         (activeTool == TOOL_BRUSH)) {
747       /* position from we starting drawing */
748       toolStartX = event->x / (POINTSIZE+1);
749       if (toolStartX < 0) toolStartX = 0;
750       if (toolStartX > bitmap.width-1) toolStartX = bitmap.width-1;
751     
752       toolStartY = event->y / (POINTSIZE+1);
753       if (toolStartY < 0) toolStartY = 0;
754       if (toolStartY > bitmap.height-1) toolStartY = bitmap.height-1;
755
756       toolLastX = toolStartX;
757       toolLastY = toolStartY;
758
759       /* store old bitmap for drawing, resp. for moving, resizing primitive */
760       memcpy(&oldBitmap,&bitmap,sizeof(oldBitmap));
761     }
762
763     if (event->button == 1) mouseButtonPushed = 1;
764   
765     switch (activeTool) { 
766       case TOOL_BRUSH:
767         ToolBrush(widget,toolStartX,toolStartY,event->button);
768         break;
769       case TOOL_LINE:
770       case TOOL_RECTANGLE:
771         if (event->button == 1) ToolBrush(widget,toolStartX,toolStartY,event->button);
772         break;
773     }
774   }
775
776   /* user is drawing some tool other than TOOL_BRUSH and pushed mouse button
777    * another than first => cancel tool and redraw to oldBitmap (bitmap when
778    * user start drawing)
779    */
780   if (mouseButtonPushed && activeTool != TOOL_BRUSH && event->button != 1) {
781     int lowestX, lowestY, highestX, highestY;
782     int i, j;
783
784     lowestX  = GetMinFrom3(toolStartX,toolLastX,toolLastX);
785     lowestY  = GetMinFrom3(toolStartY,toolLastY,toolLastY);
786     highestX = GetMaxFrom3(toolStartX,toolLastX,toolLastX);
787     highestY = GetMaxFrom3(toolStartY,toolLastY,toolLastY);
788
789     for (j = lowestY;j <= highestY;j++)
790       for (i = lowestX;i <= highestX;i++)
791         if (GSM_IsPointBitmap(&oldBitmap,i,j))
792           SetPoint(widget,i,j,0);
793         else
794           ClearPoint(widget,i,j,0);
795     UpdateToolScreen(widget,lowestX,lowestY,highestX,highestY);
796
797     mouseButtonPushed = 0;
798   }
799
800   return TRUE;
801 }
802
803 gint DrawingAreaButtonReleaseEvent(GtkWidget *widget, GdkEventButton *event) {
804   if (event->button == 1)
805     mouseButtonPushed = 0;
806
807   return TRUE;
808 }
809
810 gint DrawingAreaMotionNotifyEvent(GtkWidget *widget, GdkEventMotion *event) {
811   int x,y;
812   GdkModifierType state;
813   
814   if (!mouseButtonPushed && activeTool != TOOL_BRUSH) return TRUE;
815   
816   if (event->is_hint)
817     gdk_window_get_pointer(event->window,&x,&y,&state);
818   else {
819     x = event->x;
820     y = event->y;
821     state = event->state;
822   }
823
824   x = x / (POINTSIZE+1);
825   y = y / (POINTSIZE+1);
826   if (x < 0) x = 0;
827   if (y < 0) y = 0;
828   if (x > bitmap.width-1) x = bitmap.width-1;
829   if (y > bitmap.height-1) y = bitmap.height-1;
830
831   if (y == toolLastY && x == toolLastX) return TRUE;
832   
833   switch (activeTool) {
834     case TOOL_BRUSH:
835       if (state & GDK_BUTTON1_MASK && drawingPixmap != NULL) ToolBrush(widget,x,y,1);
836       if (state & GDK_BUTTON2_MASK && drawingPixmap != NULL) ToolBrush(widget,x,y,2);
837       if (state & GDK_BUTTON3_MASK && drawingPixmap != NULL) ToolBrush(widget,x,y,3);
838       break;
839     case TOOL_RECTANGLE:
840       if (drawingPixmap != NULL) ToolRectangleUpdate(widget,x,y);
841       break;
842     case TOOL_FILLED_RECTANGLE:
843       if (drawingPixmap != NULL) ToolFilledRectangleUpdate(widget,x,y); 
844       break; 
845     case TOOL_LINE:
846       if (drawingPixmap != NULL) ToolLineUpdate(widget,x,y); 
847       break; 
848   }   
849
850   /* what is this?
851    * it's simple, above tools updates only bitmap in memory and this
852    * function update from bitmap to screen, it's made as non-blinking
853    * drawing functions with this, simply draw everything we need and
854    * after that, redraw to screen rectangle in which we made changes 
855    * it's not redrawing pixel by pixel (blinking)
856    */
857   if (activeTool != TOOL_BRUSH) {
858     int lowestX, lowestY, highestX, highestY;
859
860     lowestX  = GetMinFrom3(toolStartX,toolLastX,x);
861     lowestY  = GetMinFrom3(toolStartY,toolLastY,y);
862     highestX = GetMaxFrom3(toolStartX,toolLastX,x);
863     highestY = GetMaxFrom3(toolStartY,toolLastY,y);
864   
865     UpdateToolScreen(widget,lowestX,lowestY,highestX,highestY);  
866   }
867
868   toolLastX = x;
869   toolLastY = y; 
870   return TRUE;  
871 }
872
873 /* configureEvent? -> event when someone resize windows, ... */
874 gint DrawingAreaConfigureEvent(GtkWidget *widget, GdkEventConfigure *event) {
875   int x, y;
876   /* got drawingPixmap? */
877   if (drawingPixmap) gdk_pixmap_unref(drawingPixmap); /* got, erase it */
878
879   /* make a new pixmap */
880   drawingPixmap = gdk_pixmap_new(widget->window,drawingAreaWidth,
881                   drawingAreaHeight,-1);
882
883   /* draw grid into pixmap */
884   for (y = 0;y < bitmap.height;y++)
885     for (x = 0;x < bitmap.width;x++)
886       if (IsPoint(x,y))
887         gdk_draw_pixmap(drawingPixmap,widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
888                         blackPointPixmap,0,0,x*(POINTSIZE+1),y*(POINTSIZE+1),-1,-1);
889       else
890         gdk_draw_pixmap(drawingPixmap,widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
891                         greenPointPixmap,0,0,x*(POINTSIZE+1),y*(POINTSIZE+1),-1,-1);
892   
893   return TRUE;
894 }
895
896 gint DrawingAreaExposeEvent(GtkWidget *widget, GdkEventExpose *event) {
897   /* got drawingPixmap? */
898   if (drawingPixmap)
899     /* got - draw it */
900     gdk_draw_pixmap(widget->window,widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
901                     drawingPixmap,
902                     event->area.x,event->area.y,event->area.x,event->area.y,
903                     event->area.width,event->area.height);
904   return FALSE; 
905 }
906
907 /* *****************************************
908  * ** TOOLBAR & MENU EVENTS ****************
909  * *****************************************
910  */
911
912 void GetNetworkInfoEvent(GtkWidget *widget) {
913   GSM_Error error;
914   PhoneEvent *e = (PhoneEvent *)g_malloc(sizeof(PhoneEvent));
915   D_NetworkInfo *data = (D_NetworkInfo *)g_malloc(sizeof(D_NetworkInfo));
916
917   /* prepare data for event */
918   data->info = &networkInfo;
919   e->event = Event_GetNetworkInfo;
920   e->data = data;
921
922   /* launch event and wait for result */
923   GUI_InsertEvent(e);
924   pthread_mutex_lock(&getNetworkInfoMutex);
925   pthread_cond_wait(&getNetworkInfoCond,&getNetworkInfoMutex);
926   pthread_mutex_unlock(&getNetworkInfoMutex);
927   error = data->status;
928   g_free(data);
929
930   /* watch for errors */
931   if (error != GE_NONE) {
932     gchar *buf = g_strdup_printf(_("Error getting network info\n(error=%d)"),error);
933     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
934     gtk_widget_show(errorDialog.dialog);
935     g_free(buf);
936   }
937
938   /* set new operator name to combo */
939   gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(networkCombo)->entry),
940                GSM_GetNetworkName(networkInfo.NetworkCode));
941 }
942
943 void GetLogoEvent(GtkWidget *widget) {
944   GSM_Error error;
945   int i;
946   PhoneEvent *e = (PhoneEvent *) g_malloc(sizeof(PhoneEvent));
947   D_Bitmap *data = (D_Bitmap *)g_malloc(sizeof(D_Bitmap));
948   char *operator = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(networkCombo)->entry));
949
950   /* prepare data for event */
951   strncpy(bitmap.netcode,GSM_GetNetworkCode(operator),7);
952   data->bitmap = &bitmap;
953   e->event = Event_GetBitmap;
954   e->data = data;
955   if (phoneMonitor.supported & PM_CALLERGROUP) {
956     for (i = 0;i < 6;i++) 
957       if (strcmp(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(callerCombo)->entry)),
958                  xgnokiiConfig.callerGroups[i]) == 0) bitmap.number = i; 
959   }
960
961   /* launch event and wait for result */
962   GUI_InsertEvent(e);
963   pthread_mutex_lock(&getBitmapMutex);
964   pthread_cond_wait(&getBitmapCond,&getBitmapMutex);
965   pthread_mutex_unlock(&getBitmapMutex);
966   error = data->status;
967   g_free(data);
968
969   /* watch for errors */
970   if (error != GE_NONE) {
971     gchar *buf = g_strdup_printf(_("Error getting bitmap\n(error=%d)"),error);
972     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
973     gtk_widget_show(errorDialog.dialog);
974     g_free(buf);
975   } else {
976     /* no error, draw logo from phone */
977     UpdatePoints(drawingArea);
978   }
979 }
980
981 void SetLogoEvent(GtkWidget *widget) {
982   GSM_Error error;
983   PhoneEvent *e = (PhoneEvent *)g_malloc(sizeof(PhoneEvent));
984   D_Bitmap *data = (D_Bitmap *)g_malloc(sizeof(D_Bitmap));
985   char *operator = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(networkCombo)->entry));
986   int i;
987
988   /* prepare data */
989   strncpy(bitmap.netcode,GSM_GetNetworkCode(operator),7);
990  
991   if (bitmap.type == GSM_CallerLogo) {
992     /* above condition must be there, because if you launch logos before
993      * callerGroups are available, you will see segfault - callerGroups not initialized 
994      */
995     if (phoneMonitor.supported & PM_CALLERGROUP) {
996       for (i = 0;i < 6;i++) 
997         if (strcmp(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(callerCombo)->entry)),
998                    xgnokiiConfig.callerGroups[i]) == 0) bitmap.number = i; 
999     }  
1000   }
1001   
1002   data->bitmap = &bitmap;
1003   e->event = Event_SetBitmap;
1004   e->data = data;
1005
1006   /* launch event and wait for result */
1007   GUI_InsertEvent(e);
1008   pthread_mutex_lock(&setBitmapMutex);
1009   pthread_cond_wait(&setBitmapCond,&setBitmapMutex);
1010   pthread_mutex_unlock(&setBitmapMutex);
1011   error = data->status;
1012   g_free(data);
1013
1014   /* watch for errors */
1015   if (error != GE_NONE) {
1016     gchar *buf = g_strdup_printf(_("Error setting bitmap\n(error=%d)"),error);
1017     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
1018     gtk_widget_show(errorDialog.dialog);
1019     g_free(buf);
1020   }
1021 }
1022
1023 typedef struct {
1024   GtkWidget *dialog;
1025   GtkWidget *entry;
1026 } SendLogoDialog;
1027 static SendLogoDialog sendLogoDialog = {NULL, NULL};
1028
1029 static void OkSendLogoDialog(GtkWidget *w, gpointer gtkdata)
1030 {
1031   GSM_SMSMessage SMS;
1032   GSM_Error error;
1033
1034   char Data[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1035
1036   PhoneEvent *e = (PhoneEvent *)g_malloc(sizeof(PhoneEvent));
1037   D_SMSMessage *data = (D_SMSMessage *)g_malloc(sizeof(D_SMSMessage));
1038   char *number = gtk_entry_get_text(GTK_ENTRY(sendLogoDialog.entry));
1039   char *operator = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(networkCombo)->entry));
1040   char *opcode = GSM_GetNetworkCode(operator);
1041   int i;
1042
1043   int current=0;
1044
1045   /* Default settings for SMS message:
1046      - no delivery report
1047      - Class Message 1
1048      - no compression
1049      - 8 bit data
1050      - SMSC no. 1
1051      - validity 3 days
1052      - set UserDataHeaderIndicator
1053   */
1054
1055   SMS.Type = GST_MO;
1056   SMS.Class = 1;
1057   SMS.Compression = false;
1058   SMS.EightBit = true;
1059   SMS.MessageCenter = xgnokiiConfig.smsSetting[0];      /* we need to at least set .Format ! */
1060   SMS.MessageCenter.No = 0;
1061   SMS.Validity = 4320; /* 4320 minutes == 72 hours */
1062   SMS_SetupUDH(&SMS,bitmap.type);
1063
1064   /* prepare data */
1065  
1066   switch (bitmap.type) {
1067
1068   case GSM_CallerLogo:
1069     /* below condition must be there, because if you launch logos before
1070      * callerGroups are available, you will see segfault - callerGroups not initialized 
1071      */
1072     if (phoneMonitor.supported & PM_CALLERGROUP) {
1073       for (i = 0;i < 6;i++) 
1074         if (strcmp(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(callerCombo)->entry)),
1075                    xgnokiiConfig.callerGroups[i]) == 0) bitmap.number = i; 
1076     }  
1077     break;
1078
1079   case GSM_OperatorLogo:
1080     opcode=GSM_GetNetworkCode(operator);
1081     Data[current++] = ((opcode[1] & 0x0f) << 4) | (opcode[0] & 0xf);
1082     Data[current++] = 0xf0 | (opcode[2] & 0x0f);
1083     Data[current++] = ((opcode[5] & 0x0f) << 4) | (opcode[4] & 0xf);
1084     break;
1085
1086   default: /* unsupported */
1087     g_free(e);
1088     g_free(data);
1089     return;
1090   }
1091
1092   strncpy(SMS.Destination,number,sizeof(SMS.Destination));
1093   SMS.Destination[sizeof(SMS.Destination)-1]='\0';
1094   
1095   /* Set the logo size */
1096   current++;
1097   Data[current++] = bitmap.width;
1098   Data[current++] = bitmap.height;
1099
1100   Data[current++] = 0x01;
1101
1102   memcpy(SMS.MessageText,Data,current);
1103   memcpy(SMS.MessageText+current,bitmap.bitmap,bitmap.size);
1104   SMS.MessageTextLength = current+bitmap.size;
1105
1106   data->sms = &SMS;
1107   e->event = Event_SendSMSMessage;
1108   e->data = data;
1109
1110   /* launch event and wait for result */
1111   GUI_InsertEvent(e);
1112   pthread_mutex_lock (&sendSMSMutex);
1113   pthread_cond_wait (&sendSMSCond, &sendSMSMutex);
1114   pthread_mutex_unlock (&sendSMSMutex);
1115   error = data->status;
1116   g_free(data);
1117
1118   /* watch for errors */
1119   if (error != GE_SMSSENDOK) {
1120     gchar *buf = g_strdup_printf(_("Error sending bitmap\n(error=%d)"),error);
1121     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
1122     gtk_widget_show(errorDialog.dialog);
1123     g_free(buf);
1124   }
1125
1126   gtk_widget_hide (((SendLogoDialog *) gtkdata)->dialog);
1127 }
1128
1129 /* Here would be appropriate xgnokii_sms/ShowSelectContactsDialog()
1130  * (and the multi-recipient handling code).
1131  * I haven't implemented yet any such code as the whole XGnokii has broken
1132  * design of hand-coded GTK+ GUI (even w/o any Gnome features) instead of Glade.
1133  * The right solution is to drop 95% of XGNokii code, not to write yet another
1134  * insane +2% of hand-coded GUI code.
1135  */
1136 void SendLogoEvent(GtkWidget *widget)
1137 {
1138   if (sendLogoDialog.dialog == NULL)
1139   {
1140     GtkWidget *button, *label;
1141
1142     sendLogoDialog.dialog = gtk_dialog_new ();
1143     gtk_window_set_title (GTK_WINDOW (sendLogoDialog.dialog), _("Send logo"));
1144     gtk_window_set_modal(GTK_WINDOW (sendLogoDialog.dialog), TRUE);
1145     gtk_container_set_border_width (GTK_CONTAINER (sendLogoDialog.dialog), 10);
1146     gtk_signal_connect (GTK_OBJECT (sendLogoDialog.dialog), "delete_event",
1147                         GTK_SIGNAL_FUNC (DeleteEvent), NULL);
1148
1149     button = gtk_button_new_with_label (_("Send"));
1150     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (sendLogoDialog.dialog)->action_area),
1151                         button, TRUE, TRUE, 10);
1152     gtk_signal_connect (GTK_OBJECT (button), "clicked",
1153                         GTK_SIGNAL_FUNC (OkSendLogoDialog), (gpointer) &sendLogoDialog);
1154     GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1155     gtk_widget_grab_default (button);
1156     gtk_widget_show (button);
1157
1158     button = gtk_button_new_with_label (_("Cancel"));
1159     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (sendLogoDialog.dialog)->action_area),
1160                         button, TRUE, TRUE, 10);
1161     gtk_signal_connect (GTK_OBJECT (button), "clicked",
1162                         GTK_SIGNAL_FUNC (CancelDialog), (gpointer) sendLogoDialog.dialog);
1163     gtk_widget_show (button);
1164
1165     gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (sendLogoDialog.dialog)->vbox), 5);
1166
1167     label = gtk_label_new (_("Number:"));
1168     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (sendLogoDialog.dialog)->vbox), label, FALSE, FALSE, 5);
1169     gtk_widget_show (label);
1170
1171     sendLogoDialog.entry = gtk_entry_new_with_max_length (GSM_MAX_PHONEBOOK_NUMBER_LENGTH);
1172     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (sendLogoDialog.dialog)->vbox), sendLogoDialog.entry, FALSE, FALSE, 5);
1173     gtk_widget_show (sendLogoDialog.entry);
1174   }
1175
1176   gtk_entry_set_text (GTK_ENTRY (sendLogoDialog.entry), "");
1177
1178   gtk_widget_show (sendLogoDialog.dialog);  
1179 }
1180
1181 static void ClearLogoEvent(GtkWidget *widget) {
1182   
1183   //  bitmap.size=bitmap.width*bitmap.height/8;
1184   
1185   GSM_ClearBitmap(&bitmap);
1186
1187   UpdatePoints(widget);
1188 }
1189
1190 void InvertLogoEvent(GtkWidget *widget) {
1191   int column, row;
1192
1193   for (column = 0;column < bitmap.width;column++)
1194     for (row = 0;row < bitmap.height;row++)
1195       if (IsPoint(column,row))
1196         GSM_ClearPointBitmap(&bitmap,column,row);
1197       else
1198         GSM_SetPointBitmap(&bitmap,column,row);
1199
1200   UpdatePoints(widget);
1201 }
1202
1203 void UpLogoEvent(GtkWidget *widget) {
1204   int column, row;
1205
1206   GSM_Bitmap tbitmap;
1207   
1208   memcpy(&tbitmap,&bitmap,sizeof(GSM_Bitmap));
1209   
1210   for (row = 0;row < bitmap.height-1;row++)
1211     for (column = 0;column < bitmap.width;column++)
1212       if (IsPoint(column,row+1))
1213         GSM_SetPointBitmap(&bitmap,column,row);
1214       else
1215         GSM_ClearPointBitmap(&bitmap,column,row);
1216
1217   for (column = 0;column < bitmap.width;column++)
1218     if (GSM_IsPointBitmap(&tbitmap,column,0))
1219       GSM_SetPointBitmap(&bitmap,column,bitmap.height-1);
1220     else
1221       GSM_ClearPointBitmap(&bitmap,column,bitmap.height-1);    
1222
1223   UpdatePoints(widget); 
1224 }
1225
1226 void DownLogoEvent(GtkWidget *widget) {
1227   int column, row;
1228
1229   GSM_Bitmap tbitmap;
1230   
1231   memcpy(&tbitmap,&bitmap,sizeof(GSM_Bitmap));
1232
1233   for (row = bitmap.height-1;row > 0;row--)
1234     for (column = 0;column < bitmap.width;column++)
1235       if (IsPoint(column,row-1))
1236         GSM_SetPointBitmap(&bitmap,column,row);
1237       else
1238         GSM_ClearPointBitmap(&bitmap,column,row);
1239
1240   for (column = 0;column < bitmap.width;column++)
1241     if (GSM_IsPointBitmap(&tbitmap,column,bitmap.height-1))
1242       GSM_SetPointBitmap(&bitmap,column,0);
1243     else
1244       GSM_ClearPointBitmap(&bitmap,column,0);
1245
1246   UpdatePoints(widget);
1247 }
1248
1249 void LeftLogoEvent(GtkWidget *widget) {
1250   int column, row;
1251
1252   GSM_Bitmap tbitmap;
1253   
1254   memcpy(&tbitmap,&bitmap,sizeof(GSM_Bitmap));
1255
1256   for (column = 0; column < bitmap.width-1;column++)
1257     for (row = 0;row < bitmap.height;row++)
1258       if (IsPoint(column+1,row))
1259         GSM_SetPointBitmap(&bitmap,column,row);
1260       else
1261         GSM_ClearPointBitmap(&bitmap,column,row);
1262
1263   for (row = 0;row < bitmap.height;row++)
1264     if (GSM_IsPointBitmap(&tbitmap,0,row))
1265       GSM_SetPointBitmap(&bitmap,bitmap.width-1,row);
1266     else
1267       GSM_ClearPointBitmap(&bitmap,bitmap.width-1,row);
1268
1269   UpdatePoints(widget);
1270 }
1271
1272 void RightLogoEvent(GtkWidget *widget) {
1273   int column, row;
1274
1275   GSM_Bitmap tbitmap;
1276   
1277   memcpy(&tbitmap,&bitmap,sizeof(GSM_Bitmap));
1278
1279   for (column = bitmap.width-1;column > 0;column--)
1280     for (row = 0;row < bitmap.height;row++)
1281       if (IsPoint(column-1,row))
1282         GSM_SetPointBitmap(&bitmap,column,row);
1283       else
1284         GSM_ClearPointBitmap(&bitmap,column,row);
1285
1286   for (row = 0;row < bitmap.height;row++)
1287     if (GSM_IsPointBitmap(&tbitmap,bitmap.width-1,row))
1288       GSM_SetPointBitmap(&bitmap,0,row);
1289     else
1290       GSM_ClearPointBitmap(&bitmap,0,row);
1291
1292   UpdatePoints(widget);
1293 }
1294
1295 void FlipVerticalLogoEvent(GtkWidget *widget) {
1296   int row, column, temp;
1297
1298   for (row = 0;row < (bitmap.height/2);row++)
1299     for (column = 0;column < bitmap.width;column++) {
1300       temp = IsPoint(column,row);
1301       if (IsPoint(column,bitmap.height-1-row))
1302         GSM_SetPointBitmap(&bitmap,column,row);
1303       else
1304         GSM_ClearPointBitmap(&bitmap,column,row);
1305
1306       if (temp)
1307         GSM_SetPointBitmap(&bitmap,column,bitmap.height-1-row);
1308       else
1309         GSM_ClearPointBitmap(&bitmap,column,bitmap.height-1-row);
1310     }
1311
1312   UpdatePoints(widget);
1313 }
1314
1315 void FlipHorizontalLogoEvent(GtkWidget *widget) {
1316   int row, column, temp;
1317
1318   for (row = 0;row < bitmap.height;row++)
1319     for (column = 0;column < (bitmap.width/2);column++) {
1320       temp = IsPoint(column,row);
1321
1322       if (IsPoint(bitmap.width-1-column,row))
1323         GSM_SetPointBitmap(&bitmap,column,row);
1324       else
1325         GSM_ClearPointBitmap(&bitmap,column,row);
1326
1327       if (temp)
1328         GSM_SetPointBitmap(&bitmap,bitmap.width-1-column,row);
1329       else
1330         GSM_ClearPointBitmap(&bitmap,bitmap.width-1-column,row);
1331     }
1332
1333   UpdatePoints(widget);
1334
1335
1336 /* this is launched when tool was changed */
1337 gint ToolTypeEvent(GtkWidget *widget) {
1338   if (GTK_TOGGLE_BUTTON(buttonBrush)->active) activeTool = TOOL_BRUSH; else
1339   if (GTK_TOGGLE_BUTTON(buttonLine)->active) activeTool = TOOL_LINE; else
1340   if (GTK_TOGGLE_BUTTON(buttonRectangle)->active) activeTool = TOOL_RECTANGLE; else
1341   if (GTK_TOGGLE_BUTTON(buttonFilledRectangle)->active)
1342     activeTool = TOOL_FILLED_RECTANGLE;
1343
1344   return 0;
1345 }
1346
1347 /* this is launched when logo type was change by buttons on toolbar */
1348 gint LogoTypeEvent(GtkWidget *widget) {
1349   int clear = 0;
1350
1351   /* is startupLogo? */
1352   /* Resize and clear anyway - CK */
1353   if (GTK_TOGGLE_BUTTON(buttonStartup)->active) {
1354     /* look for old bitmap type, clean if another */
1355     clear = 1;
1356     GSM_ResizeBitmap(&bitmap,GSM_StartupLogo, &xgnokii_statemachine.Phone.Info);
1357   }
1358
1359   /* has phone support for callerGroups? */
1360   if (phoneMonitor.supported & PM_CALLERGROUP) {
1361     if (GTK_TOGGLE_BUTTON(buttonCaller)->active && bitmap.type != GSM_CallerLogo) {
1362       /* previous was startup? clear and draw batteries, signal, ... */      
1363             /* Clear anyway for 7110...CK */
1364       clear = 1;
1365       GSM_ResizeBitmap(&bitmap,GSM_CallerLogo, &xgnokii_statemachine.Phone.Info);
1366     }
1367   }
1368
1369   /* is new type operatorLogo? */
1370   if (GTK_TOGGLE_BUTTON(buttonOperator)->active && bitmap.type != GSM_OperatorLogo) {
1371     /* previous startup? clear and draw batteries, signal, ... */      
1372           /* Clear anyway for 7110..CK */
1373     clear = 1;
1374     GSM_ResizeBitmap(&bitmap,GSM_OperatorLogo, &xgnokii_statemachine.Phone.Info);
1375   }
1376
1377   /* must clear? */
1378   if (clear) {
1379     if (previewAvailable) {
1380       /* configure event reload pixmap from disk and redraws */
1381       gtk_drawing_area_size(GTK_DRAWING_AREA(previewArea),
1382                             previewPixmapWidth,previewPixmapHeight);
1383     }   
1384
1385     /* change new drawingArea size */
1386     drawingAreaWidth = bitmap.width * (POINTSIZE+1)+1;
1387     drawingAreaHeight = bitmap.height * (POINTSIZE+1)+1;
1388
1389     gtk_drawing_area_size(GTK_DRAWING_AREA(drawingArea),
1390                           drawingAreaWidth,drawingAreaHeight);
1391   }
1392
1393   return 0;
1394 }
1395
1396 inline void CloseLogosWindow (void) {
1397   gtk_widget_hide(GUI_LogosWindow);
1398 }
1399
1400 void ExportLogoFileMain(gchar *name)
1401 {
1402   GSM_Bitmap tbitmap;
1403   GSM_Error error;
1404   
1405   tbitmap=bitmap;
1406
1407   strncpy(tbitmap.netcode,GSM_GetNetworkCode(networkInfo.NetworkCode),7);
1408
1409   error=GSM_SaveBitmapFile(name,&tbitmap);
1410   if (error!=GE_NONE) {
1411     gchar *buf = g_strdup_printf(_("Error saving file\n(error=%d)"),error);
1412     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
1413     gtk_widget_show(errorDialog.dialog);
1414     g_free(buf);
1415   }
1416 }
1417
1418 static void YesLogoFileExportDialog (GtkWidget *w, gpointer data)
1419 {
1420   gtk_widget_hide (GTK_WIDGET (data));
1421   ExportLogoFileMain(exportDialogData.fileName);
1422 }
1423
1424 static void ExportFileSelected (GtkWidget *w, GtkFileSelection *fs)
1425 {
1426   static YesNoDialog dialog = { NULL, NULL};
1427   FILE *f;
1428   gchar err[80];
1429
1430   exportDialogData.fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
1431   gtk_widget_hide (GTK_WIDGET (fs));
1432
1433   if ((f = fopen (exportDialogData.fileName, "r")) != NULL)
1434   {
1435     fclose (f);
1436     if (dialog.dialog == NULL)
1437     {
1438       CreateYesNoDialog (&dialog, YesLogoFileExportDialog, CancelDialog, GUI_LogosWindow);
1439       gtk_window_set_title (GTK_WINDOW (dialog.dialog), _("Overwrite file?"));
1440       g_snprintf ( err, 80, _("File %s already exist.\nOverwrite?"), exportDialogData.fileName); 
1441       gtk_label_set_text (GTK_LABEL(dialog.text), err);
1442     }
1443     gtk_widget_show (dialog.dialog);
1444   }
1445   else
1446     ExportLogoFileMain(exportDialogData.fileName);
1447 }
1448
1449 void ImportFileSelected(GtkWidget *w, GtkFileSelection *fs)
1450 {
1451   GSM_Bitmap tbitmap;
1452   GSM_Error error=0;
1453   
1454   gchar *fileName;
1455   FILE *f;
1456
1457   fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
1458   gtk_widget_hide (GTK_WIDGET (fs));
1459
1460   if ((f = fopen (fileName, "r")) == NULL) {
1461     gchar *buf = g_strdup_printf(_("Can't open file %s for reading !"),fileName);
1462     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
1463     gtk_widget_show(errorDialog.dialog);
1464     g_free(buf);
1465     return;
1466   } else fclose(f);
1467
1468   error=GSM_ReadBitmapFile(fileName,&tbitmap);
1469   if (error!=GE_NONE) {
1470     gchar *buf = g_strdup_printf(_("Error reading file\n(error=%d)"),error);
1471     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
1472     gtk_widget_show(errorDialog.dialog);
1473     g_free(buf);
1474     return;
1475   }
1476
1477   exportDialogData.fileName=fileName;
1478   
1479   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(buttonStartup),false);
1480   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(buttonOperator),false);
1481   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(buttonCaller),false);
1482   
1483   if (tbitmap.type==GSM_OperatorLogo) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(buttonOperator),true);
1484   if (tbitmap.type==GSM_StartupLogo) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(buttonStartup),true);
1485   if (tbitmap.type==GSM_CallerLogo) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(buttonCaller),true);
1486   
1487   memcpy(&bitmap,&tbitmap,sizeof(GSM_Bitmap));
1488   
1489   UpdatePoints(drawingArea);
1490 }
1491
1492 void SaveLogoAs(GtkWidget *widget)
1493 {
1494   FileSelection=gtk_file_selection_new (_("Save logo as ..."));
1495
1496   gtk_signal_connect (
1497         GTK_OBJECT (GTK_FILE_SELECTION (FileSelection)->ok_button),
1498         "clicked", (GtkSignalFunc) ExportFileSelected, FileSelection);
1499     
1500   gtk_signal_connect_object (
1501         GTK_OBJECT(GTK_FILE_SELECTION(FileSelection)->cancel_button),
1502         "clicked", (GtkSignalFunc) gtk_widget_destroy,
1503         GTK_OBJECT (FileSelection));
1504     
1505   gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(FileSelection));
1506
1507   gtk_widget_show(FileSelection);
1508 }
1509
1510 void SaveLogo(GtkWidget *widget)
1511 {
1512   if (exportDialogData.fileName==NULL) {
1513     SaveLogoAs(widget);
1514   } else {
1515     ExportLogoFileMain(exportDialogData.fileName);
1516   }
1517 }
1518
1519 void OpenLogo(GtkWidget *widget)
1520 {
1521   FileSelection=gtk_file_selection_new (_("Open logo..."));
1522
1523   gtk_signal_connect (
1524         GTK_OBJECT (GTK_FILE_SELECTION (FileSelection)->ok_button),
1525         "clicked", (GtkSignalFunc) ImportFileSelected, FileSelection);
1526     
1527   gtk_signal_connect_object (
1528         GTK_OBJECT(GTK_FILE_SELECTION(FileSelection)->cancel_button),
1529         "clicked", (GtkSignalFunc) gtk_widget_destroy,
1530         GTK_OBJECT (FileSelection));
1531     
1532   gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(FileSelection));
1533
1534   gtk_widget_show(FileSelection);
1535 }
1536
1537 static GtkItemFactoryEntry logosMenuItems[] = {
1538   { NULL,       NULL,           NULL,                    0, "<Branch>"},
1539   { NULL,       "<control>O",   OpenLogo,                0, NULL},
1540   { NULL,       "<control>S",   SaveLogo,                0, NULL},
1541   { NULL,       NULL,           SaveLogoAs,              0, NULL},
1542   { NULL,       NULL,           NULL,                    0, "<Separator>"},
1543   { NULL,       "<control>G",   GetNetworkInfoEvent,     0, NULL},
1544   { NULL,       NULL,           GetLogoEvent,            0, NULL},
1545   { NULL,       "<control>T",   SetLogoEvent,            0, NULL},
1546   { NULL,       "<control>N",   SendLogoEvent,           0, NULL},
1547   { NULL,       NULL,           NULL,                    0, "<Separator>"},
1548   { NULL,       "<control>W",   CloseLogosWindow,        0, NULL},
1549   { NULL,       NULL,           NULL,                    0, "<Branch>"},
1550   { NULL,       "<control>C",   ClearLogoEvent,          0, NULL},
1551   { NULL,       "<control>I",   InvertLogoEvent,         0, NULL},
1552   { NULL,       NULL,           NULL,                    0, "<Separator>"},
1553   { NULL,       "<control>U",   UpLogoEvent,             0, NULL},
1554   { NULL,       "<control>D",   DownLogoEvent,           0, NULL},
1555   { NULL,       "<control>L",   LeftLogoEvent,           0, NULL},
1556   { NULL,       "<control>R",   RightLogoEvent,          0, NULL},
1557   { NULL,       NULL,           NULL,                    0, "<Separator>"},
1558   { NULL,       "<control>H",   FlipHorizontalLogoEvent, 0, NULL},
1559   { NULL,       "<control>V",   FlipVerticalLogoEvent,   0, NULL},
1560 };
1561
1562 void InitLogosMenu (void) {
1563  logosMenuItems[0].path = g_strdup(_("/_File"));
1564  logosMenuItems[1].path = g_strdup(_("/File/_Open"));
1565  logosMenuItems[2].path = g_strdup(_("/File/_Save"));
1566  logosMenuItems[3].path = g_strdup(_("/File/Save _as ..."));
1567  logosMenuItems[4].path = g_strdup(_("/File/Sep1"));
1568  logosMenuItems[5].path = g_strdup(_("/File/_Get operator"));
1569  logosMenuItems[6].path = g_strdup(_("/File/Get _logo"));
1570  logosMenuItems[7].path = g_strdup(_("/File/Se_t logo"));
1571  logosMenuItems[8].path = g_strdup(_("/File/Se_nd logo"));
1572  logosMenuItems[9].path = g_strdup(_("/File/Sep2"));
1573  logosMenuItems[10].path = g_strdup(_("/File/_Close"));
1574  logosMenuItems[11].path = g_strdup(_("/_Edit"));
1575  logosMenuItems[12].path = g_strdup(_("/Edit/_Clear"));
1576  logosMenuItems[13].path = g_strdup(_("/Edit/_Invert"));
1577  logosMenuItems[14].path = g_strdup(_("/Edit/Sep3"));
1578  logosMenuItems[15].path = g_strdup(_("/Edit/_Up logo"));
1579  logosMenuItems[16].path = g_strdup(_("/Edit/_Down logo"));
1580  logosMenuItems[17].path = g_strdup(_("/Edit/_Left logo"));
1581  logosMenuItems[18].path = g_strdup(_("/Edit/_Right logo"));
1582  logosMenuItems[19].path = g_strdup(_("/Edit/Sep4"));
1583  logosMenuItems[20].path = g_strdup(_("/Edit/Flip _horizontal"));
1584  logosMenuItems[21].path = g_strdup(_("/Edit/Flip _vertical"));
1585 }
1586
1587 void GUI_CreateLogosWindow (void) {
1588   int nMenuItems = sizeof (logosMenuItems) / sizeof (logosMenuItems[0]);
1589   GtkAccelGroup *accelGroup;
1590   GtkItemFactory *itemFactory;
1591   GtkWidget *menuBar;
1592   GtkWidget *toolBar, *vertToolBar;
1593   GtkWidget *vbox;
1594   GtkWidget *hbox;
1595   GtkWidget *drawingBox;
1596   GtkWidget *separator;
1597   GdkBitmap *mask;
1598
1599   GList *glistNetwork = NULL;
1600
1601   int i = 0;
1602  
1603   previewPixmapWidth = PREVIEWWIDTH;
1604   previewPixmapHeight = PREVIEWHEIGHT;
1605   
1606   InitLogosMenu();
1607
1608   /* realize top level window for logos */
1609   GUI_LogosWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1610   gtk_window_set_wmclass(GTK_WINDOW(GUI_LogosWindow), "LogosWindow", "Xgnokii");
1611   gtk_window_set_policy(GTK_WINDOW(GUI_LogosWindow), 1, 1, 1);
1612   gtk_window_set_title(GTK_WINDOW(GUI_LogosWindow), _("Logos"));
1613   gtk_signal_connect(GTK_OBJECT(GUI_LogosWindow), "delete_event",
1614                      GTK_SIGNAL_FUNC(DeleteEvent), NULL);
1615   gtk_widget_realize(GUI_LogosWindow);
1616
1617   CreateErrorDialog(&errorDialog, GUI_LogosWindow);
1618   CreateInfoDialog(&infoDialog, GUI_LogosWindow);
1619
1620   accelGroup = gtk_accel_group_new();
1621   gtk_accel_group_attach(accelGroup, GTK_OBJECT(GUI_LogosWindow));
1622   
1623   /* create main vbox */
1624   vbox = gtk_vbox_new(FALSE, 1);
1625   gtk_container_add(GTK_CONTAINER(GUI_LogosWindow), vbox);
1626   gtk_widget_show(vbox);
1627  
1628   itemFactory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accelGroup);
1629   gtk_item_factory_create_items(itemFactory, nMenuItems, logosMenuItems, NULL);
1630   menuBar = gtk_item_factory_get_widget(itemFactory, "<main>");
1631
1632   gtk_box_pack_start(GTK_BOX(vbox), menuBar, FALSE, FALSE, 0);
1633   gtk_widget_show(menuBar);
1634
1635   /* toolbar */
1636   toolBar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
1637   gtk_toolbar_set_button_relief(GTK_TOOLBAR(toolBar), GTK_RELIEF_NORMAL);
1638   gtk_toolbar_set_style(GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS);
1639
1640   gtk_toolbar_append_item(GTK_TOOLBAR(toolBar), NULL, _("Clear logo"), NULL,
1641                   NewPixmap(New_xpm, GUI_LogosWindow->window,
1642                   &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1643                   (GtkSignalFunc)ClearLogoEvent, toolBar);
1644
1645   gtk_toolbar_append_space(GTK_TOOLBAR(toolBar));
1646
1647   gtk_toolbar_append_item(GTK_TOOLBAR(toolBar), NULL, _("Get logo"), NULL,
1648                  NewPixmap(Read_xpm, GUI_LogosWindow->window,
1649                  &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1650                  (GtkSignalFunc)GetLogoEvent, toolBar);
1651
1652   gtk_toolbar_append_item(GTK_TOOLBAR(toolBar), NULL, _("Set logo"), NULL,
1653                  NewPixmap(Send_xpm, GUI_LogosWindow->window,
1654                  &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1655                  (GtkSignalFunc)SetLogoEvent, toolBar);
1656
1657   gtk_toolbar_append_item(GTK_TOOLBAR(toolBar), NULL, _("Send logo"), NULL,
1658                  NewPixmap(SendSMS_xpm, GUI_LogosWindow->window,
1659                  &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1660                  (GtkSignalFunc)SendLogoEvent, toolBar);
1661
1662   gtk_toolbar_append_space(GTK_TOOLBAR(toolBar));
1663
1664   gtk_toolbar_append_item (GTK_TOOLBAR (toolBar), NULL, _("Import from file"), NULL,
1665                            NewPixmap(Open_xpm, GUI_LogosWindow->window,
1666                            &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1667                            (GtkSignalFunc) OpenLogo, NULL);
1668   gtk_toolbar_append_item (GTK_TOOLBAR (toolBar), NULL, _("Export to file"), NULL,
1669                            NewPixmap(Save_xpm, GUI_LogosWindow->window,
1670                            &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1671                            (GtkSignalFunc) SaveLogo, NULL);
1672
1673   gtk_toolbar_append_space (GTK_TOOLBAR (toolBar));
1674
1675   buttonStartup = gtk_toolbar_append_element(GTK_TOOLBAR(toolBar),
1676                   GTK_TOOLBAR_CHILD_RADIOBUTTON, NULL, NULL, _("Startup logo"),
1677                   "", NewPixmap(Startup_logo_xpm, GUI_LogosWindow->window,
1678                   &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1679                   GTK_SIGNAL_FUNC(LogoTypeEvent), NULL);
1680
1681   buttonOperator = gtk_toolbar_append_element(GTK_TOOLBAR(toolBar),
1682                   GTK_TOOLBAR_CHILD_RADIOBUTTON, buttonStartup, NULL, _("Operator logo"),
1683                   "", NewPixmap(Operator_logo_xpm, GUI_LogosWindow->window,
1684                   &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1685                   GTK_SIGNAL_FUNC(LogoTypeEvent), NULL);
1686
1687   buttonCaller = gtk_toolbar_append_element(GTK_TOOLBAR(toolBar),
1688                  GTK_TOOLBAR_CHILD_RADIOBUTTON,
1689                  buttonOperator,
1690                  NULL, _("Caller logo"),
1691                  "", NewPixmap(Caller_logo_xpm, GUI_LogosWindow->window,
1692                  &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1693                  GTK_SIGNAL_FUNC(LogoTypeEvent), NULL);
1694
1695   gtk_toolbar_append_space(GTK_TOOLBAR(toolBar));
1696   
1697   networkCombo = gtk_combo_new();
1698   gtk_combo_set_use_arrows_always(GTK_COMBO(networkCombo), 1);
1699   while (strcmp(GSM_Networks[i].Name, "unknown"))
1700     glistNetwork = g_list_insert_sorted(glistNetwork, GSM_Networks[i++].Name,
1701                    (GCompareFunc)strcmp);
1702   gtk_combo_set_popdown_strings(GTK_COMBO(networkCombo), glistNetwork);
1703   gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(networkCombo)->entry), FALSE);
1704   gtk_toolbar_append_widget(GTK_TOOLBAR(toolBar), networkCombo, "", "");
1705   gtk_widget_show(networkCombo);
1706   g_list_free(glistNetwork);
1707
1708   callerCombo = gtk_combo_new();
1709   gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(callerCombo)->entry), FALSE);
1710   gtk_toolbar_append_widget(GTK_TOOLBAR(toolBar), callerCombo, "", "");
1711   gtk_widget_show(callerCombo);
1712   
1713   gtk_box_pack_start(GTK_BOX(vbox), toolBar, FALSE, FALSE, 0);
1714   gtk_widget_show(toolBar); 
1715
1716   /* vertical separator */
1717   separator = gtk_hseparator_new();
1718   gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(separator),FALSE,FALSE,0);
1719   
1720   /* create horizontal box for preview and drawing areas */
1721   hbox = gtk_hbox_new(FALSE,5);
1722   gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
1723   gtk_widget_show(hbox);
1724  
1725   /* set GSM_Bitmap width,height needed for creating drawinArea
1726    * we are starting, default is startupLogo
1727    */
1728   bitmap.type = GSM_StartupLogo;
1729   bitmap.height = 48;
1730   bitmap.width = 84;
1731   bitmap.size = bitmap.height * bitmap.width / 8;
1732   drawingAreaWidth = bitmap.width * (POINTSIZE+1)+1;
1733   drawingAreaHeight = bitmap.height * (POINTSIZE+1)+1;
1734  
1735   /* previewArea */
1736   previewPixmap = GetPreviewPixmap(GUI_LogosWindow);
1737
1738   if (previewPixmap != NULL) {
1739     previewArea = gtk_drawing_area_new();
1740     gtk_drawing_area_size(GTK_DRAWING_AREA(previewArea),
1741                           previewPixmapWidth,previewPixmapHeight);
1742     
1743     greenPixelPixmap = gdk_pixmap_create_from_xpm_d(GUI_LogosWindow->window,
1744                        &mask,&GUI_LogosWindow->style->bg[GTK_STATE_NORMAL],
1745                        Green_pixel_xpm);
1746
1747     gtk_signal_connect(GTK_OBJECT(previewArea),"expose_event",
1748                        (GtkSignalFunc)PreviewAreaExposeEvent,NULL);
1749     gtk_signal_connect(GTK_OBJECT(previewArea),"configure_event",
1750                        (GtkSignalFunc)PreviewAreaConfigureEvent,NULL);
1751     gtk_signal_connect(GTK_OBJECT(previewArea),"button_press_event",
1752                        (GtkSignalFunc)PreviewAreaButtonPressEvent,NULL);
1753
1754     gtk_widget_set_events(previewArea,GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK );
1755
1756     gtk_box_pack_start(GTK_BOX(hbox),previewArea,FALSE,FALSE,0);
1757     gtk_widget_show(previewArea);
1758     
1759     /* clear battery, signal, menu & names from preview phone */
1760     UpdatePreviewPoints (); 
1761
1762   } else previewAvailable = 0;
1763
1764   /* drawingArea */
1765   greenPointPixmap = gdk_pixmap_create_from_xpm_d(GUI_LogosWindow->window,
1766                   &mask,&GUI_LogosWindow->style->bg[GTK_STATE_NORMAL],Green_point_xpm);
1767   blackPointPixmap = gdk_pixmap_create_from_xpm_d(GUI_LogosWindow->window,
1768                   &mask,&GUI_LogosWindow->style->bg[GTK_STATE_NORMAL],Black_point_xpm);
1769   
1770   drawingBox = gtk_vbox_new(FALSE,3);
1771   gtk_box_pack_start(GTK_BOX(hbox),drawingBox,FALSE,FALSE,0);
1772   gtk_widget_show(drawingBox);
1773
1774   drawingArea = gtk_drawing_area_new();
1775   gtk_drawing_area_size(GTK_DRAWING_AREA(drawingArea),
1776                   drawingAreaWidth,drawingAreaHeight);
1777
1778   gtk_signal_connect(GTK_OBJECT(drawingArea),"configure_event",
1779                   (GtkSignalFunc)DrawingAreaConfigureEvent,NULL);
1780   gtk_signal_connect(GTK_OBJECT(drawingArea),"expose_event",
1781                   (GtkSignalFunc)DrawingAreaExposeEvent,NULL);
1782   gtk_signal_connect(GTK_OBJECT(drawingArea),"button_press_event",
1783                   (GtkSignalFunc)DrawingAreaButtonPressEvent,NULL);
1784   gtk_signal_connect(GTK_OBJECT(drawingArea),"button_release_event",
1785                   (GtkSignalFunc)DrawingAreaButtonReleaseEvent,NULL);
1786   gtk_signal_connect(GTK_OBJECT(drawingArea),"motion_notify_event",
1787                   (GtkSignalFunc)DrawingAreaMotionNotifyEvent,NULL);
1788   
1789   gtk_widget_set_events(drawingArea,GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK |
1790                   GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | 
1791                   GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
1792
1793   gtk_box_pack_start(GTK_BOX(drawingBox),drawingArea,FALSE,FALSE,0);
1794   gtk_widget_show(drawingArea);
1795
1796   /* vertical tool bar */
1797   vertToolBar = gtk_toolbar_new(GTK_ORIENTATION_VERTICAL,GTK_TOOLBAR_ICONS);
1798   gtk_toolbar_set_button_relief(GTK_TOOLBAR(vertToolBar),GTK_RELIEF_NORMAL);
1799   gtk_toolbar_set_style(GTK_TOOLBAR(vertToolBar),GTK_TOOLBAR_ICONS);
1800
1801   buttonBrush = gtk_toolbar_append_element(GTK_TOOLBAR(vertToolBar),
1802                 GTK_TOOLBAR_CHILD_RADIOBUTTON, NULL, NULL, _("Brush tool"),
1803                 "", NewPixmap(Tool_brush_xpm, GUI_LogosWindow->window,
1804                 &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1805                 GTK_SIGNAL_FUNC(ToolTypeEvent), NULL);
1806
1807   buttonLine = gtk_toolbar_append_element(GTK_TOOLBAR(vertToolBar),
1808                GTK_TOOLBAR_CHILD_RADIOBUTTON, buttonBrush, NULL, _("Line tool"),
1809                "", NewPixmap(Tool_line_xpm, GUI_LogosWindow->window,
1810                &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1811                GTK_SIGNAL_FUNC(ToolTypeEvent), NULL);
1812
1813   buttonRectangle = gtk_toolbar_append_element(GTK_TOOLBAR(vertToolBar),
1814                     GTK_TOOLBAR_CHILD_RADIOBUTTON, buttonLine, NULL, _("Rectangle tool"),
1815                     "", NewPixmap(Tool_rectangle_xpm, GUI_LogosWindow->window,
1816                     &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1817                     GTK_SIGNAL_FUNC(ToolTypeEvent), NULL);
1818
1819   buttonFilledRectangle = gtk_toolbar_append_element(GTK_TOOLBAR(vertToolBar),
1820                           GTK_TOOLBAR_CHILD_RADIOBUTTON, buttonRectangle, NULL,
1821                           _("Filled rectangle tool"),
1822                           "", NewPixmap(Tool_filled_rectangle_xpm,
1823                           GUI_LogosWindow->window,
1824                           &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1825                           GTK_SIGNAL_FUNC(ToolTypeEvent), NULL);
1826
1827   gtk_toolbar_append_space(GTK_TOOLBAR(vertToolBar));
1828  
1829   gtk_toolbar_append_item(GTK_TOOLBAR(vertToolBar), NULL, _("Invert logo"), NULL,
1830                           NewPixmap(Edit_invert_xpm, GUI_LogosWindow->window,
1831                           &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1832                           (GtkSignalFunc)InvertLogoEvent, vertToolBar);
1833
1834   gtk_toolbar_append_item(GTK_TOOLBAR(vertToolBar), NULL, _("Horizontal flip"), NULL,
1835                           NewPixmap(Edit_flip_horizontal_xpm, GUI_LogosWindow->window,
1836                           &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1837                           (GtkSignalFunc)FlipHorizontalLogoEvent, vertToolBar);
1838
1839   gtk_toolbar_append_item(GTK_TOOLBAR(vertToolBar), NULL, _("Vertical flip"), NULL,
1840                           NewPixmap(Edit_flip_vertical_xpm, GUI_LogosWindow->window,
1841                           &GUI_LogosWindow->style->bg[GTK_STATE_NORMAL]),
1842                           (GtkSignalFunc)FlipVerticalLogoEvent, vertToolBar);
1843
1844   
1845   gtk_box_pack_start(GTK_BOX(hbox),vertToolBar,FALSE,FALSE,0);
1846   gtk_widget_show(vertToolBar);
1847
1848   GUIEventAdd(GUI_EVENT_CALLERS_GROUPS_CHANGED,&GUI_RefreshLogosGroupsCombo);
1849 }
1850
1851 void GUI_RefreshLogosGroupsCombo (void) {
1852   GList *callerList = NULL;
1853   int i;
1854   
1855   for (i = 0;i < 6;i++)
1856     callerList = g_list_insert(callerList,xgnokiiConfig.callerGroups[i],i);
1857   
1858   gtk_combo_set_popdown_strings(GTK_COMBO(callerCombo),callerList);
1859   g_list_free(callerList);
1860
1861   if (!callersGroupsInitialized) callersGroupsInitialized = 1;
1862 }
1863
1864 void GUI_ShowLogosWindow (void) {
1865   /* Set network name taken from the phone */
1866   GetNetworkInfoEvent(NULL);
1867   /* if phone support caller groups, read callerGroups names */
1868   if (phoneMonitor.supported & PM_CALLERGROUP) {
1869     if (xgnokiiConfig.callerGroups[0] == NULL) {
1870       GUI_Refresh(); 
1871       GUI_InitCallerGroupsInf ();
1872     }
1873     if (!callersGroupsInitialized) GUI_RefreshLogosGroupsCombo (); 
1874     gtk_widget_show(buttonCaller);
1875     gtk_widget_show(callerCombo); 
1876   } else {
1877     /* if not supported, hide widget for handling callerGroups */
1878     gtk_widget_hide(buttonCaller);
1879     gtk_widget_hide(callerCombo); 
1880   }        
1881
1882   /* Call to reset Startup logo size */
1883   LogoTypeEvent(GUI_LogosWindow);
1884
1885   gtk_widget_show(GUI_LogosWindow);
1886
1887   if (!previewAvailable && showPreviewErrorDialog) {
1888     gchar *buf = g_strdup(_("Load preview pixmap error, feature disabled."));
1889     gtk_label_set_text(GTK_LABEL(errorDialog.text),buf);
1890     gtk_widget_show(errorDialog.dialog);
1891     g_free(buf);
1892
1893     showPreviewErrorDialog = 0;
1894   }
1895 }