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