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/tdgtbase.c,v 1.8 2011/05/16 16:21:59 william Exp $
19 */
20
21 #define _INCLUDE_FROM_TDGTBASE_C_
22
23 #include "tgifdefs.h"
24 #include "patchlvl.h"
25 #include "tidget.h"
26
27 #include "cursor.e"
28 #include "menu.e"
29 #include "msg.e"
30 #include "raster.e"
31 #include "rect.e"
32 #include "setup.e"
33 #include "tdgtbase.e"
34 #include "text.e"
35 #include "tidget.e"
36 #include "util.e"
37
38 static void RedrawTdgtBase ARGS_DECL((TidgetInfo *pti));
39 static int TdgtBaseEventHandler ARGS_DECL((TidgetInfo *pti, XEvent *input,
40 TidgetInfo *handling_pti));
41 static int IsTdgtBaseEvent ARGS_DECL((TidgetInfo *pti, XEvent *input,
42 TidgetInfo **ppti_handler_tidget_return));
43 static void DestroyTdgtBase ARGS_DECL((TidgetInfo *pti));
44 static void MapTdgtBase ARGS_DECL((TidgetInfo *pti));
45 static void TdgtBaseMoveResize ARGS_DECL((TidgetInfo *pti, int x, int y,
46 int w, int h));
47 static int TdgtBaseSendCmd ARGS_DECL((TidgetInfo *pti, int cmd_type,
48 int cmd_arg, void *pv_cmd_userdata));
49
50 /* --------------------- RedrawTdgtBase() --------------------- */
51
52 static
RedrawTdgtBase(pti)53 void RedrawTdgtBase(pti)
54 TidgetInfo *pti;
55 {
56 TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
57 CVListElem *pElem=NULL;
58
59 XClearWindow(mainDisplay, pTdgtBase->pti->tci.win);
60
61 if (threeDLook) {
62 struct BBRec bbox;
63
64 SetBBRec(&bbox, 0, 0, pTdgtBase->pti->tci.win_info.w,
65 pTdgtBase->pti->tci.win_info.h);
66 switch (pTdgtBase->pti->tci.state) {
67 case TGBS_NORMAL: break;
68 default:
69 TgDrawThreeDButton(mainDisplay, pTdgtBase->pti->tci.win,
70 gTidgetManager.gc, &bbox, pTdgtBase->pti->tci.state, 2, FALSE);
71 break;
72 }
73 } else {
74 XDrawRectangle(mainDisplay, pTdgtBase->pti->tci.win, gTidgetManager.gc, 0,
75 0, pTdgtBase->pti->tci.win_info.w, pTdgtBase->pti->tci.win_info.h);
76 }
77 for (pElem=ListFirst(&pTdgtBase->pti->tci.clist); pElem != NULL;
78 pElem=ListNext(&pTdgtBase->pti->tci.clist, pElem)) {
79 TidgetInfo *pti=(TidgetInfo*)(pElem->obj);
80
81 if (pti != NULL) {
82 RedrawTidget(pti);
83 }
84 }
85 TidgetManagerResetGC();
86 }
87
88 /* --------------------- TdgtBaseEventHandler() --------------------- */
89
90 static
TdgtBaseEventHandler(pti,input,handling_pti)91 int TdgtBaseEventHandler(pti, input, handling_pti)
92 TidgetInfo *pti, *handling_pti;
93 XEvent *input;
94 {
95 TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
96 CVListElem *pElem=NULL;
97
98 if (pti == handling_pti) {
99 if (input->type == KeyPress &&
100 pTdgtBase->pf_key_press_ev_handler_callback != NULL) {
101 return (pTdgtBase->pf_key_press_ev_handler_callback)(pTdgtBase, input);
102 }
103 if (input->xany.window == pTdgtBase->pti->tci.win) {
104 if (IsWM_DELETE_WINDOW(input)) {
105 if (pTdgtBase->pf_wm_delete_ev_handler_callback != NULL) {
106 (pTdgtBase->pf_wm_delete_ev_handler_callback)(pTdgtBase);
107 }
108 } else if (input->type == Expose) {
109 XEvent ev;
110
111 RedrawTdgtBase(pTdgtBase->pti);
112 while (XCheckWindowEvent(mainDisplay, pTdgtBase->pti->tci.win,
113 ExposureMask, &ev)) ;
114 } else if (input->type == EnterNotify) {
115 /* may be we need to do something here */
116 } else if (input->type == LeaveNotify) {
117 /* may be we need to do something here */
118 }
119 return FALSE;
120 }
121 }
122 for (pElem=ListFirst(&pTdgtBase->pti->tci.clist); pElem != NULL;
123 pElem=ListNext(&pTdgtBase->pti->tci.clist, pElem)) {
124 TidgetInfo *pti=(TidgetInfo*)(pElem->obj);
125
126 if (pti != NULL) {
127 if (TdgtBaseEventHandler(pti, input, handling_pti)) {
128 return TRUE;
129 }
130 }
131 }
132 return FALSE;
133 }
134
135 /* --------------------- IsTdgtBaseEvent() --------------------- */
136
137 static
IsTdgtBaseEvent(pti,input,ppti_handler_tidget_return)138 int IsTdgtBaseEvent(pti, input, ppti_handler_tidget_return)
139 TidgetInfo *pti, **ppti_handler_tidget_return;
140 XEvent *input;
141 {
142 TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
143
144 if (input->type == KeyPress &&
145 pTdgtBase->pf_key_press_ev_handler_callback != NULL) {
146 CVListElem *pElem=NULL;
147
148 if (input->xany.window == pTdgtBase->pti->tci.win) {
149 *ppti_handler_tidget_return = pti;
150 return TRUE;
151 }
152 for (pElem=ListFirst(&pTdgtBase->pti->tci.clist); pElem != NULL;
153 pElem=ListNext(&pTdgtBase->pti->tci.clist, pElem)) {
154 TidgetInfo *pti=(TidgetInfo*)(pElem->obj);
155
156 if (pti != NULL) {
157 TidgetInfo *dummy_pti=NULL;
158
159 if (IsTidgetEvent(pti, input, &dummy_pti)) {
160 *ppti_handler_tidget_return = pti;
161 return TRUE;
162 }
163 }
164 }
165 }
166 return FALSE;
167 }
168
169 /* --------------------- DestroyTdgtBase() --------------------- */
170
171 static
DestroyTdgtBase(pti)172 void DestroyTdgtBase(pti)
173 TidgetInfo *pti;
174 {
175 TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
176
177 TdgtBaseReset(pTdgtBase);
178
179 free(pTdgtBase);
180 }
181
182 /* --------------------- MapTdgtBase() --------------------- */
183
184 static
MapTdgtBase(pti)185 void MapTdgtBase(pti)
186 TidgetInfo *pti;
187 {
188 TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
189 CVListElem *pElem=NULL;
190
191 #ifdef MAPBEFORESELECT
192 XMapWindow(mainDisplay, pTdgtBase->pti->tci.win);
193 XSelectInput(mainDisplay, pTdgtBase->win, StructureNotifyMask |
194 ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
195 EnterWindowMask | LeaveWindowMask);
196 #else
197 XSelectInput(mainDisplay, pTdgtBase->pti->tci.win, StructureNotifyMask |
198 ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
199 EnterWindowMask | LeaveWindowMask);
200 XMapWindow(mainDisplay, pTdgtBase->pti->tci.win);
201 #endif
202 for (pElem=ListFirst(&pTdgtBase->pti->tci.clist); pElem != NULL;
203 pElem=ListNext(&pTdgtBase->pti->tci.clist, pElem)) {
204 TidgetInfo *pti=(TidgetInfo*)(pElem->obj);
205
206 if (pti != NULL) {
207 MapTidget(pti);
208 }
209 }
210 }
211
212 /* --------------------- TdgtBaseMoveResize() --------------------- */
213
214 static
TdgtBaseMoveResize(pti,x,y,w,h)215 void TdgtBaseMoveResize(pti, x, y, w, h)
216 TidgetInfo *pti;
217 int x, y, w, h;
218 {
219 TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
220
221 /* there should be no need to resize a button */
222 pTdgtBase->pti->tci.win_info.x = x;
223 pTdgtBase->pti->tci.win_info.y = y;
224 pTdgtBase->pti->tci.win_info.w = w;
225 pTdgtBase->pti->tci.win_info.h = h;
226 XMoveResizeWindow(mainDisplay, pTdgtBase->pti->tci.win, x, y, w, h);
227 }
228
229 /* --------------------- TdgtBaseSendCmd() --------------------- */
230
231 static
TdgtBaseSendCmd(pti,cmd_type,cmd_arg,pv_cmd_userdata)232 int TdgtBaseSendCmd(pti, cmd_type, cmd_arg, pv_cmd_userdata)
233 TidgetInfo *pti;
234 int cmd_type, cmd_arg;
235 void *pv_cmd_userdata;
236 {
237 TdgtBase *pTdgtBase=(TdgtBase*)(pti->tidget);
238
239 if (pTdgtBase != NULL) {
240 switch (cmd_type) {
241 case TDGTCMD_CAN_HANDLE_FOCUS_CHANGE:
242 return (pTdgtBase->pf_focus_callback != NULL);
243 case TDGTCMD_REMOVE_FOCUS:
244 return (pTdgtBase->pf_focus_callback)(pTdgtBase, cmd_type, cmd_arg,
245 pv_cmd_userdata);
246 }
247 }
248 return FALSE;
249 }
250
251 /* --------------------- TdgtBaseReset() --------------------- */
252
TdgtBaseReset(pTdgtBase)253 void TdgtBaseReset(pTdgtBase)
254 TdgtBase *pTdgtBase;
255 {
256 CVListElem *pElem=NULL;
257
258 for (pElem=ListFirst(&pTdgtBase->pti->tci.clist); pElem != NULL;
259 pElem=ListNext(&pTdgtBase->pti->tci.clist, pElem)) {
260 TidgetInfo *pti=(TidgetInfo*)(pElem->obj);
261
262 if (pti != NULL) {
263 DestroyTidget(&pti);
264 }
265 }
266 ListUnlinkAll(&pTdgtBase->pti->tci.clist);
267
268 ResetTidgetCommon(&pTdgtBase->pti->tci);
269 }
270
271 /* --------------------- CreateTdgtBase() --------------------- */
272
CreateTdgtBase(parent_win,parent_tidgetinfo,ctl_id,x,y,w,h,h_pad,v_pad,state,caption)273 TdgtBase *CreateTdgtBase(parent_win, parent_tidgetinfo, ctl_id, x, y, w, h,
274 h_pad, v_pad, state, caption)
275 Window parent_win;
276 TidgetInfo *parent_tidgetinfo;
277 int ctl_id, x, y, w, h, h_pad, v_pad, state;
278 char *caption;
279 {
280 int bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel);
281 XWMHints wmhints;
282 XSetWindowAttributes win_attrs;
283 TdgtBase *pTdgtBase=NULL;
284
285 pTdgtBase = (TdgtBase*)malloc(sizeof(TdgtBase));
286 if (pTdgtBase == NULL) FailAllocMessage();
287 memset(pTdgtBase, 0, sizeof(TdgtBase));
288
289 pTdgtBase->pti = NewTidgetInfo(parent_tidgetinfo, TIDGET_TYPE_BASE,
290 pTdgtBase, ctl_id, NULL);
291 if ((pTdgtBase->pti->tci.win=XCreateSimpleWindow(mainDisplay, parent_win,
292 x, y, w, h, brdrW, myBorderPixel, bg_pixel)) == 0) {
293 FailToCreateWindowMessage("CreateTdgtBase()", NULL, TRUE);
294 }
295 XSelectInput(mainDisplay, pTdgtBase->pti->tci.win, StructureNotifyMask |
296 ButtonReleaseMask | ButtonPressMask | KeyPressMask | ExposureMask |
297 EnterWindowMask | LeaveWindowMask);
298 SetTidgetInfoBasic(pTdgtBase->pti, TIDGET_TYPE_BASE, pTdgtBase, parent_win,
299 x, y, w, h, h_pad, v_pad, state, caption);
300 TidgetCanHaveChildren(pTdgtBase->pti, TRUE);
301 TidgetSetCallbacks(pTdgtBase->pti,
302 RedrawTdgtBase, TdgtBaseEventHandler, IsTdgtBaseEvent, DestroyTdgtBase,
303 MapTdgtBase, TdgtBaseMoveResize, TdgtBaseSendCmd);
304
305 XDefineCursor(mainDisplay, pTdgtBase->pti->tci.win, defaultCursor);
306
307 memset(&win_attrs, 0, sizeof(XSetWindowAttributes));
308 win_attrs.save_under = True;
309 win_attrs.colormap = mainColormap;
310 XChangeWindowAttributes(mainDisplay, pTdgtBase->pti->tci.win,
311 CWSaveUnder | CWOverrideRedirect | CWColormap, &win_attrs);
312
313 memset(&wmhints, 0, sizeof(XWMHints));
314 wmhints.flags = InputHint;
315 wmhints.input = True;
316 XSetWMHints(mainDisplay, pTdgtBase->pti->tci.win, &wmhints);
317
318 RegisterWM_DELETE_WINDOW(pTdgtBase->pti->tci.win);
319 if (caption != NULL && *caption != '\0') {
320 XStoreName(mainDisplay, pTdgtBase->pti->tci.win, caption);
321 }
322 return pTdgtBase;
323 }
324
325 /* --------------------- TdgtBaseSetText() --------------------- */
326
TdgtBaseSetText(pTdgtBase,str)327 int TdgtBaseSetText(pTdgtBase, str)
328 TdgtBase *pTdgtBase;
329 char *str;
330 {
331 RedrawTdgtBase(pTdgtBase->pti);
332 if (str != NULL) {
333 FreeDynStrBuf(&(pTdgtBase->pti->tci.dyn_str));
334 DynStrSet(&(pTdgtBase->pti->tci.dyn_str), str);
335 }
336 return TRUE;
337 }
338
339 /* --------------------- TdgtBaseGetText() --------------------- */
340
TdgtBaseGetText(pTdgtBase)341 char *TdgtBaseGetText(pTdgtBase)
342 TdgtBase *pTdgtBase;
343 {
344 return pTdgtBase->pti->tci.dyn_str.s;
345 }
346
347 /* --------------------- TdgtBaseSetState() --------------------- */
348
TdgtBaseSetState(pTdgtBase,new_state)349 int TdgtBaseSetState(pTdgtBase, new_state)
350 TdgtBase *pTdgtBase;
351 int new_state;
352 {
353 int need_to_redraw=(pTdgtBase->pti->tci.state != new_state);
354
355 pTdgtBase->pti->tci.state = new_state;
356 if (need_to_redraw) {
357 RedrawTdgtBase(pTdgtBase->pti);
358 }
359 return TRUE;
360 }
361
362 /* --------------------- TdgtBaseGetState() --------------------- */
363
TdgtBaseGetState(pTdgtBase)364 int TdgtBaseGetState(pTdgtBase)
365 TdgtBase *pTdgtBase;
366 {
367 return pTdgtBase->pti->tci.state;
368 }
369
370 /* --------------------- TdgtBaseAddChild() --------------------- */
371
TdgtBaseAddChild(pTdgtBase,pChildTidgetInfo)372 int TdgtBaseAddChild(pTdgtBase, pChildTidgetInfo)
373 TdgtBase *pTdgtBase;
374 TidgetInfo *pChildTidgetInfo;
375 {
376 return ListAppend(&pTdgtBase->pti->tci.clist, pChildTidgetInfo);
377 }
378
379 /* ------------------- TdgtBaseWillHandleKeyPressEvents() ------------------- */
380
TdgtBaseWillHandleKeyPressEvents(pTdgtBase,pf_key_press_ev_handler_callback)381 void TdgtBaseWillHandleKeyPressEvents(pTdgtBase,
382 pf_key_press_ev_handler_callback)
383 TdgtBase *pTdgtBase;
384 TdgtBaseKeyPressEvHandlerCallbackFunc *pf_key_press_ev_handler_callback;
385 {
386 pTdgtBase->pf_key_press_ev_handler_callback =
387 pf_key_press_ev_handler_callback;
388 }
389
390 /* ------------------- TdgtBaseSetWmDeleteCallback() ------------------- */
391
TdgtBaseSetWmDeleteCallback(pTdgtBase,pf_wm_delete_ev_handler_callback)392 void TdgtBaseSetWmDeleteCallback(pTdgtBase,
393 pf_wm_delete_ev_handler_callback)
394 TdgtBase *pTdgtBase;
395 TdgtBaseWmDeleteEvHandlerCallbackFunc *pf_wm_delete_ev_handler_callback;
396 {
397 pTdgtBase->pf_wm_delete_ev_handler_callback =
398 pf_wm_delete_ev_handler_callback;
399 }
400
401 /* ------------------- TdgtBaseSetFocusCallback() ------------------- */
402
TdgtBaseSetFocusCallback(pTdgtBase,pf_focus_callback)403 void TdgtBaseSetFocusCallback(pTdgtBase, pf_focus_callback)
404 TdgtBase *pTdgtBase;
405 TdgtBaseFocusCallbackFunc *pf_focus_callback;
406 {
407 pTdgtBase->pf_focus_callback = pf_focus_callback;
408 }
409
410 /* --------------------- Init & Clean Up --------------------- */
411
InitTdgtBase()412 int InitTdgtBase()
413 {
414 return TRUE;
415 }
416
CleanUpTdgtBase()417 void CleanUpTdgtBase()
418 {
419 }
420
421