From 6601199e2324bf03d3bede0a852683434198f2be Mon Sep 17 00:00:00 2001 From: Jaimos Skriletz Date: Wed, 17 Apr 2024 20:26:09 -0600 Subject: [PATCH 1/4] FvwmPager: Splitup large source files. Split up the two monolithic source FvwmPager.c and x_pager.c source files into smaller files to help manage the code. The new structure is. FvwmPager.c - main event loop fpmonitors.c - fpmonitor methods. init_pager.c - collection of all the initialization methods. messages.c - respond to messages from fvwm. x_pager.c - main still fairly large handling of the X windows that build the pager, this includes processing events and computing the position of all the windows. x_update.c - update_foo methods for x_pager.c to update locations and window graphics. --- modules/FvwmPager/FvwmPager.c | 1982 +++----------------------------- modules/FvwmPager/FvwmPager.h | 130 +-- modules/FvwmPager/Makefile.am | 3 +- modules/FvwmPager/fpmonitor.c | 165 +++ modules/FvwmPager/init_pager.c | 1283 +++++++++++++++++++++ modules/FvwmPager/messages.c | 982 ++++++++++++++++ modules/FvwmPager/x_pager.c | 1211 +------------------ modules/FvwmPager/x_update.c | 474 ++++++++ 8 files changed, 3136 insertions(+), 3094 deletions(-) create mode 100644 modules/FvwmPager/fpmonitor.c create mode 100644 modules/FvwmPager/init_pager.c create mode 100644 modules/FvwmPager/messages.c create mode 100644 modules/FvwmPager/x_update.c diff --git a/modules/FvwmPager/FvwmPager.c b/modules/FvwmPager/FvwmPager.c index 5bcf089ee..3cc14d0d1 100644 --- a/modules/FvwmPager/FvwmPager.c +++ b/modules/FvwmPager/FvwmPager.c @@ -24,7 +24,6 @@ #include #include #include -#include "libs/FScreen.h" #include "libs/ftime.h" #include "libs/safemalloc.h" #include @@ -34,12 +33,7 @@ #endif /* Saul */ #include "libs/Module.h" -#include "libs/fvwmlib.h" -#include "libs/FShape.h" -#include "libs/FRenderInit.h" #include "libs/FEvent.h" -#include "libs/Colorset.h" -#include "libs/Flocale.h" #include "libs/fvwmsignal.h" #include "libs/Grab.h" #include "libs/Parse.h" @@ -47,12 +41,11 @@ #include "libs/System.h" #include "fvwm/fvwm.h" +#include "libs/vpacket.h" #include "FvwmPager.h" /* - * * Shared variables. - * */ /* Colors, Pixmaps, Fonts, etc. */ char *smallFont = NULL; @@ -129,406 +122,182 @@ struct fpmonitors fp_monitor_q; static int x_fd; static fd_set_size_t fd_width; -static bool fp_new_block = false; -static void SetDeskLabel(int desk, const char *label); +static void Loop(int *fd); static RETSIGTYPE TerminateHandler(int); -static void list_monitor_focus(unsigned long *); -static struct fpmonitor *fpmonitor_new(struct monitor *); -static void fpmonitor_disable(struct fpmonitor *); -static void parse_monitor_line(char *); -static void parse_desktop_size_line(char *); -static void parse_desktop_configuration_line(char *); -static PagerWindow *find_pager_window(Window target_w); -static void update_monitor_to_track(struct fpmonitor **, char *, bool); - -struct fpmonitor * -fpmonitor_new(struct monitor *m) -{ - struct fpmonitor *fp; - - fp = fxcalloc(1, sizeof(*fp)); - if (HilightDesks) - fp->CPagerWin = fxcalloc(1, ndesks * sizeof(*fp->CPagerWin)); - else - fp->CPagerWin = NULL; - fp->m = m; - fp->disabled = false; - TAILQ_INSERT_TAIL(&fp_monitor_q, fp, entry); - - return (fp); -} - -void fpmonitor_disable(struct fpmonitor *fp) -{ - int i; - - fp->disabled = true; - for (i = 0; i < ndesks; i++) { - XMoveWindow(dpy, fp->CPagerWin[i], -32768,-32768); - } - - if (fp == monitor_to_track) - monitor_to_track = fpmonitor_this(NULL); - -} - -struct fpmonitor * -fpmonitor_by_name(const char *name) -{ - struct fpmonitor *fm; - - if (name == NULL || StrEquals(name, "none")) - return (NULL); - - TAILQ_FOREACH(fm, &fp_monitor_q, entry) { - if (fm->m != NULL && (strcmp(name, fm->m->si->name) == 0)) - return (fm); - } - return (NULL); -} - -struct fpmonitor * -fpmonitor_this(struct monitor *m_find) -{ - struct monitor *m; - struct fpmonitor *fp = NULL; +static int My_XNextEvent(Display *dpy, XEvent *event); - if (m_find != NULL) { - /* We've been asked to find a specific monitor. */ - m = m_find; - } else if (monitor_to_track != NULL) { - return (monitor_to_track); - } else { - m = monitor_get_current(); - } - - if (m == NULL || m->flags & MONITOR_DISABLED) - return (NULL); - TAILQ_FOREACH(fp, &fp_monitor_q, entry) { - if (fp->m == m) - return (fp); - } - return (NULL); - -} - -void initialize_colorsets(void) -{ - DeskStyle *style; - - TAILQ_FOREACH(style, &desk_style_q, entry) { - if (style->cs >= 0) { - style->fg = Colorset[style->cs].fg; - style->bg = Colorset[style->cs].bg; - } - if (style->hi_cs >= 0) { - style->hi_fg = Colorset[style->hi_cs].fg; - style->hi_bg = Colorset[style->hi_cs].bg; - } - } -} - -/* - * - * Procedure: - * main - start of module - * - */ +/* Procedure: main - start of module */ int main(int argc, char **argv) { - char *display_name = NULL; - int itemp,i; - short opt_num; - Window JunkRoot, JunkChild; - int JunkX, JunkY; - unsigned JunkMask; - struct monitor *mon; - - FlocaleInit(LC_CTYPE, "", "", "FvwmPager"); - - /* Tell the FEvent module an event type that is not used by fvwm. */ - fev_init_invalid_event_type(KeymapNotify); + short opt_num; - /* Save our program name - for error messages */ - MyName = GetFileNameFromPath(argv[0]); + /* Save our program name */ + MyName = GetFileNameFromPath(argv[0]); - if(argc < 6) - { - fvwm_debug(__func__, "%s Version %s should only be executed by fvwm!\n", - MyName, - VERSION); - exit(1); - } - - TAILQ_INIT(&fp_monitor_q); - TAILQ_INIT(&desk_style_q); + if (argc < 6) { + fprintf(stderr, "%s must be executed by fvwm!\n", MyName), + exit(1); + } #ifdef HAVE_SIGACTION - { - struct sigaction sigact; - - sigemptyset(&sigact.sa_mask); - sigaddset(&sigact.sa_mask, SIGPIPE); - sigaddset(&sigact.sa_mask, SIGTERM); - sigaddset(&sigact.sa_mask, SIGQUIT); - sigaddset(&sigact.sa_mask, SIGINT); - sigaddset(&sigact.sa_mask, SIGHUP); + { + struct sigaction sigact; + + sigemptyset(&sigact.sa_mask); + sigaddset(&sigact.sa_mask, SIGPIPE); + sigaddset(&sigact.sa_mask, SIGTERM); + sigaddset(&sigact.sa_mask, SIGQUIT); + sigaddset(&sigact.sa_mask, SIGINT); + sigaddset(&sigact.sa_mask, SIGHUP); # ifdef SA_INTERRUPT - sigact.sa_flags = SA_INTERRUPT; + sigact.sa_flags = SA_INTERRUPT; # else - sigact.sa_flags = 0; + sigact.sa_flags = 0; # endif - sigact.sa_handler = TerminateHandler; + sigact.sa_handler = TerminateHandler; - sigaction(SIGPIPE, &sigact, NULL); - sigaction(SIGTERM, &sigact, NULL); - sigaction(SIGQUIT, &sigact, NULL); - sigaction(SIGINT, &sigact, NULL); - sigaction(SIGHUP, &sigact, NULL); - } + sigaction(SIGPIPE, &sigact, NULL); + sigaction(SIGTERM, &sigact, NULL); + sigaction(SIGQUIT, &sigact, NULL); + sigaction(SIGINT, &sigact, NULL); + sigaction(SIGHUP, &sigact, NULL); + } #else - /* We don't have sigaction(), so fall back to less robust methods. */ + /* We don't have sigaction(), so fall back to less robust methods. */ #ifdef USE_BSD_SIGNALS - fvwmSetSignalMask( sigmask(SIGPIPE) | - sigmask(SIGTERM) | - sigmask(SIGQUIT) | - sigmask(SIGINT) | - sigmask(SIGHUP) ); + fvwmSetSignalMask(sigmask(SIGPIPE) | + sigmask(SIGTERM) | + sigmask(SIGQUIT) | + sigmask(SIGINT) | + sigmask(SIGHUP)); #endif - signal(SIGPIPE, TerminateHandler); - signal(SIGTERM, TerminateHandler); - signal(SIGQUIT, TerminateHandler); - signal(SIGINT, TerminateHandler); - signal(SIGHUP, TerminateHandler); + + signal(SIGPIPE, TerminateHandler); + signal(SIGTERM, TerminateHandler); + signal(SIGQUIT, TerminateHandler); + signal(SIGINT, TerminateHandler); + signal(SIGHUP, TerminateHandler); + #ifdef HAVE_SIGINTERRUPT - siginterrupt(SIGPIPE, 1); - siginterrupt(SIGTERM, 1); - siginterrupt(SIGQUIT, 1); - siginterrupt(SIGINT, 1); - siginterrupt(SIGHUP, 1); + siginterrupt(SIGPIPE, 1); + siginterrupt(SIGTERM, 1); + siginterrupt(SIGQUIT, 1); + siginterrupt(SIGINT, 1); + siginterrupt(SIGHUP, 1); #endif #endif - fd[0] = atoi(argv[1]); - fd[1] = atoi(argv[2]); - - fd_width = GetFdWidth(); - - opt_num = 6; - if (argc >= 7 && (StrEquals(argv[opt_num], "-transient") || - StrEquals(argv[opt_num], "transient"))) - { - opt_num++; - is_transient = true; - do_ignore_next_button_release = true; - } - - /* Check for an alias */ - if (argc >= opt_num + 1) - { - char *s; + /* Parse command line options */ + fd[0] = atoi(argv[1]); + fd[1] = atoi(argv[2]); + fd_width = GetFdWidth(); - if (!StrEquals(argv[opt_num], "*")) - { - for (s = argv[opt_num]; *s; s++) + opt_num = 6; + if (argc >= 7 && (StrEquals(argv[opt_num], "-transient") || + StrEquals(argv[opt_num], "transient"))) { - if (!isdigit(*s) && - (*s != '-' || s != argv[opt_num] || *(s+1) == 0)) - { - free(MyName); - MyName = fxstrdup(argv[opt_num]); - opt_num++; - break; - } + opt_num++; + is_transient = true; + do_ignore_next_button_release = true; + } + + /* Check for an alias */ + if (argc >= opt_num + 1) { + char *s; + + if (!StrEquals(argv[opt_num], "*")) { + for (s = argv[opt_num]; *s; s++) { + if (!isdigit(*s) && (*s != '-' || + s != argv[opt_num] || *(s+1) == 0)) + { + free(MyName); + MyName = fxstrdup(argv[opt_num]); + opt_num++; + break; + } + } + } } - } - } - if (argc < opt_num + 1) - { - desk1 = 0; - desk2 = 0; - } - else if (StrEquals(argv[opt_num], "*")) - { - desk1 = 0; - desk2 = 0; - fAlwaysCurrentDesk = true; - } - else - { - desk1 = atoi(argv[opt_num]); - if (argc == opt_num+1) - desk2 = desk1; - else - desk2 = atoi(argv[opt_num+1]); - if(desk2 < desk1) - { - itemp = desk1; - desk1 = desk2; - desk2 = itemp; + /* Determine which desks to show. */ + if (argc < opt_num + 1) { + desk1 = desk2 = 0; + } else if (StrEquals(argv[opt_num], "*")) { + desk1 = desk2 = 0; + fAlwaysCurrentDesk = true; + } else { + desk1 = atoi(argv[opt_num]); + if (argc == opt_num+1) + desk2 = desk1; + else + desk2 = atoi(argv[opt_num+1]); + if (desk1 < 0) + desk1 = 0; + if (desk2 < 0) + desk2 = 0; + if (desk2 < desk1) { + int dtemp = desk1; + desk1 = desk2; + desk2 = dtemp; + } } - } - ndesks = desk2 - desk1 + 1; - - /* Initialize X connection */ - if (!(dpy = XOpenDisplay(display_name))) - { - fvwm_debug(__func__, "%s: can't open display %s", MyName, - XDisplayName(display_name)); - exit (1); - } - - flib_init_graphics(dpy); - - x_fd = XConnectionNumber(dpy); - - Scr.screen = DefaultScreen(dpy); - Scr.Root = RootWindow(dpy, Scr.screen); - /* make a temp window for any pixmaps, deleted later */ - initialize_viz_pager(); - - /* Initialize default DeskStyle, stored on desk -1. */ - { - DeskStyle *default_style; - - default_style = fxcalloc(1, sizeof(DeskStyle)); - default_style->desk = -1; - default_style->label = fxstrdup("-"); - - default_style->use_label_pixmap = true; - default_style->cs = -1; - default_style->hi_cs = -1; - default_style->win_cs = -1; - default_style->focus_cs = -1; - default_style->balloon_cs = -1; - default_style->fg = GetSimpleColor("black"); - default_style->bg = GetSimpleColor("white"); - default_style->hi_fg = GetSimpleColor("black"); - default_style->hi_bg = GetSimpleColor("grey"); - default_style->win_fg = None; /* Use fvwm pixel unless defined. */ - default_style->win_bg = None; - default_style->focus_fg = None; - default_style->focus_bg = None; - default_style->balloon_fg = None; - default_style->balloon_bg = None; - default_style->balloon_border = None; - default_style->bgPixmap = NULL; - default_style->hiPixmap = NULL; - TAILQ_INSERT_TAIL(&desk_style_q, default_style, entry); - } + ndesks = desk2 - desk1 + 1; + + /* Tell the FEvent module an event type that is not used by fvwm. */ + /* Is this needed, I don't see this event being used. */ + fev_init_invalid_event_type(KeymapNotify); + + SetMessageMask(fd, + M_VISIBLE_NAME | + M_ADD_WINDOW| + M_CONFIGURE_WINDOW| + M_DESTROY_WINDOW| + M_FOCUS_CHANGE| + M_NEW_PAGE| + M_NEW_DESK| + M_RAISE_WINDOW| + M_LOWER_WINDOW| + M_ICONIFY| + M_ICON_LOCATION| + M_DEICONIFY| + M_RES_NAME| + M_RES_CLASS| + M_CONFIG_INFO| + M_END_CONFIG_INFO| + M_MINI_ICON| + M_END_WINDOWLIST| + M_RESTACK|M_STRING); + SetMessageMask(fd, + MX_VISIBLE_ICON_NAME| + MX_PROPERTY_CHANGE| + MX_MONITOR_FOCUS); + + /* Initialize X connection */ + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "%s: can't open display", MyName); + exit(1); + } + flib_init_graphics(dpy); + x_fd = XConnectionNumber(dpy); + Scr.screen = DefaultScreen(dpy); + Scr.Root = RootWindow(dpy, Scr.screen); + + /* Initialize pager components. */ + init_fvwm_pager(); + + /* tell fvwm we're running */ + SendFinishedStartupNotification(fd); + + /* Event loop */ + Loop(fd); - SetMessageMask(fd, - M_VISIBLE_NAME | - M_ADD_WINDOW| - M_CONFIGURE_WINDOW| - M_DESTROY_WINDOW| - M_FOCUS_CHANGE| - M_NEW_PAGE| - M_NEW_DESK| - M_RAISE_WINDOW| - M_LOWER_WINDOW| - M_ICONIFY| - M_ICON_LOCATION| - M_DEICONIFY| - M_RES_NAME| - M_RES_CLASS| - M_CONFIG_INFO| - M_END_CONFIG_INFO| - M_MINI_ICON| - M_END_WINDOWLIST| - M_RESTACK|M_STRING); - SetMessageMask(fd, - MX_VISIBLE_ICON_NAME| - MX_PROPERTY_CHANGE| - MX_MONITOR_FOCUS); - - RB_FOREACH(mon, monitors, &monitor_q) - (void)fpmonitor_new(mon); - - Desks = fxcalloc(1, ndesks*sizeof(DeskInfo)); - for(i = 0; i < ndesks; i++) - { - Desks[i].style = FindDeskStyle(i); - Desks[i].fp = fpmonitor_from_desk(i + desk1); - } - - ParseOptions(); - if (is_transient) - { - FQueryPointer( - dpy, Scr.Root, &JunkRoot, &JunkChild, &pwindow.x, &pwindow.y, &JunkX, - &JunkY, &JunkMask); - usposition = false; - xneg = false; - yneg = false; - } - - if (WindowLabelFormat == NULL) - WindowLabelFormat = fxstrdup("%i"); - - /* Create a list of all windows */ - /* Request a list of all windows, - * wait for ConfigureWindow packets */ - SendInfo(fd,"Send_WindowList",0); - - /* open a pager window */ - initialize_colorsets(); - initialise_common_pager_fragments(); - initialize_pager(); - - if (is_transient) - { - bool is_pointer_grabbed = false; - bool is_keyboard_grabbed = false; - XSync(dpy,0); - for (i = 0; i < 50 && !(is_pointer_grabbed && is_keyboard_grabbed); i++) - { - if (!is_pointer_grabbed && - XGrabPointer( - dpy, Scr.Root, true, - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| - PointerMotionMask|EnterWindowMask|LeaveWindowMask, GrabModeAsync, - GrabModeAsync, None, None, CurrentTime) == GrabSuccess) - { - is_pointer_grabbed = true; - } - if (!is_keyboard_grabbed && - XGrabKeyboard( - dpy, Scr.Root, true, GrabModeAsync, GrabModeAsync, CurrentTime) == - GrabSuccess) - { - is_keyboard_grabbed = true; - } - /* If you go too fast, other windows may not get a change to release - * any grab that they have. */ - usleep(20000); - } - if (!is_pointer_grabbed) - { - XBell(dpy, 0); - fvwm_debug(__func__, - "%s: could not grab pointer in transient mode. exiting.\n", - MyName); - exit(1); - } - - XSync(dpy,0); - } - - /* tell fvwm we're running */ - SendFinishedStartupNotification(fd); - - Loop(fd); #ifdef FVWM_DEBUG_MSGS - if ( isTerminated ) - { - fvwm_debug(__func__, "%s: Received signal: exiting...\n", MyName); - } + if (isTerminated) + fprintf(stderr, "%s: Received signal: exiting...\n", MyName); #endif - return 0; + return 0; } /* @@ -564,120 +333,6 @@ void Loop(int *fd) } -/* - * Procedure: - * Process message - examines packet types, and takes appropriate action - */ -void process_message(FvwmPacket* packet) -{ - unsigned long type = packet->type; - unsigned long length = packet->size; - unsigned long* body = packet->body; - - switch (type) - { - case M_ADD_WINDOW: - list_configure(body); - break; - case M_CONFIGURE_WINDOW: - list_configure(body); - break; - case M_DESTROY_WINDOW: - list_destroy(body); - break; - case M_FOCUS_CHANGE: - list_focus(body); - break; - case M_NEW_PAGE: - list_new_page(body); - break; - case M_NEW_DESK: - list_new_desk(body); - break; - case M_RAISE_WINDOW: - list_raise(body); - break; - case M_LOWER_WINDOW: - list_lower(body); - break; - case M_ICONIFY: - case M_ICON_LOCATION: - list_iconify(body); - break; - case M_DEICONIFY: - list_deiconify(body, length); - break; - case M_RES_CLASS: - case M_RES_NAME: - case M_VISIBLE_NAME: - list_window_name(body, type); - break; - case MX_VISIBLE_ICON_NAME: - list_icon_name(body); - break; - case M_MINI_ICON: - list_mini_icon(body); - break; - case M_END_WINDOWLIST: - list_end(); - break; - case M_RESTACK: - list_restack(body, length); - break; - case M_CONFIG_INFO: - list_config_info(body); - break; - case MX_PROPERTY_CHANGE: - list_property_change(body); - break; - case MX_MONITOR_FOCUS: - list_monitor_focus(body); - break; - case MX_REPLY: - list_reply(body); - break; - case M_STRING: { - char *this = (char *)&body[3]; - char *token; - char *rest = GetNextToken(this, &token); - - if (rest != NULL && StrEquals(token, "Monitor")) { - update_monitor_to_track( - &monitor_to_track, rest, true); - } else if (StrEquals(token, "CurrentMonitor")) { - update_monitor_to_track( - ¤t_monitor, rest, false); - } else if (StrEquals(token, "DeskLabels")) { - use_desk_label = true; - } else if (StrEquals(token, "NoDeskLabels")) { - use_desk_label = false; - } else if (StrEquals(token, "MonitorLabels")) { - use_monitor_label = true; - } else if (StrEquals(token, "NoMonitorLabels")) { - use_monitor_label = false; - } - else if (StrEquals(token, "CurrentDeskPerMonitor")) { - CurrentDeskPerMonitor = true; - } else if (StrEquals(token, "CurrentDeskGlobal")) { - CurrentDeskPerMonitor = false; - } else if (StrEquals(token, "IsShared")) { - IsShared = true; - } else if (StrEquals(token, "IsNotShared")) { - IsShared = false; - } else { - break; - } - set_desk_size(true); - ReConfigure(); - break; - } - default: - /* ignore unknown packet */ - break; - } -} - - /* * Procedure: * SIGPIPE handler - SIGPIPE means fvwm is dying @@ -688,667 +343,14 @@ static RETSIGTYPE TerminateHandler(int sig) SIGNAL_RETURN; } +#if 0 +/* Is this used? */ RETSIGTYPE DeadPipe(int nonsense) { exit(0); SIGNAL_RETURN; } - -/* Convince method to find target window. */ -PagerWindow *find_pager_window(Window target_w) -{ - PagerWindow *t; - - t = Start; - while(t != NULL && t->w != target_w) - t = t->next; - - return t; -} - -/* - * Procedure: - * handle_config_win_package - updates a PagerWindow - * with respect to a ConfigWinPacket - */ -void handle_config_win_package(PagerWindow *t, - ConfigWinPacket *cfgpacket) -{ - if (t->w != None && t->w != cfgpacket->w) - { - /* Should never happen */ - fvwm_debug(__func__, - "%s: Error: Internal window list corrupt\n",MyName); - /* might be a good idea to exit here */ - return; - } - t->w = cfgpacket->w; - t->frame = cfgpacket->frame; - t->frame_x = cfgpacket->frame_x; - t->frame_y = cfgpacket->frame_y; - t->frame_width = cfgpacket->frame_width; - t->frame_height = cfgpacket->frame_height; - t->m = monitor_by_output(cfgpacket->monitor_id); - - t->desk = cfgpacket->desk; - - t->title_height = cfgpacket->title_height; - t->border_width = cfgpacket->border_width; - - t->icon_w = cfgpacket->icon_w; - t->icon_pixmap_w = cfgpacket->icon_pixmap_w; - - memcpy(&(t->flags), &(cfgpacket->flags), sizeof(cfgpacket->flags)); - memcpy(&(t->allowed_actions), &(cfgpacket->allowed_actions), - sizeof(cfgpacket->allowed_actions)); - - /* These are used for windows if no pixel is set. */ - t->text = cfgpacket->TextPixel; - t->back = cfgpacket->BackPixel; - - if (IS_ICONIFIED(t)) - { - /* For new windows icon_x and icon_y will be zero until - * iconify message is recived - */ - t->x = t->icon_x; - t->y = t->icon_y; - t->width = t->icon_width; - t->height = t->icon_height; - if(IS_ICON_SUPPRESSED(t) || t->width == 0 || t->height == 0) - { - t->x = -32768; - t->y = -32768; - } - } - else - { - t->x = t->frame_x; - t->y = t->frame_y; - t->width = t->frame_width; - t->height = t->frame_height; - } -} - -void list_add(unsigned long *body) -{ - PagerWindow *t, **prev; - struct ConfigWinPacket *cfgpacket = (void *)body; - - t = Start; - prev = &Start; - - while(t != NULL) - { - if (t->w == cfgpacket->w) - { - /* it's already there, do nothing */ - return; - } - prev = &(t->next); - t = t->next; - } - *prev = fxcalloc(1, sizeof(PagerWindow)); - handle_config_win_package(*prev, cfgpacket); - AddNewWindow(*prev); - - return; -} - -void list_configure(unsigned long *body) -{ - PagerWindow *t; - struct ConfigWinPacket *cfgpacket = (void *)body; - bool is_new_desk; - - t = find_pager_window(cfgpacket->w); - if (t == NULL) - { - list_add(body); - return; - } - - is_new_desk = (t->desk != cfgpacket->desk); - handle_config_win_package(t, cfgpacket); - if (is_new_desk) - ChangeDeskForWindow(t, cfgpacket->desk); - MoveResizePagerView(t, true); -} - -void list_destroy(unsigned long *body) -{ - PagerWindow *t, **prev; - Window target_w; - - target_w = body[0]; - t = Start; - prev = &Start; - while(t != NULL && t->w != target_w) - { - prev = &(t->next); - t = t->next; - } - - if(t != NULL) - { - if(prev != NULL) - *prev = t->next; - /* remove window from the chain */ - - XDestroyWindow(dpy, t->PagerView); - XDestroyWindow(dpy, t->IconView); - if(FocusWin == t) - FocusWin = NULL; - - free(t->res_class); - free(t->res_name); - free(t->window_name); - free(t->icon_name); - free(t->window_label); - free(t); - } -} - -void list_monitor_focus(unsigned long *body) -{ - return; -} - -void list_focus(unsigned long *body) -{ - PagerWindow *t = find_pager_window(body[0]); - bool do_force_update = false; - - /* Update Pixels data. */ - if (Scr.focus_win_fg != body[3] || Scr.focus_win_bg != body[4]) - do_force_update = true; - Scr.focus_win_fg = body[3]; - Scr.focus_win_bg = body[4]; - - if (do_force_update || t != FocusWin) { - PagerWindow *focus = FocusWin; - FocusWin = t; - - update_window_background(focus); - update_window_background(t); - } -} - -void list_new_page(unsigned long *body) -{ - bool do_reconfigure = false; - int mon_num = body[7]; - struct monitor *m; - struct fpmonitor *fp; - - m = monitor_by_output(mon_num); - /* Don't allow monitor_by_output to fallback to RB_MIN. */ - if (m->si->rr_output != mon_num) - return; - - /* Still need to update the monitors when tracking a single - * monitor, but don't need to reconfigure anything. - */ - if (monitor_to_track != NULL && m == monitor_to_track->m) { - fp = monitor_to_track; - do_reconfigure = true; - } else { - fp = fpmonitor_this(m); - if (fp == NULL) - return; - do_reconfigure = true; - } - - fp->virtual_scr.Vx = fp->m->virtual_scr.Vx = body[0]; - fp->virtual_scr.Vy = fp->m->virtual_scr.Vy = body[1]; - if (fp->m->virtual_scr.CurrentDesk != body[2]) { - /* first handle the new desk */ - body[0] = body[2]; - body[1] = mon_num; - list_new_desk(body); - } - if (fp->virtual_scr.VxPages != body[5] || fp->virtual_scr.VyPages != body[6]) - { - fp->virtual_scr.VxPages = body[5]; - fp->virtual_scr.VyPages = body[6]; - fp->virtual_scr.VWidth = fp->virtual_scr.VxPages * fpmonitor_get_all_widths(); - fp->virtual_scr.VHeight = fp->virtual_scr.VyPages * fpmonitor_get_all_heights(); - fp->virtual_scr.VxMax = fp->virtual_scr.VWidth - fpmonitor_get_all_widths(); - fp->virtual_scr.VyMax = fp->virtual_scr.VHeight - fpmonitor_get_all_heights(); - if (do_reconfigure) - ReConfigure(); - } - - if (do_reconfigure) { - MovePage(); - MoveStickyWindows(true, false); - update_window_background(FocusWin); - } -} - -void list_new_desk(unsigned long *body) -{ - int oldDesk, newDesk; - int mon_num = body[1]; - struct monitor *mout; - struct fpmonitor *fp; - DeskStyle *style; - - mout = monitor_by_output(mon_num); - /* Don't allow monitor_by_output to fallback to RB_MIN. */ - if (mout->si->rr_output != mon_num) - return; - - fp = fpmonitor_this(mout); - if (fp == NULL) - return; - - /* Best to update the desk, even if the monitor isn't being - * tracked, as this could change. - */ - oldDesk = fp->m->virtual_scr.CurrentDesk; - newDesk = fp->m->virtual_scr.CurrentDesk = (long)body[0]; - if (newDesk >= desk1 && newDesk <= desk2) - Desks[newDesk - desk1].fp = fp; - - /* Only update FvwmPager's desk for the monitors being tracked. - * Exceptions: - * + If CurrentDeskPerMonitor is set, always update desk. - * + If current_monitor is set, only update if that monitor changes - * and tracking is per-monitor or shared. - */ - if (!CurrentDeskPerMonitor && ((monitor_to_track != NULL && - mout != monitor_to_track->m) || - (current_monitor != NULL && - monitor_to_track == NULL && - mout != current_monitor->m && - (monitor_mode == MONITOR_TRACKING_M || - is_tracking_shared)))) - { - /* Still need to update monitor location of other monitors. */ - if (current_monitor != NULL && oldDesk != newDesk) - goto update_grid; - return; - } - - /* Update the current desk. */ - desk_i = newDesk; - style = FindDeskStyle(newDesk); - /* Create and update GCs if needed. */ - if (oldDesk != newDesk) { - if (style->label_gc) - update_desk_style_gcs(style); - else - initialize_desk_style_gcs(style); - } - - /* Keep monitors in sync when tracking is global. */ - if (monitor_mode == MONITOR_TRACKING_G) - monitor_assign_virtual(fp->m); - - /* If always tracking current desk. Update Desks[0]. */ - if (fAlwaysCurrentDesk && oldDesk != newDesk) - { - PagerWindow *t; - - desk1 = desk2 = newDesk; - for (t = Start; t != NULL; t = t->next) - { - if (t->desk == oldDesk || t->desk == newDesk) - ChangeDeskForWindow(t, t->desk); - } - - /* Update DeskStyle */ - Desks[0].style = style; - update_desk_background(0); - update_monitor_locations(0); - update_monitor_backgrounds(0); - ReConfigureAll(); - } - - XStoreName(dpy, Scr.pager_w, style->label); - XSetIconName(dpy, Scr.pager_w, style->label); - -update_grid: - MovePage(); - draw_desk_grid(oldDesk - desk1); - draw_desk_grid(newDesk - desk1); - MoveStickyWindows(false, true); - update_window_background(FocusWin); -} - -void list_raise(unsigned long *body) -{ - PagerWindow *t = find_pager_window(body[0]); - - if (t == NULL) - return; - - XRaiseWindow(dpy, t->PagerView); - XRaiseWindow(dpy, t->IconView); -} - -void list_lower(unsigned long *body) -{ - struct fpmonitor *fp; - PagerWindow *t = find_pager_window(body[0]); - - if (t == NULL) - return; - - XLowerWindow(dpy, t->PagerView); - if (HilightDesks && t->desk >= desk1 && t->desk <= desk2) { - TAILQ_FOREACH(fp, &fp_monitor_q, entry) { - XLowerWindow(dpy, fp->CPagerWin[t->desk - desk1]); - } - } - XLowerWindow(dpy, t->IconView); -} - -void list_iconify(unsigned long *body) -{ - PagerWindow *t = find_pager_window(body[0]); - - if (t == NULL) - return; - - t->frame = body[1]; - t->icon_x = body[3]; - t->icon_y = body[4]; - t->icon_width = body[5]; - t->icon_height = body[6]; - SET_ICONIFIED(t, true); - if (IS_ICON_SUPPRESSED(t) || t->icon_width == 0 || - t->icon_height == 0) - { - t->x = -32768; - t->y = -32768; - } - else - { - t->x = t->icon_x; - t->y = t->icon_y; - } - t->width = t->icon_width; - t->height = t->icon_height; - - /* if iconifying main pager window turn balloons on or off */ - if (t->w == Scr.pager_w) - Balloon.show = Balloon.show_in_icon; - MoveResizePagerView(t, true); -} - -void list_deiconify(unsigned long *body, unsigned long length) -{ - PagerWindow *t = find_pager_window(body[0]); - - if (t == NULL) - return; - - SET_ICONIFIED(t, false); - if (length >= 11 + FvwmPacketHeaderSize) - { - t->frame_x = body[7]; - t->frame_y = body[8]; - t->frame_width = body[9]; - t->frame_height = body[10]; - } - t->x = t->frame_x; - t->y = t->frame_y; - t->width = t->frame_width; - t->height = t->frame_height; - - /* if deiconifying main pager window turn balloons on or off */ - if (t->w == Scr.pager_w) - Balloon.show = Balloon.show_in_pager; - - MoveResizePagerView(t, true); -} - -void list_window_name(unsigned long *body, unsigned long type) -{ - PagerWindow *t = find_pager_window(body[0]); - - if (t == NULL) - return; - - switch (type) { - case M_RES_CLASS: - free(t->res_class); - CopyString(&t->res_class, (char *)(&body[3])); - break; - case M_RES_NAME: - free(t->res_name); - CopyString(&t->res_name, (char *)(&body[3])); - break; - case M_VISIBLE_NAME: - free(t->window_name); - CopyString(&t->window_name, (char *)(&body[3])); - break; - } - - /* repaint by clearing window */ - if (FwindowFont != NULL && t->icon_name != NULL && - !(MiniIcons && t->mini_icon.picture)) - { - XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); - XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); - } - if (Balloon.is_mapped) - { - /* update balloons */ - UnmapBalloonWindow(); - MapBalloonWindow(t, Balloon.is_icon); - } -} - -void list_icon_name(unsigned long *body) -{ - PagerWindow *t = find_pager_window(body[0]); - - if (t == NULL) - return; - - free(t->icon_name); - CopyString(&t->icon_name, (char *)(&body[3])); - /* repaint by clearing window */ - if (FwindowFont != NULL && t->icon_name != NULL && - !(MiniIcons && t->mini_icon.picture)) - { - XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); - XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); - } -} - -void list_mini_icon(unsigned long *body) -{ - MiniIconPacket *mip = (MiniIconPacket *) body; - PagerWindow *t = find_pager_window(mip->w); - - if (t == NULL) - return; - - t->mini_icon.width = mip->width; - t->mini_icon.height = mip->height; - t->mini_icon.depth = mip->depth; - t->mini_icon.picture = mip->picture; - t->mini_icon.mask = mip->mask; - t->mini_icon.alpha = mip->alpha; - /* repaint by clearing window */ - if (MiniIcons && t->mini_icon.picture) { - XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); - XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); - } -} - -void list_restack(unsigned long *body, unsigned long length) -{ - PagerWindow *t; - PagerWindow *pager_wins[length]; - Window *wins; - int i, j, desk; - - wins = fxmalloc(length * sizeof (Window)); - - /* Should figure out how to do this with a single loop of the list, - * not one per desk + icon window. - */ - - /* first restack in the icon view */ - j = 0; - for (i = 0; i < (length - FvwmPacketHeaderSize); i += 3) - { - t = find_pager_window(body[i]); - if (t != NULL) { - pager_wins[j] = t; - wins[j++] = t->IconView; - } - } - XRestackWindows(dpy, wins, j); - length = j; - - /* now restack each desk separately, since they have separate roots */ - for (desk = 0; desk < ndesks; desk++) - { - j = 0; - for (i = 0; i < length; i++) - { - t = pager_wins[i]; - if (t != NULL && t->desk == desk + desk1) - wins[j++] = t->PagerView; - } - XRestackWindows(dpy, wins, j); - } - - free(wins); -} - -void list_end(void) -{ - unsigned int nchildren, i; - Window root, parent, *children; - PagerWindow *ptr; - - if (!XQueryTree(dpy, Scr.Root, &root, &parent, &children, &nchildren)) - return; - - for(i = 0; i < nchildren; i++) - { - ptr = Start; - while(ptr != NULL) - { - if (ptr->frame == children[i] || - ptr->icon_w == children[i] || - ptr->icon_pixmap_w == children[i]) - { - XRaiseWindow(dpy, ptr->PagerView); - XRaiseWindow(dpy, ptr->IconView); - } - ptr = ptr->next; - } - } - - if (nchildren > 0) - XFree((char *)children); -} - -void list_config_info(unsigned long *body) -{ - struct fpmonitor *m; - char *tline, *token; - - tline = (char*)&(body[3]); - token = PeekToken(tline, &tline); - if (StrEquals(token, "Colorset")) - { - int color; - DeskStyle *style; - - color = LoadColorset(tline); - TAILQ_FOREACH(style, &desk_style_q, entry) { - if (style->cs == color || style->hi_cs == color) - { - update_desk_style_gcs(style); - if (style->desk < desk1 || style->desk > desk2) - continue; - - update_desk_background(style->desk - desk1); - update_monitor_backgrounds(style->desk - desk1); - } - if (style->win_cs == color || style->focus_cs == color) { - PagerWindow *t = Start; - - update_desk_style_gcs(style); - while (t != NULL) { - if (t->desk != style->desk) { - t = t->next; - continue; - } - update_desk_style_gcs(style); - update_window_background(t); - update_window_decor(t); - t = t->next; - } - } - } - } - else if (StrEquals(token, "DesktopName")) - { - int val; - if (GetIntegerArguments(tline, &tline, &val, 1) > 0) - { - SetDeskLabel(val, (const char *)tline); - } - else - { - return; - } - if (fAlwaysCurrentDesk) - { - TAILQ_FOREACH(m, &fp_monitor_q, entry) { - if (m->m->virtual_scr.CurrentDesk == val) - val = 0; - } - } - else if ((val >= desk1) && (val <=desk2)) - { - val = val - desk1; - } - draw_desk_grid(val); - } else if (StrEquals(token, "Monitor")) { - parse_monitor_line(tline); - ReConfigure(); - } else if (StrEquals(token, "DesktopSize")) { - parse_desktop_size_line(tline); - } else if (StrEquals(token, "DesktopConfiguration")) { - parse_desktop_configuration_line(tline); - } -} - -void list_property_change(unsigned long *body) -{ - if (body[0] == MX_PROPERTY_CHANGE_BACKGROUND) - { - if (((!Swallowed && body[2] == 0) || - (Swallowed && body[2] == Scr.pager_w))) - update_pr_transparent_windows(); - } - else if (body[0] == MX_PROPERTY_CHANGE_SWALLOW && - body[2] == Scr.pager_w) - { - Swallowed = body[1]; - } -} - - -void list_reply(unsigned long *body) -{ - char *tline; - tline = (char*)&(body[3]); - - if (strcmp(tline, "ScrollDone") == 0) - HandleScrollDone(); -} +#endif /* * @@ -1391,688 +393,6 @@ int My_XNextEvent(Display *dpy, XEvent *event) return 0; } - - -/* This function is really tricky. An offset of the colorset members - * in the DeskStyle strut is used to set the desired colorset. - * The lines accessing this info look very ugly, but they work. - */ -static void SetDeskStyleColorset(char *arg1, char *arg2, void *offset_style) -{ - int colorset = 0; - int desk; - unsigned long offset = (unsigned long)offset_style; - DeskStyle *style; - - sscanf(arg2, "%d", &colorset); - AllocColorset(colorset); - if (arg1[0] == '*') { - TAILQ_FOREACH(style, &desk_style_q, entry) { - *(int *)(((char *)style) + offset) = colorset; - } - } else { - desk = desk1; - sscanf(arg1, "%d", &desk); - - style = FindDeskStyle(desk); - *(int *)(((char *)style) + offset) = colorset; - } - - return; -} - -static void SetDeskStylePixel(char *arg1, char *arg2, void *offset_style) -{ - int desk; - unsigned long offset = (unsigned long)offset_style; - DeskStyle *style; - Pixel pix; - - pix = GetSimpleColor(arg2); - if (arg1[0] == '*') { - TAILQ_FOREACH(style, &desk_style_q, entry) { - *(unsigned long *)(((char *)style) + offset) = pix; - } - } else { - desk = desk1; - sscanf(arg1, "%d", &desk); - - style = FindDeskStyle(desk); - *(unsigned long *)(((char *)style) + offset) = pix; - } - - return; -} - -static void SetDeskStyleBool(char *arg1, char *arg2, void *offset_style) -{ - int desk; - unsigned long offset = (unsigned long)offset_style; - DeskStyle *style; - bool val; - - /* We are a bit greedy here, but it is okay. */ - if (arg2[0] == 't' || arg2[0] == 'T' || arg2[0] == '1') { - val = true; - } else if (arg2[0] == 'f' || arg2[0] == 'F' || arg2[0] == '0') { - val = false; - } else { - /* But not too greedy. */ - return; - } - - - - if (arg1[0] == '*') { - TAILQ_FOREACH(style, &desk_style_q, entry) { - *(bool *)(((char *)style) + offset) = val; - } - } else { - desk = desk1; - sscanf(arg1, "%d", &desk); - - style = FindDeskStyle(desk); - *(bool *)(((char *)style) + offset) = val; - } - - return; -} - -static void SetDeskLabel(int desk, const char *label) -{ - DeskStyle *style = FindDeskStyle(desk); - - free(style->label); - CopyString(&(style->label), label); -} - -void parse_monitor_line(char *tline) -{ - int dx, dy, Vx, Vy, VxMax, VyMax, CurrentDesk; - int scr_width, scr_height; - int flags; - char *mname; - struct monitor *tm; - struct fpmonitor *fp; - - tline = GetNextToken(tline, &mname); - - sscanf(tline, "%d %d %d %d %d %d %d %d %d %d", &flags, - &dx, &dy, &Vx, &Vy, &VxMax, &VyMax, &CurrentDesk, - &scr_width, &scr_height); - - monitor_refresh_module(dpy); - - tm = monitor_resolve_name(mname); - if (tm == NULL) - return; - - if (flags & MONITOR_DISABLED) { - fp = fpmonitor_by_name(mname); - if (fp != NULL) { - bool disabled = fp->disabled; - fpmonitor_disable(fp); - if (!disabled) - ReConfigure(); - } - return; - } - - if ((fp = fpmonitor_this(tm)) == NULL) { - if (fp_new_block) - return; - fp_new_block = true; - fp = fpmonitor_new(tm); - fp->m->flags |= MONITOR_NEW; - } - - /* This ensures that if monitor_to_track gets disconnected - * then reconnected, the pager can resume tracking it. - */ - if (preferred_monitor != NULL && - strcmp(fp->m->si->name, preferred_monitor) == 0) - { - monitor_to_track = fp; - } - fp->disabled = false; - fp->scr_width = scr_width; - fp->scr_height = scr_height; - fp->m->dx = dx; - fp->m->dy = dy; - fp->m->virtual_scr.Vx = fp->virtual_scr.Vx = Vx; - fp->m->virtual_scr.Vy = fp->virtual_scr.Vy = Vy; - fp->m->virtual_scr.VxMax = fp->virtual_scr.VxMax = VxMax; - fp->m->virtual_scr.VyMax = fp->virtual_scr.VyMax = VyMax; - fp->m->virtual_scr.CurrentDesk = CurrentDesk; - - fp->virtual_scr.VxMax = dx * fpmonitor_get_all_widths() - fpmonitor_get_all_widths(); - fp->virtual_scr.VyMax = dy * fpmonitor_get_all_heights() - fpmonitor_get_all_heights(); - if (fp->virtual_scr.VxMax < 0) - fp->virtual_scr.VxMax = 0; - if (fp->virtual_scr.VyMax < 0) - fp->virtual_scr.VyMax = 0; - fp->virtual_scr.VWidth = fp->virtual_scr.VxMax + fpmonitor_get_all_widths(); - fp->virtual_scr.VHeight = fp->virtual_scr.VyMax + fpmonitor_get_all_heights(); - fp->virtual_scr.VxPages = fp->virtual_scr.VWidth / fpmonitor_get_all_widths(); - fp->virtual_scr.VyPages = fp->virtual_scr.VHeight / fpmonitor_get_all_heights(); - - if (fp->m != NULL && fp->m->flags & MONITOR_NEW) { - fp->m->flags &= ~MONITOR_NEW; - initialize_fpmonitor_windows(fp); - } - fp_new_block = false; -} - -void parse_desktop_size_line(char *tline) -{ - int dx, dy; - struct fpmonitor *m; - - sscanf(tline, "%d %d", &dx, &dy); - - TAILQ_FOREACH(m, &fp_monitor_q, entry) { - m->virtual_scr.VxMax = dx * fpmonitor_get_all_widths() - fpmonitor_get_all_widths(); - m->virtual_scr.VyMax = dy * fpmonitor_get_all_heights() - fpmonitor_get_all_heights(); - if (m->virtual_scr.VxMax < 0) - m->virtual_scr.VxMax = 0; - if (m->virtual_scr.VyMax < 0) - m->virtual_scr.VyMax = 0; - m->virtual_scr.VWidth = m->virtual_scr.VxMax + fpmonitor_get_all_widths(); - m->virtual_scr.VHeight = m->virtual_scr.VyMax + fpmonitor_get_all_heights(); - m->virtual_scr.VxPages = m->virtual_scr.VWidth / fpmonitor_get_all_widths(); - m->virtual_scr.VyPages = m->virtual_scr.VHeight / fpmonitor_get_all_heights(); - } -} - -void parse_desktop_configuration_line(char *tline) -{ - int mmode, is_shared; - - sscanf(tline, "%d %d", &mmode, &is_shared); - - if (mmode > 0) { - monitor_mode = mmode; - is_tracking_shared = is_shared; - } -} - -static void update_monitor_to_track(struct fpmonitor **fp_track, - char *name, bool update_prefered) -{ - struct fpmonitor *new_fp; - - name = SkipSpaces(name, NULL, 0); - if (StrEquals(name, "none")) { - *fp_track = NULL; - if (update_prefered) { - free(preferred_monitor); - preferred_monitor = NULL; - } - return; - } - - new_fp = fpmonitor_by_name(name); - /* Fallback to current monitor, if monitor not already set. */ - if (new_fp != NULL) - *fp_track = new_fp; - else if (*fp_track == NULL) - *fp_track = fpmonitor_this(NULL); - if (update_prefered) { - /* Set this even if no monitor matches given name. - * That monitor may get enabled later. - */ - free(preferred_monitor); - preferred_monitor = fxstrdup(name); - } -} - -/* - * This routine is responsible for reading and parsing the config file - */ -void ParseOptions(void) -{ - char *tline= NULL; - char *mname; - bool MoveThresholdSetForModule = false; - - FvwmPictureAttributes fpa; - Scr.VScale = 32; - - fpa.mask = 0; - if (Pdepth <= 8) - { - fpa.mask |= FPAM_DITHER; - } - - xasprintf(&mname, "*%s", MyName); - InitGetConfigLine(fd, mname); - free(mname); - - for (GetConfigLine(fd, &tline); tline != NULL; - GetConfigLine(fd, &tline)) - { - int g_x, g_y, flags; - unsigned width, height; - char *resource; - char *arg1 = NULL; - char *arg2 = NULL; - char *tline2; - char *token; - char *next; - - token = PeekToken(tline, &next); - - /* Step 1: Initial configuration broadcasts are parsed here. - * This needs to match list_config_info(), along with having - * a few extra broadcasts that are sent during initialization. - */ - if (token[0] == '*') { - /* Module configuration item, skip to next step. */ - } else if (StrEquals(token, "Colorset")) { - LoadColorset(next); - continue; - } else if (StrEquals(token, "DesktopSize")) { - parse_desktop_size_line(next); - continue; - } else if (StrEquals(token, "ImagePath")) { - free(ImagePath); - ImagePath = NULL; - GetNextToken(next, &ImagePath); - continue; - } else if (StrEquals(token, "MoveThreshold")) { - if (MoveThresholdSetForModule) - continue; - - int val; - if (GetIntegerArguments(next, NULL, &val, 1) > 0) - MoveThreshold = (val >= 0) ? val : - DEFAULT_PAGER_MOVE_THRESHOLD; - continue; - } else if (StrEquals(token, "DesktopName")) { - int val; - - if (GetIntegerArguments(next, &next, &val, 1) > 0) - SetDeskLabel(val, (const char *)next); - continue; - } else if (StrEquals(token, "Monitor")) { - parse_monitor_line(next); - continue; - } else if (StrEquals(token, "DesktopConfiguration")) { - parse_desktop_configuration_line(next); - continue; - } else { - /* Module configuration lines have skipped this. */ - continue; - } - - /* Step 2: Parse module configuration options. */ - tline2 = GetModuleResource(tline, &resource, MyName); - if (!resource) - continue; - - /* Start by looking for options with no parameters. */ - flags = 1; - if (StrEquals(resource, "DeskLabels")) { - use_desk_label = true; - } else if (StrEquals(resource, "NoDeskLabels")) { - use_desk_label = false; - } else if (StrEquals(resource, "MonitorLabels")) { - use_monitor_label = true; - } else if (StrEquals(resource, "NoMonitorLabels")) { - use_monitor_label = false; - } else if (StrEquals(resource, "CurrentDeskPerMonitor")) { - CurrentDeskPerMonitor = true; - } else if (StrEquals(resource, "CurrentDeskGlobal")) { - CurrentDeskPerMonitor = false; - } else if (StrEquals(resource, "IsShared")) { - IsShared = true; - } else if (StrEquals(resource, "IsNotShared")) { - IsShared = false; - } else if (StrEquals(resource, "DeskHilight")) { - HilightDesks = true; - } else if (StrEquals(resource, "NoDeskHilight")) { - HilightDesks = false; - } else if (StrEquals(resource, "LabelHilight")) { - HilightLabels = true; - } else if (StrEquals(resource, "NoLabelHilight")) { - HilightLabels = false; - } else if (StrEquals(resource, "MiniIcons")) { - MiniIcons = true; - } else if (StrEquals(resource, "StartIconic")) { - StartIconic = true; - } else if (StrEquals(resource, "NoStartIconic")) { - StartIconic = false; - } else if (StrEquals(resource, "LabelsBelow")) { - LabelsBelow = true; - } else if (StrEquals(resource, "LabelsAbove")) { - LabelsBelow = false; - } else if (StrEquals(resource, "ShapeLabels")) { - if (FHaveShapeExtension) - ShapeLabels = true; - } else if (StrEquals(resource, "NoShapeLabels")) { - ShapeLabels = false; - } else if (StrEquals(resource, "HideSmallWindows")) { - HideSmallWindows = true; - } else if (StrEquals(resource, "Window3dBorders")) { - WindowBorders3d = true; - } else if (StrEquals(resource,"UseSkipList")) { - UseSkipList = true; - } else if (StrEquals(resource, "SloppyFocus")) { - do_focus_on_enter = true; - } else if (StrEquals(resource, "FocusAfterMove")) { - FocusAfterMove = true; - } else if (StrEquals(resource, "SolidSeparators")) { - use_dashed_separators = false; - use_no_separators = false; - } else if (StrEquals(resource, "NoSeparators")) { - use_no_separators = true; - } else { - /* No Match, set this to continue parsing. */ - flags = 0; - } - if (flags == 1) { - free(resource); - continue; - } - - /* Now look for options with additional inputs. - * Many inputs are of the form: [desk] value - * Since desk is optional, inputs are stored as: - * One input: arg1 = '*'; arg2 = input1 - * Two inputs: arg1 = input1; arg2 = input2 - * Options that expect one input should use "next". - */ - tline2 = GetNextToken(tline2, &arg1); - if (!arg1) - /* No inputs, nothing to do. */ - continue; - - tline2 = GetNextToken(tline2, &arg2); - if (!arg2) - { - arg2 = arg1; - arg1 = NULL; - arg1 = fxmalloc(1); - arg1[0] = '*'; - } - - next = SkipSpaces(next, NULL, 0); - if (StrEquals(resource, "Monitor")) { - update_monitor_to_track( - &monitor_to_track, next, true); - } else if (StrEquals(resource, "CurrentMonitor")) { - update_monitor_to_track( - ¤t_monitor, next, false); - } else if(StrEquals(resource, "Colorset")) { - SetDeskStyleColorset(arg1, arg2, - &(((DeskStyle *)(NULL))->cs)); - } else if(StrEquals(resource, "BalloonColorset")) { - SetDeskStyleColorset(arg1, arg2, - &(((DeskStyle *)(NULL))->balloon_cs)); - } else if(StrEquals(resource, "HilightColorset")) { - SetDeskStyleColorset(arg1, arg2, - &(((DeskStyle *)(NULL))->hi_cs)); - } else if (StrEquals(resource, "WindowColorset")) { - SetDeskStyleColorset(arg1, arg2, - &(((DeskStyle *)(NULL))->win_cs)); - } else if (StrEquals(resource, "FocusColorset")) { - SetDeskStyleColorset(arg1, arg2, - &(((DeskStyle *)(NULL))->focus_cs)); - } else if (StrEquals(resource, "WindowColorsets")) { - /* Backwards compatibility. */ - if (arg1[0] != '*') { - SetDeskStyleColorset("*", arg1, - &(((DeskStyle *)(NULL))->win_cs)); - SetDeskStyleColorset("*", arg2, - &(((DeskStyle *)(NULL))->focus_cs)); - } - } else if (StrEquals(resource, "Fore")) { - if (Pdepth > 0) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->fg)); - } else if (StrEquals(resource, "Back") || - StrEquals(resource, "DeskColor")) - { - if (Pdepth > 0) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->bg)); - } else if (StrEquals(resource, "HiFore")) { - if (Pdepth > 0) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->hi_fg)); - } else if (StrEquals(resource, "HiBack") || - StrEquals(resource, "Hilight")) - { - if (Pdepth > 0) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->hi_bg)); - } else if (StrEquals(resource, "WindowFore")) { - if (Pdepth > 1) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->win_fg)); - } else if (StrEquals(resource, "WindowBack")) { - if (Pdepth > 1) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->win_bg)); - } else if (StrEquals(resource, "FocusFore")) { - if (Pdepth > 1) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->focus_fg)); - } else if (StrEquals(resource, "FocusBack")) { - if (Pdepth > 1) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->focus_bg)); - } else if (StrEquals(resource, "WindowColors")) { - /* Backwards compatibility. */ - if (Pdepth > 1 && arg1[0] != '*') - { - SetDeskStylePixel("*", arg1, - &(((DeskStyle *)(NULL))->win_bg)); - SetDeskStylePixel("*", arg2, - &(((DeskStyle *)(NULL))->win_bg)); - free(arg2); - tline2 = GetNextToken(tline2, &arg2); - SetDeskStylePixel("*", arg2, - &(((DeskStyle *)(NULL))->focus_fg)); - free(arg2); - tline2 = GetNextToken(tline2, &arg2); - SetDeskStylePixel("*", arg2, - &(((DeskStyle *)(NULL))->focus_bg)); - } - } else if (StrEquals(resource, "BalloonFore")) { - if (Pdepth > 1) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->balloon_fg)); - } else if (StrEquals(resource, "BalloonBack")) { - if (Pdepth > 1) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->balloon_bg)); - } else if (StrEquals(resource, "BalloonBorderColor")) { - if (Pdepth > 1) - SetDeskStylePixel(arg1, arg2, - &(((DeskStyle *)(NULL))->balloon_border)); - } else if (StrEquals(resource, "LabelPixmap")) { - SetDeskStyleBool(arg1, arg2, - &(((DeskStyle *)(NULL))->use_label_pixmap)); - } else if (StrEquals(resource, "Geometry")) { - flags = FScreenParseGeometry( - next, &g_x, &g_y, &width, &height); - if (flags & WidthValue) - pwindow.width = width; - if (flags & HeightValue) - pwindow.height = height; - if (flags & XValue) { - pwindow.x = g_x; - usposition = true; - if (flags & XNegative) - xneg = true; - } - if (flags & YValue) { - pwindow.y = g_y; - usposition = true; - if (flags & YNegative) - yneg = true; - } - } else if (StrEquals(resource, "IconGeometry")) { - flags = FScreenParseGeometry( - next, &g_x, &g_y, &width, &height); - if (flags & WidthValue) - icon.width = width; - if (flags & HeightValue) - icon.height = height; - if (flags & XValue) { - icon.x = g_x; - if (flags & XNegative) - icon_xneg = true; - } - if (flags & YValue) { - icon.y = g_y; - if (flags & YNegative) - icon_yneg = true; - } - } else if (StrEquals(resource, "Font")) { - free(font_string); - CopyStringWithQuotes(&font_string, next); - if(strncasecmp(font_string, "none", 4) == 0) { - use_desk_label = false; - use_monitor_label = false; - free(font_string); - font_string = NULL; - } - } else if (StrEquals(resource, "Pixmap") || - StrEquals(resource, "DeskPixmap")) - { - if (Pdepth == 0) - goto free_vars; - - DeskStyle *style; - if (arg1[0] == '*') { - TAILQ_FOREACH(style, &desk_style_q, entry) { - if (style->bgPixmap != NULL) { - PDestroyFvwmPicture( - dpy, style->bgPixmap); - style->bgPixmap = NULL; - } - style->bgPixmap = PCacheFvwmPicture( - dpy, Scr.pager_w, ImagePath, - arg2, fpa); - } - } else { - int desk = 0; - sscanf(arg1, "%d", &desk); - style = FindDeskStyle(desk); - if (style->bgPixmap != NULL) { - PDestroyFvwmPicture( - dpy, style->bgPixmap); - style->bgPixmap = NULL; - } - style->bgPixmap = PCacheFvwmPicture(dpy, - Scr.pager_w, ImagePath, arg2, fpa); - } - } else if (StrEquals(resource, "HilightPixmap")) { - if (Pdepth == 0) - goto free_vars; - - DeskStyle *style; - if (arg1[0] == '*') { - TAILQ_FOREACH(style, &desk_style_q, entry) { - if (style->hiPixmap != NULL) { - PDestroyFvwmPicture( - dpy, style->hiPixmap); - style->hiPixmap = NULL; - } - style->hiPixmap = PCacheFvwmPicture( - dpy, Scr.pager_w, ImagePath, - arg2, fpa); - } - } else { - int desk = 0; - sscanf(arg1, "%d", &desk); - style = FindDeskStyle(desk); - if (style->hiPixmap != NULL) { - PDestroyFvwmPicture( - dpy, style->hiPixmap); - style->hiPixmap = NULL; - } - style->hiPixmap = PCacheFvwmPicture(dpy, - Scr.pager_w, ImagePath, arg2, fpa); - } - } else if (StrEquals(resource, "WindowFont") || - StrEquals(resource, "SmallFont")) - { - free(smallFont); - CopyStringWithQuotes(&smallFont, next); - if (strncasecmp(smallFont, "none", 4) == 0) { - free(smallFont); - smallFont = NULL; - } - } else if (StrEquals(resource, "Rows")) { - sscanf(next, "%d", &Rows); - } else if (StrEquals(resource, "Columns")) { - sscanf(next, "%d", &Columns); - } else if (StrEquals(resource, "DesktopScale")) { - sscanf(next, "%d", &Scr.VScale); - } else if (StrEquals(resource, "WindowBorderWidth")) { - MinSize = MinSize - 2*WindowBorderWidth; - sscanf(next, "%d", &WindowBorderWidth); - if (WindowBorderWidth > 0) - MinSize = 2 * WindowBorderWidth + MinSize; - else - MinSize = MinSize + 2 * - DEFAULT_PAGER_WINDOW_BORDER_WIDTH; - } else if (StrEquals(resource, "WindowMinSize")) { - sscanf(next, "%d", &MinSize); - if (MinSize > 0) - MinSize = 2 * WindowBorderWidth + MinSize; - else - MinSize = 2 * WindowBorderWidth + - DEFAULT_PAGER_WINDOW_MIN_SIZE; - } else if (StrEquals(resource,"WindowLabelFormat")) { - free(WindowLabelFormat); - CopyString(&WindowLabelFormat, next); - } else if (StrEquals(resource, "MoveThreshold")) { - int val; - if (GetIntegerArguments(next, NULL, &val, 1) > 0 && - val >= 0) - { - MoveThreshold = val; - MoveThresholdSetForModule = true; - } - } else if (StrEquals(resource, "Balloons")) { - if (StrEquals(next, "Pager")) { - Balloon.show_in_pager = true; - Balloon.show_in_icon = false; - } else if (StrEquals(next, "Icon")) { - Balloon.show_in_pager = false; - Balloon.show_in_icon = true; - } else if (StrEquals(next, "None")) { - Balloon.show_in_pager = false; - Balloon.show_in_icon = false; - } else { - Balloon.show_in_pager = true; - Balloon.show_in_icon = true; - } - } else if (StrEquals(resource, "BalloonFont")) { - free(BalloonFont); - CopyStringWithQuotes(&BalloonFont, next); - } else if (StrEquals(resource, "BalloonBorderWidth")) { - sscanf(next, "%d", &(Balloon.border_width)); - } else if (StrEquals(resource, "BalloonYOffset")) { - sscanf(next, "%d", &(Balloon.y_offset)); - } else if (StrEquals(resource,"BalloonStringFormat")) { - free(Balloon.label_format); - CopyString(&(Balloon.label_format), next); - } - -free_vars: - free(resource); - free(arg1); - free(arg2); - } - - return; -} - /* Returns the DeskStyle for inputted desk. */ DeskStyle *FindDeskStyle(int desk) { diff --git a/modules/FvwmPager/FvwmPager.h b/modules/FvwmPager/FvwmPager.h index b433730cc..ea42f73b4 100644 --- a/modules/FvwmPager/FvwmPager.h +++ b/modules/FvwmPager/FvwmPager.h @@ -3,12 +3,6 @@ #ifndef FVWMPAGER_H #define FVWMPAGER_H -#include "libs/Picture.h" -#include "libs/vpacket.h" -#include "libs/Flocale.h" -#include "libs/Module.h" -#include "libs/FScreen.h" - #define DEFAULT_PAGER_WINDOW_BORDER_WIDTH 1 #define DEFAULT_PAGER_WINDOW_MIN_SIZE 3 #define DEFAULT_PAGER_MOVE_THRESHOLD 3 @@ -20,16 +14,16 @@ struct fpmonitor { Window *CPagerWin; - struct { - int VxMax; - int VyMax; - int Vx; - int Vy; + struct { + int VxMax; + int VyMax; + int Vx; + int Vy; int VxPages; /* desktop size */ int VyPages; int VWidth; /* Size of virtual desktop */ int VHeight; - } virtual_scr; + } virtual_scr; int scr_width; /* Size of DisplayWidth() */ int scr_height; /* Size of DisplayHeight() */ @@ -37,10 +31,7 @@ struct fpmonitor { TAILQ_ENTRY(fpmonitor) entry; }; TAILQ_HEAD(fpmonitors, fpmonitor); - extern struct fpmonitors fp_monitor_q; -struct fpmonitor *fpmonitor_by_name(const char *); -struct fpmonitor *fpmonitor_this(struct monitor *); typedef struct ScreenInfo { @@ -176,9 +167,7 @@ typedef struct desk_info } DeskInfo; /* - * * Shared variables. - * */ /* Colors, Pixmaps, Fonts, etc. */ extern char *smallFont; @@ -192,6 +181,7 @@ extern Pixmap default_pixmap; extern FlocaleFont *Ffont; extern FlocaleFont *FwindowFont; extern FlocaleWinString *FwinString; +extern Atom wm_del_win; /* Sizes / Dimensions */ extern int Rows; @@ -199,6 +189,9 @@ extern int desk1; extern int desk2; extern int desk_i; extern int ndesks; +extern int desk_w; +extern int desk_h; +extern int label_h; extern int Columns; extern int MoveThreshold; extern unsigned int WindowBorderWidth; @@ -252,84 +245,65 @@ extern char *preferred_monitor; extern struct fpmonitors fp_monitor_q; /* - * - * Subroutine Prototypes - * + * Shared methods prototypes */ -void Loop(int *fd); -RETSIGTYPE DeadPipe(int nonsense); -void process_message(FvwmPacket*); -void ParseOptions(void); - -void list_add(unsigned long *body); -void list_configure(unsigned long *body); -void list_config_info(unsigned long *body); -void list_destroy(unsigned long *body); -void list_focus(unsigned long *body); -void list_toggle(unsigned long *body); -void list_new_page(unsigned long *body); -void list_new_desk(unsigned long *body); -void list_raise(unsigned long *body); -void list_lower(unsigned long *body); -void list_unknown(unsigned long *body); -void list_iconify(unsigned long *body); -void list_deiconify(unsigned long *body, unsigned long length); -void list_window_name(unsigned long *body,unsigned long type); -void list_icon_name(unsigned long *body); -void list_class(unsigned long *body); -void list_res_name(unsigned long *body); -void list_mini_icon(unsigned long *body); -void list_restack(unsigned long *body, unsigned long length); -void list_property_change(unsigned long *body); -void list_end(void); -void list_reply(unsigned long *body); -int My_XNextEvent(Display *dpy, XEvent *event); +/* FvwmPager.c methods */ DeskStyle *FindDeskStyle(int desk); void ExitPager(void); -void initialize_colorsets(); - -/* Stuff in x_pager.c */ -void change_colorset(int colorset); -void initialise_common_pager_fragments(void); -void initialize_pager(void); -void initialize_fpmonitor_windows(struct fpmonitor *); -void initialize_viz_pager(void); -Pixel GetSimpleColor(char *name); -void set_desk_size(bool); + +/* x_pager.c methods */ +void HandleScrollDone(void); +rectangle set_vp_size_and_loc(struct fpmonitor *, bool is_icon); void DispatchEvent(XEvent *Event); void ReConfigure(void); void ReConfigureAll(void); -void update_pr_transparent_windows(void); void MovePage(); void draw_desk_grid(int desk); -void draw_icon_grid(int erase); -void SwitchToDesk(int Desk, struct fpmonitor *m); -void SwitchToDeskAndPage(int Desk, XEvent *Event); void AddNewWindow(PagerWindow *prev); -void MoveResizePagerView(PagerWindow *t, bool do_force_redraw); void ChangeDeskForWindow(PagerWindow *t,long newdesk); +void MoveResizePagerView(PagerWindow *t, bool do_force_redraw); void MoveStickyWindows(bool is_new_page, bool is_new_desk); -void Scroll(int x, int y, int Desk, bool do_scroll_icon); -void MoveWindow(XEvent *Event); -void ReConfigureIcons(bool do_reconfigure_desk_only); -void IconSwitchPage(XEvent *Event); -void IconMoveWindow(XEvent *Event,PagerWindow *t); -void HandleEnterNotify(XEvent *Event); -void HandleExpose(XEvent *Event); void MapBalloonWindow(PagerWindow *t, bool is_icon_view); +char *get_label(const PagerWindow *pw, const char *fmt); void UnmapBalloonWindow(void); -void HandleScrollDone(void); -int fpmonitor_get_all_widths(void); -int fpmonitor_get_all_heights(void); -struct fpmonitor *fpmonitor_from_desk(int desk); -void initialize_desk_style_gcs(DeskStyle *style); -void update_desk_style_gcs(DeskStyle *style); -void update_desk_background(int desk); + +/* x_update.c methods */ void update_monitor_locations(int desk); void update_monitor_backgrounds(int desk); +void update_desk_background(int desk); void update_window_background(PagerWindow *t); -void update_window_decor(PagerWindow *t); +void update_pr_transparent_windows(void); +void update_desk_style_gcs(DeskStyle *style); void update_pager_window_decor(PagerWindow *t); void update_icon_window_decor(PagerWindow *t); +void update_window_decor(PagerWindow *t); + +/* fpmonitor.c methods */ +struct fpmonitor *fpmonitor_new(struct monitor *); +struct fpmonitor *fpmonitor_this(struct monitor *); +struct fpmonitor *fpmonitor_by_name(const char *); +struct fpmonitor *fpmonitor_from_desk(int desk); +struct fpmonitor *fpmonitor_from_xy(int x, int y); +struct fpmonitor *fpmonitor_from_n(int n); +void fpmonitor_disable(struct fpmonitor *); +int fpmonitor_get_all_widths(void); +int fpmonitor_get_all_heights(void); +int fpmonitor_count(void); + +/* messages.c methods */ +void process_message(FvwmPacket *packet); +void set_desk_label(int desk, const char *label); +void set_desk_size(bool update_label); +void parse_monitor_line(char *tline); +void parse_desktop_size_line(char *tline); +void parse_desktop_configuration_line(char *tline); +void update_monitor_to_track(struct fpmonitor **fp_track, + char *name, bool update_prefered); + +/* init_pager.c methods */ +void init_fvwm_pager(void); +void initialize_colorset(DeskStyle *style); +void initialize_fpmonitor_windows(struct fpmonitor *fp); +void initialize_desk_style_gcs(DeskStyle *style); #endif /* FVWMPAGER_H */ diff --git a/modules/FvwmPager/Makefile.am b/modules/FvwmPager/Makefile.am index df5fc6afb..f261f03d6 100644 --- a/modules/FvwmPager/Makefile.am +++ b/modules/FvwmPager/Makefile.am @@ -11,7 +11,8 @@ EXTRA_DIST = ConfigFvwmPager config_DATA = \ ConfigFvwmPager -FvwmPager_SOURCES = FvwmPager.c FvwmPager.h x_pager.c +FvwmPager_SOURCES = FvwmPager.c FvwmPager.h x_pager.c fpmonitor.c \ + messages.c init_pager.c x_update.c FvwmPager_DEPENDENCIES = $(top_builddir)/libs/libfvwm3.a ## Xpm note: while this module may not depend on Xpm explicitly, diff --git a/modules/FvwmPager/fpmonitor.c b/modules/FvwmPager/fpmonitor.c new file mode 100644 index 000000000..e9802b83f --- /dev/null +++ b/modules/FvwmPager/fpmonitor.c @@ -0,0 +1,165 @@ +/* -*-c-*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see: + */ + +#include "config.h" +#include "libs/FScreen.h" +#include "libs/fvwmlib.h" +#include "libs/Module.h" +#include "libs/Strings.h" +#include "fvwm/fvwm.h" +#include "FvwmPager.h" + +struct fpmonitor *fpmonitor_new(struct monitor *m) +{ + struct fpmonitor *fp; + + fp = fxcalloc(1, sizeof(*fp)); + if (HilightDesks) + fp->CPagerWin = fxcalloc(1, ndesks * sizeof(*fp->CPagerWin)); + else + fp->CPagerWin = NULL; + fp->m = m; + fp->disabled = false; + TAILQ_INSERT_TAIL(&fp_monitor_q, fp, entry); + + return (fp); +} + +struct fpmonitor *fpmonitor_this(struct monitor *m_find) +{ + struct monitor *m; + struct fpmonitor *fp = NULL; + + if (m_find != NULL) { + /* We've been asked to find a specific monitor. */ + m = m_find; + } else if (monitor_to_track != NULL) { + return (monitor_to_track); + } else { + m = monitor_get_current(); + } + + if (m == NULL || m->flags & MONITOR_DISABLED) + return (NULL); + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (fp->m == m) + return (fp); + } + return (NULL); +} + +struct fpmonitor *fpmonitor_by_name(const char *name) +{ + struct fpmonitor *fm; + + if (name == NULL || StrEquals(name, "none")) + return (NULL); + + TAILQ_FOREACH(fm, &fp_monitor_q, entry) { + if (fm->m != NULL && (strcmp(name, fm->m->si->name) == 0)) + return (fm); + } + return (NULL); +} + +struct fpmonitor *fpmonitor_from_desk(int desk) +{ + struct fpmonitor *fp; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) + if (!fp->disabled && fp->m->virtual_scr.CurrentDesk == desk) + return fp; + + return NULL; +} + +struct fpmonitor *fpmonitor_from_xy(int x, int y) +{ + struct fpmonitor *fp; + + if (monitor_to_track == NULL && monitor_mode != MONITOR_TRACKING_G) { + x %= fpmonitor_get_all_widths(); + y %= fpmonitor_get_all_heights(); + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) + if (x >= fp->m->si->x && + x < fp->m->si->x + fp->m->si->w && + y >= fp->m->si->y && + y < fp->m->si->y + fp->m->si->h) + return fp; + } else { + return fpmonitor_this(NULL); + } + + return NULL; +} + +struct fpmonitor *fpmonitor_from_n(int n) +{ + struct fpmonitor *fp; + int c = 0; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (fp->disabled) + continue; + if (c == n) + return fp; + c++; + } + return fp; +} + +void fpmonitor_disable(struct fpmonitor *fp) +{ + int i; + + fp->disabled = true; + for (i = 0; i < ndesks; i++) { + XMoveWindow(dpy, fp->CPagerWin[i], -32768,-32768); + } + + if (fp == monitor_to_track) + monitor_to_track = fpmonitor_this(NULL); +} + +int fpmonitor_get_all_widths(void) +{ + struct fpmonitor *fp = TAILQ_FIRST(&fp_monitor_q); + + if (fp->scr_width <= 0) + return (monitor_get_all_widths()); + + return (fp->scr_width); +} + +int fpmonitor_get_all_heights(void) +{ + struct fpmonitor *fp = TAILQ_FIRST(&fp_monitor_q); + + if (fp->scr_height <= 0) + return (monitor_get_all_heights()); + return (fp->scr_height); +} + +int fpmonitor_count(void) +{ + struct fpmonitor *fp; + int c = 0; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) + if (!fp->disabled) + c++; + return (c); +} diff --git a/modules/FvwmPager/init_pager.c b/modules/FvwmPager/init_pager.c new file mode 100644 index 000000000..1bed0f0fa --- /dev/null +++ b/modules/FvwmPager/init_pager.c @@ -0,0 +1,1283 @@ +/* -*-c-*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see: + */ + +#include "config.h" +#include "libs/Module.h" +#include "libs/Parse.h" +#include "libs/Graphics.h" +#include "libs/Picture.h" +#include "libs/ColorUtils.h" +#include "libs/FShape.h" +#include "libs/FEvent.h" +#include "fvwm/fvwm.h" +#include "FvwmPager.h" + +static void initialize_viz_pager(void); +static void initialize_desks_and_monitors(void); +static void initialize_colorsets(void); +static int fvwm_error_handler(Display *dpy, XErrorEvent *event); +static void initialise_common_pager_fragments(void); +static void initialize_balloon_window(void); +static void initialize_desk_windows(int desk); +static void initialize_pager(void); +static void set_desk_style_cset(char *arg1, char *arg2, void *offset_style); +static void set_desk_style_pixel(char *arg1, char *arg2, void *offset_style); +static void set_desk_style_bool(char *arg1, char *arg2, void *offset_style); +static void parse_options(void); + +void init_fvwm_pager(void) +{ + + Window JunkRoot, JunkChild; + int JunkX, JunkY; + unsigned JunkMask; + + /* Initialize fonts. */ + FlocaleInit(LC_CTYPE, "", "", "FvwmPager"); + + /* make a temp window for any pixmaps, deleted later */ + initialize_viz_pager(); + + /* Run initializations */ + initialize_desks_and_monitors(); + parse_options(); + + if (is_transient) { + FQueryPointer( + dpy, Scr.Root, &JunkRoot, &JunkChild, &pwindow.x, + &pwindow.y, &JunkX, &JunkY, &JunkMask); + usposition = false; + xneg = false; + yneg = false; + } + + if (WindowLabelFormat == NULL) + WindowLabelFormat = fxstrdup("%i"); + + /* Create a list of all windows, by requesting a list of all + * windows, and wait for ConfigureWindow packets. + */ + SendInfo(fd,"Send_WindowList",0); + + /* Initialize pager window */ + initialize_colorsets(); + initialise_common_pager_fragments(); + initialize_pager(); + + if (is_transient) + { + int i; + bool is_pointer_grabbed = false; + bool is_keyboard_grabbed = false; + + XSync(dpy,0); + for (i = 0; i < 50 && !(is_pointer_grabbed && is_keyboard_grabbed); i++) + { + if (!is_pointer_grabbed && + XGrabPointer( + dpy, Scr.Root, true, + ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| + PointerMotionMask|EnterWindowMask|LeaveWindowMask, GrabModeAsync, + GrabModeAsync, None, None, CurrentTime) == GrabSuccess) + { + is_pointer_grabbed = true; + } + if (!is_keyboard_grabbed && + XGrabKeyboard( + dpy, Scr.Root, true, GrabModeAsync, GrabModeAsync, CurrentTime) == + GrabSuccess) + { + is_keyboard_grabbed = true; + } + /* If you go too fast, other windows may not get a change to release + * any grab that they have. */ + usleep(20000); + } + if (!is_pointer_grabbed) + { + XBell(dpy, 0); + fvwm_debug(__func__, + "%s: could not grab pointer in transient mode. exiting.\n", + MyName); + exit(1); + } + + XSync(dpy,0); + } + + +} + + +/* Procedure: + * Initialize_viz_pager - creates a temp window of the correct visual + * so that pixmaps may be created for use with the main window + */ +void initialize_viz_pager(void) +{ + XSetWindowAttributes attr; + XGCValues xgcv; + + /* FIXME: I think that we only need that Pdepth == + * DefaultDepth(dpy, Scr.screen) to use the Scr.Root for Scr.pager_w */ + if (Pdefault) + { + Scr.pager_w = Scr.Root; + } + else + { + attr.background_pixmap = None; + attr.border_pixel = 0; + attr.colormap = Pcmap; + Scr.pager_w = XCreateWindow( + dpy, Scr.Root, -10, -10, 10, 10, 0, Pdepth, + InputOutput, Pvisual, + CWBackPixmap|CWBorderPixel|CWColormap, &attr); + } + Scr.NormalGC = fvwmlib_XCreateGC(dpy, Scr.pager_w, 0, NULL); + + xgcv.plane_mask = AllPlanes; + Scr.MiniIconGC = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCPlaneMask, &xgcv); + + /* Transparent background are only allowed when the depth matched the + * root */ + if (Pdepth == DefaultDepth(dpy, Scr.screen)) + default_pixmap = ParentRelative; +} + +void initialize_desks_and_monitors(void) +{ + DeskStyle *default_style; + struct monitor *mon; + int i; + + TAILQ_INIT(&fp_monitor_q); + TAILQ_INIT(&desk_style_q); + + RB_FOREACH(mon, monitors, &monitor_q) + (void)fpmonitor_new(mon); + + /* Initialize default DeskStyle, stored on desk -1. */ + default_style = fxcalloc(1, sizeof(DeskStyle)); + default_style->desk = -1; + default_style->label = fxstrdup("-"); + + default_style->use_label_pixmap = true; + default_style->cs = -1; + default_style->hi_cs = -1; + default_style->win_cs = -1; + default_style->focus_cs = -1; + default_style->balloon_cs = -1; + default_style->fg = GetSimpleColor("black"); + default_style->bg = GetSimpleColor("white"); + default_style->hi_fg = GetSimpleColor("black"); + default_style->hi_bg = GetSimpleColor("grey"); + default_style->win_fg = None; /* Use fvwm pixel unless defined. */ + default_style->win_bg = None; + default_style->focus_fg = None; + default_style->focus_bg = None; + default_style->balloon_fg = None; + default_style->balloon_bg = None; + default_style->balloon_border = None; + default_style->bgPixmap = NULL; + default_style->hiPixmap = NULL; + TAILQ_INSERT_TAIL(&desk_style_q, default_style, entry); + + Desks = fxcalloc(1, ndesks*sizeof(DeskInfo)); + for(i = 0; i < ndesks; i++) { + Desks[i].style = FindDeskStyle(i); + Desks[i].fp = fpmonitor_from_desk(i + desk1); + } +} + +void initialize_colorset(DeskStyle *style) +{ + if (style->cs >= 0) { + style->fg = Colorset[style->cs].fg; + style->bg = Colorset[style->cs].bg; + } + if (style->hi_cs >= 0) { + style->hi_fg = Colorset[style->hi_cs].fg; + style->hi_bg = Colorset[style->hi_cs].bg; + } + if (style->win_cs >= 0) { + style->win_fg = Colorset[style->win_cs].fg; + style->win_bg = Colorset[style->win_cs].bg; + } + if (style->focus_cs >= 0) { + style->focus_fg = Colorset[style->focus_cs].fg; + style->focus_bg = Colorset[style->focus_cs].bg; + } + if (style->balloon_cs >= 0) { + style->balloon_fg = Colorset[style->balloon_cs].fg; + style->balloon_bg = Colorset[style->balloon_bg].bg; + } +} + +void initialize_colorsets(void) +{ + DeskStyle *style; + + TAILQ_FOREACH(style, &desk_style_q, entry) { + initialize_colorset(style); + } +} + +int fvwm_error_handler(Display *dpy, XErrorEvent *event) +{ + /* Ignore errors from windows dying unexpectedly. */ + error_occured = true; + return 0; +} + +void initialise_common_pager_fragments(void) +{ + DeskStyle *style = FindDeskStyle(-1); + + /* I don't think that this is necessary - just let pager die */ + /* domivogt (07-mar-1999): But it is! A window being moved in the pager + * might die at any moment causing the Xlib calls to generate BadMatch + * errors. Without an error handler the pager will die! */ + XSetErrorHandler(fvwm_error_handler); + + wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); + + /* load the font */ + /* Note: "font" is always created, whether labels are used or not + because a GC below is set to use a font. dje Dec 2001. + OK, I fixed the GC below, but now something else is blowing up. + Right now, I've got to do some Real Life stuff, so this kludge is + in place, its still better than I found it. + I hope that I've fixed this (olicha) + */ + Ffont = FlocaleLoadFont(dpy, font_string, MyName); + + /* init our Flocale window string */ + FlocaleAllocateWinString(&FwinString); + + /* Check that shape extension exists. */ + if (FHaveShapeExtension && ShapeLabels) + { + ShapeLabels = (FShapesSupported) ? 1 : 0; + } + + if(smallFont != NULL) + { + FwindowFont = FlocaleLoadFont(dpy, smallFont, MyName); + } + + /* Load pixmaps for mono use */ + if (Pdepth < 2) + { + /* assorted gray bitmaps for decorative borders */ + int g_width = 2, g_height = 2; + int l_g_width = 4, l_g_height = 2; + int s_g_width = 4, s_g_height = 4; + char g_bits[] = {0x02, 0x01}; + char l_g_bits[] = {0x08, 0x02}; + char s_g_bits[] = {0x01, 0x02, 0x04, 0x08}; + + Scr.gray_pixmap = XCreatePixmapFromBitmapData( + dpy, Scr.pager_w, g_bits, g_width, g_height, + style->fg, style->bg, Pdepth); + Scr.light_gray_pixmap = XCreatePixmapFromBitmapData( + dpy, Scr.pager_w, l_g_bits, l_g_width, l_g_height, + style->fg, style->bg, Pdepth); + Scr.sticky_gray_pixmap = XCreatePixmapFromBitmapData( + dpy, Scr.pager_w, s_g_bits, s_g_width, s_g_height, + style->fg, style->bg, Pdepth); + } + + /* Size the window */ + if(Rows < 0) + { + if(Columns <= 0) + { + Columns = ndesks; + Rows = 1; + } + else + { + Rows = ndesks/Columns; + if(Rows*Columns < ndesks) + Rows++; + } + } + if(Columns < 0) + { + if (Rows == 0) + Rows = 1; + Columns = ndesks/Rows; + if(Rows*Columns < ndesks) + Columns++; + } + + if(Rows*Columns < ndesks) + { + if (Columns == 0) + Columns = 1; + Rows = ndesks/Columns; + if (Rows*Columns < ndesks) + Rows++; + } + set_desk_size(true); +} + +/* create balloon window -- ric@giccs.georgetown.edu */ +void initialize_balloon_window(void) +{ + XGCValues xgcv; + unsigned long valuemask; + XSetWindowAttributes attributes; + + Balloon.is_mapped = false; + if (!(Balloon.show_in_pager || Balloon.show_in_icon)) { + Scr.balloon_w = None; + return; + } + + /* Set some defaults */ + if (Balloon.border_width <= 0) + Balloon.border_width = DEFAULT_BALLOON_BORDER_WIDTH; + if (Balloon.y_offset == 0) + /* we don't allow y_offset of 0 because it allows direct + * transit from pager window to balloon window, setting + * up a LeaveNotify/EnterNotify event loop. + */ + Balloon.y_offset = DEFAULT_BALLOON_Y_OFFSET; + if (Balloon.label_format == NULL) + Balloon.label_format = fxstrdup("%i"); + + valuemask = CWOverrideRedirect | CWEventMask | CWColormap; + /* tell WM to ignore this window */ + attributes.override_redirect = true; + attributes.event_mask = ExposureMask; + attributes.colormap = Pcmap; + /* now create the window */ + Scr.balloon_w = XCreateWindow( + dpy, Scr.Root, 0, 0, /* coords set later */ 1, 1, + Balloon.border_width, Pdepth, InputOutput, Pvisual, valuemask, + &attributes); + + /* Initialize, actual values will be updated later. */ + valuemask = GCForeground; + xgcv.foreground = GetSimpleColor("black"); + Balloon.Ffont = FlocaleLoadFont(dpy, BalloonFont, MyName); + Balloon.gc = fvwmlib_XCreateGC( + dpy, Scr.balloon_w, valuemask, &xgcv); + free(BalloonFont); +} + +void initialize_fpmonitor_windows(struct fpmonitor *fp) +{ + /* No need to create windows if not using HilightDesks. */ + if (!HilightDesks) + return; + + int i; + unsigned long valuemask; + XSetWindowAttributes attributes; + rectangle vp = set_vp_size_and_loc(fp, false); + + attributes.colormap = Pcmap; + for (i = 0; i < ndesks; i++) { + valuemask = CWColormap; + if (Desks[i].style->hiPixmap || + (Desks[i].style->hi_cs > -1 && + Colorset[Desks[i].style->hi_cs].pixmap)) + { + valuemask |= CWBackPixmap; + attributes.background_pixmap = None; /* set later */ + } else { + valuemask |= CWBackPixel; + attributes.background_pixel = Desks[i].style->hi_bg; + } + + fp->CPagerWin[i] = XCreateWindow(dpy, Desks[i].w, + -32768, -32768, vp.width, vp.height, 0, + CopyFromParent, InputOutput, + CopyFromParent, valuemask, + &attributes); + XMapRaised(dpy, fp->CPagerWin[i]); + update_monitor_locations(i); + update_monitor_backgrounds(i); + } +} + +void initialize_desk_style_gcs(DeskStyle *style) +{ + XGCValues gcv; + char dash_list[2]; + + /* Desk labels GC. */ + gcv.foreground = style->fg; + if (Ffont && Ffont->font) { + gcv.font = Ffont->font->fid; + style->label_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground | GCFont, &gcv); + } else { + style->label_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); + } + + /* Hilight GC, used for monitors and labels backgrounds. */ + gcv.foreground = (Pdepth < 2) ? style->bg : style->hi_bg; + style->hi_bg_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); + + /* create the hilight desk title drawing GC */ + gcv.foreground = (Pdepth < 2) ? style->fg : style->hi_fg; + if (Ffont && Ffont->font) + style->hi_fg_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground | GCFont, &gcv); + else + style->hi_fg_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); + + /* create the virtual page boundary GC */ + gcv.foreground = style->fg; + gcv.line_width = 1; + gcv.line_style = (use_dashed_separators) ? LineOnOffDash : LineSolid; + style->dashed_gc = fvwmlib_XCreateGC(dpy, + Scr.pager_w, GCForeground | GCLineStyle | GCLineWidth, &gcv); + if (use_dashed_separators) { + /* Although this should already be the default for a freshly + * created GC, some X servers do not draw properly dashed + * lines if the dash style is not set explicitly. + */ + dash_list[0] = 4; + dash_list[1] = 4; + XSetDashes(dpy, style->dashed_gc, 0, dash_list, 2); + } + + /* Window borders. */ + gcv.foreground = (style->win_cs) ? + Colorset[style->win_cs].hilite : style->fg; + style->win_hi_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); + gcv.foreground = (style->win_cs) ? + Colorset[style->win_cs].shadow : style->fg; + style->win_sh_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); + + /* Focus window borders. */ + gcv.foreground = (style->focus_cs) ? + Colorset[style->focus_cs].hilite : style->fg; + style->focus_hi_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); + gcv.foreground = (style->focus_cs) ? + Colorset[style->focus_cs].shadow : style->fg; + style->focus_sh_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); +} + +void initialize_desk_windows(int desk) +{ + unsigned long valuemask; + XSetWindowAttributes attributes; + DeskStyle *style = Desks[desk].style; + + /* Common settings for both title and desk window. */ + attributes.colormap = Pcmap; + attributes.background_pixmap = default_pixmap; + attributes.border_pixel = style->fg; + + /* Note, pixmaps are set to None to be updated later. */ + valuemask = (CWBorderPixel | CWColormap | CWEventMask); + if (style->use_label_pixmap && style->cs >= 0) { + if (Colorset[style->cs].pixmap) { + valuemask |= CWBackPixmap; + attributes.background_pixmap = None; + } else { + valuemask |= CWBackPixel; + attributes.background_pixel = style->bg; + } + } else if (style->use_label_pixmap && style->bgPixmap) { + valuemask |= CWBackPixmap; + attributes.background_pixmap = None; + } else { + valuemask |= CWBackPixel; + attributes.background_pixel = style->bg; + } + + attributes.event_mask = (ExposureMask | ButtonReleaseMask); + Desks[desk].title_w = XCreateWindow(dpy, Scr.pager_w, + -1, -1, desk_w, desk_h + label_h, 1, + CopyFromParent, InputOutput, CopyFromParent, + valuemask, &attributes); + + /* Create desk windows. */ + valuemask &= ~(CWBackPixel | CWBackPixmap); + if (style->cs >= 0) { + valuemask |= CWBackPixmap; + if (style->use_label_pixmap) { + attributes.background_pixmap = ParentRelative; + attributes.background_pixel = None; + } else { + valuemask |= CWBackPixel; + attributes.background_pixmap = None; + attributes.background_pixel = style->bg; + } + } else if (Desks[desk].style->bgPixmap) { + valuemask |= CWBackPixmap; + if (Desks[desk].style->use_label_pixmap) + attributes.background_pixmap = ParentRelative; + else + attributes.background_pixmap = None; + } else { + valuemask |= CWBackPixel; + attributes.background_pixel = Desks[desk].style->bg; + } + + attributes.event_mask = (ExposureMask | ButtonReleaseMask | + ButtonPressMask | ButtonMotionMask); + Desks[desk].w = XCreateWindow(dpy, Desks[desk].title_w, + -1, LabelsBelow ? -1 : label_h - 1, desk_w, desk_h, 1, + CopyFromParent, InputOutput, CopyFromParent, + valuemask, &attributes); + + XMapRaised(dpy, Desks[desk].title_w); + XMapRaised(dpy, Desks[desk].w); +} + +void initialize_pager(void) +{ + XWMHints wmhints; + XClassHint class1; + XTextProperty name; + unsigned long valuemask; + XSetWindowAttributes attributes; + int i = 0; + struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *m; + DeskStyle *style; + + XSizeHints sizehints = + { + (PWinGravity), /* flags */ + 0, 0, 100, 100, /* x, y, width and height (legacy) */ + 1, 1, /* Min width and height */ + 0, 0, /* Max width and height */ + 1, 1, /* Width and height increments */ + {0, 0}, {0, 0}, /* Aspect ratio */ + 1, 1, /* base size */ + (NorthWestGravity) /* gravity */ + }; + + int VxPages = fp->virtual_scr.VxPages, VyPages = fp->virtual_scr.VyPages; + + /* Set window size if not fully set by user to match */ + /* aspect ratio of monitor(s) being shown. */ + if ( pwindow.width == 0 || pwindow.height == 0 ) { + int vWidth = fpmonitor_get_all_widths(); + int vHeight = fpmonitor_get_all_heights(); + if (monitor_to_track != NULL || IsShared) { + vWidth = fp->m->si->w; + vHeight = fp->m->si->h; + } + + if (pwindow.width > 0) { + pwindow.height = (pwindow.width * vHeight) / vWidth + + label_h * Rows + Rows; + } else if (pwindow.height > label_h * Rows) { + pwindow.width = ((pwindow.height - label_h * Rows + Rows) * + vWidth) / vHeight + Columns; + } else { + pwindow.width = (VxPages * vWidth * Columns) / Scr.VScale + + Columns; + pwindow.height = (VyPages * vHeight * Rows) / Scr.VScale + + label_h * Rows + Rows; + } + } + set_desk_size(false); + + if (is_transient) + { + rectangle screen_g; + fscreen_scr_arg fscr; + + fscr.xypos.x = pwindow.x; + fscr.xypos.y = pwindow.y; + FScreenGetScrRect( + &fscr, FSCREEN_XYPOS, + &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); + /* FIXME: Recalculate what to do if window is off screen. */ + /* Leaving alone for now */ + if (pwindow.width + pwindow.x > screen_g.x + screen_g.width) + { + pwindow.x = screen_g.x + screen_g.width - fp->m->si->w; //fp->m->virtual_scr.MyDisplayWidth; + xneg = true; + } + if (pwindow.height + pwindow.y > screen_g.y + screen_g.height) + { + pwindow.y = screen_g.y + screen_g.height - fp->m->si->h; //fp->m->virtual_scr.MyDisplayHeight; + yneg = true; + } + } + if (xneg) + { + sizehints.win_gravity = NorthEastGravity; + pwindow.x = fpmonitor_get_all_widths() - pwindow.width + pwindow.x; + } + if (yneg) + { + pwindow.y = fpmonitor_get_all_heights() - pwindow.height + pwindow.y; + if(sizehints.win_gravity == NorthEastGravity) + sizehints.win_gravity = SouthEastGravity; + else + sizehints.win_gravity = SouthWestGravity; + } + + if(usposition) + sizehints.flags |= USPosition; + + valuemask = (CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask); + attributes.background_pixmap = default_pixmap; + attributes.border_pixel = 0; + attributes.colormap = Pcmap; + attributes.event_mask = (StructureNotifyMask); + + /* destroy the temp window first, don't worry if it's the Root */ + if (Scr.pager_w != Scr.Root) + XDestroyWindow(dpy, Scr.pager_w); + Scr.pager_w = XCreateWindow (dpy, Scr.Root, pwindow.x, pwindow.y, pwindow.width, + pwindow.height, 0, Pdepth, InputOutput, Pvisual, + valuemask, &attributes); + XSetWMProtocols(dpy,Scr.pager_w,&wm_del_win,1); + /* hack to prevent mapping on wrong screen with StartsOnScreen */ + FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS, &sizehints); + XSetWMNormalHints(dpy,Scr.pager_w,&sizehints); + if (is_transient) + { + XSetTransientForHint(dpy, Scr.pager_w, Scr.Root); + } + + if (FlocaleTextListToTextProperty( + dpy, &(Desks[0].style->label), 1, XStdICCTextStyle, &name) == 0) + { + fprintf(stderr,"%s: fatal error: cannot allocate desk name", MyName); + exit(0); + } + + attributes.event_mask = (StructureNotifyMask| ExposureMask); + if(icon.width < 1) + icon.width = (pwindow.width - Columns + 1) / Columns; + if(icon.height < 1) + icon.height = (pwindow.height - Rows * label_h - Rows + 1) / Rows; + + icon.width = (icon.width / (VxPages + 1)) * (VxPages + 1) + VxPages; + icon.height = (icon.height / (VyPages + 1)) * (VyPages + 1) + VyPages; + Scr.icon_w = XCreateWindow (dpy, Scr.Root, pwindow.x, pwindow.y, + icon.width, icon.height, + 0, Pdepth, InputOutput, Pvisual, valuemask, + &attributes); + XGrabButton(dpy, 1, AnyModifier, Scr.icon_w, + True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, + None); + XGrabButton(dpy, 2, AnyModifier, Scr.icon_w, + True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, + None); + XGrabButton(dpy, 3, AnyModifier, Scr.icon_w, + True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, + None); + + if (StartIconic) { + Balloon.show = Balloon.show_in_icon; + wmhints.initial_state = IconicState; + } else { + Balloon.show = Balloon.show_in_pager; + wmhints.initial_state = NormalState; + } + wmhints.flags = 0; + if (icon.x != -10000) + { + if (icon_xneg) + icon.x = fpmonitor_get_all_widths() + icon.x - icon.width; + if (icon.y != -10000) + { + if (icon_yneg) + icon.y = fpmonitor_get_all_heights() + icon.y - icon.height; + } + else + { + icon.y = 0; + } + icon_xneg = false; + icon_yneg = false; + wmhints.icon_x = icon.x; + wmhints.icon_y = icon.y; + wmhints.flags = IconPositionHint; + } + wmhints.icon_window = Scr.icon_w; + wmhints.input = True; + wmhints.flags |= InputHint | StateHint | IconWindowHint; + + class1.res_name = MyName; + class1.res_class = "FvwmPager"; + + XSetWMProperties(dpy,Scr.pager_w,&name,&name,NULL,0, + &sizehints,&wmhints,&class1); + XFree((char *)name.value); + + /* change colour/font for labelling mini-windows */ + XSetForeground(dpy, Scr.NormalGC, GetSimpleColor("black")); + + if (FwindowFont != NULL && FwindowFont->font != NULL) + XSetFont(dpy, Scr.NormalGC, FwindowFont->font->fid); + + /* Initialize DeskStyle GCs */ + for (i = 0; i < ndesks; i++) { + /* Create any missing DeskStyles. */ + style = FindDeskStyle(i); + } + TAILQ_FOREACH(style, &desk_style_q, entry) { + initialize_desk_style_gcs(style); + } + + for(i=0;i 0) + MoveThreshold = (val >= 0) ? val : + DEFAULT_PAGER_MOVE_THRESHOLD; + continue; + } else if (StrEquals(token, "DesktopName")) { + int val; + + if (GetIntegerArguments(next, &next, &val, 1) > 0) + set_desk_label(val, (const char *)next); + continue; + } else if (StrEquals(token, "Monitor")) { + parse_monitor_line(next); + continue; + } else if (StrEquals(token, "DesktopConfiguration")) { + parse_desktop_configuration_line(next); + continue; + } else { + /* Module configuration lines have skipped this. */ + continue; + } + + /* Step 2: Parse module configuration options. */ + tline2 = GetModuleResource(tline, &resource, MyName); + if (!resource) + continue; + + /* Start by looking for options with no parameters. */ + flags = 1; + if (StrEquals(resource, "DeskLabels")) { + use_desk_label = true; + } else if (StrEquals(resource, "NoDeskLabels")) { + use_desk_label = false; + } else if (StrEquals(resource, "MonitorLabels")) { + use_monitor_label = true; + } else if (StrEquals(resource, "NoMonitorLabels")) { + use_monitor_label = false; + } else if (StrEquals(resource, "CurrentDeskPerMonitor")) { + CurrentDeskPerMonitor = true; + } else if (StrEquals(resource, "CurrentDeskGlobal")) { + CurrentDeskPerMonitor = false; + } else if (StrEquals(resource, "IsShared")) { + IsShared = true; + } else if (StrEquals(resource, "IsNotShared")) { + IsShared = false; + } else if (StrEquals(resource, "DeskHilight")) { + HilightDesks = true; + } else if (StrEquals(resource, "NoDeskHilight")) { + HilightDesks = false; + } else if (StrEquals(resource, "LabelHilight")) { + HilightLabels = true; + } else if (StrEquals(resource, "NoLabelHilight")) { + HilightLabels = false; + } else if (StrEquals(resource, "MiniIcons")) { + MiniIcons = true; + } else if (StrEquals(resource, "StartIconic")) { + StartIconic = true; + } else if (StrEquals(resource, "NoStartIconic")) { + StartIconic = false; + } else if (StrEquals(resource, "LabelsBelow")) { + LabelsBelow = true; + } else if (StrEquals(resource, "LabelsAbove")) { + LabelsBelow = false; + } else if (StrEquals(resource, "ShapeLabels")) { + if (FHaveShapeExtension) + ShapeLabels = true; + } else if (StrEquals(resource, "NoShapeLabels")) { + ShapeLabels = false; + } else if (StrEquals(resource, "HideSmallWindows")) { + HideSmallWindows = true; + } else if (StrEquals(resource, "Window3dBorders")) { + WindowBorders3d = true; + } else if (StrEquals(resource,"UseSkipList")) { + UseSkipList = true; + } else if (StrEquals(resource, "SloppyFocus")) { + do_focus_on_enter = true; + } else if (StrEquals(resource, "FocusAfterMove")) { + FocusAfterMove = true; + } else if (StrEquals(resource, "SolidSeparators")) { + use_dashed_separators = false; + use_no_separators = false; + } else if (StrEquals(resource, "NoSeparators")) { + use_no_separators = true; + } else { + /* No Match, set this to continue parsing. */ + flags = 0; + } + if (flags == 1) { + free(resource); + continue; + } + + /* Now look for options with additional inputs. + * Many inputs are of the form: [desk] value + * Since desk is optional, inputs are stored as: + * One input: arg1 = '*'; arg2 = input1 + * Two inputs: arg1 = input1; arg2 = input2 + * Options that expect one input should use "next". + */ + tline2 = GetNextToken(tline2, &arg1); + if (!arg1) + /* No inputs, nothing to do. */ + continue; + + tline2 = GetNextToken(tline2, &arg2); + if (!arg2) + { + arg2 = arg1; + arg1 = NULL; + arg1 = fxmalloc(1); + arg1[0] = '*'; + } + + next = SkipSpaces(next, NULL, 0); + if (StrEquals(resource, "Monitor")) { + update_monitor_to_track( + &monitor_to_track, next, true); + } else if (StrEquals(resource, "CurrentMonitor")) { + update_monitor_to_track( + ¤t_monitor, next, false); + } else if(StrEquals(resource, "Colorset")) { + set_desk_style_cset(arg1, arg2, + &(((DeskStyle *)(NULL))->cs)); + } else if(StrEquals(resource, "BalloonColorset")) { + set_desk_style_cset(arg1, arg2, + &(((DeskStyle *)(NULL))->balloon_cs)); + } else if(StrEquals(resource, "HilightColorset")) { + set_desk_style_cset(arg1, arg2, + &(((DeskStyle *)(NULL))->hi_cs)); + } else if (StrEquals(resource, "WindowColorset")) { + set_desk_style_cset(arg1, arg2, + &(((DeskStyle *)(NULL))->win_cs)); + } else if (StrEquals(resource, "FocusColorset")) { + set_desk_style_cset(arg1, arg2, + &(((DeskStyle *)(NULL))->focus_cs)); + } else if (StrEquals(resource, "WindowColorsets")) { + /* Backwards compatibility. */ + if (arg1[0] != '*') { + set_desk_style_cset("*", arg1, + &(((DeskStyle *)(NULL))->win_cs)); + set_desk_style_cset("*", arg2, + &(((DeskStyle *)(NULL))->focus_cs)); + } + } else if (StrEquals(resource, "Fore")) { + if (Pdepth > 0) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->fg)); + } else if (StrEquals(resource, "Back") || + StrEquals(resource, "DeskColor")) + { + if (Pdepth > 0) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->bg)); + } else if (StrEquals(resource, "HiFore")) { + if (Pdepth > 0) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->hi_fg)); + } else if (StrEquals(resource, "HiBack") || + StrEquals(resource, "Hilight")) + { + if (Pdepth > 0) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->hi_bg)); + } else if (StrEquals(resource, "WindowFore")) { + if (Pdepth > 1) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->win_fg)); + } else if (StrEquals(resource, "WindowBack")) { + if (Pdepth > 1) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->win_bg)); + } else if (StrEquals(resource, "FocusFore")) { + if (Pdepth > 1) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->focus_fg)); + } else if (StrEquals(resource, "FocusBack")) { + if (Pdepth > 1) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->focus_bg)); + } else if (StrEquals(resource, "WindowColors")) { + /* Backwards compatibility. */ + if (Pdepth > 1 && arg1[0] != '*') + { + set_desk_style_pixel("*", arg1, + &(((DeskStyle *)(NULL))->win_bg)); + set_desk_style_pixel("*", arg2, + &(((DeskStyle *)(NULL))->win_bg)); + free(arg2); + tline2 = GetNextToken(tline2, &arg2); + set_desk_style_pixel("*", arg2, + &(((DeskStyle *)(NULL))->focus_fg)); + free(arg2); + tline2 = GetNextToken(tline2, &arg2); + set_desk_style_pixel("*", arg2, + &(((DeskStyle *)(NULL))->focus_bg)); + } + } else if (StrEquals(resource, "BalloonFore")) { + if (Pdepth > 1) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->balloon_fg)); + } else if (StrEquals(resource, "BalloonBack")) { + if (Pdepth > 1) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->balloon_bg)); + } else if (StrEquals(resource, "BalloonBorderColor")) { + if (Pdepth > 1) + set_desk_style_pixel(arg1, arg2, + &(((DeskStyle *)(NULL))->balloon_border)); + } else if (StrEquals(resource, "LabelPixmap")) { + set_desk_style_bool(arg1, arg2, + &(((DeskStyle *)(NULL))->use_label_pixmap)); + } else if (StrEquals(resource, "Geometry")) { + flags = FScreenParseGeometry( + next, &g_x, &g_y, &width, &height); + if (flags & WidthValue) + pwindow.width = width; + if (flags & HeightValue) + pwindow.height = height; + if (flags & XValue) { + pwindow.x = g_x; + usposition = true; + if (flags & XNegative) + xneg = true; + } + if (flags & YValue) { + pwindow.y = g_y; + usposition = true; + if (flags & YNegative) + yneg = true; + } + } else if (StrEquals(resource, "IconGeometry")) { + flags = FScreenParseGeometry( + next, &g_x, &g_y, &width, &height); + if (flags & WidthValue) + icon.width = width; + if (flags & HeightValue) + icon.height = height; + if (flags & XValue) { + icon.x = g_x; + if (flags & XNegative) + icon_xneg = true; + } + if (flags & YValue) { + icon.y = g_y; + if (flags & YNegative) + icon_yneg = true; + } + } else if (StrEquals(resource, "Font")) { + free(font_string); + CopyStringWithQuotes(&font_string, next); + if(strncasecmp(font_string, "none", 4) == 0) { + use_desk_label = false; + use_monitor_label = false; + free(font_string); + font_string = NULL; + } + } else if (StrEquals(resource, "Pixmap") || + StrEquals(resource, "DeskPixmap")) + { + if (Pdepth == 0) + goto free_vars; + + DeskStyle *style; + if (arg1[0] == '*') { + TAILQ_FOREACH(style, &desk_style_q, entry) { + if (style->bgPixmap != NULL) { + PDestroyFvwmPicture( + dpy, style->bgPixmap); + style->bgPixmap = NULL; + } + style->bgPixmap = PCacheFvwmPicture( + dpy, Scr.pager_w, ImagePath, + arg2, fpa); + } + } else { + int desk = 0; + sscanf(arg1, "%d", &desk); + style = FindDeskStyle(desk); + if (style->bgPixmap != NULL) { + PDestroyFvwmPicture( + dpy, style->bgPixmap); + style->bgPixmap = NULL; + } + style->bgPixmap = PCacheFvwmPicture(dpy, + Scr.pager_w, ImagePath, arg2, fpa); + } + } else if (StrEquals(resource, "HilightPixmap")) { + if (Pdepth == 0) + goto free_vars; + + DeskStyle *style; + if (arg1[0] == '*') { + TAILQ_FOREACH(style, &desk_style_q, entry) { + if (style->hiPixmap != NULL) { + PDestroyFvwmPicture( + dpy, style->hiPixmap); + style->hiPixmap = NULL; + } + style->hiPixmap = PCacheFvwmPicture( + dpy, Scr.pager_w, ImagePath, + arg2, fpa); + } + } else { + int desk = 0; + sscanf(arg1, "%d", &desk); + style = FindDeskStyle(desk); + if (style->hiPixmap != NULL) { + PDestroyFvwmPicture( + dpy, style->hiPixmap); + style->hiPixmap = NULL; + } + style->hiPixmap = PCacheFvwmPicture(dpy, + Scr.pager_w, ImagePath, arg2, fpa); + } + } else if (StrEquals(resource, "WindowFont") || + StrEquals(resource, "SmallFont")) + { + free(smallFont); + CopyStringWithQuotes(&smallFont, next); + if (strncasecmp(smallFont, "none", 4) == 0) { + free(smallFont); + smallFont = NULL; + } + } else if (StrEquals(resource, "Rows")) { + sscanf(next, "%d", &Rows); + } else if (StrEquals(resource, "Columns")) { + sscanf(next, "%d", &Columns); + } else if (StrEquals(resource, "DesktopScale")) { + sscanf(next, "%d", &Scr.VScale); + } else if (StrEquals(resource, "WindowBorderWidth")) { + MinSize = MinSize - 2*WindowBorderWidth; + sscanf(next, "%d", &WindowBorderWidth); + if (WindowBorderWidth > 0) + MinSize = 2 * WindowBorderWidth + MinSize; + else + MinSize = MinSize + 2 * + DEFAULT_PAGER_WINDOW_BORDER_WIDTH; + } else if (StrEquals(resource, "WindowMinSize")) { + sscanf(next, "%d", &MinSize); + if (MinSize > 0) + MinSize = 2 * WindowBorderWidth + MinSize; + else + MinSize = 2 * WindowBorderWidth + + DEFAULT_PAGER_WINDOW_MIN_SIZE; + } else if (StrEquals(resource,"WindowLabelFormat")) { + free(WindowLabelFormat); + CopyString(&WindowLabelFormat, next); + } else if (StrEquals(resource, "MoveThreshold")) { + int val; + if (GetIntegerArguments(next, NULL, &val, 1) > 0 && + val >= 0) + { + MoveThreshold = val; + MoveThresholdSetForModule = true; + } + } else if (StrEquals(resource, "Balloons")) { + if (StrEquals(next, "Pager")) { + Balloon.show_in_pager = true; + Balloon.show_in_icon = false; + } else if (StrEquals(next, "Icon")) { + Balloon.show_in_pager = false; + Balloon.show_in_icon = true; + } else if (StrEquals(next, "None")) { + Balloon.show_in_pager = false; + Balloon.show_in_icon = false; + } else { + Balloon.show_in_pager = true; + Balloon.show_in_icon = true; + } + } else if (StrEquals(resource, "BalloonFont")) { + free(BalloonFont); + CopyStringWithQuotes(&BalloonFont, next); + } else if (StrEquals(resource, "BalloonBorderWidth")) { + sscanf(next, "%d", &(Balloon.border_width)); + } else if (StrEquals(resource, "BalloonYOffset")) { + sscanf(next, "%d", &(Balloon.y_offset)); + } else if (StrEquals(resource,"BalloonStringFormat")) { + free(Balloon.label_format); + CopyString(&(Balloon.label_format), next); + } + +free_vars: + free(resource); + free(arg1); + free(arg2); + } + + return; +} diff --git a/modules/FvwmPager/messages.c b/modules/FvwmPager/messages.c new file mode 100644 index 000000000..08e50b20a --- /dev/null +++ b/modules/FvwmPager/messages.c @@ -0,0 +1,982 @@ +/* -*-c-*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see: + */ + +#include "config.h" +#include "libs/FScreen.h" +#include "libs/fvwmlib.h" +#include "libs/Module.h" +#include "libs/Parse.h" +#include "fvwm/fvwm.h" +#include "libs/vpacket.h" +#include "FvwmPager.h" + +static bool fp_new_block = false; + +static PagerWindow *find_pager_window(Window target_w); +static void handle_config_win_package(PagerWindow *t, + ConfigWinPacket *cfgpacket); + +static void process_add(unsigned long *body); +static void process_configure(unsigned long *body); +static void process_destroy(unsigned long *body); +static void process_monitor_focus(unsigned long *body); +static void process_focus(unsigned long *body); +static void process_new_page(unsigned long *body); +static void process_new_desk(unsigned long *body); +static void process_raise(unsigned long *body); +static void process_lower(unsigned long *body); +static void process_iconify(unsigned long *body); +static void process_deiconify(unsigned long *body, unsigned long length); +static void process_window_name(unsigned long *body,unsigned long type); +static void process_icon_name(unsigned long *body); +static void process_mini_icon(unsigned long *body); +static void process_restack(unsigned long *body, unsigned long length); +static void process_end(void); +static void process_config_info(unsigned long *body); +static void process_property_change(unsigned long *body); +static void process_reply(unsigned long *body); + +/* + * Procedure: + * Process message - examines packet types, and takes appropriate action + */ +void process_message(FvwmPacket *packet) +{ + unsigned long type = packet->type; + unsigned long length = packet->size; + unsigned long* body = packet->body; + + switch (type) + { + case M_ADD_WINDOW: + process_configure(body); + break; + case M_CONFIGURE_WINDOW: + process_configure(body); + break; + case M_DESTROY_WINDOW: + process_destroy(body); + break; + case M_FOCUS_CHANGE: + process_focus(body); + break; + case M_NEW_PAGE: + process_new_page(body); + break; + case M_NEW_DESK: + process_new_desk(body); + break; + case M_RAISE_WINDOW: + process_raise(body); + break; + case M_LOWER_WINDOW: + process_lower(body); + break; + case M_ICONIFY: + case M_ICON_LOCATION: + process_iconify(body); + break; + case M_DEICONIFY: + process_deiconify(body, length); + break; + case M_RES_CLASS: + case M_RES_NAME: + case M_VISIBLE_NAME: + process_window_name(body, type); + break; + case MX_VISIBLE_ICON_NAME: + process_icon_name(body); + break; + case M_MINI_ICON: + process_mini_icon(body); + break; + case M_END_WINDOWLIST: + process_end(); + break; + case M_RESTACK: + process_restack(body, length); + break; + case M_CONFIG_INFO: + process_config_info(body); + break; + case MX_PROPERTY_CHANGE: + process_property_change(body); + break; + case MX_MONITOR_FOCUS: + process_monitor_focus(body); + break; + case MX_REPLY: + process_reply(body); + break; + case M_STRING: { + char *this = (char *)&body[3]; + char *token; + char *rest = GetNextToken(this, &token); + + if (rest != NULL && StrEquals(token, "Monitor")) { + update_monitor_to_track( + &monitor_to_track, rest, true); + } else if (StrEquals(token, "CurrentMonitor")) { + update_monitor_to_track( + ¤t_monitor, rest, false); + } else if (StrEquals(token, "DeskLabels")) { + use_desk_label = true; + } else if (StrEquals(token, "NoDeskLabels")) { + use_desk_label = false; + } else if (StrEquals(token, "MonitorLabels")) { + use_monitor_label = true; + } else if (StrEquals(token, "NoMonitorLabels")) { + use_monitor_label = false; + } + else if (StrEquals(token, "CurrentDeskPerMonitor")) { + CurrentDeskPerMonitor = true; + } else if (StrEquals(token, "CurrentDeskGlobal")) { + CurrentDeskPerMonitor = false; + } else if (StrEquals(token, "IsShared")) { + IsShared = true; + } else if (StrEquals(token, "IsNotShared")) { + IsShared = false; + } else { + break; + } + set_desk_size(true); + ReConfigure(); + break; + } + default: + /* ignore unknown packet */ + break; + } +} + +/* Convenience method to find target window. */ +PagerWindow *find_pager_window(Window target_w) +{ + PagerWindow *t; + + t = Start; + while(t != NULL && t->w != target_w) + t = t->next; + + return t; +} + +/* + * Procedure: + * handle_config_win_package - updates a PagerWindow + * with respect to a ConfigWinPacket + */ +void handle_config_win_package(PagerWindow *t, + ConfigWinPacket *cfgpacket) +{ + if (t->w != None && t->w != cfgpacket->w) + { + /* Should never happen */ + fvwm_debug(__func__, + "%s: Error: Internal window list corrupt\n",MyName); + /* might be a good idea to exit here */ + return; + } + t->w = cfgpacket->w; + t->frame = cfgpacket->frame; + t->frame_x = cfgpacket->frame_x; + t->frame_y = cfgpacket->frame_y; + t->frame_width = cfgpacket->frame_width; + t->frame_height = cfgpacket->frame_height; + t->m = monitor_by_output(cfgpacket->monitor_id); + + t->desk = cfgpacket->desk; + + t->title_height = cfgpacket->title_height; + t->border_width = cfgpacket->border_width; + + t->icon_w = cfgpacket->icon_w; + t->icon_pixmap_w = cfgpacket->icon_pixmap_w; + + memcpy(&(t->flags), &(cfgpacket->flags), sizeof(cfgpacket->flags)); + memcpy(&(t->allowed_actions), &(cfgpacket->allowed_actions), + sizeof(cfgpacket->allowed_actions)); + + /* These are used for windows if no pixel is set. */ + t->text = cfgpacket->TextPixel; + t->back = cfgpacket->BackPixel; + + if (IS_ICONIFIED(t)) + { + /* For new windows icon_x and icon_y will be zero until + * iconify message is recived + */ + t->x = t->icon_x; + t->y = t->icon_y; + t->width = t->icon_width; + t->height = t->icon_height; + if(IS_ICON_SUPPRESSED(t) || t->width == 0 || t->height == 0) + { + t->x = -32768; + t->y = -32768; + } + } + else + { + t->x = t->frame_x; + t->y = t->frame_y; + t->width = t->frame_width; + t->height = t->frame_height; + } +} + +void process_add(unsigned long *body) +{ + PagerWindow *t, **prev; + struct ConfigWinPacket *cfgpacket = (void *)body; + + t = Start; + prev = &Start; + + while(t != NULL) + { + if (t->w == cfgpacket->w) + { + /* it's already there, do nothing */ + return; + } + prev = &(t->next); + t = t->next; + } + *prev = fxcalloc(1, sizeof(PagerWindow)); + handle_config_win_package(*prev, cfgpacket); + AddNewWindow(*prev); + + return; +} + +void process_configure(unsigned long *body) +{ + PagerWindow *t; + struct ConfigWinPacket *cfgpacket = (void *)body; + bool is_new_desk; + + t = find_pager_window(cfgpacket->w); + if (t == NULL) + { + process_add(body); + return; + } + + is_new_desk = (t->desk != cfgpacket->desk); + handle_config_win_package(t, cfgpacket); + if (is_new_desk) + ChangeDeskForWindow(t, cfgpacket->desk); + MoveResizePagerView(t, true); +} + +void process_destroy(unsigned long *body) +{ + PagerWindow *t, **prev; + Window target_w; + + target_w = body[0]; + t = Start; + prev = &Start; + while(t != NULL && t->w != target_w) + { + prev = &(t->next); + t = t->next; + } + + if(t != NULL) + { + if(prev != NULL) + *prev = t->next; + /* remove window from the chain */ + + XDestroyWindow(dpy, t->PagerView); + XDestroyWindow(dpy, t->IconView); + if(FocusWin == t) + FocusWin = NULL; + + free(t->res_class); + free(t->res_name); + free(t->window_name); + free(t->icon_name); + free(t->window_label); + free(t); + } +} + +void process_monitor_focus(unsigned long *body) +{ + return; +} + +void process_focus(unsigned long *body) +{ + PagerWindow *t = find_pager_window(body[0]); + bool do_force_update = false; + + /* Update Pixels data. */ + if (Scr.focus_win_fg != body[3] || Scr.focus_win_bg != body[4]) + do_force_update = true; + Scr.focus_win_fg = body[3]; + Scr.focus_win_bg = body[4]; + + if (do_force_update || t != FocusWin) { + PagerWindow *focus = FocusWin; + FocusWin = t; + + update_window_background(focus); + update_window_background(t); + } +} + +void process_new_page(unsigned long *body) +{ + bool do_reconfigure = false; + int mon_num = body[7]; + struct monitor *m; + struct fpmonitor *fp; + + m = monitor_by_output(mon_num); + /* Don't allow monitor_by_output to fallback to RB_MIN. */ + if (m->si->rr_output != mon_num) + return; + + /* Still need to update the monitors when tracking a single + * monitor, but don't need to reconfigure anything. + */ + if (monitor_to_track != NULL && m == monitor_to_track->m) { + fp = monitor_to_track; + do_reconfigure = true; + } else { + fp = fpmonitor_this(m); + if (fp == NULL) + return; + do_reconfigure = true; + } + + fp->virtual_scr.Vx = fp->m->virtual_scr.Vx = body[0]; + fp->virtual_scr.Vy = fp->m->virtual_scr.Vy = body[1]; + if (fp->m->virtual_scr.CurrentDesk != body[2]) { + /* first handle the new desk */ + body[0] = body[2]; + body[1] = mon_num; + process_new_desk(body); + } + if (fp->virtual_scr.VxPages != body[5] || fp->virtual_scr.VyPages != body[6]) + { + fp->virtual_scr.VxPages = body[5]; + fp->virtual_scr.VyPages = body[6]; + fp->virtual_scr.VWidth = fp->virtual_scr.VxPages * fpmonitor_get_all_widths(); + fp->virtual_scr.VHeight = fp->virtual_scr.VyPages * fpmonitor_get_all_heights(); + fp->virtual_scr.VxMax = fp->virtual_scr.VWidth - fpmonitor_get_all_widths(); + fp->virtual_scr.VyMax = fp->virtual_scr.VHeight - fpmonitor_get_all_heights(); + if (do_reconfigure) + ReConfigure(); + } + + if (do_reconfigure) { + MovePage(); + MoveStickyWindows(true, false); + update_window_background(FocusWin); + } +} + +void process_new_desk(unsigned long *body) +{ + int oldDesk, newDesk; + int mon_num = body[1]; + struct monitor *mout; + struct fpmonitor *fp; + DeskStyle *style; + + mout = monitor_by_output(mon_num); + /* Don't allow monitor_by_output to fallback to RB_MIN. */ + if (mout->si->rr_output != mon_num) + return; + + fp = fpmonitor_this(mout); + if (fp == NULL) + return; + + /* Best to update the desk, even if the monitor isn't being + * tracked, as this could change. + */ + oldDesk = fp->m->virtual_scr.CurrentDesk; + newDesk = fp->m->virtual_scr.CurrentDesk = (long)body[0]; + if (newDesk >= desk1 && newDesk <= desk2) + Desks[newDesk - desk1].fp = fp; + + /* Only update FvwmPager's desk for the monitors being tracked. + * Exceptions: + * + If CurrentDeskPerMonitor is set, always update desk. + * + If current_monitor is set, only update if that monitor changes + * and tracking is per-monitor or shared. + */ + if (!CurrentDeskPerMonitor && ((monitor_to_track != NULL && + mout != monitor_to_track->m) || + (current_monitor != NULL && + monitor_to_track == NULL && + mout != current_monitor->m && + (monitor_mode == MONITOR_TRACKING_M || + is_tracking_shared)))) + { + /* Still need to update monitor location of other monitors. */ + if (current_monitor != NULL && oldDesk != newDesk) + goto update_grid; + return; + } + + /* Update the current desk. */ + desk_i = newDesk; + style = FindDeskStyle(newDesk); + /* Create and update GCs if needed. */ + if (oldDesk != newDesk) { + if (style->label_gc) + update_desk_style_gcs(style); + else + initialize_desk_style_gcs(style); + } + + /* Keep monitors in sync when tracking is global. */ + if (monitor_mode == MONITOR_TRACKING_G) + monitor_assign_virtual(fp->m); + + /* If always tracking current desk. Update Desks[0]. */ + if (fAlwaysCurrentDesk && oldDesk != newDesk) + { + PagerWindow *t; + + desk1 = desk2 = newDesk; + for (t = Start; t != NULL; t = t->next) + { + if (t->desk == oldDesk || t->desk == newDesk) + ChangeDeskForWindow(t, t->desk); + } + + /* Update DeskStyle */ + Desks[0].style = style; + update_desk_background(0); + update_monitor_locations(0); + update_monitor_backgrounds(0); + ReConfigureAll(); + } + + XStoreName(dpy, Scr.pager_w, style->label); + XSetIconName(dpy, Scr.pager_w, style->label); + +update_grid: + MovePage(); + draw_desk_grid(oldDesk - desk1); + draw_desk_grid(newDesk - desk1); + MoveStickyWindows(false, true); + update_window_background(FocusWin); +} + +void process_raise(unsigned long *body) +{ + PagerWindow *t = find_pager_window(body[0]); + + if (t == NULL) + return; + + XRaiseWindow(dpy, t->PagerView); + XRaiseWindow(dpy, t->IconView); +} + +void process_lower(unsigned long *body) +{ + struct fpmonitor *fp; + PagerWindow *t = find_pager_window(body[0]); + + if (t == NULL) + return; + + XLowerWindow(dpy, t->PagerView); + if (HilightDesks && t->desk >= desk1 && t->desk <= desk2) { + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + XLowerWindow(dpy, fp->CPagerWin[t->desk - desk1]); + } + } + XLowerWindow(dpy, t->IconView); +} + +void process_iconify(unsigned long *body) +{ + PagerWindow *t = find_pager_window(body[0]); + + if (t == NULL) + return; + + t->frame = body[1]; + t->icon_x = body[3]; + t->icon_y = body[4]; + t->icon_width = body[5]; + t->icon_height = body[6]; + SET_ICONIFIED(t, true); + if (IS_ICON_SUPPRESSED(t) || t->icon_width == 0 || + t->icon_height == 0) + { + t->x = -32768; + t->y = -32768; + } + else + { + t->x = t->icon_x; + t->y = t->icon_y; + } + t->width = t->icon_width; + t->height = t->icon_height; + + /* if iconifying main pager window turn balloons on or off */ + if (t->w == Scr.pager_w) + Balloon.show = Balloon.show_in_icon; + MoveResizePagerView(t, true); +} + +void process_deiconify(unsigned long *body, unsigned long length) +{ + PagerWindow *t = find_pager_window(body[0]); + + if (t == NULL) + return; + + SET_ICONIFIED(t, false); + if (length >= 11 + FvwmPacketHeaderSize) + { + t->frame_x = body[7]; + t->frame_y = body[8]; + t->frame_width = body[9]; + t->frame_height = body[10]; + } + t->x = t->frame_x; + t->y = t->frame_y; + t->width = t->frame_width; + t->height = t->frame_height; + + /* if deiconifying main pager window turn balloons on or off */ + if (t->w == Scr.pager_w) + Balloon.show = Balloon.show_in_pager; + + MoveResizePagerView(t, true); +} + +void process_window_name(unsigned long *body, unsigned long type) +{ + PagerWindow *t = find_pager_window(body[0]); + + if (t == NULL) + return; + + switch (type) { + case M_RES_CLASS: + free(t->res_class); + CopyString(&t->res_class, (char *)(&body[3])); + break; + case M_RES_NAME: + free(t->res_name); + CopyString(&t->res_name, (char *)(&body[3])); + break; + case M_VISIBLE_NAME: + free(t->window_name); + CopyString(&t->window_name, (char *)(&body[3])); + break; + } + + /* repaint by clearing window */ + if (FwindowFont != NULL && t->icon_name != NULL && + !(MiniIcons && t->mini_icon.picture)) + { + XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); + XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); + } + if (Balloon.is_mapped) + { + /* update balloons */ + UnmapBalloonWindow(); + MapBalloonWindow(t, Balloon.is_icon); + } +} + +void process_icon_name(unsigned long *body) +{ + PagerWindow *t = find_pager_window(body[0]); + + if (t == NULL) + return; + + free(t->icon_name); + CopyString(&t->icon_name, (char *)(&body[3])); + /* repaint by clearing window */ + if (FwindowFont != NULL && t->icon_name != NULL && + !(MiniIcons && t->mini_icon.picture)) + { + XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); + XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); + } +} + +void process_mini_icon(unsigned long *body) +{ + MiniIconPacket *mip = (MiniIconPacket *) body; + PagerWindow *t = find_pager_window(mip->w); + + if (t == NULL) + return; + + t->mini_icon.width = mip->width; + t->mini_icon.height = mip->height; + t->mini_icon.depth = mip->depth; + t->mini_icon.picture = mip->picture; + t->mini_icon.mask = mip->mask; + t->mini_icon.alpha = mip->alpha; + /* repaint by clearing window */ + if (MiniIcons && t->mini_icon.picture) { + XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); + XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); + } +} + +void process_restack(unsigned long *body, unsigned long length) +{ + PagerWindow *t; + PagerWindow *pager_wins[length]; + Window *wins; + int i, j, desk; + + wins = fxmalloc(length * sizeof (Window)); + + /* Should figure out how to do this with a single loop of the list, + * not one per desk + icon window. + */ + + /* first restack in the icon view */ + j = 0; + for (i = 0; i < (length - FvwmPacketHeaderSize); i += 3) + { + t = find_pager_window(body[i]); + if (t != NULL) { + pager_wins[j] = t; + wins[j++] = t->IconView; + } + } + XRestackWindows(dpy, wins, j); + length = j; + + /* now restack each desk separately, since they have separate roots */ + for (desk = 0; desk < ndesks; desk++) + { + j = 0; + for (i = 0; i < length; i++) + { + t = pager_wins[i]; + if (t != NULL && t->desk == desk + desk1) + wins[j++] = t->PagerView; + } + XRestackWindows(dpy, wins, j); + } + + free(wins); +} + +void process_end(void) +{ + unsigned int nchildren, i; + Window root, parent, *children; + PagerWindow *ptr; + + if (!XQueryTree(dpy, Scr.Root, &root, &parent, &children, &nchildren)) + return; + + for(i = 0; i < nchildren; i++) + { + ptr = Start; + while(ptr != NULL) + { + if (ptr->frame == children[i] || + ptr->icon_w == children[i] || + ptr->icon_pixmap_w == children[i]) + { + XRaiseWindow(dpy, ptr->PagerView); + XRaiseWindow(dpy, ptr->IconView); + } + ptr = ptr->next; + } + } + + if (nchildren > 0) + XFree((char *)children); +} + +void process_config_info(unsigned long *body) +{ + struct fpmonitor *m; + char *tline, *token; + + tline = (char*)&(body[3]); + token = PeekToken(tline, &tline); + if (StrEquals(token, "Colorset")) + { + int color; + DeskStyle *style; + + color = LoadColorset(tline); + TAILQ_FOREACH(style, &desk_style_q, entry) { + if (style->cs == color || style->hi_cs == color) + { + update_desk_style_gcs(style); + if (style->desk < desk1 || style->desk > desk2) + continue; + + update_desk_background(style->desk - desk1); + update_monitor_backgrounds(style->desk - desk1); + } + if (style->win_cs == color || style->focus_cs == color) { + PagerWindow *t = Start; + + update_desk_style_gcs(style); + while (t != NULL) { + if (t->desk != style->desk) { + t = t->next; + continue; + } + update_desk_style_gcs(style); + update_window_background(t); + update_window_decor(t); + t = t->next; + } + } + } + } + else if (StrEquals(token, "DesktopName")) + { + int val; + if (GetIntegerArguments(tline, &tline, &val, 1) > 0) + { + set_desk_label(val, (const char *)tline); + } + else + { + return; + } + if (fAlwaysCurrentDesk) + { + TAILQ_FOREACH(m, &fp_monitor_q, entry) { + if (m->m->virtual_scr.CurrentDesk == val) + val = 0; + } + } + else if ((val >= desk1) && (val <=desk2)) + { + val = val - desk1; + } + draw_desk_grid(val); + } else if (StrEquals(token, "Monitor")) { + parse_monitor_line(tline); + ReConfigure(); + } else if (StrEquals(token, "DesktopSize")) { + parse_desktop_size_line(tline); + } else if (StrEquals(token, "DesktopConfiguration")) { + parse_desktop_configuration_line(tline); + } +} + +void process_property_change(unsigned long *body) +{ + if (body[0] == MX_PROPERTY_CHANGE_BACKGROUND) + { + if (((!Swallowed && body[2] == 0) || + (Swallowed && body[2] == Scr.pager_w))) + update_pr_transparent_windows(); + } + else if (body[0] == MX_PROPERTY_CHANGE_SWALLOW && + body[2] == Scr.pager_w) + { + Swallowed = body[1]; + } +} + +void process_reply(unsigned long *body) +{ + char *tline; + tline = (char*)&(body[3]); + + if (strcmp(tline, "ScrollDone") == 0) + HandleScrollDone(); +} + +/* These methods are also used in parse_options in init_pager.c */ +void set_desk_label(int desk, const char *label) +{ + DeskStyle *style = FindDeskStyle(desk); + + free(style->label); + CopyString(&(style->label), label); +} + +void set_desk_size(bool update_label) +{ + if (update_label) { + label_h = 0; + if (use_desk_label) + label_h += Ffont->height + 2; + if (use_monitor_label) + label_h += Ffont->height + 2; + } + + desk_w = (pwindow.width - Columns + 1) / Columns; + desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; + + return; +} + +void parse_monitor_line(char *tline) +{ + int dx, dy, Vx, Vy, VxMax, VyMax, CurrentDesk; + int scr_width, scr_height; + int flags; + char *mname; + struct monitor *tm; + struct fpmonitor *fp; + + tline = GetNextToken(tline, &mname); + + sscanf(tline, "%d %d %d %d %d %d %d %d %d %d", &flags, + &dx, &dy, &Vx, &Vy, &VxMax, &VyMax, &CurrentDesk, + &scr_width, &scr_height); + + monitor_refresh_module(dpy); + + tm = monitor_resolve_name(mname); + if (tm == NULL) + return; + + if (flags & MONITOR_DISABLED) { + fp = fpmonitor_by_name(mname); + if (fp != NULL) { + bool disabled = fp->disabled; + fpmonitor_disable(fp); + if (!disabled) + ReConfigure(); + } + return; + } + + if ((fp = fpmonitor_this(tm)) == NULL) { + if (fp_new_block) + return; + fp_new_block = true; + fp = fpmonitor_new(tm); + fp->m->flags |= MONITOR_NEW; + } + + /* This ensures that if monitor_to_track gets disconnected + * then reconnected, the pager can resume tracking it. + */ + if (preferred_monitor != NULL && + strcmp(fp->m->si->name, preferred_monitor) == 0) + { + monitor_to_track = fp; + } + fp->disabled = false; + fp->scr_width = scr_width; + fp->scr_height = scr_height; + fp->m->dx = dx; + fp->m->dy = dy; + fp->m->virtual_scr.Vx = fp->virtual_scr.Vx = Vx; + fp->m->virtual_scr.Vy = fp->virtual_scr.Vy = Vy; + fp->m->virtual_scr.VxMax = fp->virtual_scr.VxMax = VxMax; + fp->m->virtual_scr.VyMax = fp->virtual_scr.VyMax = VyMax; + fp->m->virtual_scr.CurrentDesk = CurrentDesk; + + fp->virtual_scr.VxMax = dx * fpmonitor_get_all_widths() - fpmonitor_get_all_widths(); + fp->virtual_scr.VyMax = dy * fpmonitor_get_all_heights() - fpmonitor_get_all_heights(); + if (fp->virtual_scr.VxMax < 0) + fp->virtual_scr.VxMax = 0; + if (fp->virtual_scr.VyMax < 0) + fp->virtual_scr.VyMax = 0; + fp->virtual_scr.VWidth = fp->virtual_scr.VxMax + fpmonitor_get_all_widths(); + fp->virtual_scr.VHeight = fp->virtual_scr.VyMax + fpmonitor_get_all_heights(); + fp->virtual_scr.VxPages = fp->virtual_scr.VWidth / fpmonitor_get_all_widths(); + fp->virtual_scr.VyPages = fp->virtual_scr.VHeight / fpmonitor_get_all_heights(); + + if (fp->m != NULL && fp->m->flags & MONITOR_NEW) { + fp->m->flags &= ~MONITOR_NEW; + initialize_fpmonitor_windows(fp); + } + fp_new_block = false; +} + +void parse_desktop_size_line(char *tline) +{ + int dx, dy; + struct fpmonitor *m; + + sscanf(tline, "%d %d", &dx, &dy); + + TAILQ_FOREACH(m, &fp_monitor_q, entry) { + m->virtual_scr.VxMax = dx * fpmonitor_get_all_widths() - fpmonitor_get_all_widths(); + m->virtual_scr.VyMax = dy * fpmonitor_get_all_heights() - fpmonitor_get_all_heights(); + if (m->virtual_scr.VxMax < 0) + m->virtual_scr.VxMax = 0; + if (m->virtual_scr.VyMax < 0) + m->virtual_scr.VyMax = 0; + m->virtual_scr.VWidth = m->virtual_scr.VxMax + fpmonitor_get_all_widths(); + m->virtual_scr.VHeight = m->virtual_scr.VyMax + fpmonitor_get_all_heights(); + m->virtual_scr.VxPages = m->virtual_scr.VWidth / fpmonitor_get_all_widths(); + m->virtual_scr.VyPages = m->virtual_scr.VHeight / fpmonitor_get_all_heights(); + } +} + +void parse_desktop_configuration_line(char *tline) +{ + int mmode, is_shared; + + sscanf(tline, "%d %d", &mmode, &is_shared); + + if (mmode > 0) { + monitor_mode = mmode; + is_tracking_shared = is_shared; + } +} + +void update_monitor_to_track(struct fpmonitor **fp_track, + char *name, bool update_prefered) +{ + struct fpmonitor *new_fp; + + name = SkipSpaces(name, NULL, 0); + if (StrEquals(name, "none")) { + *fp_track = NULL; + if (update_prefered) { + free(preferred_monitor); + preferred_monitor = NULL; + } + return; + } + + new_fp = fpmonitor_by_name(name); + /* Fallback to current monitor, if monitor not already set. */ + if (new_fp != NULL) + *fp_track = new_fp; + else if (*fp_track == NULL) + *fp_track = fpmonitor_this(NULL); + if (update_prefered) { + /* Set this even if no monitor matches given name. + * That monitor may get enabled later. + */ + free(preferred_monitor); + preferred_monitor = fxstrdup(name); + } +} diff --git a/modules/FvwmPager/x_pager.c b/modules/FvwmPager/x_pager.c index b9be0da1b..2004b73a8 100644 --- a/modules/FvwmPager/x_pager.c +++ b/modules/FvwmPager/x_pager.c @@ -30,55 +30,46 @@ #include #include -#include "libs/FScreen.h" -#include "libs/fvwmlib.h" #include "libs/FShape.h" #include "libs/Module.h" -#include "libs/Colorset.h" -#include "libs/Graphics.h" -#include "fvwm/fvwm.h" -#include "libs/PictureGraphics.h" #include "libs/FEvent.h" +#include "fvwm/fvwm.h" #include "FvwmPager.h" -static Atom wm_del_win; -static int desk_w = 0; -static int desk_h = 0; -static int label_h = 0; +Atom wm_del_win; +int desk_w = 0; +int desk_h = 0; +int label_h = 0; static int Wait = 0; static int MyVx, MyVy; /* copy of Scr.Vx/y for drag logic */ static struct fpmonitor *ScrollFp = NULL; /* Stash monitor drag logic */ -/* assorted gray bitmaps for decorative borders */ -#define g_width 2 -#define g_height 2 -static char g_bits[] = {0x02, 0x01}; - -#define l_g_width 4 -#define l_g_height 2 -static char l_g_bits[] = {0x08, 0x02}; - -#define s_g_width 4 -#define s_g_height 4 -static char s_g_bits[] = {0x01, 0x02, 0x04, 0x08}; - -#define label_border g_width - -static int FvwmErrorHandler(Display *, XErrorEvent *); +static void do_scroll( + int sx, int sy, bool do_send_message, bool is_message_recieved); +static int _pred_weed_window_events( + Display *display, XEvent *current_event, XPointer arg); +static void discard_events(long event_type, Window w, XEvent *last_ev); static rectangle CalcGeom(PagerWindow *, bool); -static void HideWindow(PagerWindow *, Window); -static void MoveResizeWindow(PagerWindow *, bool, bool); -static void DrawInBalloonWindow(void); -static rectangle set_vp_size_and_loc(struct fpmonitor *, bool is_icon); -static struct fpmonitor *fpmonitor_from_xy(int x, int y); -static struct fpmonitor *fpmonitor_from_n(int n); -static int fpmonitor_count(void); static void fvwmrec_to_pager(rectangle *, bool, struct fpmonitor *); static void pagerrec_to_fvwm(rectangle *, bool, struct fpmonitor *); -static char *get_label(const PagerWindow *pw,const char *fmt); -static int is_window_visible(PagerWindow *t); +static void UpdateWindowShape(void); +static void HandleEnterNotify(XEvent *Event); +static void HandleExpose(XEvent *Event); static void draw_desk_label(const char *label, const char *small, int desk, int x, int y, int width, int height, bool hilight); +static void draw_icon_grid(int erase); +static void SwitchToDesk(int Desk, struct fpmonitor *m); +static void SwitchToDeskAndPage(int Desk, XEvent *Event); +static void IconSwitchPage(XEvent *Event); +static void HideWindow(PagerWindow *, Window); +static void MoveResizeWindow(PagerWindow *, bool, bool); +static int is_window_visible(PagerWindow *t); +static void Scroll(int x, int y, int Desk, bool do_scroll_icon); +static void MoveWindow(XEvent *Event); +static void IconMoveWindow(XEvent *Event, PagerWindow *t); +static void setup_balloon_window(PagerWindow *t); +static void InsertExpand(char **dest, char *s); +static void DrawInBalloonWindow(void); #define MAX_UNPROCESSED_MESSAGES 1 /* sums up pixels to scroll. If do_send_message is true a Scroll command is @@ -166,83 +157,6 @@ static void discard_events(long event_type, Window w, XEvent *last_ev) return; } -int fpmonitor_get_all_widths(void) -{ - struct fpmonitor *fp = TAILQ_FIRST(&fp_monitor_q); - - if (fp->scr_width <= 0) - return (monitor_get_all_widths()); - - return (fp->scr_width); -} - -int fpmonitor_get_all_heights(void) -{ - struct fpmonitor *fp = TAILQ_FIRST(&fp_monitor_q); - - if (fp->scr_height <= 0) - return (monitor_get_all_heights()); - return (fp->scr_height); -} - -int fpmonitor_count(void) -{ - struct fpmonitor *fp; - int c = 0; - - TAILQ_FOREACH(fp, &fp_monitor_q, entry) - if (!fp->disabled) - c++; - return (c); -} - -static struct fpmonitor *fpmonitor_from_n(int n) -{ - struct fpmonitor *fp; - int c = 0; - - TAILQ_FOREACH(fp, &fp_monitor_q, entry) { - if (fp->disabled) - continue; - if (c == n) - return fp; - c++; - } - return fp; -} - -struct fpmonitor *fpmonitor_from_desk(int desk) -{ - struct fpmonitor *fp; - - TAILQ_FOREACH(fp, &fp_monitor_q, entry) - if (!fp->disabled && fp->m->virtual_scr.CurrentDesk == desk) - return fp; - - return NULL; -} - -static struct fpmonitor *fpmonitor_from_xy(int x, int y) -{ - struct fpmonitor *fp; - - if (monitor_to_track == NULL && monitor_mode != MONITOR_TRACKING_G) { - x %= fpmonitor_get_all_widths(); - y %= fpmonitor_get_all_heights(); - - TAILQ_FOREACH(fp, &fp_monitor_q, entry) - if (x >= fp->m->si->x && - x < fp->m->si->x + fp->m->si->w && - y >= fp->m->si->y && - y < fp->m->si->y + fp->m->si->h) - return fp; - } else { - return fpmonitor_this(NULL); - } - - return NULL; -} - static rectangle CalcGeom(PagerWindow *t, bool is_icon) { /* Place initial rectangle off screen. */ @@ -313,306 +227,6 @@ static rectangle CalcGeom(PagerWindow *t, bool is_icon) return rec; } -/* - * - * Procedure: - * Initialize_viz_pager - creates a temp window of the correct visual - * so that pixmaps may be created for use with the main window - */ -void initialize_viz_pager(void) -{ - XSetWindowAttributes attr; - XGCValues xgcv; - - /* FIXME: I think that we only need that Pdepth == - * DefaultDepth(dpy, Scr.screen) to use the Scr.Root for Scr.pager_w */ - if (Pdefault) - { - Scr.pager_w = Scr.Root; - } - else - { - attr.background_pixmap = None; - attr.border_pixel = 0; - attr.colormap = Pcmap; - Scr.pager_w = XCreateWindow( - dpy, Scr.Root, -10, -10, 10, 10, 0, Pdepth, - InputOutput, Pvisual, - CWBackPixmap|CWBorderPixel|CWColormap, &attr); - Scr.NormalGC = fvwmlib_XCreateGC(dpy, Scr.pager_w, 0, &xgcv); - } - Scr.NormalGC = fvwmlib_XCreateGC(dpy, Scr.pager_w, 0, NULL); - - xgcv.plane_mask = AllPlanes; - Scr.MiniIconGC = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCPlaneMask, &xgcv); - - /* Transparent background are only allowed when the depth matched the - * root */ - if (Pdepth == DefaultDepth(dpy, Scr.screen)) - { - default_pixmap = ParentRelative; - } - - return; -} - -void set_desk_size(bool update_label) -{ - if (update_label) { - label_h = 0; - if (use_desk_label) - label_h += Ffont->height + 2; - if (use_monitor_label) - label_h += Ffont->height + 2; - } - - desk_w = (pwindow.width - Columns + 1) / Columns; - desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; - - return; -} - -void update_monitor_locations(int i) -{ - if (!HilightDesks) - return; - - struct fpmonitor *fp; - - TAILQ_FOREACH(fp, &fp_monitor_q, entry) { - if (fp->disabled) - continue; - - rectangle vp = set_vp_size_and_loc(fp, false); - - /* Conditions to show a monitor view port are: - * + Never show monitors not being tracked. - * + Always shown when CurrntDeskPerMonitor is in use. - * + Otherwise only show monitors on desk. - */ - if ((monitor_to_track == NULL || monitor_to_track == fp) && - ((CurrentDeskPerMonitor && fAlwaysCurrentDesk) || - fp->m->virtual_scr.CurrentDesk == i + desk1)) - { - XMoveResizeWindow(dpy, fp->CPagerWin[i], - vp.x, vp.y, vp.width, vp.height); - } else { - XMoveResizeWindow(dpy, fp->CPagerWin[i], - -32768, -32768, vp.width, vp.height); - } - } -} - -void update_monitor_backgrounds(int desk) -{ - if (!HilightDesks) - return; - - rectangle vp; - struct fpmonitor *fp; - DeskStyle *style = Desks[desk].style; - - TAILQ_FOREACH(fp, &fp_monitor_q, entry) { - if (CurrentDeskPerMonitor && fAlwaysCurrentDesk) - style = FindDeskStyle(fp->m->virtual_scr.CurrentDesk); - - if (style->hi_cs < 0) { - if (style->hiPixmap != NULL) - XSetWindowBackgroundPixmap(dpy, - fp->CPagerWin[desk], - style->hiPixmap->picture); - else - XSetWindowBackground(dpy, - fp->CPagerWin[desk], style->hi_bg); - } else { - vp = set_vp_size_and_loc(fp, false); - SetWindowBackground(dpy, - fp->CPagerWin[desk], vp.width, vp.height, - &Colorset[style->hi_cs], Pdepth, - style->hi_bg_gc, True); - } - XLowerWindow(dpy, fp->CPagerWin[desk]); - XClearWindow(dpy, fp->CPagerWin[desk]); - } -} - -void update_desk_background(int desk) -{ - DeskStyle *style = Desks[desk].style; - - XSetWindowBorder(dpy, Desks[desk].title_w, style->fg); - XSetWindowBorder(dpy, Desks[desk].w, style->fg); - - if (style->cs < 0) { - XSetWindowBorder(dpy, Desks[desk].title_w, style->fg); - XSetWindowBorder(dpy, Desks[desk].w, style->fg); - if (style->bgPixmap != NULL) { - if (style->use_label_pixmap) - XSetWindowBackgroundPixmap(dpy, - Desks[desk].title_w, - style->bgPixmap->picture); - else - XSetWindowBackgroundPixmap(dpy, - Desks[desk].w, - style->bgPixmap->picture); - } else { - XSetWindowBackground(dpy, - Desks[desk].title_w, style->bg); - XSetWindowBackground(dpy, - Desks[desk].w, style->bg); - } - } else { - if (style->use_label_pixmap) - SetWindowBackground(dpy, - Desks[desk].title_w, desk_w, desk_h + label_h, - &Colorset[style->cs], Pdepth, Scr.NormalGC, - True); - else - SetWindowBackground(dpy, - Desks[desk].w, desk_w, desk_h, - &Colorset[style->cs], Pdepth, Scr.NormalGC, - True); - } - - XClearWindow(dpy, Desks[desk].title_w); - XClearWindow(dpy, Desks[desk].w); -} - -void update_window_background(PagerWindow *t) -{ - if (t == NULL || t->PagerView == None || t->IconView == None) - return; - - if (Pdepth < 2) - { - if (t == FocusWin) { - XSetWindowBackgroundPixmap( - dpy, t->PagerView, Scr.gray_pixmap); - XSetWindowBackgroundPixmap( - dpy, t->IconView, Scr.gray_pixmap); - } else if (IS_STICKY_ACROSS_DESKS(t) || - IS_STICKY_ACROSS_PAGES(t)) - { - XSetWindowBackgroundPixmap(dpy, t->PagerView, - Scr.sticky_gray_pixmap); - XSetWindowBackgroundPixmap(dpy, t->IconView, - Scr.sticky_gray_pixmap); - } else { - XSetWindowBackgroundPixmap(dpy, t->PagerView, - Scr.light_gray_pixmap); - XSetWindowBackgroundPixmap(dpy, t->IconView, - Scr.light_gray_pixmap); - } - XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); - XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); - return; - } - - int cs = -1; - Pixel pix = None; - DeskStyle *style = FindDeskStyle(t->desk); - - if (t == FocusWin) { - if (style->focus_cs >= 0) { - cs = style->focus_cs; - } else if (style->focus_bg) { - pix = style->focus_bg; - } else { - pix = Scr.focus_win_bg; - } - } else { - if (style->win_cs >= 0) { - cs = style->win_cs; - } else if (style->win_bg) { - pix = style->win_bg; - } else { - pix = t->back; - } - } - - if (cs >= 0) { - SetWindowBackground(dpy, t->PagerView, - t->pager_view.width, t->pager_view.height, - &Colorset[cs], Pdepth, Scr.NormalGC, True); - SetWindowBackground(dpy, t->IconView, - t->icon_view.width, t->icon_view.height, - &Colorset[cs], Pdepth, Scr.NormalGC, True); - } else if (pix != None) { - XSetWindowBackground(dpy, t->PagerView, pix); - XSetWindowBackground(dpy, t->IconView, pix); - } - - XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); - XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); -} - -/* - * - * Procedure: - * Initialize_pager - creates the pager window, if needed - * - * Inputs: - * x,y location of the window - * - */ -XSizeHints sizehints = -{ - (PWinGravity), /* flags */ - 0, 0, 100, 100, /* x, y, width and height (legacy) */ - 1, 1, /* Min width and height */ - 0, 0, /* Max width and height */ - 1, 1, /* Width and height increments */ - {0, 0}, {0, 0}, /* Aspect ratio */ - 1, 1, /* base size */ - (NorthWestGravity) /* gravity */ -}; - -/* create balloon window -- ric@giccs.georgetown.edu */ -void initialize_balloon_window(void) -{ - XGCValues xgcv; - unsigned long valuemask; - XSetWindowAttributes attributes; - - Balloon.is_mapped = false; - if (!(Balloon.show_in_pager || Balloon.show_in_icon)) { - Scr.balloon_w = None; - return; - } - - /* Set some defaults */ - if (Balloon.border_width <= 0) - Balloon.border_width = DEFAULT_BALLOON_BORDER_WIDTH; - if (Balloon.y_offset == 0) - /* we don't allow y_offset of 0 because it allows direct - * transit from pager window to balloon window, setting - * up a LeaveNotify/EnterNotify event loop. - */ - Balloon.y_offset = DEFAULT_BALLOON_Y_OFFSET; - if (Balloon.label_format == NULL) - Balloon.label_format = fxstrdup("%i"); - - valuemask = CWOverrideRedirect | CWEventMask | CWColormap; - /* tell WM to ignore this window */ - attributes.override_redirect = true; - attributes.event_mask = ExposureMask; - attributes.colormap = Pcmap; - /* now create the window */ - Scr.balloon_w = XCreateWindow( - dpy, Scr.Root, 0, 0, /* coords set later */ 1, 1, - Balloon.border_width, Pdepth, InputOutput, Pvisual, valuemask, - &attributes); - - /* Initialize, actual values will be updated later. */ - valuemask = GCForeground; - xgcv.foreground = GetSimpleColor("black"); - Balloon.Ffont = FlocaleLoadFont(dpy, BalloonFont, MyName); - Balloon.gc = fvwmlib_XCreateGC( - dpy, Scr.balloon_w, valuemask, &xgcv); - free(BalloonFont); -} - /* Computes pager size rectangle from fvwm size or visa versa */ static void fvwmrec_to_pager(rectangle *rec, bool is_icon, struct fpmonitor *fp) @@ -687,8 +301,7 @@ pagerrec_to_fvwm(rectangle *rec, bool is_icon, struct fpmonitor *fp) rec->y = (rec->y * m_height) / scale_h + offset_y; } -static rectangle -set_vp_size_and_loc(struct fpmonitor *m, bool is_icon) +rectangle set_vp_size_and_loc(struct fpmonitor *m, bool is_icon) { int Vx = 0, Vy = 0, vp_w, vp_h; rectangle vp = {0, 0, 0, 0}; @@ -718,503 +331,6 @@ set_vp_size_and_loc(struct fpmonitor *m, bool is_icon) return vp; } -void initialise_common_pager_fragments(void) -{ - extern char *font_string, *smallFont; - DeskStyle *style = FindDeskStyle(-1); - - /* I don't think that this is necessary - just let pager die */ - /* domivogt (07-mar-1999): But it is! A window being moved in the pager - * might die at any moment causing the Xlib calls to generate BadMatch - * errors. Without an error handler the pager will die! */ - XSetErrorHandler(FvwmErrorHandler); - - wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); - - /* load the font */ - /* Note: "font" is always created, whether labels are used or not - because a GC below is set to use a font. dje Dec 2001. - OK, I fixed the GC below, but now something else is blowing up. - Right now, I've got to do some Real Life stuff, so this kludge is - in place, its still better than I found it. - I hope that I've fixed this (olicha) - */ - Ffont = FlocaleLoadFont(dpy, font_string, MyName); - - /* init our Flocale window string */ - FlocaleAllocateWinString(&FwinString); - - /* Check that shape extension exists. */ - if (FHaveShapeExtension && ShapeLabels) - { - ShapeLabels = (FShapesSupported) ? 1 : 0; - } - - if(smallFont != NULL) - { - FwindowFont = FlocaleLoadFont(dpy, smallFont, MyName); - } - - /* Load pixmaps for mono use */ - if (Pdepth < 2) - { - Scr.gray_pixmap = XCreatePixmapFromBitmapData( - dpy, Scr.pager_w, g_bits, g_width, g_height, - style->fg, style->bg, Pdepth); - Scr.light_gray_pixmap = XCreatePixmapFromBitmapData( - dpy, Scr.pager_w, l_g_bits, l_g_width, l_g_height, - style->fg, style->bg, Pdepth); - Scr.sticky_gray_pixmap = XCreatePixmapFromBitmapData( - dpy, Scr.pager_w, s_g_bits, s_g_width, s_g_height, - style->fg, style->bg, Pdepth); - } - - /* Size the window */ - if(Rows < 0) - { - if(Columns <= 0) - { - Columns = ndesks; - Rows = 1; - } - else - { - Rows = ndesks/Columns; - if(Rows*Columns < ndesks) - Rows++; - } - } - if(Columns < 0) - { - if (Rows == 0) - Rows = 1; - Columns = ndesks/Rows; - if(Rows*Columns < ndesks) - Columns++; - } - - if(Rows*Columns < ndesks) - { - if (Columns == 0) - Columns = 1; - Rows = ndesks/Columns; - if (Rows*Columns < ndesks) - Rows++; - } - set_desk_size(true); -} - -void initialize_fpmonitor_windows(struct fpmonitor *fp) -{ - /* No need to create windows if not using HilightDesks. */ - if (!HilightDesks) - return; - - int i; - unsigned long valuemask; - XSetWindowAttributes attributes; - rectangle vp = set_vp_size_and_loc(fp, false); - - attributes.colormap = Pcmap; - for (i = 0; i < ndesks; i++) { - valuemask = CWColormap; - if (Desks[i].style->hiPixmap || - (Desks[i].style->hi_cs > -1 && - Colorset[Desks[i].style->hi_cs].pixmap)) - { - valuemask |= CWBackPixmap; - attributes.background_pixmap = None; /* set later */ - } else { - valuemask |= CWBackPixel; - attributes.background_pixel = Desks[i].style->hi_bg; - } - - fp->CPagerWin[i] = XCreateWindow(dpy, Desks[i].w, - -32768, -32768, vp.width, vp.height, 0, - CopyFromParent, InputOutput, - CopyFromParent, valuemask, - &attributes); - XMapRaised(dpy, fp->CPagerWin[i]); - update_monitor_locations(i); - update_monitor_backgrounds(i); - } -} - -void update_desk_style_gcs(DeskStyle *style) -{ - if (style->cs >= 0) { - style->fg = Colorset[style->cs].fg; - style->bg = Colorset[style->cs].bg; - } - if (style->hi_cs >= 0) { - style->hi_fg = Colorset[style->hi_cs].fg; - style->hi_bg = Colorset[style->hi_cs].bg; - } - if (style->win_cs >= 0) { - style->win_fg = Colorset[style->win_cs].fg; - style->win_bg = Colorset[style->win_cs].bg; - } - if (style->focus_cs >= 0) { - style->focus_fg = Colorset[style->focus_cs].fg; - style->focus_bg = Colorset[style->focus_cs].bg; - } - if (style->balloon_cs >= 0) { - style->balloon_fg = Colorset[style->balloon_cs].fg; - style->balloon_bg = Colorset[style->balloon_bg].bg; - } - - XSetForeground(dpy, style->label_gc, style->fg); - XSetForeground(dpy, style->dashed_gc, style->fg); - XSetForeground(dpy, style->hi_bg_gc, style->hi_bg); - XSetForeground(dpy, style->hi_fg_gc, style->hi_fg); - if (WindowBorders3d && style->win_cs > 0) { - XSetForeground(dpy, style->win_hi_gc, - Colorset[style->win_cs].hilite); - XSetForeground(dpy, style->win_sh_gc, - Colorset[style->win_cs].shadow); - } - if (WindowBorders3d && style->focus_cs > 0) { - XSetForeground(dpy, style->focus_hi_gc, - Colorset[style->focus_cs].hilite); - XSetForeground(dpy, style->focus_sh_gc, - Colorset[style->focus_cs].shadow); - } -} - -void initialize_desk_style_gcs(DeskStyle *style) -{ - XGCValues gcv; - char dash_list[2]; - - /* Desk labels GC. */ - gcv.foreground = style->fg; - if (Ffont && Ffont->font) { - gcv.font = Ffont->font->fid; - style->label_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground | GCFont, &gcv); - } else { - style->label_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); - } - - /* Hilight GC, used for monitors and labels backgrounds. */ - gcv.foreground = (Pdepth < 2) ? style->bg : style->hi_bg; - style->hi_bg_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); - - /* create the hilight desk title drawing GC */ - gcv.foreground = (Pdepth < 2) ? style->fg : style->hi_fg; - if (Ffont && Ffont->font) - style->hi_fg_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground | GCFont, &gcv); - else - style->hi_fg_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); - - /* create the virtual page boundary GC */ - gcv.foreground = style->fg; - gcv.line_width = 1; - gcv.line_style = (use_dashed_separators) ? LineOnOffDash : LineSolid; - style->dashed_gc = fvwmlib_XCreateGC(dpy, - Scr.pager_w, GCForeground | GCLineStyle | GCLineWidth, &gcv); - if (use_dashed_separators) { - /* Although this should already be the default for a freshly - * created GC, some X servers do not draw properly dashed - * lines if the dash style is not set explicitly. - */ - dash_list[0] = 4; - dash_list[1] = 4; - XSetDashes(dpy, style->dashed_gc, 0, dash_list, 2); - } - - /* Window borders. */ - gcv.foreground = (style->win_cs) ? - Colorset[style->win_cs].hilite : style->fg; - style->win_hi_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); - gcv.foreground = (style->win_cs) ? - Colorset[style->win_cs].shadow : style->fg; - style->win_sh_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); - - /* Focus window borders. */ - gcv.foreground = (style->focus_cs) ? - Colorset[style->focus_cs].hilite : style->fg; - style->focus_hi_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); - gcv.foreground = (style->focus_cs) ? - Colorset[style->focus_cs].shadow : style->fg; - style->focus_sh_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); -} - -void initialize_desk_windows(int desk) -{ - unsigned long valuemask; - XSetWindowAttributes attributes; - DeskStyle *style = Desks[desk].style; - - /* Common settings for both title and desk window. */ - attributes.colormap = Pcmap; - attributes.background_pixmap = default_pixmap; - attributes.border_pixel = style->fg; - - /* Note, pixmaps are set to None to be updated later. */ - valuemask = (CWBorderPixel | CWColormap | CWEventMask); - if (style->use_label_pixmap && style->cs >= 0) { - if (Colorset[style->cs].pixmap) { - valuemask |= CWBackPixmap; - attributes.background_pixmap = None; - } else { - valuemask |= CWBackPixel; - attributes.background_pixel = style->bg; - } - } else if (style->use_label_pixmap && style->bgPixmap) { - valuemask |= CWBackPixmap; - attributes.background_pixmap = None; - } else { - valuemask |= CWBackPixel; - attributes.background_pixel = style->bg; - } - - attributes.event_mask = (ExposureMask | ButtonReleaseMask); - Desks[desk].title_w = XCreateWindow(dpy, Scr.pager_w, - -1, -1, desk_w, desk_h + label_h, 1, - CopyFromParent, InputOutput, CopyFromParent, - valuemask, &attributes); - - /* Create desk windows. */ - valuemask &= ~(CWBackPixel | CWBackPixmap); - if (style->cs >= 0) { - valuemask |= CWBackPixmap; - if (style->use_label_pixmap) { - attributes.background_pixmap = ParentRelative; - attributes.background_pixel = None; - } else { - valuemask |= CWBackPixel; - attributes.background_pixmap = None; - attributes.background_pixel = style->bg; - } - } else if (Desks[desk].style->bgPixmap) { - valuemask |= CWBackPixmap; - if (Desks[desk].style->use_label_pixmap) - attributes.background_pixmap = ParentRelative; - else - attributes.background_pixmap = None; - } else { - valuemask |= CWBackPixel; - attributes.background_pixel = Desks[desk].style->bg; - } - - attributes.event_mask = (ExposureMask | ButtonReleaseMask | - ButtonPressMask | ButtonMotionMask); - Desks[desk].w = XCreateWindow(dpy, Desks[desk].title_w, - -1, LabelsBelow ? -1 : label_h - 1, desk_w, desk_h, 1, - CopyFromParent, InputOutput, CopyFromParent, - valuemask, &attributes); - - XMapRaised(dpy, Desks[desk].title_w); - XMapRaised(dpy, Desks[desk].w); -} - -void initialize_pager(void) -{ - XWMHints wmhints; - XClassHint class1; - XTextProperty name; - unsigned long valuemask; - XSetWindowAttributes attributes; - int i = 0; - struct fpmonitor *fp = fpmonitor_this(NULL); - struct fpmonitor *m; - DeskStyle *style; - - int VxPages = fp->virtual_scr.VxPages, VyPages = fp->virtual_scr.VyPages; - - /* Set window size if not fully set by user to match */ - /* aspect ratio of monitor(s) being shown. */ - if ( pwindow.width == 0 || pwindow.height == 0 ) { - int vWidth = fpmonitor_get_all_widths(); - int vHeight = fpmonitor_get_all_heights(); - if (monitor_to_track != NULL || IsShared) { - vWidth = fp->m->si->w; - vHeight = fp->m->si->h; - } - - if (pwindow.width > 0) { - pwindow.height = (pwindow.width * vHeight) / vWidth + - label_h * Rows + Rows; - } else if (pwindow.height > label_h * Rows) { - pwindow.width = ((pwindow.height - label_h * Rows + Rows) * - vWidth) / vHeight + Columns; - } else { - pwindow.width = (VxPages * vWidth * Columns) / Scr.VScale + - Columns; - pwindow.height = (VyPages * vHeight * Rows) / Scr.VScale + - label_h * Rows + Rows; - } - } - set_desk_size(false); - - if (is_transient) - { - rectangle screen_g; - fscreen_scr_arg fscr; - - fscr.xypos.x = pwindow.x; - fscr.xypos.y = pwindow.y; - FScreenGetScrRect( - &fscr, FSCREEN_XYPOS, - &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); - /* FIXME: Recalculate what to do if window is off screen. */ - /* Leaving alone for now */ - if (pwindow.width + pwindow.x > screen_g.x + screen_g.width) - { - pwindow.x = screen_g.x + screen_g.width - fp->m->si->w; //fp->m->virtual_scr.MyDisplayWidth; - xneg = true; - } - if (pwindow.height + pwindow.y > screen_g.y + screen_g.height) - { - pwindow.y = screen_g.y + screen_g.height - fp->m->si->h; //fp->m->virtual_scr.MyDisplayHeight; - yneg = true; - } - } - if (xneg) - { - sizehints.win_gravity = NorthEastGravity; - pwindow.x = fpmonitor_get_all_widths() - pwindow.width + pwindow.x; - } - if (yneg) - { - pwindow.y = fpmonitor_get_all_heights() - pwindow.height + pwindow.y; - if(sizehints.win_gravity == NorthEastGravity) - sizehints.win_gravity = SouthEastGravity; - else - sizehints.win_gravity = SouthWestGravity; - } - - if(usposition) - sizehints.flags |= USPosition; - - valuemask = (CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask); - attributes.background_pixmap = default_pixmap; - attributes.border_pixel = 0; - attributes.colormap = Pcmap; - attributes.event_mask = (StructureNotifyMask); - - /* destroy the temp window first, don't worry if it's the Root */ - if (Scr.pager_w != Scr.Root) - XDestroyWindow(dpy, Scr.pager_w); - Scr.pager_w = XCreateWindow (dpy, Scr.Root, pwindow.x, pwindow.y, pwindow.width, - pwindow.height, 0, Pdepth, InputOutput, Pvisual, - valuemask, &attributes); - XSetWMProtocols(dpy,Scr.pager_w,&wm_del_win,1); - /* hack to prevent mapping on wrong screen with StartsOnScreen */ - FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS, &sizehints); - XSetWMNormalHints(dpy,Scr.pager_w,&sizehints); - if (is_transient) - { - XSetTransientForHint(dpy, Scr.pager_w, Scr.Root); - } - - if (FlocaleTextListToTextProperty( - dpy, &(Desks[0].style->label), 1, XStdICCTextStyle, &name) == 0) - { - fprintf(stderr,"%s: fatal error: cannot allocate desk name", MyName); - exit(0); - } - - attributes.event_mask = (StructureNotifyMask| ExposureMask); - if(icon.width < 1) - icon.width = (pwindow.width - Columns + 1) / Columns; - if(icon.height < 1) - icon.height = (pwindow.height - Rows * label_h - Rows + 1) / Rows; - - icon.width = (icon.width / (VxPages + 1)) * (VxPages + 1) + VxPages; - icon.height = (icon.height / (VyPages + 1)) * (VyPages + 1) + VyPages; - Scr.icon_w = XCreateWindow (dpy, Scr.Root, pwindow.x, pwindow.y, - icon.width, icon.height, - 0, Pdepth, InputOutput, Pvisual, valuemask, - &attributes); - XGrabButton(dpy, 1, AnyModifier, Scr.icon_w, - True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, - None); - XGrabButton(dpy, 2, AnyModifier, Scr.icon_w, - True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, - None); - XGrabButton(dpy, 3, AnyModifier, Scr.icon_w, - True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, - None); - - if (StartIconic) { - Balloon.show = Balloon.show_in_icon; - wmhints.initial_state = IconicState; - } else { - Balloon.show = Balloon.show_in_pager; - wmhints.initial_state = NormalState; - } - wmhints.flags = 0; - if (icon.x != -10000) - { - if (icon_xneg) - icon.x = fpmonitor_get_all_widths() + icon.x - icon.width; - if (icon.y != -10000) - { - if (icon_yneg) - icon.y = fpmonitor_get_all_heights() + icon.y - icon.height; - } - else - { - icon.y = 0; - } - icon_xneg = false; - icon_yneg = false; - wmhints.icon_x = icon.x; - wmhints.icon_y = icon.y; - wmhints.flags = IconPositionHint; - } - wmhints.icon_window = Scr.icon_w; - wmhints.input = True; - wmhints.flags |= InputHint | StateHint | IconWindowHint; - - class1.res_name = MyName; - class1.res_class = "FvwmPager"; - - XSetWMProperties(dpy,Scr.pager_w,&name,&name,NULL,0, - &sizehints,&wmhints,&class1); - XFree((char *)name.value); - - /* change colour/font for labelling mini-windows */ - XSetForeground(dpy, Scr.NormalGC, GetSimpleColor("black")); - - if (FwindowFont != NULL && FwindowFont->font != NULL) - XSetFont(dpy, Scr.NormalGC, FwindowFont->font->fid); - - /* Initialize DeskStyle GCs */ - for (i = 0; i < ndesks; i++) { - /* Create any missing DeskStyles. */ - style = FindDeskStyle(i); - } - TAILQ_FOREACH(style, &desk_style_q, entry) { - initialize_desk_style_gcs(style); - } - - for(i=0;ics)) - update_desk_background(cset); - if (CSET_IS_TRANSPARENT_PR(Desks[cset].style->hi_cs)) - update_monitor_backgrounds(cset); - } - - /* subordinate windows with a pr parent desk */ - t = Start; - for(t = Start; t != NULL; t = t->next) - { - DeskStyle *style = FindDeskStyle(t->desk); - - cset = (t == FocusWin) ? style->focus_cs : style->win_cs; - if (!CSET_IS_TRANSPARENT_PR(cset) || - (fAlwaysCurrentDesk && - !CSET_IS_TRANSPARENT_PR(Desks[0].style->cs)) || - (!fAlwaysCurrentDesk && - !CSET_IS_TRANSPARENT_PR(Desks[t->desk].style->cs))) - { - continue; - } - update_window_background(t); - } - - /* ballon */ - if (Balloon.is_mapped && CSET_IS_TRANSPARENT_PR(Balloon.cs)) - XClearArea(dpy, Scr.balloon_w, 0, 0, 0, 0, True); -} - void MovePage() { /* No monitor highlights, nothing to do. */ @@ -2692,243 +1772,6 @@ void MoveWindow(XEvent *Event) ExitPager(); /* does not return */ } - -/* - * - * Procedure: - * FvwmErrorHandler - displays info on internal errors - * - */ -int FvwmErrorHandler(Display *dpy, XErrorEvent *event) -{ -#if 1 - extern bool error_occured; - error_occured = true; - return 0; -#else - /* really should just exit here... */ - /* domivogt (07-mar-1999): No, not really. See comment above. */ - PrintXErrorAndCoredump(dpy, event, MyName); - return 0; -#endif /* 1 */ -} - -static void draw_window_border(PagerWindow *t, Window w, rectangle r) -{ - if (t == NULL) - return; - - DeskStyle *style = FindDeskStyle(t->desk); - - if (WindowBorders3d && t == FocusWin && style->focus_cs > 0) { - RelieveRectangle( - dpy, w, 0, 0, r.width - 1, r.height - 1, - style->focus_hi_gc, style->focus_sh_gc, - WindowBorderWidth); - return; - } else if (WindowBorders3d && t != FocusWin && style->win_cs > 0) { - RelieveRectangle( - dpy, w, 0, 0, r.width - 1, r.height - 1, - style->win_hi_gc, style->win_sh_gc, - WindowBorderWidth); - return; - } - - if (t == FocusWin) { - if (style->focus_fg) - XSetForeground(dpy, - style->focus_hi_gc, style->focus_fg); - else - XSetForeground(dpy, - style->focus_hi_gc, Scr.focus_win_fg); - RelieveRectangle( - dpy, w, 0, 0, r.width - 1, r.height - 1, - style->focus_hi_gc, style->focus_hi_gc, - WindowBorderWidth); - } else { - if (style->win_fg) - XSetForeground(dpy, - style->win_hi_gc, style->win_fg); - else - XSetForeground(dpy, - style->win_hi_gc, t->text); - RelieveRectangle( - dpy, w, 0, 0, r.width - 1, r.height - 1, - style->win_hi_gc, style->win_hi_gc, - WindowBorderWidth); - } -} - -/* draw the window label with simple greedy wrapping */ -static void label_window_wrap(PagerWindow *t, rectangle win_r) -{ - char *cur, *next, *end; - int space_width, cur_width; - - space_width = FlocaleTextWidth(FwindowFont, " ", 1); - cur_width = 0; - - cur = next = t->window_label; - end = cur + strlen(cur); - - while (*cur) { - while (*next) { - int width; - char *p; - - if (!(p = strchr(next, ' '))) - p = end; - - width = FlocaleTextWidth(FwindowFont, next, p - next ); - if (width > win_r.width - cur_width - space_width - 2*label_border) - break; - cur_width += width + space_width; - next = *p ? p + 1 : p; - } - - if (cur == next) { - /* word too large for window */ - while (*next) { - int len, width; - - len = FlocaleStringNumberOfBytes(FwindowFont, next); - width = FlocaleTextWidth(FwindowFont, next, len); - - if (width > win_r.width - cur_width - 2*label_border && cur != next) - break; - - next += len; - cur_width += width; - } - } - - FwinString->str = fxmalloc(next - cur + 1); - strncpy(FwinString->str, cur, next - cur); - FwinString->str[next - cur] = 0; - - FlocaleDrawString(dpy, FwindowFont, FwinString, 0); - - free(FwinString->str); - FwinString->str = NULL; - - FwinString->y += FwindowFont->height; - cur = next; - cur_width = 0; - } -} - -static void do_label_window(PagerWindow *t, Window w, rectangle r) -{ - if (t == NULL || w == None || FwindowFont == NULL || - (MiniIcons && t->mini_icon.picture) || /* Draw image later. */ - t->icon_name == NULL) - return; - - int cs; - Pixel pix; - DeskStyle *style = FindDeskStyle(t->desk); - - if (t == FocusWin) { - pix = (style->focus_fg) ? style->focus_fg : Scr.focus_win_fg; - cs = style->focus_cs; - } else { - pix = (style->win_fg) ? style->win_fg : t->text; - cs = style->win_cs; - } - XSetForeground(dpy, Scr.NormalGC, pix); - - free(t->window_label); - t->window_label = get_label(t, WindowLabelFormat); - - if (FftSupport) - XClearWindow(dpy, w); - FwinString->win = w; - FwinString->gc = Scr.NormalGC; - FwinString->flags.has_colorset = False; - if (cs >= 0) { - FwinString->colorset = &Colorset[cs]; - FwinString->flags.has_colorset = True; - } - FwinString->x = label_border; - FwinString->y = FwindowFont->ascent+2; - - label_window_wrap(t, r); -} - -static void do_picture_window(PagerWindow *t, Window w, rectangle r) -{ - if (t == NULL || !MiniIcons || !(t->mini_icon.picture)) - return; - - int iconX, iconY; - int src_x = 0, src_y = 0; - int dest_w, dest_h; - int cs; - FvwmRenderAttributes fra; - DeskStyle *style = FindDeskStyle(t->desk); - - cs = (t != FocusWin) ? style->win_cs : style->focus_cs; - dest_w = t->mini_icon.width; - dest_h = t->mini_icon.height; - if (r.width > t->mini_icon.width) { - iconX = (r.width - t->mini_icon.width) / 2; - } else if (r.width < t->mini_icon.width) { - iconX = 0; - src_x = (t->mini_icon.width - r.width) / 2; - dest_w = r.width; - } else { - iconX = 0; - } - if (r.height > t->mini_icon.height) { - iconY = (r.height - t->mini_icon.height) / 2; - } else if (r.height < t->mini_icon.height) { - iconY = 0; - src_y = (t->mini_icon.height - r.height) / 2; - dest_h = r.height; - } else { - iconY = 0; - } - - fra.mask = FRAM_DEST_IS_A_WINDOW; - if (t->mini_icon.alpha != None || - (cs >= 0 && Colorset[cs].icon_alpha_percent < 100)) - { - XClearArea(dpy, w, iconX, iconY, t->mini_icon.width, - t->mini_icon.height, False); - } - - if (cs >= 0) { - fra.mask |= FRAM_HAVE_ICON_CSET; - fra.colorset = &Colorset[cs]; - } - - PGraphicsRenderPicture(dpy, w, &t->mini_icon, &fra, w, - Scr.MiniIconGC, None, None, src_x, src_y, - t->mini_icon.width - src_x, - t->mini_icon.height - src_y, - iconX, iconY, dest_w, dest_h, False); -} - -void update_pager_window_decor(PagerWindow *t) -{ - do_label_window(t, t->PagerView, t->pager_view); - do_picture_window(t, t->PagerView, t->pager_view); - draw_window_border(t, t->PagerView, t->pager_view); -} - -void update_icon_window_decor(PagerWindow *t) -{ - do_label_window(t, t->IconView, t->icon_view); - do_picture_window(t, t->IconView, t->icon_view); - draw_window_border(t, t->IconView, t->icon_view); -} - -void update_window_decor(PagerWindow *t) -{ - update_pager_window_decor(t); - update_icon_window_decor(t); -} - void IconMoveWindow(XEvent *Event, PagerWindow *t) { int finished = 0, x = 0, y = 0, xi = 0, yi = 0; diff --git a/modules/FvwmPager/x_update.c b/modules/FvwmPager/x_update.c new file mode 100644 index 000000000..8df41f7e6 --- /dev/null +++ b/modules/FvwmPager/x_update.c @@ -0,0 +1,474 @@ +/* -*-c-*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see: + */ + +#include "config.h" +#include "libs/Module.h" +#include "libs/Graphics.h" +#include "libs/PictureGraphics.h" +#include "fvwm/fvwm.h" +#include "FvwmPager.h" + +#define label_border 2 + +static void do_label_window(PagerWindow *t, Window w, rectangle r); +static void do_picture_window(PagerWindow *t, Window w, rectangle r); +static void do_border_window(PagerWindow *t, Window w, rectangle r); + +void update_monitor_locations(int i) +{ + if (!HilightDesks) + return; + + struct fpmonitor *fp; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (fp->disabled) + continue; + + rectangle vp = set_vp_size_and_loc(fp, false); + + /* Conditions to show a monitor view port are: + * + Never show monitors not being tracked. + * + Always shown when CurrntDeskPerMonitor is in use. + * + Otherwise only show monitors on desk. + */ + if ((monitor_to_track == NULL || monitor_to_track == fp) && + ((CurrentDeskPerMonitor && fAlwaysCurrentDesk) || + fp->m->virtual_scr.CurrentDesk == i + desk1)) + { + XMoveResizeWindow(dpy, fp->CPagerWin[i], + vp.x, vp.y, vp.width, vp.height); + } else { + XMoveResizeWindow(dpy, fp->CPagerWin[i], + -32768, -32768, vp.width, vp.height); + } + } +} + +void update_monitor_backgrounds(int desk) +{ + if (!HilightDesks) + return; + + rectangle vp; + struct fpmonitor *fp; + DeskStyle *style = Desks[desk].style; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (CurrentDeskPerMonitor && fAlwaysCurrentDesk) + style = FindDeskStyle(fp->m->virtual_scr.CurrentDesk); + + if (style->hi_cs < 0) { + if (style->hiPixmap != NULL) + XSetWindowBackgroundPixmap(dpy, + fp->CPagerWin[desk], + style->hiPixmap->picture); + else + XSetWindowBackground(dpy, + fp->CPagerWin[desk], style->hi_bg); + } else { + vp = set_vp_size_and_loc(fp, false); + SetWindowBackground(dpy, + fp->CPagerWin[desk], vp.width, vp.height, + &Colorset[style->hi_cs], Pdepth, + style->hi_bg_gc, True); + } + XLowerWindow(dpy, fp->CPagerWin[desk]); + XClearWindow(dpy, fp->CPagerWin[desk]); + } +} + +void update_desk_background(int desk) +{ + DeskStyle *style = Desks[desk].style; + + XSetWindowBorder(dpy, Desks[desk].title_w, style->fg); + XSetWindowBorder(dpy, Desks[desk].w, style->fg); + + if (style->cs < 0) { + XSetWindowBorder(dpy, Desks[desk].title_w, style->fg); + XSetWindowBorder(dpy, Desks[desk].w, style->fg); + if (style->bgPixmap != NULL) { + if (style->use_label_pixmap) + XSetWindowBackgroundPixmap(dpy, + Desks[desk].title_w, + style->bgPixmap->picture); + else + XSetWindowBackgroundPixmap(dpy, + Desks[desk].w, + style->bgPixmap->picture); + } else { + XSetWindowBackground(dpy, + Desks[desk].title_w, style->bg); + XSetWindowBackground(dpy, + Desks[desk].w, style->bg); + } + } else { + if (style->use_label_pixmap) + SetWindowBackground(dpy, + Desks[desk].title_w, desk_w, desk_h + label_h, + &Colorset[style->cs], Pdepth, Scr.NormalGC, + True); + else + SetWindowBackground(dpy, + Desks[desk].w, desk_w, desk_h, + &Colorset[style->cs], Pdepth, Scr.NormalGC, + True); + } + + XClearWindow(dpy, Desks[desk].title_w); + XClearWindow(dpy, Desks[desk].w); +} + +void update_window_background(PagerWindow *t) +{ + if (t == NULL || t->PagerView == None || t->IconView == None) + return; + + if (Pdepth < 2) + { + if (t == FocusWin) { + XSetWindowBackgroundPixmap( + dpy, t->PagerView, Scr.gray_pixmap); + XSetWindowBackgroundPixmap( + dpy, t->IconView, Scr.gray_pixmap); + } else if (IS_STICKY_ACROSS_DESKS(t) || + IS_STICKY_ACROSS_PAGES(t)) + { + XSetWindowBackgroundPixmap(dpy, t->PagerView, + Scr.sticky_gray_pixmap); + XSetWindowBackgroundPixmap(dpy, t->IconView, + Scr.sticky_gray_pixmap); + } else { + XSetWindowBackgroundPixmap(dpy, t->PagerView, + Scr.light_gray_pixmap); + XSetWindowBackgroundPixmap(dpy, t->IconView, + Scr.light_gray_pixmap); + } + XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); + XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); + return; + } + + int cs = -1; + Pixel pix = None; + DeskStyle *style = FindDeskStyle(t->desk); + + if (t == FocusWin) { + if (style->focus_cs >= 0) { + cs = style->focus_cs; + } else if (style->focus_bg) { + pix = style->focus_bg; + } else { + pix = Scr.focus_win_bg; + } + } else { + if (style->win_cs >= 0) { + cs = style->win_cs; + } else if (style->win_bg) { + pix = style->win_bg; + } else { + pix = t->back; + } + } + + if (cs >= 0) { + SetWindowBackground(dpy, t->PagerView, + t->pager_view.width, t->pager_view.height, + &Colorset[cs], Pdepth, Scr.NormalGC, True); + SetWindowBackground(dpy, t->IconView, + t->icon_view.width, t->icon_view.height, + &Colorset[cs], Pdepth, Scr.NormalGC, True); + } else if (pix != None) { + XSetWindowBackground(dpy, t->PagerView, pix); + XSetWindowBackground(dpy, t->IconView, pix); + } + + XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); + XClearArea(dpy, t->IconView, 0, 0, 0, 0, True); +} + +/* update all the parental relative windows: pr background change */ +void update_pr_transparent_windows(void) +{ + int cset; + PagerWindow *t; + + for(cset = 0; cset < ndesks; cset++) { + if (CSET_IS_TRANSPARENT_PR(Desks[cset].style->cs)) + update_desk_background(cset); + if (CSET_IS_TRANSPARENT_PR(Desks[cset].style->hi_cs)) + update_monitor_backgrounds(cset); + } + + /* subordinate windows with a pr parent desk */ + t = Start; + for(t = Start; t != NULL; t = t->next) + { + DeskStyle *style = FindDeskStyle(t->desk); + + cset = (t == FocusWin) ? style->focus_cs : style->win_cs; + if (!CSET_IS_TRANSPARENT_PR(cset) || + (fAlwaysCurrentDesk && + !CSET_IS_TRANSPARENT_PR(Desks[0].style->cs)) || + (!fAlwaysCurrentDesk && + !CSET_IS_TRANSPARENT_PR(Desks[t->desk].style->cs))) + { + continue; + } + update_window_background(t); + } + + /* ballon */ + if (Balloon.is_mapped && CSET_IS_TRANSPARENT_PR(Balloon.cs)) + XClearArea(dpy, Scr.balloon_w, 0, 0, 0, 0, True); +} + +void update_desk_style_gcs(DeskStyle *style) +{ + initialize_colorset(style); + + XSetForeground(dpy, style->label_gc, style->fg); + XSetForeground(dpy, style->dashed_gc, style->fg); + XSetForeground(dpy, style->hi_bg_gc, style->hi_bg); + XSetForeground(dpy, style->hi_fg_gc, style->hi_fg); + if (WindowBorders3d && style->win_cs > 0) { + XSetForeground(dpy, style->win_hi_gc, + Colorset[style->win_cs].hilite); + XSetForeground(dpy, style->win_sh_gc, + Colorset[style->win_cs].shadow); + } + if (WindowBorders3d && style->focus_cs > 0) { + XSetForeground(dpy, style->focus_hi_gc, + Colorset[style->focus_cs].hilite); + XSetForeground(dpy, style->focus_sh_gc, + Colorset[style->focus_cs].shadow); + } +} + +void update_pager_window_decor(PagerWindow *t) +{ + do_label_window(t, t->PagerView, t->pager_view); + do_picture_window(t, t->PagerView, t->pager_view); + do_border_window(t, t->PagerView, t->pager_view); +} + +void update_icon_window_decor(PagerWindow *t) +{ + do_label_window(t, t->IconView, t->icon_view); + do_picture_window(t, t->IconView, t->icon_view); + do_border_window(t, t->IconView, t->icon_view); +} + +void update_window_decor(PagerWindow *t) +{ + update_pager_window_decor(t); + update_icon_window_decor(t); +} + +void do_label_window(PagerWindow *t, Window w, rectangle r) +{ + if (t == NULL || w == None || FwindowFont == NULL || + (MiniIcons && t->mini_icon.picture) || /* Draw image later. */ + t->icon_name == NULL) + return; + + int cs; + Pixel pix; + DeskStyle *style = FindDeskStyle(t->desk); + + if (t == FocusWin) { + pix = (style->focus_fg) ? style->focus_fg : Scr.focus_win_fg; + cs = style->focus_cs; + } else { + pix = (style->win_fg) ? style->win_fg : t->text; + cs = style->win_cs; + } + XSetForeground(dpy, Scr.NormalGC, pix); + + free(t->window_label); + t->window_label = get_label(t, WindowLabelFormat); + + if (FftSupport) + XClearWindow(dpy, w); + FwinString->win = w; + FwinString->gc = Scr.NormalGC; + FwinString->flags.has_colorset = False; + if (cs >= 0) { + FwinString->colorset = &Colorset[cs]; + FwinString->flags.has_colorset = True; + } + FwinString->x = label_border; + FwinString->y = FwindowFont->ascent+2; + + /* draw the window label with simple greedy wrapping */ + char *cur, *next, *end; + int space_width, cur_width; + + space_width = FlocaleTextWidth(FwindowFont, " ", 1); + cur_width = 0; + cur = next = t->window_label; + end = cur + strlen(cur); + + while (*cur) { + while (*next) { + int width; + char *p; + + if (!(p = strchr(next, ' '))) + p = end; + + width = FlocaleTextWidth( + FwindowFont, next, p - next ); + if (width > r.width - cur_width - + space_width - 2*label_border) + break; + cur_width += width + space_width; + next = *p ? p + 1 : p; + } + + if (cur == next) { + /* word too large for window */ + while (*next) { + int len, width; + + len = FlocaleStringNumberOfBytes( + FwindowFont, next); + width = FlocaleTextWidth( + FwindowFont, next, len); + + if (width > r.width - cur_width - + 2 * label_border && cur != next) + break; + + next += len; + cur_width += width; + } + } + + FwinString->str = fxmalloc(next - cur + 1); + strncpy(FwinString->str, cur, next - cur); + FwinString->str[next - cur] = 0; + + FlocaleDrawString(dpy, FwindowFont, FwinString, 0); + + free(FwinString->str); + FwinString->str = NULL; + + FwinString->y += FwindowFont->height; + cur = next; + cur_width = 0; + } +} + +void do_picture_window(PagerWindow *t, Window w, rectangle r) +{ + if (t == NULL || !MiniIcons || !(t->mini_icon.picture)) + return; + + int iconX, iconY; + int src_x = 0, src_y = 0; + int dest_w, dest_h; + int cs; + FvwmRenderAttributes fra; + DeskStyle *style = FindDeskStyle(t->desk); + + cs = (t != FocusWin) ? style->win_cs : style->focus_cs; + dest_w = t->mini_icon.width; + dest_h = t->mini_icon.height; + if (r.width > t->mini_icon.width) { + iconX = (r.width - t->mini_icon.width) / 2; + } else if (r.width < t->mini_icon.width) { + iconX = 0; + src_x = (t->mini_icon.width - r.width) / 2; + dest_w = r.width; + } else { + iconX = 0; + } + if (r.height > t->mini_icon.height) { + iconY = (r.height - t->mini_icon.height) / 2; + } else if (r.height < t->mini_icon.height) { + iconY = 0; + src_y = (t->mini_icon.height - r.height) / 2; + dest_h = r.height; + } else { + iconY = 0; + } + + fra.mask = FRAM_DEST_IS_A_WINDOW; + if (t->mini_icon.alpha != None || + (cs >= 0 && Colorset[cs].icon_alpha_percent < 100)) + { + XClearArea(dpy, w, iconX, iconY, t->mini_icon.width, + t->mini_icon.height, False); + } + + if (cs >= 0) { + fra.mask |= FRAM_HAVE_ICON_CSET; + fra.colorset = &Colorset[cs]; + } + + PGraphicsRenderPicture(dpy, w, &t->mini_icon, &fra, w, + Scr.MiniIconGC, None, None, src_x, src_y, + t->mini_icon.width - src_x, + t->mini_icon.height - src_y, + iconX, iconY, dest_w, dest_h, False); +} + +void do_border_window(PagerWindow *t, Window w, rectangle r) +{ + if (t == NULL) + return; + + DeskStyle *style = FindDeskStyle(t->desk); + + if (WindowBorders3d && t == FocusWin && style->focus_cs > 0) { + RelieveRectangle( + dpy, w, 0, 0, r.width - 1, r.height - 1, + style->focus_hi_gc, style->focus_sh_gc, + WindowBorderWidth); + return; + } else if (WindowBorders3d && t != FocusWin && style->win_cs > 0) { + RelieveRectangle( + dpy, w, 0, 0, r.width - 1, r.height - 1, + style->win_hi_gc, style->win_sh_gc, + WindowBorderWidth); + return; + } + + if (t == FocusWin) { + if (style->focus_fg) + XSetForeground(dpy, + style->focus_hi_gc, style->focus_fg); + else + XSetForeground(dpy, + style->focus_hi_gc, Scr.focus_win_fg); + RelieveRectangle( + dpy, w, 0, 0, r.width - 1, r.height - 1, + style->focus_hi_gc, style->focus_hi_gc, + WindowBorderWidth); + } else { + if (style->win_fg) + XSetForeground(dpy, + style->win_hi_gc, style->win_fg); + else + XSetForeground(dpy, + style->win_hi_gc, t->text); + RelieveRectangle( + dpy, w, 0, 0, r.width - 1, r.height - 1, + style->win_hi_gc, style->win_hi_gc, + WindowBorderWidth); + } +} From b8aa7cf0778b01530201aa4c70985078fb3ba5e4 Mon Sep 17 00:00:00 2001 From: Jaimos Skriletz Date: Thu, 18 Apr 2024 14:43:21 -0600 Subject: [PATCH 2/4] FvwmPager: Restructure initialization methods. * Split up the large initialization method into smaller methods to better group related pieces of the initialization together. * Cleaup variable use, don't store font names, just create the font and discard the name, reducing pointer usage. * Cleanup ExitPager() to try to catch any remaining pointers to free. * Group the -transient pager initialization together and update it to place the pager under the pointer. In addition update the position using fpmonitors to ensure the pager isn't off screen. --- modules/FvwmPager/FvwmPager.c | 88 ++--- modules/FvwmPager/FvwmPager.h | 26 +- modules/FvwmPager/init_pager.c | 652 ++++++++++++++++----------------- modules/FvwmPager/messages.c | 184 +++++----- modules/FvwmPager/x_pager.c | 30 +- modules/FvwmPager/x_update.c | 16 +- 6 files changed, 482 insertions(+), 514 deletions(-) diff --git a/modules/FvwmPager/FvwmPager.c b/modules/FvwmPager/FvwmPager.c index 3cc14d0d1..077bfac9c 100644 --- a/modules/FvwmPager/FvwmPager.c +++ b/modules/FvwmPager/FvwmPager.c @@ -38,6 +38,7 @@ #include "libs/Grab.h" #include "libs/Parse.h" #include "libs/Strings.h" +#include "libs/Picture.h" #include "libs/System.h" #include "fvwm/fvwm.h" @@ -48,15 +49,11 @@ * Shared variables. */ /* Colors, Pixmaps, Fonts, etc. */ -char *smallFont = NULL; char *ImagePath = NULL; -char *font_string = NULL; char *BalloonFont = NULL; char *WindowLabelFormat = NULL; -Pixmap default_pixmap = None; -FlocaleFont *Ffont; -FlocaleFont *FwindowFont; FlocaleWinString *FwinString; +Atom wm_del_win; /* Sizes / Dimensions */ int Rows = -1; @@ -64,6 +61,9 @@ int desk1 = 0; int desk2 = 0; int desk_i = 0; int ndesks = 0; +int desk_w = 0; +int desk_h = 0; +int label_h = 0; int Columns = -1; int MoveThreshold = DEFAULT_PAGER_MOVE_THRESHOLD; int BalloonBorderWidth = DEFAULT_BALLOON_BORDER_WIDTH; @@ -75,14 +75,9 @@ rectangle pwindow = {0, 0, 0, 0}; rectangle icon = {-10000, -10000, 0, 0}; /* Settings */ -bool xneg = false; -bool yneg = false; bool IsShared = false; -bool icon_xneg = false; -bool icon_yneg = false; bool MiniIcons = false; bool Swallowed = false; -bool usposition = false; bool UseSkipList = false; bool StartIconic = false; bool LabelsBelow = false; @@ -420,30 +415,37 @@ DeskStyle *FindDeskStyle(int desk) void ExitPager(void) { - DeskStyle *style, *style2; - struct fpmonitor *fp, *fp1; - PagerWindow *t, *t2; - - /* Balloons */ - free(Balloon.label); - free(Balloon.label_format); - - /* Monitors */ - TAILQ_FOREACH_SAFE(fp, &fp_monitor_q, entry, fp1) { - TAILQ_REMOVE(&fp_monitor_q, fp, entry); - free(fp->CPagerWin); - free(fp); - } + DeskStyle *style, *style2; + struct fpmonitor *fp, *fp1; + PagerWindow *t, *t2; + + /* Balloons */ + free(Balloon.label); + free(Balloon.label_format); + + /* Fonts */ + FlocaleUnloadFont(dpy, Scr.Ffont); + FlocaleUnloadFont(dpy, Scr.winFfont); + FlocaleUnloadFont(dpy, Balloon.Ffont); + + /* Monitors */ + TAILQ_FOREACH_SAFE(fp, &fp_monitor_q, entry, fp1) { + TAILQ_REMOVE(&fp_monitor_q, fp, entry); + free(fp->CPagerWin); + free(fp); + } - /* DeskStyles */ - TAILQ_FOREACH_SAFE(style, &desk_style_q, entry, style2) { - TAILQ_REMOVE(&desk_style_q, style, entry); - free(style->label); - free(style); - } - free(Desks); + /* DeskStyles */ + TAILQ_FOREACH_SAFE(style, &desk_style_q, entry, style2) { + TAILQ_REMOVE(&desk_style_q, style, entry); + PDestroyFvwmPicture(dpy, style->bgPixmap); + PDestroyFvwmPicture(dpy, style->hiPixmap); + free(style->label); + free(style); + } + free(Desks); - /* PagerWindows */ + /* PagerWindows */ t2 = Start; while (t2 != NULL) { t = t2; @@ -459,13 +461,17 @@ void ExitPager(void) free(t); } - if (is_transient) - { - XUngrabPointer(dpy,CurrentTime); - MyXUngrabServer(dpy); - XSync(dpy,0); - } - XUngrabKeyboard(dpy, CurrentTime); - free(preferred_monitor); - exit(0); + /* Additional pointers */ + free(preferred_monitor); + free(ImagePath); + free(WindowLabelFormat); + + if (is_transient) { + XUngrabPointer(dpy, CurrentTime); + MyXUngrabServer(dpy); + XSync(dpy, 0); + } + XUngrabKeyboard(dpy, CurrentTime); + + exit(0); } \ No newline at end of file diff --git a/modules/FvwmPager/FvwmPager.h b/modules/FvwmPager/FvwmPager.h index ea42f73b4..845969370 100644 --- a/modules/FvwmPager/FvwmPager.h +++ b/modules/FvwmPager/FvwmPager.h @@ -43,12 +43,14 @@ typedef struct ScreenInfo Window label_w; Window balloon_w; - Font PagerFont; /* font struct for window labels in pager (optional)*/ + FlocaleFont *Ffont; + FlocaleFont *winFfont; GC NormalGC; /* used for window names and setting backgrounds */ GC MiniIconGC; /* used for clipping mini-icons */ unsigned VScale; /* Panner scale factor */ + Pixmap sticky_gray_pixmap; Pixmap light_gray_pixmap; Pixmap gray_pixmap; @@ -169,17 +171,9 @@ typedef struct desk_info /* * Shared variables. */ -/* Colors, Pixmaps, Fonts, etc. */ -extern char *smallFont; +/* Misc */ extern char *ImagePath; -extern char *font_string; -extern char *BalloonFont; extern char *WindowLabelFormat; -extern Pixel focus_win_fg; -extern Pixel focus_win_bg; -extern Pixmap default_pixmap; -extern FlocaleFont *Ffont; -extern FlocaleFont *FwindowFont; extern FlocaleWinString *FwinString; extern Atom wm_del_win; @@ -200,14 +194,9 @@ extern rectangle pwindow; extern rectangle icon; /* Settings */ -extern bool xneg; -extern bool yneg; extern bool IsShared; -extern bool icon_xneg; -extern bool icon_yneg; extern bool MiniIcons; extern bool Swallowed; -extern bool usposition; extern bool UseSkipList; extern bool StartIconic; extern bool LabelsBelow; @@ -258,6 +247,7 @@ void DispatchEvent(XEvent *Event); void ReConfigure(void); void ReConfigureAll(void); void MovePage(); +void set_desk_size(bool update_label); void draw_desk_grid(int desk); void AddNewWindow(PagerWindow *prev); void ChangeDeskForWindow(PagerWindow *t,long newdesk); @@ -292,11 +282,7 @@ int fpmonitor_count(void); /* messages.c methods */ void process_message(FvwmPacket *packet); -void set_desk_label(int desk, const char *label); -void set_desk_size(bool update_label); -void parse_monitor_line(char *tline); -void parse_desktop_size_line(char *tline); -void parse_desktop_configuration_line(char *tline); +void process_config_info_line(char *line, bool is_init); void update_monitor_to_track(struct fpmonitor **fp_track, char *name, bool update_prefered); diff --git a/modules/FvwmPager/init_pager.c b/modules/FvwmPager/init_pager.c index 1bed0f0fa..83d532832 100644 --- a/modules/FvwmPager/init_pager.c +++ b/modules/FvwmPager/init_pager.c @@ -24,14 +24,25 @@ #include "fvwm/fvwm.h" #include "FvwmPager.h" +static Pixmap default_pixmap; +static bool usposition = false; +static bool xneg = false; +static bool yneg = false; +static bool icon_usposition = false; +static bool icon_xneg = false; +static bool icon_yneg = false; + static void initialize_viz_pager(void); static void initialize_desks_and_monitors(void); static void initialize_colorsets(void); static int fvwm_error_handler(Display *dpy, XErrorEvent *event); +static void initialize_fonts(void); +static void initialize_transient(void); static void initialise_common_pager_fragments(void); +static void initialize_pager_size(void); static void initialize_balloon_window(void); static void initialize_desk_windows(int desk); -static void initialize_pager(void); +static void initialize_pager_window(void); static void set_desk_style_cset(char *arg1, char *arg2, void *offset_style); static void set_desk_style_pixel(char *arg1, char *arg2, void *offset_style); static void set_desk_style_bool(char *arg1, char *arg2, void *offset_style); @@ -39,85 +50,52 @@ static void parse_options(void); void init_fvwm_pager(void) { - - Window JunkRoot, JunkChild; - int JunkX, JunkY; - unsigned JunkMask; - - /* Initialize fonts. */ - FlocaleInit(LC_CTYPE, "", "", "FvwmPager"); + int i; + DeskStyle *style; + struct fpmonitor *fp; /* make a temp window for any pixmaps, deleted later */ initialize_viz_pager(); /* Run initializations */ initialize_desks_and_monitors(); + initialize_fonts(); parse_options(); + initialize_colorsets(); + initialise_common_pager_fragments(); + initialize_pager_size(); + if (is_transient) + initialize_transient(); + initialize_pager_window(); + + /* Initialize DeskStyle GCs */ + for (i = 0; i < ndesks; i++) { + /* Create any missing DeskStyles. */ + style = FindDeskStyle(i); + } + TAILQ_FOREACH(style, &desk_style_q, entry) { + initialize_desk_style_gcs(style); + } + + /* After DeskStyles are initialized, initialize desk windows. */ + for (i = 0; i < ndesks; i++) { + initialize_desk_windows(i); + } - if (is_transient) { - FQueryPointer( - dpy, Scr.Root, &JunkRoot, &JunkChild, &pwindow.x, - &pwindow.y, &JunkX, &JunkY, &JunkMask); - usposition = false; - xneg = false; - yneg = false; + /* Hilight monitor windows. */ + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + initialize_fpmonitor_windows(fp); } - if (WindowLabelFormat == NULL) - WindowLabelFormat = fxstrdup("%i"); + initialize_balloon_window(); /* Create a list of all windows, by requesting a list of all * windows, and wait for ConfigureWindow packets. */ - SendInfo(fd,"Send_WindowList",0); - - /* Initialize pager window */ - initialize_colorsets(); - initialise_common_pager_fragments(); - initialize_pager(); - - if (is_transient) - { - int i; - bool is_pointer_grabbed = false; - bool is_keyboard_grabbed = false; - - XSync(dpy,0); - for (i = 0; i < 50 && !(is_pointer_grabbed && is_keyboard_grabbed); i++) - { - if (!is_pointer_grabbed && - XGrabPointer( - dpy, Scr.Root, true, - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| - PointerMotionMask|EnterWindowMask|LeaveWindowMask, GrabModeAsync, - GrabModeAsync, None, None, CurrentTime) == GrabSuccess) - { - is_pointer_grabbed = true; - } - if (!is_keyboard_grabbed && - XGrabKeyboard( - dpy, Scr.Root, true, GrabModeAsync, GrabModeAsync, CurrentTime) == - GrabSuccess) - { - is_keyboard_grabbed = true; - } - /* If you go too fast, other windows may not get a change to release - * any grab that they have. */ - usleep(20000); - } - if (!is_pointer_grabbed) - { - XBell(dpy, 0); - fvwm_debug(__func__, - "%s: could not grab pointer in transient mode. exiting.\n", - MyName); - exit(1); - } - - XSync(dpy,0); - } - + SendInfo(fd, "Send_WindowList", 0); + /* Initialization done! */ + XMapRaised(dpy, Scr.pager_w); } @@ -243,6 +221,93 @@ int fvwm_error_handler(Display *dpy, XErrorEvent *event) return 0; } +void initialize_fonts(void) +{ + /* Initialize fonts. */ + FlocaleInit(LC_CTYPE, "", "", "FvwmPager"); + + /* load a default font. */ + Scr.Ffont = FlocaleLoadFont(dpy, "", MyName); + + /* init our Flocale window string */ + FlocaleAllocateWinString(&FwinString); + + WindowLabelFormat = fxstrdup("%i"); +} + +void initialize_transient(void) +{ + int i; + Window junk_w; + unsigned junk_mask; + struct fpmonitor *fp; + bool is_pointer_grabbed = false; + bool is_keyboard_grabbed = false; + + /* Place window at pointer. */ + usposition = true; + xneg = false; + yneg = false; + FQueryPointer( + dpy, Scr.Root, &junk_w, &junk_w, &pwindow.x, + &pwindow.y, &i, &i, &junk_mask); + + /* Find monitor pointer is on. */ + fp = fpmonitor_from_xy(pwindow.x, pwindow.y); + if (fp == NULL) + fp = fpmonitor_this(NULL); + + /* Center window on pointer. This ignores window decor size. */ + pwindow.x -= pwindow.width / 2; + pwindow.y -= pwindow.height / 2; + + /* Adjust if pager is outside of monitor boundary. + * This ignores EWMH working area. + */ + if (pwindow.x < fp->m->si->x) + pwindow.x = fp->m->si->x; + if (pwindow.y < fp->m->si->y) + pwindow.y = fp->m->si->y; + if (pwindow.x + pwindow.width > fp->m->si->x + fp->m->si->w) + pwindow.x = fp->m->si->x + fp->m->si->w - pwindow.width; + if (pwindow.y + pwindow.height > fp->m->si->y + fp->m->si->h) + pwindow.y = fp->m->si->y + fp->m->si->h - pwindow.height; + + /* Grab pointer. */ + XSync(dpy, 0); + for (i = 0; i < 50 && + !(is_pointer_grabbed && is_keyboard_grabbed); i++) + { + if (!is_pointer_grabbed && XGrabPointer( + dpy, Scr.Root, true, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | PointerMotionMask | + EnterWindowMask | LeaveWindowMask, + GrabModeAsync, GrabModeAsync, + None, None, CurrentTime) == GrabSuccess) + is_pointer_grabbed = true; + + if (!is_keyboard_grabbed && XGrabKeyboard( + dpy, Scr.Root, true, GrabModeAsync, GrabModeAsync, + CurrentTime) == GrabSuccess) + is_keyboard_grabbed = true; + + /* If you go too fast, other windows may not get a + * change to release any grab that they have. + */ + usleep(20000); + } + + if (!is_pointer_grabbed) { + XBell(dpy, 0); + fprintf(stderr, + "%s: could not grab pointer in transient mode. " + "Exiting.\n", MyName); + ExitPager(); + } + XSync(dpy, 0); +} + void initialise_common_pager_fragments(void) { DeskStyle *style = FindDeskStyle(-1); @@ -255,30 +320,12 @@ void initialise_common_pager_fragments(void) wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); - /* load the font */ - /* Note: "font" is always created, whether labels are used or not - because a GC below is set to use a font. dje Dec 2001. - OK, I fixed the GC below, but now something else is blowing up. - Right now, I've got to do some Real Life stuff, so this kludge is - in place, its still better than I found it. - I hope that I've fixed this (olicha) - */ - Ffont = FlocaleLoadFont(dpy, font_string, MyName); - - /* init our Flocale window string */ - FlocaleAllocateWinString(&FwinString); - /* Check that shape extension exists. */ if (FHaveShapeExtension && ShapeLabels) { ShapeLabels = (FShapesSupported) ? 1 : 0; } - if(smallFont != NULL) - { - FwindowFont = FlocaleLoadFont(dpy, smallFont, MyName); - } - /* Load pixmaps for mono use */ if (Pdepth < 2) { @@ -300,11 +347,18 @@ void initialise_common_pager_fragments(void) dpy, Scr.pager_w, s_g_bits, s_g_width, s_g_height, style->fg, style->bg, Pdepth); } +} - /* Size the window */ - if(Rows < 0) +void initialize_pager_size(void) +{ + struct fpmonitor *fp = fpmonitor_this(NULL); + int VxPages = fp->virtual_scr.VxPages; + int VyPages = fp->virtual_scr.VyPages; + + /* Grid size */ + if (Rows < 0) { - if(Columns <= 0) + if (Columns <= 0) { Columns = ndesks; Rows = 1; @@ -316,7 +370,7 @@ void initialise_common_pager_fragments(void) Rows++; } } - if(Columns < 0) + if (Columns < 0) { if (Rows == 0) Rows = 1; @@ -325,7 +379,7 @@ void initialise_common_pager_fragments(void) Columns++; } - if(Rows*Columns < ndesks) + if (Rows*Columns < ndesks) { if (Columns == 0) Columns = 1; @@ -334,6 +388,59 @@ void initialise_common_pager_fragments(void) Rows++; } set_desk_size(true); + + /* Set window size if not fully set by user to match */ + /* aspect ratio of monitor(s) being shown. */ + if (pwindow.width == 0 || pwindow.height == 0) { + int vWidth = fpmonitor_get_all_widths(); + int vHeight = fpmonitor_get_all_heights(); + + if (monitor_to_track != NULL || IsShared) { + vWidth = fp->m->si->w; + vHeight = fp->m->si->h; + } + + if (pwindow.width > 0) { + pwindow.height = (pwindow.width * vHeight) / + vWidth + label_h * Rows + Rows; + } else if (pwindow.height > label_h * Rows) { + pwindow.width = ((pwindow.height - label_h * Rows + + Rows) * vWidth) / vHeight + Columns; + } else { + pwindow.width = (VxPages * vWidth * Columns) / + Scr.VScale + Columns; + pwindow.height = (VyPages * vHeight * Rows) / + Scr.VScale + label_h * Rows + Rows; + } + } + set_desk_size(false); + + /* Icon window size. */ + if (icon.width < 1) + icon.width = (pwindow.width - Columns + 1) / Columns; + if (icon.height < 1) + icon.height = (pwindow.height - Rows * label_h - Rows + 1) / + Rows; + + /* Icon window location. */ + if (icon.x != -10000) { + icon_usposition = true; + if (icon_xneg) + icon.x = fpmonitor_get_all_widths() + icon.x - icon.width; + } else { + icon.x = 0; + } + if (icon.y != -10000) { + icon_usposition = true; + if (icon_yneg) + icon.y = fpmonitor_get_all_heights() + icon.y - icon.height; + } else { + icon.y = 0; + } + + /* Make each page have same number of pixels. */ + icon.width = (icon.width / (VxPages + 1)) * (VxPages + 1) + VxPages; + icon.height = (icon.height / (VyPages + 1)) * (VyPages + 1) + VyPages; } /* create balloon window -- ric@giccs.georgetown.edu */ @@ -350,6 +457,8 @@ void initialize_balloon_window(void) } /* Set some defaults */ + Balloon.show = (StartIconic) ? + Balloon.show_in_icon : Balloon.show_in_pager; if (Balloon.border_width <= 0) Balloon.border_width = DEFAULT_BALLOON_BORDER_WIDTH; if (Balloon.y_offset == 0) @@ -360,6 +469,8 @@ void initialize_balloon_window(void) Balloon.y_offset = DEFAULT_BALLOON_Y_OFFSET; if (Balloon.label_format == NULL) Balloon.label_format = fxstrdup("%i"); + if (!Balloon.Ffont) + Balloon.Ffont = FlocaleLoadFont(dpy, "", MyName); valuemask = CWOverrideRedirect | CWEventMask | CWColormap; /* tell WM to ignore this window */ @@ -375,10 +486,8 @@ void initialize_balloon_window(void) /* Initialize, actual values will be updated later. */ valuemask = GCForeground; xgcv.foreground = GetSimpleColor("black"); - Balloon.Ffont = FlocaleLoadFont(dpy, BalloonFont, MyName); Balloon.gc = fvwmlib_XCreateGC( dpy, Scr.balloon_w, valuemask, &xgcv); - free(BalloonFont); } void initialize_fpmonitor_windows(struct fpmonitor *fp) @@ -424,8 +533,8 @@ void initialize_desk_style_gcs(DeskStyle *style) /* Desk labels GC. */ gcv.foreground = style->fg; - if (Ffont && Ffont->font) { - gcv.font = Ffont->font->fid; + if (Scr.Ffont && Scr.Ffont->font) { + gcv.font = Scr.Ffont->font->fid; style->label_gc = fvwmlib_XCreateGC( dpy, Scr.pager_w, GCForeground | GCFont, &gcv); } else { @@ -440,7 +549,7 @@ void initialize_desk_style_gcs(DeskStyle *style) /* create the hilight desk title drawing GC */ gcv.foreground = (Pdepth < 2) ? style->fg : style->hi_fg; - if (Ffont && Ffont->font) + if (Scr.Ffont && Scr.Ffont->font) style->hi_fg_gc = fvwmlib_XCreateGC( dpy, Scr.pager_w, GCForeground | GCFont, &gcv); else @@ -553,213 +662,100 @@ void initialize_desk_windows(int desk) XMapRaised(dpy, Desks[desk].w); } -void initialize_pager(void) +void initialize_pager_window(void) { - XWMHints wmhints; - XClassHint class1; - XTextProperty name; - unsigned long valuemask; - XSetWindowAttributes attributes; - int i = 0; - struct fpmonitor *fp = fpmonitor_this(NULL); - struct fpmonitor *m; - DeskStyle *style; - - XSizeHints sizehints = - { - (PWinGravity), /* flags */ - 0, 0, 100, 100, /* x, y, width and height (legacy) */ - 1, 1, /* Min width and height */ - 0, 0, /* Max width and height */ - 1, 1, /* Width and height increments */ - {0, 0}, {0, 0}, /* Aspect ratio */ - 1, 1, /* base size */ - (NorthWestGravity) /* gravity */ - }; - - int VxPages = fp->virtual_scr.VxPages, VyPages = fp->virtual_scr.VyPages; - - /* Set window size if not fully set by user to match */ - /* aspect ratio of monitor(s) being shown. */ - if ( pwindow.width == 0 || pwindow.height == 0 ) { - int vWidth = fpmonitor_get_all_widths(); - int vHeight = fpmonitor_get_all_heights(); - if (monitor_to_track != NULL || IsShared) { - vWidth = fp->m->si->w; - vHeight = fp->m->si->h; - } - - if (pwindow.width > 0) { - pwindow.height = (pwindow.width * vHeight) / vWidth + - label_h * Rows + Rows; - } else if (pwindow.height > label_h * Rows) { - pwindow.width = ((pwindow.height - label_h * Rows + Rows) * - vWidth) / vHeight + Columns; - } else { - pwindow.width = (VxPages * vWidth * Columns) / Scr.VScale + - Columns; - pwindow.height = (VyPages * vHeight * Rows) / Scr.VScale + - label_h * Rows + Rows; - } - } - set_desk_size(false); - - if (is_transient) - { - rectangle screen_g; - fscreen_scr_arg fscr; - - fscr.xypos.x = pwindow.x; - fscr.xypos.y = pwindow.y; - FScreenGetScrRect( - &fscr, FSCREEN_XYPOS, - &screen_g.x, &screen_g.y, &screen_g.width, &screen_g.height); - /* FIXME: Recalculate what to do if window is off screen. */ - /* Leaving alone for now */ - if (pwindow.width + pwindow.x > screen_g.x + screen_g.width) - { - pwindow.x = screen_g.x + screen_g.width - fp->m->si->w; //fp->m->virtual_scr.MyDisplayWidth; - xneg = true; - } - if (pwindow.height + pwindow.y > screen_g.y + screen_g.height) - { - pwindow.y = screen_g.y + screen_g.height - fp->m->si->h; //fp->m->virtual_scr.MyDisplayHeight; - yneg = true; - } - } - if (xneg) - { - sizehints.win_gravity = NorthEastGravity; - pwindow.x = fpmonitor_get_all_widths() - pwindow.width + pwindow.x; - } - if (yneg) - { - pwindow.y = fpmonitor_get_all_heights() - pwindow.height + pwindow.y; - if(sizehints.win_gravity == NorthEastGravity) - sizehints.win_gravity = SouthEastGravity; - else - sizehints.win_gravity = SouthWestGravity; - } - - if(usposition) - sizehints.flags |= USPosition; - - valuemask = (CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask); - attributes.background_pixmap = default_pixmap; - attributes.border_pixel = 0; - attributes.colormap = Pcmap; - attributes.event_mask = (StructureNotifyMask); - - /* destroy the temp window first, don't worry if it's the Root */ - if (Scr.pager_w != Scr.Root) - XDestroyWindow(dpy, Scr.pager_w); - Scr.pager_w = XCreateWindow (dpy, Scr.Root, pwindow.x, pwindow.y, pwindow.width, - pwindow.height, 0, Pdepth, InputOutput, Pvisual, - valuemask, &attributes); - XSetWMProtocols(dpy,Scr.pager_w,&wm_del_win,1); - /* hack to prevent mapping on wrong screen with StartsOnScreen */ - FScreenMangleScreenIntoUSPosHints(FSCREEN_XYPOS, &sizehints); - XSetWMNormalHints(dpy,Scr.pager_w,&sizehints); - if (is_transient) - { - XSetTransientForHint(dpy, Scr.pager_w, Scr.Root); - } - - if (FlocaleTextListToTextProperty( - dpy, &(Desks[0].style->label), 1, XStdICCTextStyle, &name) == 0) - { - fprintf(stderr,"%s: fatal error: cannot allocate desk name", MyName); - exit(0); - } - - attributes.event_mask = (StructureNotifyMask| ExposureMask); - if(icon.width < 1) - icon.width = (pwindow.width - Columns + 1) / Columns; - if(icon.height < 1) - icon.height = (pwindow.height - Rows * label_h - Rows + 1) / Rows; - - icon.width = (icon.width / (VxPages + 1)) * (VxPages + 1) + VxPages; - icon.height = (icon.height / (VyPages + 1)) * (VyPages + 1) + VyPages; - Scr.icon_w = XCreateWindow (dpy, Scr.Root, pwindow.x, pwindow.y, - icon.width, icon.height, - 0, Pdepth, InputOutput, Pvisual, valuemask, - &attributes); - XGrabButton(dpy, 1, AnyModifier, Scr.icon_w, - True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, - None); - XGrabButton(dpy, 2, AnyModifier, Scr.icon_w, - True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, - None); - XGrabButton(dpy, 3, AnyModifier, Scr.icon_w, - True, ButtonPressMask | ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, - None); - - if (StartIconic) { - Balloon.show = Balloon.show_in_icon; - wmhints.initial_state = IconicState; - } else { - Balloon.show = Balloon.show_in_pager; - wmhints.initial_state = NormalState; - } - wmhints.flags = 0; - if (icon.x != -10000) - { - if (icon_xneg) - icon.x = fpmonitor_get_all_widths() + icon.x - icon.width; - if (icon.y != -10000) - { - if (icon_yneg) - icon.y = fpmonitor_get_all_heights() + icon.y - icon.height; - } - else - { - icon.y = 0; - } - icon_xneg = false; - icon_yneg = false; - wmhints.icon_x = icon.x; - wmhints.icon_y = icon.y; - wmhints.flags = IconPositionHint; - } - wmhints.icon_window = Scr.icon_w; - wmhints.input = True; - wmhints.flags |= InputHint | StateHint | IconWindowHint; - - class1.res_name = MyName; - class1.res_class = "FvwmPager"; - - XSetWMProperties(dpy,Scr.pager_w,&name,&name,NULL,0, - &sizehints,&wmhints,&class1); - XFree((char *)name.value); - - /* change colour/font for labelling mini-windows */ - XSetForeground(dpy, Scr.NormalGC, GetSimpleColor("black")); - - if (FwindowFont != NULL && FwindowFont->font != NULL) - XSetFont(dpy, Scr.NormalGC, FwindowFont->font->fid); - - /* Initialize DeskStyle GCs */ - for (i = 0; i < ndesks; i++) { - /* Create any missing DeskStyles. */ - style = FindDeskStyle(i); - } - TAILQ_FOREACH(style, &desk_style_q, entry) { - initialize_desk_style_gcs(style); - } - - for(i=0;ilabel), 1, XStdICCTextStyle, &name) == 0) + { + fprintf(stderr,"%s: fatal error: cannot allocate desk name", MyName); + ExitPager(); + } + + /* Icon Window */ + attributes.event_mask = StructureNotifyMask | ExposureMask; + Scr.icon_w = XCreateWindow ( + dpy, Scr.Root, pwindow.x, pwindow.y, + icon.width, icon.height, 0, Pdepth, + InputOutput, Pvisual, valuemask, &attributes); + XGrabButton(dpy, 1, AnyModifier, Scr.icon_w, True, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, None); + XGrabButton(dpy, 2, AnyModifier, Scr.icon_w, True, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, None); + XGrabButton(dpy, 3, AnyModifier, Scr.icon_w, True, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeAsync, None, None); + + wmhints.initial_state = (StartIconic) ? IconicState : NormalState; + wmhints.flags = 0; + wmhints.icon_x = icon.x; + wmhints.icon_y = icon.y; + wmhints.flags = InputHint | StateHint | IconWindowHint; + if (icon_usposition) + wmhints.flags |= IconPositionHint; + wmhints.icon_window = Scr.icon_w; + wmhints.input = True; + + class1.res_name = MyName; + class1.res_class = "FvwmPager"; + + XSetWMProperties(dpy, Scr.pager_w, &name, &name, NULL, 0, + &sizehints, &wmhints, &class1); + XFree((char *)name.value); } /* These functions are really tricky. An offset of the struct member @@ -871,23 +867,9 @@ void parse_options(void) token = PeekToken(tline, &next); - /* Step 1: Initial configuration broadcasts are parsed here. - * This needs to match list_config_info(), along with having - * a few extra broadcasts that are sent during initialization. - */ + /* Step 1: Initial configuration broadcasts are parsed here. */ if (token[0] == '*') { /* Module configuration item, skip to next step. */ - } else if (StrEquals(token, "Colorset")) { - LoadColorset(next); - continue; - } else if (StrEquals(token, "DesktopSize")) { - parse_desktop_size_line(next); - continue; - } else if (StrEquals(token, "ImagePath")) { - free(ImagePath); - ImagePath = NULL; - GetNextToken(next, &ImagePath); - continue; } else if (StrEquals(token, "MoveThreshold")) { if (MoveThresholdSetForModule) continue; @@ -897,20 +879,9 @@ void parse_options(void) MoveThreshold = (val >= 0) ? val : DEFAULT_PAGER_MOVE_THRESHOLD; continue; - } else if (StrEquals(token, "DesktopName")) { - int val; - - if (GetIntegerArguments(next, &next, &val, 1) > 0) - set_desk_label(val, (const char *)next); - continue; - } else if (StrEquals(token, "Monitor")) { - parse_monitor_line(next); - continue; - } else if (StrEquals(token, "DesktopConfiguration")) { - parse_desktop_configuration_line(next); - continue; } else { - /* Module configuration lines have skipped this. */ + /* Deal with any M_CONFIG_INFO lines. */ + process_config_info_line(tline, true); continue; } @@ -1140,13 +1111,12 @@ void parse_options(void) icon_yneg = true; } } else if (StrEquals(resource, "Font")) { - free(font_string); - CopyStringWithQuotes(&font_string, next); - if(strncasecmp(font_string, "none", 4) == 0) { + if (strncasecmp(next, "none", 4) == 0) { use_desk_label = false; use_monitor_label = false; - free(font_string); - font_string = NULL; + } else { + FlocaleUnloadFont(dpy, Scr.Ffont); + Scr.Ffont = FlocaleLoadFont(dpy, next, MyName); } } else if (StrEquals(resource, "Pixmap") || StrEquals(resource, "DeskPixmap")) @@ -1209,12 +1179,10 @@ void parse_options(void) } else if (StrEquals(resource, "WindowFont") || StrEquals(resource, "SmallFont")) { - free(smallFont); - CopyStringWithQuotes(&smallFont, next); - if (strncasecmp(smallFont, "none", 4) == 0) { - free(smallFont); - smallFont = NULL; - } + FlocaleUnloadFont(dpy, Scr.winFfont); + if (strncasecmp(next, "none", 4) != 0) + Scr.winFfont = FlocaleLoadFont( + dpy, next, MyName); } else if (StrEquals(resource, "Rows")) { sscanf(next, "%d", &Rows); } else if (StrEquals(resource, "Columns")) { @@ -1236,7 +1204,7 @@ void parse_options(void) else MinSize = 2 * WindowBorderWidth + DEFAULT_PAGER_WINDOW_MIN_SIZE; - } else if (StrEquals(resource,"WindowLabelFormat")) { + } else if (StrEquals(resource, "WindowLabelFormat")) { free(WindowLabelFormat); CopyString(&WindowLabelFormat, next); } else if (StrEquals(resource, "MoveThreshold")) { @@ -1262,13 +1230,13 @@ void parse_options(void) Balloon.show_in_icon = true; } } else if (StrEquals(resource, "BalloonFont")) { - free(BalloonFont); - CopyStringWithQuotes(&BalloonFont, next); + FlocaleUnloadFont(dpy, Balloon.Ffont); + Balloon.Ffont = FlocaleLoadFont(dpy, next, MyName); } else if (StrEquals(resource, "BalloonBorderWidth")) { sscanf(next, "%d", &(Balloon.border_width)); } else if (StrEquals(resource, "BalloonYOffset")) { sscanf(next, "%d", &(Balloon.y_offset)); - } else if (StrEquals(resource,"BalloonStringFormat")) { + } else if (StrEquals(resource, "BalloonStringFormat")) { free(Balloon.label_format); CopyString(&(Balloon.label_format), next); } diff --git a/modules/FvwmPager/messages.c b/modules/FvwmPager/messages.c index 08e50b20a..3dc504c43 100644 --- a/modules/FvwmPager/messages.c +++ b/modules/FvwmPager/messages.c @@ -14,6 +14,7 @@ */ #include "config.h" +#include #include "libs/FScreen.h" #include "libs/fvwmlib.h" #include "libs/Module.h" @@ -44,9 +45,11 @@ static void process_icon_name(unsigned long *body); static void process_mini_icon(unsigned long *body); static void process_restack(unsigned long *body, unsigned long length); static void process_end(void); -static void process_config_info(unsigned long *body); static void process_property_change(unsigned long *body); static void process_reply(unsigned long *body); +static void parse_monitor_line(char *tline); +static void parse_desktop_size_line(char *tline); +static void parse_desktop_configuration_line(char *tline); /* * Procedure: @@ -109,7 +112,7 @@ void process_message(FvwmPacket *packet) process_restack(body, length); break; case M_CONFIG_INFO: - process_config_info(body); + process_config_info_line((char *)&body[3], false); break; case MX_PROPERTY_CHANGE: process_property_change(body); @@ -595,7 +598,7 @@ void process_window_name(unsigned long *body, unsigned long type) } /* repaint by clearing window */ - if (FwindowFont != NULL && t->icon_name != NULL && + if (Scr.winFfont != NULL && t->icon_name != NULL && !(MiniIcons && t->mini_icon.picture)) { XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); @@ -619,7 +622,7 @@ void process_icon_name(unsigned long *body) free(t->icon_name); CopyString(&t->icon_name, (char *)(&body[3])); /* repaint by clearing window */ - if (FwindowFont != NULL && t->icon_name != NULL && + if (Scr.winFfont != NULL && t->icon_name != NULL && !(MiniIcons && t->mini_icon.picture)) { XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); @@ -719,79 +722,6 @@ void process_end(void) XFree((char *)children); } -void process_config_info(unsigned long *body) -{ - struct fpmonitor *m; - char *tline, *token; - - tline = (char*)&(body[3]); - token = PeekToken(tline, &tline); - if (StrEquals(token, "Colorset")) - { - int color; - DeskStyle *style; - - color = LoadColorset(tline); - TAILQ_FOREACH(style, &desk_style_q, entry) { - if (style->cs == color || style->hi_cs == color) - { - update_desk_style_gcs(style); - if (style->desk < desk1 || style->desk > desk2) - continue; - - update_desk_background(style->desk - desk1); - update_monitor_backgrounds(style->desk - desk1); - } - if (style->win_cs == color || style->focus_cs == color) { - PagerWindow *t = Start; - - update_desk_style_gcs(style); - while (t != NULL) { - if (t->desk != style->desk) { - t = t->next; - continue; - } - update_desk_style_gcs(style); - update_window_background(t); - update_window_decor(t); - t = t->next; - } - } - } - } - else if (StrEquals(token, "DesktopName")) - { - int val; - if (GetIntegerArguments(tline, &tline, &val, 1) > 0) - { - set_desk_label(val, (const char *)tline); - } - else - { - return; - } - if (fAlwaysCurrentDesk) - { - TAILQ_FOREACH(m, &fp_monitor_q, entry) { - if (m->m->virtual_scr.CurrentDesk == val) - val = 0; - } - } - else if ((val >= desk1) && (val <=desk2)) - { - val = val - desk1; - } - draw_desk_grid(val); - } else if (StrEquals(token, "Monitor")) { - parse_monitor_line(tline); - ReConfigure(); - } else if (StrEquals(token, "DesktopSize")) { - parse_desktop_size_line(tline); - } else if (StrEquals(token, "DesktopConfiguration")) { - parse_desktop_configuration_line(tline); - } -} - void process_property_change(unsigned long *body) { if (body[0] == MX_PROPERTY_CHANGE_BACKGROUND) @@ -816,7 +746,7 @@ void process_reply(unsigned long *body) HandleScrollDone(); } -/* These methods are also used in parse_options in init_pager.c */ +/* Helper methods */ void set_desk_label(int desk, const char *label) { DeskStyle *style = FindDeskStyle(desk); @@ -825,22 +755,6 @@ void set_desk_label(int desk, const char *label) CopyString(&(style->label), label); } -void set_desk_size(bool update_label) -{ - if (update_label) { - label_h = 0; - if (use_desk_label) - label_h += Ffont->height + 2; - if (use_monitor_label) - label_h += Ffont->height + 2; - } - - desk_w = (pwindow.width - Columns + 1) / Columns; - desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; - - return; -} - void parse_monitor_line(char *tline) { int dx, dy, Vx, Vy, VxMax, VyMax, CurrentDesk; @@ -951,6 +865,88 @@ void parse_desktop_configuration_line(char *tline) } } +/* These methods are also used in parse_options in init_pager.c */ +void process_config_info_line(char *line, bool is_init) +{ + char *token, *next; + + token = PeekToken(line, &next); + if (StrEquals(token, "DesktopSize")) { + parse_desktop_size_line(next); + } else if (StrEquals(token, "DesktopConfiguration")) { + parse_desktop_configuration_line(next); + } else if (StrEquals(token, "Monitor")) { + parse_monitor_line(next); + if (!is_init) + ReConfigure(); + } else if (StrEquals(token, "ImagePath")) { + free(ImagePath); + ImagePath = NULL; + GetNextToken(next, &ImagePath); + } else if (StrEquals(token, "DesktopName")) { + int val; + + if (GetIntegerArguments(next, &next, &val, 1) <= 0) + return; + + set_desk_label(val, (const char *)next); + + if (is_init) + return; + + if (fAlwaysCurrentDesk) + { + struct fpmonitor *fp; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (fp->m->virtual_scr.CurrentDesk == val) + val = 0; + } + } + else if ((val >= desk1) && (val <=desk2)) + { + val = val - desk1; + } + draw_desk_grid(val); + } else if (StrEquals(token, "Colorset")) { + DeskStyle *style; + int color = LoadColorset(next); + + if (is_init) + return; + + TAILQ_FOREACH(style, &desk_style_q, entry) { + if (style->cs == color || style->hi_cs == color) + { + update_desk_style_gcs(style); + if (style->desk < desk1 || + style->desk > desk2) + continue; + + int i = style->desk - desk1; + update_desk_background(i); + update_monitor_backgrounds(i); + } + if (style->win_cs == color || + style->focus_cs == color) + { + PagerWindow *t = Start; + + update_desk_style_gcs(style); + while (t != NULL) { + if (t->desk != style->desk) { + t = t->next; + continue; + } + update_window_background(t); + update_window_decor(t); + t = t->next; + } + } + } + } +} + void update_monitor_to_track(struct fpmonitor **fp_track, char *name, bool update_prefered) { diff --git a/modules/FvwmPager/x_pager.c b/modules/FvwmPager/x_pager.c index 2004b73a8..f96e16d4c 100644 --- a/modules/FvwmPager/x_pager.c +++ b/modules/FvwmPager/x_pager.c @@ -36,10 +36,6 @@ #include "fvwm/fvwm.h" #include "FvwmPager.h" -Atom wm_del_win; -int desk_w = 0; -int desk_h = 0; -int label_h = 0; static int Wait = 0; static int MyVx, MyVy; /* copy of Scr.Vx/y for drag logic */ static struct fpmonitor *ScrollFp = NULL; /* Stash monitor drag logic */ @@ -331,6 +327,22 @@ rectangle set_vp_size_and_loc(struct fpmonitor *m, bool is_icon) return vp; } +void set_desk_size(bool update_label) +{ + if (update_label) { + label_h = 0; + if (use_desk_label) + label_h += Scr.Ffont->height + 2; + if (use_monitor_label) + label_h += Scr.Ffont->height + 2; + } + + desk_w = (pwindow.width - Columns + 1) / Columns; + desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; + + return; +} + void UpdateWindowShape(void) { if (FHaveShapeExtension) @@ -479,7 +491,7 @@ void DispatchEvent(XEvent *Event) if(Event->xany.window == Desks[i].w) { FQueryPointer(dpy, Desks[i].w, &JunkRoot, &JunkChild, - &JunkX, &JunkY,&x, &y, &JunkMask); + &JunkX, &JunkY, &x, &y, &JunkMask); Scroll(x, y, i, false); } } @@ -880,11 +892,11 @@ void draw_desk_label(const char *label, const char *small, int desk, int w, cs; char *str = fxstrdup(label); - w = FlocaleTextWidth(Ffont, str, strlen(label)); + w = FlocaleTextWidth(Scr.Ffont, str, strlen(label)); if (w > width) { free(str); str = fxstrdup(small); - w = FlocaleTextWidth(Ffont, str, strlen(str)); + w = FlocaleTextWidth(Scr.Ffont, str, strlen(str)); } if (w <= width) { @@ -923,9 +935,9 @@ void draw_desk_label(const char *label, const char *small, int desk, FwinString->flags.has_colorset = True; } FwinString->x = x + (width - w)/2; - FwinString->y = y + Ffont->ascent + 1; + FwinString->y = y + Scr.Ffont->ascent + 1; FwinString->flags.has_clip_region = False; - FlocaleDrawString(dpy, Ffont, FwinString, 0); + FlocaleDrawString(dpy, Scr.Ffont, FwinString, 0); } free(str); diff --git a/modules/FvwmPager/x_update.c b/modules/FvwmPager/x_update.c index 8df41f7e6..6474bc4ac 100644 --- a/modules/FvwmPager/x_update.c +++ b/modules/FvwmPager/x_update.c @@ -280,7 +280,7 @@ void update_window_decor(PagerWindow *t) void do_label_window(PagerWindow *t, Window w, rectangle r) { - if (t == NULL || w == None || FwindowFont == NULL || + if (t == NULL || w == None || Scr.winFfont == NULL || (MiniIcons && t->mini_icon.picture) || /* Draw image later. */ t->icon_name == NULL) return; @@ -311,13 +311,13 @@ void do_label_window(PagerWindow *t, Window w, rectangle r) FwinString->flags.has_colorset = True; } FwinString->x = label_border; - FwinString->y = FwindowFont->ascent+2; + FwinString->y = Scr.winFfont->ascent+2; /* draw the window label with simple greedy wrapping */ char *cur, *next, *end; int space_width, cur_width; - space_width = FlocaleTextWidth(FwindowFont, " ", 1); + space_width = FlocaleTextWidth(Scr.winFfont, " ", 1); cur_width = 0; cur = next = t->window_label; end = cur + strlen(cur); @@ -331,7 +331,7 @@ void do_label_window(PagerWindow *t, Window w, rectangle r) p = end; width = FlocaleTextWidth( - FwindowFont, next, p - next ); + Scr.winFfont, next, p - next ); if (width > r.width - cur_width - space_width - 2*label_border) break; @@ -345,9 +345,9 @@ void do_label_window(PagerWindow *t, Window w, rectangle r) int len, width; len = FlocaleStringNumberOfBytes( - FwindowFont, next); + Scr.winFfont, next); width = FlocaleTextWidth( - FwindowFont, next, len); + Scr.winFfont, next, len); if (width > r.width - cur_width - 2 * label_border && cur != next) @@ -362,12 +362,12 @@ void do_label_window(PagerWindow *t, Window w, rectangle r) strncpy(FwinString->str, cur, next - cur); FwinString->str[next - cur] = 0; - FlocaleDrawString(dpy, FwindowFont, FwinString, 0); + FlocaleDrawString(dpy, Scr.winFfont, FwinString, 0); free(FwinString->str); FwinString->str = NULL; - FwinString->y += FwindowFont->height; + FwinString->y += Scr.winFfont->height; cur = next; cur_width = 0; } From 1ccbbd2cf6f34987eb6cc7f866b1aaecb7e76379 Mon Sep 17 00:00:00 2001 From: Jaimos Skriletz Date: Thu, 18 Apr 2024 21:59:25 -0600 Subject: [PATCH 3/4] FvwmPager: ShapedLabels per-monitor aware. Make ShapedLabels show the labels of all desks any monitor is currently in. --- modules/FvwmPager/init_pager.c | 2 - modules/FvwmPager/x_pager.c | 86 +++++++++++++++------------------- 2 files changed, 39 insertions(+), 49 deletions(-) diff --git a/modules/FvwmPager/init_pager.c b/modules/FvwmPager/init_pager.c index 83d532832..260d85d58 100644 --- a/modules/FvwmPager/init_pager.c +++ b/modules/FvwmPager/init_pager.c @@ -322,9 +322,7 @@ void initialise_common_pager_fragments(void) /* Check that shape extension exists. */ if (FHaveShapeExtension && ShapeLabels) - { ShapeLabels = (FShapesSupported) ? 1 : 0; - } /* Load pixmaps for mono use */ if (Pdepth < 2) diff --git a/modules/FvwmPager/x_pager.c b/modules/FvwmPager/x_pager.c index f96e16d4c..f85b24534 100644 --- a/modules/FvwmPager/x_pager.c +++ b/modules/FvwmPager/x_pager.c @@ -345,58 +345,50 @@ void set_desk_size(bool update_label) void UpdateWindowShape(void) { - if (FHaveShapeExtension) - { - int i, j, cnt, shape_count, x_pos, y_pos; - XRectangle *shape; - struct fpmonitor *fp = fpmonitor_this(NULL); - - if (!fp || !ShapeLabels || label_h == 0) - return; - - shape_count = - ndesks + ((fp->m->virtual_scr.CurrentDesk < desk1 || fp->m->virtual_scr.CurrentDesk >desk2) ? 0 : 1); - - shape = fxmalloc(shape_count * sizeof (XRectangle)); - - cnt = 0; - y_pos = (LabelsBelow ? 0 : label_h); + if (!ShapeLabels || label_h == 0 || fAlwaysCurrentDesk) + return; - for (i = 0; i < Rows; ++i) - { - x_pos = 0; - for (j = 0; j < Columns; ++j) - { - if (cnt < ndesks) - { - shape[cnt].x = x_pos; - shape[cnt].y = y_pos; - shape[cnt].width = desk_w + 1; - shape[cnt].height = desk_h + 2; + int i, j, cnt, x_pos, y_pos; + XRectangle *shape; + struct fpmonitor *fp; + shape = fxmalloc(ndesks * sizeof (XRectangle)); + + cnt = 0; + y_pos = (LabelsBelow) ? 0 : label_h; + for (i = 0; i < Rows; i++) { + x_pos = 0; + for (j = 0; j < Columns; j++) { + if (cnt >= ndesks) + continue; - if (cnt == fp->m->virtual_scr.CurrentDesk - desk1) - { - shape[ndesks].x = x_pos; - shape[ndesks].y = - (LabelsBelow ? y_pos + desk_h + 2 : y_pos - label_h); - shape[ndesks].width = desk_w; - shape[ndesks].height = label_h + 2; - } + /* Default shape/hide labels. */ + shape[cnt].x = x_pos; + shape[cnt].y = y_pos; + shape[cnt].width = desk_w + 1; + shape[cnt].height = desk_h + 2; + + /* Show labels for active monitors. */ + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (fp->disabled || + (monitor_to_track != NULL && + monitor_to_track != fp) || + cnt + desk1 != + fp->m->virtual_scr.CurrentDesk) + continue; + + shape[cnt].y -= (LabelsBelow) ? 0 : label_h; + shape[cnt].height += label_h; + } + cnt++; + x_pos += desk_w + 1; + } + y_pos += desk_h + 2 + label_h; } - ++cnt; - x_pos += desk_w + 1; - } - y_pos += desk_h + 2 + label_h; - } - - FShapeCombineRectangles( - dpy, Scr.pager_w, FShapeBounding, 0, 0, shape, shape_count, FShapeSet, 0); - free(shape); - } + FShapeCombineRectangles(dpy, Scr.pager_w, FShapeBounding, + 0, 0, shape, cnt, FShapeSet, 0); + free(shape); } - - /* * * Decide what to do about received X events From 5e09da9daa0a18b54a58a6231f19e4035a56464c Mon Sep 17 00:00:00 2001 From: Jaimos Skriletz Date: Fri, 19 Apr 2024 21:03:05 -0600 Subject: [PATCH 4/4] FvwmPager: Clean up DeskStyle initialization. * Initialize new DeskStyle GC's when they are created. There is a dummy window available at this time for this, no need to wait. * Don't put fonts in DeskStyle GC's, fonts are done with FwinString, which doesn't use these GCs. * Fix a typo in the balloon colorset initialization, which would cause a crash trying to access a non allocated colorset. This fixes #1014. * Protect against updating gc's on default desk on colorset change, but colorset Pixels still need updated. * Fix some issues with updating on new_page and new_desk changes. --- modules/FvwmPager/FvwmPager.c | 1 + modules/FvwmPager/init_pager.c | 31 +++++++++---------------- modules/FvwmPager/messages.c | 41 +++++++++++++++++----------------- modules/FvwmPager/x_update.c | 4 ++++ 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/modules/FvwmPager/FvwmPager.c b/modules/FvwmPager/FvwmPager.c index 077bfac9c..5ad602fef 100644 --- a/modules/FvwmPager/FvwmPager.c +++ b/modules/FvwmPager/FvwmPager.c @@ -408,6 +408,7 @@ DeskStyle *FindDeskStyle(int desk) style->desk = desk; xasprintf(&style->label, "Desk %d", desk); + initialize_desk_style_gcs(style); TAILQ_INSERT_TAIL(&desk_style_q, style, entry); return style; diff --git a/modules/FvwmPager/init_pager.c b/modules/FvwmPager/init_pager.c index 260d85d58..82e173132 100644 --- a/modules/FvwmPager/init_pager.c +++ b/modules/FvwmPager/init_pager.c @@ -68,14 +68,14 @@ void init_fvwm_pager(void) initialize_transient(); initialize_pager_window(); - /* Initialize DeskStyle GCs */ + /* Update styles with user configurations. */ + TAILQ_FOREACH(style, &desk_style_q, entry) { + update_desk_style_gcs(style); + } + /* Initialize any non configured desks. */ for (i = 0; i < ndesks; i++) { - /* Create any missing DeskStyles. */ style = FindDeskStyle(i); } - TAILQ_FOREACH(style, &desk_style_q, entry) { - initialize_desk_style_gcs(style); - } /* After DeskStyles are initialized, initialize desk windows. */ for (i = 0; i < ndesks; i++) { @@ -201,7 +201,7 @@ void initialize_colorset(DeskStyle *style) } if (style->balloon_cs >= 0) { style->balloon_fg = Colorset[style->balloon_cs].fg; - style->balloon_bg = Colorset[style->balloon_bg].bg; + style->balloon_bg = Colorset[style->balloon_cs].bg; } } @@ -531,14 +531,8 @@ void initialize_desk_style_gcs(DeskStyle *style) /* Desk labels GC. */ gcv.foreground = style->fg; - if (Scr.Ffont && Scr.Ffont->font) { - gcv.font = Scr.Ffont->font->fid; - style->label_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground | GCFont, &gcv); - } else { - style->label_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); - } + style->label_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); /* Hilight GC, used for monitors and labels backgrounds. */ gcv.foreground = (Pdepth < 2) ? style->bg : style->hi_bg; @@ -547,12 +541,8 @@ void initialize_desk_style_gcs(DeskStyle *style) /* create the hilight desk title drawing GC */ gcv.foreground = (Pdepth < 2) ? style->fg : style->hi_fg; - if (Scr.Ffont && Scr.Ffont->font) - style->hi_fg_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground | GCFont, &gcv); - else - style->hi_fg_gc = fvwmlib_XCreateGC( - dpy, Scr.pager_w, GCForeground, &gcv); + style->hi_fg_gc = fvwmlib_XCreateGC( + dpy, Scr.pager_w, GCForeground, &gcv); /* create the virtual page boundary GC */ gcv.foreground = style->fg; @@ -864,7 +854,6 @@ void parse_options(void) char *next; token = PeekToken(tline, &next); - /* Step 1: Initial configuration broadcasts are parsed here. */ if (token[0] == '*') { /* Module configuration item, skip to next step. */ diff --git a/modules/FvwmPager/messages.c b/modules/FvwmPager/messages.c index 3dc504c43..6f66e4b5b 100644 --- a/modules/FvwmPager/messages.c +++ b/modules/FvwmPager/messages.c @@ -64,8 +64,6 @@ void process_message(FvwmPacket *packet) switch (type) { case M_ADD_WINDOW: - process_configure(body); - break; case M_CONFIGURE_WINDOW: process_configure(body); break; @@ -366,7 +364,8 @@ void process_new_page(unsigned long *body) fp = fpmonitor_this(m); if (fp == NULL) return; - do_reconfigure = true; + if (monitor_to_track == NULL) + do_reconfigure = true; } fp->virtual_scr.Vx = fp->m->virtual_scr.Vx = body[0]; @@ -377,16 +376,20 @@ void process_new_page(unsigned long *body) body[1] = mon_num; process_new_desk(body); } - if (fp->virtual_scr.VxPages != body[5] || fp->virtual_scr.VyPages != body[6]) + if (fp->virtual_scr.VxPages != body[5] || + fp->virtual_scr.VyPages != body[6]) { fp->virtual_scr.VxPages = body[5]; fp->virtual_scr.VyPages = body[6]; - fp->virtual_scr.VWidth = fp->virtual_scr.VxPages * fpmonitor_get_all_widths(); - fp->virtual_scr.VHeight = fp->virtual_scr.VyPages * fpmonitor_get_all_heights(); - fp->virtual_scr.VxMax = fp->virtual_scr.VWidth - fpmonitor_get_all_widths(); - fp->virtual_scr.VyMax = fp->virtual_scr.VHeight - fpmonitor_get_all_heights(); - if (do_reconfigure) - ReConfigure(); + fp->virtual_scr.VWidth = + fp->virtual_scr.VxPages * fpmonitor_get_all_widths(); + fp->virtual_scr.VHeight = + fp->virtual_scr.VyPages * fpmonitor_get_all_heights(); + fp->virtual_scr.VxMax = + fp->virtual_scr.VWidth - fpmonitor_get_all_widths(); + fp->virtual_scr.VyMax = + fp->virtual_scr.VHeight - fpmonitor_get_all_heights(); + ReConfigure(); } if (do_reconfigure) { @@ -428,10 +431,10 @@ void process_new_desk(unsigned long *body) * and tracking is per-monitor or shared. */ if (!CurrentDeskPerMonitor && ((monitor_to_track != NULL && - mout != monitor_to_track->m) || + fp != monitor_to_track) || (current_monitor != NULL && monitor_to_track == NULL && - mout != current_monitor->m && + fp != current_monitor && (monitor_mode == MONITOR_TRACKING_M || is_tracking_shared)))) { @@ -444,13 +447,6 @@ void process_new_desk(unsigned long *body) /* Update the current desk. */ desk_i = newDesk; style = FindDeskStyle(newDesk); - /* Create and update GCs if needed. */ - if (oldDesk != newDesk) { - if (style->label_gc) - update_desk_style_gcs(style); - else - initialize_desk_style_gcs(style); - } /* Keep monitors in sync when tracking is global. */ if (monitor_mode == MONITOR_TRACKING_G) @@ -473,7 +469,6 @@ void process_new_desk(unsigned long *body) update_desk_background(0); update_monitor_locations(0); update_monitor_backgrounds(0); - ReConfigureAll(); } XStoreName(dpy, Scr.pager_w, style->label); @@ -481,6 +476,7 @@ void process_new_desk(unsigned long *body) update_grid: MovePage(); + ReConfigureAll(); draw_desk_grid(oldDesk - desk1); draw_desk_grid(newDesk - desk1); MoveStickyWindows(false, true); @@ -932,7 +928,10 @@ void process_config_info_line(char *line, bool is_init) { PagerWindow *t = Start; - update_desk_style_gcs(style); + /* Only update if it wasn't updated previously. */ + if (style->cs != color && style->hi_cs != color) + update_desk_style_gcs(style); + while (t != NULL) { if (t->desk != style->desk) { t = t->next; diff --git a/modules/FvwmPager/x_update.c b/modules/FvwmPager/x_update.c index 6474bc4ac..4932e70a9 100644 --- a/modules/FvwmPager/x_update.c +++ b/modules/FvwmPager/x_update.c @@ -240,6 +240,10 @@ void update_desk_style_gcs(DeskStyle *style) { initialize_colorset(style); + /* Don't update GC's for default style. */ + if (style->desk < 0) + return; + XSetForeground(dpy, style->label_gc, style->fg); XSetForeground(dpy, style->dashed_gc, style->fg); XSetForeground(dpy, style->hi_bg_gc, style->hi_bg);