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/tdgtmsg.c,v 1.9 2011/05/16 16:22:00 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_TDGTMSG_C_
22 
23 #include "tgifdefs.h"
24 #include "patchlvl.h"
25 #include "tidget.h"
26 
27 #include "choose.e"
28 #include "cursor.e"
29 #include "font.e"
30 #include "menu.e"
31 #include "msg.e"
32 #include "raster.e"
33 #include "rect.e"
34 #include "setup.e"
35 #include "tdgtmsg.e"
36 #include "text.e"
37 #include "tidget.e"
38 #include "util.e"
39 
40 static void RedrawTdgtMsg ARGS_DECL((TidgetInfo *pti));
41 static int TdgtMsgEventHandler ARGS_DECL((TidgetInfo *pti, XEvent *input,
42                 TidgetInfo *handling_pti));
43 static int IsTdgtMsgEvent ARGS_DECL((TidgetInfo *pti, XEvent *input,
44                 TidgetInfo **ppti_handler_tidget_return));
45 static void DestroyTdgtMsg ARGS_DECL((TidgetInfo *pti));
46 static void MapTdgtMsg ARGS_DECL((TidgetInfo *pti));
47 static void TdgtMsgMoveResize ARGS_DECL((TidgetInfo *pti, int x, int y,
48                 int w, int h));
49 static int TdgtMsgSendCmd ARGS_DECL((TidgetInfo *pti, int cmd_type,
50                 int cmd_arg, void *pv_cmd_userdata));
51 
52 /* --------------------- RedrawTdgtMsg() --------------------- */
53 
54 static
TdgtMsgDrawCaption(pTdgtMsg)55 void TdgtMsgDrawCaption(pTdgtMsg)
56    TdgtMsg *pTdgtMsg;
57 {
58    int x=windowPadding+pTdgtMsg->pti->tci.h_pad;
59    int y=windowPadding+pTdgtMsg->pti->tci.v_pad;
60    int just=pTdgtMsg->just;
61    int win_w=pTdgtMsg->pti->tci.win_info.w;
62    char *psz=NULL, *psz_cur=TdgtMsgGetText(pTdgtMsg);
63 
64    if (boldMsgFontSet != NULL || boldMsgFontPtr != NULL) {
65        if (boldMsgFontPtr != NULL) {
66           XSetFont(mainDisplay, gTidgetManager.gc, boldMsgFontPtr->fid);
67        }
68        y += boldMsgFontAsc;
69    } else if (msgFontSet != NULL || msgFontPtr != NULL) {
70        XSetFont(mainDisplay, gTidgetManager.gc, msgFontPtr->fid);
71        y += msgFontAsc;
72    } else {
73        y += defaultFontAsc;
74    }
75    switch (just) {
76    case JUST_L: break;
77    case JUST_C: x = (win_w>>1); break;
78    case JUST_R: x = win_w-windowPadding-pTdgtMsg->pti->tci.h_pad; break;
79    }
80    do {
81       int line_w=0;
82 
83       psz = strchr(psz_cur, '\n');
84       if (psz != NULL) *psz = '\0';
85 
86       switch (just) {
87       case JUST_L:
88          DrawBoldMsgString(mainDisplay, pTdgtMsg->pti->tci.win,
89                gTidgetManager.gc, x, y, psz_cur, strlen(psz_cur));
90          break;
91       case JUST_C:
92          line_w = BoldMsgTextWidth(boldMsgFontPtr, psz_cur, strlen(psz_cur));
93          DrawBoldMsgString(mainDisplay, pTdgtMsg->pti->tci.win,
94                gTidgetManager.gc, x-(line_w>>1), y, psz_cur, strlen(psz_cur));
95          break;
96       case JUST_R:
97          line_w = BoldMsgTextWidth(boldMsgFontPtr, psz_cur, strlen(psz_cur));
98          DrawBoldMsgString(mainDisplay, pTdgtMsg->pti->tci.win,
99                gTidgetManager.gc, x-line_w, y, psz_cur, strlen(psz_cur));
100          break;
101       }
102       if (boldMsgFontSet != NULL || boldMsgFontPtr != NULL) {
103           y += boldMsgFontHeight;
104       } else if (msgFontSet != NULL || msgFontPtr != NULL) {
105           y += msgFontHeight;
106       } else {
107           y += defaultFontHeight;
108       }
109       if (psz != NULL) {
110          *psz++ = '\n';
111          psz_cur = psz;
112       } else {
113          psz_cur = NULL;
114       }
115    } while (psz != NULL);
116    TidgetManagerResetGC();
117 }
118 
119 static
RedrawTdgtMsg(pti)120 void RedrawTdgtMsg(pti)
121    TidgetInfo *pti;
122 {
123    TdgtMsg *pTdgtMsg=(TdgtMsg*)(pti->tidget);
124 
125    XClearWindow(mainDisplay, pTdgtMsg->pti->tci.win);
126 
127    if (threeDLook) {
128       struct BBRec bbox;
129 
130       SetBBRec(&bbox, 0, 0, pTdgtMsg->pti->tci.win_info.w,
131             pTdgtMsg->pti->tci.win_info.h);
132       switch (pTdgtMsg->pti->tci.state) {
133       case TGBS_NORMAL: break;
134       default:
135          TgDrawThreeDButton(mainDisplay, pTdgtMsg->pti->tci.win,
136                gTidgetManager.gc, &bbox, pTdgtMsg->pti->tci.state, 2, TRUE);
137          TidgetManagerResetGC();
138          break;
139       }
140    } else {
141       /*
142        * XDrawRectangle(mainDisplay, pTdgtMsg->pti->tci.win, gTidgetManager.gc,
143        *       0, 0, pTdgtMsg->pti->tci.win_info.w,
144        *       pTdgtMsg->pti->tci.win_info.h);
145        */
146    }
147    TdgtMsgDrawCaption(pTdgtMsg);
148 }
149 
150 /* --------------------- TdgtMsgEventHandler() --------------------- */
151 
152 static
TdgtMsgEventHandler(pti,input,handling_pti)153 int TdgtMsgEventHandler(pti, input, handling_pti)
154    TidgetInfo *pti, *handling_pti;
155    XEvent *input;
156 {
157    TdgtMsg *pTdgtMsg=(TdgtMsg*)(pti->tidget);
158 
159    if (pti != handling_pti) return FALSE;
160 
161    if (input->type == Expose) {
162       XEvent ev;
163 
164       RedrawTdgtMsg(pTdgtMsg->pti);
165       while (XCheckWindowEvent(mainDisplay, pTdgtMsg->pti->tci.win,
166             ExposureMask, &ev)) ;
167    }
168    return FALSE;
169 }
170 
171 /* --------------------- IsTdgtMsgEvent() --------------------- */
172 
173 static
IsTdgtMsgEvent(pti,input,ppti_handler_tidget_return)174 int IsTdgtMsgEvent(pti, input, ppti_handler_tidget_return)
175    TidgetInfo *pti, **ppti_handler_tidget_return;
176    XEvent *input;
177 {
178    TdgtMsg *pTdgtMsg=(TdgtMsg*)(pti->tidget);
179 
180    if (input->xany.window == pTdgtMsg->pti->tci.win) {
181       *ppti_handler_tidget_return = pti;
182       return TRUE;
183    }
184    return FALSE;
185 }
186 
187 /* --------------------- DestroyTdgtMsg() --------------------- */
188 
189 static
DestroyTdgtMsg(pti)190 void DestroyTdgtMsg(pti)
191    TidgetInfo *pti;
192 {
193    TdgtMsg *pTdgtMsg=(TdgtMsg*)(pti->tidget);
194 
195    TdgtMsgReset(pTdgtMsg);
196 
197    free(pTdgtMsg);
198 }
199 
200 /* --------------------- MapTdgtMsg() --------------------- */
201 
202 static
MapTdgtMsg(pti)203 void MapTdgtMsg(pti)
204    TidgetInfo *pti;
205 {
206    TdgtMsg *pTdgtMsg=(TdgtMsg*)(pti->tidget);
207 
208 #ifdef MAPBEFORESELECT
209    XMapWindow(mainDisplay, pTdgtMsg->pti->tci.win);
210    XSelectInput(mainDisplay, pTdgtMsg->pti->tci.win,
211          ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
212          EnterWindowMask | LeaveWindowMask);
213 #else
214    XSelectInput(mainDisplay, pTdgtMsg->pti->tci.win,
215          ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
216          EnterWindowMask | LeaveWindowMask);
217    XMapWindow(mainDisplay, pTdgtMsg->pti->tci.win);
218 #endif
219 }
220 
221 /* --------------------- TdgtMsgMoveResize() --------------------- */
222 
223 static
TdgtMsgMoveResize(pti,x,y,w,h)224 void TdgtMsgMoveResize(pti, x, y, w, h)
225    TidgetInfo *pti;
226    int x, y, w, h;
227 {
228    TdgtMsg *pTdgtMsg=(TdgtMsg*)(pti->tidget);
229 
230    /* there should be no need to resize a button */
231    pTdgtMsg->pti->tci.win_info.x = x;
232    pTdgtMsg->pti->tci.win_info.y = y;
233    pTdgtMsg->pti->tci.win_info.w = w;
234    pTdgtMsg->pti->tci.win_info.h = h;
235    XMoveResizeWindow(mainDisplay, pTdgtMsg->pti->tci.win, x, y, w, h);
236 }
237 
238 /* --------------------- TdgtMsgSendCmd() --------------------- */
239 
240 static
TdgtMsgSendCmd(pti,cmd_type,cmd_arg,pv_cmd_userdata)241 int TdgtMsgSendCmd(pti, cmd_type, cmd_arg, pv_cmd_userdata)
242    TidgetInfo *pti;
243    int cmd_type, cmd_arg;
244    void *pv_cmd_userdata;
245 {
246    TdgtMsg *pTdgtMsg=(TdgtMsg*)(pti->tidget);
247 
248    if (pTdgtMsg != NULL) {
249    }
250    return FALSE;
251 }
252 
253 /* --------------------- TdgtMsgReset() --------------------- */
254 
TdgtMsgReset(pTdgtMsg)255 void TdgtMsgReset(pTdgtMsg)
256    TdgtMsg *pTdgtMsg;
257 {
258    FreeDynStrBuf(&pTdgtMsg->pti->tci.dyn_str);
259 }
260 
261 /* --------------------- CreateTdgtMsg() --------------------- */
262 
263 static
TdgtMsgCalcGeom(caption,pn_w,pn_h)264 void TdgtMsgCalcGeom(caption, pn_w, pn_h)
265    char *caption;
266    int *pn_w, *pn_h;
267 {
268    int w=0, h=0;
269    char *psz=NULL, *psz_cur=NULL, *dup_caption=UtilStrDup(caption);
270 
271    if (dup_caption == NULL) FailAllocMessage();
272 
273    psz_cur = dup_caption;
274    do {
275       int line_w=0;
276 
277       psz = strchr(psz_cur, '\n');
278       if (psz != NULL) *psz = '\0';
279       line_w = BoldMsgTextWidth(boldMsgFontPtr, psz_cur, strlen(psz_cur));
280       if (line_w > w) w = line_w;
281       if (boldMsgFontSet != NULL || boldMsgFontPtr != NULL) {
282           h += boldMsgFontHeight;
283       } else if (msgFontSet != NULL || msgFontPtr != NULL) {
284           h += msgFontHeight;
285       } else {
286           h += defaultFontHeight;
287       }
288       if (psz != NULL) {
289          *psz++ = '\n';
290          psz_cur = psz;
291       } else {
292          psz_cur = NULL;
293       }
294    } while (psz != NULL);
295 
296    UtilFree(dup_caption);
297 
298    if (pn_w != NULL) *pn_w = w;
299    if (pn_h != NULL) *pn_h = h;
300 }
301 
CreateTdgtMsg(parent_win,parent_tidgetinfo,ctl_id,x,y,h_pad,v_pad,state,caption,just)302 TdgtMsg *CreateTdgtMsg(parent_win, parent_tidgetinfo, ctl_id, x, y, h_pad,
303       v_pad, state, caption, just)
304    Window parent_win;
305    TidgetInfo *parent_tidgetinfo;
306    int ctl_id, x, y, h_pad, v_pad, state, just;
307    char *caption;
308 {
309    int bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel), w=0, h=0;
310    TdgtMsg *pTdgtMsg=NULL;
311 
312    if (caption != NULL) {
313       int msg_w=0, msg_h=0;
314 
315       TdgtMsgCalcGeom(caption, &msg_w, &msg_h);
316       w = msg_w + (windowPadding<<1) + (h_pad<<1);
317       h = msg_h + (windowPadding<<1) + (v_pad<<1);
318    }
319    pTdgtMsg = (TdgtMsg*)malloc(sizeof(TdgtMsg));
320    if (pTdgtMsg == NULL) FailAllocMessage();
321    memset(pTdgtMsg, 0, sizeof(TdgtMsg));
322 
323    pTdgtMsg->pti = NewTidgetInfo(parent_tidgetinfo, TIDGET_TYPE_MSG, pTdgtMsg,
324          ctl_id, NULL);
325    if ((pTdgtMsg->pti->tci.win=XCreateSimpleWindow(mainDisplay, parent_win,
326          x, y, w, h, brdrW, myBorderPixel, bg_pixel)) == 0) {
327       FailToCreateWindowMessage("CreateTdgtMsg()", NULL, TRUE);
328       return NULL;
329    }
330    XSelectInput(mainDisplay, pTdgtMsg->pti->tci.win,
331          ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
332          EnterWindowMask | LeaveWindowMask);
333    SetTidgetInfoBasic(pTdgtMsg->pti, TIDGET_TYPE_MSG, pTdgtMsg, parent_win,
334          x, y, w, h, h_pad, v_pad, state, caption);
335    TidgetSetCallbacks(pTdgtMsg->pti,
336          RedrawTdgtMsg, TdgtMsgEventHandler, IsTdgtMsgEvent, DestroyTdgtMsg,
337          MapTdgtMsg, TdgtMsgMoveResize, TdgtMsgSendCmd);
338 
339    pTdgtMsg->just = just;
340 
341    return pTdgtMsg;
342 }
343 
344 /* --------------------- TdgtMsgSetText() --------------------- */
345 
TdgtMsgSetText(pTdgtMsg,str)346 int TdgtMsgSetText(pTdgtMsg, str)
347    TdgtMsg *pTdgtMsg;
348    char *str;
349 {
350    RedrawTdgtMsg(pTdgtMsg->pti);
351    if (str != NULL) {
352       FreeDynStrBuf(&(pTdgtMsg->pti->tci.dyn_str));
353       DynStrSet(&(pTdgtMsg->pti->tci.dyn_str), str);
354    }
355    return TRUE;
356 }
357 
358 /* --------------------- TdgtMsgGetText() --------------------- */
359 
TdgtMsgGetText(pTdgtMsg)360 char *TdgtMsgGetText(pTdgtMsg)
361    TdgtMsg *pTdgtMsg;
362 {
363    return pTdgtMsg->pti->tci.dyn_str.s;
364 }
365 
366 /* --------------------- TdgtMsgSetState() --------------------- */
367 
TdgtMsgSetState(pTdgtMsg,new_state)368 int TdgtMsgSetState(pTdgtMsg, new_state)
369    TdgtMsg *pTdgtMsg;
370    int new_state;
371 {
372    int need_to_redraw=(pTdgtMsg->pti->tci.state != new_state);
373 
374    pTdgtMsg->pti->tci.state = new_state;
375    if (need_to_redraw) {
376       RedrawTdgtMsg(pTdgtMsg->pti);
377    }
378    return TRUE;
379 }
380 
381 /* --------------------- TdgtMsgGetState() --------------------- */
382 
TdgtMsgGetState(pTdgtMsg)383 int TdgtMsgGetState(pTdgtMsg)
384    TdgtMsg *pTdgtMsg;
385 {
386    return pTdgtMsg->pti->tci.state;
387 }
388 
389 /* --------------------- Init & Clean Up --------------------- */
390 
InitTdgtMsg()391 int InitTdgtMsg()
392 {
393    return TRUE;
394 }
395 
CleanUpTdgtMsg()396 void CleanUpTdgtMsg()
397 {
398 }
399 
400