Mercurial > ecos
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 } |
