1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/tgisdl.c,v 1.15 2011/05/16 16:22:00 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_TGISDL_C_
22 
23 #include "tgifdefs.h"
24 #include "tidget.h"
25 
26 #include "auxtext.e"
27 #include "dialog.e"
28 #include "file.e"
29 #include "font.e"
30 #include "mainloop.e"
31 #include "msg.e"
32 #include "names.e"
33 #include "raster.e"
34 #include "setup.e"
35 #include "strtbl.e"
36 #include "tdgtbase.e"
37 #include "tdgtbrow.e"
38 #include "tdgtbtn.e"
39 #include "tdgtdraw.e"
40 #include "text.e"
41 #include "tidget.e"
42 #include "tgisdl.e"
43 #include "util.e"
44 
45 InsertSymbolInfo gInsertSymbolInfo;
46 
47 typedef struct tagInsertSymbolDlgInfo {
48    Window parent_win; /* should be the rootWindow */
49 
50    TdgtDraw *sym_pixmap_ctl; /* user pick HS values here */
51    TdgtBtnRow *btn_row_ctl;
52 
53    int screen_w, screen_h;
54    int base_win_w, base_win_h;
55 
56    int sym_x, sym_y;
57 
58    int btn_row_x, btn_row_y, btn_row_w, btn_row_h;
59 
60    char *title_str, *formatted_title_str;
61    int def_btn_id;
62 
63    int sym_pixmap_x, sym_pixmap_y, v_pixmap_x, v_pixmap_y;
64 
65    unsigned char r, g, b;
66    int h, s, v; /* 0 <= h,s,v <= 255 */
67    int pixel;
68    char color_str[40];
69 
70    TrueColorInfo tci;
71 } InsertSymbolDlgInfo;
72 
73 /* --------------------- Utility Functions --------------------- */
74 
75 #define TDGTARG_INSSYM_DPY_CLEAR 1 /* pv_cmd_userdata is NULL */
76 
77 static
ClearAllControls(pTdgtBase)78 void ClearAllControls(pTdgtBase)
79    TdgtBase *pTdgtBase;
80 {
81    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
82 
83    TidgetSendCmd(pisdi->sym_pixmap_ctl->pti, TDGTCMD_DRAW_USER,
84          TDGTARG_INSSYM_DPY_CLEAR, pTdgtBase);
85 }
86 
87 static
InsertSymbolGetSelectedChar()88 char InsertSymbolGetSelectedChar()
89 {
90    int row=gInsertSymbolInfo.selected_row, col=gInsertSymbolInfo.selected_col;
91    int index=0;
92 
93    if (!gInsertSymbolInfo.something_selected) return '\0';
94 
95    if (row > 6) {
96       index = 0xa0 + ((row-7)<<4) + col;
97    } else {
98       index = 0x20 + (row<<4) + col;
99    }
100    return (char)(((unsigned int)index) & 0x0ff);
101 }
102 
103 static
InsertSymbolInAppl(pTdgtBase)104 int InsertSymbolInAppl(pTdgtBase)
105    TdgtBase *pTdgtBase;
106 {
107    char buf[3];
108 
109    buf[0] = InsertSymbolGetSelectedChar();
110    buf[1] = buf[2] = '\0';
111    HandleInputFromBuffer(buf);
112 
113    return TRUE;
114 }
115 
116 static
InsertSymbolToggleSelected(pTdgtDraw)117 void InsertSymbolToggleSelected(pTdgtDraw)
118    TdgtDraw *pTdgtDraw;
119 {
120    int x=windowPadding+TDGTBASE_DEF_H_PAD-1;
121    int y=windowPadding+TDGTBASE_DEF_V_PAD-1;
122 
123    x += (gInsertSymbolInfo.a_symbol_w+1)*gInsertSymbolInfo.selected_col;
124    y += (gInsertSymbolInfo.a_symbol_h+1)*gInsertSymbolInfo.selected_row;
125 
126    XFillRectangle(mainDisplay, pTdgtDraw->pti->tci.win, revDefaultGC,
127          x, y, gInsertSymbolInfo.a_symbol_w, gInsertSymbolInfo.a_symbol_h);
128 }
129 
130 static
InsertSymbolSelectedValid(row,col)131 int InsertSymbolSelectedValid(row, col)
132    int row, col;
133 {
134    if (row >= TGIS_ROWS || col >= TGIS_COLS || row == 6) return FALSE;
135 
136    if (row == 0 && col == 0) return FALSE;
137    if (row == 5 && col == 15) return FALSE;
138    if (row == 12 && col == 0) return FALSE;
139    if (row == 12 && col == 15) return FALSE;
140 
141    return TRUE;
142 }
143 
144 /* --------------------- Focus Stuff --------------------- */
145 
146 static
InsertSymbolDlgRemoveFocus(pTdgtBase)147 void InsertSymbolDlgRemoveFocus(pTdgtBase)
148    TdgtBase *pTdgtBase;
149 {
150    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
151    Window win=TidgetGetFocusWindow();
152 
153    if (win == None) return;
154    if (win == pisdi->sym_pixmap_ctl->pti->tci.win) {
155       TidgetDrawFocusRect(pisdi->sym_pixmap_ctl->pti,
156             &pisdi->sym_pixmap_ctl->client_area);
157    }
158 }
159 
160 /* --------------------- HSRedrawCallback --------------------- */
161 
162 static
SetupControls(pTdgtBase)163 void SetupControls(pTdgtBase)
164    TdgtBase *pTdgtBase;
165 {
166 }
167 
168 static
RedrawInsertSymbolPixmapControlValues(pTdgtBase)169 void RedrawInsertSymbolPixmapControlValues(pTdgtBase)
170    TdgtBase *pTdgtBase;
171 {
172    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
173 
174    RedrawTidget(pisdi->sym_pixmap_ctl->pti);
175 }
176 
177 #define SKIP_NONE      0x0
178 #define SKIP_HS_PIXMAP 0x1
179 #define SKIP_V_PIXMAP  0x2
180 
181 static
RedrawControls(pTdgtBase,skip)182 void RedrawControls(pTdgtBase, skip)
183    TdgtBase *pTdgtBase;
184    int skip;
185 {
186    if ((skip & SKIP_HS_PIXMAP) != SKIP_HS_PIXMAP) {
187       RedrawInsertSymbolPixmapControlValues(pTdgtBase);
188    }
189 }
190 
191 static
HSRedrawCallback(pTdgtDraw)192 int HSRedrawCallback(pTdgtDraw)
193    TdgtDraw *pTdgtDraw;
194 {
195    TdgtBase *pTdgtBase=NULL;
196 
197    if (pTdgtDraw == NULL) return FALSE;
198    pTdgtBase = (TdgtBase*)(pTdgtDraw->pti->tci.parent_tidgetinfo->tidget);
199 
200    XCopyArea(mainDisplay, gInsertSymbolInfo.sym_pixmap, pTdgtDraw->pti->tci.win,
201          gTidgetManager.gc, 0, 0, pTdgtDraw->client_area.w,
202          pTdgtDraw->client_area.h, pTdgtDraw->client_area.x,
203          pTdgtDraw->client_area.y);
204    if (gInsertSymbolInfo.something_selected) {
205       InsertSymbolToggleSelected(pTdgtDraw);
206    }
207    if (TidgetGetFocusWindow() == pTdgtDraw->pti->tci.win) {
208       TidgetDrawFocusRect(pTdgtDraw->pti, &pTdgtDraw->client_area);
209    }
210    TidgetManagerResetGC();
211 
212    return TRUE;
213 }
214 
215 /* --------------------- HSEvHandlerCallback() --------------------- */
216 
217 static
GetRowCol(x,y,pn_row,pn_col)218 int GetRowCol(x, y, pn_row, pn_col)
219    int x, y, *pn_row, *pn_col;
220 {
221    int row=0, col=0;
222 
223    x -= (windowPadding+TDGTBASE_DEF_H_PAD-1);
224    y -= (windowPadding+TDGTBASE_DEF_V_PAD-1);
225 
226    if (x < 0 || y < 0) return FALSE;
227 
228    row = (int)(y / (gInsertSymbolInfo.a_symbol_h+1));
229    col = (int)(x / (gInsertSymbolInfo.a_symbol_w+1));
230 
231    if (!InsertSymbolSelectedValid(row, col)) {
232       return FALSE;
233    }
234    *pn_row = row;
235    *pn_col = col;
236 
237    return TRUE;
238 }
239 
240 static
ClickInInsertSymbolPixmap(pTdgtDraw,button_ev)241 int ClickInInsertSymbolPixmap(pTdgtDraw, button_ev)
242    TdgtDraw *pTdgtDraw;
243    XButtonEvent *button_ev;
244 {
245    TdgtBase *pTdgtBase=
246          (TdgtBase*)(pTdgtDraw->pti->tci.parent_tidgetinfo->tidget);
247    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
248    int x=button_ev->x, y=button_ev->y;
249    int on_a_symbol=FALSE, row=0, col=0, changed=FALSE;
250    int double_clicked=FALSE;
251    Time click_time=button_ev->time;
252 
253    if (TidgetGetFocusWindow() == pTdgtDraw->pti->tci.win) {
254       /* no need to change focus */
255    } else {
256       /* change focus */
257       TidgetSendCmd(pTdgtBase->pti, TDGTCMD_REMOVE_FOCUS, 0, NULL);
258       TidgetSetFocusWindow(pTdgtDraw->pti->tci.win);
259    }
260    on_a_symbol = GetRowCol(x, y, &row, &col);
261    if (gInsertSymbolInfo.something_selected) {
262       if (on_a_symbol) {
263          if (row == gInsertSymbolInfo.selected_row &&
264                col == gInsertSymbolInfo.selected_col) {
265             /* clicked on the same symbol */
266             double_clicked = ((click_time-gInsertSymbolInfo.last_click_time) <
267                   doubleClickInterval);
268          } else {
269             InsertSymbolToggleSelected(pisdi->sym_pixmap_ctl);
270             gInsertSymbolInfo.selected_row = row;
271             gInsertSymbolInfo.selected_col = col;
272             changed = TRUE;
273          }
274       } else {
275          gInsertSymbolInfo.something_selected = FALSE;
276          changed = TRUE;
277       }
278    } else {
279       if (on_a_symbol) {
280          gInsertSymbolInfo.something_selected = TRUE;
281          gInsertSymbolInfo.selected_row = row;
282          gInsertSymbolInfo.selected_col = col;
283          changed = TRUE;
284       }
285    }
286    if (changed) {
287       SetupControls(pTdgtBase);
288       RedrawControls(pTdgtBase, SKIP_NONE);
289    } else if (double_clicked && gInsertSymbolInfo.something_selected) {
290       InsertSymbolInAppl(pTdgtBase);
291    }
292    gInsertSymbolInfo.last_click_time = click_time;
293 
294    return FALSE;
295 }
296 
297 static
HSEvHandlerCallback(pTdgtDraw,pXEv)298 int HSEvHandlerCallback(pTdgtDraw, pXEv)
299    TdgtDraw *pTdgtDraw;
300    XEvent *pXEv;
301 {
302    if (pXEv->xany.window == pTdgtDraw->pti->tci.win) {
303       if (pXEv->type == ButtonPress) {
304          XButtonEvent *button_ev=(&(pXEv->xbutton));
305 
306          return ClickInInsertSymbolPixmap(pTdgtDraw, button_ev);
307       }
308    }
309    return FALSE;
310 }
311 
312 /* --------------------- HSSendCmdCallback() --------------------- */
313 
314 static
HSSendCmdCallback(pTdgtDraw,cmd_type,cmd_arg,pv_cmd_userdata)315 int HSSendCmdCallback(pTdgtDraw, cmd_type, cmd_arg, pv_cmd_userdata)
316    TdgtDraw *pTdgtDraw;
317    int cmd_type, cmd_arg;
318    void *pv_cmd_userdata;
319 {
320    TdgtBase *pTdgtBase=NULL;
321    InsertSymbolDlgInfo *pisdi=NULL;
322 
323    switch (cmd_type) {
324    case TDGTCMD_DRAW_USER:
325       switch (cmd_arg) {
326       case TDGTARG_INSSYM_DPY_CLEAR:
327          pTdgtBase = (TdgtBase*)pv_cmd_userdata;
328          pisdi = (InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
329          /* clear it */
330          gInsertSymbolInfo.something_selected = FALSE;
331          RedrawTidget(pisdi->sym_pixmap_ctl->pti);
332          break;
333       }
334       break;
335    }
336    return FALSE;
337 }
338 
339 /* --------------- KeyPress Event Handlers --------------- */
340 
341 static
HandleCRorLF(pTdgtBase)342 int HandleCRorLF(pTdgtBase)
343    TdgtBase *pTdgtBase;
344 {
345    if (gInsertSymbolInfo.something_selected) {
346       InsertSymbolInAppl(pTdgtBase);
347    }
348    return FALSE;
349 }
350 
351 static
HandleTab(pTdgtBase)352 int HandleTab(pTdgtBase)
353    TdgtBase *pTdgtBase;
354 {
355    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
356    Window win=TidgetGetFocusWindow();
357 
358    if (win == None) {
359       TidgetSetFocusWindow(pisdi->sym_pixmap_ctl->pti->tci.win);
360       return FALSE;
361    }
362    return FALSE;
363 }
364 
365 static
HandleBackSpace(pTdgtBase)366 int HandleBackSpace(pTdgtBase)
367    TdgtBase *pTdgtBase;
368 {
369    return FALSE;
370 }
371 
372 static
HandleCursorKey(pTdgtBase,key_sym)373 int HandleCursorKey(pTdgtBase, key_sym)
374    TdgtBase *pTdgtBase;
375    KeySym key_sym;
376 {
377    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
378    Window win=TidgetGetFocusWindow();
379    int dir=(-1);
380 
381    if (win == None) return FALSE;
382 
383    switch (key_sym) {
384    case XK_Up: dir = SCROLL_UP; break;
385    case XK_KP_Up: dir = SCROLL_UP; break;
386    case XK_Down: dir = SCROLL_DOWN; break;
387    case XK_KP_Down: dir = SCROLL_DOWN; break;
388    case XK_Left: dir = SCROLL_LEFT; break;
389    case XK_KP_Left: dir = SCROLL_LEFT; break;
390    case XK_Right: dir = SCROLL_RIGHT; break;
391    case XK_KP_Right: dir = SCROLL_RIGHT; break;
392    default: return FALSE;
393    }
394    if (gInsertSymbolInfo.something_selected) {
395       InsertSymbolToggleSelected(pisdi->sym_pixmap_ctl);
396 
397       switch (dir) {
398       case SCROLL_UP:
399          gInsertSymbolInfo.selected_row--;
400          if (gInsertSymbolInfo.selected_row < 0) {
401             gInsertSymbolInfo.selected_row = TGIS_ROWS-1;
402          }
403          break;
404       case SCROLL_DOWN:
405          gInsertSymbolInfo.selected_row++;
406          if (gInsertSymbolInfo.selected_row >= TGIS_ROWS) {
407             gInsertSymbolInfo.selected_row = 0;
408          }
409          break;
410       case SCROLL_LEFT:
411          gInsertSymbolInfo.selected_col--;
412          if (gInsertSymbolInfo.selected_col < 0) {
413             gInsertSymbolInfo.selected_col = TGIS_COLS-1;
414          }
415          break;
416       case SCROLL_RIGHT:
417          gInsertSymbolInfo.selected_col++;
418          if (gInsertSymbolInfo.selected_col >= TGIS_COLS) {
419             gInsertSymbolInfo.selected_col = 0;
420          }
421          break;
422       }
423    } else {
424       switch (dir) {
425       case SCROLL_UP:
426          gInsertSymbolInfo.selected_row = TGIS_ROWS-1;
427          gInsertSymbolInfo.selected_col = TGIS_COLS-1;
428          break;
429       case SCROLL_DOWN:
430          gInsertSymbolInfo.selected_row = 0;
431          gInsertSymbolInfo.selected_col = 0;
432          break;
433       case SCROLL_LEFT:
434          gInsertSymbolInfo.selected_row = TGIS_ROWS-1;
435          gInsertSymbolInfo.selected_col = TGIS_COLS-1;
436          break;
437       case SCROLL_RIGHT:
438          gInsertSymbolInfo.selected_row = 0;
439          gInsertSymbolInfo.selected_col = 0;
440          break;
441       }
442       gInsertSymbolInfo.something_selected = TRUE;
443    }
444    while (!InsertSymbolSelectedValid(gInsertSymbolInfo.selected_row,
445          gInsertSymbolInfo.selected_col)) {
446       switch (dir) {
447       case SCROLL_UP:
448          gInsertSymbolInfo.selected_row--;
449          if (gInsertSymbolInfo.selected_row < 0) {
450             gInsertSymbolInfo.selected_row = TGIS_ROWS-1;
451          }
452          break;
453       case SCROLL_DOWN:
454          gInsertSymbolInfo.selected_row++;
455          if (gInsertSymbolInfo.selected_row >= TGIS_ROWS) {
456             gInsertSymbolInfo.selected_row = 0;
457          }
458          break;
459       case SCROLL_LEFT:
460          gInsertSymbolInfo.selected_col--;
461          if (gInsertSymbolInfo.selected_col < 0) {
462             gInsertSymbolInfo.selected_col = TGIS_COLS-1;
463          }
464          break;
465       case SCROLL_RIGHT:
466          gInsertSymbolInfo.selected_col++;
467          if (gInsertSymbolInfo.selected_col >= TGIS_COLS) {
468             gInsertSymbolInfo.selected_col = 0;
469          }
470          break;
471       }
472    }
473    SetupControls(pTdgtBase);
474    RedrawControls(pTdgtBase, SKIP_NONE);
475 
476    return FALSE;
477 }
478 
479 static
HandleChar(pTdgtBase,key_sym,buf,has_ch)480 int HandleChar(pTdgtBase, key_sym, buf, has_ch)
481    TdgtBase *pTdgtBase;
482    KeySym key_sym;
483    char *buf;
484    int has_ch;
485 {
486    return FALSE;
487 }
488 
489 /* --------------- TdgtInsertSymbolDlgKeyPressEvHandlerCallback --------------- */
490 
491 static XComposeStatus c_stat;
492 
493 static
TdgtInsertSymbolDlgKeyPressEvHandlerCallback(pTdgtBase,pXEv)494 int TdgtInsertSymbolDlgKeyPressEvHandlerCallback(pTdgtBase, pXEv)
495    TdgtBase *pTdgtBase;
496    XEvent *pXEv;
497 {
498    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
499    int has_ch=0;
500    char buf[80];
501    KeySym key_sym=(KeySym)0;
502    XKeyEvent *key_ev=NULL;
503 
504    if (pXEv->type != KeyPress) return FALSE;
505    if (pisdi == NULL) return FALSE;
506 
507    key_ev = (&(pXEv->xkey));
508    has_ch = XLookupString(key_ev, buf, sizeof(buf), &key_sym, &c_stat);
509    TranslateKeys(buf, &key_sym);
510 
511    if (CharIsESC(key_ev, buf, key_sym, &has_ch)) {
512       HideTdgtInsertSymbolDialogBox();
513    } else if (CharIsCRorLF(key_ev, buf, key_sym, &has_ch)) {
514       return HandleCRorLF(pTdgtBase);
515    } else if (CharIsTAB(key_ev, buf, key_sym, &has_ch)) {
516       return HandleTab(pTdgtBase);
517    } else if (CharIsCntrlSpace(key_ev, buf, key_sym, &has_ch)) {
518       HideTdgtInsertSymbolDialogBox();
519    } else if (CharIsBS(key_ev, buf, key_sym, &has_ch, FALSE)) {
520       return HandleBackSpace(pTdgtBase);
521    } else if (key_sym==XK_Up || key_sym==XK_KP_Up || key_sym==XK_Down ||
522          key_sym==XK_KP_Down || key_sym==XK_Left || key_sym==XK_KP_Left ||
523          key_sym==XK_Right || key_sym==XK_KP_Right ||
524          (key_sym>'\040' && key_sym<='\177' &&
525          (key_ev->state & ControlMask) == ControlMask)) {
526       return HandleCursorKey(pTdgtBase, key_sym);
527    } else if (key_sym>='\040' && key_sym<='\177') {
528       return HandleChar(pTdgtBase, key_sym, buf, has_ch);
529    }
530    return FALSE;
531 }
532 
533 /* --------------------- ShowTdgtInsertSymbolDialogBox --------------------- */
534 
ShowTdgtInsertSymbolDialogBox()535 void ShowTdgtInsertSymbolDialogBox()
536 {
537    TidgetInfo *pti=gInsertSymbolInfo.dialogbox_tidgetinfo;
538    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pti->userdata);
539 
540    TidgetManagerSetWantAllKeyPressEvents(pti, TRUE);
541    gInsertSymbolInfo.mapped = TRUE;
542    MapTidget(pti);
543 
544    if (pisdi != NULL) {
545       ClearAllControls((TdgtBase*)(pti->tidget));
546       SetupControls((TdgtBase*)(pti->tidget));
547    }
548 }
549 
550 /* --------------------- HideTdgtInsertSymbolDialogBox --------------------- */
551 
HideTdgtInsertSymbolDialogBox()552 void HideTdgtInsertSymbolDialogBox()
553 {
554    TidgetManagerSetWantAllKeyPressEvents(NULL, FALSE);
555    TidgetSetHasFocus(FALSE);
556    gInsertSymbolInfo.mapped = FALSE;
557    XUnmapWindow(mainDisplay, gInsertSymbolInfo.dialogbox_tidgetinfo->tci.win);
558 
559    if (warpToWinCenter) {
560       XWarpPointer(mainDisplay, None, drawWindow, 0, 0, 0, 0,
561             (int)(ZOOMED_SIZE(drawWinW)>>1), (int)(ZOOMED_SIZE(drawWinH)>>1));
562    }
563 }
564 
565 /* --------------------- CreateTdgtInsertSymbolDialogBox --------------------- */
566 
567 static
TdgtInsertSymbolDlgSetEntries(pti,dsp_ptr,entries,num_entries,marked_index)568 int TdgtInsertSymbolDlgSetEntries(pti, dsp_ptr, entries, num_entries, marked_index)
569    TidgetInfo *pti;
570    DspList *dsp_ptr;
571    char **entries;
572    int num_entries, marked_index;
573 {
574    return TRUE;
575 }
576 
577 static
TdgtInsertSymbolDlgSetMsg(pti,msg)578 int TdgtInsertSymbolDlgSetMsg(pti, msg)
579    TidgetInfo *pti;
580    char *msg;
581 {
582    return TRUE;
583 }
584 
585 static
InitTdgtInsertSymbolDlgInfo(pti)586 void InitTdgtInsertSymbolDlgInfo(pti)
587    TidgetInfo *pti;
588 {
589    InsertSymbolDlgInfo *pisdi=NULL;
590 
591    if (pti == NULL) return;
592 
593    pisdi = (InsertSymbolDlgInfo*)(pti->userdata);
594    if (pisdi == NULL) return;
595 
596    pisdi->screen_w = DisplayWidth(mainDisplay, mainScreen);
597    pisdi->screen_h = DisplayHeight(mainDisplay, mainScreen);
598    TdgtInsertSymbolDlgSetMsg(pti, "");
599 
600    pisdi->def_btn_id = ID_INSSYM_BTN_OK;
601 }
602 
603 typedef struct tagCreateBtnInfo {
604    char *text;
605    int ctl_id;
606 } CreateBtnInfo;
607 
608 static CreateBtnInfo cbi[] = {
609    { "Insert Symbol",     ID_INSSYM_BTN_ADD    },
610    { "Insert and Close",  ID_INSSYM_BTN_OK     },
611    { "Close",             ID_INSSYM_BTN_CANCEL },
612    { NULL, 0 }
613 };
614 
615 static
CreateInsertSymbolButtons(pTdgtBase)616 int CreateInsertSymbolButtons(pTdgtBase)
617    TdgtBase *pTdgtBase;
618 {
619    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
620    TdgtBtnRow *pTdgtBtnRow=pisdi->btn_row_ctl;
621    int i=0;
622 
623    for (i=0; cbi[i].text != NULL; i++) {
624       TdgtBtn *pTdgtBtn=NULL;
625       int btn_w=0, btn_h=0;
626 
627       CalcTdgtBtnDim(cbi[i].text, 8, TDGTBTN_DEF_H_PAD, TDGTBTN_DEF_V_PAD,
628             &btn_w, &btn_h);
629       pTdgtBtn = CreateTdgtBtn(pTdgtBtnRow->pti->tci.win,
630             pTdgtBtnRow->pti, cbi[i].ctl_id, 0, 0, btn_w, btn_h,
631             TDGTBTN_DEF_H_PAD, TDGTBTN_DEF_V_PAD, TGMUTYPE_TEXT, TDGTBTN_CLICK,
632             TGBS_NORMAL, STYLE_NR, cbi[i].text, NULL);
633       if (pTdgtBtn == NULL) {
634          DestroyTidget(&pTdgtBase->pti);
635          return FALSE;
636       }
637       if (!TdgtBtnRowAddBtn(pTdgtBtnRow, pTdgtBtn)) {
638          DestroyTidget(&pTdgtBase->pti);
639          return FALSE;
640       }
641    }
642    return TRUE;
643 }
644 
645 static
AdjustDialogBoxWidth(dpy,pTdgtBase)646 void AdjustDialogBoxWidth(dpy, pTdgtBase)
647    Display *dpy;
648    TdgtBase *pTdgtBase;
649 {
650    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
651    int max_w=0, bottom=0, h_pad=pTdgtBase->pti->tci.h_pad, cur_x=0, cur_y=0;
652    int v_pad=pTdgtBase->pti->tci.v_pad, end_y=0;
653    SimpleWinInfo *pswi=NULL;
654 
655    /* hue edit */
656    pswi = (&(pisdi->sym_pixmap_ctl->pti->tci.win_info));
657    max_w = pswi->w;
658 
659    bottom = pisdi->btn_row_ctl->pti->tci.win_info.y +
660          pisdi->btn_row_ctl->pti->tci.win_info.h;
661 
662    cur_x = windowPadding + h_pad;
663    cur_y = windowPadding + v_pad;
664 
665    /* sym_pixmap */
666    pswi = (&(pisdi->sym_pixmap_ctl->pti->tci.win_info));
667    end_y = pswi->y+pswi->h;
668 
669    /* button row */
670    pswi = (&(pisdi->btn_row_ctl->pti->tci.win_info));
671    pswi->w = max_w;
672    TidgetMoveResize(pisdi->btn_row_ctl->pti, pswi->x, pswi->y, pswi->w,
673          pswi->h);
674 
675    pswi = (&(pTdgtBase->pti->tci.win_info));
676    pswi->w = max_w+(windowPadding<<1)+(h_pad<<1);
677    pswi->h = bottom+windowPadding+v_pad;
678    TidgetMoveResize(pTdgtBase->pti, pswi->x, pswi->y, pswi->w, pswi->h);
679 }
680 
681 static
TdgtInsertSymbolDlgWmDeleteCallback(pTdgtBase)682 void TdgtInsertSymbolDlgWmDeleteCallback(pTdgtBase)
683    TdgtBase *pTdgtBase;
684 {
685    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
686 
687    if (pisdi == NULL) return;
688 
689    HideTdgtInsertSymbolDialogBox();
690 }
691 
692 static
TdgtInsertSymbolDlgFocusCallback(pTdgtBase,cmd_type,cmd_arg,pv_cmd_userdata)693 int TdgtInsertSymbolDlgFocusCallback(pTdgtBase, cmd_type, cmd_arg,
694       pv_cmd_userdata)
695    TdgtBase *pTdgtBase;
696    int cmd_type, cmd_arg;
697    void *pv_cmd_userdata;
698 {
699    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
700 
701    if (pisdi == NULL) return FALSE;
702 
703    switch (cmd_type) {
704    case TDGTCMD_CAN_HANDLE_FOCUS_CHANGE: return TRUE;
705    case TDGTCMD_REMOVE_FOCUS: InsertSymbolDlgRemoveFocus(pTdgtBase); return TRUE;
706    }
707    return FALSE;
708 }
709 
710 static
AdjustDialogBoxSize(dpy,pTdgtBase)711 void AdjustDialogBoxSize(dpy, pTdgtBase)
712    Display *dpy;
713    TdgtBase *pTdgtBase;
714 {
715    InsertSymbolDlgInfo *pisdi=(InsertSymbolDlgInfo*)(pTdgtBase->pti->userdata);
716    int base_win_x=0, base_win_y=0, base_win_w=0, base_win_h=0;
717    XWMHints wmhints;
718    XSizeHints sizehints;
719 
720    if (pTdgtBase == NULL) return;
721 
722    AdjustDialogBoxWidth(dpy, pTdgtBase);
723 
724    base_win_w = pTdgtBase->pti->tci.win_info.w;
725    base_win_h = pTdgtBase->pti->tci.win_info.h;
726 
727    memset(&wmhints, 0, sizeof(XWMHints));
728    wmhints.flags = InputHint | StateHint;
729    wmhints.input = True;
730    wmhints.initial_state = NormalState;
731    XSetWMHints(dpy, pTdgtBase->pti->tci.win, &wmhints);
732 
733    base_win_x = (base_win_w > pisdi->screen_w) ? 0 :
734          ((pisdi->screen_w-base_win_w)>>1);
735    base_win_y = (base_win_h > pisdi->screen_h) ? 0 :
736          ((pisdi->screen_h-base_win_h)/3);
737 
738    XMoveResizeWindow(dpy, pTdgtBase->pti->tci.win, base_win_x,
739          base_win_y, base_win_w, base_win_h);
740 
741    sizehints.flags = PPosition | PSize | USPosition | PMinSize | PMaxSize;
742    sizehints.x = base_win_x;
743    sizehints.y = base_win_y;
744    sizehints.width = sizehints.min_width = sizehints.max_width = base_win_w;
745    sizehints.height = sizehints.min_height = sizehints.max_height = base_win_h;
746 #ifdef NOTR4MODE
747    XSetNormalHints(dpy, pTdgtBase->pti->tci.win, &sizehints);
748 #else
749    XSetWMNormalHints(dpy, pTdgtBase->pti->tci.win, &sizehints);
750 #endif
751 
752    XSetTransientForHint(dpy, pTdgtBase->pti->tci.win, mainWindow);
753 }
754 
755 static
SetupInsertSymbolPixmap(pisdi)756 int SetupInsertSymbolPixmap(pisdi)
757    InsertSymbolDlgInfo *pisdi;
758 {
759    int row=0, y=0;
760    char ch=(char)0x20;
761    XGCValues values;
762    Pixmap pixmap=gInsertSymbolInfo.sym_pixmap;
763    GC gc=gInsertSymbolInfo.gc;
764    int padding=gInsertSymbolInfo.padding;
765    int asc=gInsertSymbolInfo.font_asc;
766 
767    if (pixmap == None) return FALSE;
768 
769    values.foreground = myBgPixel;
770    XChangeGC(mainDisplay, gc, GCForeground, &values);
771 
772    XFillRectangle(mainDisplay, pixmap, gc, 0, 0, gInsertSymbolInfo.pixmap_w,
773          gInsertSymbolInfo.pixmap_h);
774 
775    values.foreground = myFgPixel;
776    XChangeGC(mainDisplay, gc, GCForeground, &values);
777 
778    for (row=0; row < TGIS_ROWS; row++) {
779       int col=0, x=0;
780 
781       if (row == 6) {
782          ch = (char)0xa0;
783       } else {
784          for (col=0; col < TGIS_COLS; col++) {
785             XDrawRectangle(mainDisplay, pixmap, gc, x, y,
786                   gInsertSymbolInfo.a_symbol_w+1,
787                   gInsertSymbolInfo.a_symbol_h+1);
788             XDrawString(mainDisplay, pixmap, gc, x+padding, y+padding+asc,
789                   &ch, 1);
790             x += gInsertSymbolInfo.a_symbol_w+1;
791             ch++;
792          }
793       }
794       y += gInsertSymbolInfo.a_symbol_h+1;
795    }
796    return TRUE;
797 }
798 
CreateTdgtInsertSymbolDialogBox(dpy,parent_win)799 TidgetInfo *CreateTdgtInsertSymbolDialogBox(dpy, parent_win)
800    Display *dpy;
801    Window parent_win; /* should be the rootWindow */
802 {
803    int cur_x=0, cur_y=0, v_gap=20, h_pad=0, v_pad=0;
804    int vh_padding=0, h_gap=14, end_y=0, rgbhsv_width=0;
805    TdgtBase *pTdgtBase=NULL;
806    InsertSymbolDlgInfo *pisdi=NULL;
807    char caption[MAXSTRING];
808 
809    TidgetSetFocusWindow(None);
810    if (!colorDisplay || mainVisual->class != TrueColor) {
811       sprintf(gszMsgBox, TgLoadString(STID_COLOR_WHEEL_NOT_AVAIL));
812       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
813       free(pisdi);
814       return NULL;
815    }
816    pisdi = (InsertSymbolDlgInfo*)malloc(sizeof(InsertSymbolDlgInfo));
817    if (pisdi == NULL) FailAllocMessage();
818    memset(pisdi, 0, sizeof(InsertSymbolDlgInfo));
819 
820    memset(&pisdi->tci, 0, sizeof(TrueColorInfo));
821    if (!SetupInsertSymbolPixmap(pisdi)) {
822       free(pisdi);
823       return NULL;
824    }
825    if (boldMsgFontSet != NULL || boldMsgFontPtr != NULL) {
826        rgbhsv_width = BoldMsgTextWidth(boldMsgFontPtr, "9999", 4);
827    } else if (msgFontSet != NULL || msgFontPtr != NULL) {
828        rgbhsv_width = MsgTextWidth(msgFontPtr, "9999", 4);
829    } else {
830        rgbhsv_width = defaultFontWidth * 4;
831    }
832    h_pad = TDGTBASE_DEF_H_PAD;
833    v_pad = TDGTBASE_DEF_V_PAD;
834    if (msgFontSet != NULL || msgFontPtr != NULL) {
835       vh_padding = (msgFontWidth<<1);
836    } else {
837       vh_padding = (defaultFontWidth<<1);
838    }
839    cur_x = vh_padding+windowPadding;
840    cur_y = vh_padding+windowPadding;
841 
842    sprintf(caption, TgLoadString(STID_TOOL_COLOR_WHEEL), TOOL_NAME);
843    pTdgtBase = CreateTdgtBase(parent_win, NULL, ID_INSSYM_DIALOG, 0, 0, 100,
844          100, vh_padding, vh_padding, (dialogboxUse3DBorder ? TGBS_RAISED :
845          TGBS_NORMAL), caption);
846    if (pTdgtBase == NULL) {
847       free(pisdi);
848       return NULL;
849    }
850    pTdgtBase->pti->userdata = pisdi;
851    InitTdgtInsertSymbolDlgInfo(pTdgtBase->pti);
852 
853    /* sym_pixmap */
854    pisdi->sym_pixmap_x = cur_x;
855    pisdi->sym_pixmap_y = cur_y;
856    pisdi->sym_pixmap_ctl = CreateTdgtDraw(pTdgtBase->pti->tci.win,
857          pTdgtBase->pti, ID_INSSYM_SYM_AREA, cur_x, cur_y,
858          gInsertSymbolInfo.pixmap_w, gInsertSymbolInfo.pixmap_h,
859          TDGTDRAW_DEF_H_PAD, TDGTDRAW_DEF_V_PAD, TGBS_LOWRED, NULL);
860    if (pisdi->sym_pixmap_ctl == NULL) {
861       DestroyTidget(&pTdgtBase->pti);
862       return NULL;
863    }
864    TdgtDrawSetRedrawCallback(pisdi->sym_pixmap_ctl, HSRedrawCallback);
865    TdgtDrawSetEvHandlerCallback(pisdi->sym_pixmap_ctl, HSEvHandlerCallback);
866    TdgtDrawSetSendCmdCallback(pisdi->sym_pixmap_ctl, HSSendCmdCallback);
867 
868    cur_x += pisdi->sym_pixmap_ctl->pti->tci.win_info.w + h_gap;
869    end_y = cur_y + pisdi->sym_pixmap_ctl->pti->tci.win_info.h - windowPadding;
870 
871    /* buttons */
872 
873    cur_x = vh_padding+windowPadding;
874    cur_y = end_y + v_gap;
875    pisdi->btn_row_ctl = CreateTdgtBtnRow(pTdgtBase->pti->tci.win,
876          pTdgtBase->pti, INVALID, cur_x, cur_y, TDGTBROW_DEF_H_PAD,
877          TDGTBROW_DEF_V_PAD, TGBS_NORMAL, defaultFontWidth, JUST_C);
878    if (pisdi->btn_row_ctl == NULL) {
879       DestroyTidget(&pTdgtBase->pti);
880       return NULL;
881    }
882    if (!CreateInsertSymbolButtons(pTdgtBase)) {
883       DestroyTidget(&pTdgtBase->pti);
884       return NULL;
885    }
886    TdgtInsertSymbolDlgSetEntries(pTdgtBase->pti, NULL, NULL, 0, INVALID);
887 
888    /*
889     * Specify that the base tidget will handle all the KeyPress events
890     *         in all its children tidgets.
891     */
892    TdgtBaseWillHandleKeyPressEvents(pTdgtBase,
893          TdgtInsertSymbolDlgKeyPressEvHandlerCallback);
894    /*
895     * Specify that the base tidget will handle all the KeyPress events
896     *         in all its children tidgets.
897     */
898    TdgtBaseSetWmDeleteCallback(pTdgtBase, TdgtInsertSymbolDlgWmDeleteCallback);
899 
900    /*
901     * Specify a callback function to answer some focus related questions.
902     */
903    TdgtBaseSetFocusCallback(pTdgtBase, TdgtInsertSymbolDlgFocusCallback);
904 
905    AdjustDialogBoxSize(dpy, pTdgtBase);
906    TidgetSetFocusWindow(pisdi->sym_pixmap_ctl->pti->tci.win);
907 
908    return pTdgtBase->pti;
909 }
910 
911 /* --------------------- DestroyTdgtInsertSymbolDialogBox --------------------- */
912 
DestroyTdgtInsertSymbolDialogBox(dpy,pti)913 void DestroyTdgtInsertSymbolDialogBox(dpy, pti)
914    Display *dpy;
915    TidgetInfo *pti;
916 {
917    InsertSymbolDlgInfo *pisdi=NULL;
918 
919    if (pti == NULL) return;
920 
921    pisdi = (InsertSymbolDlgInfo*)(pti->userdata);
922    if (pisdi != NULL) {
923       free(pisdi);
924    }
925    DestroyTidget(&pti);
926 }
927 
928 /* --------------------- TdgtInsertSymbolDlgLoop --------------------- */
929 
930 static
HandleTdgtNotifyEvent(pTdgtBase,pTdgtNtfy)931 int HandleTdgtNotifyEvent(pTdgtBase, pTdgtNtfy)
932    TdgtBase *pTdgtBase;
933    TdgtNtfy *pTdgtNtfy;
934 {
935    switch (pTdgtNtfy->ctl_id) {
936    case ID_INSSYM_BTN_ADD: InsertSymbolInAppl(pTdgtBase); break;
937    case ID_INSSYM_BTN_OK:
938       if (InsertSymbolInAppl(pTdgtBase)) {
939          HideTdgtInsertSymbolDialogBox();
940       }
941       break;
942    case ID_INSSYM_BTN_CANCEL: HideTdgtInsertSymbolDialogBox(); break;
943    }
944    return FALSE;
945 }
946 
TdgtInsertSymbolDlgLoop(pti)947 int TdgtInsertSymbolDlgLoop(pti)
948    TidgetInfo *pti;
949 {
950    TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
951    int which_btn_clicked=INVALID, first_time_config=TRUE;
952 
953    if (pTdgtBase == NULL) return which_btn_clicked;
954 
955    while (gInsertSymbolInfo.mapped) {
956       XEvent xev;
957       TdgtNtfy tdgt_notify;
958       TidgetInfo *handling_pti=NULL;
959 
960       XNextEvent(mainDisplay, &xev);
961 
962       if (xev.type == MotionNotify) {
963          /* do nothing */
964       } else if (xev.type == ConfigureNotify &&
965             xev.xany.window == pti->tci.win) {
966          if (first_time_config) {
967             first_time_config = FALSE;
968             if (warpToWinCenter) {
969                /* does not work because the window has been moved */
970                XWarpPointer(mainDisplay, None, pti->tci.win, 0, 0, 0, 0,
971                      (pti->tci.win_info.w>>1), (pti->tci.win_info.h>>1));
972             }
973          }
974       } else if (xev.type == Expose) {
975          ExposeEventHandler(&xev, FALSE);
976       } else if (xev.type == ConfigureNotify &&
977             xev.xany.window==mainWindow) {
978          Reconfigure(FALSE);
979       } else if (xev.type == KeyPress) {
980          TidgetManagerHandleAllKeyPressEvent(&xev);
981       } else if (IsTdgtNotifyEvent(pti, &xev, &tdgt_notify)) {
982          HandleTdgtNotifyEvent(pTdgtBase, &tdgt_notify);
983       } else if (IsTidgetEvent(pti, &xev, &handling_pti)) {
984          TidgetEventHandler(pti, &xev, handling_pti);
985       } else {
986          /* anything else? */
987       }
988    }
989    return which_btn_clicked;
990 }
991 
992 /* --------------------- Init & Clean Up --------------------- */
993 
InitTdgtInsertSymbolDlg()994 int InitTdgtInsertSymbolDlg()
995 {
996    return TRUE;
997 }
998 
CleanUpTdgtInsertSymbolDlg()999 void CleanUpTdgtInsertSymbolDlg()
1000 {
1001 }
1002 
1003