--- ./src/screen.c.orig-defcursor Mon Apr 19 10:42:56 1999 +++ ./src/screen.c Sat Apr 24 01:46:48 1999 @@ -710,7 +710,9 @@ return NULL; } +#ifndef DEFINABLE_CURSOR XDefineCursor(dpy, scr->root_win, wCursor[WCUR_DEFAULT]); +#endif /* screen descriptor for raster graphic library */ rattr.flags = RC_RenderMode | RC_ColorsPerChannel; --- ./src/wconfig.h.in.orig-defcursor Sat Apr 24 01:32:05 1999 +++ ./src/wconfig.h.in Sat Apr 24 01:52:36 1999 @@ -233,6 +233,12 @@ #define TEXTURE_PLUGIN /* + * define DEFINABLE_CURSOR if you want WindowMaker's default cursor + * to be user-definable instead of using a hard-coded left_ptr. + */ +#define DEFINABLE_CURSOR + +/* *-------------------------------------------------------------------- * Default Configuration * --- ./src/defaults.c.orig-defcursor Wed Apr 21 07:16:08 1999 +++ ./src/defaults.c Sat Apr 24 01:51:33 1999 @@ -178,6 +178,11 @@ static int updateUsableArea(); +#ifdef DEFINABLE_CURSOR +extern Cursor wCursor[WCUR_LAST]; +static int getCursor(); +static int setCursor(); +#endif /* @@ -739,6 +744,31 @@ &wPreferences.title_shadow, getBool, setJustify } #endif /* TITLE_TEXT_SHADOW */ +#ifdef DEFINABLE_CURSOR + ,{"NormalCursor", "(builtin, left_ptr)", (void*)WCUR_ROOT, + NULL, getCursor, setCursor + } + ,{"MoveCursor", "(builtin, fleur)", (void*)WCUR_MOVE, + NULL, getCursor, setCursor + } + ,{"ResizeCursor", "(builtin, sizing)", (void*)WCUR_RESIZE, + NULL, getCursor, setCursor + } + ,{"WaitCursor", "(builtin, watch)", (void*)WCUR_WAIT, + NULL, getCursor, setCursor + } +#if 0 + ,{"ArrowCursor", "(builtin, top_left_arrow)", (void*)WCUR_ARROW, + NULL, getCursor, setCursor + } + ,{"QuestionCursor", "(builtin, question_arrow)", (void*)WCUR_QUESTION, + NULL, getCursor, setCursor + } + ,{"TextCursor", "(builtin, xterm)", (void*)WCUR_TEXT, + NULL, getCursor, setCursor + } +#endif +#endif /* DEFINABLE_CURSOR */ }; @@ -2143,6 +2173,296 @@ return True; } +#ifdef DEFINABLE_CURSOR + +# include +typedef struct +{ + char *name; + int id; +} WCursorLookup; + +#define CURSOR_ID_NONE (XC_num_glyphs) + +static WCursorLookup cursor_table[] = +{ + { "X_cursor", XC_X_cursor }, + { "arrow", XC_arrow }, + { "based_arrow_down", XC_based_arrow_down }, + { "based_arrow_up", XC_based_arrow_up }, + { "boat", XC_boat }, + { "bogosity", XC_bogosity }, + { "bottom_left_corner", XC_bottom_left_corner }, + { "bottom_right_corner", XC_bottom_right_corner }, + { "bottom_side", XC_bottom_side }, + { "bottom_tee", XC_bottom_tee }, + { "box_spiral", XC_box_spiral }, + { "center_ptr", XC_center_ptr }, + { "circle", XC_circle }, + { "clock", XC_clock }, + { "coffee_mug", XC_coffee_mug }, + { "cross", XC_cross }, + { "cross_reverse", XC_cross_reverse }, + { "crosshair", XC_crosshair }, + { "diamond_cross", XC_diamond_cross }, + { "dot", XC_dot }, + { "dotbox", XC_dotbox }, + { "double_arrow", XC_double_arrow }, + { "draft_large", XC_draft_large }, + { "draft_small", XC_draft_small }, + { "draped_box", XC_draped_box }, + { "exchange", XC_exchange }, + { "fleur", XC_fleur }, + { "gobbler", XC_gobbler }, + { "gumby", XC_gumby }, + { "hand1", XC_hand1 }, + { "hand2", XC_hand2 }, + { "heart", XC_heart }, + { "icon", XC_icon }, + { "iron_cross", XC_iron_cross }, + { "left_ptr", XC_left_ptr }, + { "left_side", XC_left_side }, + { "left_tee", XC_left_tee }, + { "leftbutton", XC_leftbutton }, + { "ll_angle", XC_ll_angle }, + { "lr_angle", XC_lr_angle }, + { "man", XC_man }, + { "middlebutton", XC_middlebutton }, + { "mouse", XC_mouse }, + { "pencil", XC_pencil }, + { "pirate", XC_pirate }, + { "plus", XC_plus }, + { "question_arrow", XC_question_arrow }, + { "right_ptr", XC_right_ptr }, + { "right_side", XC_right_side }, + { "right_tee", XC_right_tee }, + { "rightbutton", XC_rightbutton }, + { "rtl_logo", XC_rtl_logo }, + { "sailboat", XC_sailboat }, + { "sb_down_arrow", XC_sb_down_arrow }, + { "sb_h_double_arrow", XC_sb_h_double_arrow }, + { "sb_left_arrow", XC_sb_left_arrow }, + { "sb_right_arrow", XC_sb_right_arrow }, + { "sb_up_arrow", XC_sb_up_arrow }, + { "sb_v_double_arrow", XC_sb_v_double_arrow }, + { "shuttle", XC_shuttle }, + { "sizing", XC_sizing }, + { "spider", XC_spider }, + { "spraycan", XC_spraycan }, + { "star", XC_star }, + { "target", XC_target }, + { "tcross", XC_tcross }, + { "top_left_arrow", XC_top_left_arrow }, + { "top_left_corner", XC_top_left_corner }, + { "top_right_corner", XC_top_right_corner }, + { "top_side", XC_top_side }, + { "top_tee", XC_top_tee }, + { "trek", XC_trek }, + { "ul_angle", XC_ul_angle }, + { "umbrella", XC_umbrella }, + { "ur_angle", XC_ur_angle }, + { "watch", XC_watch }, + { "xterm", XC_xterm }, + { NULL, CURSOR_ID_NONE } +}; + +static void check_bitmap_status(int status, char *filename, Pixmap bitmap) +{ + switch(status) + { + case BitmapOpenFailed: + wwarning(_("failed to open bitmap file \"%s\""), filename); + break; + case BitmapFileInvalid: + wwarning(_("\"%s\" is not a valid bitmap file"), filename); + break; + case BitmapNoMemory: + wwarning(_("out of memory reading bitmap file \"%s\""), filename); + break; + case BitmapSuccess: + XFreePixmap(dpy, bitmap); + break; + } +} + +/* + * (none) + * (builtin, ) + * (bitmap, , ) + */ +static int parse_cursor(WScreen *scr, proplist_t pl, Cursor *cursor) +{ + proplist_t elem; + char *val; + int nelem; + int status = 0; + + nelem = PLGetNumberOfElements(pl); + if (nelem < 1) + { + return(status); + } + elem = PLGetArrayElement(pl, 0); + if (!elem || !PLIsString(elem)) + { + return(status); + } + val = PLGetString(elem); + + if (0 == strcasecmp(val, "none")) + { + status = 1; + *cursor = None; + } + else if (0 == strcasecmp(val, "builtin")) + { + int i; + int cursor_id = CURSOR_ID_NONE; + + if (2 != nelem) + { + wwarning(_("bad number of arguments in cursor specification")); + return(status); + } + elem = PLGetArrayElement(pl, 1); + if (!elem || !PLIsString(elem)) + { + return(status); + } + val = PLGetString(elem); + + for (i = 0; NULL != cursor_table[i].name; i++) + { + if (0 == strcasecmp(val, cursor_table[i].name)) + { + cursor_id = cursor_table[i].id; + break; + } + } + if (CURSOR_ID_NONE == cursor_id) + { + wwarning(_("unknown builtin cursor name \"%s\""), val); + } + else + { + *cursor = XCreateFontCursor(dpy, cursor_id); + status = 1; + } + } + else if (0 == strcasecmp(val, "bitmap")) + { + char *bitmap_name; + char *mask_name; + int bitmap_status; + int mask_status; + Pixmap bitmap; + Pixmap mask; + unsigned int w, h; + int x, y; + XColor fg, bg; + + if (3 != nelem) + { + wwarning(_("bad number of arguments in cursor specification")); + return(status); + } + elem = PLGetArrayElement(pl, 1); + if (!elem || !PLIsString(elem)) + { + return(status); + } + val = PLGetString(elem); + bitmap_name = FindImage(wPreferences.pixmap_path, val); + if (!bitmap_name) + { + wwarning(_("could not find cursor bitmap file \"%s\""), val); + return(status); + } + elem = PLGetArrayElement(pl, 2); + if (!elem || !PLIsString(elem)) + { + free(bitmap_name); + return(status); + } + val = PLGetString(elem); + mask_name = FindImage(wPreferences.pixmap_path, val); + if (!mask_name) + { + free(bitmap_name); + wwarning(_("could not find cursor bitmap file \"%s\""), val); + return(status); + } + mask_status = XReadBitmapFile(dpy, scr->w_win, mask_name, &w, &h, + &mask, &x, &y); + bitmap_status = XReadBitmapFile(dpy, scr->w_win, bitmap_name, &w, &h, + &bitmap, &x, &y); + if ((BitmapSuccess == bitmap_status) && + (BitmapSuccess == mask_status)) + { + fg.pixel = scr->black_pixel; + bg.pixel = scr->white_pixel; + XQueryColor(dpy, scr->w_colormap, &fg); + XQueryColor(dpy, scr->w_colormap, &bg); + *cursor = XCreatePixmapCursor(dpy, bitmap, mask, &fg, &bg, x, y); + status = 1; + } + check_bitmap_status(bitmap_status, bitmap_name, bitmap); + check_bitmap_status(mask_status, mask_name, mask); + free(bitmap_name); + free(mask_name); + } + return(status); +} + +static int +getCursor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr, + void **ret) +{ + static Cursor cursor; + int status; + int changed = 0; + +again: + if (!PLIsArray(value)) + { + wwarning(_("Wrong option format for key \"%s\". Should be %s."), + entry->key, "cursor specification"); + if (!changed) + { + value = entry->plvalue; + changed = 1; + wwarning(_("using default \"%s\" instead"), entry->default_value); + goto again; + } + return(False); + } + status = parse_cursor(scr, value, &cursor); + if (!status) + { + wwarning(_("Error in cursor specification for key \"%s\""), entry->key); + if (!changed) + { + value = entry->plvalue; + changed = 1; + wwarning(_("using default \"%s\" instead"), entry->default_value); + goto again; + } + return(False); + } + if (ret) + { + *ret = &cursor; + } + if (addr) + { + *(Cursor *)addr = cursor; + } + return(True); +} +#undef CURSOR_ID_NONE + +#endif /* DEFINABLE_CURSOR */ + static int @@ -2447,7 +2767,6 @@ } - static int setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo) { @@ -2986,6 +3305,27 @@ { return REFRESH_MENU_TEXTURE; } + + +#ifdef DEFINABLE_CURSOR +static int +setCursor(WScreen *scr, WDefaultEntry *entry, Cursor *cursor, long index) +{ + if (None != wCursor[index]) + { + XFreeCursor(dpy, wCursor[index]); + } + + wCursor[index] = *cursor; + + if ((WCUR_ROOT == index) && (None != *cursor)) + { + XDefineCursor(dpy, scr->root_win, *cursor); + } + + return 0; +} +#endif /* DEFINABLE_CURSOR*/ /* --- ./src/WindowMaker.h.orig-defcursor Wed Apr 14 11:03:14 1999 +++ ./src/WindowMaker.h Sat Apr 24 01:46:48 1999 @@ -120,7 +120,12 @@ #define WCUR_ARROW 4 #define WCUR_QUESTION 5 #define WCUR_TEXT 6 +#ifdef DEFINABLE_CURSOR +#define WCUR_ROOT 7 +#define WCUR_LAST 8 +#else #define WCUR_LAST 7 +#endif /* geometry displays */ --- ./src/startup.c.orig-defcursor Wed Apr 21 07:16:08 1999 +++ ./src/startup.c Sat Apr 24 01:46:48 1999 @@ -708,7 +708,12 @@ /* cursors */ +#ifdef DEFINABLE_CURSOR + wCursor[WCUR_NORMAL] = None; + wCursor[WCUR_ROOT] = XCreateFontCursor(dpy, XC_left_ptr); +#else wCursor[WCUR_NORMAL] = XCreateFontCursor(dpy, XC_left_ptr); +#endif wCursor[WCUR_ARROW] = XCreateFontCursor(dpy, XC_top_left_arrow); wCursor[WCUR_MOVE] = XCreateFontCursor(dpy, XC_fleur); wCursor[WCUR_RESIZE] = XCreateFontCursor(dpy, XC_sizing);