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/tidget.c,v 1.8 2011/05/16 16:22:00 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_TIDGET_C_
22 
23 #include "tgifdefs.h"
24 #include "patchlvl.h"
25 #include "tidget.h"
26 
27 #include "font.e"
28 #include "msg.e"
29 #include "raster.e"
30 #include "setup.e"
31 #include "tdgtbase.e"
32 #include "tdgtbmpl.e"
33 #include "tdgtbrow.e"
34 #include "tdgtbtn.e"
35 #include "tdgtdraw.e"
36 #include "tdgtlist.e"
37 #include "tdgtmsg.e"
38 #include "tdgtsedt.e"
39 #include "text.e"
40 #include "tidget.e"
41 #include "util.e"
42 
43 TidgetManager gTidgetManager;
44 
45 /* --------------------- TidgetWindowNotify --------------------- */
46 
TidgetWindowNotify(win,ctl_id,nf_type,nf_arg,nf_arg2)47 void TidgetWindowNotify(win, ctl_id, nf_type, nf_arg, nf_arg2)
48    Window win;
49    int ctl_id, nf_type, nf_arg, nf_arg2;
50 {
51    XClientMessageEvent client_ev;
52 
53    memset(&client_ev, 0, sizeof(XClientMessageEvent));
54    client_ev.type = ClientMessage;
55    client_ev.window = win;
56    client_ev.message_type = gTidgetManager.notify_atom;
57    client_ev.format = 32;
58    client_ev.data.l[0] = (long)(TDGT_NOTIFY & 0x0ffffffff);
59    client_ev.data.l[1] = (long)(ctl_id & 0x0ffffffff);
60    client_ev.data.l[2] = (long)(nf_type & 0x0ffffffff);
61    client_ev.data.l[3] = (long)(nf_arg & 0x0ffffffff);
62    client_ev.data.l[4] = (long)(nf_arg2 & 0x0ffffffff);
63    XSendEvent(mainDisplay, win, False, NoEventMask, (XEvent*)&client_ev);
64 }
65 
66 /* --------------------- TidgetNotify --------------------- */
67 
TidgetNotify(pti,ctl_id,nf_type,nf_arg,nf_arg2)68 void TidgetNotify(pti, ctl_id, nf_type, nf_arg, nf_arg2)
69    TidgetInfo *pti; /* referring to a base tidget */
70    int ctl_id, nf_type, nf_arg, nf_arg2;
71 {
72    TidgetWindowNotify(pti->tci.win, ctl_id, nf_type, nf_arg, nf_arg2);
73 }
74 
75 /* --------------------- TidgetControlNotify --------------------- */
76 
77 static
DoTidgetControlNotify(pti,ctl_id,nf_type,nf_arg,nf_arg2)78 void DoTidgetControlNotify(pti, ctl_id, nf_type, nf_arg, nf_arg2)
79    TidgetInfo *pti; /* referring to tidget, e.g., a button */
80    int ctl_id, nf_type, nf_arg, nf_arg2;
81 {
82    if (pti->tci.parent_tidgetinfo == NULL) {
83       TidgetWindowNotify(pti->tci.parent_win, ctl_id, nf_type, nf_arg, nf_arg2);
84    } else if (pti->tci.parent_tidgetinfo->type == TIDGET_TYPE_BASE) {
85       TidgetWindowNotify(pti->tci.parent_win, ctl_id, nf_type, nf_arg, nf_arg2);
86    } else {
87       DoTidgetControlNotify(pti->tci.parent_tidgetinfo, ctl_id, nf_type, nf_arg,
88             nf_arg2);
89    }
90 }
91 
TidgetControlNotify(pti,nf_type,nf_arg,nf_arg2)92 void TidgetControlNotify(pti, nf_type, nf_arg, nf_arg2)
93    TidgetInfo *pti; /* referring to tidget, e.g., a button */
94    int nf_type, nf_arg, nf_arg2;
95 {
96    DoTidgetControlNotify(pti, pti->tci.ctl_id, nf_type, nf_arg, nf_arg2);
97 }
98 
99 /* --------------------- IsTdgtWindowNotifyEvent --------------------- */
100 
IsTdgtWindowNotifyEvent(win,pXEv,pTdgtNtfy)101 int IsTdgtWindowNotifyEvent(win, pXEv, pTdgtNtfy)
102    Window win;
103    XEvent *pXEv;
104    TdgtNtfy *pTdgtNtfy;
105 {
106    if (pXEv->xany.window == win && pXEv->type == ClientMessage) {
107       if (pXEv->xclient.message_type == gTidgetManager.notify_atom &&
108             pXEv->xclient.format == 32 &&
109             pXEv->xclient.data.l[0] == TDGT_NOTIFY) {
110          if (pTdgtNtfy != NULL) {
111             memset(pTdgtNtfy, 0, sizeof(TdgtNtfy));
112 
113             pTdgtNtfy->ctl_id = (int)(pXEv->xclient.data.l[1]);
114             pTdgtNtfy->nf_type = (int)(pXEv->xclient.data.l[2]);
115             pTdgtNtfy->nf_arg = (int)(pXEv->xclient.data.l[3]);
116             pTdgtNtfy->nf_arg2 = (int)(pXEv->xclient.data.l[4]);
117          }
118          return TRUE;
119       }
120    }
121    return FALSE;
122 }
123 
124 /* --------------------- IsTdgtNotifyEvent --------------------- */
125 
IsTdgtNotifyEvent(pti,pXEv,pTdgtNtfy)126 int IsTdgtNotifyEvent(pti, pXEv, pTdgtNtfy)
127    TidgetInfo *pti; /* referring to a base tidget */
128    XEvent *pXEv;
129    TdgtNtfy *pTdgtNtfy;
130 {
131    return IsTdgtWindowNotifyEvent(pti->tci.win, pXEv, pTdgtNtfy);
132 }
133 
134 /* --------------------- TidgetDrawFocusRect --------------------- */
135 
TidgetDrawFocusRect(pti,pswi)136 void TidgetDrawFocusRect(pti, pswi)
137    TidgetInfo *pti;
138    SimpleWinInfo *pswi;
139 {
140    Window win=pti->tci.win;
141    XGCValues values;
142    int x=pswi->x, y=pswi->y, w=pswi->w, h=pswi->h;
143 
144    XSetDashes(mainDisplay, revDefaultGC, 0, dashList[8], dashListLength[8]);
145    values.line_style = LineOnOffDash;
146    XChangeGC(mainDisplay, revDefaultGC, GCLineStyle, &values);
147 
148    XDrawRectangle(mainDisplay, win, revDefaultGC, x-1, y-1, w+2, h+2);
149 
150    values.line_style = LineSolid;
151    XChangeGC(mainDisplay, revDefaultGC, GCLineStyle, &values);
152 }
153 
154 /* --------------------- RedrawTidget --------------------- */
155 
RedrawTidget(pti)156 void RedrawTidget(pti)
157    TidgetInfo *pti;
158 {
159    if (pti->tci.pf_redraw_callback != NULL) {
160       if (!pti->tci.redraw_disabled) {
161          (pti->tci.pf_redraw_callback)(pti);
162          TidgetSetDirty(pti, FALSE);
163       }
164    }
165 }
166 
167 /* --------------------- TidgetEventHandler --------------------- */
168 
TidgetEventHandler(pti,input,pti_handler_tidget)169 int TidgetEventHandler(pti, input, pti_handler_tidget)
170    /*
171     * Returns TRUE if the event has been handled.
172     */
173    TidgetInfo *pti, *pti_handler_tidget;
174    XEvent *input;
175 {
176    if (pti == pti_handler_tidget) {
177       if (pti->tci.pf_ev_handler_callback != NULL) {
178          (pti->tci.pf_ev_handler_callback)(pti, input, pti_handler_tidget);
179       }
180       return TRUE;
181    }
182    /* iterate through tidget-based child windows */
183    if (pti->tci.can_have_children) {
184       CVListElem *pElem=NULL;
185 
186       for (pElem=ListFirst(&pti->tci.clist); pElem != NULL;
187             pElem=ListNext(&pti->tci.clist, pElem)) {
188          TidgetInfo *child_pti=(TidgetInfo*)(pElem->obj);
189 
190          if (TidgetEventHandler(child_pti, input, pti_handler_tidget)) {
191             return TRUE;
192          }
193       }
194    }
195    return FALSE;
196 }
197 
198 /* --------------------- TestAndHandleEventForTidget --------------------- */
199 
200 #ifdef NOT_DEFINED
TestAndHandleEventForTidget(pti,input)201 int TestAndHandleEventForTidget(pti, input)
202    TidgetInfo *pti;
203    XEvent *input;
204 {
205    if (input->xany.window == pti->tci.win) {
206       if (pti->tci.pf_ev_handler_callback != NULL) {
207          (pti->tci.pf_ev_handler_callback)(pti, input);
208       }
209       return TRUE;
210    }
211    /*
212     * If a tidget has non-tidget child windows, then it should
213     *         have an is_event callback function.
214     */
215    if (pti->tci.pf_is_event_callback != NULL &&
216          (pti->tci.pf_is_event_callback)(pti, input)) {
217       /* gets here if the tidget has other non-tidget child windows */
218       if (pti->tci.pf_ev_handler_callback != NULL) {
219          (pti->tci.pf_ev_handler_callback)(pti, input);
220       }
221       return TRUE;
222    }
223    /* iterate through tidget-based child windows */
224    if (pti->tci.can_have_children) {
225       CVListElem *pElem=NULL;
226 
227       for (pElem=ListFirst(&pti->tci.clist); pElem != NULL;
228             pElem=ListNext(&pti->tci.clist, pElem)) {
229          TidgetInfo *child_pti=(TidgetInfo*)(pElem->obj);
230 
231          if (TestAndHandleEventForTidget(child_pti, input)) {
232             return TRUE;
233          }
234       }
235    }
236    return FALSE;
237 }
238 #endif /* NOT_DEFINED */
239 
240 /* --------------------- IsTidgetEvent --------------------- */
241 
IsTidgetEvent(pti,input,ppti_handler_tidget_return)242 int IsTidgetEvent(pti, input, ppti_handler_tidget_return)
243    TidgetInfo *pti, **ppti_handler_tidget_return;
244    XEvent *input;
245 {
246    if (input->xany.window == pti->tci.win) {
247       *ppti_handler_tidget_return = pti;
248       return TRUE;
249    }
250    /*
251     * If a tidget has non-tidget child windows, then it should
252     *         have an is_event callback function.
253     */
254    if (pti->tci.pf_is_event_callback != NULL &&
255          (pti->tci.pf_is_event_callback)(pti, input,
256          ppti_handler_tidget_return)) {
257       return TRUE;
258    }
259    /* iterate through tidget-based child windows */
260    if (pti->tci.can_have_children) {
261       CVListElem *pElem=NULL;
262 
263       for (pElem=ListFirst(&pti->tci.clist); pElem != NULL;
264             pElem=ListNext(&pti->tci.clist, pElem)) {
265          TidgetInfo *child_pti=(TidgetInfo*)(pElem->obj);
266 
267          if (IsTidgetEvent(child_pti, input, ppti_handler_tidget_return)) {
268             return TRUE;
269          }
270       }
271    }
272    return FALSE;
273 }
274 
275 /* --------------------- DestroyTidget --------------------- */
276 
DestroyTidget(ppti)277 void DestroyTidget(ppti)
278    TidgetInfo **ppti;
279 {
280    TidgetInfo *pti=(*ppti);
281 
282    if (pti->tci.parent_tidgetinfo == NULL) {
283       CVListElem *pElem=ListFind(&gTidgetManager.toplevel_tidgets, pti, NULL);
284 
285       if (pElem == NULL) {
286 #ifdef _TGIF_DBG /* debug, do not translate */
287          fprintf(stderr, "Cannot find a TidgetInfo in DestroyTidget().\n");
288 #endif /* _TGIF_DBG */
289       } else {
290          ListUnlink(&gTidgetManager.toplevel_tidgets, pElem);
291          free(pElem);
292       }
293    }
294    if (pti->tci.pf_destroy_callback != NULL) {
295       (pti->tci.pf_destroy_callback)(pti);
296    }
297    free(pti);
298    *ppti = NULL;
299 }
300 
301 /* --------------------- SetTidgetInfoBasic --------------------- */
302 
SetTidgetInfoBasic(pti,tidget_type,tidget,parent_win,x,y,w,h,h_pad,v_pad,state,caption)303 void SetTidgetInfoBasic(pti, tidget_type, tidget, parent_win, x, y, w, h, h_pad,
304       v_pad, state, caption)
305    TidgetInfo *pti;
306    int tidget_type, x, y, w, h, h_pad, v_pad, state;
307    void *tidget;
308    Window parent_win;
309    char *caption;
310 {
311    pti->type = tidget_type;
312    pti->tidget = tidget;
313 
314    pti->tci.parent_win = parent_win;
315    pti->tci.win_info.x = x;
316    pti->tci.win_info.y = y;
317    pti->tci.win_info.w = w;
318    pti->tci.win_info.h = h;
319    pti->tci.h_pad = h_pad;
320    pti->tci.v_pad = v_pad;
321    pti->tci.content_w = w-(windowPadding<<1)-(h_pad<<1);
322    pti->tci.content_h = h-(windowPadding<<1)-(v_pad<<1);
323    pti->tci.state = state;
324 
325    if (caption != NULL) {
326       DynStrSet(&(pti->tci.dyn_str), caption);
327    }
328 }
329 
330 /* --------------------- TidgetCanHaveChildren --------------------- */
331 
TidgetCanHaveChildren(pti,can_have_children)332 void TidgetCanHaveChildren(pti, can_have_children)
333    TidgetInfo *pti;
334    int can_have_children;
335 {
336    pti->tci.can_have_children = can_have_children;
337 }
338 
339 /* --------------------- TidgetSetCallbacks --------------------- */
340 
TidgetSetCallbacks(pti,pf_redraw_callback,pf_ev_handler_callback,pf_is_event_callback,pf_destroy_callback,pf_map_callback,pf_moveresize_callback,pf_sendcmd_callback)341 void TidgetSetCallbacks(pti, pf_redraw_callback, pf_ev_handler_callback,
342       pf_is_event_callback, pf_destroy_callback, pf_map_callback,
343       pf_moveresize_callback, pf_sendcmd_callback)
344    TidgetInfo *pti;
345    TidgetRedrawCallbackFunc *pf_redraw_callback;
346    TidgetEvHandlerCallbackFunc *pf_ev_handler_callback;
347    TidgetIsEventCallbackFunc *pf_is_event_callback;
348    TidgetDestroyCallbackFunc *pf_destroy_callback;
349    TidgetMapCallbackFunc *pf_map_callback;
350    TidgetMoveResizeCallbackFunc *pf_moveresize_callback;
351    TidgetSendCmdCallbackFunc *pf_sendcmd_callback;
352 {
353    pti->tci.pf_redraw_callback = pf_redraw_callback;
354    pti->tci.pf_ev_handler_callback = pf_ev_handler_callback;
355    pti->tci.pf_is_event_callback = pf_is_event_callback;
356    pti->tci.pf_destroy_callback = pf_destroy_callback;
357    pti->tci.pf_map_callback = pf_map_callback;
358    pti->tci.pf_moveresize_callback = pf_moveresize_callback;
359    pti->tci.pf_sendcmd_callback = pf_sendcmd_callback;
360 }
361 
362 /* --------------------- NewTidgetInfo --------------------- */
363 
NewTidgetInfo(parent_tidgetinfo,type,tidget,ctl_id,userdata)364 TidgetInfo *NewTidgetInfo(parent_tidgetinfo, type, tidget, ctl_id, userdata)
365    TidgetInfo *parent_tidgetinfo;
366    int type, ctl_id;
367    void *tidget;
368    void *userdata;
369 {
370    TidgetInfo *pti=(TidgetInfo*)malloc(sizeof(TidgetInfo));
371 
372    if (pti == NULL) FailAllocMessage();
373    memset(pti, 0, sizeof(TidgetInfo));
374 
375    pti->type = type;
376    pti->tidget = tidget;
377    pti->userdata = userdata;
378 
379    pti->tci.ctl_id = ctl_id;
380    pti->tci.parent_tidgetinfo = parent_tidgetinfo;
381    CVListInit(&pti->tci.clist);
382 
383    if (parent_tidgetinfo == NULL) {
384       ListAppend(&gTidgetManager.toplevel_tidgets, pti);
385    } else if (parent_tidgetinfo->type == TIDGET_TYPE_BASE &&
386          parent_tidgetinfo->tidget != NULL) {
387       if (!TdgtBaseAddChild((TdgtBase*)(parent_tidgetinfo->tidget), pti)) {
388          /* this should not happen */
389       }
390    }
391    return pti;
392 }
393 
394 /* --------------------- MapTidget --------------------- */
395 
MapTidget(pti)396 void MapTidget(pti)
397    TidgetInfo *pti;
398 {
399    if (pti->tci.pf_map_callback != NULL) {
400       (pti->tci.pf_map_callback)(pti);
401    }
402 }
403 
404 /* --------------------- TidgetMoveResize --------------------- */
405 
TidgetMoveResize(pti,x,y,w,h)406 void TidgetMoveResize(pti, x, y, w, h)
407    TidgetInfo *pti;
408    int x, y, w, h;
409 {
410    if (pti->tci.pf_moveresize_callback != NULL) {
411       (pti->tci.pf_moveresize_callback)(pti, x, y, w, h);
412    }
413 }
414 
415 /* --------------------- ResetTidgetCommon --------------------- */
416 
ResetTidgetCommon(ptci)417 void ResetTidgetCommon(ptci)
418    TidgetCommonInfo *ptci;
419 {
420    TidgetInfo *saved_parent_tidgetinfo=NULL;
421 
422    if (ptci == NULL) return;
423 
424    saved_parent_tidgetinfo = ptci->parent_tidgetinfo;
425    XDestroyWindow(mainDisplay, ptci->win);
426 
427    FreeDynStrBuf(&(ptci->dyn_str));
428 
429    memset(ptci, 0, sizeof(TidgetCommonInfo));
430 
431    ptci->parent_tidgetinfo = saved_parent_tidgetinfo;
432    CVListInit(&ptci->clist);
433 }
434 
435 /* --------------------- TidgetSendCmd --------------------- */
436 
TidgetSendCmd(pti,cmd_type,cmd_arg,pv_cmd_userdata)437 int TidgetSendCmd(pti, cmd_type, cmd_arg, pv_cmd_userdata)
438    TidgetInfo *pti;
439    int cmd_type, cmd_arg;
440    void *pv_cmd_userdata;
441 {
442    if (pti->tci.pf_sendcmd_callback != NULL) {
443       return (pti->tci.pf_sendcmd_callback)(pti, cmd_type, cmd_arg,
444             pv_cmd_userdata);
445    }
446    return FALSE;
447 }
448 
449 /* --------------------- TidgetEnableRedraw --------------------- */
450 
TidgetDisableRedraw(pti,redraw_disabled)451 int TidgetDisableRedraw(pti, redraw_disabled)
452    TidgetInfo *pti;
453    int redraw_disabled;
454 {
455    int prev_redraw_disabled=(pti->tci.redraw_disabled);
456 
457    pti->tci.redraw_disabled = redraw_disabled;
458 
459    if (!redraw_disabled && prev_redraw_disabled && pti->tci.dirty) {
460       RedrawTidget(pti);
461    }
462    return prev_redraw_disabled;
463 }
464 
465 /* --------------------- TidgetSetDirty --------------------- */
466 
TidgetSetDirty(pti,dirty)467 int TidgetSetDirty(pti, dirty)
468    TidgetInfo *pti;
469    int dirty;
470 {
471    int prev_dirty=(pti->tci.dirty);
472 
473    pti->tci.dirty = dirty;
474 
475    return prev_dirty;
476 }
477 
478 /* --------------------- TidgetHasFocus --------------------- */
479 
480 static int gnTidgetHasFocus=FALSE;
481 
TidgetHasFocus()482 int TidgetHasFocus()
483 {
484    return gnTidgetHasFocus;
485 }
486 
487 /* --------------------- TidgetSetHasFocus --------------------- */
488 
TidgetSetHasFocus(has_focus)489 int TidgetSetHasFocus(has_focus)
490    int has_focus;
491 {
492    int prev_has_focus=gnTidgetHasFocus;
493 
494    gnTidgetHasFocus = has_focus;
495 
496    return prev_has_focus;
497 }
498 
499 /* --------------------- TidgetGetFocusWindow --------------------- */
500 
501 static Window gFocusWindow=None;
502 
TidgetGetFocusWindow()503 Window TidgetGetFocusWindow()
504 {
505    return gFocusWindow;
506 }
507 
508 /* --------------------- TidgetSetFocusWindow --------------------- */
509 
TidgetSetFocusWindow(win)510 Window TidgetSetFocusWindow(win)
511    Window win;
512 {
513    Window prev_win=gFocusWindow;
514 
515    gFocusWindow = win;
516 
517    return prev_win;
518 }
519 
520 /* --------------------- TidgetIsFocus --------------------- */
521 
TidgetIsFocus(pti)522 int TidgetIsFocus(pti)
523    TidgetInfo *pti;
524 {
525    if (gFocusWindow == None) return FALSE;
526 
527    return (pti->tci.win == gFocusWindow);
528 }
529 
530 /* --------------------- TidgetGetFontInfo --------------------- */
531 
TidgetGetFontInfo(pnFontIndex,pnSzUnit)532 void TidgetGetFontInfo(pnFontIndex, pnSzUnit)
533    int *pnFontIndex, *pnSzUnit;
534 {
535    if (pnFontIndex != NULL) *pnFontIndex = FONT_HEL;
536    if (pnSzUnit != NULL) *pnSzUnit = FontSizeToSzUnit(14);
537 }
538 
539 /* --------------------- TidgetGetFontInfoGivenStyle --------------------- */
540 
TidgetGetFontInfoGivenStyle(font_style,pp_font_ptr,pn_font_width,pn_font_height,pn_font_asc,pn_font_des)541 void TidgetGetFontInfoGivenStyle(font_style, pp_font_ptr, pn_font_width,
542       pn_font_height, pn_font_asc, pn_font_des)
543    int font_style, *pn_font_width, *pn_font_height, *pn_font_asc, *pn_font_des;
544    XFontStruct **pp_font_ptr;
545 {
546    int font_width=defaultFontWidth;
547    int font_height=defaultFontHeight;
548    int font_asc=defaultFontAsc;
549    int font_des=defaultFontDes;
550    XFontStruct *font_ptr=defaultFontPtr;
551 
552    if (msgFontSet != NULL || msgFontPtr != NULL) {
553       font_width = msgFontWidth;
554       font_height = msgFontHeight;
555       font_asc = msgFontAsc;
556       font_des = msgFontDes;
557       font_ptr = msgFontPtr;
558    }
559    switch (font_style) {
560    case STYLE_NR:
561       if (msgFontSet != NULL || msgFontPtr != NULL) {
562          font_width = msgFontWidth;
563          font_height = msgFontHeight;
564          font_asc = msgFontAsc;
565          font_des = msgFontDes;
566          font_ptr = msgFontPtr;
567       }
568       break;
569    case STYLE_BR:
570       if (boldMsgFontSet != NULL || boldMsgFontPtr != NULL) {
571          font_width = boldMsgFontWidth;
572          font_height = boldMsgFontHeight;
573          font_asc = boldMsgFontAsc;
574          font_des = boldMsgFontDes;
575          font_ptr = boldMsgFontPtr;
576       }
577       break;
578    case STYLE_NI:
579       if (italicMsgFontSet != NULL || italicMsgFontPtr != NULL) {
580          font_width = italicMsgFontWidth;
581          font_height = italicMsgFontHeight;
582          font_asc = italicMsgFontAsc;
583          font_des = italicMsgFontDes;
584          font_ptr = italicMsgFontPtr;
585       }
586       break;
587    case STYLE_BI:
588       if (boldItalicMsgFontSet != NULL || boldItalicMsgFontPtr != NULL) {
589          font_width = boldItalicMsgFontWidth;
590          font_height = boldItalicMsgFontHeight;
591          font_asc = boldItalicMsgFontAsc;
592          font_des = boldItalicMsgFontDes;
593          font_ptr = boldItalicMsgFontPtr;
594       }
595       break;
596    }
597    if (pp_font_ptr != NULL) *pp_font_ptr = font_ptr;
598    if (pn_font_width != NULL) *pn_font_width = font_width;
599    if (pn_font_height != NULL) *pn_font_height = font_height;
600    if (pn_font_asc != NULL) *pn_font_asc = font_asc;
601    if (pn_font_des != NULL) *pn_font_des = font_des;
602 }
603 
604 /* --------------------- TidgetManagerResetGC --------------------- */
605 
TidgetManagerResetGC()606 void TidgetManagerResetGC()
607 {
608    if (gTidgetManager.gc != NULL) {
609       XGCValues values;
610 
611       values.background = myBgPixel;
612       values.foreground = myFgPixel;
613       values.font = defaultFontPtr->fid;
614       values.fill_style = FillSolid;
615       values.function = GXcopy;
616       values.ts_x_origin = values.ts_y_origin = 0;
617       XChangeGC(mainDisplay, gTidgetManager.gc,
618             GCBackground | GCForeground | GCFont | GCFillStyle | GCFunction |
619             GCTileStipXOrigin | GCTileStipYOrigin, &values);
620    }
621 }
622 
623 /* --------------------- TidgetManagerHandleEvent --------------------- */
624 
TidgetManagerHandleEvent(pXEv)625 int TidgetManagerHandleEvent(pXEv)
626    /* return TRUE if the event is handled */
627    XEvent *pXEv;
628 {
629    CVListElem *pElem=NULL;
630 
631    for (pElem=ListFirst(&gTidgetManager.toplevel_tidgets); pElem != NULL;
632          pElem=ListNext(&gTidgetManager.toplevel_tidgets, pElem)) {
633       TidgetInfo *pti=(TidgetInfo*)(pElem->obj);
634 
635       if (pti != NULL) {
636          TidgetInfo *handling_pti=NULL;
637 
638          if (IsTidgetEvent(pti, pXEv, &handling_pti)) {
639             TidgetEventHandler(pti, pXEv, handling_pti);
640             return TRUE;
641          }
642       }
643    }
644    return FALSE;
645 }
646 
647 /* ------------------ TidgetManagerHandleAllKeyPressEvent ------------------ */
648 
TidgetManagerHandleAllKeyPressEvent(pXEv)649 int TidgetManagerHandleAllKeyPressEvent(pXEv)
650    /* return TRUE if the event is handled */
651    XEvent *pXEv;
652 {
653    TidgetInfo *pti=(gTidgetManager.key_press_base_tidgetinfo);
654    TdgtBase *pTdgtBase=NULL;
655 
656    if (pti == NULL)  return FALSE;
657 
658    if (pti->type != TIDGET_TYPE_BASE) return FALSE;
659 
660    pTdgtBase = pti->tidget;
661 
662    if (pTdgtBase == NULL) return FALSE;
663 
664    if (pTdgtBase->pf_key_press_ev_handler_callback != NULL) {
665       return (pTdgtBase->pf_key_press_ev_handler_callback)(pTdgtBase, pXEv);
666    }
667    return FALSE;
668 }
669 
670 /* ------------------- TidgetManagerWantAllKeyPressEvents ------------------- */
671 
TidgetManagerWantAllKeyPressEvents()672 int TidgetManagerWantAllKeyPressEvents()
673 {
674    return gTidgetManager.want_all_key_press_events;
675 }
676 
677 /* ----------------- TidgetManagerSetWantAllKeyPressEvents ----------------- */
678 
TidgetManagerSetWantAllKeyPressEvents(pti,want_all_key_press_events)679 int TidgetManagerSetWantAllKeyPressEvents(pti, want_all_key_press_events)
680    TidgetInfo *pti;
681    int want_all_key_press_events;
682 {
683    int prev_want_all_key_press_events=gTidgetManager.want_all_key_press_events;
684 
685    gTidgetManager.want_all_key_press_events = want_all_key_press_events;
686    gTidgetManager.key_press_base_tidgetinfo = pti;
687 
688    return prev_want_all_key_press_events;
689 }
690 
691 /* --------------------- Init & Clean Up --------------------- */
692 
InitTidget()693 int InitTidget()
694 {
695    int ok=TRUE;
696    XGCValues values;
697 
698    memset(&gTidgetManager, 0, sizeof(TidgetManager));
699    CVListInit(&gTidgetManager.toplevel_tidgets);
700 
701    if (mainDisplay != NULL) {
702       values.background = myBgPixel;
703       values.foreground = myFgPixel;
704       values.fill_style = FillSolid;
705       values.function = GXcopy;
706       gTidgetManager.gc = XCreateGC(mainDisplay, mainWindow,
707             GCBackground | GCForeground | GCFillStyle | GCFunction, &values);
708 
709       gTidgetManager.notify_atom = XInternAtom(mainDisplay, "TDGT_NOTIFY",
710             False);
711    }
712    if (!InitTdgtBase()) ok = FALSE;
713    if (!InitTdgtList()) ok = FALSE;
714    if (!InitTdgtBtn()) ok = FALSE;
715    if (!InitTdgtDraw()) ok = FALSE;
716    if (!InitTdgtMsg()) ok = FALSE;
717    if (!InitTdgtBtnRow()) ok = FALSE;
718    if (!InitTdgtBmpList()) ok = FALSE;
719    if (!InitTdgtSmplEdit()) ok = FALSE;
720 
721    return ok;
722 }
723 
CleanUpTidget()724 void CleanUpTidget()
725 {
726    CVListElem *pElem=NULL;
727 
728    if (ListLength(&gTidgetManager.toplevel_tidgets) > 0) {
729 #ifdef _TGIF_DBG /* debug, do not translate */
730       fprintf(stderr,
731             "gTidgetManager.toplevel_tidgets is not empty.  %1d left.\n",
732             ListLength(&gTidgetManager.toplevel_tidgets));
733 #endif /* _TGIF_DBG */
734       for (pElem=ListFirst(&gTidgetManager.toplevel_tidgets); pElem != NULL;
735             pElem=ListNext(&gTidgetManager.toplevel_tidgets, pElem)) {
736       }
737       ListUnlinkAll(&gTidgetManager.toplevel_tidgets);
738    }
739    CleanUpTdgtBase();
740    CleanUpTdgtList();
741    CleanUpTdgtBtn();
742    CleanUpTdgtDraw();
743    CleanUpTdgtMsg();
744    CleanUpTdgtBtnRow();
745    CleanUpTdgtBmpList();
746    CleanUpTdgtSmplEdit();
747 
748    if (gTidgetManager.gc != NULL) {
749       XFreeGC(mainDisplay, gTidgetManager.gc);
750       gTidgetManager.gc = NULL;
751    }
752    memset(&gTidgetManager, 0, sizeof(TidgetManager));
753 }
754 
755