| 1 | greg | 1.1 | #ifndef lint | 
| 2 |  |  | static char SCCSid[] = "$SunId$ LBL"; | 
| 3 |  |  | #endif | 
| 4 |  |  |  | 
| 5 |  |  | /* Copyright (c) 1989 Regents of the University of California */ | 
| 6 |  |  |  | 
| 7 |  |  | /* | 
| 8 | greg | 1.4 | *  x11.c - driver for X-windows version 11.3 | 
| 9 | greg | 1.1 | * | 
| 10 | greg | 1.4 | *     Jan 1990 | 
| 11 | greg | 1.1 | */ | 
| 12 |  |  |  | 
| 13 |  |  | #include  <stdio.h> | 
| 14 |  |  |  | 
| 15 |  |  | #include  <sys/ioctl.h> | 
| 16 |  |  |  | 
| 17 |  |  | #include  <X11/Xlib.h> | 
| 18 | greg | 1.4 | #include  <X11/cursorfont.h> | 
| 19 |  |  | #include  <X11/Xutil.h> | 
| 20 | greg | 1.1 |  | 
| 21 |  |  | #include  "color.h" | 
| 22 |  |  | #include  "driver.h" | 
| 23 |  |  | #include  "x11twind.h" | 
| 24 |  |  |  | 
| 25 |  |  | #define GAMMA           2.2             /* exponent for color correction */ | 
| 26 |  |  |  | 
| 27 | greg | 1.6 | #define MINWIDTH        (32*COMCW)      /* minimum graphics window width */ | 
| 28 |  |  | #define MINHEIGHT       MINWIDTH        /* minimum graphics window height */ | 
| 29 | greg | 1.4 |  | 
| 30 | greg | 1.1 | #define BORWIDTH        5               /* border width */ | 
| 31 |  |  | #define COMHEIGHT       (COMLH*COMCH)   /* command line height (pixels) */ | 
| 32 |  |  |  | 
| 33 |  |  | #define COMFN           "8x13"          /* command line font name */ | 
| 34 |  |  | #define COMLH           3               /* number of command lines */ | 
| 35 |  |  | #define COMCW           8               /* approx. character width (pixels) */ | 
| 36 |  |  | #define COMCH           14              /* approx. character height (pixels) */ | 
| 37 |  |  |  | 
| 38 | greg | 1.4 | #define  ourscreen      DefaultScreen(ourdisplay) | 
| 39 |  |  | #define  ourroot        RootWindow(ourdisplay,ourscreen) | 
| 40 |  |  | #define  ourwhite       WhitePixel(ourdisplay,ourscreen) | 
| 41 |  |  | #define  ourblack       BlackPixel(ourdisplay,ourscreen) | 
| 42 |  |  |  | 
| 43 |  |  | #define  levptr(etype)  ((etype *)¤tevent) | 
| 44 | greg | 1.1 |  | 
| 45 | greg | 1.4 | static XEvent  currentevent;            /* current event */ | 
| 46 | greg | 1.1 |  | 
| 47 |  |  | static int  ncolors = 0;                /* color table size */ | 
| 48 |  |  | static int  *pixval = NULL;             /* allocated pixels */ | 
| 49 |  |  |  | 
| 50 |  |  | static Display  *ourdisplay = NULL;     /* our display */ | 
| 51 |  |  |  | 
| 52 | greg | 1.6 | static Visual  *ourvisual;              /* our visual structure */ | 
| 53 |  |  |  | 
| 54 | greg | 1.1 | static Window  gwind = 0;               /* our graphics window */ | 
| 55 |  |  |  | 
| 56 |  |  | static Cursor  pickcursor = 0;          /* cursor used for picking */ | 
| 57 |  |  |  | 
| 58 | greg | 1.4 | static int  gwidth, gheight;            /* graphics window size */ | 
| 59 | greg | 1.1 |  | 
| 60 |  |  | static TEXTWIND  *comline = NULL;       /* our command line */ | 
| 61 |  |  |  | 
| 62 |  |  | static char  c_queue[64];               /* input queue */ | 
| 63 |  |  | static int  c_first = 0;                /* first character in queue */ | 
| 64 |  |  | static int  c_last = 0;                 /* last character in queue */ | 
| 65 |  |  |  | 
| 66 |  |  | static GC  ourgc = 0;                   /* our graphics context for drawing */ | 
| 67 |  |  |  | 
| 68 | greg | 1.6 | static Colormap ourmap = 0;             /* our color map */ | 
| 69 | greg | 1.1 |  | 
| 70 |  |  | extern char  *malloc(); | 
| 71 |  |  |  | 
| 72 |  |  | int  x11_close(), x11_clear(), x11_paintr(), x11_errout(), | 
| 73 | greg | 1.5 | x11_getcur(), x11_comout(), x11_comin(), x11_flush(); | 
| 74 | greg | 1.1 |  | 
| 75 |  |  | static struct driver  x11_driver = { | 
| 76 |  |  | x11_close, x11_clear, x11_paintr, x11_getcur, | 
| 77 | greg | 1.5 | x11_comout, x11_comin, x11_flush, 1.0 | 
| 78 | greg | 1.1 | }; | 
| 79 |  |  |  | 
| 80 |  |  |  | 
| 81 |  |  | struct driver * | 
| 82 |  |  | x11_init(name, id)              /* initialize driver */ | 
| 83 |  |  | char  *name, *id; | 
| 84 |  |  | { | 
| 85 | greg | 1.6 | int  nplanes; | 
| 86 |  |  | XVisualInfo  ourvinfo; | 
| 87 | greg | 1.10 | XSetWindowAttributes    ourwinattr; | 
| 88 | greg | 1.4 | XWMHints  ourxwmhints; | 
| 89 | greg | 1.12 | XSizeHints      oursizhints; | 
| 90 | greg | 1.1 |  | 
| 91 |  |  | ourdisplay = XOpenDisplay(NULL); | 
| 92 |  |  | if (ourdisplay == NULL) { | 
| 93 |  |  | stderr_v("cannot open X-windows; DISPLAY variable set?\n"); | 
| 94 |  |  | return(NULL); | 
| 95 |  |  | } | 
| 96 | greg | 1.6 | nplanes = DisplayPlanes(ourdisplay, ourscreen); | 
| 97 |  |  | if (nplanes < 4) { | 
| 98 | greg | 1.1 | stderr_v("not enough colors\n"); | 
| 99 |  |  | return(NULL); | 
| 100 | greg | 1.6 | } else if (nplanes <= 12) { | 
| 101 |  |  | if (!XMatchVisualInfo(ourdisplay,ourscreen, | 
| 102 |  |  | nplanes,PseudoColor,&ourvinfo)) { | 
| 103 |  |  | stderr_v("PseudoColor not supported\n"); | 
| 104 |  |  | return(NULL); | 
| 105 |  |  | } | 
| 106 |  |  | } else if (!XMatchVisualInfo(ourdisplay,ourscreen, | 
| 107 |  |  | nplanes,TrueColor,&ourvinfo)) { | 
| 108 |  |  | stderr_v("TrueColor not supported\n"); | 
| 109 |  |  | return(NULL); | 
| 110 | greg | 1.1 | } | 
| 111 | greg | 1.6 | ourvisual = ourvinfo.visual; | 
| 112 |  |  | make_gmap(GAMMA); | 
| 113 | greg | 1.4 | /* open window */ | 
| 114 | greg | 1.12 | ourwinattr.background_pixel = ourblack; | 
| 115 | greg | 1.10 | ourwinattr.border_pixel = ourblack; | 
| 116 |  |  | gwind = XCreateWindow(ourdisplay, ourroot, 0, 0, | 
| 117 | greg | 1.4 | DisplayWidth(ourdisplay,ourscreen)-2*BORWIDTH, | 
| 118 |  |  | DisplayHeight(ourdisplay,ourscreen)-2*BORWIDTH, | 
| 119 | greg | 1.10 | BORWIDTH, nplanes, InputOutput, ourvisual, | 
| 120 |  |  | CWBackPixel|CWBorderPixel, &ourwinattr); | 
| 121 | greg | 1.4 | if (gwind == 0) { | 
| 122 |  |  | stderr_v("cannot create window\n"); | 
| 123 |  |  | return(NULL); | 
| 124 |  |  | } | 
| 125 |  |  | XStoreName(ourdisplay, gwind, id); | 
| 126 | greg | 1.10 | /* create a cursor */ | 
| 127 |  |  | pickcursor = XCreateFontCursor(ourdisplay, XC_diamond_cross); | 
| 128 | greg | 1.4 | ourgc = XCreateGC(ourdisplay, gwind, 0, NULL); | 
| 129 |  |  | ourxwmhints.flags = InputHint; | 
| 130 |  |  | ourxwmhints.input = True; | 
| 131 |  |  | XSetWMHints(ourdisplay, gwind, &ourxwmhints); | 
| 132 | greg | 1.12 | oursizhints.min_width = MINWIDTH; | 
| 133 |  |  | oursizhints.min_height = MINHEIGHT+COMHEIGHT; | 
| 134 |  |  | oursizhints.flags = PMinSize; | 
| 135 |  |  | XSetNormalHints(ourdisplay, gwind, &oursizhints); | 
| 136 | greg | 1.4 | XSelectInput(ourdisplay, gwind, ExposureMask); | 
| 137 |  |  | XMapWindow(ourdisplay, gwind); | 
| 138 |  |  | XWindowEvent(ourdisplay, gwind, ExposureMask, levptr(XExposeEvent)); | 
| 139 |  |  | gwidth = levptr(XExposeEvent)->width; | 
| 140 |  |  | gheight = levptr(XExposeEvent)->height - COMHEIGHT; | 
| 141 |  |  | x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth; | 
| 142 |  |  | x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight; | 
| 143 | greg | 1.1 | x11_driver.inpready = 0; | 
| 144 |  |  | cmdvec = x11_comout;                    /* set error vectors */ | 
| 145 |  |  | if (wrnvec != NULL) | 
| 146 |  |  | wrnvec = x11_errout; | 
| 147 |  |  | return(&x11_driver); | 
| 148 |  |  | } | 
| 149 |  |  |  | 
| 150 |  |  |  | 
| 151 |  |  | static | 
| 152 |  |  | x11_close()                     /* close our display */ | 
| 153 |  |  | { | 
| 154 |  |  | cmdvec = NULL;                          /* reset error vectors */ | 
| 155 |  |  | if (wrnvec != NULL) | 
| 156 |  |  | wrnvec = stderr_v; | 
| 157 |  |  | if (ourdisplay == NULL) | 
| 158 |  |  | return; | 
| 159 |  |  | if (comline != NULL) { | 
| 160 |  |  | xt_close(comline); | 
| 161 |  |  | comline = NULL; | 
| 162 |  |  | } | 
| 163 | greg | 1.8 | freepixels(); | 
| 164 |  |  | XFreeGC(ourdisplay, ourgc); | 
| 165 |  |  | XDestroyWindow(ourdisplay, gwind); | 
| 166 |  |  | gwind = 0; | 
| 167 |  |  | ourgc = 0; | 
| 168 | greg | 1.1 | XFreeCursor(ourdisplay, pickcursor); | 
| 169 |  |  | XCloseDisplay(ourdisplay); | 
| 170 |  |  | ourdisplay = NULL; | 
| 171 |  |  | } | 
| 172 |  |  |  | 
| 173 |  |  |  | 
| 174 |  |  | static | 
| 175 |  |  | x11_clear(xres, yres)                   /* clear our display */ | 
| 176 |  |  | int  xres, yres; | 
| 177 |  |  | { | 
| 178 | greg | 1.12 | /* check limits */ | 
| 179 |  |  | if (xres < MINWIDTH) | 
| 180 |  |  | xres = MINWIDTH; | 
| 181 |  |  | if (yres < MINHEIGHT) | 
| 182 |  |  | yres = MINHEIGHT; | 
| 183 |  |  | /* resize window */ | 
| 184 |  |  | if (xres != gwidth || yres != gheight) { | 
| 185 | greg | 1.4 | XSelectInput(ourdisplay, gwind, 0); | 
| 186 |  |  | XResizeWindow(ourdisplay, gwind, xres, yres+COMHEIGHT); | 
| 187 | greg | 1.1 | gwidth = xres; | 
| 188 |  |  | gheight = yres; | 
| 189 | greg | 1.8 | XFlush(ourdisplay); | 
| 190 |  |  | sleep(2);                       /* wait for window manager */ | 
| 191 | greg | 1.4 | XSync(ourdisplay, 1);           /* discard input */ | 
| 192 |  |  | } | 
| 193 | greg | 1.13 | XClearWindow(ourdisplay, gwind); | 
| 194 |  |  | /* reinitialize color table */ | 
| 195 |  |  | if (ourvisual->class == PseudoColor) | 
| 196 |  |  | if (getpixels() == 0) | 
| 197 |  |  | stderr_v("cannot allocate colors\n"); | 
| 198 |  |  | else | 
| 199 |  |  | new_ctab(ncolors); | 
| 200 | greg | 1.12 | /* get new command line */ | 
| 201 | greg | 1.13 | if (comline != NULL) | 
| 202 |  |  | xt_close(comline); | 
| 203 | greg | 1.12 | comline = xt_open(ourdisplay, | 
| 204 |  |  | DefaultGC(ourdisplay,ourscreen), | 
| 205 |  |  | gwind, 0, gheight, gwidth, COMHEIGHT, 0, COMFN); | 
| 206 |  |  | if (comline == NULL) { | 
| 207 |  |  | stderr_v("Cannot open command line window\n"); | 
| 208 |  |  | quit(1); | 
| 209 |  |  | } | 
| 210 |  |  | XSelectInput(ourdisplay, comline->w, ExposureMask); | 
| 211 |  |  | /* remove earmuffs */ | 
| 212 | greg | 1.4 | XSelectInput(ourdisplay, gwind, | 
| 213 |  |  | StructureNotifyMask|ExposureMask|KeyPressMask|ButtonPressMask); | 
| 214 | greg | 1.1 | } | 
| 215 |  |  |  | 
| 216 |  |  |  | 
| 217 |  |  | static | 
| 218 |  |  | x11_paintr(col, xmin, ymin, xmax, ymax)         /* fill a rectangle */ | 
| 219 |  |  | COLOR  col; | 
| 220 |  |  | int  xmin, ymin, xmax, ymax; | 
| 221 |  |  | { | 
| 222 |  |  | extern int  xnewcolr();         /* pixel assignment routine */ | 
| 223 | greg | 1.6 | extern unsigned long  true_pixel(); | 
| 224 |  |  | unsigned long  pixel; | 
| 225 | greg | 1.1 |  | 
| 226 | greg | 1.6 | if (ncolors > 0) | 
| 227 |  |  | pixel = pixval[get_pixel(col, xnewcolr)]; | 
| 228 |  |  | else if (ourvisual->class == TrueColor) | 
| 229 |  |  | pixel = true_pixel(col); | 
| 230 |  |  | else | 
| 231 |  |  | return; | 
| 232 |  |  | XSetForeground(ourdisplay, ourgc, pixel); | 
| 233 |  |  | XFillRectangle(ourdisplay, gwind, | 
| 234 |  |  | ourgc, xmin, gheight-ymax, xmax-xmin, ymax-ymin); | 
| 235 | greg | 1.5 | } | 
| 236 |  |  |  | 
| 237 |  |  |  | 
| 238 |  |  | static | 
| 239 |  |  | x11_flush()                     /* flush output */ | 
| 240 |  |  | { | 
| 241 | greg | 1.10 | XNoOp(ourdisplay); | 
| 242 | greg | 1.5 | while (XPending(ourdisplay) > 0) | 
| 243 |  |  | getevent(); | 
| 244 | greg | 1.1 | } | 
| 245 |  |  |  | 
| 246 |  |  |  | 
| 247 |  |  | static | 
| 248 | greg | 1.3 | x11_comin(inp, prompt)          /* read in a command line */ | 
| 249 |  |  | char  *inp, *prompt; | 
| 250 | greg | 1.1 | { | 
| 251 |  |  | int  x11_getc(), x11_comout(); | 
| 252 |  |  |  | 
| 253 | greg | 1.3 | if (prompt != NULL) | 
| 254 | greg | 1.4 | if (fromcombuf(inp, &x11_driver)) | 
| 255 |  |  | return; | 
| 256 |  |  | else | 
| 257 |  |  | xt_puts(prompt, comline); | 
| 258 | greg | 1.1 | xt_cursor(comline, TBLKCURS); | 
| 259 |  |  | editline(inp, x11_getc, x11_comout); | 
| 260 |  |  | xt_cursor(comline, TNOCURS); | 
| 261 |  |  | } | 
| 262 |  |  |  | 
| 263 |  |  |  | 
| 264 |  |  | static | 
| 265 |  |  | x11_comout(out)                 /* output a string to command line */ | 
| 266 |  |  | char  *out; | 
| 267 |  |  | { | 
| 268 | greg | 1.11 | if (comline == NULL) | 
| 269 |  |  | return; | 
| 270 |  |  | xt_puts(out, comline); | 
| 271 |  |  | if (out[strlen(out)-1] == '\n') | 
| 272 |  |  | XFlush(ourdisplay); | 
| 273 | greg | 1.1 | } | 
| 274 |  |  |  | 
| 275 |  |  |  | 
| 276 |  |  | static | 
| 277 |  |  | x11_errout(msg)                 /* output an error message */ | 
| 278 |  |  | char  *msg; | 
| 279 |  |  | { | 
| 280 | greg | 1.9 | stderr_v(msg);          /* send to stderr also! */ | 
| 281 | greg | 1.1 | x11_comout(msg); | 
| 282 |  |  | } | 
| 283 |  |  |  | 
| 284 |  |  |  | 
| 285 |  |  | static int | 
| 286 |  |  | x11_getcur(xp, yp)              /* get cursor position */ | 
| 287 |  |  | int  *xp, *yp; | 
| 288 |  |  | { | 
| 289 |  |  | while (XGrabPointer(ourdisplay, gwind, True, ButtonPressMask, | 
| 290 |  |  | GrabModeAsync, GrabModeAsync, None, pickcursor, | 
| 291 |  |  | CurrentTime) != GrabSuccess) | 
| 292 |  |  | sleep(2); | 
| 293 |  |  |  | 
| 294 |  |  | do | 
| 295 |  |  | getevent(); | 
| 296 |  |  | while (c_last <= c_first && levptr(XEvent)->type != ButtonPress); | 
| 297 |  |  | *xp = levptr(XButtonPressedEvent)->x; | 
| 298 |  |  | *yp = gheight-1 - levptr(XButtonPressedEvent)->y; | 
| 299 |  |  | XUngrabPointer(ourdisplay, CurrentTime); | 
| 300 |  |  | XFlush(ourdisplay);                             /* insure release */ | 
| 301 |  |  | if (c_last > c_first)                   /* key pressed */ | 
| 302 |  |  | return(x11_getc()); | 
| 303 |  |  | /* button pressed */ | 
| 304 |  |  | if (levptr(XButtonPressedEvent)->button & Button1) | 
| 305 |  |  | return(MB1); | 
| 306 |  |  | if (levptr(XButtonPressedEvent)->button & Button2) | 
| 307 |  |  | return(MB2); | 
| 308 |  |  | if (levptr(XButtonPressedEvent)->button & Button3) | 
| 309 |  |  | return(MB3); | 
| 310 |  |  | if (levptr(XButtonPressedEvent)->button & (Button4|Button5)) | 
| 311 |  |  | return(MB1); | 
| 312 |  |  | return(ABORT); | 
| 313 |  |  | } | 
| 314 |  |  |  | 
| 315 |  |  |  | 
| 316 |  |  | static | 
| 317 |  |  | xnewcolr(ndx, r, g, b)          /* enter a color into hardware table */ | 
| 318 |  |  | int  ndx; | 
| 319 |  |  | int  r, g, b; | 
| 320 |  |  | { | 
| 321 |  |  | XColor  xcolor; | 
| 322 |  |  |  | 
| 323 |  |  | xcolor.pixel = pixval[ndx]; | 
| 324 |  |  | xcolor.red = r << 8; | 
| 325 |  |  | xcolor.green = g << 8; | 
| 326 |  |  | xcolor.blue = b << 8; | 
| 327 |  |  | xcolor.flags = DoRed|DoGreen|DoBlue; | 
| 328 |  |  |  | 
| 329 |  |  | XStoreColor(ourdisplay, ourmap, &xcolor); | 
| 330 |  |  | } | 
| 331 |  |  |  | 
| 332 |  |  |  | 
| 333 |  |  | static int | 
| 334 |  |  | getpixels()                             /* get the color map */ | 
| 335 |  |  | { | 
| 336 | greg | 1.4 | if (ncolors > 0) | 
| 337 |  |  | return(ncolors); | 
| 338 | greg | 1.6 | if (ourvisual == DefaultVisual(ourdisplay,ourscreen)) { | 
| 339 |  |  | ourmap = DefaultColormap(ourdisplay,ourscreen); | 
| 340 |  |  | goto loop; | 
| 341 |  |  | } | 
| 342 |  |  | newmap: | 
| 343 |  |  | ourmap = XCreateColormap(ourdisplay,gwind,ourvisual,AllocNone); | 
| 344 |  |  | loop: | 
| 345 |  |  | for (ncolors = ourvisual->map_entries; | 
| 346 |  |  | ncolors > ourvisual->map_entries/3; | 
| 347 |  |  | ncolors = ncolors*.937) { | 
| 348 | greg | 1.1 | pixval = (int *)malloc(ncolors*sizeof(int)); | 
| 349 |  |  | if (pixval == NULL) | 
| 350 | greg | 1.6 | return(ncolors = 0); | 
| 351 | greg | 1.1 | if (XAllocColorCells(ourdisplay,ourmap,0,NULL,0, | 
| 352 |  |  | pixval,ncolors) != 0) | 
| 353 | greg | 1.6 | break; | 
| 354 | greg | 1.1 | free((char *)pixval); | 
| 355 | greg | 1.6 | pixval = NULL; | 
| 356 | greg | 1.1 | } | 
| 357 | greg | 1.6 | if (pixval == NULL) { | 
| 358 |  |  | if (ourmap == DefaultColormap(ourdisplay,ourscreen)) | 
| 359 |  |  | goto newmap;            /* try it with our map */ | 
| 360 |  |  | else | 
| 361 |  |  | return(ncolors = 0);    /* failed */ | 
| 362 |  |  | } | 
| 363 |  |  | if (ourmap != DefaultColormap(ourdisplay,ourscreen)) { | 
| 364 |  |  | XColor  thiscolor; | 
| 365 |  |  | register int  i, j; | 
| 366 |  |  | /* reset black and white */ | 
| 367 |  |  | for (i = 0; i < ncolors; i++) { | 
| 368 |  |  | if (pixval[i] != ourblack && pixval[i] != ourwhite) | 
| 369 |  |  | continue; | 
| 370 |  |  | thiscolor.pixel = pixval[i]; | 
| 371 |  |  | thiscolor.flags = DoRed|DoGreen|DoBlue; | 
| 372 |  |  | XQueryColor(ourdisplay, | 
| 373 |  |  | DefaultColormap(ourdisplay,ourscreen), | 
| 374 |  |  | &thiscolor); | 
| 375 |  |  | XStoreColor(ourdisplay, ourmap, &thiscolor); | 
| 376 |  |  | for (j = i; j+1 < ncolors; j++) | 
| 377 |  |  | pixval[j] = pixval[j+1]; | 
| 378 |  |  | ncolors--; | 
| 379 |  |  | i--; | 
| 380 |  |  | } | 
| 381 |  |  | } | 
| 382 |  |  | XSetWindowColormap(ourdisplay, gwind, ourmap); | 
| 383 |  |  | return(ncolors); | 
| 384 | greg | 1.1 | } | 
| 385 |  |  |  | 
| 386 |  |  |  | 
| 387 |  |  | static | 
| 388 |  |  | freepixels()                            /* free our pixels */ | 
| 389 |  |  | { | 
| 390 |  |  | if (ncolors == 0) | 
| 391 |  |  | return; | 
| 392 |  |  | XFreeColors(ourdisplay,ourmap,pixval,ncolors,0L); | 
| 393 |  |  | ncolors = 0; | 
| 394 | greg | 1.8 | if (ourmap != DefaultColormap(ourdisplay,ourscreen)) | 
| 395 | greg | 1.6 | XFreeColormap(ourdisplay, ourmap); | 
| 396 |  |  | ourmap = 0; | 
| 397 | greg | 1.1 | } | 
| 398 |  |  |  | 
| 399 |  |  |  | 
| 400 | greg | 1.6 | static unsigned long | 
| 401 |  |  | true_pixel(col)                 /* return true pixel value for color */ | 
| 402 |  |  | COLOR  col; | 
| 403 |  |  | { | 
| 404 |  |  | unsigned long  rval; | 
| 405 |  |  | BYTE  rgb[3]; | 
| 406 |  |  |  | 
| 407 |  |  | map_color(rgb, col); | 
| 408 |  |  | rval = ourvisual->red_mask*rgb[RED]/255 & ourvisual->red_mask; | 
| 409 |  |  | rval |= ourvisual->green_mask*rgb[GRN]/255 & ourvisual->green_mask; | 
| 410 |  |  | rval |= ourvisual->blue_mask*rgb[BLU]/255 & ourvisual->blue_mask; | 
| 411 |  |  | return(rval); | 
| 412 |  |  | } | 
| 413 |  |  |  | 
| 414 |  |  |  | 
| 415 | greg | 1.1 | static int | 
| 416 |  |  | x11_getc()                      /* get a command character */ | 
| 417 |  |  | { | 
| 418 |  |  | while (c_last <= c_first) { | 
| 419 |  |  | c_first = c_last = 0;           /* reset */ | 
| 420 |  |  | getevent();                     /* wait for key */ | 
| 421 |  |  | } | 
| 422 |  |  | x11_driver.inpready--; | 
| 423 |  |  | return(c_queue[c_first++]); | 
| 424 |  |  | } | 
| 425 |  |  |  | 
| 426 |  |  |  | 
| 427 |  |  | static | 
| 428 |  |  | getevent()                      /* get next event */ | 
| 429 |  |  | { | 
| 430 |  |  | XNextEvent(ourdisplay, levptr(XEvent)); | 
| 431 |  |  | switch (levptr(XEvent)->type) { | 
| 432 | greg | 1.4 | case ConfigureNotify: | 
| 433 |  |  | resizewindow(levptr(XConfigureEvent)); | 
| 434 |  |  | break; | 
| 435 |  |  | case UnmapNotify: | 
| 436 |  |  | freepixels(); | 
| 437 |  |  | break; | 
| 438 |  |  | case MapNotify: | 
| 439 | greg | 1.6 | if (ourvisual->class == PseudoColor) | 
| 440 |  |  | if (getpixels() == 0) | 
| 441 |  |  | stderr_v("Cannot allocate colors\n"); | 
| 442 |  |  | else | 
| 443 |  |  | new_ctab(ncolors); | 
| 444 | greg | 1.4 | break; | 
| 445 |  |  | case Expose: | 
| 446 |  |  | fixwindow(levptr(XExposeEvent)); | 
| 447 |  |  | break; | 
| 448 | greg | 1.1 | case KeyPress: | 
| 449 |  |  | getkey(levptr(XKeyPressedEvent)); | 
| 450 |  |  | break; | 
| 451 |  |  | case ButtonPress: | 
| 452 |  |  | break; | 
| 453 |  |  | } | 
| 454 |  |  | } | 
| 455 |  |  |  | 
| 456 |  |  |  | 
| 457 |  |  | static | 
| 458 |  |  | getkey(ekey)                            /* get input key */ | 
| 459 |  |  | register XKeyPressedEvent  *ekey; | 
| 460 |  |  | { | 
| 461 | greg | 1.8 | register int  n; | 
| 462 | greg | 1.7 |  | 
| 463 |  |  | n = XLookupString(ekey, c_queue+c_last, sizeof(c_queue)-c_last, | 
| 464 | greg | 1.1 | NULL, NULL); | 
| 465 | greg | 1.7 | c_last += n; | 
| 466 |  |  | x11_driver.inpready += n; | 
| 467 | greg | 1.1 | } | 
| 468 |  |  |  | 
| 469 |  |  |  | 
| 470 |  |  | static | 
| 471 |  |  | fixwindow(eexp)                         /* repair damage to window */ | 
| 472 |  |  | register XExposeEvent  *eexp; | 
| 473 |  |  | { | 
| 474 | greg | 1.4 | if (eexp->window == gwind) { | 
| 475 |  |  | sprintf(getcombuf(&x11_driver), "repaint %d %d %d %d\n", | 
| 476 |  |  | eexp->x, gheight - eexp->y - eexp->height, | 
| 477 | greg | 1.1 | eexp->x + eexp->width, gheight - eexp->y); | 
| 478 | greg | 1.4 | } else if (eexp->window == comline->w) { | 
| 479 |  |  | if (eexp->count == 0) | 
| 480 |  |  | xt_redraw(comline); | 
| 481 |  |  | } | 
| 482 | greg | 1.1 | } | 
| 483 | greg | 1.4 |  | 
| 484 |  |  |  | 
| 485 |  |  | static | 
| 486 |  |  | resizewindow(ersz)                      /* resize window */ | 
| 487 |  |  | register XConfigureEvent  *ersz; | 
| 488 |  |  | { | 
| 489 |  |  | if (ersz->width == gwidth && ersz->height-COMHEIGHT == gheight) | 
| 490 |  |  | return; | 
| 491 |  |  |  | 
| 492 |  |  | gwidth = ersz->width; | 
| 493 |  |  | gheight = ersz->height-COMHEIGHT; | 
| 494 |  |  | x11_driver.xsiz = gwidth < MINWIDTH ? MINWIDTH : gwidth; | 
| 495 |  |  | x11_driver.ysiz = gheight < MINHEIGHT ? MINHEIGHT : gheight; | 
| 496 |  |  |  | 
| 497 |  |  | strcpy(getcombuf(&x11_driver), "new\n"); | 
| 498 |  |  | } |