Mercurial > ~darius > hgwebdir.cgi > paradise_client
view x11window.c @ 3:5a977ccbc7a9 default tip
Empty changelog
author | darius |
---|---|
date | Sat, 06 Dec 1997 05:41:29 +0000 |
parents | |
children |
line wrap: on
line source
/* $Id: x11window.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ /* x11window.c * * Kevin P. Smith 6/11/89 * Much modified by Jerry Frain and Joe Young */ #include <stdio.h> #ifdef __STDC__ #include <stdlib.h> #endif #include <X11/Xlib.h> #include <X11/Xutil.h> #ifdef RFCURSORS #include <X11/Xmu/CurUtil.h> #endif #include <X11/cursorfont.h> #include <assert.h> #include <string.h> #include "Wlib.h" #include "defs.h" #include "struct.h" #include "data.h" #include "proto.h" #define INVALID_POSITION -10000 /* gotta be a big negative */ /* XFIX speedup */ #define MAXCACHE 128 /* changes too good to risk leaving out, by Richard Caley (rjc@cstr.ed.ac.uk)*/ #define RJC #define FOURPLANEFIX /* #define NORMAL_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*" #define BOLD_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*" #define ITALIC_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*" */ #define NORMAL_FONT "6x10" #define BOLD_FONT "6x10" #define BOLD_FONT2 "-*-clean-bold-r-normal--10-100-75-75-c-60-*" #define ITALIC_FONT "6x10" #define ITALIC_FONT2 "-*-clean-bold-r-normal--10-100-75-75-c-60-*" #define BIG_FONT "-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*" #define IND_FONT "-*-clean-bold-r-normal--10-100-75-75-c-60-*" /*#define BOLD_FONT2 "-schumacher-clean-bold-r-normal--10-100-75-75-c-60-iso8859-1" #define ITALIC_FONT2 "-misc-fixed-medium-i-normal--10-100-75-75-c-60-iso8859-1" #define BIG_FONT "-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*" */ static char *_nfonts[] = { NORMAL_FONT, "-*-clean-medium-r-normal--10-100-75-75-c-60-*", "fixed", NULL, }; static char *_bfonts[] = { BOLD_FONT, "-*-clean-bold-r-normal--10-100-75-75-c-60-*", "fixed", NULL, }; static char *_ifonts[] = { ITALIC_FONT, "-*-clean-bold-r-normal--10-100-75-75-c-60-*", "fixed", NULL, }; static char *_bgfonts[] = { BIG_FONT, "-*-lucidatypewriter-*-*-*-*-40-*-*-*-*-*-*-*", "fixed", NULL, }; #define FONTS 4 #define BITGC 4 #define WHITE 0 #define BLACK 1 #define RED 2 #define GREEN 3 #define YELLOW 4 #define CYAN 5 #define GREY 6 static int zero = 0; static int one = 1; static int two = 2; static int three = 3; int controlkey = 0; #define BillsScrewyAltMask (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) int altkey = 0; int W_FastClear = 0; #ifdef CONTINUOUS_MOUSE int buttonDown = 0; #endif /* CONTINUOUS_MOUSE */ Display *W_Display; Window W_Root; Colormap W_Colormap; int W_Screen; #ifdef FOURPLANEFIX Visual *W_Visual; #endif W_Font W_BigFont = (W_Font) & zero, W_RegularFont = (W_Font) & one; W_Font W_HighlightFont = (W_Font) & two, W_UnderlineFont = (W_Font) & three; W_Color W_White = WHITE, W_Black = BLACK, W_Red = RED, W_Green = GREEN; W_Color W_Yellow = YELLOW, W_Cyan = CYAN, W_Grey = GREY; int W_Textwidth, W_Textheight; char *getdefault(); char *strdup(); int W_in_message = 0; /* jfy -- for Jerry's warp message hack */ #ifdef RJC extern W_Window baseWin; static XClassHint class_hint = { "netrek", "Netrek", }; static XWMHints wm_hint = { InputHint | StateHint, True, WithdrawnState, None, None, 0, 0, None, None, }; static XSizeHints wm_size_hint; #endif /* RJC */ static W_Event W_myevent; static int W_isEvent = 0; struct fontInfo { XFontStruct *fontstruct; int baseline; }; struct colors { char *name; GC contexts[FONTS + 1]; Pixmap pixmap; long pixelValue; }; struct icon { Window window; Pixmap bitmap; int width, height; Pixmap pixmap; }; #define WIN_GRAPH 1 #define WIN_TEXT 2 #define WIN_MENU 3 #define WIN_SCROLL 4 struct window { Window window; int type; char *data; int mapped; int width, height; char *name; Cursor cursor; #ifdef SHORT_PACKETS int insensitive; #endif #if 0 W_Callback handle_keydown; W_Callback handle_keyup; W_Callback handle_button; W_Callback handle_expose; #endif /* 0 */ }; struct stringList { char *string; W_Color color; struct stringList *next; }; struct menuItem { char *string; W_Color color; W_Font font; }; struct colors colortable[] = { {"white"}, {"black"}, {"red"}, {"green"}, {"yellow"}, {"cyan"}, {"light grey"} }; struct windowlist { struct window *window; struct windowlist *next; }; #define HASHSIZE 29 #define hash(x) (((int) (x)) % HASHSIZE) struct windowlist *hashtable[HASHSIZE]; struct fontInfo fonts[FONTS]; struct window *newWindow(); #ifndef NeXT #ifndef __STDC__ char *malloc(); #endif #endif /* NeXT */ short *x11tox10bits(); struct window myroot; #define NCOLORS (sizeof(colortable)/sizeof(colortable[0])) #define W_Void2Window(win) ((win) ? (struct window *) (win) : &myroot) #define W_Window2Void(window) ((W_Window) (window)) #define W_Void2Icon(bit) ((struct icon *) (bit)) #define W_Icon2Void(bit) ((W_Icon) (bit)) #define fontNum(font) (*((int *) font)) #define TILESIDE 16 #define WIN_EDGE 5 /* border on l/r edges of text windows */ #define MENU_PAD 4 /* border on t/b edges of text windows */ #define MENU_BAR 2 /* width of menu bar */ static unsigned char gray[] = { 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55 }; static unsigned char striped[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0 }; static unsigned char solid[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /* Prototypes */ /*static int _myerror P((Display *d , XErrorEvent *e ));*/ static void GetFonts P((void)); static XFontStruct *find_font P((char *oldf, char **fonts)); static void GetColors P((void)); static void FlushClearAreaCache P((Window win)); static int W_SpNextEvent P((W_Event * wevent)); static void FlushLineCache P((Window win, int color)); static void FlushPointCache P((Window win, int color)); static struct window *findWindow P((Window window)); static void addToHash P((struct window * win)); static void AddToScrolling P((struct window * win, W_Color color, char *str, int len)); static void redrawScrolling P((struct window * win)); static void resizeScrolling P((struct window * win, int width, int height)); static void redrawMenu P((struct window * win)); static void redrawMenuItem P((struct window * win, int n)); static void changeMenuItem P((struct window * win, int n, W_Color color, char *str, int len, W_Font font)); /*static void W_SetTransientForHint P((W_Window w , W_Window pw ));*/ static void checkGeometry P((char *name, int *x, int *y, int *width, int *height)); static void checkParent P((char *name, W_Window * parent)); static void checkCursor P((char *name, char *cursname, Cursor * cursor)); static void findMouse P((int *x, int *y)); #ifdef AUTOKEY static void W_Flush P((void)); #endif /* AUTOKEY */ static void deleteWindow P((struct window * window)); /* X debugging */ #if 0 static int _myerror(d, e) Display *d; XErrorEvent *e; { abort(); } #endif /* 0 */ void W_Initialize(str) char *str; { int i; #ifdef DEBUG printf("Initializing...\n"); #endif for (i = 0; i < HASHSIZE; i++) { hashtable[i] = NULL; } if ((W_Display = XOpenDisplay(str)) == NULL) { fprintf(stderr, "Cannot open display \"%s\"\n", str ? str : "(null)"); EXIT(1); } #if 0 /* tmp */ XSynchronize(W_Display, True); XSetErrorHandler(_myerror); #endif W_Root = DefaultRootWindow(W_Display); #ifdef FOURPLANEFIX W_Visual = DefaultVisual(W_Display, DefaultScreen(W_Display)); #endif W_Screen = DefaultScreen(W_Display); W_Colormap = DefaultColormap(W_Display, W_Screen); myroot.window = W_Root; myroot.type = WIN_GRAPH; GetFonts(); GetColors(); } static void GetFonts() { Font regular, italic, bold, big; int i; XGCValues values; XFontStruct *fontinfo; char *fontname; fontname = getdefault("font"); if (fontname == NULL) fontname = NORMAL_FONT; fontinfo = XLoadQueryFont(W_Display, fontname); if (fontinfo == NULL) { fontinfo = find_font(fontname, _nfonts); } if (fontinfo == NULL) { printf("netrek: Can't find any fonts!\n"); EXIT(1); } regular = fontinfo->fid; W_Textwidth = fontinfo->max_bounds.width; W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent; fonts[1].baseline = fontinfo->max_bounds.ascent; fonts[1].fontstruct = fontinfo; fontname = getdefault("boldfont"); if (fontname == NULL) { if (DisplayCells(W_Display, W_Screen) <= 4) fontname = BOLD_FONT2; else fontname = BOLD_FONT; } fontinfo = XLoadQueryFont(W_Display, fontname); if (fontinfo == NULL) { fontinfo = find_font(fontname, _bfonts); } if (fontinfo == NULL) { bold = regular; fonts[2].baseline = fonts[1].baseline; fonts[2].fontstruct = fonts[1].fontstruct; } else { bold = fontinfo->fid; fonts[2].baseline = fontinfo->max_bounds.ascent; fonts[2].fontstruct = fontinfo; if (fontinfo->max_bounds.width > W_Textwidth) W_Textwidth = fontinfo->max_bounds.width; if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight) W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent; } fontname = getdefault("italicfont"); if (fontname == NULL) { if (DisplayCells(W_Display, W_Screen) <= 4) fontname = ITALIC_FONT2; else fontname = ITALIC_FONT; } fontinfo = XLoadQueryFont(W_Display, fontname); if (fontinfo == NULL) { fontinfo = find_font(fontname, _ifonts); } if (fontinfo == NULL) { italic = regular; fonts[3].baseline = fonts[1].baseline; fonts[3].fontstruct = fonts[1].fontstruct; } else { italic = fontinfo->fid; fonts[3].baseline = fontinfo->max_bounds.ascent; fonts[3].fontstruct = fontinfo; if (fontinfo->max_bounds.width > W_Textwidth) W_Textwidth = fontinfo->max_bounds.width; if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight) W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent; } fontname = getdefault("bigfont"); if (fontname == NULL) fontname = BIG_FONT; fontinfo = XLoadQueryFont(W_Display, fontname); if (fontinfo == NULL) { fontinfo = find_font(fontname, _bgfonts); } if (fontinfo == NULL) { big = regular; fonts[0].baseline = fonts[1].baseline; fonts[0].fontstruct = fonts[1].fontstruct; } else { big = fontinfo->fid; fonts[0].baseline = fontinfo->max_bounds.ascent; fonts[0].fontstruct = fontinfo; } for (i = 0; i < NCOLORS; i++) { values.font = big; colortable[i].contexts[0] = XCreateGC(W_Display, W_Root, GCFont, &values); XSetGraphicsExposures(W_Display, colortable[i].contexts[0], False); values.font = regular; colortable[i].contexts[1] = XCreateGC(W_Display, W_Root, GCFont, &values); XSetGraphicsExposures(W_Display, colortable[i].contexts[1], False); values.font = bold; colortable[i].contexts[2] = XCreateGC(W_Display, W_Root, GCFont, &values); XSetGraphicsExposures(W_Display, colortable[i].contexts[2], False); values.font = italic; colortable[i].contexts[3] = XCreateGC(W_Display, W_Root, GCFont, &values); XSetGraphicsExposures(W_Display, colortable[i].contexts[3], False); { static char dl[] = {1, 4}; XSetLineAttributes(W_Display, colortable[i].contexts[3], 0, LineOnOffDash, CapButt, JoinMiter); XSetDashes(W_Display, colortable[i].contexts[3], 0, dl, 2); } values.function = GXor; colortable[i].contexts[BITGC] = XCreateGC(W_Display, W_Root, GCFunction, &values); XSetGraphicsExposures(W_Display, colortable[i].contexts[BITGC], False); } } static XFontStruct * find_font(oldf, fonts) char *oldf, **fonts; { XFontStruct *fi; char **f; fprintf(stderr, "netrek: Can't find font %s. Trying others...\n", oldf); for (f = fonts; *f; f++) { if (strcmp(*f, oldf) != 0) { if ((fi = XLoadQueryFont(W_Display, *f))) return fi; } } printf("Error - can't find any font!\n"); return NULL; } #ifdef FOURPLANEFIX static unsigned short extrared[8] = {0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0}; static unsigned short extragreen[8] = {0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20}; static unsigned short extrablue[8] = {0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20, 0x40, 0x60}; #endif int W_Mono() { return forceMono; } static void GetColors() { int i, j; XColor foo; int white, black; unsigned long pixel; unsigned long planes[3]; char defaultstring[100]; char *defaults; #ifdef FOURPLANEFIX unsigned long extracolors[8]; XColor colordef; #endif extern int forceMono; forceMono = booleanDefault("forcemono", forceMono); if ((DisplayCells(W_Display, W_Screen) <= 4) || forceMono) { forceMono = 1; white = WhitePixel(W_Display, W_Screen); black = BlackPixel(W_Display, W_Screen); for (i = 0; i < NCOLORS; i++) { if (i != W_Black) { colortable[i].pixelValue = white; } else { colortable[i].pixelValue = black; } if (i == W_Red) { colortable[i].pixmap = XCreatePixmapFromBitmapData (W_Display, W_Root, (char *) striped, TILESIDE, TILESIDE, white, black, DefaultDepth(W_Display, W_Screen)); } else if (i == W_Yellow) { colortable[i].pixmap = XCreatePixmapFromBitmapData (W_Display, W_Root, (char *) gray, TILESIDE, TILESIDE, white, black, DefaultDepth(W_Display, W_Screen)); } else { colortable[i].pixmap = XCreatePixmapFromBitmapData (W_Display, W_Root, (char *) solid, TILESIDE, TILESIDE, colortable[i].pixelValue, colortable[i].pixelValue, DefaultDepth(W_Display, W_Screen)); } /* We assume white is 0 or 1, and black is 0 or 1. We adjust graphics function based upon who is who. */ if (white == 0) { /* Black is 1 */ XSetFunction(W_Display, colortable[i].contexts[BITGC], GXand); } } } else if (DefaultVisual(W_Display, W_Screen)->class == TrueColor) { /* Stuff added by sheldon@iastate.edu 5/28/93 * This is supposed to detect a TrueColor display, and then do a lookup of * the colors in default colormap, instead of creating new colormap */ for (i = 0; i < NCOLORS; i++) { sprintf(defaultstring, "color.%s", colortable[i].name); defaults = getdefault(defaultstring); if (defaults == NULL) defaults = colortable[i].name; XParseColor(W_Display, W_Colormap, defaults, &foo); XAllocColor(W_Display, W_Colormap, &foo); colortable[i].pixelValue = foo.pixel; colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display, W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel, DefaultDepth(W_Display, W_Screen)); } } else { #ifdef FOURPLANEFIX if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3, &pixel, 1)) { /* couldn't allocate 3 planes, make a new colormap */ W_Colormap = XCreateColormap(W_Display, W_Root, W_Visual, AllocNone); if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3, &pixel, 1)) { fprintf(stderr, "Cannot create new colormap\n"); EXIT(1); } /* and fill it with at least 8 more colors so when mouse is inside netrek windows, use might be able to see his other windows */ if (XAllocColorCells(W_Display, W_Colormap, False, NULL, 0, extracolors, 8)) { colordef.flags = DoRed | DoGreen | DoBlue; for (i = 0; i < 8; i++) { colordef.pixel = extracolors[i]; colordef.red = extrared[i] << 8; colordef.green = extragreen[i] << 8; colordef.blue = extrablue[i] << 8; XStoreColor(W_Display, W_Colormap, &colordef); } } } #else XAllocColorCells(W_Display, W_Colormap, False, planes, 3, &pixel, 1); #endif for (i = 0; i < NCOLORS; i++) { /* strcpy(defaultstring, "color.%s", colortable[i].name); */ sprintf(defaultstring, "color.%s", colortable[i].name); defaults = getdefault(defaultstring); if (defaults == NULL) defaults = colortable[i].name; XParseColor(W_Display, W_Colormap, defaults, &foo); /* Black must be the color with all the planes off. That is the only restriction I concerned myself with in the following case statement. */ switch (i) { case WHITE: foo.pixel = pixel | planes[0] | planes[1] | planes[2]; break; case BLACK: foo.pixel = pixel; break; case RED: foo.pixel = pixel | planes[0]; break; case CYAN: foo.pixel = pixel | planes[1]; break; case YELLOW: foo.pixel = pixel | planes[2]; break; case GREY: foo.pixel = pixel | planes[0] | planes[1]; break; case GREEN: foo.pixel = pixel | planes[1] | planes[2]; break; } XStoreColor(W_Display, W_Colormap, &foo); colortable[i].pixelValue = foo.pixel; colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display, W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel, DefaultDepth(W_Display, W_Screen)); } } for (i = 0; i < NCOLORS; i++) { for (j = 0; j < FONTS + 1; j++) { XSetForeground(W_Display, colortable[i].contexts[j], colortable[i].pixelValue); XSetBackground(W_Display, colortable[i].contexts[j], colortable[W_Black].pixelValue); } } } void W_RenameWindow(window, str) W_Window window; char *str; { XStoreName(W_Display, ((struct window *) window)->window, str); } static W_Window w_MakeWindow(name, x, y, width, height, parent, cursname, border, color, wsort) char *name; int x, y, width, height; W_Window parent; char *cursname; int border; W_Color color; int wsort; /* WIN_? */ { int gx, gy; struct window *newwin; Window wparent; Cursor cursor; XSetWindowAttributes attrs; int pwidth, pheight; /* pixel width and height */ checkGeometry(name, &gx, &gy, &width, &height); if (gx != INVALID_POSITION) x = gx; if (gy != INVALID_POSITION) y = gy; checkParent(name, &parent); wparent = W_Void2Window(parent)->window; checkCursor(name, cursname, &cursor); attrs.cursor = cursor; attrs.border_pixel = colortable[color].pixelValue; attrs.background_pixel = colortable[W_Black].pixelValue; if (wsort == WIN_TEXT || wsort == WIN_SCROLL || wsort == WIN_MENU) { pwidth = width * W_Textwidth + WIN_EDGE * 2; if (wsort == WIN_MENU) pheight = height * (W_Textheight + MENU_PAD * 2 + MENU_BAR) - MENU_BAR; else pheight = height * W_Textheight + MENU_PAD * 2; } else { pwidth = width; pheight = height; } switch (wsort) { case WIN_TEXT: case WIN_MENU: attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | ButtonReleaseMask; attrs.do_not_propagate_mask = ExposureMask | KeyPressMask | ButtonPressMask; break; case WIN_GRAPH: attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | LeaveWindowMask | ButtonReleaseMask | ButtonMotionMask; attrs.do_not_propagate_mask = ExposureMask; break; case WIN_SCROLL: attrs.event_mask = ResizeRedirectMask | ExposureMask | KeyPressMask | ButtonReleaseMask | ButtonPressMask; attrs.do_not_propagate_mask = ResizeRedirectMask | ExposureMask; break; default: fprintf(stderr, "x11window.c: w_MakeWindow: unknown wsort %d\n", wsort); } #ifdef AUTOKEY if (attrs.event_mask & KeyPressMask) attrs.event_mask |= KeyReleaseMask; #endif /* AUTOKEY */ if (strcmp(name, "netrek_icon") == 0) /* icon should not select for input */ attrs.event_mask = ExposureMask; if (strcmp(name, "wait_icon") == 0) /* same here [BDyess] */ attrs.event_mask = ExposureMask; if (strcmp(name, "info") == 0) /* make info window passthru [BDyess] */ attrs.event_mask = ExposureMask; newwin = newWindow (XCreateWindow(W_Display, wparent, x, y, pwidth, pheight, border, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWBorderPixel | CWEventMask | (cursor ? CWCursor : 0), &attrs), wsort); newwin->cursor = cursor; { char *s; if (0 == strcmp(name, "wait")) s = serverName; else if (0 == strcmp(name, "Motd")) s = "Motd - [f] forward, [b] back, [tab] sysdefs, [space] unmap"; else if (0 == strcmp(name, "netrek")) { if (!title) { char buf[80]; sprintf(buf, "Netrek @ %s", serverName); s = buf; } else { /* but title on command line will override */ /* from -h arg */ s = title; } } else s = name; XStoreName(W_Display, newwin->window, s); } wm_size_hint.width = wm_size_hint.min_width = wm_size_hint.max_width = wm_size_hint.base_width = pwidth; wm_size_hint.min_height = wm_size_hint.height = wm_size_hint.max_height = wm_size_hint.base_height = pheight; wm_size_hint.flags = USSize | PMinSize | PMaxSize | PBaseSize; if (gx > INVALID_POSITION || gy > INVALID_POSITION) { wm_size_hint.flags |= USPosition; wm_size_hint.x = x; wm_size_hint.y = y; } XSetWMNormalHints(W_Display, newwin->window, &wm_size_hint); class_hint.res_name = name; class_hint.res_class = "Netrek"; XSetClassHint(W_Display, newwin->window, &class_hint); XSetWMHints(W_Display, newwin->window, &wm_hint); if (((wparent == W_Root && baseWin != NULL && strcmp(name, "wait") != 0) || wsort == WIN_MENU) && strcmp(name, "MetaServer List") != 0 && strcmp(name, "Motd") != 0) { XSetTransientForHint(W_Display, newwin->window, W_Void2Window(baseWin)->window); } newwin->name = strdup(name); newwin->width = width; newwin->height = height; if (wsort == WIN_MENU) { int i; struct menuItem *items; items = (struct menuItem *) malloc(height * sizeof(struct menuItem)); for (i = 0; i < height; i++) { items[i].string = NULL; items[i].color = W_White; items[i].font = W_RegularFont; } newwin->data = (char *) items; } else { newwin->data = 0; } if (wparent != W_Root) if (checkMapped(name)) W_MapWindow(W_Window2Void(newwin)); #ifdef DEBUG printf("New graphics window %d, child of %d\n", newwin, parent); #endif #ifdef FOURPLANEFIX XSetWindowColormap(W_Display, newwin->window, W_Colormap); #endif return (W_Window2Void(newwin)); } W_Window W_MakeWindow(name, x, y, width, height, parent, cursname, border, color) char *name; int x, y, width, height; W_Window parent; char *cursname; int border; W_Color color; { return w_MakeWindow(name, x, y, width, height, parent, cursname, border, color, WIN_GRAPH); } void W_ChangeBorder(window, color) W_Window window; int color; { #ifdef DEBUG printf("Changing border of %d\n", window); #endif /* fix inexplicable color bug */ if (DisplayCells(W_Display, W_Screen) <= 2) XSetWindowBorderPixmap(W_Display, W_Void2Window(window)->window, colortable[color].pixmap); else XSetWindowBorder(W_Display, W_Void2Window(window)->window, colortable[color].pixelValue); } void W_MapWindow(window) W_Window window; { struct window *win; #ifdef DEBUG printf("Mapping %d\n", window); #endif win = W_Void2Window(window); if (win->mapped) return; win->mapped = 1; XMapRaised(W_Display, win->window); } void W_UnmapWindow(window) W_Window window; { struct window *win; #ifdef DEBUG printf("UnMapping %d\n", window); #endif win = W_Void2Window(window); if (win->mapped == 0) return; win->mapped = 0; XUnmapWindow(W_Display, win->window); } int W_IsMapped(window) W_Window window; { struct window *win; win = W_Void2Window(window); if (win == NULL) return (0); return (win->mapped); } void W_FillArea(window, x, y, width, height, color) W_Window window; int x, y, width, height; W_Color color; { struct window *win; #ifdef DEBUG printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height, color, window); #endif win = W_Void2Window(window); switch (win->type) { case WIN_GRAPH: XFillRectangle(W_Display, win->window, colortable[color].contexts[0], x, y, width, height); break; default: XFillRectangle(W_Display, win->window, colortable[color].contexts[0], WIN_EDGE + x * W_Textwidth, MENU_PAD + y * W_Textheight, width * W_Textwidth, height * W_Textheight); } } /* XFIX */ static XRectangle _rcache[MAXCACHE]; static int _rcache_index; static void FlushClearAreaCache(win) Window win; { XFillRectangles(W_Display, win, colortable[backColor].contexts[0], _rcache, _rcache_index); _rcache_index = 0; } /* local window only */ void W_CacheClearArea(window, x, y, width, height) W_Window window; int x, y, width, height; { Window win = W_Void2Window(window)->window; register XRectangle *r; if (_rcache_index == MAXCACHE) FlushClearAreaCache(win); r = &_rcache[_rcache_index++]; r->x = (short) x; r->y = (short) y; r->width = (unsigned short) width; r->height = (unsigned short) height; } void W_FlushClearAreaCache(window) W_Window window; { Window win = W_Void2Window(window)->window; if (_rcache_index) FlushClearAreaCache(win); } /* XFIX: clears now instead of filling. */ void W_ClearArea(window, x, y, width, height) W_Window window; int x, y, width, height; { struct window *win; #ifdef DEBUG printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height, color, window); #endif win = W_Void2Window(window); switch (win->type) { case WIN_GRAPH: /* XFIX: changed */ XClearArea(W_Display, win->window, x, y, width, height, False); break; default: /* XFIX: changed */ XClearArea(W_Display, win->window, WIN_EDGE + x * W_Textwidth, MENU_PAD + y * W_Textheight, width * W_Textwidth, height * W_Textheight, False); break; } } void W_ClearWindow(window) W_Window window; { #ifdef DEBUG printf("Clearing %d\n", window); #endif XClearWindow(W_Display, W_Void2Window(window)->window); } void W_GetEvent(wevent) W_Event *wevent; { /* blocks until an event is received [BDyess] */ XEvent event; if (W_isEvent) { *wevent = W_myevent; W_isEvent = 0; return; } XNextEvent(W_Display, &event); XPutBackEvent(W_Display, &event); W_SpNextEvent(wevent); } int W_EventsPending() { if (W_isEvent) return (1); while (XPending(W_Display) || buttonDown) { if (W_SpNextEvent(&W_myevent)) { W_isEvent = 1; return (1); } } return (0); } void W_NextEvent(wevent) W_Event *wevent; { if (W_isEvent) { *wevent = W_myevent; W_isEvent = 0; return; } while (W_SpNextEvent(wevent) == 0); } static int W_SpNextEvent(wevent) W_Event *wevent; { XEvent event; XKeyEvent *key; XButtonEvent *button; XExposeEvent *expose; XResizeRequestEvent *resize; char ch; struct window *win; #ifdef CONTINUOUS_MOUSE static W_Event buttonEvent; static int delay, cupd = -1; #endif /* CONTINUOUS_MOUSE */ #ifdef DEBUG printf("Getting an event...\n"); #endif key = (XKeyEvent *) & event; button = (XButtonEvent *) & event; expose = (XExposeEvent *) & event; resize = (XResizeRequestEvent *) & event; for (;;) { if (XPending(W_Display)) XNextEvent(W_Display, &event); #ifdef CONTINUOUS_MOUSE else if (buttonDown) { if (continuousMouse && allowContinuousMouse) { if (cupd != udcounter) { cupd = udcounter; if (delay == 0) { bcopy(&buttonEvent, wevent, sizeof(W_Event)); delay = clickDelay; } else { delay--; wevent->type = -1; } } else wevent->type = -1; exitInputLoop = 1; } else { wevent->type = -1; buttonDown = 0; } return (1); } #endif else return (0); /* printf("read an event %d\n", event.type); */ win = findWindow(key->window); if (win == NULL) return (0); if ((event.type == KeyPress || event.type == ButtonPress) && win->type == WIN_MENU) { if (key->y % (W_Textheight + MENU_PAD * 2 + MENU_BAR) >= W_Textheight + MENU_PAD * 2) return (0); key->y = key->y / (W_Textheight + MENU_PAD * 2 + MENU_BAR); } switch ((int) event.type) { case LeaveNotify: /* for message window -- jfy */ if (win == (struct window *) messagew) { W_in_message = 0; } return (0); break; case KeyPress: if (key->state & ControlMask) { controlkey = 1; key->state &= ~ControlMask; } else controlkey = 0; if (key->state & BillsScrewyAltMask) { altkey = 1; key->state &= ~BillsScrewyAltMask; } else altkey = 0; if (XLookupString(key, &ch, 1, NULL, NULL) > 0) { wevent->type = W_EV_KEY; wevent->Window = W_Window2Void(win); wevent->x = key->x; wevent->y = key->y; if (controlkey) wevent->key = (int) ch + 128; else if (altkey) wevent->key = (int) ch + 256; else wevent->key = ch; return (1); } return (0); break; #ifdef AUTOKEY case KeyRelease: if (XLookupString(key, &ch, 1, NULL, NULL) > 0) { wevent->type = W_EV_KEY_OFF; wevent->Window = W_Window2Void(win); wevent->x = key->x; wevent->y = key->y; wevent->key = ch; return (1); } return (0); break; #endif /* AUTOKEY */ case ButtonPress: wevent->type = W_EV_BUTTON; wevent->Window = W_Window2Void(win); wevent->x = button->x; wevent->y = button->y; switch (button->button & 0xf) { case Button3: wevent->key = W_RBUTTON; break; case Button1: wevent->key = W_LBUTTON; break; case Button2: wevent->key = W_MBUTTON; break; } if (key->state & ControlMask) wevent->key += 6; if (key->state & ShiftMask) wevent->key += 3; if (key->state & BillsScrewyAltMask) wevent->key += 12; /* alt */ #ifdef CONTINUOUS_MOUSE if (continuousMouse && allowContinuousMouse && (wevent->Window == w || wevent->Window == mapw) && /* buttonRepeatMask allows only certain buttons to repeat [BDyess] */ (1 << (wevent->key) & buttonRepeatMask)) { buttonDown = 1; exitInputLoop = 1; delay = clickDelay; bcopy(wevent, &buttonEvent, sizeof(W_Event)); } return (1); case ButtonRelease: /* bcopy(&buttonEvent,wevent,sizeof(W_Event)); */ wevent->type = -1; buttonDown = 0; return (1); case MotionNotify: /* the !buttonDown ensures that if you press a button and then press another, release just the second, and then move the mouse that nothing happens. */ if (!(continuousMouse && allowContinuousMouse) || !buttonDown) { wevent->type = -1; return (1); } wevent->type = W_EV_BUTTON; wevent->Window = W_Window2Void(win); wevent->x = button->x; wevent->y = button->y; wevent->key = buttonEvent.key; bcopy(wevent, &buttonEvent, sizeof(W_Event)); if (cupd == udcounter) wevent->type = -1; else cupd = udcounter; return (1); #else return (1); #endif /* CONTINUOUS_MOUSE */ case Expose: if (expose->count != 0) return (0); if (win->type == WIN_SCROLL) { redrawScrolling(win); return (0); } if (win->type == WIN_MENU) { redrawMenu(win); return (0); } wevent->type = W_EV_EXPOSE; wevent->Window = W_Window2Void(win); return (1); case ResizeRequest: resizeScrolling(win, resize->width, resize->height); break; default: return (0); break; } } } void W_MakeLine(window, x0, y0, x1, y1, color) W_Window window; int x0, y0, x1, y1; W_Color color; { Window win; #ifdef DEBUG printf("Line on %d\n", window); #endif win = W_Void2Window(window)->window; XDrawLine(W_Display, win, colortable[color].contexts[0], x0, y0, x1, y1); } void W_DrawPoint(window, x, y, color) W_Window window; int x, y; W_Color color; { Window win; #ifdef DEBUG printf("Point on %d\n", window); #endif win = W_Void2Window(window)->window; XDrawPoint(W_Display, win, colortable[color].contexts[0], x, y); } /* XFIX */ static XSegment _lcache[NCOLORS][MAXCACHE]; static int _lcache_index[NCOLORS]; static void FlushLineCache(win, color) Window win; int color; { XDrawSegments(W_Display, win, colortable[color].contexts[0], _lcache[color], _lcache_index[color]); _lcache_index[color] = 0; } /* for local window only */ void W_CacheLine(window, x0, y0, x1, y1, color) W_Window window; int x0, y0, x1, y1, color; { Window win = W_Void2Window(window)->window; register XSegment *s; if (_lcache_index[color] == MAXCACHE) FlushLineCache(win, color); s = &_lcache[color][_lcache_index[color]++]; s->x1 = (short) x0; s->y1 = (short) y0; s->x2 = (short) x1; s->y2 = (short) y1; } void W_FlushLineCaches(window) W_Window window; { Window win = W_Void2Window(window)->window; register i; for (i = 0; i < NCOLORS; i++) { if (_lcache_index[i]) FlushLineCache(win, i); } } static XPoint _pcache[NCOLORS][MAXCACHE]; static int _pcache_index[NCOLORS]; static void FlushPointCache(win, color) Window win; int color; { XDrawPoints(W_Display, win, colortable[color].contexts[0], _pcache[color], _pcache_index[color], CoordModeOrigin); _pcache_index[color] = 0; } void W_CachePoint(window, x, y, color) W_Window window; int x, y, color; { Window win = W_Void2Window(window)->window; register XPoint *p; if (_pcache_index[color] == MAXCACHE) FlushPointCache(win, color); p = &_pcache[color][_pcache_index[color]++]; p->x = (short) x; p->y = (short) y; } void W_FlushPointCaches(window) W_Window window; { Window win = W_Void2Window(window)->window; register i; for (i = 0; i < NCOLORS; i++) { if (_pcache_index[i]) FlushPointCache(win, i); } } void W_MakeTractLine(window, x0, y0, x1, y1, color) W_Window window; int x0, y0, x1, y1; W_Color color; { Window win; #ifdef DEBUG printf("Line on %d\n", window); #endif win = W_Void2Window(window)->window; XDrawLine(W_Display, win, colortable[color].contexts[3], x0, y0, x1, y1); } void W_DrawSectorHighlight(window, x, y, w, h, color) W_Window window; int x, y, w, h; W_Color color; { Window win; #ifdef YUCK XRectangle r[2]; r[0].x = (short) x; r[0].y = (short) y; r[0].width = (unsigned short) w; r[0].height = (unsigned short) h; r[1].x = (short) x + 2; r[1].y = (short) y + 2; r[1].width = (unsigned short) w - 4; r[1].height = (unsigned short) h - 4; win = W_Void2Window(window)->window; XDrawRectangles(W_Display, win, colortable[color].contexts[3], r, 2); #else XRectangle r[1]; r[0].x = (short) x + 2; r[0].y = (short) y + 2; r[0].width = (unsigned short) w - 4; r[0].height = (unsigned short) h - 4; win = W_Void2Window(window)->window; XDrawRectangles(W_Display, win, colortable[color].contexts[3], r, 1); #endif } void W_WriteTriangle(window, x, y, s, t, color) W_Window window; int x, y, s; int t; W_Color color; { struct window *win = W_Void2Window(window); XPoint points[3]; if (t == 0) { points[0].x = x; points[0].y = y; points[1].x = x + s; points[1].y = y - s; points[2].x = x - s; points[2].y = y - s; } else { points[0].x = x; points[0].y = y; points[1].x = x + s; points[1].y = y + s; points[2].x = x - s; points[2].y = y + s; } XFillPolygon(W_Display, win->window, colortable[color].contexts[0], points, 3, Convex, CoordModeOrigin); } void W_WriteText(window, x, y, color, str, len, font) W_Window window; int x, y, len; W_Color color; W_Font font; char *str; { struct window *win; int addr; if (!font) font = W_RegularFont; #ifdef DEBUG printf("Text for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str); #endif win = W_Void2Window(window); switch (win->type) { case WIN_GRAPH: addr = fonts[fontNum(font)].baseline; XDrawImageString(W_Display, win->window, colortable[color].contexts[fontNum(font)], x, y + addr, str, len); break; case WIN_SCROLL: if (y<0) { XCopyArea(W_Display, win->window, win->window, colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD, win->width * W_Textwidth, (win->height - 1) * W_Textheight, WIN_EDGE, MENU_PAD+W_Textheight); XClearArea(W_Display, win->window, WIN_EDGE, MENU_PAD, W_Textwidth * win->width, W_Textheight, False); XDrawImageString(W_Display, win->window, colortable[color].contexts[1], WIN_EDGE, MENU_PAD + fonts[1].baseline, str, len); } else { XCopyArea(W_Display, win->window, win->window, colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD + W_Textheight, win->width * W_Textwidth, (win->height - 1) * W_Textheight, WIN_EDGE, MENU_PAD); XClearArea(W_Display, win->window, WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1), W_Textwidth * win->width, W_Textheight, False); XDrawImageString(W_Display, win->window, colortable[color].contexts[1], WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1) + fonts[1].baseline, str, len); } AddToScrolling(win, color, str, len); break; case WIN_MENU: changeMenuItem(win, y, color, str, len, font); break; default: addr = fonts[fontNum(font)].baseline; XDrawImageString(W_Display, win->window, colortable[color].contexts[fontNum(font)], x * W_Textwidth + WIN_EDGE, MENU_PAD + y * W_Textheight + addr, str, len); break; } } void W_MaskText(window, x, y, color, str, len, font) W_Window window; int x, y, len; W_Color color; W_Font font; char *str; { struct window *win; int addr; addr = fonts[fontNum(font)].baseline; #ifdef DEBUG printf("TextMask for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str); #endif win = W_Void2Window(window); XDrawString(W_Display, win->window, colortable[color].contexts[fontNum(font)], x, y + addr, str, len); } W_Icon W_StoreBitmap(width, height, data, window) int width, height; W_Window window; char *data; { struct icon *newicon; struct window *win; #ifdef DEBUG printf("Storing bitmap for %d (%d x %d)\n", window, width, height); fflush(stdout); #endif win = W_Void2Window(window); newicon = (struct icon *) malloc(sizeof(struct icon)); newicon->width = width; newicon->height = height; newicon->bitmap = XCreateBitmapFromData(W_Display, win->window, data, width, height); newicon->window = win->window; newicon->pixmap = 0; return (W_Icon2Void(newicon)); } void W_FreeBitmap(bit) W_Icon bit; { struct icon *icon; icon = W_Void2Icon(bit); XFreePixmap(W_Display, icon->bitmap); free(icon); } void W_WriteBitmap(x, y, bit, color) int x, y; W_Icon bit; W_Color color; { struct icon *icon; icon = W_Void2Icon(bit); #ifdef DEBUG printf("Writing bitmap to %d\n", icon->window); #endif XCopyPlane(W_Display, icon->bitmap, icon->window, colortable[color].contexts[BITGC], 0, 0, icon->width, icon->height, x, y, 1); } void W_WriteWinBitmap(win, x, y, bit, color) W_Window win; int x, y; W_Icon bit; W_Color color; { struct icon *icon; Window original; icon = W_Void2Icon(bit); original = icon->window; icon->window = W_Void2Window(win)->window; W_WriteBitmap(x, y, bit, color); icon->window = original; return; } void W_TileWindow(window, bit) W_Window window; W_Icon bit; { Window win; struct icon *icon; #ifdef DEBUG printf("Tiling window %d\n", window); #endif icon = W_Void2Icon(bit); win = W_Void2Window(window)->window; if (icon->pixmap == 0) { icon->pixmap = XCreatePixmap(W_Display, W_Root, icon->width, icon->height, DefaultDepth(W_Display, W_Screen)); XCopyPlane(W_Display, icon->bitmap, icon->pixmap, colortable[W_White].contexts[0], 0, 0, icon->width, icon->height, 0, 0, 1); } XSetWindowBackgroundPixmap(W_Display, win, icon->pixmap); XClearWindow(W_Display, win); /* if (icon->pixmap==0) { icon->pixmap=XMakePixmap(icon->bitmap, colortable[W_White].pixelValue, colortable[W_Black].pixelValue); } XChangeBackground(win, icon->pixmap); XClear(win); */ } void W_UnTileWindow(window) W_Window window; { Window win; #ifdef DEBUG printf("Untiling window %d\n", window); #endif win = W_Void2Window(window)->window; XSetWindowBackground(W_Display, win, colortable[W_Black].pixelValue); XClearWindow(W_Display, win); } W_Window W_MakeTextWindow(name, x, y, width, height, parent, cursname, border) char *name; int x, y, width, height; W_Window parent; char *cursname; int border; { return w_MakeWindow(name, x, y, width, height, parent, cursname, border, W_White, WIN_TEXT); } struct window * newWindow(window, type) Window window; int type; { struct window *newwin; newwin = (struct window *) malloc(sizeof(struct window)); newwin->window = window; newwin->type = type; newwin->mapped = 0; newwin->insensitive = 0; addToHash(newwin); return (newwin); } static struct window * findWindow(window) Window window; { struct windowlist *entry; entry = hashtable[hash(window)]; while (entry != NULL) { if (entry->window->window == window) return (entry->window); entry = entry->next; } return (NULL); } static void addToHash(win) struct window *win; { struct windowlist **new; #ifdef DEBUG printf("Adding to %d\n", hash(win->window)); #endif new = &hashtable[hash(win->window)]; while (*new != NULL) { new = &((*new)->next); } *new = (struct windowlist *) malloc(sizeof(struct windowlist)); (*new)->next = NULL; (*new)->window = win; } W_Window W_MakeScrollingWindow(name, x, y, width, height, parent, cursname, border) char *name; int x, y, width, height; W_Window parent; char *cursname; int border; { return w_MakeWindow(name, x, y, width, height, parent, cursname, border, W_White, WIN_SCROLL); } /* Add a string to the string list of the scrolling window. */ static void AddToScrolling(win, color, str, len) struct window *win; W_Color color; char *str; int len; { struct stringList **strings; char *newstring; int count; strings = (struct stringList **) & (win->data); count = 0; while ((*strings) != NULL) { count++; strings = &((*strings)->next); } (*strings) = (struct stringList *) malloc(sizeof(struct stringList)); (*strings)->next = NULL; (*strings)->color = color; newstring = (char *) malloc(len + 1); strncpy(newstring, str, len); newstring[len] = 0; (*strings)->string = newstring; if (count >= 100) { /* Arbitrary large size. */ struct stringList *temp; temp = (struct stringList *) win->data; free(temp->string); temp = temp->next; free((char *) win->data); win->data = (char *) temp; } } #ifdef SHORT_PACKETS void W_SetSensitive(w, v) W_Window w; int v; { struct window *win = W_Void2Window(w); win->insensitive = !v; if (win->type == WIN_SCROLL) redrawScrolling(win); } #endif static void redrawScrolling(win) struct window *win; { int count; struct stringList *list; int y; XClearWindow(W_Display, win->window); count = 0; list = (struct stringList *) win->data; while (list != NULL) { list = list->next; count++; } list = (struct stringList *) win->data; while (count > win->height) { list = list->next; count--; } y = (win->height - count) * W_Textheight + fonts[1].baseline; if (count == 0) return; while (list != NULL) { XDrawImageString(W_Display, win->window, colortable[list->color].contexts[1], WIN_EDGE, MENU_PAD + y, list->string, strlen(list->string)); list = list->next; y = y + W_Textheight; } } static void resizeScrolling(win, width, height) struct window *win; int width, height; { win->height = (height - MENU_PAD * 2) / W_Textheight; win->width = (width - WIN_EDGE * 2) / W_Textwidth; XResizeWindow(W_Display, win->window, win->width * W_Textwidth + WIN_EDGE * 2, win->height * W_Textheight + MENU_PAD * 2); } W_Window W_MakeMenu(name, x, y, width, height, parent, border) char *name; int x, y, width, height; W_Window parent; int border; { return w_MakeWindow(name, x, y, width, height, parent, "left_ptr", border, W_White, WIN_MENU); } static void redrawMenu(win) struct window *win; { int count; for (count = 1; count < win->height; count++) { XFillRectangle(W_Display, win->window, colortable[W_Grey].contexts[0], 0, count * (W_Textheight + MENU_PAD * 2) + (count - 1) * MENU_BAR, win->width * W_Textwidth + WIN_EDGE * 2, MENU_BAR); } for (count = 0; count < win->height; count++) { redrawMenuItem(win, count); } } static void redrawMenuItem(win, n) struct window *win; int n; { struct menuItem *items; int addr; items = (struct menuItem *) win->data; XFillRectangle(W_Display, win->window, colortable[W_Black].contexts[0], WIN_EDGE, n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD, win->width * W_Textwidth, W_Textheight); if (items[n].string) { addr = fonts[fontNum(items[n].font)].baseline; XDrawImageString(W_Display, win->window, colortable[items[n].color].contexts[fontNum(items[n].font)], WIN_EDGE, n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD + addr, items[n].string, strlen(items[n].string)); } } static void changeMenuItem(win, n, color, str, len, font) struct window *win; int n; W_Color color; char *str; int len; W_Font font; { struct menuItem *items; char *news; items = (struct menuItem *) win->data; if (items[n].string) { free(items[n].string); } news = malloc(len + 1); strncpy(news, str, len); news[len] = 0; items[n].string = news; items[n].color = color; items[n].font = font; redrawMenuItem(win, n); XFlush(W_Display); } static Cursor make_cursor(bits, mask, width, height, xhot, yhot) char *bits, *mask; int width, height, xhot, yhot; { Pixmap cursbits; Pixmap cursmask; XColor whiteCol, blackCol; Cursor curs; whiteCol.pixel = colortable[W_White].pixelValue; XQueryColor(W_Display, W_Colormap, &whiteCol); blackCol.pixel = colortable[W_Black].pixelValue; XQueryColor(W_Display, W_Colormap, &blackCol); cursbits = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display), bits, width, height); cursmask = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display), mask, width, height); curs = XCreatePixmapCursor(W_Display, cursbits, cursmask, &whiteCol, &blackCol, xhot, yhot); XFreePixmap(W_Display, cursbits); XFreePixmap(W_Display, cursmask); return curs; } #ifdef TCURSORS #if 1 void W_DefineTCrossCursor(window) W_Window window; { return; } void W_DefineTextCursor(window) W_Window window; { static Cursor new = 0; struct window *win = W_Void2Window(window); XColor f, b; if (!new) { f.pixel = colortable[W_Yellow].pixelValue; b.pixel = colortable[W_Black].pixelValue; XQueryColor(W_Display, W_Colormap, &f); XQueryColor(W_Display, W_Colormap, &b); new = XCreateFontCursor(W_Display, XC_xterm); XRecolorCursor(W_Display, new, &f, &b); } XDefineCursor(W_Display, win->window, new); return; } void W_RevertCursor(window) W_Window window; { struct window *win = W_Void2Window(window); XDefineCursor(W_Display, win->window, win->cursor); return; } void W_DefineCursor(window, width, height, bits, mask, xhot, yhot) W_Window window; int width, height, xhot, yhot; char *bits, *mask; { return; } #else #ifdef YUCK void W_DefineTCrossCursor(window) W_Window window; { static Cursor new; struct window *win = W_Void2Window(window); static XColor f, b; if (new) { XDefineCursor(W_Display, win->window, new); return; } f.pixel = colortable[W_White].pixelValue; b.pixel = colortable[W_Black].pixelValue; XQueryColor(W_Display, W_Colormap, &f); XQueryColor(W_Display, W_Colormap, &b); new = XCreateFontCursor(W_Display, XC_tcross); XRecolorCursor(W_Display, new, &f, &b); XDefineCursor(W_Display, win->window, new); } #else W_DefineTCrossCursor(window) W_Window window; { W_DefineCursor(window, cross_width, cross_height, cross_bits, crossmask_bits, cross_x_hot, cross_y_hot); } #endif void W_DefineTextCursor(window) W_Window window; { static Cursor new; struct window *win = W_Void2Window(window); XColor f, b; if (new) { XDefineCursor(W_Display, win->window, new); return; } f.pixel = colortable[W_Yellow].pixelValue; b.pixel = colortable[W_Black].pixelValue; XQueryColor(W_Display, W_Colormap, &f); XQueryColor(W_Display, W_Colormap, &b); new = XCreateFontCursor(W_Display, XC_xterm); XRecolorCursor(W_Display, new, &f, &b); XDefineCursor(W_Display, win->window, new); } void W_DefineCursor(window, width, height, bits, mask, xhot, yhot) W_Window window; int width, height, xhot, yhot; char *bits, *mask; { static char *oldbits = NULL; static Cursor curs; struct window *win; #ifdef DEBUG printf("Defining cursor for %d\n", window); #endif win = W_Void2Window(window); if (!oldbits || oldbits != bits) { oldbits = bits; curs = make_cursor(bits, mask, width, height, xhot, yhot); } XDefineCursor(W_Display, win->window, curs); } #endif #endif void W_Beep() { XBell(W_Display, 0); } int W_WindowWidth(window) W_Window window; { return (W_Void2Window(window)->width); } int W_WindowHeight(window) W_Window window; { return (W_Void2Window(window)->height); } int W_Socket() { return (ConnectionNumber(W_Display)); } void W_DestroyWindow(window) W_Window window; { struct window *win; #ifdef DEBUG printf("Destroying %d\n", window); #endif win = W_Void2Window(window); deleteWindow(win); XDestroyWindow(W_Display, win->window); free((char *) win); } static void deleteWindow(window) struct window *window; { struct windowlist **rm; struct windowlist *temp; rm = &hashtable[hash(window->window)]; while (*rm != NULL && (*rm)->window != window) { rm = &((*rm)->next); } if (*rm == NULL) { printf("Attempt to delete non-existent window!\n"); return; } temp = *rm; *rm = temp->next; free((char *) temp); } void W_SetIconWindow(main, icon) W_Window main; W_Window icon; { XWMHints hints; XSetIconName(W_Display, W_Void2Window(icon)->window, W_Void2Window(main)->name); hints.flags = IconWindowHint; hints.icon_window = W_Void2Window(icon)->window; XSetWMHints(W_Display, W_Void2Window(main)->window, &hints); } static void checkGeometry(name, x, y, width, height) char *name; int *x, *y, *width, *height; /* fixed so that it handles negative positions 12/21/93 */ /* note that this is NOT standard X syntax, but it was requested */ /* and it's how BRM-Hadley works. [BDyess] */ { char *adefault; char buf[100]; char *s; #ifdef RJC *x = *y = INVALID_POSITION; #endif /* RJC */ sprintf(buf, "%s.geometry", name); adefault = getdefault(buf); if (adefault == NULL) return; /* geometry should be of the form 502x885+1+1, 502x885, or +1+1 */ s = adefault; if (*s != '+' && *s != '-') { while (*s != 'x' && *s != 0) s++; *width = atoi(adefault); if (*s == 0) return; s++; adefault = s; while (*s != '+' && *s != '-' && *s != 0) s++; *height = atoi(adefault); if (*s == 0) return; } adefault = s; s++; if (*s == '-') s++; /* for the case where they have wxh+-x+y */ while (*s != '+' && *s != '-' && *s != 0) s++; *x = atoi(adefault + 1); if (*adefault == '-') *x = -*x; if (*s == 0) return; *y = atoi(s + 1); if (*s == '-') *y = -*y; /* printf("width: %d, height: %d, x: %d, y: %d\n",*width, *height,*x,*y); */ return; } static void checkParent(name, parent) char *name; W_Window *parent; { char *adefault; char buf[100]; int i; struct windowlist *windows; sprintf(buf, "%s.parent", name); adefault = getdefault(buf); if (adefault == NULL) return; /* parent must be name of other window or "root" */ if (strcmpi(adefault, "root") == 0) { *parent = W_Window2Void(&myroot); return; } for (i = 0; i < HASHSIZE; i++) { windows = hashtable[i]; while (windows != NULL) { if (strcmpi(adefault, windows->window->name) == 0) { *parent = W_Window2Void(windows->window); return; } windows = windows->next; } } } #ifdef YUCK #define cross_width 15 #define cross_height 15 #define cross_x_hot 7 #define cross_y_hot 7 static unsigned char cross_bits[] = { 0x00, 0x00, 0xc0, 0x01, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x00, 0x04, 0x10, 0x82, 0x20, 0x56, 0x35, 0x82, 0x20, 0x04, 0x10, 0x80, 0x00, 0x00, 0x00, 0xa0, 0x02, 0xc0, 0x01, 0x00, 0x00}; static unsigned char crossmask_bits[] = { 0xe0, 0x03, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xce, 0x39, 0xcf, 0x79, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xcf, 0x79, 0xce, 0x39, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 0x03}; #else #define cross_width 16 #define cross_height 16 #define cross_x_hot 7 #define cross_y_hot 7 static unsigned char cross_bits[] = { 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00, 0x10, 0x04, 0x3f, 0x7e, 0x10, 0x04, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00}; static unsigned char crossmask_bits[] = { 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xd0, 0x05, 0xbf, 0x7e, 0x7f, 0x7f, 0xbf, 0x7e, 0xd0, 0x05, 0xe0, 0x03, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00}; #endif static void checkCursor(name, cursname, cursor) char *name; char *cursname; Cursor *cursor; { char buf[100]; unsigned cnum; char *adefault; *cursor = 0; sprintf(buf, "%s.cursor", name); adefault = getdefault(buf); if (adefault == NULL) adefault = cursname; if (adefault == NULL) return; #ifdef RFCURSORS cnum = XmuCursorNameToIndex(adefault); if (cnum != -1) { XColor f, b; *cursor = XCreateFontCursor(W_Display, cnum); if (cnum == XC_xterm) { f.pixel = colortable[W_Yellow].pixelValue; b.pixel = colortable[W_Black].pixelValue; XQueryColor(W_Display, W_Colormap, &f); XQueryColor(W_Display, W_Colormap, &b); XRecolorCursor(W_Display, *cursor, &f, &b); } else if (cnum == XC_pirate) { f.pixel = colortable[W_Red].pixelValue; b.pixel = colortable[W_Black].pixelValue; XQueryColor(W_Display, W_Colormap, &f); XQueryColor(W_Display, W_Colormap, &b); XRecolorCursor(W_Display, *cursor, &f, &b); } } else #endif if (0 == strcmp("bomb here", adefault)) { static Cursor bomb_here = 0; if (bomb_here == 0) { bomb_here = make_cursor(cross_bits, crossmask_bits, cross_width, cross_height, cross_x_hot, cross_y_hot); } *cursor = bomb_here; } } int checkMapped(name) char *name; { char buf[100]; sprintf(buf, "%s.mapped", name); return (booleanDefault(buf, 0)); } void W_WarpPointer(window, x, y) W_Window window; int x, y; { static int warped_from_x = 0, warped_from_y = 0; if (window == NULL) { if (W_in_message) { XWarpPointer(W_Display, None, W_Root, 0, 0, 0, 0, warped_from_x, warped_from_y); W_in_message = 0; } } else { findMouse(&warped_from_x, &warped_from_y); XWarpPointer(W_Display, None, W_Void2Window(window)->window, 0, 0, 0, 0, 0, 0); W_in_message = 1; } } static void findMouse(x, y) int *x, *y; { Window theRoot, theChild; int wX, wY, rootX, rootY, status; unsigned int wButtons; status = XQueryPointer(W_Display, W_Root, &theRoot, &theChild, &rootX, &rootY, &wX, &wY, &wButtons); if (status == True) { *x = wX; *y = wY; } else { *x = 0; *y = 0; } } int findMouseInWin(x, y, w) int *x, *y; W_Window w; { Window theRoot, theChild; int wX, wY, rootX, rootY, status; unsigned int wButtons; struct window *win = W_Void2Window(w); Window thisWin = win->window; status = XQueryPointer(W_Display, thisWin, &theRoot, &theChild, &rootX, &rootY, &wX, &wY, &wButtons); if (status == True) { /* if it's in the window we specified then the values returned should be within the with and height of the window */ if (wX <= win->width && wY <= win->height) { *x = wX; *y = wY; return 1; } } *x = 0; *y = 0; return 0; } #ifdef AUTOKEY static void W_Flush() { XFlush(W_Display); } W_AutoRepeatOff() { XAutoRepeatOff(W_Display); W_Flush(); } W_AutoRepeatOn() { XAutoRepeatOn(W_Display); W_Flush(); } #endif /* AUTOKEY */ /* find the width of a font */ int W_StringWidth(string, font) char string[]; W_Font font; { int x, y; y = strlen(string); x = XTextWidth(fonts[fontNum(font)].fontstruct, string, y); return (x); /* just a guess ?? old never returned! WHS 4/6/93 */ } void W_TranslatePoints(w, x, y) int *x, *y; W_Window w; { struct window *win; win = W_Void2Window(w); if (win->type == WIN_TEXT) { *y = (*y - MENU_PAD) / W_Textheight; *x = (*x - MENU_PAD) / W_Textwidth; } return; } #if 0 #define MAKE_WINDOW_GETTER(name, part) \ W_Callback name(w) \ W_Window w; \ { \ return W_Void2Window(w)->part; \ } #define MAKE_WINDOW_SETTER(name, port) \ W_Callback name(w, c) \ W_Window w; \ W_Callback c; \ { \ W_Void2Window(w)->port = c; \ } MAKE_WINDOW_GETTER(W_GetWindowKeyDownHandler, handle_keydown); MAKE_WINDOW_SETTER(W_SetWindowKeyDownHandler, handle_keydown); MAKE_WINDOW_GETTER(W_GetWindowKeyUpHandler, handle_keyup); MAKE_WINDOW_SETTER(W_SetWindowKeyUpHandler, handle_keyup); MAKE_WINDOW_GETTER(W_GetWindowButtonHandler, handle_button); MAKE_WINDOW_SETTER(W_SetWindowButtonHandler, handle_button); MAKE_WINDOW_GETTER(W_GetWindowExposeHandler, handle_expose); MAKE_WINDOW_SETTER(W_SetWindowExposeHandler, handle_expose); #endif /* 0 */ void W_ResizeWindow(window, neww, newh) /* TSH 2/93 */ W_Window window; int neww, newh; { Window win = W_Void2Window(window)->window; XResizeWindow(W_Display, win, (unsigned int) neww, (unsigned int) newh); } void W_ResizeMenu(window, neww, newh)/* TSH 2/93 */ W_Window window; int neww, newh; { W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2, newh * (W_Textheight + MENU_PAD * 2) + (newh - 1) * MENU_BAR); } void W_ResizeText(window, neww, newh)/* TSH 2/93 */ W_Window window; int neww, newh; { W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2, newh * W_Textheight + MENU_PAD * 2); } void W_Deiconify(window) W_Window window; { struct window *win; win = W_Void2Window(window); /* according to ICCCM 4.1.4, this is how you deiconify a window. */ XMapWindow(W_Display, win->window); } W_Icon W_MakeShieldBitmap(width, height, window) int width, height; W_Window window; { static GC pen = 0; struct window *win; struct icon *newicon; win = W_Void2Window(window); newicon = (struct icon *) malloc(sizeof(struct icon)); newicon->width = width; newicon->height = height; newicon->bitmap = XCreatePixmap(W_Display, win->window, width, height, 1); newicon->window = win->window; newicon->pixmap = 0; pen = XCreateGC(W_Display, newicon->bitmap, 0L, 0); XSetForeground(W_Display, pen, 0L); XFillRectangle(W_Display, newicon->bitmap, pen, 0, 0, width, height); XSetForeground(W_Display, pen, 1L); XDrawArc(W_Display, newicon->bitmap, pen, 0, 0, width - 1, height - 1, 0, 360 * 64); XFreeGC(W_Display, pen); return W_Icon2Void(newicon); } #ifdef BEEPLITE void W_OverlayBitmap(x, y, bit, color) int x, y; W_Icon bit; W_Color color; { struct icon *icon = W_Void2Icon(bit); #ifdef DEBUG printf("Overlaying bitmap to %d\n", icon->window); #endif XCopyPlane(W_Display, icon->bitmap, icon->window, colortable[color].contexts[0], 0, 0, icon->width, icon->height, x, y, 1); } #endif