Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

win.c

Go to the documentation of this file.
00001 /* win.c
00002  * Biao Lu                     biao@eagle.drexel.edu
00003  */
00004 
00005 #include "win.h"
00006 #include <X11/keysym.h>
00007 #include <X11/cursorfont.h>
00008 #include <string.h>
00009 
00010 /* Global variables: only 1 of each allowed in lux! */
00011 
00012 Display      *display;
00013 Visual       *visual;
00014 char         *display_name = NULL;
00015 unsigned int  display_width, display_height, default_depth;
00016 Pixmap        default_icon_pixmap;
00017 int           pmpallocflag = 1;
00018 int           screen;
00019 lux_wins     *windows = (lux_wins *)NULL;
00020 XStandardColormap  map_info;
00021 int                colormap_size;
00022 char         *colorfile = (char *)NULL;
00023 Colormap      colormap;
00024 Window        popup;
00025 Atom          protocols;   /* for delete */
00026 
00027 XFontStruct  *font_info;
00028 GC            defaultgc, redrawgc;
00029 Cursor        cursor;
00030 int           lux_colors = 0;
00031 int           lux_colormap;
00032 
00033 
00034 extern        redraw(), lux_setup_region(), lux_setup_axis(), 
00035               lux_reconvert_coord();
00036 
00037 extern  Colormap   lux_setup_colormap();
00038 extern  unsigned   long lux_rgb_pixel();
00039 extern  unsigned   long lux_lookup_color();
00040 
00041 
00042 #define REPORT_EVENT 0
00043 #define DOUBLECLICKLENGTH 300L
00044 
00045 
00046 /* Used for McDraw */
00047 
00048 static  int  mcdrawflag = 0;
00049 
00050 /* Used for McDraw */
00051 
00052 static char* default_font = "fixed";
00053 
00054 set_default_font(char* font)
00055 {
00056     default_font = malloc(strlen(font)+1);
00057     strcpy(default_font, font);
00058 }
00059 
00060 /* The following are for input focus */
00061 Window        focus;
00062 int           revert;
00063 /* The above     are for input focus */
00064 
00065 long      XMAXREQUESTSIZE;
00066 
00067 #define X_CreatePixmap 53   /* Got this from XErrorDB */
00068 
00069 int lux_handler(display, lux_err)
00070 Display      *display;
00071 XErrorEvent  *lux_err;
00072 {
00073     char msg[80];
00074     XGetErrorText(display, lux_err->error_code, msg, 80);
00075     fprintf(stderr, "luxwins: Error %s\n Request code %d\n", 
00076             msg, lux_err->request_code);
00077     if (lux_err->request_code == X_CreatePixmap) pmpallocflag = 0;
00078 }
00079 
00080 
00081 load_font(font_info)
00082 XFontStruct **font_info;
00083 {
00084     char *fontname = default_font;
00085 
00086     /* Access font */
00087 
00088     if ((*font_info = XLoadQueryFont(display, fontname)) == NULL) {
00089 
00090         fprintf(stderr, "LUX: Cannot open font \"%s\"\n", fontname);
00091         fprintf(stderr, "     Trying font \"fixed\"\n");
00092 
00093         if ((*font_info = XLoadQueryFont(display, "fixed")) == NULL) {
00094             if (mcdrawflag)
00095                 return 0;
00096             else
00097                 exit(-1);
00098         }
00099 
00100     }
00101 
00102     /* fprintf(stderr, "font loaded\n");*/
00103 
00104     return 1;
00105 }
00106 
00107 
00108 lux_init_gc()
00109 {
00110   static int  status = 0;
00111   XGCValues            values;
00112   unsigned long        valuemask   = 0; /* ignore XGCvalues and use defaults */
00113 
00114   values.graphics_exposures = False;
00115 
00116   defaultgc = XCreateGC(display, RootWindow(display, screen), 
00117                         valuemask, &values);
00118   redrawgc  = XCreateGC(display, RootWindow(display, screen), 
00119                         valuemask, &values);
00120 
00121   if (load_font(&font_info))
00122     XSetFont(display, defaultgc, font_info->fid);
00123 
00124   XSetForeground(display, defaultgc, BlackPixel(display, screen));
00125   XSetBackground(display, defaultgc, WhitePixel(display, screen));
00126     
00127   XChangeGC(display, defaultgc, GCGraphicsExposures, &values);
00128   return 0;
00129 }
00130 
00131 lux_get_wingc(win)
00132 lux_win *win;
00133 {
00134     XGCValues            values;
00135     unsigned long        valuemask = 0; /* ignore XGCvalues and use defaults */
00136 
00137     win->gc = XCreateGC(win->display, RootWindow(win->display, win->screen), 
00138                         valuemask, &values);
00139 
00140     XCopyGC(win->display, defaultgc, (long)0x003FFFFF, win->gc);
00141 
00142 }
00143 
00144 lux_create_popup()
00145 {
00146   
00147     XSetWindowAttributes   attrib;
00148     unsigned     long      valuemask;
00149 
00150     if (colormap != DefaultColormap(display, screen)) {
00151       attrib.colormap = colormap;
00152       attrib.background_pixel = WhitePixel(display, screen);
00153       attrib.border_pixel = BlackPixel(display, screen);
00154       attrib.save_under = True;
00155       valuemask = CWColormap | CWBackPixel | CWBorderPixel | CWSaveUnder ;
00156       popup = XCreateWindow(display, 
00157                           RootWindow(display, screen), 
00158                           0, 0, 40*font_info->max_bounds.width, 
00159                           font_info->ascent+font_info->descent, 2, 
00160                           default_depth, InputOutput, visual, valuemask, 
00161                           &attrib);
00162     }
00163     else {           
00164       popup = XCreateSimpleWindow(display, 
00165                                   RootWindow(display, screen), 
00166                                   0, 0, 40*font_info->max_bounds.width, 
00167                                   font_info->ascent+font_info->descent, 2, 
00168                                   BlackPixel(display, screen), 
00169                                   WhitePixel(display, screen));
00170       attrib.save_under = True;
00171       XChangeWindowAttributes(display, popup, CWSaveUnder, 
00172                               &attrib);
00173 
00174     }
00175 
00176     if (REPORT_EVENT) fprintf(stderr, "Popup window id = %ld \n", popup);
00177 }
00178 
00179 lux_xinit()
00180 {
00181     static int status = 0;
00182 
00183     if( !status ) {
00184 
00185       XSetErrorHandler(lux_handler);
00186       if ( (display=XOpenDisplay(display_name)) == NULL )
00187         {
00188           (void) fprintf( stderr, 
00189                          "Cannot connect to X server %s\n", 
00190                          XDisplayName(display_name));
00191           if (mcdrawflag) return 1;
00192           else exit( -1 );
00193         }
00194  
00195       screen = DefaultScreen(display);
00196       display_width  = DisplayWidth(display, screen);
00197       display_height = DisplayHeight(display, screen);
00198       default_depth  = DefaultDepth(display, screen);
00199 
00200       cursor = XCreateFontCursor(display, XC_crosshair);
00201       {
00202         /* To get the window ID where the program start from, not for sure */
00203         XGetInputFocus(display, &focus, &revert);
00204 /*      fprintf(stderr, "Window focus in %d \n", focus);*/
00205       }
00206       XMAXREQUESTSIZE = XMaxRequestSize(display);
00207 /*      fprintf(stderr, "XMaxRequestSize = %d \n", XMaxRequestSize(display);*/
00208 
00209       colormap = lux_setup_colormap(display, screen, &visual);
00210       if (colormap == DefaultColormap(display, screen)) {
00211         visual = DefaultVisual(display, screen);
00212 /*      fprintf(stderr, "Use default visual\n");*/
00213       }
00214       protocols = XInternAtom(display, "WM_DELETE_WINDOW", True);
00215       lux_init_gc();
00216       lux_create_popup();
00217       status = 1;
00218      }
00219 /*    fprintf(stderr, "Initialized\n");*/
00220     return 0;
00221 }
00222 
00223 /* Convenient accessors: */
00224 
00225 int lux_get_display_width()
00226 {
00227     return display_width;
00228 }
00229 
00230 int lux_get_display_height()
00231 {
00232     return display_height;
00233 }
00234 
00235 Bool predproc(display, event, arg)
00236 Display  *display;
00237 XEvent   *event;
00238 char     *arg;
00239 {
00240     register Window win;
00241 
00242     win = *(Window *)arg;
00243 
00244     switch (event->type) {
00245         case Expose:
00246           if (event->xexpose.window != win) return False;
00247           return True;
00248           break;
00249         default:
00250           return False;
00251           break;
00252     }
00253 }
00254 
00255 lux_wait_windowexpose(win)
00256 Window win;
00257 {
00258     XEvent report;
00259     Window window;
00260 
00261     window = win;   /* Very tricky */
00262     XPeekIfEvent(display, &report, predproc, (char *)(&window));
00263 }
00264 
00265 Bool keypredproc(display, event, arg)
00266 Display     *display;
00267 XEvent   *event;
00268 char        *arg;
00269 {
00270     Window              win;
00271     char                buffer[255];
00272     KeySym              keysym;
00273     int                 buffersize;
00274     int                 charcount;
00275     XComposeStatus      compose;
00276     char                key;
00277 
00278     buffersize = 20;
00279 
00280     win = *(Window *)arg;
00281     key = arg[sizeof(Window)];
00282 
00283     switch (event->type) {
00284         case KeyPress:
00285           if (event->xkey.window != win) break;
00286           charcount = XLookupString(&(event->xkey), buffer, buffersize, 
00287                                     &keysym, &compose);
00288           if (charcount == 0) break;
00289           if (((keysym >= XK_KP_Space) && (keysym <= XK_KP_9))
00290               || ((keysym >= XK_space) && (keysym <= XK_asciitilde))) {
00291             buffer[charcount] = 0;
00292 /*          fprintf(stderr, "get %d  %s keypress in win %u\n", charcount, 
00293                    buffer, win);*/
00294             if (buffer[0] == key) return True;
00295           }
00296           break;
00297         default:
00298           return False;
00299           break;
00300     }
00301     return False;
00302 }
00303 
00304 Bool lux_check_keypress(win, key)
00305 Window win;
00306 char key;
00307 {
00308 
00309     XEvent report;
00310     char   s[20];
00311 
00312     ((Window *)s)[0] = win;
00313     s[sizeof(Window)] = key;
00314     return XCheckIfEvent(display, &report, keypredproc, s);
00315 }
00316 
00317 
00318 Bool lux_next_keypress(win, key, function, shift, control)
00319 Window win;
00320 char *key, *shift, *control, function[20];
00321 {
00322     char                buffer[255];
00323     KeySym              keysym;
00324     int                 buffersize = 20;
00325     int                 charcount;
00326     XComposeStatus      compose;
00327     XEvent              report;
00328 
00329     *key = 0;
00330     *shift = 0;
00331     *control = 0;
00332     function[0] = 0;
00333 
00334     /* Really should take care of expose/resize events while waiting... */
00335 
00336     if (XCheckTypedWindowEvent(display, win, KeyPress, &report)) {
00337 
00338         charcount = XLookupString(&(report.xkey), buffer, buffersize, 
00339                                   &keysym, &compose);
00340 /*
00341         fprintf(stderr, "Charcount=%d, Keystate=%d, keysym=%d, key=%c\n", 
00342                 charcount, report.xkey.state, keysym, buffer[0]);
00343 */
00344         if (charcount != 0 ) {
00345             *key = buffer[0];
00346             return 1;
00347         } else {
00348             if      (keysym == XK_Up)    strcat(function, "Up");
00349             else if (keysym == XK_Down)  strcat(function, "Down");
00350             else if (keysym == XK_Right) strcat(function, "Right");
00351             else if (keysym == XK_Left)  strcat(function, "Left");
00352             else if (keysym == XK_R7)    strcat(function, "Home");
00353             else if (keysym == XK_R9)    strcat(function, "PgUp");
00354             else if (keysym == XK_R11)   strcat(function, "R11");
00355             else if (keysym == XK_R15)   strcat(function, "PgDn");
00356             else if (keysym == XK_End)   strcat(function, "End");
00357             else return 0; /* Other keys are not yet handled */
00358 
00359             if (report.xkey.state & ControlMask) *control = 1;
00360             if (report.xkey.state & ShiftMask) *shift = 1;
00361         }
00362         return 1;
00363     }
00364     return 0;
00365 }
00366 
00367 Bool buttonpredproc(display, event, arg)
00368 Display  *display;
00369 XEvent   *event;
00370 char     *arg;
00371 {
00372     Window  win;
00373 
00374     win = *((Window *)arg);
00375 
00376     switch (event->type) {
00377         case ButtonPress:
00378           if (event->xbutton.window != win) break;
00379           ((unsigned int *)arg)[0] = event->xbutton.button;
00380           return True;
00381           break;
00382         default:
00383           return False;
00384           break;
00385     }
00386     return False;
00387 }
00388 
00389 lux_check_buttonpress(win)
00390 Window win;
00391 {
00392     XEvent report;
00393     char   s[32];
00394 
00395     ((Window *)s)[0] = win;
00396     if (XCheckIfEvent(display, &report, buttonpredproc, s)) {
00397 /*      fprintf(stderr, "Button pressed %d \n", 
00398               ((unsigned int *)s)[0]);*/
00399       return (((unsigned int *)s)[0]);
00400     }
00401     else return -1;
00402 }
00403 
00404 
00405 Bool buttonpositionpred(display, event, arg)
00406 Display  *display;
00407 XEvent   *event;
00408 char     *arg;
00409 {
00410     Window  win;
00411 
00412     win = *((Window *)arg);
00413 
00414     switch (event->type) {
00415         case ButtonPress:
00416           if (event->xbutton.window != win) break;
00417           ((unsigned int *)arg)[0] = event->xbutton.button;
00418           ((int *)(&(arg[sizeof(Window)])))[0] = event->xbutton.x;
00419           ((int *)(&(arg[sizeof(Window)])))[1] = event->xbutton.y;
00420           return True;
00421           break;
00422         default:
00423           return False;
00424           break;
00425     }
00426     return False;
00427 }
00428 
00429 lux_check_buttonposition(win, x, y)
00430 Window win;
00431 int *x, *y;
00432 {
00433 
00434     XEvent report;
00435     char   s[sizeof(Window)+sizeof(int)*2];
00436 
00437     ((Window *)s)[0] = win;
00438     if (XCheckIfEvent(display, &report, buttonpositionpred, s)) {
00439 /*      fprintf(stderr, "Button pressed %d \n", 
00440               ((unsigned int *)s)[0]);*/
00441         *x = ((int *)(&(s[sizeof(Window)])))[0];
00442         *y = ((int *)(&(s[sizeof(Window)])))[1];
00443       return (((unsigned int *)s)[0]);
00444     }
00445     else return 0;
00446 }
00447 
00448 lux_clear_pixmap(display, pixmap, gc, x, y, width, height)
00449 Display *display;
00450 Drawable pixmap;
00451 GC       gc;
00452 unsigned int x, y, width, height;
00453 {
00454     XGCValues values;
00455 
00456     XGetGCValues(display, gc, GCForeground | GCBackground, &values);
00457 
00458     XSetForeground(display, gc, values.background);
00459     XFillRectangle(display, pixmap, gc, x, y, width, height);
00460     XSetForeground(display, gc, values.foreground);
00461 }
00462 
00463 
00464 #define icon_bitmap_width 40
00465 #define icon_bitmap_height 40
00466 
00467 lux_createwin(win)
00468 lux_win *win;
00469 {
00470     
00471     static char default_win_name[255];
00472     static char default_icon_name[255];
00473 
00474     static unsigned char default_icon_bitmap_bits[] = {
00475         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
00476         0x00, 0x00, 0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00, 
00477         0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0xe0, 0x00, 0x40, 0x00, 0x00, 0xc0, 
00478         0x00, 0x00, 0x00, 0x00, 0xc0, 0x05, 0x00, 0xc0, 0x00, 0x80, 0x03, 0x00, 
00479         0x00, 0x00, 0x80, 0x13, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 
00480         0x00, 0x9e, 0x00, 0x00, 0x02, 0x00, 0x7c, 0x48, 0x00, 0x00, 0x00, 0xf8, 
00481         0xfe, 0x00, 0x00, 0x00, 0xf0, 0xf8, 0x01, 0x00, 0x00, 0xf0, 0xf3, 0x03, 
00482         0x00, 0x08, 0xe0, 0xe3, 0x03, 0x00, 0x00, 0xc0, 0xd7, 0x03, 0x00, 0x10, 
00483         0xe0, 0x8f, 0x07, 0x00, 0x10, 0xa0, 0x5f, 0x06, 0x00, 0x00, 0xe0, 0x3f, 
00484         0x04, 0x10, 0x00, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x40, 0xff, 0x05, 0x00, 
00485         0x00, 0x80, 0xff, 0x03, 0x40, 0x00, 0x80, 0xfe, 0x0b, 0x00, 0x00, 0x00, 
00486         0xfa, 0x03, 0x00, 0x00, 0x00, 0xa8, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x3e, 
00487         0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x18, 
00488         0x00, 0x00, 0x60, 0x40, 0x0c, 0x00, 0x00, 0xa0, 0x00, 0x08, 0x40, 0x00, 
00489         0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x05, 0x00, 0x80, 0x00, 0x00, 0x0c, 
00490         0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
00491         0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00, 0x00};
00492     static XSizeHints default_size_hints = {
00493       USPosition | USSize | PPosition | PSize, 
00494       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00495     static int        status = 0, num = 0;
00496     XSetWindowAttributes   attrib;
00497     unsigned     long      valuemask;
00498     Window root;      unsigned int border_width;
00499 
00500     if ( !status ) {
00501       default_icon_pixmap
00502           = (Pixmap) XCreateBitmapFromData(display, 
00503                                            RootWindow(display, screen), 
00504                                            (char*) default_icon_bitmap_bits, 
00505                                            icon_bitmap_width, 
00506                                            icon_bitmap_height);
00507       sprintf(default_win_name, " Window (%d) ", num);
00508       sprintf(default_icon_name, " Icon (%d) ", num);
00509       status = 1;
00510     }
00511     else {
00512       if (win->type == GRAPH_WINDOW || win->type == DIALOG_WINDOW) {
00513       num++;
00514       sprintf(default_win_name, " Window (%d) ", num);
00515       sprintf(default_icon_name, " Icon (%d) ", num);
00516       }
00517     }
00518 
00519     switch(win->type) {
00520       case GRAPH_WINDOW:
00521       case DIALOG_WINDOW:
00522         win->parent = RootWindow(win->display, win->screen);
00523         break;
00524       case BUTTON_WINDOW:
00525       case INPUT_WINDOW:
00526         break;
00527       default:
00528         win->parent = RootWindow(win->display, win->screen);
00529         break;
00530     }
00531 
00532     if (colormap != DefaultColormap(win->display, win->screen)) {
00533       attrib.colormap = colormap;
00534       attrib.background_pixel=WhitePixel(display, screen);
00535       attrib.border_pixel = BlackPixel(display, screen);
00536       valuemask = CWColormap | CWBackPixel | CWBorderPixel;
00537       win->window = XCreateWindow(win->display, win->parent, 
00538                           win->x, win->y, win->width, win->height, 1, 
00539                           win->window_depth, InputOutput, visual, valuemask, 
00540                           &attrib);
00541       win->colormap = colormap;
00542     }
00543     else {           
00544       win->window = XCreateSimpleWindow(
00545                     win->display, win->parent, 
00546                     win->x, win->y, win->width, win->height, 1, 
00547                     BlackPixel(win->display, win->screen), 
00548                     WhitePixel(win->display, win->screen));
00549       win->colormap = DefaultColormap(win->display, win->screen);
00550     }
00551 
00552     if ( win->window_name == (char *)NULL ) win->window_name = default_win_name;
00553     if ( win->icon_name   == (char *)NULL ) win->icon_name   = default_icon_name;
00554     if ( win->icon_pixmap == (Pixmap)NULL ) win->icon_pixmap = default_icon_pixmap;
00555 
00556 
00557     if ( win->size_hints.flags == (long)NULL ) {
00558       win->size_hints.flags = default_size_hints.flags;
00559       win->size_hints.x = win->x;
00560       win->size_hints.y = win->y;
00561       win->size_hints.width  = win->width;
00562       win->size_hints.height = win->height;
00563       win->size_hints.min_width  = 0;
00564       win->size_hints.min_height = 0;
00565       switch(win->type) {
00566         case DIALOG_WINDOW:
00567         case BUTTON_WINDOW:
00568         case INPUT_WINDOW:
00569           win->size_hints.flags = PAllHints | USPosition | USSize;
00570           win->size_hints.min_width  = win->size_hints.max_width  = win->width;
00571           win->size_hints.min_height = win->size_hints.max_height = win->height;
00572           win->size_hints.width_inc  = win->size_hints.height_inc = 0;
00573           break;
00574         case GRAPH_WINDOW:
00575         default:
00576           break;
00577         }
00578     }
00579 
00580     lux_get_wingc(win);
00581 
00582     XSetStandardProperties(win->display, win->window, win->window_name, 
00583                            win->icon_name, win->icon_pixmap, 
00584                            (char **)NULL, 0, &win->size_hints);
00585 
00586     switch(win->type) {
00587       case GRAPH_WINDOW:
00588       case DIALOG_WINDOW:
00589         valuemask = ExposureMask | KeyPressMask | ButtonPressMask | 
00590                     ButtonReleaseMask | StructureNotifyMask |
00591                     ButtonMotionMask | EnterWindowMask | LeaveWindowMask 
00592                     /*| FocusChangeMask*/;
00593         break;
00594       case BUTTON_WINDOW:
00595         valuemask = ExposureMask | ButtonPressMask | 
00596                     EnterWindowMask | LeaveWindowMask;
00597         break;
00598       case INPUT_WINDOW:
00599         valuemask = ExposureMask | KeyPressMask | 
00600                     EnterWindowMask | LeaveWindowMask;
00601         break;
00602       default:
00603         valuemask = ExposureMask | KeyPressMask | ButtonPressMask | 
00604                     ButtonReleaseMask | StructureNotifyMask |
00605                     ButtonMotionMask | EnterWindowMask | LeaveWindowMask 
00606                     /*| FocusChangeMask*/;
00607         break;
00608       }
00609     XSelectInput(win->display, win->window, valuemask);
00610 
00611     XSetWMProtocols(win->display, win->window, &protocols, 1);
00612 
00613     switch(win->type) {
00614       case BUTTON_WINDOW:
00615       case INPUT_WINDOW:
00616         XMapWindow(win->display, win->window);
00617         break;
00618       case GRAPH_WINDOW:
00619 
00620         XMapWindow(win->display, win->window);
00621         XFlush(win->display);
00622 
00623         lux_wait_windowexpose(win->window);
00624 
00625         /*
00626          * This is for reconfiguring the window in case it was changed by
00627          * the WM.  The x, y will not be the values you provide, and even
00628          * not relative to the root, but to its parent which WM creates
00629          * for you
00630          */
00631 
00632         XGetGeometry(win->display, win->window, &root, &win->x, &win->y, 
00633                      &win->width, &win->height, &border_width,
00634                      &win->window_depth);
00635 
00636         if (win->width != win->old_width) 
00637           win->xresizefactor = (float)win->width/(float)win->user_width;
00638         if (win->height != win->old_height) 
00639           win->yresizefactor = (float)win->height/(float)win->user_height;
00640 
00641 
00642         win->pixmap = XCreatePixmap(win->display, 
00643                                     win->window, 
00644                                     win->width, win->height, 
00645                                     win->window_depth);
00646 
00647         XSync(win->display, False);/* Wait for operation to finish in order
00648                                       for error to be handled */
00649         if (!pmpallocflag) {win->pixmap = (Pixmap)NULL; pmpallocflag = 1;}
00650 
00651         if (win->pixmap)         /* Here is to clear the pixmap  */
00652           lux_clear_pixmap(win->display, win->pixmap, win->gc, 
00653                            0, 0, win->width, win->height);
00654         break;
00655       case DIALOG_WINDOW:
00656 /*        XMapWindow(win->display, win->window);*/
00657         break;
00658       default:
00659         fprintf(stderr, "No window type specified !");
00660         XMapWindow(win->display, win->window);
00661         break;
00662       }
00663 }
00664 
00665 lux_wins *lux_allocwin()
00666 {
00667 
00668      register lux_wins *newwin;
00669 
00670      if ( windows == (lux_wins *)NULL ) {
00671        if ( (newwin = windows = (lux_wins *)malloc(sizeof(lux_wins))) == NULL )
00672                       return (lux_wins *)NULL;
00673        windows->next = windows;
00674      }
00675      else {
00676        if ( (newwin = (lux_wins *)malloc(sizeof(lux_wins))) == NULL ) 
00677                       return (lux_wins *)NULL;
00678        newwin->next  = windows->next;
00679        windows->next = newwin;
00680      }
00681      
00682      /* Setup default values for window */
00683      newwin->win.display = display;
00684      newwin->win.screen  = screen;
00685      newwin->win.update_flag  = 1;      /* default to no animation    */
00686      newwin->win.discard_flag    = 0;      /* default to save everything */
00687      newwin->win.pixmap  = (Pixmap)NULL;
00688      newwin->win.window_depth = default_depth;
00689      newwin->win.window_name  = (char *)NULL;
00690      newwin->win.icon_name    = (char *)NULL;
00691      newwin->win.icon_pixmap  = (Pixmap)NULL;
00692      newwin->win.size_hints.flags   =   (long)NULL;
00693      newwin->win.data = (lux_data *)NULL;
00694      newwin->win.currentdata = (lux_data *)NULL;
00695      newwin->win.window_size = 0;      /* set to ok */
00696      newwin->win.msg[0] = (char)NULL;
00697      if (colorfile == NULL) newwin->win.colormapfile = NULL;
00698      else {
00699          newwin->win.colormapfile = (char *)malloc(strlen(colorfile)+1);
00700          newwin->win.colormapfile[0] = 0;
00701          strcat(newwin->win.colormapfile, colorfile);
00702      }
00703      newwin->win.lux_colormap = lux_colormap;
00704 
00705      return newwin;
00706 }
00707 
00708 Window lux_openwin(x, y, width, height)   /* Open a new graphics window */
00709 unsigned int x, y, width, height;
00710 {
00711     register lux_wins *mywin;
00712     static   int       status = 0;
00713 
00714     if ( !status ) {
00715       if(lux_xinit()) return 0;
00716       status = 1;
00717     }
00718 
00719     if ((mywin = lux_allocwin()) == (lux_wins *)NULL ) return (Window)NULL;
00720     
00721     mywin->win.type = GRAPH_WINDOW;
00722 
00723     mywin->win.x = x;
00724     mywin->win.y = y;
00725     mywin->win.width  = width;
00726     mywin->win.height = height;
00727     mywin->win.old_width   = width;
00728     mywin->win.old_height  = height;
00729     mywin->win.user_width  = width;
00730     mywin->win.user_height = height;
00731     mywin->win.xresizefactor = 1.0;
00732     mywin->win.yresizefactor = 1.0;
00733 
00734     mywin->win.buttonflag = 0;
00735 
00736     mywin->win.fxorg = 0.0;
00737     mywin->win.fyorg = 0.0;
00738     mywin->win.fxsize = 10.0;
00739     mywin->win.fysize = 10.0;
00740     mywin->win.xfactor = 1.0;
00741     mywin->win.yfactor = 1.0;
00742     mywin->win.xmin = 1.0;
00743     mywin->win.xmax = width;
00744     mywin->win.ymin = 1.0;
00745     mywin->win.ymax = height;
00746     mywin->win.xsize = width;
00747     mywin->win.ysize = height;
00748     mywin->win.xorg = 0;
00749     mywin->win.yorg = 0;
00750     
00751     mywin->win.lnx = 0;    /* Default to ordinary axis */
00752     mywin->win.lny = 0;
00753 
00754     lux_createwin(&mywin->win);
00755  
00756 /* Make sure that all this setup to default when start to redraw */   
00757     lux_setup_region(mywin->win.window, 
00758                      mywin->win.fxorg, mywin->win.fyorg, 
00759                      mywin->win.fxsize, mywin->win.fysize);
00760     lux_setup_axis_style(mywin->win.window, mywin->win.lnx, mywin->win.lny);
00761     lux_setup_axis(mywin->win.window, 
00762                    mywin->win.xmin, mywin->win.xmax, 
00763                    mywin->win.ymin, mywin->win.ymax);
00764 /* Maybe we should add clear screen to set the window clear to default */
00765 
00766     return mywin->win.window;
00767 }
00768 
00769 lux_wins *get_currentwin(window)
00770 Window    window;
00771 {
00772     register lux_wins *start;
00773     
00774     if ( windows == (lux_wins *)NULL ) 
00775       fprintf(stderr, "lux_err: NULL window!\n");
00776     start = windows;
00777     while (start->win.window != window ) { 
00778       start = start->next;
00779       if (start == windows && start->win.window != window) {
00780         fprintf(stderr, "lux_err: Window id = %d not found!\n", window);
00781         break;
00782       }
00783     }
00784     windows = start;
00785     return start;    
00786 }
00787 
00788 lux_freedata(win)
00789 Window win;
00790 {
00791     register lux_wins *current;
00792     register int      *ptr;
00793 
00794     current = get_currentwin(win);
00795 
00796     if ( current->win.data == (lux_data *)NULL ) return;
00797     
00798     while(1) {
00799       current->win.currentdata = current->win.data;
00800       if (current->win.data == (current->win.data)->next) {
00801         if((current->win.currentdata)->data.b != (char *)NULL) {
00802             if ((current->win.currentdata)->type == DRAW_VSTRING) {
00803                 ptr = (int *)(&(current->win.currentdata)->data.f[3]);
00804                 XDestroyImage(((XImage **)(&ptr[2]))[0]);
00805             }
00806             free((current->win.currentdata)->data.b);
00807         }
00808         free(current->win.currentdata);
00809         break;
00810       }
00811 
00812       current->win.data = (current->win.data)->next;
00813       if((current->win.currentdata)->data.b != (char *)NULL) {
00814           if ((current->win.currentdata)->type == DRAW_VSTRING) {
00815               ptr = (int *)(&(current->win.currentdata)->data.f[3]);
00816               XDestroyImage(((XImage **)(&ptr[2]))[0]);
00817           }
00818           free((current->win.currentdata)->data.b);
00819       }
00820       free(current->win.currentdata);
00821     }
00822 
00823     current->win.currentdata = current->win.data = (lux_data *)NULL;
00824 }
00825 
00826 lux_freewins()
00827 {
00828     register lux_wins *current, *start, *tmp;
00829     XEvent             report;
00830 
00831     if ( windows == (lux_wins *)NULL ) return;
00832 
00833     current = start = windows;
00834 
00835     XDestroyWindow(current->win.display, popup);
00836     lux_create_popup();
00837 
00838     do {
00839       lux_freedata(current->win.window);
00840       current = current->next;
00841     } while(current != start);
00842   
00843     do {
00844       tmp = current;
00845       current = current->next;
00846       if ((tmp->win.icon_pixmap != default_icon_pixmap) && 
00847           tmp->win.icon_pixmap) {
00848         XFreePixmap(tmp->win.display, tmp->win.icon_pixmap);
00849         tmp->win.icon_pixmap = (Pixmap)NULL;
00850       }
00851       if (tmp->win.pixmap) {
00852         XFreePixmap(tmp->win.display, tmp->win.pixmap);
00853         tmp->win.pixmap = (Pixmap)NULL;
00854       }
00855       XUnmapWindow(tmp->win.display, tmp->win.window);
00856       XDestroyWindow(tmp->win.display, tmp->win.window);
00857       XSync(tmp->win.display, False);
00858       while(XCheckWindowEvent(tmp->win.display, 
00859                               tmp->win.window, 
00860                               0xFFFFFFFF, &report));
00861       XFreeGC(tmp->win.display, tmp->win.gc);
00862       free(tmp);
00863     } while(current != start);
00864 
00865     windows = (lux_wins *)NULL;
00866 }
00867 
00868 lux_reset_window(win)    /* Clear everything and the default values are random*/
00869 Window win;
00870 {
00871     register lux_wins *current;
00872 
00873     current = get_currentwin(win);
00874   
00875     XClearWindow(current->win.display, current->win.window);
00876     if (current->win.pixmap) 
00877       lux_clear_pixmap(current->win.display, current->win.pixmap, 
00878                        defaultgc, 0, 0, 
00879                        current->win.width, current->win.height);
00880     XFlush(current->win.display);
00881     lux_freedata(current->win.window);
00882 }
00883 
00884 lux_freewin(win)        /* Delete the specified window */
00885 Window win;
00886 {
00887     register lux_wins *current, *tmp;
00888     XEvent             report;
00889 
00890     if ( windows == (lux_wins *)NULL ) return;
00891 
00892     current = get_currentwin(win);
00893 
00894     XDestroyWindow(current->win.display, popup);
00895     lux_create_popup();
00896 
00897     lux_freedata(current->win.window);
00898 
00899     tmp = current;
00900     if ((tmp->win.icon_pixmap != default_icon_pixmap) && 
00901         tmp->win.icon_pixmap) {
00902       XFreePixmap(tmp->win.display, tmp->win.icon_pixmap);
00903       tmp->win.icon_pixmap = (Pixmap)NULL;
00904     }
00905     if (tmp->win.pixmap) {
00906       XFreePixmap(tmp->win.display, tmp->win.pixmap);
00907       tmp->win.pixmap = (Pixmap)NULL;
00908     }
00909     XUnmapWindow(tmp->win.display, tmp->win.window);
00910     XDestroyWindow(tmp->win.display, tmp->win.window);
00911     XSync(tmp->win.display, False);
00912     while(XCheckWindowEvent(tmp->win.display, 
00913                             tmp->win.window, 
00914                             0xFFFFFFFF, &report));
00915     XFreeGC(tmp->win.display, tmp->win.gc);
00916     while(tmp->next != current) tmp = tmp->next;
00917     tmp->next = current->next;
00918     if (current == current->next)
00919       windows = (lux_wins*)NULL;
00920     else  windows = current->next;
00921     free(current);
00922 }
00923 
00924 lux_exit()
00925 {
00926   if (display == (Display *)NULL) {
00927     fprintf(stderr, "No open window!\n");
00928     exit(0);
00929   }
00930 
00931   lux_freewins();
00932   XFreePixmap(display, default_icon_pixmap);
00933   XUnloadFont(display, font_info->fid);
00934   XFreeGC(display, defaultgc);
00935   XFreeGC(display, redrawgc);
00936   XCloseDisplay(display);
00937   exit(1);
00938 }
00939 
00940 lux_quick_exit()
00941 {
00942   if (display == (Display *)NULL) {
00943 /*    fprintf(stderr, "No open window!\n");*/
00944    if (mcdrawflag) return 0;
00945    else exit(0);
00946   }
00947 
00948   XFreePixmap(display, default_icon_pixmap);
00949   XUnloadFont(display, font_info->fid);
00950   XFreeGC(display, defaultgc);
00951   XFreeGC(display, redrawgc);
00952   XCloseDisplay(display);
00953   if (mcdrawflag) return 0;
00954   else exit(1);
00955 }
00956 
00957 static int wait_time = 0;
00958 void set_wait_time(i)
00959 int i;
00960 {
00961     wait_time = i;
00962 }
00963 int get_wait_time()
00964 {
00965     return wait_time;
00966 }
00967 
00968 char win_getkey(Window win)
00969 
00970 /*
00971  * See if a key has been pressed in the specified window, and respond
00972  * to a resize event in any window.  Return after the first event with
00973  * NULL or the key that was pressed.
00974  */
00975 
00976 {
00977     XEvent              report;
00978     register lux_wins  *current;
00979     char                buffer[255];
00980     KeySym              keysym;
00981     int                 buffersize = 20;
00982     int                 charcount;
00983     XComposeStatus      compose;
00984 
00985     buffer[0] = buffer[1] = 0;
00986 
00987     if (windows == (lux_wins *)NULL) {
00988         if (REPORT_EVENT) fprintf(stderr, "No open window!\n");
00989         return 0;
00990     }
00991 
00992     /* Grab the next event from the queue. */
00993 
00994     XNextEvent(display, &report);
00995 
00996     current = get_currentwin(report.xany.window);
00997 
00998     /* (The current window ID, as returned by lux_openwin, is
00999      *
01000      *          current->win.window
01001      *
01002      *  which is of type Window, aka unsigned long.)
01003      */
01004 
01005     /* Expose and ConfigureNotify events must be acted upon
01006      * regardless of the window they occur in.
01007      *
01008      * DISCARD all other events, except a keypress in the
01009      * specified window.
01010      */
01011 
01012     if (report.type == Expose) {        /* Window exposed (or resized?) */
01013 
01014         if (REPORT_EVENT) fprintf(stderr, "Get Expose event in win %u\n", 
01015                                   current->win.window);
01016 
01017         if (!report.xexpose.count) {
01018 
01019             if (current->win.window_size == SMALL)
01020                 /* do something for small? */
01021                 ;
01022 
01023             redraw(current->win.window, 0);
01024         }
01025 
01026     } else if (report.type == ConfigureNotify) {        /* Window resized */
01027 
01028         if (REPORT_EVENT) fprintf(stderr,
01029                                   "Get ConfigureNotify in win %u\n", 
01030                                   current->win.window);
01031 
01032         current->win.x = report.xconfigure.x;
01033         current->win.y = report.xconfigure.y;
01034         current->win.width  = report.xconfigure.width;
01035         current->win.height = report.xconfigure.height;
01036 
01037         if (current->win.old_width  != current->win.width) 
01038             current->win.xresizefactor
01039                 = (float)current->win.width /
01040                     (float)current->win.user_width;
01041 
01042         if (current->win.old_height != current->win.height) 
01043             current->win.yresizefactor
01044                 = (float)current->win.height /
01045                     (float)current->win.user_height;
01046 
01047         if ((current->win.width
01048              < current->win.size_hints.min_width) ||
01049             (current->win.height
01050              < current->win.size_hints.min_height))
01051             current->win.window_size = SMALL;
01052         else
01053             current->win.window_size = OK;
01054 
01055     } else if (current->win.window == win && report.type == KeyPress)
01056 
01057         if (XLookupString(&(report.xkey), 
01058                           buffer, buffersize, 
01059                           &keysym, &compose)) return buffer[0];
01060 
01061     return 0;
01062 }
01063 
01064 void win_checkevent(Window win)
01065 
01066 /*
01067  * Respond to all pending expose or resize events in the specified
01068  * window.  Return when the pending stack is exhausted.
01069  */
01070 
01071 {
01072     XEvent              report;
01073     register lux_wins  *current;
01074     char                buffer[255];
01075     KeySym              keysym;
01076     int                 buffersize = 20;
01077     int                 charcount;
01078     XComposeStatus      compose;
01079 
01080     buffer[0] = buffer[1] = 0;
01081 
01082     if (windows == (lux_wins *)NULL)
01083         if (REPORT_EVENT) fprintf(stderr, "No open window!\n");
01084 
01085     current = get_currentwin(win);
01086 
01087     /* (The current window ID, as returned by lux_openwin, is
01088      *
01089      *          current->win.window
01090      *
01091      *  which is of type Window, aka unsigned long.)
01092      */
01093 
01094     /* Loop through all pending events for this window. */
01095 
01096     while (XCheckWindowEvent(current->win.display, 
01097                             current->win.window, 
01098                             0xFFFFFFFF, &report)) {
01099 
01100         /* Act upon Expose and ConfigureNotify events.  DISCARD all others. */
01101 
01102         if (report.type == Expose) {    /* Window exposed (or resized?) */
01103 
01104             if (REPORT_EVENT) fprintf(stderr, "Get Expose event in win %u\n", 
01105                                       current->win.window);
01106 
01107             if (!report.xexpose.count) {
01108 
01109                 if (current->win.window_size == SMALL)
01110                     /* do something for small? */
01111                     ;
01112 
01113                 redraw(current->win.window, 0);
01114         }
01115 
01116         } else if (report.type == ConfigureNotify) {    /* Window resized */
01117 
01118             if (REPORT_EVENT) fprintf(stderr,
01119                                       "Get ConfigureNotify in win %u\n", 
01120                                       current->win.window);
01121 
01122             current->win.x = report.xconfigure.x;
01123             current->win.y = report.xconfigure.y;
01124             current->win.width  = report.xconfigure.width;
01125             current->win.height = report.xconfigure.height;
01126 
01127             if (current->win.old_width  != current->win.width) 
01128                 current->win.xresizefactor
01129                     = (float)current->win.width /
01130                         (float)current->win.user_width;
01131 
01132             if (current->win.old_height != current->win.height) 
01133                 current->win.yresizefactor
01134                     = (float)current->win.height /
01135                         (float)current->win.user_height;
01136 
01137             if ((current->win.width
01138                  < current->win.size_hints.min_width) ||
01139                 (current->win.height
01140                  < current->win.size_hints.min_height))
01141                 current->win.window_size = SMALL;
01142             else
01143                 current->win.window_size = OK;
01144 
01145         }
01146     }
01147 }
01148 
01149 int win_getevent(Window win, int win_type, int hide_on_cr)
01150 
01151 /* Expands on functionality of old lux_getevent.
01152  * Comments and modifications added 10/95, SLWM.
01153  */
01154 
01155 {
01156     XEvent              report;
01157     register lux_wins  *current;
01158     char                buffer[255];
01159     KeySym              keysym;
01160     int                 buffersize = 20;
01161     int                 charcount;
01162     XComposeStatus      compose;
01163     Time                buttondown;
01164     unsigned int        button, xbutton, ybutton;
01165     int                 click = 0;
01166     Window              wbutton;
01167     int                 pop = 0;
01168 
01169     buffer[0] = buffer[1] = 0;
01170 
01171     if (windows == (lux_wins *)NULL) {
01172         if (REPORT_EVENT) fprintf(stderr, "No open window!\n");
01173         return 0;
01174     }
01175 
01176     /* Enter infinite event loop. */
01177 
01178     while (1)  {
01179 
01180         if (wait_time > 0) lux_pause(wait_time);  /* Unit = microseconds */
01181 
01182         if (mcdrawflag) {
01183             if (XPending(display) == 0) {
01184                 if (get_timeout()) return 7;
01185                 continue;
01186             }
01187         }
01188 
01189         /* Grab the next event from the queue. */
01190 
01191         XNextEvent(display, &report);
01192 
01193         current = get_currentwin(report.xany.window);
01194 
01195         /* (The current window ID, as returned by lux_openwin, is
01196          *
01197          *              current->win.window
01198          *
01199          *  which is of type Window, aka unsigned long.)
01200          */
01201 
01202 /*
01203         fprintf(stderr,
01204                 "win_getevent: target win = %ld, type = %d\n",
01205                 win, win_type, current->win.window);
01206         fprintf(stderr,
01207                 "              event win = %ld, type = %d, parent = %ld\n",
01208                 current->win.type, current->win.parent);
01209 */
01210 
01211         /* Note: Expose and ConfigureNotify events must be acted upon
01212          * regardless of the window they occur in.  Others may be
01213          * limited depending on the input preferences.
01214          */
01215 
01216         if (report.type == Expose) {    /* Window exposed (or resized?) */
01217 
01218             if (REPORT_EVENT) fprintf(stderr, "Get Expose event in win %u\n", 
01219                                       current->win.window);
01220 
01221             if (!report.xexpose.count) {
01222 
01223                 if (current->win.window_size == SMALL)
01224                     /* do something for small? */
01225                     ;
01226 
01227                 redraw(current->win.window, 0);
01228             }
01229 
01230         } else if (report.type == ConfigureNotify) {    /* Window resized */
01231 
01232             if (REPORT_EVENT) fprintf(stderr,
01233                                       "Get ConfigureNotify in win %u\n", 
01234                                       current->win.window);
01235 
01236             current->win.x = report.xconfigure.x;
01237             current->win.y = report.xconfigure.y;
01238             current->win.width  = report.xconfigure.width;
01239             current->win.height = report.xconfigure.height;
01240 
01241             if (current->win.old_width  != current->win.width) 
01242                 current->win.xresizefactor
01243                     = (float)current->win.width /
01244                         (float)current->win.user_width;
01245 
01246             if (current->win.old_height != current->win.height) 
01247                 current->win.yresizefactor
01248                     = (float)current->win.height /
01249                         (float)current->win.user_height;
01250 
01251             if ((current->win.width
01252                  < current->win.size_hints.min_width) ||
01253                 (current->win.height
01254                  < current->win.size_hints.min_height))
01255                 current->win.window_size = SMALL;
01256             else
01257                 current->win.window_size = OK;
01258 
01259         } else if ( (win <= 0 && win_type <= 0)
01260                      || current->win.window == win
01261                      || current->win.parent == win
01262                      || current->win.type == win_type) {
01263 
01264             /* Other events may be restricted in scope. */
01265 
01266             switch (report.type) {              /* Branch on event type */
01267 
01268                 case ButtonPress:               /* A button has been pressed */
01269 
01270                   if (REPORT_EVENT) {
01271                       fprintf(stderr, "get button press in win %u\n", 
01272                               current->win.window);
01273                       fprintf(stderr, 
01274                               "Button %d, position x= %d, y= %d, time= %u\n", 
01275                               report.xbutton.button, 
01276                               report.xbutton.x, 
01277                               report.xbutton.y, 
01278                               report.xbutton.time);
01279                   }
01280 
01281                   switch(current->win.type) {   /* Action depends on window */
01282 
01283                     case DIALOG_WINDOW:
01284                     case GRAPH_WINDOW:
01285 
01286                       if (report.xbutton.button == Button1
01287                            || report.xbutton.button == Button3) {
01288 
01289                           /* Left or right mouse button pressed: pop up a
01290                            * window showing the current cursor position. */
01291 
01292                           XReparentWindow(current->win.display, 
01293                                           popup, 
01294                                           current->win.window, 
01295                                           0, 
01296                                           (report.xbutton.y
01297                                             > current->win.height/2) ?
01298                                           0 : (current->win.height
01299                                                - (font_info->ascent
01300                                                   + font_info->descent) - 4) );
01301                           XMapWindow(current->win.display, popup);
01302                           pop = 1;
01303                           XFlush(current->win.display);
01304 
01305                           {
01306                               float fx, fy;
01307                               lux_reconvert_coord(current->win.window, 
01308                                                   report.xmotion.x, 
01309                                                   report.xmotion.y, 
01310                                                   &fx, &fy);
01311                               sprintf(buffer, "(%d, %d) (%f, %f)        ", 
01312                                       report.xmotion.x, report.xmotion.y, 
01313                                       fx, fy);
01314                               XDrawImageString(display, popup, defaultgc, 
01315                                                0, font_info->ascent, 
01316                                                buffer, strlen(buffer));
01317                               XFlush(current->win.display);
01318                           }
01319 
01320                           XDefineCursor(current->win.display, 
01321                                         current->win.window, cursor);
01322                           XFlush(current->win.display);
01323 
01324                           /* Special treatment of button 1: */
01325 
01326                           if (report.xbutton.button == Button1) {
01327                               if (wbutton != report.xbutton.window) click = 0;
01328                               if (report.xbutton.time - buttondown
01329                                     >= DOUBLECLICKLENGTH)
01330                                   click = 0; 
01331                               if (!click) {
01332                                   buttondown = report.xbutton.time;
01333                                   wbutton = report.xbutton.window;
01334                               }
01335                           }
01336                       }
01337                       break;
01338 
01339                     case BUTTON_WINDOW:
01340 
01341                       /* Return a value of 3 or 4 if an "exit"
01342                        * button has been pressed. */
01343 
01344                       if (current->win.subtype == OK_BUTTON) {
01345 
01346                           lux_ok_data(current->win.parent);
01347                           lux_hide_dialog(current->win.parent);
01348 
01349                           return 3;   /* OK data */
01350 
01351                       } else if (current->win.subtype == OK_KEEP_BUTTON) {
01352 
01353                           lux_ok_data(current->win.parent);
01354 
01355                           return 3;   /* OK data */
01356 
01357                       } else if (current->win.subtype == CANCEL_BUTTON) {
01358 
01359                           lux_cancel_data(current->win.parent);
01360                           lux_hide_dialog(current->win.parent);
01361 
01362                           return 4;   /* Cancel data */
01363 
01364                       } else if (current->win.subtype == CHECK_BUTTON) {
01365 
01366                           /* Otherwise, modify a check button. */
01367 
01368                           if (current->win.msg[0] == 1) {
01369 
01370                               /* Erase the box contents. */
01371 
01372                               lux_reset_window(current->win.window);
01373                               current->win.msg[0] = 0;
01374 
01375                           } else if (current->win.msg[0] == 0) {
01376 
01377                               /* Place an "X" in the box. */
01378 
01379                               lux_draw_line(current->win.window, 0, 0, 
01380                                             current->win.width, 
01381                                             current->win.height);
01382                               lux_draw_line(current->win.window, 0, 
01383                                             current->win.height, 
01384                                             current->win.width, 0);
01385                               current->win.msg[0] = 1;
01386                           }
01387                       }  
01388                       break;
01389 
01390                     case INPUT_WINDOW:
01391                       default:
01392                       break;
01393                   }
01394                   break;
01395 
01396                 case ButtonRelease:             /* A button was released */
01397 
01398                   if (REPORT_EVENT) {
01399                       fprintf(stderr, "get button release in win %u\n", 
01400                               current->win.window);
01401                       fprintf(stderr, 
01402                               "Button %d, position x= %d, y= %d, time= %u\n", 
01403                               report.xbutton.button, 
01404                               report.xbutton.x, 
01405                               report.xbutton.y, 
01406                               report.xbutton.time);
01407                   }
01408 
01409                   if (report.xbutton.button == Button1) {
01410 
01411                       /* Left mouse button: remove popup and deal
01412                        * with double click. */
01413 
01414                       XUnmapWindow(display, popup);
01415                       pop = 0;
01416 
01417                       if (report.xbutton.time - buttondown
01418                             < DOUBLECLICKLENGTH) {
01419 
01420                           if (click) {
01421 
01422                               if (REPORT_EVENT) fprintf(stderr,
01423                                                         "Double Click\n");
01424 
01425                               lux_reconvert_coord(current->win.window, 
01426                                                   report.xbutton.x, 
01427                                                   report.xbutton.y, 
01428                                                   &current->win.xbutton, 
01429                                                   &current->win.ybutton);
01430                               if (REPORT_EVENT)
01431                                   fprintf(stderr, 
01432                                           "Button position %f %f\n", 
01433                                           current->win.xbutton, 
01434                                           current->win.ybutton);
01435 
01436                               XBell(current->win.display, 100);
01437                               click = 0;
01438                               XUndefineCursor(current->win.display, 
01439                                               current->win.window);
01440 
01441                               if (current->win.buttonflag) return 0;
01442 
01443                           } else {
01444 
01445                               if (REPORT_EVENT) fprintf(stderr, "One Click\n");
01446 
01447                               click = 1;
01448                               XUndefineCursor(current->win.display, 
01449                                               current->win.window);
01450                           }
01451 
01452                       } else {
01453 
01454                           click = 0;
01455                           XUndefineCursor(current->win.display, 
01456                                           current->win.window);
01457                       }
01458 
01459                   } else if (report.xbutton.button == Button3) {
01460 
01461                       /* Right mouse button: just remove popup */
01462 
01463                       XUnmapWindow(display, popup);
01464                       pop = 0;
01465                       lux_reconvert_coord(current->win.window, 
01466                                           report.xbutton.x, report.xbutton.y, 
01467                                           &current->win.xbutton, 
01468                                           &current->win.ybutton);
01469                       XUndefineCursor(current->win.display, 
01470                                       current->win.window);
01471 
01472                       if (current->win.buttonflag) return 0;
01473 
01474                   }
01475                   break;
01476 
01477                 case MotionNotify:              /* The cursor has moved */
01478 
01479                   if (pop) {
01480 
01481                       /* Update the popup display. */
01482 
01483                       {
01484                           float fx, fy;
01485                           lux_reconvert_coord(current->win.window, 
01486                                               report.xmotion.x, 
01487                                               report.xmotion.y, 
01488                                               &fx, &fy);        
01489                           sprintf(buffer, 
01490                           "(%d, %d) (%g, %g)                                  ", 
01491                                   report.xmotion.x, report.xmotion.y, fx, fy);
01492                           XDrawImageString(display, popup, defaultgc, 
01493                                            0, font_info->ascent, 
01494                                            buffer, strlen(buffer));
01495                       }
01496                       XFlush(current->win.display);
01497                   } 
01498                   break;
01499 
01500                 case KeyPress:                  /* Keyboard input */
01501 
01502                   switch(current->win.type) {   /* Action depends on window */
01503 
01504                     case DIALOG_WINDOW: /* Dialog, outside of input regions */
01505 
01506                       charcount = XLookupString(&(report.xkey), 
01507                                                 buffer, buffersize, 
01508                                                 &keysym, &compose);
01509 
01510                       if (   ((keysym >= XK_KP_Space) && (keysym <= XK_KP_9))
01511                           || ((keysym >= XK_space)
01512                                 && (keysym <= XK_asciitilde))
01513                           || (keysym == XK_Return
01514                               || keysym == XK_Linefeed
01515                               || keysym == XK_KP_Enter) ) {
01516 
01517                           /* Keypad ' ' - '9', <CR>, or nonwhite
01518                              ASCII character. */
01519 
01520                           /* Terminate the input string. */
01521 
01522                           buffer[charcount] = 0;   /* A little bit stupid */
01523                           if (charcount == 0) break;
01524 
01525                           /* o/O in dialog window ==> OK / OK and hide
01526                            *                            (<CR> <==> 'o' or 'O')
01527                            * c/C in dialog window ==> cancel / cancel and hide
01528                            * q/Q in dialog window ==> quit program
01529                            */
01530 
01531                           if (buffer[0] == 'o' || buffer[0] == 'O'
01532                               || keysym == XK_Return
01533                               || keysym == XK_Linefeed
01534                               || keysym == XK_KP_Enter) {
01535 
01536                               /* Return, use dialog data, optionally
01537                                * hide window. */
01538 
01539                               lux_ok_data(current->win.window);
01540                               if (buffer[0] == 'O'
01541                                   || (buffer[0] != 'o' && hide_on_cr))
01542                                   lux_hide_dialog(current->win.window);
01543 
01544                               return 3;   /* OK data */
01545 
01546                           } else if (buffer[0] == 'c' || buffer[0] == 'C') {
01547 
01548                               /* Return, cancel dialog data, optionally
01549                                * hide window. */
01550 
01551                               lux_cancel_data(current->win.window);
01552                               if (buffer[0] == 'C')
01553                                   lux_hide_dialog(current->win.window);
01554 
01555                               return 4;   /* Cancel data */
01556 
01557                           } else if (buffer[0] == 'q' || buffer[0] == 'Q') {
01558 
01559                               /* Quit program. */
01560 
01561                               lux_quick_exit();
01562                           }
01563                       }
01564                       break;
01565 
01566                     case GRAPH_WINDOW:
01567 
01568                       if (mcdrawflag) {
01569 
01570                           charcount = XLookupString(&(report.xkey), 
01571                                                     buffer, buffersize, 
01572                                                     &keysym, &compose);
01573                           if (REPORT_EVENT)
01574                               fprintf(stderr, 
01575                                       "get %d %d %s keypress in win %u\n", 
01576                                       charcount, buffer[0], 
01577                                       buffer, current->win.window);
01578 
01579                           if (charcount == 0) break;
01580 
01581                           if (keysym == XK_Return
01582                               || keysym == XK_Linefeed
01583                               || keysym == XK_KP_Enter)
01584                               *buffer = '\n';
01585 
01586                           if (keysym == XK_BackSpace || keysym == XK_Delete)
01587                               *buffer = '\b';
01588 
01589                           if (process_char(*buffer)) return 6;
01590 
01591                       } else {
01592 
01593                           /* Allow limited input via the graph window. */
01594 
01595                           charcount = XLookupString(&(report.xkey), 
01596                                                     buffer, buffersize, 
01597                                                     &keysym, &compose);
01598 
01599                           if (((keysym >= XK_KP_Space)
01600                                  && (keysym <= XK_KP_9))
01601                               || ((keysym >= XK_space)
01602                                     && (keysym <= XK_asciitilde))) {
01603 
01604                               /* Keypad ' ' - '9' or nonwhite character. */
01605 
01606                               /* Terminate the input string. */
01607 
01608                               buffer[charcount] = 0;  /* A little bit stupid */
01609 
01610                               if (REPORT_EVENT)
01611                                   fprintf(stderr, 
01612                                           "get %d %s keypress in win %u\n", 
01613                                           charcount, buffer, 
01614                                           current->win.window);
01615 
01616                               if (charcount == 0) break;
01617 
01618                               /* q ==> quit
01619                                * d ==> show dialog (what if more than 1?)
01620                                * c ==> return, leave dialog unread
01621                                * C ==> clear window
01622                                * r ==> redraw window
01623                                */
01624 
01625                               if (buffer[0] == 'q')
01626 
01627                                   lux_quick_exit();
01628 
01629                               else if (buffer[0] == 'd')
01630 
01631                                   lux_show_dialog(current->win.window);
01632 
01633                               else if (buffer[0] == 'c') {
01634 
01635                                   /* A 'c' in the graph window will cause an
01636                                      immediate return.  Any dialog windows
01637                                      will remain open, but will not be
01638                                      read. */
01639 
01640                                   return 1;
01641 
01642                               } else if (buffer[0] == 'C')
01643 
01644                                   lux_reset_window(current->win.window);
01645 
01646                               else if (buffer[0] == 'r')
01647 
01648                                   redraw(current->win.window, 1);
01649                           }
01650                       }
01651 
01652                       break;
01653 
01654                     case INPUT_WINDOW:          /* Modify an input window */
01655 
01656                       charcount = XLookupString(&(report.xkey), 
01657                                                 buffer, buffersize, 
01658                                                 &keysym, &compose);
01659                       if (charcount == 0) break;
01660 
01661                       if (REPORT_EVENT)
01662                           fprintf(stderr, 
01663                               "get %d %s keypress in window %u, keysym %x\n", 
01664                                   charcount, buffer, current->win.window,
01665                                   keysym);
01666 
01667                       /* Terminate the string. */
01668 
01669                       buffer[charcount] = 0; 
01670 
01671                       {
01672                           char *tmp;
01673                           tmp = &(current->win.data->data.b[3*sizeof(float)
01674                                                              + 1]); /* wow! */
01675 
01676                           /* Note: tmp is a pointer to the first character of
01677                              the string associated with this input window. */
01678 
01679                           if ((keysym == XK_Return)
01680                               || (keysym == XK_KP_Enter)
01681                               || (keysym == XK_Linefeed))  {
01682 
01683                               lux_ok_data(current->win.parent);
01684 
01685                               if (hide_on_cr)
01686                                   lux_hide_dialog(current->win.parent);
01687 
01688                               return 3;
01689 
01690                           } else if (((keysym >= XK_KP_Space)
01691                                       && (keysym <= XK_KP_9))
01692                                    || ((keysym >= XK_space)
01693                                          && (keysym <= XK_asciitilde))) {
01694 
01695                               /* Keypad ' ' - '9' or nonwhite character. */
01696 
01697                               /* Build up the string. */
01698 
01699                               if ((int)(strlen(tmp) + strlen(buffer)) > 230) 
01700                                   XBell(current->win.display, 100);
01701                               else
01702                                   strcat(tmp, buffer);
01703 
01704                           } else if ((keysym == XK_BackSpace)
01705                                        || (keysym == XK_Delete)) {
01706 
01707                               int length;
01708                               if ((length = strlen(tmp)) > 0)
01709                                   tmp[length-1] = (char)NULL;
01710 
01711                           } else if (keysym == XK_Escape) {
01712 
01713                               /* ESCAPE deletes the entire string. */
01714 
01715                               tmp[0] = (char)NULL;
01716 
01717                           }
01718                       }
01719                       redraw(current->win.window, 1);
01720                       break;
01721 
01722                     case BUTTON_WINDOW:
01723                       default:
01724                       break;
01725                   }
01726                   buffer[1]=(char)NULL;
01727                   break;
01728 
01729                 case EnterNotify:               /* Highlight input or button
01730                                                    window on entry */
01731 
01732                   if (REPORT_EVENT) fprintf(stderr, "EnterNotify in win %u\n", 
01733                                             current->win.window);
01734 
01735                   /* XSetInputFocus(current->win.display, focus, 
01736                                     RevertToPointerRoot, CurrentTime); */
01737 
01738                   if (current->win.type == INPUT_WINDOW || 
01739                       current->win.type == BUTTON_WINDOW) 
01740                       lux_highlight(current->win.window);
01741 
01742                   break;
01743 
01744                 case LeaveNotify:               /* Unhighlight input or button
01745                                                    window on exit */
01746 
01747                   if (REPORT_EVENT) fprintf(stderr, "LeaveNotify in win %u\n", 
01748                                             current->win.window);
01749 
01750                   /* XSetInputFocus(current->win.display, PointerRoot, 
01751                                     RevertToPointerRoot, CurrentTime); */
01752 
01753                   if (current->win.type == INPUT_WINDOW || 
01754                       current->win.type == BUTTON_WINDOW) 
01755                       lux_unhighlight(current->win.window);
01756 
01757                   break;
01758 
01759                 case FocusIn:
01760 
01761                   if (REPORT_EVENT) fprintf(stderr, "FocusIn in win %u\n", 
01762                                             current->win.window);
01763 
01764                   /* XSetInputFocus(current->win.display, focus, 
01765                                     RevertToPointerRoot, CurrentTime); */
01766 
01767                   break;
01768 
01769                 case FocusOut:
01770 
01771                   if (REPORT_EVENT) fprintf(stderr, "FocusOut in win %u\n", 
01772                                             current->win.window);
01773 
01774                   break;
01775 
01776                 case DestroyNotify:       /* Window has been deleted via WM */
01777 
01778                   if (REPORT_EVENT) fprintf(stderr, "Destroy win %u\n", 
01779                                             current->win.window);
01780 
01781                   lux_freewin(current->win.window);
01782                   break;
01783 
01784                 case ClientMessage:
01785 
01786                   if (REPORT_EVENT) fprintf(stderr, 
01787                                             "Got a ClientMessage in win %u\n", 
01788                                       current->win.window);
01789 
01790                   if (current->win.type != GRAPH_WINDOW)
01791 
01792                       XBell(current->win.display, 100);
01793 
01794                   else {
01795 
01796                       lux_wins *tmp; tmp = current->next;
01797                       while(tmp->win.type != GRAPH_WINDOW) tmp = tmp->next;
01798 
01799                       if (tmp == current) {
01800 
01801                           XBell(current->win.display, 100);
01802                           fprintf(stderr, 
01803                                   "Ambiguous command! Type q to quit..\n");
01804 
01805                       } else if (report.xclient.message_type == 
01806                                  XInternAtom(display, "WM_PROTOCOLS", True)) {
01807 
01808 /*
01809                           XDestroyWindow(current->win.display, popup);
01810                           lux_create_popup();
01811                           XUnmapWindow(current->win.display, 
01812                                        current->win.window);
01813                           XDestroyWindow(current->win.display, 
01814                                          current->win.window);
01815                           XSync(current->win.display, False);
01816                           while(XCheckWindowEvent(current->win.display, 
01817                                                   current->win.window, 
01818                                                   0xFFFFFFFF, &report));
01819 */
01820                           lux_freewin(current->win.window);
01821                       }
01822                   }
01823                   break;
01824 
01825                 case MappingNotify:
01826 
01827                   if (REPORT_EVENT) fprintf(stderr, 
01828                                             "Got a MappingNotify in win %u\n", 
01829                                             current->win.window);
01830 
01831                   /* XRefreshKeyboardMapping(&report); */
01832                   break;
01833 
01834                 default:
01835                   break;
01836 
01837             }   /* switch (report.type) */
01838 
01839         }       /* else if (win...      */
01840 
01841     }           /* while(1)             */
01842 }
01843 
01844 int lux_getevent()
01845 {
01846     return win_getevent(0, 0, 0);
01847 }
01848 
01849 get_mouse_position(win, fx, fy)
01850 Window win;
01851 float *fx, *fy;
01852 {
01853   register lux_wins *current;
01854 
01855   current = get_currentwin(win);
01856   
01857   current->win.buttonflag = 1;
01858 
01859   lux_getevent();
01860 
01861   current->win.buttonflag = 0;
01862 
01863   *fx = current->win.xbutton;
01864   *fy = current->win.ybutton;
01865 
01866 }
01867 
01868 lux_set_window_name(win, name)
01869 Window win;
01870 char  *name;
01871 {
01872   register lux_wins *current;
01873 
01874   current = get_currentwin(win);
01875 
01876   XStoreName(current->win.display, current->win.window, name);
01877   XSetIconName(current->win.display, current->win.window, name);
01878 
01879 }
01880 
01881 
01882 lux_display(width, height)
01883 unsigned int *width, *height;
01884 {
01885     Display *display;
01886 
01887     if ( (display=XOpenDisplay(display_name)) == NULL ) {
01888         (void) fprintf( stderr, 
01889                        "Cannot connect to X server %s\n", 
01890                        XDisplayName(display_name));
01891         if (mcdrawflag) return 1;
01892         else exit( -1 );
01893     }
01894  
01895     screen = DefaultScreen(display);
01896     *width  = DisplayWidth(display, screen);
01897     *height = DisplayHeight(display, screen);
01898     XCloseDisplay(display);
01899     return 0;
01900 }
01901 
01902 
01903 lux_use_mcdraw()
01904 {
01905     mcdrawflag = 1;
01906 }
01907 
01908 lux_iconify_window(win)
01909 Window win;
01910 {
01911     register lux_wins *current;
01912 
01913     current = get_currentwin(win);
01914 
01915     XIconifyWindow(current->win.display, current->win.window, current->win.screen);
01916 }
01917 
01918 
01919 lux_uniconify_window(win)
01920 Window win;
01921 {
01922     register lux_wins *current;
01923 
01924     current = get_currentwin(win);
01925 
01926 /*    XUnmapWindow(current->win.display, current->win.window);*/
01927     XMapWindow(current->win.display, current->win.window);
01928 }
01929 
01930 lux_raise_window(win)
01931 Window win;
01932 {
01933     register lux_wins *current;
01934 
01935     current = get_currentwin(win);
01936 
01937     XRaiseWindow(current->win.display, current->win.window);
01938 }
01939 
01940 lux_clear_keyboard_buffer()
01941 {
01942     XEvent report;
01943     while(XCheckTypedEvent(display, KeyPress, &report));
01944 }

Generated at Sun Feb 24 09:57:20 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001