From 629b1187677ac9174b67b07cd016e7ae68f96687 Mon Sep 17 00:00:00 2001 From: Ralf Hoffmann Date: Thu, 10 Dec 2009 19:57:23 +0100 Subject: [PATCH] fixed problem with default visual ID for multi-screen setups by using multiple IDs for each screen Since a single default visual ID cannot be used for multiple screens, thus Window Maker refused to start. There is now a global function for getting the default visual ID. The command line argument --visual-id can be a comma separated list of visual IDs for each screen. A default value is only set for the first screen. --- src/funcs.h | 2 ++ src/main.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/screen.c | 5 ++- 3 files changed, 101 insertions(+), 9 deletions(-) diff --git a/src/funcs.h b/src/funcs.h index f49536ef..8dfcc5c9 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -148,4 +148,6 @@ char* GetProgramNameForWindow(Window win); Bool GetCommandForPid(int pid, char ***argv, int *argc); +int getWVisualID(int screen); + #endif diff --git a/src/main.c b/src/main.c index 2ad68f86..98badde9 100644 --- a/src/main.c +++ b/src/main.c @@ -145,9 +145,6 @@ char WProgramSigState = 0; char WProgramState = WSTATE_NORMAL; char WDelayedActionSet = 0; -/* temporary stuff */ -int wVisualID = -1; - /* notifications */ const char *WMNManaged = "WMNManaged"; const char *WMNUnmanaged = "WMNUnmanaged"; @@ -178,8 +175,100 @@ extern int MonitorLoop(int argc, char **argv); static Bool multiHead = True; +static int *wVisualID = NULL; +static int wVisualID_len = 0; + static int real_main(int argc, char **argv); +int getWVisualID(int screen) +{ + if (wVisualID == NULL) + return -1; + if (screen < 0 || screen >= wVisualID_len) + return -1; + + return wVisualID[screen]; +} + +static void setWVisualID(int screen, int val) +{ + int i; + + if (screen < 0) + return; + + if (wVisualID == NULL) { + /* no array at all, alloc space for screen + 1 entries + * and init with default value */ + wVisualID_len = screen + 1; + wVisualID = (int *)malloc(wVisualID_len * sizeof(int)); + for (i = 0; i < wVisualID_len; i++) { + wVisualID[i] = -1; + } + } else if (screen >= wVisualID_len) { + /* larger screen number than previously allocated + so enlarge array */ + int oldlen = wVisualID_len; + + wVisualID_len = screen + 1; + wVisualID = (int *)realloc(wVisualID, wVisualID_len * sizeof(int)); + for (i = oldlen; i < wVisualID_len; i++) { + wVisualID[i] = -1; + } + } + + wVisualID[screen] = val; +} + +/* + * this function splits a given string at the comma into tokens + * and set the wVisualID variable to each parsed number + */ +static int initWVisualID(const char *user_str) +{ + char *mystr = strdup(user_str); + int cur_in_pos = 0; + int cur_out_pos = 0; + int cur_screen = 0; + int error_found = 0; + + for (;;) { + /* check for delimiter */ + if (user_str[cur_in_pos] == '\0' || user_str[cur_in_pos] == ',') { + int v; + + mystr[cur_out_pos] = '\0'; + + if (sscanf(mystr, "%i", &v) != 1) { + error_found = 1; + break; + } + + setWVisualID(cur_screen, v); + + cur_screen++; + cur_out_pos = 0; + } + + /* break in case last char has been consumed */ + if (user_str[cur_in_pos] == '\0') + break; + + /* if the current char is no delimiter put it into mystr */ + if (user_str[cur_in_pos] != ',') { + mystr[cur_out_pos++] = user_str[cur_in_pos]; + } + cur_in_pos++; + } + + free(mystr); + + if (cur_screen == 0||error_found != 0) + return 1; + + return 0; +} + void Exit(int status) { #ifdef XSMP_ENABLED @@ -640,7 +729,7 @@ static int real_main(int argc, char **argv) wwarning(_("too few arguments for %s"), argv[i - 1]); exit(0); } - if (sscanf(argv[i], "%i", &wVisualID) != 1) { + if (initWVisualID(argv[i]) != 0) { wwarning(_("bad value for visualid: \"%s\""), argv[i]); exit(0); } @@ -722,7 +811,8 @@ static int real_main(int argc, char **argv) exit(1); } - if (wVisualID < 0) + + if (getWVisualID(0) < 0) { /* * If unspecified, use default visual instead of waiting * for wrlib/context.c:bestContext() that may end up choosing @@ -730,7 +820,8 @@ static int real_main(int argc, char **argv) * This is required to avoid all sort of corruptions when * composite is enabled, and at a depth other than 24. */ - wVisualID = (int)DefaultVisual(dpy, DefaultScreen(dpy))->visualid; + setWVisualID(0, (int)DefaultVisual(dpy, DefaultScreen(dpy))->visualid); + } /* check if the user specified a complete display name (with screen). * If so, only manage the specified screen */ diff --git a/src/screen.c b/src/screen.c index 58649f95..6dd30bad 100644 --- a/src/screen.c +++ b/src/screen.c @@ -538,7 +538,6 @@ WScreen *wScreenInit(int screen_number) WScreen *scr; XIconSize icon_size[1]; RContextAttributes rattr; - extern int wVisualID; long event_mask; XErrorHandler oldHandler; int i; @@ -625,9 +624,9 @@ WScreen *wScreenInit(int screen_number) rattr.standard_colormap_mode = RUseStdColormap; } - if (wVisualID >= 0) { + if (getWVisualID(screen_number) >= 0) { rattr.flags |= RC_VisualID; - rattr.visualid = wVisualID; + rattr.visualid = getWVisualID(screen_number); } scr->rcontext = RCreateContext(dpy, screen_number, &rattr); -- 2.11.4.GIT