From 41334b84d5de067701dbbfb8e666f32ac8da2522 Mon Sep 17 00:00:00 2001 From: kojima Date: Fri, 3 Mar 2000 20:55:35 +0000 Subject: [PATCH] added configurable cursor path added some GNUstep support code --- src/GNUstep.h | 2 - src/WindowMaker.h | 6 +- src/actions.c | 7 +- src/defaults.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dialog.c | 4 +- src/moveres.c | 6 +- src/screen.c | 2 + src/startup.c | 5 + src/wconfig.h.in | 6 + src/window.c | 3 +- src/window.h | 3 +- 11 files changed, 372 insertions(+), 13 deletions(-) diff --git a/src/GNUstep.h b/src/GNUstep.h index 9083f13b..d6b050b9 100644 --- a/src/GNUstep.h +++ b/src/GNUstep.h @@ -99,8 +99,6 @@ typedef struct { /* extra flags */ #define GSDocumentEditedFlag (1<<0) -#define GSWindowWillResizeNotificationsFlag (1<<1) -#define GSWindowWillMoveNotificationsFlag (1<<2) #define GSNoApplicationIconFlag (1<<5) diff --git a/src/WindowMaker.h b/src/WindowMaker.h index 5b78b3b0..12128579 100644 --- a/src/WindowMaker.h +++ b/src/WindowMaker.h @@ -128,8 +128,8 @@ typedef enum { #define WCUR_QUESTION 5 #define WCUR_TEXT 6 #define WCUR_SELECT 7 -#define WCUR_LAST 8 - +#define WCUR_ROOT 8 +#define WCUR_LAST 9 /* geometry displays */ #define WDIS_NEW 0 /* new style */ @@ -303,7 +303,7 @@ typedef struct WPreferences { char constrain_window_size; /* don't let windows get bigger than * screen */ - char circ_raise; /* raise window when Alt-tabbing */ + char circ_raise; /* raise window after Alt-tabbing */ char ignore_focus_click; diff --git a/src/actions.c b/src/actions.c index c17b409a..c12b067c 100644 --- a/src/actions.c +++ b/src/actions.c @@ -160,7 +160,7 @@ wSetFocusTo(WScreen *scr, WWindow *wwin) if (wwin == NULL) { XSetInputFocus(dpy, scr->no_focus_win, RevertToParent, timestamp); - if (old_focused) { + if (old_focused && !old_focused->flags.is_gnustep) { wWindowUnfocus(old_focused); } if (oapp) { @@ -174,7 +174,7 @@ wSetFocusTo(WScreen *scr, WWindow *wwin) wKWMSendEventMessage(NULL, WKWMFocusWindow); #endif return; - } else if(old_scr != scr && old_focused) { + } else if (old_scr != scr && old_focused && !old_focused->flags.is_gnustep) { wWindowUnfocus(old_focused); } @@ -237,7 +237,8 @@ wSetFocusTo(WScreen *scr, WWindow *wwin) } } - wWindowFocus(wwin, focused); + if (!wwin->flags.is_gnustep) + wWindowFocus(wwin, focused); if (napp && !wasfocused) { #ifdef USER_MENU diff --git a/src/defaults.c b/src/defaults.c index c5063f2d..d72d9f2b 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -186,6 +186,11 @@ static int setMultiByte(); static int updateUsableArea(); +#ifdef DEFINABLE_CURSOR +extern Cursor wCursor[WCUR_LAST]; +static int getCursor(); +static int setCursor(); +#endif /* @@ -792,6 +797,31 @@ WDefaultEntry optionList[] = { &wPreferences.modelock, getBool, NULL } #endif /* KEEP_XKB_LOCK_STATUS */ +#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 */ }; @@ -2401,6 +2431,296 @@ getRImages(WScreen *scr, WDefaultEntry *entry, proplist_t value, } #endif +#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 */ + /* ---------------- value setting functions --------------- */ static int @@ -3098,3 +3418,24 @@ setMultiByte(WScreen *scr, WDefaultEntry *entry, int *value, void *foo) return 0; } + +#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*/ + diff --git a/src/dialog.c b/src/dialog.c index 3473c4e7..cc29c21d 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -704,8 +704,8 @@ typedef struct { #define COPYRIGHT_TEXT \ - "Copyright \xa9 1997~1999 Alfredo K. Kojima \n"\ - "Copyright \xa9 1998,1999 Dan Pascu " + "Copyright \xa9 1997~2000 Alfredo K. Kojima \n"\ + "Copyright \xa9 1998~2000 Dan Pascu " diff --git a/src/moveres.c b/src/moveres.c index e8b9771e..83f8f8a6 100644 --- a/src/moveres.c +++ b/src/moveres.c @@ -1566,6 +1566,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev) (unsigned *) &junk); } else { WMMaskEvent(dpy, KeyPressMask | ButtonMotionMask + | PointerMotionHintMask | ButtonReleaseMask | ButtonPressMask | ExposureMask, &event); @@ -1856,7 +1857,8 @@ wMouseResizeWindow(WWindow *wwin, XEvent *ev) else h = 0; while (1) { - WMMaskEvent(dpy, KeyPressMask | ButtonMotionMask | ButtonReleaseMask + WMMaskEvent(dpy, KeyPressMask | ButtonMotionMask + | ButtonReleaseMask | PointerMotionHintMask | ButtonPressMask | ExposureMask, &event); if (!checkMouseSamplingRate(&event)) continue; @@ -1875,6 +1877,8 @@ wMouseResizeWindow(WWindow *wwin, XEvent *ev) case MotionNotify: if (started) { + while (XCheckMaskEvent(dpy, ButtonMotionMask, &event)) ; + dw = 0; dh = 0; diff --git a/src/screen.c b/src/screen.c index f7f61d76..c7b298a2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -705,7 +705,9 @@ wScreenInit(int screen_number) 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 | RC_StandardColormap; diff --git a/src/startup.c b/src/startup.c index fef44fa2..ae72b9e6 100644 --- a/src/startup.c +++ b/src/startup.c @@ -734,7 +734,12 @@ StartUp(Bool defaultScreenOnly) /* cursors */ +#ifdef DEFINABLE_CURSOR + wCursor[WCUR_NORMAL] = None; +#else wCursor[WCUR_NORMAL] = XCreateFontCursor(dpy, XC_left_ptr); +#endif + wCursor[WCUR_ROOT] = XCreateFontCursor(dpy, XC_left_ptr); wCursor[WCUR_ARROW] = XCreateFontCursor(dpy, XC_top_left_arrow); wCursor[WCUR_MOVE] = XCreateFontCursor(dpy, XC_fleur); wCursor[WCUR_RESIZE] = XCreateFontCursor(dpy, XC_sizing); diff --git a/src/wconfig.h.in b/src/wconfig.h.in index 83fc1ff8..382f06db 100644 --- a/src/wconfig.h.in +++ b/src/wconfig.h.in @@ -225,6 +225,12 @@ */ #undef GRADIENT_CLIP_ARROWS +/* + * 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 + /* *-------------------------------------------------------------------- diff --git a/src/window.c b/src/window.c index 36f2e25e..b18fb940 100644 --- a/src/window.c +++ b/src/window.c @@ -2478,7 +2478,8 @@ wWindowResetMouseGrabs(WWindow *wwin) GrabModeAsync, None, None); } - if (!wwin->flags.focused && !WFLAGP(wwin, no_focusable)) { + if (!wwin->flags.focused && !WFLAGP(wwin, no_focusable) + && !wwin->flags.is_gnustep) { /* the passive grabs to focus the window */ if (wPreferences.focus_mode == WKF_CLICK) XGrabButton(dpy, AnyButton, AnyModifier, wwin->client_win, diff --git a/src/window.h b/src/window.h index 56a9b055..fe100574 100644 --- a/src/window.h +++ b/src/window.h @@ -248,7 +248,8 @@ typedef struct WWindow { #endif /* info flags */ - unsigned int is_gnustep:1; + unsigned int is_gnustep:1; /* 1 if the window belongs to a GNUstep + app */ unsigned int buttons_dont_fit:1; unsigned int rebuild_texture:1;/* the window was resized and -- 2.11.4.GIT