cc6aae9ba45a64f52cac77a70ccc23be6a37aac6
[AXE.git] / src / xwindow.cpp
1 /**************************************************************************
2 **  (c) Copyright 1998, Andromeda Technology & Automation
3 ***************************************************************************
4 ** MODULE INFORMATION *
5 ***********************
6 **      FILE NAME      : xwindow.cpp
7 **      SYSTEM NAME    : AXE - Andromeda X-windows Encapsulation
8 **      VERSION NUMBER : $Revision: 1.2 $
9 **
10 **  DESCRIPTION      :  Implementation of the window class
11 **
12 **  EXPORTED OBJECTS : 
13 **  LOCAL    OBJECTS : 
14 **  MODULES  USED    :
15 ***************************************************************************
16 **  ADMINISTRATIVE INFORMATION *
17 ********************************
18 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
19 **      CREATION DATE   : Feb 06, 1998
20 **      LAST UPDATE     : Feb 09, 1998
21 **      MODIFICATIONS   : 
22 **************************************************************************/
23
24 /*****************************
25    $Log: xwindow.cpp,v $
26    Revision 1.2  2002-09-26 14:50:54  arjen
27    Proper casting of event data in EV_ClientMessage()
28
29    Revision 1.1  2002/07/25 08:01:27  arjen
30    First checkin, AXE release 0.2
31
32 *****************************/
33
34 static const char *RCSID = "$Id: xwindow.cpp,v 1.2 2002-09-26 14:50:54 arjen Exp $";
35
36 #include "xappl.h"   /*  Includes xwindow.h   */
37
38 #include <stdio.h>
39
40
41 /*=========================================================================
42 **  NAME           : 
43 **  SYNOPSIS       :
44 **  PARAMETERS     :
45 **  RETURN VALUE   :
46 **
47 **  DESCRIPTION    : 
48 **
49 **  VARS USED      :
50 **  VARS CHANGED   :
51 **  FUNCTIONS USED :
52 **  SEE ALSO       :
53 **  LAST MODIFIED  : 
54 **=========================================================================
55 */
56
57 window::window(int x, int y, unsigned int _w, unsigned int _h, int bw)
58 {
59    w = _w;
60    h = _h;
61
62    parent = 0;
63    children = 0;
64
65    win_id = XCreateSimpleWindow(stddpy.Dpy(), stddpy.Root(),
66                     x, y, w, h, bw,
67                    stddpy.Black(), stddpy.White());
68
69    selection_mask = 0;
70
71    XApp->add_window(win_id, this);
72 }
73
74
75 /*=========================================================================
76 **  NAME           : 
77 **  SYNOPSIS       :
78 **  PARAMETERS     :
79 **  RETURN VALUE   :
80 **
81 **  DESCRIPTION    : 
82 **
83 **  VARS USED      :
84 **  VARS CHANGED   :
85 **  FUNCTIONS USED :
86 **  SEE ALSO       :
87 **  LAST MODIFIED  : 
88 **=========================================================================
89 */
90
91 window::window(window &parentw, int x, int y,
92                unsigned int _w, unsigned int _h, int bw)
93 {
94    w = _w;
95    h = _h;
96
97    parent = &parentw;
98    children = 0;
99    parentw.add_child(this);
100
101    win_id = XCreateSimpleWindow(stddpy.Dpy(), parentw.win_id,
102                     x, y, w, h, bw,
103                    stddpy.Black(), stddpy.White());
104
105    selection_mask = 0;
106
107    XApp->add_window(win_id, this);
108 }
109
110
111 /*=========================================================================
112 **  NAME           : 
113 **  SYNOPSIS       :
114 **  PARAMETERS     :
115 **  RETURN VALUE   :
116 **
117 **  DESCRIPTION    : 
118 **
119 **  VARS USED      :
120 **  VARS CHANGED   :
121 **  FUNCTIONS USED :
122 **  SEE ALSO       :
123 **  LAST MODIFIED  : 
124 **=========================================================================
125 */
126
127 window::~window()
128 {
129    if (parent)
130    {
131       parent->remove_child(this);
132    }
133
134    XDestroyWindow(stddpy.Dpy(), win_id);
135
136    XApp->remove_window(win_id);
137 }
138
139
140
141 /*=========================================================================
142 **  NAME           : add_child - Add subwindow in the list
143 **  SYNOPSIS       :
144 **  PARAMETERS     :
145 **  RETURN VALUE   :
146 **
147 **  DESCRIPTION    : 
148 **
149 **  VARS USED      :
150 **  VARS CHANGED   :
151 **  FUNCTIONS USED :
152 **  SEE ALSO       :
153 **  LAST MODIFIED  : 
154 **=========================================================================
155 */
156
157 void window::add_child(window *ch)
158 {
159    win_list *l;
160
161    l = new win_list;
162
163    l->next = children;
164    l->child = ch;
165    children = l;
166 }
167
168 /*=========================================================================
169 **  NAME           : remove_child - Remove subwindow from the list
170 **  SYNOPSIS       :
171 **  PARAMETERS     :
172 **  RETURN VALUE   :
173 **
174 **  DESCRIPTION    : 
175 **
176 **  VARS USED      :
177 **  VARS CHANGED   :
178 **  FUNCTIONS USED :
179 **  SEE ALSO       :
180 **  LAST MODIFIED  : 
181 **=========================================================================
182 */
183
184 void window::remove_child(window *ch)
185 {
186    win_list *l = 0, *prev = 0;
187
188    l = children;
189    while (l && l->child != ch)
190    {
191       prev = l;
192       l = l->next;
193    }
194
195    // If l would be NULL, the child window would not be in
196    // it's parent's list of children. This can not happen !
197
198    if (prev)
199    {
200       prev->next = l->next;
201    }
202    else
203    {
204       children = l->next;
205    }
206
207    delete l;
208 }
209
210 /*=========================================================================
211 **  NAME           : EV_Expose
212 **  SYNOPSIS       : int window::EV_Expose(XExposeEvent ev)
213 **  PARAMETERS     :
214 **  RETURN VALUE   : 0 if the application should quit
215 **
216 **  DESCRIPTION    : Event handling functions.
217 **                   Most of the event handling functions are empty.
218 **                   Derived classes of window should override these functions
219 **                   to implement speecific behavior.
220 **
221 **  VARS USED      :
222 **  VARS CHANGED   :
223 **  FUNCTIONS USED :
224 **  SEE ALSO       :
225 **  LAST MODIFIED  : 
226 **=========================================================================
227 */
228
229 int window::EV_Expose(XExposeEvent ev)
230 {
231    return 1;
232 }
233
234 int window::EV_NoExpose(XNoExposeEvent ev)
235 {
236    return 1;
237 }
238
239 int window::EV_KeyPress(XKeyEvent ev)
240 {
241    return 1;
242 }
243
244 int window::EV_KeyRelease(XKeyEvent ev)
245 {
246    return 1;
247 }
248
249 int window::EV_ButtonPress(XButtonEvent ev)
250 {
251    return 1;
252 }
253
254 int window::EV_ButtonRelease(XButtonEvent ev)
255 {
256    return 1;
257 }
258
259 int window::EV_MotionNotify(XMotionEvent ev)
260 {
261    return 1;
262 }
263
264 int window::EV_EnterNotify(XCrossingEvent ev)
265 {
266    return 1;
267 }
268
269 int window::EV_LeaveNotify(XCrossingEvent ev)
270 {
271    return 1;
272 }
273
274 int window::EV_FocusIn(XFocusChangeEvent ev)
275 {
276    return 1;
277 }
278
279 int window::EV_FocusOut(XFocusChangeEvent ev)
280 {
281    return 1;
282 }
283
284
285 /*=========================================================================
286 **  NAME           : EV_ConfigureNotify - Handle Configure event
287 **  SYNOPSIS       :
288 **  PARAMETERS     :
289 **  RETURN VALUE   :
290 **
291 **  DESCRIPTION    : Handles the event where the window is moved relative
292 **                   to its parent, resized or restacked.
293 **                   The default handler calls ParentResized for all of its
294 **                   children. The subwindows usually react by fitting their
295 **                   size to the size of the parent.
296 **
297 **  VARS USED      :
298 **  VARS CHANGED   :
299 **  FUNCTIONS USED :
300 **  SEE ALSO       :
301 **  LAST MODIFIED  : Feb 10, 1998
302 **=========================================================================
303 */
304
305 int window::EV_ConfigureNotify(XConfigureEvent ev)
306 {
307    win_list *l;
308
309    w = ev.width;
310    h = ev.height;
311
312    for (l = children; l; l = l->next)
313    {
314       l->child->ParentResized(ev.width, ev.height);
315    }
316    return 1;
317 }
318
319 int window::EV_ClientMessage(XClientMessageEvent ev)
320 {
321    return 1;
322 }
323
324 int window::ParentResized(int w, int h)
325 {
326    // stub
327
328    return 1;
329 }
330
331 /* Event names.  Used in "type" field in XEvent structures.  Not to be
332 confused with event masks above.  They start from 2 because 0 and 1
333 are reserved in the protocol for errors and replies. */
334
335 static char * event_names[] =
336 {
337    " Undefined(0)",
338    " Undefined(1)",
339    " KeyPress",
340    " KeyRelease",
341    " ButtonPress",
342    " ButtonRelease",
343    " MotionNotify",
344    " EnterNotify",
345    " LeaveNotify",
346    " FocusIn",
347    " FocusOut",
348    " KeymapNotify",
349    " Expose",
350    " GraphicsExpose",
351    " NoExpose",
352    " VisibilityNotify",
353    " CreateNotify",
354    " DestroyNotify",
355    " UnmapNotify",
356    " MapNotify",
357    " MapRequest",
358    " ReparentNotify",
359    " ConfigureNotify",
360    " ConfigureRequest",
361    " GravityNotify",
362    " ResizeRequest",
363    " CirculateNotify",
364    " CirculateRequest",
365    " PropertyNotify",
366    " SelectionClear",
367    " SelectionRequest",
368    " SelectionNotify",
369    " ColormapNotify",
370    " ClientMessage",
371    " MappingNotify"
372 };
373
374 int window::EV_Default(XEvent ev)
375 {
376    return 1;
377 }
378
379 void window::ChildMessage(win_message &msg)
380 {
381 }
382
383 void window::ParentMessage(int id)
384 {
385    win_message  msg;
386
387
388    msg.msg_id = id;
389    msg.from   = this;
390
391    parent->ChildMessage(msg);
392 }
393
394 void window::Resize(unsigned width, unsigned height)
395 {
396    w  = width;
397    h  = height;
398
399    XResizeWindow(stddpy.Dpy(), win_id, w, h);
400 }
401
402 void window::Resize(size sz)
403 {
404    w  = sz.w;
405    h  = sz.h;
406
407    XResizeWindow(stddpy.Dpy(), win_id, w, h);
408 }
409
410 void window::Move(int x, int y)
411 {
412    XMoveWindow(stddpy, win_id, x, y);
413 }
414
415 /*=========================================================================
416 **  NAME           : Background
417 **  SYNOPSIS       : void window::Background(unsigned long pixel)
418 **  PARAMETERS     :
419 **  RETURN VALUE   :
420 **
421 **  DESCRIPTION    : Set the pixel value of the window's background color
422 **
423 **  VARS USED      :
424 **  VARS CHANGED   :
425 **  FUNCTIONS USED :
426 **  SEE ALSO       :
427 **  LAST MODIFIED  : 
428 **=========================================================================
429 */
430
431 void window::Background(unsigned long pixel)
432 {
433    XSetWindowAttributes attrib;
434
435    attrib.background_pixel = pixel;
436    XChangeWindowAttributes(stddpy.Dpy(), win_id, CWBackPixel, &attrib);
437 }
438
439 void window::WindowGravity(int gravity)
440 {
441    XSetWindowAttributes attrib;
442
443    attrib.win_gravity = gravity;
444    XChangeWindowAttributes(stddpy.Dpy(), win_id, CWWinGravity, &attrib);
445 }
446
447 void window::Clear(void)
448 {
449    XClearWindow(stddpy.Dpy(), win_id);
450 }
451
452 /*=========================================================================
453 **  NAME           : SelectInput - Turn events on or off.
454 **  SYNOPSIS       : long window::SelectInput(long events, int on)
455 **  PARAMETERS     : events   : Bitwise OR of event masks
456 **                   on       : 0 - Events off; 1 - Events on
457 **  RETURN VALUE   : The new event selection mask
458 **
459 **  DESCRIPTION    : 
460 **
461 **  VARS USED      :
462 **  VARS CHANGED   :
463 **  FUNCTIONS USED :
464 **  SEE ALSO       :
465 **  LAST MODIFIED  : 
466 **=========================================================================
467 */
468
469 long window::SelectInput(long events, int on)
470 {
471    if (on)
472    {
473       selection_mask |= events;
474    }
475    else
476    {
477       selection_mask &= ~events;
478    }
479
480    XSelectInput(stddpy.Dpy(), win_id, selection_mask);
481
482    return selection_mask;
483 }
484
485 int  window::GrabPointer(Cursor curs)
486 {
487    int status;
488
489    status = XGrabPointer(stddpy, win_id, True,
490           ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask,
491                 GrabModeAsync, GrabModeAsync, None, curs, CurrentTime);
492    XApp->Pgrab(this);
493
494    return status;
495 }
496
497 int  window::UngrabPointer(void)
498 {
499    int status;
500
501    status = XUngrabPointer(stddpy, CurrentTime);
502    XApp->Pgrab(None);
503
504    return status;
505 }
506
507 int managed_window::EV_FocusIn(XFocusChangeEvent ev)
508 {
509    XApp->Topwin(this);
510
511    return 1;
512 }
513
514 int managed_window::EV_ClientMessage(XClientMessageEvent ev)
515 {
516    if (ev.message_type == XInternAtom(stddpy, "WM_PROTOCOLS", True))
517    {
518       if ((Atom)ev.data.l[0] == XInternAtom(stddpy, "WM_DELETE_WINDOW", True))
519       {
520          return XApp->SendCommand(WM_Delete_Command);
521       }
522    }
523    return 1;
524 }