]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/demos/nanowm/clients.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / demos / nanowm / clients.c
1 /*
2  * NanoWM - Window Manager for Nano-X
3  *
4  * Copyright (C) 2000 Greg Haerr <greg@censoft.com>
5  * Copyright (C) 2000 Alex Holden <alex@linuxhacker.org>
6  */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #define MWINCLUDECOLORS
10 #include "nano-X.h"
11 #include "nxdraw.h"
12 /* Uncomment this if you want debugging output from this file */
13 /*#define DEBUG*/
14
15 #include "nanowm.h"
16
17 /* default window style for GR_WM_PROPS_APPWINDOW*/
18 #define DEFAULT_WINDOW_STYLE    (GR_WM_PROPS_APPFRAME | GR_WM_PROPS_CAPTION |\
19                                         GR_WM_PROPS_CLOSEBOX)
20
21 static GR_COORD lastx = FIRST_WINDOW_LOCATION;
22 static GR_COORD lasty = FIRST_WINDOW_LOCATION;
23
24 /*
25  * A new client window has been mapped, so we need to reparent and decorate it.
26  * Returns -1 on failure or 0 on success.
27  */
28 int new_client_window(GR_WINDOW_ID wid)
29 {
30         win window;
31         GR_WINDOW_ID pid;
32         GR_WINDOW_INFO winfo;
33         GR_COORD x, y, width, height, xoffset, yoffset;
34         GR_WM_PROPS style;
35         GR_WM_PROPERTIES props;
36
37         /* get client window information*/
38         GrGetWindowInfo(wid, &winfo);
39         style = winfo.props;
40
41         /* if not redecorating or not child of root window, return*/
42         if (winfo.parent != GR_ROOT_WINDOW_ID ||
43             (style & GR_WM_PROPS_NODECORATE))
44                 return 0;
45
46         /* deal with replacing borders with window decorations*/
47         if (winfo.bordersize) {
48                 /*
49                  * For complex reasons, it's easier to unmap,
50                  * remove the borders, and then map again,
51                  * rather than try to recalculate the window
52                  * position in the server w/o borders.  By
53                  * the time we get this event, the window has
54                  * already been painted with borders...
55                  * This currently causes a screen flicker as
56                  * the window is painted twice.  The workaround
57                  * is to create the window without borders in
58                  * the first place.
59                  */
60                 GrUnmapWindow(wid);
61
62                 /* remove client borders, if any*/
63                 props.flags = style | GR_WM_FLAGS_BORDERSIZE;
64                 props.bordersize = 0;
65                 GrSetWMProperties(wid, &props);
66
67                 /* remap the window without borders, call this routine again*/
68                 GrMapWindow(wid);
69                 return 0;
70         }
71         
72         /* if default decoration style asked for, set real draw bits*/
73         if ((style & GR_WM_PROPS_APPMASK) == GR_WM_PROPS_APPWINDOW) {
74                 GR_WM_PROPERTIES pr;
75
76                 style = (style & ~GR_WM_PROPS_APPMASK)|DEFAULT_WINDOW_STYLE;
77                 pr.flags = GR_WM_FLAGS_PROPS;
78                 pr.props = style;
79                 GrSetWMProperties(wid, &pr);
80         }
81
82         /* determine container widths and client child window offsets*/
83         if (style & GR_WM_PROPS_APPFRAME) {
84                 width = winfo.width + CXFRAME;
85                 height = winfo.height + CYFRAME;
86                 xoffset = CXBORDER;
87                 yoffset = CYBORDER;
88         } else if (style & GR_WM_PROPS_BORDER) {
89                 width = winfo.width + 2;
90                 height = winfo.height + 2;
91                 xoffset = 1;
92                 yoffset = 1;
93         } else {
94                 width = winfo.width;
95                 height = winfo.height;
96                 xoffset = 0;
97                 yoffset = 0;
98         }
99         if (style & GR_WM_PROPS_CAPTION) {
100                 height += CYCAPTION;
101                 yoffset += CYCAPTION;
102                 if (style & GR_WM_PROPS_APPFRAME) {
103                         /* extra line under caption with appframe*/
104                         ++height;
105                         ++yoffset;
106                 }
107         }
108
109         /* determine x,y window location*/
110         if (style & GR_WM_PROPS_NOAUTOMOVE) {
111                 x = winfo.x;
112                 y = winfo.y;
113         } else {
114                 /* We could proably use a more intelligent algorithm here */
115                 x = lastx + WINDOW_STEP;
116                 if((x + width) > si.cols)
117                         x = FIRST_WINDOW_LOCATION;
118                 lastx = x;
119                 y = lasty + WINDOW_STEP;
120                 if((y + height) > si.rows)
121                         y = FIRST_WINDOW_LOCATION;
122                 lasty = y;
123         }
124
125         /* create container window*/
126         pid = GrNewWindow(GR_ROOT_WINDOW_ID, x, y, width, height,
127                 0, LTGRAY, BLACK);
128         window.wid = pid;
129         window.pid = GR_ROOT_WINDOW_ID;
130         window.type = WINDOW_TYPE_CONTAINER;
131         window.sizing = GR_FALSE;
132         window.active = 0;
133         window.data = NULL;
134         window.clientid = wid;
135         add_window(&window);
136
137         /* don't erase background of container window*/
138         props.flags = GR_WM_FLAGS_PROPS;
139         props.props = style | GR_WM_PROPS_NOBACKGROUND;
140         GrSetWMProperties(pid, &props);
141
142         Dprintf("New client window %d container %d\n", wid, pid);
143
144         GrSelectEvents(pid, GR_EVENT_MASK_CHLD_UPDATE
145                 | GR_EVENT_MASK_BUTTON_UP | GR_EVENT_MASK_BUTTON_DOWN
146                 | GR_EVENT_MASK_MOUSE_POSITION | GR_EVENT_MASK_EXPOSURE);
147
148         /* reparent client to container window*/
149         /* must map before reparent (nano-x bug)*/
150         GrMapWindow(pid);
151         GrReparentWindow(wid, pid, xoffset, yoffset);
152
153         GrSetFocus(wid);        /* force fixed focus*/
154
155         /* add client window*/
156         window.wid = wid;
157         window.pid = pid;
158         window.type = WINDOW_TYPE_CLIENT;
159         window.sizing = GR_FALSE;
160         window.active = 0;
161         window.clientid = 0;
162         window.data = NULL;
163         add_window(&window);
164
165 #if 0000
166         /* add system utility button*/
167         nid = GrNewWindow(pid, 0, 0, TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT, 0,
168                                                         LTGRAY, BLACK);
169         window.wid = nid;
170         window.pid = pid;
171         window.type = WINDOW_TYPE_UTILITYBUTTON;
172         window.active = GR_FALSE;
173         window.data = NULL;
174         add_window(&window);
175
176         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
177                                 | GR_EVENT_MASK_EXPOSURE
178                                 | GR_EVENT_MASK_MOUSE_EXIT);
179         GrMapWindow(nid);
180         GrBitmap(nid, buttonsgc, 0, 0, TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT,
181                                                 utilitybutton_notpressed);
182
183         nid = GrNewWindow(pid, TITLE_BAR_HEIGHT + 1, 1, width - (4 *
184                         TITLE_BAR_HEIGHT) - 3, TITLE_BAR_HEIGHT - 3, 1, LTGRAY,
185                                                                 BLACK);
186         window.wid = nid;
187         window.pid = pid;
188         window.type = WINDOW_TYPE_TOPBAR;
189         window.active = GR_FALSE;
190         window.data = NULL;
191
192         add_window(&window);
193
194         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
195                                 | GR_EVENT_MASK_EXPOSURE
196                                 | GR_EVENT_MASK_MOUSE_POSITION);
197         GrMapWindow(nid);
198
199         nid = GrNewWindow(pid, width - (3 * TITLE_BAR_HEIGHT), 0,
200                         TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT, 0, LTGRAY, BLACK);
201         window.wid = nid;
202         window.pid = pid;
203         window.type = WINDOW_TYPE_ICONISEBUTTON;
204         window.active = GR_FALSE;
205         window.data = NULL;
206         add_window(&window);
207
208         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
209                                 | GR_EVENT_MASK_EXPOSURE
210                                 | GR_EVENT_MASK_MOUSE_EXIT);
211         GrMapWindow(nid);
212         GrBitmap(nid, buttonsgc, 0, 0, TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT,
213                                                 iconisebutton_notpressed);
214
215         nid = GrNewWindow(pid, width - (2 * TITLE_BAR_HEIGHT), 0,
216                         TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT, 0, LTGRAY, BLACK);
217         window.wid = nid;
218         window.pid = pid;
219         window.type = WINDOW_TYPE_MAXIMISEBUTTON;
220         window.active = GR_FALSE;
221         window.data = NULL;
222         add_window(&window);
223
224         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
225                                 | GR_EVENT_MASK_EXPOSURE
226                                 | GR_EVENT_MASK_MOUSE_EXIT);
227         GrMapWindow(nid);
228         GrBitmap(nid, buttonsgc, 0, 0, TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT,
229                                                 maximisebutton_notpressed);
230
231         nid = GrNewWindow(pid, width - TITLE_BAR_HEIGHT, 0,
232                         TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT, 0, LTGRAY, BLACK);
233         window.wid = nid;
234         window.pid = pid;
235         window.type = WINDOW_TYPE_CLOSEBUTTON;
236         window.active = GR_FALSE;
237         window.data = NULL;
238         add_window(&window);
239
240         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
241                                 | GR_EVENT_MASK_EXPOSURE
242                                 | GR_EVENT_MASK_MOUSE_EXIT);
243         GrMapWindow(nid);
244         GrBitmap(nid, buttonsgc, 0, 0, TITLE_BAR_HEIGHT, TITLE_BAR_HEIGHT,
245                                                 closebutton_notpressed);
246
247         nid = GrNewWindow(pid, 1, TITLE_BAR_HEIGHT + 1, BORDER_WIDTHS - 2,
248                                 height - TITLE_BAR_HEIGHT - BORDER_WIDTHS - 1,
249                                 1, LTGRAY, BLACK);
250         window.wid = nid;
251         window.pid = pid;
252         window.type = WINDOW_TYPE_LEFTBAR;
253         window.active = GR_FALSE;
254         window.data = NULL;
255
256         add_window(&window);
257
258         GrSetCursor(nid, horizontal_resize_columns, horizontal_resize_rows,
259                         horizontal_resize_hotx, horizontal_resize_hoty,
260                         BLACK, WHITE, horizontal_resize_fg,
261                         horizontal_resize_bg);
262
263         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
264                                 | GR_EVENT_MASK_MOUSE_POSITION);
265
266         GrMapWindow(nid);
267
268         nid = GrNewWindow(pid, 1, height - BORDER_WIDTHS + 1, BORDER_WIDTHS - 2,
269                                         BORDER_WIDTHS - 2, 1, LTGRAY, BLACK);
270         window.wid = nid;
271         window.pid = pid;
272         window.type = WINDOW_TYPE_LEFTRESIZE;
273         window.active = GR_FALSE;
274         window.data = NULL;
275
276
277         add_window(&window);
278
279         GrSetCursor(nid, lefthand_resize_columns, lefthand_resize_rows,
280                         lefthand_resize_hotx, lefthand_resize_hoty,
281                         BLACK, WHITE, lefthand_resize_fg, lefthand_resize_bg);
282
283         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
284                                 | GR_EVENT_MASK_MOUSE_POSITION);
285
286         GrMapWindow(nid);
287
288         nid = GrNewWindow(pid, BORDER_WIDTHS, height - BORDER_WIDTHS + 1,
289                         width - (2 * BORDER_WIDTHS), BORDER_WIDTHS - 2, 1,
290                                                         LTGRAY, BLACK);
291         window.wid = nid;
292         window.pid = pid;
293         window.type = WINDOW_TYPE_BOTTOMBAR;
294         window.active = GR_FALSE;
295         window.data = NULL;
296         add_window(&window);
297
298         GrSetCursor(nid, vertical_resize_columns, vertical_resize_rows,
299                         vertical_resize_hotx, vertical_resize_hoty,
300                         BLACK, WHITE, vertical_resize_fg, vertical_resize_bg);
301
302         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
303                                 | GR_EVENT_MASK_MOUSE_POSITION);
304
305         GrMapWindow(nid);
306
307         nid = GrNewWindow(pid, width - BORDER_WIDTHS + 1,
308                         height - BORDER_WIDTHS + 1, BORDER_WIDTHS - 2,
309                                         BORDER_WIDTHS - 2, 1, LTGRAY, BLACK);
310         window.wid = nid;
311         window.pid = pid;
312         window.type = WINDOW_TYPE_RIGHTRESIZE;
313         window.active = GR_FALSE;
314         window.data = NULL;
315
316         add_window(&window);
317
318         GrSetCursor(nid, righthand_resize_columns, righthand_resize_rows,
319                         righthand_resize_hotx, righthand_resize_hoty,
320                         BLACK, WHITE, righthand_resize_fg, righthand_resize_bg);
321
322         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
323                                 | GR_EVENT_MASK_MOUSE_POSITION);
324
325         GrMapWindow(nid);
326
327         nid = GrNewWindow(pid, width - BORDER_WIDTHS + 1, TITLE_BAR_HEIGHT + 1,
328                 BORDER_WIDTHS - 2, height - TITLE_BAR_HEIGHT - BORDER_WIDTHS -1,
329                                                          1, LTGRAY, BLACK);
330         window.wid = nid;
331         window.pid = pid;
332         window.type = WINDOW_TYPE_RIGHTBAR;
333         window.active = GR_FALSE;
334         window.data = NULL;
335
336         add_window(&window);
337
338         GrSetCursor(nid, horizontal_resize_columns, horizontal_resize_rows,
339                         horizontal_resize_hotx, horizontal_resize_hoty,
340                         BLACK, WHITE, horizontal_resize_fg,
341                         horizontal_resize_bg);
342
343         GrSelectEvents(nid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP
344                                 | GR_EVENT_MASK_MOUSE_POSITION);
345         GrMapWindow(nid);
346 #endif
347         return 0;
348 }
349
350 /*
351  * We've just received an event notifying us that a client window has been
352  * unmapped, so we need to destroy all of the decorations.
353  */
354 void client_window_destroy(win *window)
355 {
356         win *pwin;
357         GR_WINDOW_ID pid;
358
359         Dprintf("Client window %d has been destroyed\n", window->wid);
360
361         if(!(pwin = find_window(window->pid))) {
362                 fprintf(stderr, "Couldn't find parent of destroyed window "
363                                 "%d\n", window->wid);
364                 return;
365         }
366
367         /* Do it this way around so we don't handle events after destroying */
368         pid = pwin->wid;
369         remove_window_and_children(pwin);
370
371         Dprintf("Destroying container %d\n", pid);
372         GrDestroyWindow(pid);
373 }