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