|
|
1.1 ! root 1: /* $Header: dsimple.c,v 1.1 87/09/11 08:23:17 toddb Exp $ */ ! 2: #include <X11/Xlib.h> ! 3: #include <X11/Xutil.h> ! 4: #include <X11/cursorfont.h> ! 5: #include <stdio.h> ! 6: /* ! 7: * Other_stuff.h: Definitions of routines in other_stuff. ! 8: * ! 9: * Written by Mark Lillibridge. Last updated 7/1/87 ! 10: * ! 11: * Send bugs, etc. to [email protected]. ! 12: */ ! 13: ! 14: unsigned long Resolve_Color(); ! 15: Pixmap Bitmap_To_Pixmap(); ! 16: Window Select_Window(); ! 17: void out(); ! 18: void blip(); ! 19: Window Window_With_Name(); ! 20: /* ! 21: * Just_display: A group of routines designed to make the writting of simple ! 22: * X11 applications which open a display but do not open ! 23: * any windows much faster and easier. Unless a routine says ! 24: * otherwise, it may be assumed to require program_name, dpy, ! 25: * and screen already defined on entry. ! 26: * ! 27: * Written by Mark Lillibridge. Last updated 7/1/87 ! 28: * ! 29: * Send bugs, etc. to [email protected]. ! 30: */ ! 31: ! 32: #include <strings.h> ! 33: ! 34: #define NULL 0 ! 35: ! 36: /* This stuff is defined in the calling program by just_display.h */ ! 37: extern char *program_name; ! 38: extern Display *dpy; ! 39: extern int screen; ! 40: ! 41: ! 42: /* ! 43: * Standard fatal error routine - call like printf but maximum of 7 arguments. ! 44: * Does not require dpy or screen defined. ! 45: */ ! 46: void Fatal_Error(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6) ! 47: char *msg; ! 48: char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; ! 49: { ! 50: fflush(stdout); ! 51: fflush(stderr); ! 52: fprintf(stderr, "%s: error: ", program_name); ! 53: fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6); ! 54: fprintf(stderr, "\n"); ! 55: exit(1); ! 56: } ! 57: ! 58: ! 59: /* ! 60: * Malloc: like malloc but handles out of memory using Fatal_Error. ! 61: */ ! 62: char *Malloc(size) ! 63: unsigned size; ! 64: { ! 65: char *data, *malloc(); ! 66: ! 67: if (!(data = malloc(size))) ! 68: Fatal_Error("Out of memory!"); ! 69: ! 70: return(data); ! 71: } ! 72: ! 73: ! 74: /* ! 75: * Realloc: like Malloc except for realloc, handles NULL using Malloc. ! 76: */ ! 77: char *Realloc(ptr, size) ! 78: char *ptr; ! 79: int size; ! 80: { ! 81: char *new_ptr, *realloc(); ! 82: ! 83: if (!ptr) ! 84: return(Malloc(size)); ! 85: ! 86: if (!(new_ptr = realloc(ptr, size))) ! 87: Fatal_Error("Out of memory!"); ! 88: ! 89: return(new_ptr); ! 90: } ! 91: ! 92: ! 93: /* ! 94: * Get_Display_Name: Routine which returns the name of the display we ! 95: * are supposed to use. This is either the display name ! 96: * given in the list of command arguments or if no name ! 97: * is given, the value of the DISPLAY environmental ! 98: * variable. If DISPLAY is unset, NULL is returned. ! 99: * The main program should pass its command arguments ! 100: * to this routine. The display argument if any is found ! 101: * will be removed from the list of command arguments. ! 102: * Any command argument containing a ':' which occurs ! 103: * before a '-' is considered to be a display. If ! 104: * two or more of these occur, only the first will be used. ! 105: * Does not require dpy or screen defined on entry. ! 106: */ ! 107: char *Get_Display_Name(argc, argv) ! 108: int *argc; /* MODIFIED */ ! 109: char **argv; /* MODIFIED */ ! 110: { ! 111: char *display; ! 112: char *getenv(); ! 113: int nargc=1; ! 114: int count; ! 115: char **nargv; ! 116: ! 117: /* Get default display name from environmental variable DISPLAY */ ! 118: display = getenv("DISPLAY"); ! 119: ! 120: /* ! 121: * Search for a user supplied overide command argument of the ! 122: * form host:display and remove it from command arguments if found. ! 123: */ ! 124: count = *argc; ! 125: nargv = argv + 1; ! 126: for (count--, argv++; count>0; count--, argv++) { ! 127: if (!strcmp("-", *argv)) { /* Don't search past a "-" */ ! 128: break; ! 129: } ! 130: if (index(*argv, ':')) { ! 131: display = *(argv++); ! 132: count--; ! 133: break; /* Only use first display name */ ! 134: } ! 135: *(nargv++) = *argv; ! 136: nargc++; ! 137: } ! 138: while (count>0) { ! 139: *(nargv++) = *(argv++); ! 140: nargc++; count--; ! 141: } ! 142: *argc = nargc; ! 143: ! 144: return(display); ! 145: } ! 146: ! 147: ! 148: /* ! 149: * Open_Display: Routine to open a display with correct error handling. ! 150: * Does not require dpy or screen defined on entry. ! 151: */ ! 152: Display *Open_Display(display_name) ! 153: char *display_name; ! 154: { ! 155: Display *d; ! 156: ! 157: d = XOpenDisplay(display_name); ! 158: if (d == NULL) { ! 159: if (display_name == NULL) ! 160: Fatal_Error("Could not open default display!"); ! 161: else ! 162: Fatal_Error("Could not open display %s!", display_name); ! 163: } ! 164: ! 165: return(d); ! 166: } ! 167: ! 168: ! 169: /* ! 170: * Setup_Display_And_Screen: This routine opens up the correct display (i.e., ! 171: * it calls Get_Display_Name) and then stores a ! 172: * pointer to it in dpy. The default screen ! 173: * for this display is then stored in screen. ! 174: * Does not require dpy or screen defined. ! 175: */ ! 176: void Setup_Display_And_Screen(argc, argv) ! 177: int *argc; /* MODIFIED */ ! 178: char **argv; /* MODIFIED */ ! 179: { ! 180: dpy = Open_Display(Get_Display_Name(argc, argv)); ! 181: screen = DefaultScreen(dpy); ! 182: } ! 183: ! 184: ! 185: /* ! 186: * Open_Font: This routine opens a font with error handling. ! 187: */ ! 188: XFontStruct *Open_Font(name) ! 189: char *name; ! 190: { ! 191: XFontStruct *font; ! 192: ! 193: if (!(font=XLoadQueryFont(dpy, name))) ! 194: Fatal_Error("Unable to open font %s!", name); ! 195: ! 196: return(font); ! 197: } ! 198: ! 199: ! 200: /* ! 201: * Beep: Routine to beep the display. ! 202: */ ! 203: void Beep() ! 204: { ! 205: XBell(dpy, 50); ! 206: } ! 207: ! 208: ! 209: /* ! 210: * ReadBitmapFile: same as XReadBitmapFile except it returns the bitmap ! 211: * directly and handles errors using Fatal_Error. ! 212: */ ! 213: static void _bitmap_error(status, filename) ! 214: int status; ! 215: char *filename; ! 216: { ! 217: if (status == BitmapOpenFailed) ! 218: Fatal_Error("Can't open file %s!", filename); ! 219: else if (status == BitmapFileInvalid) ! 220: Fatal_Error("file %s: Bad bitmap format.", filename); ! 221: else ! 222: Fatal_Error("Out of memory!"); ! 223: } ! 224: ! 225: Pixmap ReadBitmapFile(d, filename, width, height, x_hot, y_hot) ! 226: Drawable d; ! 227: char *filename; ! 228: int *width, *height, *x_hot, *y_hot; ! 229: { ! 230: Pixmap bitmap; ! 231: int status; ! 232: ! 233: status = XReadBitmapFile(dpy, RootWindow(dpy, screen), filename, width, ! 234: height, &bitmap, x_hot, y_hot); ! 235: if (status != BitmapSuccess) ! 236: _bitmap_error(status, filename); ! 237: ! 238: return(bitmap); ! 239: } ! 240: ! 241: ! 242: /* ! 243: * WriteBitmapFile: same as XWriteBitmapFile except it handles errors ! 244: * using Fatal_Error. ! 245: */ ! 246: void WriteBitmapFile(filename, bitmap, width, height, x_hot, y_hot) ! 247: char *filename; ! 248: Pixmap bitmap; ! 249: int width, height, x_hot, y_hot; ! 250: { ! 251: int status; ! 252: ! 253: status= XWriteBitmapFile(dpy, filename, bitmap, width, height, x_hot, ! 254: y_hot); ! 255: if (status != BitmapSuccess) ! 256: _bitmap_error(status, filename); ! 257: } ! 258: ! 259: ! 260: /* ! 261: * Select_Window_Args: a rountine to provide a common interface for ! 262: * applications that need to allow the user to select one ! 263: * window on the screen for special consideration. ! 264: * This routine implements the following command line ! 265: * arguments: ! 266: * ! 267: * -root Selects the root window. ! 268: * -id <id> Selects window with id <id>. <id> may ! 269: * be either in decimal or hex. ! 270: * -name <name> Selects the window with name <name>. ! 271: * ! 272: * Call as Select_Window_Args(&argc, argv) in main before ! 273: * parsing any of your program's command line arguments. ! 274: * Select_Window_Args will remove its arguments so that ! 275: * your program does not have to worry about them. ! 276: * The window returned is the window selected or 0 if ! 277: * none of the above arguments was present. If 0 is ! 278: * returned, Select_Window should probably be called after ! 279: * all command line arguments, and other setup is done. ! 280: * For examples of usage, see xwininfo, xwd, or xprop. ! 281: */ ! 282: Window Select_Window_Args(rargc, argv) ! 283: int *rargc; ! 284: char **argv; ! 285: #define ARGC (*rargc) ! 286: { ! 287: int nargc=1; ! 288: int argc; ! 289: char **nargv; ! 290: Window w=0; ! 291: ! 292: nargv = argv+1; argc = ARGC; ! 293: #define OPTION argv[0] ! 294: #define NXTOPTP ++argv, --argc>0 ! 295: #define NXTOPT if (++argv, --argc==0) usage() ! 296: #define COPYOPT nargv++[0]=OPTION; nargc++ ! 297: ! 298: while (NXTOPTP) { ! 299: if (!strcmp(OPTION, "-")) { ! 300: COPYOPT; ! 301: while (NXTOPTP) ! 302: COPYOPT; ! 303: break; ! 304: } ! 305: if (!strcmp(OPTION, "-root")) { ! 306: w=RootWindow(dpy, screen); ! 307: continue; ! 308: } ! 309: if (!strcmp(OPTION, "-name")) { ! 310: NXTOPT; ! 311: w = Window_With_Name(dpy, RootWindow(dpy, screen), ! 312: OPTION); ! 313: if (!w) ! 314: Fatal_Error("No window with name %s exists!",OPTION); ! 315: continue; ! 316: } ! 317: if (!strcmp(OPTION, "-id")) { ! 318: NXTOPT; ! 319: w=0; ! 320: sscanf(OPTION, "0x%lx", &w); ! 321: if (!w) ! 322: sscanf(OPTION, "%ld", &w); ! 323: if (!w) ! 324: Fatal_Error("Invalid window id format: %s.", OPTION); ! 325: continue; ! 326: } ! 327: COPYOPT; ! 328: } ! 329: ARGC = nargc; ! 330: ! 331: return(w); ! 332: } ! 333: ! 334: /* ! 335: * Other_stuff: A group of routines which do common X11 tasks. ! 336: * ! 337: * Written by Mark Lillibridge. Last updated 7/1/87 ! 338: * ! 339: * Send bugs, etc. to [email protected]. ! 340: */ ! 341: ! 342: ! 343: #define NULL 0 ! 344: ! 345: extern Display *dpy; ! 346: extern int screen; ! 347: ! 348: /* ! 349: * Resolve_Color: This routine takes a color name and returns the pixel # ! 350: * that when used in the window w will be of color name. ! 351: * (WARNING: The colormap of w MAY be modified! ) ! 352: * If colors are run out of, only the first n colors will be ! 353: * as correct as the hardware can make them where n depends ! 354: * on the display. This routine does not require wind to ! 355: * be defined. ! 356: */ ! 357: unsigned long Resolve_Color(w, name) ! 358: Window w; ! 359: char *name; ! 360: { ! 361: XColor c; ! 362: Colormap colormap; ! 363: XWindowAttributes wind_info; ! 364: ! 365: /* ! 366: * The following is a hack to insure machines without a rgb table ! 367: * handle at least white & black right. ! 368: */ ! 369: if (!strcmp(name, "white")) ! 370: name="#ffffffffffff"; ! 371: if (!strcmp(name, "black")) ! 372: name="#000000000000"; ! 373: ! 374: XGetWindowAttributes(dpy, w, &wind_info); ! 375: colormap = wind_info.colormap; ! 376: ! 377: if (!XParseColor(dpy, colormap, name, &c)) ! 378: Fatal_Error("Bad color format '%s'.", name); ! 379: ! 380: if (!XAllocColor(dpy, colormap, &c)) ! 381: Fatal_Error("XAllocColor failed!"); ! 382: ! 383: return(c.pixel); ! 384: } ! 385: ! 386: ! 387: /* ! 388: * Bitmap_To_Pixmap: Convert a bitmap to a 2 colored pixmap. The colors come ! 389: * from the foreground and background colors of the gc. ! 390: * Width and height are required solely for efficiency. ! 391: * If needed, they can be obtained via. XGetGeometry. ! 392: */ ! 393: Pixmap Bitmap_To_Pixmap(dpy, d, gc, bitmap, width, height) ! 394: Display *dpy; ! 395: Drawable d; ! 396: GC gc; ! 397: Pixmap bitmap; ! 398: int width, height; ! 399: { ! 400: Pixmap pix; ! 401: int x, depth; ! 402: Drawable root; ! 403: ! 404: if (!XGetGeometry(dpy, d, &root, &x, &x, &x, &x, &x, &depth)) ! 405: return(0); ! 406: ! 407: pix = XCreatePixmap(dpy, d, width, height, depth); ! 408: ! 409: XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, 1); ! 410: ! 411: return(pix); ! 412: } ! 413: ! 414: ! 415: /* ! 416: * outl: a debugging routine. Flushes stdout then prints a message on stderr ! 417: * and flushes stderr. Used to print messages when past certain points ! 418: * in code so we can tell where we are. Outl may be invoked like ! 419: * printf with up to 7 arguments. ! 420: */ ! 421: outl(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6) ! 422: char *msg; ! 423: char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6; ! 424: { ! 425: fflush(stdout); ! 426: fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6); ! 427: fprintf(stderr, "\n"); ! 428: fflush(stderr); ! 429: } ! 430: ! 431: ! 432: /* ! 433: * blip: a debugging routine. Prints Blip! on stderr with flushing. ! 434: */ ! 435: void blip() ! 436: { ! 437: outl("blip!"); ! 438: } ! 439: ! 440: ! 441: /* ! 442: * Routine to let user select a window using the mouse ! 443: */ ! 444: ! 445: Window Select_Window(dpy) ! 446: Display *dpy; ! 447: { ! 448: int status; ! 449: Cursor cursor; ! 450: XEvent event; ! 451: Window target_win; ! 452: ! 453: /* Make the target cursor */ ! 454: cursor = XCreateFontCursor(dpy, XC_crosshair); ! 455: ! 456: /* Grab the pointer using target cursor, letting it room all over */ ! 457: status = XGrabPointer(dpy, RootWindow(dpy, screen), True, ! 458: ButtonPressMask, GrabModeAsync, ! 459: GrabModeAsync, None, cursor, CurrentTime); ! 460: if (status != GrabSuccess) Fatal_Error("Can't grab the mouse."); ! 461: ! 462: /* Let the user select a window... */ ! 463: XNextEvent(dpy, &event); ! 464: target_win = event.xbutton.subwindow; /* Get which window selected */ ! 465: ! 466: XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ ! 467: ! 468: /* 0 for subwindow means root window */ ! 469: if (target_win == 0) ! 470: target_win = RootWindow(dpy, screen); ! 471: ! 472: return(target_win); ! 473: } ! 474: ! 475: ! 476: /* ! 477: * Window_With_Name: routine to locate a window with a given name on a display. ! 478: * If no window with the given name is found, 0 is returned. ! 479: * If more than one window has the given name, the first ! 480: * one found will be returned. Only top and its subwindows ! 481: * are looked at. Normally, top should be the RootWindow. ! 482: */ ! 483: Window Window_With_Name(dpy, top, name) ! 484: Display *dpy; ! 485: Window top; ! 486: char *name; ! 487: { ! 488: Window *children, dummy; ! 489: int nchildren, i; ! 490: Window w=0; ! 491: char *window_name; ! 492: ! 493: if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name)) ! 494: return(top); ! 495: ! 496: if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren)) ! 497: return(0); ! 498: ! 499: for (i=0; i<nchildren; i++) { ! 500: w = Window_With_Name(dpy, children[i], name); ! 501: if (w) ! 502: break; ! 503: } ! 504: XFree(children); ! 505: return(w); ! 506: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.