comparison packages/services/gfx/mw/current/src/demos/nanox/npanel.c @ 208:e0c0827131d1 ecos

Merge from eCos master repository on 2002-05-20-20:11:54-BST
author jlarmour
date Mon, 20 May 2002 22:19:26 +0000
parents
children
comparison
equal deleted inserted replaced
207:74c807ddde34 208:e0c0827131d1
1 /*
2 * nano-X launcher/window manager program
3 * (C) 1999 Alistair Riddoch <ajr@ecs.soton.ac.uk>
4 * (C) 2000 Alex Holden <alex@linuxhacker.org>
5 */
6
7 /*
8 Undefine this if solid window moves are incredibly slow on your hardware.
9 Unfortunately since outline moves are not supported yet, the only
10 alternative is "invisible" moving.
11 */
12 #define SHOW_WINDOW_MOTION
13
14 /*
15 Define this if you want the mouse pointer to become bell shaped when over
16 the launcher window.
17 */
18 #undef USE_WEIRD_POINTER
19
20 #include <stdio.h>
21 #include <signal.h>
22 #include <sys/time.h>
23 #include <sys/wait.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #define MWINCLUDECOLORS
27 #include "nano-X.h"
28
29 /*
30 * Definitions to make it easy to define cursors
31 */
32 #define _ ((unsigned) 0) /* off bits */
33 #define X ((unsigned) 1) /* on bits */
34 #define MASK(a,b,c,d,e,f,g) \
35 (((((((((((((a * 2) + b) * 2) + c) * 2) + d) * 2) \
36 + e) * 2) + f) * 2) + g) << 9)
37
38 #define DEC_HEIGHT 7
39 #define IDLE_DELAY 100000
40
41 static GR_WINDOW_ID w1; /* id for launcher window */
42 static GR_GC_ID gc; /* graphics context for rectangle */
43 static GR_GC_ID bgc; /* graphics context for rectangle */
44 static GR_SCREEN_INFO si; /* information about screen */
45 static int fwidth, fheight;
46 static int fbase;
47 static int num_apps = 0;
48
49 void do_exposure();
50 void do_buttondown();
51 void do_buttonup();
52 void do_update();
53 void do_mouse();
54
55 struct app_info {
56 char app_id[10];
57 char app_path[64];
58 } Apps[] = {
59 #if ELKS
60 {"clock", "/root/nclock"},
61 {"term", "/root/nterm"},
62 {"demo", "/root/demo"},
63 {"demo2", "/root/demo2"},
64 #else
65 {"clock", "bin/nclock"},
66 {"term", "bin/nterm"},
67 {"demo", "bin/demo"},
68 {"demo2", "bin/demo2"},
69 {"ntest", "bin/ntest"},
70 #endif
71 {"", ""}
72 };
73
74 typedef struct managed_window mwin;
75 struct managed_window {
76 GR_WINDOW_ID wid; /* Application's window */
77 GR_WINDOW_ID fid; /* Title bar */
78 GR_COORD x; /* Overall window X origin */
79 GR_COORD y; /* Overall window Y origin */
80 GR_SIZE width; /* Overall width of window */
81 mwin * next;
82 };
83
84 mwin * mwins = NULL;
85 mwin * in_motion = NULL;
86 GR_COORD move_xoff;
87 GR_COORD move_yoff;
88
89 /*
90 * Reap the dead children whenever we get a SIGCHLD.
91 */
92 void reaper(int signum) { while(waitpid(WAIT_ANY, NULL, WNOHANG) > 0); }
93
94 int
95 main(int argc,char **argv)
96 {
97 GR_EVENT event; /* current event */
98 struct app_info * act;
99 int width, height;
100
101 #ifdef USE_WEIRD_POINTER
102 GR_BITMAP bitmap1fg[7]; /* bitmaps for first cursor */
103 GR_BITMAP bitmap1bg[7];
104 #endif
105
106 for(act = Apps; act->app_id[0] != '\0'; act++, num_apps++);
107
108 if (GrOpen() < 0) {
109 fprintf(stderr, "cannot open graphics\n");
110 exit(1);
111 }
112
113 GrGetScreenInfo(&si);
114
115 signal(SIGCHLD, &reaper);
116
117 gc = GrNewGC();
118 bgc = GrNewGC();
119
120 GrSetGCForeground(bgc, GRAY);
121 GrSetGCFont(gc, GrCreateFont(GR_FONT_OEM_FIXED, 0, NULL));
122
123 GrGetGCTextSize(gc, "A", 1, GR_TFASCII, &fwidth, &fheight, &fbase);
124 width = fwidth * 8 + 4;
125 height = (fheight) * num_apps + 4;
126
127 w1 = GrNewWindow(GR_ROOT_WINDOW_ID, 5, 5, width,
128 height, 1, WHITE, BLACK);
129
130 GrSelectEvents(w1, GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_BUTTON_DOWN
131 | GR_EVENT_MASK_CLOSE_REQ);
132 GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_EXPOSURE |
133 GR_EVENT_MASK_CHLD_UPDATE);
134
135 GrMapWindow(w1);
136
137 #ifdef USE_WEIRD_POINTER
138 bitmap1bg[0] = MASK(_,_,X,X,X,_,_);
139 bitmap1bg[1] = MASK(_,X,X,X,X,X,_);
140 bitmap1bg[2] = MASK(_,X,X,X,X,X,_);
141 bitmap1bg[3] = MASK(_,X,X,X,X,X,_);
142 bitmap1bg[4] = MASK(_,X,X,X,X,X,_);
143 bitmap1bg[5] = MASK(_,X,X,X,X,X,_);
144 bitmap1bg[6] = MASK(X,X,X,X,X,X,X);
145
146 bitmap1fg[0] = MASK(_,_,_,_,_,_,_);
147 bitmap1fg[1] = MASK(_,_,_,X,_,_,_);
148 bitmap1fg[2] = MASK(_,_,X,X,X,_,_);
149 bitmap1fg[3] = MASK(_,_,X,X,X,_,_);
150 bitmap1fg[4] = MASK(_,_,X,X,X,_,_);
151 bitmap1fg[5] = MASK(_,_,X,X,X,_,_);
152 bitmap1fg[6] = MASK(_,X,X,X,X,X,_);
153
154 GrSetCursor(w1, 7, 7, 3, 3, WHITE, BLACK, bitmap1fg, bitmap1bg);
155 #endif
156
157 GrFillRect(GR_ROOT_WINDOW_ID, bgc, 0, 0, si.cols, si.rows);
158
159 GrSetGCForeground(gc, BLACK);
160 GrSetGCBackground(gc, WHITE);
161
162 while (1) {
163 GrGetNextEvent(&event);
164
165 switch (event.type) {
166 case GR_EVENT_TYPE_EXPOSURE:
167 do_exposure(&event.exposure);
168 break;
169 case GR_EVENT_TYPE_BUTTON_DOWN:
170 do_buttondown(&event.button);
171 break;
172 case GR_EVENT_TYPE_BUTTON_UP:
173 do_buttonup(&event.button);
174 break;
175 case GR_EVENT_TYPE_UPDATE:
176 do_update(&event.update);
177 break;
178 case GR_EVENT_TYPE_MOUSE_POSITION:
179 do_mouse(&event.mouse);
180 break;
181 case GR_EVENT_TYPE_CLOSE_REQ:
182 GrClose();
183 exit(0);
184 }
185 }
186 }
187
188 mwin * IsDecoration(GR_WINDOW_ID wid)
189 {
190 mwin * mwp;
191 for(mwp = mwins; mwp; mwp = mwp->next) {
192 if (mwp->fid == wid) {
193 return mwp;
194 }
195 }
196 return NULL;
197 }
198
199 mwin * FindWindow(GR_WINDOW_ID wid)
200 {
201 mwin * mwp;
202 for(mwp = mwins; mwp; mwp = mwp->next) {
203 if (mwp->wid == wid) {
204 return mwp;
205 }
206 }
207 return NULL;
208 }
209
210 mwin * NewWindow(GR_WINDOW_ID wid)
211 {
212 mwin * mwp = malloc(sizeof(mwin));
213
214 if (mwp) {
215 mwp->wid = wid;
216 mwp->next = mwins;
217 mwins = mwp;
218 }
219 return mwp;
220 }
221
222 void
223 do_update(ep)
224 GR_EVENT_UPDATE *ep;
225 {
226 mwin * mwp;
227 mwin * tmwp;
228 GR_WINDOW_INFO winfo;
229
230 if (IsDecoration(ep->wid)) return;
231
232 if ((mwp = FindWindow(ep->wid)) == NULL) {
233 /* We have a new window */
234 if (ep->utype != GR_UPDATE_MAP) return;
235 if ((mwp = NewWindow(ep->wid)) == NULL) {
236 printf("malloc failed\n");
237 return;
238 }
239 GrGetWindowInfo(ep->wid, &winfo);
240 mwp->x = ep->x - winfo.bordersize;
241 mwp->y = ep->y - winfo.bordersize;
242 mwp->width = ep->width + 2 * winfo.bordersize;
243 GrMoveWindow(mwp->wid, mwp->x + winfo.bordersize,
244 mwp->y + DEC_HEIGHT +
245 2 * winfo.bordersize);
246 mwp->fid = GrNewWindow(GR_ROOT_WINDOW_ID, mwp->x + 1,
247 mwp->y + 1, mwp->width - 2,
248 DEC_HEIGHT - 2, 1, BLUE, BLACK);
249 GrSelectEvents(mwp->fid, GR_EVENT_MASK_BUTTON_DOWN |
250 GR_EVENT_MASK_BUTTON_UP | GR_EVENT_MASK_MOUSE_POSITION);
251 GrMapWindow(mwp->fid);
252 } else {
253 switch (ep->utype) {
254 case GR_UPDATE_UNMAP:
255 GrUnmapWindow(mwp->fid);
256 GrDestroyWindow(mwp->fid);
257 if (mwins == mwp) {
258 mwins = mwp->next;
259 } else for(tmwp = mwins; tmwp; tmwp = tmwp->next) {
260 if (tmwp->next == mwp) {
261 tmwp->next = mwp->next;
262 }
263 }
264 free(mwp);
265 break;
266 case GR_UPDATE_MOVE:
267 GrGetWindowInfo(ep->wid, &winfo);
268 if ((ep->x == (mwp->x + winfo.bordersize)) &&
269 (ep->y == (mwp->y + winfo.bordersize
270 + DEC_HEIGHT))) {
271 return;
272 }
273 mwp->x = ep->x - winfo.bordersize;
274 mwp->y = ep->y - winfo.bordersize - DEC_HEIGHT;
275 GrMoveWindow(mwp->fid, mwp->x + 1, mwp->y + 1);
276 default:
277 break;
278 }
279 }
280 }
281
282 /*
283 * Handle mouse position events
284 */
285 void do_mouse(ep)
286 GR_EVENT_MOUSE *ep;
287 {
288 #ifdef SHOW_WINDOW_MOTION
289 GR_WINDOW_INFO winfo;
290
291 if(!in_motion) return;
292
293 in_motion->x = ep->rootx - move_xoff - 1;
294 in_motion->y = ep->rooty - move_yoff - 1;
295 GrMoveWindow(in_motion->fid, in_motion->x + 1, in_motion->y + 1);
296 GrGetWindowInfo(in_motion->wid, &winfo);
297 GrMoveWindow(in_motion->wid, in_motion->x + winfo.bordersize - 1,
298 in_motion->y + 2 * winfo.bordersize + DEC_HEIGHT - 1);
299 #endif
300 }
301
302 /*
303 * Here when an exposure event occurs.
304 */
305 void
306 do_exposure(ep)
307 GR_EVENT_EXPOSURE *ep;
308 {
309 struct app_info * act;
310 int app_no;
311
312 if (ep->wid == w1) {
313 for(act=Apps,app_no=0;act->app_id[0]!='\0';act++,app_no++) {
314 GrText(w1, gc, 2, 2 + fheight * (app_no + 1),
315 act->app_id, -1, GR_TFBOTTOM);
316 }
317 } else if (ep->wid == GR_ROOT_WINDOW_ID) {
318 GrFillRect(GR_ROOT_WINDOW_ID, bgc, ep->x, ep->y,
319 ep->width, ep->height);
320 }
321 }
322
323 extern char ** environ;
324
325 void
326 do_buttondown(ep)
327 GR_EVENT_BUTTON *ep;
328 {
329 mwin * mwp;
330 static int app_no;
331
332 if (ep->wid == w1) {
333 app_no = ep->y / fheight;
334 if (app_no >= num_apps) {
335 app_no = num_apps - 1;
336 }
337
338 if (!vfork()) {
339 char * nargv[2];
340
341 nargv[0] = Apps[app_no].app_path;
342 nargv[1] = 0;
343 execve(nargv[0], nargv, environ);
344 /* write(1, "\7", 1); */
345 exit(1);
346 }
347 } else if ((mwp = IsDecoration(ep->wid)) != NULL) {
348 GrRaiseWindow(mwp->wid);
349 GrRaiseWindow(mwp->fid);
350 in_motion = mwp;
351 move_xoff = ep->x;
352 move_yoff = ep->y;
353 }
354 }
355
356 void
357 do_buttonup(ep)
358 GR_EVENT_BUTTON *ep;
359 {
360 #ifdef SHOW_WINDOW_MOTION
361 in_motion = NULL;
362 #else
363 mwin * mwp;
364 GR_WINDOW_INFO winfo;
365
366 if ((mwp = IsDecoration(ep->wid)) != NULL) {
367 if (mwp == in_motion) {
368 mwp->x = ep->rootx - 1 - move_xoff;
369 mwp->y = ep->rooty - 1 - move_yoff;
370 GrMoveWindow(mwp->fid, mwp->x + 1, mwp->y + 1);
371 GrGetWindowInfo(mwp->wid, &winfo);
372 GrMoveWindow(mwp->wid, mwp->x + winfo.bordersize,
373 mwp->y + 2 * winfo.bordersize + DEC_HEIGHT);
374 in_motion = NULL;
375 }
376 }
377 #endif
378 }