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/tdgtbtn.c,v 1.8 2011/05/16 16:22:00 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_TDGTBTN_C_
22 
23 #include "tgifdefs.h"
24 #include "patchlvl.h"
25 #include "tidget.h"
26 
27 #include "button.e"
28 #include "color.e"
29 #include "cursor.e"
30 #include "font.e"
31 #include "menu.e"
32 #include "msg.e"
33 #include "raster.e"
34 #include "rect.e"
35 #include "setup.e"
36 #include "tdgtbtn.e"
37 #include "tidget.e"
38 #include "util.e"
39 
40 static void RedrawTdgtBtn ARGS_DECL((TidgetInfo *pti));
41 static int TdgtBtnEventHandler ARGS_DECL((TidgetInfo *pti, XEvent *input,
42                 TidgetInfo *handling_pti));
43 static int IsTdgtBtnEvent ARGS_DECL((TidgetInfo *pti, XEvent *input,
44                 TidgetInfo **ppti_handler_tidget_return));
45 static void DestroyTdgtBtn ARGS_DECL((TidgetInfo *pti));
46 static void MapTdgtBtn ARGS_DECL((TidgetInfo *pti));
47 static void TdgtBtnMoveResize ARGS_DECL((TidgetInfo *pti, int x, int y,
48                 int w, int h));
49 static int TdgtBtnSendCmd ARGS_DECL((TidgetInfo *pti, int cmd_type,
50                 int cmd_arg, void *pv_cmd_userdata));
51 
52 static int gnBtnFontHeight=0;
53 static int gnBtnFontWidth=0;
54 static int gnBtnFontAsc=0;
55 static int gnBtnFontDes=0;
56 static XFontStruct *gnBtnFontPtr=NULL;
57 
58 /* --------------------- RedrawTdgtBtn() --------------------- */
59 
CalcTdgtBtnDim(text,min_len,h_pad,v_pad,pn_width,pn_height)60 void CalcTdgtBtnDim(text, min_len, h_pad, v_pad, pn_width, pn_height)
61    char *text;
62    int min_len, h_pad, v_pad, *pn_width, *pn_height;
63 {
64    int btn_w=ButtonWidth(text, min_len, NULL)+(h_pad<<1), btn_h=0;
65 
66    if (boldMsgFontSet != NULL || boldMsgFontPtr != NULL) {
67       btn_h = boldMsgFontHeight;
68    } else if (msgFontSet != NULL || msgFontPtr != NULL) {
69       btn_h = msgFontHeight;
70    } else {
71       btn_h = defaultFontHeight;
72    }
73    btn_h += (v_pad<<1)+(windowPadding<<1);
74 
75    if (pn_width != NULL) *pn_width = btn_w;
76    if (pn_height != NULL) *pn_height = btn_h;
77 }
78 
79 /* --------------------- RedrawTdgtBtn() --------------------- */
80 
81 static
DrawTdgtTextBtn(pTdgtBtn,pBBRec,str,len,down,pButtonFontInfo)82 void DrawTdgtTextBtn(pTdgtBtn, pBBRec, str, len, down, pButtonFontInfo)
83    TdgtBtn *pTdgtBtn;
84    struct BBRec *pBBRec;
85    char *str;
86    int len, down;
87    ButtonFontInfo *pButtonFontInfo;
88 {
89    if (down) {
90       DisplayButtonInBBox(pTdgtBtn->pti->tci.win, str, len, pBBRec,
91             BUTTON_INVERT, FALSE, 0, pButtonFontInfo);
92       if (threeDLook) {
93          TgDrawThreeDButton(mainDisplay, pTdgtBtn->pti->tci.win,
94                gTidgetManager.gc, pBBRec, TGBS_LOWRED, 2, TRUE);
95       }
96    } else {
97       DisplayButtonInBBox(pTdgtBtn->pti->tci.win, str, len, pBBRec,
98             BUTTON_NORMAL, FALSE, 0, pButtonFontInfo);
99       if (threeDLook) {
100          TgDrawThreeDButton(mainDisplay, pTdgtBtn->pti->tci.win,
101                gTidgetManager.gc, pBBRec, TGBS_RAISED, 2, TRUE);
102       }
103    }
104    TidgetManagerResetGC();
105 }
106 
107 static
RedrawTdgtBtn(pti)108 void RedrawTdgtBtn(pti)
109    TidgetInfo *pti;
110 {
111    TdgtBtn *pTdgtBtn=(TdgtBtn*)(pti->tidget);
112    struct BBRec bbox;
113    char *str=NULL;
114    int len=0, pixel=INVALID, btn_down=(pTdgtBtn->pti->tci.state != TGBS_NORMAL);
115    ButtonFontInfo btn_font_info;
116    XGCValues values;
117    Pixmap bitmap=None;
118 
119    SetBBRec(&bbox, 0, 0, pTdgtBtn->pti->tci.win_info.w,
120          pTdgtBtn->pti->tci.win_info.h);
121 
122    switch (pTdgtBtn->btn_type) {
123    case TGMUTYPE_TEXT:
124       str = ((pTdgtBtn->str == NULL) ? "" : pTdgtBtn->str);
125       len = strlen(str);
126       memset(&btn_font_info, 0, sizeof(ButtonFontInfo));
127       btn_font_info.font_style = pTdgtBtn->font_style;
128       DrawTdgtTextBtn(pTdgtBtn, &bbox, str, len, FALSE, &btn_font_info);
129       break;
130    case TGMUTYPE_COLOR:
131       if (colorDisplay) {
132          pixel = (btn_down ? myFgPixel : colorPixels[(int)(long)(pTdgtBtn->str)]);
133       } else {
134          pixel = myFgPixel;
135       }
136       values.foreground = pixel;
137       values.function = GXcopy;
138       values.fill_style = FillOpaqueStippled;
139       values.stipple = patPixmap[1];
140       XChangeGC(mainDisplay, gTidgetManager.gc,
141             GCForeground | GCFunction | GCFillStyle | GCStipple, &values);
142 
143       XFillRectangle(mainDisplay, pTdgtBtn->pti->tci.win, gTidgetManager.gc,
144             windowPadding, windowPadding, pTdgtBtn->pti->tci.content_w,
145             pTdgtBtn->pti->tci.content_h);
146       if (threeDLook) {
147          TgDrawThreeDButton(mainDisplay, pTdgtBtn->pti->tci.win,
148                gTidgetManager.gc, &bbox, (btn_down ? TGBS_LOWRED : TGBS_RAISED),
149                2, TRUE);
150       }
151       TidgetManagerResetGC();
152       break;
153    case TGMUTYPE_BITMAP:
154       bitmap = (*(Pixmap*)pTdgtBtn->str);
155       if (threeDLook) {
156          values.foreground = myFgPixel;
157          values.background = (threeDLook ? myLtGryPixel : myBgPixel);
158          values.function = GXcopy;
159          values.fill_style = FillStippled;
160          values.stipple = bitmap;
161          values.ts_x_origin = windowPadding;
162          values.ts_y_origin = windowPadding;
163          XChangeGC(mainDisplay, gTidgetManager.gc,
164                GCForeground | GCBackground | GCFunction | GCFillStyle |
165                GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &values);
166          XFillRectangle(mainDisplay, pTdgtBtn->pti->tci.win, gTidgetManager.gc,
167                values.ts_x_origin, values.ts_y_origin,
168                pTdgtBtn->pti->tci.content_w, pTdgtBtn->pti->tci.content_h);
169          XSetTSOrigin(mainDisplay, gTidgetManager.gc, 0, 0);
170          switch (pTdgtBtn->btn_style) {
171          case TDGTBTN_CLICK:
172             break;
173          case TDGTBTN_STICKY:
174             TidgetManagerResetGC();
175             TgDrawThreeDButton(mainDisplay, pTdgtBtn->pti->tci.win,
176                   gTidgetManager.gc, &bbox,
177                   (btn_down ? TGBS_LOWRED : TGBS_RAISED), 2, TRUE);
178             break;
179          }
180          TidgetManagerResetGC();
181       } else {
182          if (btn_down) {
183             values.foreground = myFgPixel;
184             values.fill_style = FillSolid;
185             XChangeGC(mainDisplay, gTidgetManager.gc,
186                   GCForeground | GCFillStyle, &values);
187 
188             XFillRectangle(mainDisplay, pTdgtBtn->pti->tci.win,
189                   gTidgetManager.gc, windowPadding, windowPadding,
190                   pTdgtBtn->pti->tci.content_w, pTdgtBtn->pti->tci.content_h);
191 
192             values.foreground = myFgPixel;
193             values.fill_style = FillStippled;
194             values.stipple = bitmap;
195             XChangeGC(mainDisplay, gTidgetManager.gc,
196                   GCForeground | GCFillStyle | GCStipple, &values);
197             XFillRectangle(mainDisplay, pTdgtBtn->pti->tci.win,
198                   gTidgetManager.gc, windowPadding, windowPadding,
199                   pTdgtBtn->pti->tci.content_w, pTdgtBtn->pti->tci.content_h);
200          } else {
201             values.foreground = myFgPixel;
202             values.fill_style = FillStippled;
203             values.stipple = bitmap;
204             XChangeGC(mainDisplay, gTidgetManager.gc,
205                   GCForeground | GCFillStyle | GCStipple, &values);
206 
207             XFillRectangle(mainDisplay, pTdgtBtn->pti->tci.win,
208                   gTidgetManager.gc, windowPadding, windowPadding,
209                   pTdgtBtn->pti->tci.content_w, pTdgtBtn->pti->tci.content_h);
210          }
211          TidgetManagerResetGC();
212       }
213       break;
214    }
215 }
216 
217 /* --------------------- TdgtBtnEventHandler() --------------------- */
218 
219 static
ButtonPressInTdgtBtn(pTdgtBtn,button_ev,pn_changing,pn_selected_btn_index)220 int ButtonPressInTdgtBtn(pTdgtBtn, button_ev, pn_changing,
221       pn_selected_btn_index)
222    TdgtBtn *pTdgtBtn;
223    XButtonEvent *button_ev;
224    int *pn_changing, *pn_selected_btn_index;
225 {
226    struct BBRec bbox;
227    char *str=NULL;
228    int len=0, looping=TRUE, selected=TRUE;
229    ButtonFontInfo btn_font_info;
230    XEvent ev;
231 
232    memset(&btn_font_info, 0, sizeof(ButtonFontInfo));
233    btn_font_info.font_style = pTdgtBtn->font_style;
234 
235    SetBBRec(&bbox, 0, 0, pTdgtBtn->pti->tci.win_info.w,
236          pTdgtBtn->pti->tci.win_info.h);
237 
238    if (!debugNoPointerGrab) {
239       XGrabPointer(mainDisplay, pTdgtBtn->pti->tci.win, False,
240             PointerMotionMask | ButtonReleaseMask, GrabModeAsync,
241             GrabModeAsync, None, handCursor, CurrentTime);
242    }
243    switch (pTdgtBtn->btn_type) {
244    case TGMUTYPE_TEXT:
245       str = ((pTdgtBtn->str == NULL) ? "" : pTdgtBtn->str);
246       len = strlen(str);
247       DrawTdgtTextBtn(pTdgtBtn, &bbox, str, len, TRUE, &btn_font_info);
248       break;
249    case TGMUTYPE_COLOR:
250       pTdgtBtn->pti->tci.state = TGBS_LOWRED;
251       RedrawTdgtBtn(pTdgtBtn->pti);
252       pTdgtBtn->pti->tci.state = TGBS_NORMAL;
253       break;
254    case TGMUTYPE_BITMAP:
255       break;
256    }
257    while (looping) {
258       XNextEvent(mainDisplay, &ev);
259 
260       if (ev.type == ButtonRelease) {
261          XUngrabPointer(mainDisplay, CurrentTime);
262          if (debugNoPointerGrab) XSync(mainDisplay, False);
263          looping = FALSE;
264       } else if (ev.type == MotionNotify) {
265          if (PointInBBox(ev.xmotion.x, ev.xmotion.y, bbox)) {
266             if (!selected) {
267                selected = TRUE;
268                switch (pTdgtBtn->btn_type) {
269                case TGMUTYPE_TEXT:
270                   DrawTdgtTextBtn(pTdgtBtn, &bbox, str, len, TRUE,
271                         &btn_font_info);
272                   break;
273                case TGMUTYPE_COLOR:
274                   pTdgtBtn->pti->tci.state = TGBS_LOWRED;
275                   RedrawTdgtBtn(pTdgtBtn->pti);
276                   pTdgtBtn->pti->tci.state = TGBS_NORMAL;
277                   break;
278                case TGMUTYPE_BITMAP: break;
279                }
280             }
281          } else {
282             if (selected) {
283                selected = FALSE;
284                switch (pTdgtBtn->btn_type) {
285                case TGMUTYPE_TEXT:
286                   DrawTdgtTextBtn(pTdgtBtn, &bbox, str, len, FALSE,
287                         &btn_font_info);
288                   break;
289                case TGMUTYPE_COLOR: RedrawTdgtBtn(pTdgtBtn->pti); break;
290                case TGMUTYPE_BITMAP: break;
291                }
292             }
293          }
294       }
295    }
296    if (selected) {
297       switch (pTdgtBtn->btn_type) {
298       case TGMUTYPE_TEXT:
299          DrawTdgtTextBtn(pTdgtBtn, &bbox, str, len, FALSE, &btn_font_info);
300          break;
301       case TGMUTYPE_COLOR: RedrawTdgtBtn(pTdgtBtn->pti); break;
302       case TGMUTYPE_BITMAP: break;
303       }
304    }
305    return selected;
306 }
307 
308 static
TdgtBtnEventHandler(pti,input,handling_pti)309 int TdgtBtnEventHandler(pti, input, handling_pti)
310    TidgetInfo *pti, *handling_pti;
311    XEvent *input;
312 {
313    TdgtBtn *pTdgtBtn=(TdgtBtn*)(pti->tidget);
314    int nf_arg=0, nf_arg2=INVALID;
315 
316    if (pti != handling_pti) return FALSE;
317 
318    if (input->type == Expose) {
319       XEvent ev;
320 
321       RedrawTdgtBtn(pTdgtBtn->pti);
322       while (XCheckWindowEvent(mainDisplay, pTdgtBtn->pti->tci.win,
323             ExposureMask, &ev)) ;
324    } else if (input->type == ButtonPress) {
325       switch (pTdgtBtn->btn_style) {
326       case TDGTBTN_CLICK:
327          switch (pTdgtBtn->btn_type) {
328          case TGMUTYPE_TEXT:
329             if (ButtonPressInTdgtBtn(pTdgtBtn, &input->xbutton, NULL, NULL)) {
330                /* clicked */
331                TidgetControlNotify(pTdgtBtn->pti, TDGTNF_BTN_CLICKED, 0, 0);
332                return TRUE;
333             }
334             break;
335          case TGMUTYPE_COLOR:
336             switch (input->xbutton.button) {
337             case Button1: nf_arg = (int)Button1; break;
338             case Button2:
339                {
340                   int x=0, y=0, root_x=0, root_y=0, color_index=0;
341                   Window root_win, child_win;
342                   unsigned int status=0;
343 
344                   XQueryPointer(mainDisplay, rootWindow, &root_win, &child_win,
345                         &root_x, &root_y, &x, &y, &status);
346                   gstMenuDontSendCommandInfo.dont_send_command = TRUE;
347                   gstMenuDontSendCommandInfo.selected_index = INVALID;
348                   ColorMenu(x, y, FALSE);
349                   color_index = gstMenuDontSendCommandInfo.selected_index;
350                   if (color_index >= 0 && color_index < maxColors) {
351                      nf_arg = Button2;
352                      nf_arg2 = color_index;
353                   }
354                   memset(&gstMenuDontSendCommandInfo, 0,
355                         sizeof(MenuDontSendCommandInfo));
356                }
357                break;
358             case Button3: nf_arg = Button3; break;
359             default: break;
360             }
361             if (nf_arg != 0) {
362                TidgetControlNotify(pTdgtBtn->pti, TDGTNF_MULTI_BTN_CLICKED,
363                      nf_arg, nf_arg2);
364             }
365             return TRUE;
366          case TGMUTYPE_BITMAP: break;
367          }
368          break;
369       case TDGTBTN_STICKY:
370          /* press it */
371          if (pTdgtBtn->pti->tci.state == TGBS_NORMAL) {
372             pTdgtBtn->pti->tci.state = TGBS_LOWRED;
373          } else {
374             pTdgtBtn->pti->tci.state = TGBS_NORMAL;
375          }
376          TidgetControlNotify(pTdgtBtn->pti, TDGTNF_BTN_CLICKED, 0, 0);
377          RedrawTdgtBtn(pTdgtBtn->pti);
378          return TRUE;
379       }
380    } else if (input->type == EnterNotify) {
381       if (pTdgtBtn->mosi.one_line_status) {
382          SetStringStatus(pTdgtBtn->mosi.one_line_str);
383       } else {
384          MouseOverStatusInfo *pmosi=(&pTdgtBtn->mosi);
385 
386          SetMouseStatus(pmosi->btn_str[0], pmosi->btn_str[1],
387                pmosi->btn_str[2]);
388       }
389    } else if (input->type == LeaveNotify) {
390       SetMouseStatus("", "", "");
391    }
392    return FALSE;
393 }
394 
395 /* --------------------- IsTdgtBtnEvent() --------------------- */
396 
397 static
IsTdgtBtnEvent(pti,input,ppti_handler_tidget_return)398 int IsTdgtBtnEvent(pti, input, ppti_handler_tidget_return)
399    TidgetInfo *pti, **ppti_handler_tidget_return;
400    XEvent *input;
401 {
402    TdgtBtn *pTdgtBtn=(TdgtBtn*)(pti->tidget);
403 
404    if (input->xany.window == pTdgtBtn->pti->tci.win) return TRUE;
405 
406    return FALSE;
407 }
408 
409 /* --------------------- DestroyTdgtBtn() --------------------- */
410 
411 static
DestroyTdgtBtn(pti)412 void DestroyTdgtBtn(pti)
413    TidgetInfo *pti;
414 {
415    TdgtBtn *pTdgtBtn=(TdgtBtn*)(pti->tidget);
416 
417    TdgtBtnReset(pTdgtBtn);
418 
419    free(pTdgtBtn);
420 }
421 
422 /* --------------------- MapTdgtBtn() --------------------- */
423 
424 static
MapTdgtBtn(pti)425 void MapTdgtBtn(pti)
426    TidgetInfo *pti;
427 {
428    TdgtBtn *pTdgtBtn=(TdgtBtn*)(pti->tidget);
429 
430 #ifdef MAPBEFORESELECT
431    XMapWindow(mainDisplay, pTdgtBtn->pti->tci.win);
432    XSelectInput(mainDisplay, pTdgtBtn->pti->tci.win,
433          ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
434          EnterWindowMask | LeaveWindowMask);
435 #else
436    XSelectInput(mainDisplay, pTdgtBtn->pti->tci.win,
437          ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
438          EnterWindowMask | LeaveWindowMask);
439    XMapWindow(mainDisplay, pTdgtBtn->pti->tci.win);
440 #endif
441 }
442 
443 /* --------------------- TdgtBtnMoveResize() --------------------- */
444 
445 static
TdgtBtnMoveResize(pti,x,y,w,h)446 void TdgtBtnMoveResize(pti, x, y, w, h)
447    TidgetInfo *pti;
448    int x, y, w, h;
449 {
450    TdgtBtn *pTdgtBtn=(TdgtBtn*)(pti->tidget);
451 
452    /* there should be no need to resize a button */
453    pTdgtBtn->pti->tci.win_info.x = x;
454    pTdgtBtn->pti->tci.win_info.y = y;
455    pTdgtBtn->pti->tci.win_info.w = w;
456    pTdgtBtn->pti->tci.win_info.h = h;
457    XMoveResizeWindow(mainDisplay, pTdgtBtn->pti->tci.win, x, y, w, h);
458 }
459 
460 /* --------------------- TdgtBtnSendCmd() --------------------- */
461 
462 static
TdgtBtnSendCmd(pti,cmd_type,cmd_arg,pv_cmd_userdata)463 int TdgtBtnSendCmd(pti, cmd_type, cmd_arg, pv_cmd_userdata)
464    TidgetInfo *pti;
465    int cmd_type, cmd_arg;
466    void *pv_cmd_userdata;
467 {
468    TdgtBtn *pTdgtBtn=(TdgtBtn*)(pti->tidget);
469 
470    if (pTdgtBtn != NULL) {
471    }
472    return FALSE;
473 }
474 
475 /* --------------------- TdgtBtnReset() --------------------- */
476 
TdgtBtnReset(pTdgtBtn)477 void TdgtBtnReset(pTdgtBtn)
478    TdgtBtn *pTdgtBtn;
479 {
480    switch (pTdgtBtn->btn_type) {
481    case TGMUTYPE_TEXT: UtilFree(pTdgtBtn->str); break;
482    case TGMUTYPE_COLOR: break;
483    case TGMUTYPE_BITMAP: break;
484    }
485    pTdgtBtn->str = NULL;
486 }
487 
488 /* --------------------- CreateTdgtBtn() --------------------- */
489 
CreateTdgtBtn(parent_win,parent_tidgetinfo,ctl_id,x,y,w,h,h_pad,v_pad,btn_type,btn_style,state,font_style,str,pmosi)490 TdgtBtn *CreateTdgtBtn(parent_win, parent_tidgetinfo, ctl_id, x, y, w, h, h_pad,
491       v_pad, btn_type, btn_style, state, font_style, str, pmosi)
492    Window parent_win;
493    TidgetInfo *parent_tidgetinfo;
494    int ctl_id, x, y, w, h, h_pad, v_pad, state, font_style;
495    char *str;
496    MouseOverStatusInfo *pmosi;
497 {
498    int bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel);
499    TdgtBtn *pTdgtBtn=NULL;
500 
501    pTdgtBtn = (TdgtBtn*)malloc(sizeof(TdgtBtn));
502    if (pTdgtBtn == NULL) FailAllocMessage();
503    memset(pTdgtBtn, 0, sizeof(TdgtBtn));
504 
505    pTdgtBtn->pti = NewTidgetInfo(parent_tidgetinfo, TIDGET_TYPE_BTN, pTdgtBtn,
506          ctl_id, NULL);
507    if ((pTdgtBtn->pti->tci.win=XCreateSimpleWindow(mainDisplay, parent_win,
508          x, y, w, h, brdrW, myBorderPixel, bg_pixel)) == 0) {
509       FailToCreateWindowMessage("CreateTdgtBtn()", NULL, TRUE);
510    }
511    XSelectInput(mainDisplay, pTdgtBtn->pti->tci.win,
512          ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
513          EnterWindowMask | LeaveWindowMask);
514    SetTidgetInfoBasic(pTdgtBtn->pti, TIDGET_TYPE_BTN, pTdgtBtn, parent_win,
515          x, y, w, h, h_pad, v_pad, state, NULL);
516    TidgetSetCallbacks(pTdgtBtn->pti,
517          RedrawTdgtBtn, TdgtBtnEventHandler, IsTdgtBtnEvent, DestroyTdgtBtn,
518          MapTdgtBtn, TdgtBtnMoveResize, TdgtBtnSendCmd);
519 
520    switch (btn_type) {
521    case TGMUTYPE_TEXT:
522       if (str != NULL) {
523          pTdgtBtn->str = UtilStrDup(str);
524          if (pTdgtBtn->str == NULL) FailAllocMessage();
525       }
526       break;
527    case TGMUTYPE_COLOR: pTdgtBtn->str = str; break;
528    case TGMUTYPE_BITMAP: pTdgtBtn->str = str; break;
529    }
530    if (pmosi != NULL) {
531       memcpy(&pTdgtBtn->mosi, pmosi, sizeof(MouseOverStatusInfo));
532    }
533    pTdgtBtn->btn_type = btn_type;
534    pTdgtBtn->btn_style = btn_style;
535    pTdgtBtn->font_style = font_style;
536 
537    return pTdgtBtn;
538 }
539 
540 /* --------------------- TdgtBtnSetText() --------------------- */
541 
TdgtBtnSetText(pTdgtBtn,str,pmosi)542 int TdgtBtnSetText(pTdgtBtn, str, pmosi)
543    TdgtBtn *pTdgtBtn;
544    char *str;
545    MouseOverStatusInfo *pmosi;
546 {
547    switch (pTdgtBtn->btn_type) {
548    case TGMUTYPE_TEXT:
549       UtilFree(pTdgtBtn->str);
550       if (str != NULL) {
551          pTdgtBtn->str = UtilStrDup(str);
552          if (pTdgtBtn->str == NULL) FailAllocMessage();
553       }
554       break;
555    case TGMUTYPE_COLOR: pTdgtBtn->str = str; break;
556    case TGMUTYPE_BITMAP: pTdgtBtn->str = str; break;
557    }
558    if (pmosi != NULL) {
559       memcpy(&pTdgtBtn->mosi, pmosi, sizeof(MouseOverStatusInfo));
560    }
561    RedrawTdgtBtn(pTdgtBtn->pti);
562 
563    return TRUE;
564 }
565 
566 /* --------------------- TdgtBtnGetText() --------------------- */
567 
TdgtBtnGetText(pTdgtBtn)568 char *TdgtBtnGetText(pTdgtBtn)
569    TdgtBtn *pTdgtBtn;
570 {
571    return pTdgtBtn->str;
572 }
573 
574 /* --------------------- TdgtBtnSetState() --------------------- */
575 
TdgtBtnSetState(pTdgtBtn,new_state)576 int TdgtBtnSetState(pTdgtBtn, new_state)
577    TdgtBtn *pTdgtBtn;
578    int new_state;
579 {
580    int need_to_redraw=(pTdgtBtn->pti->tci.state != new_state);
581 
582    pTdgtBtn->pti->tci.state = new_state;
583    if (need_to_redraw) {
584       RedrawTdgtBtn(pTdgtBtn->pti);
585    }
586    return TRUE;
587 }
588 
589 /* --------------------- TdgtBtnGetState() --------------------- */
590 
TdgtBtnGetState(pTdgtBtn)591 int TdgtBtnGetState(pTdgtBtn)
592    TdgtBtn *pTdgtBtn;
593 {
594    return pTdgtBtn->pti->tci.state;
595 }
596 
597 /* --------------------- Init & Clean Up --------------------- */
598 
InitTdgtBtn()599 int InitTdgtBtn()
600 {
601    if (msgFontSet == NULL && msgFontPtr == NULL) {
602       gnBtnFontHeight = defaultFontHeight;
603       gnBtnFontWidth = defaultFontWidth;
604       gnBtnFontAsc = defaultFontAsc;
605       gnBtnFontDes = defaultFontDes;
606       gnBtnFontPtr = defaultFontPtr;
607    } else {
608       gnBtnFontHeight = msgFontHeight;
609       gnBtnFontWidth = msgFontWidth;
610       gnBtnFontAsc = msgFontAsc;
611       gnBtnFontDes = msgFontDes;
612       gnBtnFontPtr = msgFontPtr;
613    }
614    return TRUE;
615 }
616 
CleanUpTdgtBtn()617 void CleanUpTdgtBtn()
618 {
619    gnBtnFontHeight = gnBtnFontWidth = gnBtnFontAsc = gnBtnFontDes = 0;
620    gnBtnFontPtr = NULL;
621 }
622 
623