diff options
author | sabetts <sabetts> | 2004-02-27 08:28:16 +0000 |
---|---|---|
committer | sabetts <sabetts> | 2004-02-27 08:28:16 +0000 |
commit | fab11adc940f3258dc53c823903f242d9c65da91 (patch) | |
tree | b1057b031c67173189c0c60dbf93fe2b2f8c1210 /src/screen.c | |
parent | a5c30aed8f3d73ac39e997a11068d12b82eab42e (diff) | |
download | ratpoison-fab11adc940f3258dc53c823903f242d9c65da91.zip |
* src/window.c (give_window_focus): save the mouse position before
checking if win is NULL.
(give_window_focus): set rp_current_screen to xine_screen_num of
the window's screen.
(set_active_window): when using xinerama get the frame from the
current screen.
* src/split.c (set_frames_window): update the window's scr
attribute to point to the frame's screen.
(find_window_for_frame): when xinerama is being used search all
windows.
(set_active_frame): update rp_current_screen to point to the
frame's screen.
* src/screen.h (init_screens): new prototype
(is_rp_window_for_screen): likewise
* src/screen.c: include string.h and X11/cursorfont.h
(init_screens): new function
(is_rp_window_for_screen): new function.
(init_screen): fill in xine_screen_num when using xinerama.
* src/ratpoison.h: include xinerama.h
* src/manage.c (current_screen): use xine_screen_num to find the
current screen.
(scanwins): use is_rp_window_for_screen to skip over ratpoison windows.
(scanwins): when using xinerama only manage windows inside the viewable area.
* src/main.c (main): call init_xinerama and init_screens. Move
screen initing code to these functions.
(init_rat_cursor): move to screen.c
(init_screen): likewise
(find_screen): likewise
(clean_up): call free_xinerama
* src/group.c (group_last_window): only check windows in the
current screen, unless xinerama is being used in which case all
windows are accessible.
(group_next_window): likewise
(group_prev_window): likewise
* src/globals.h: new globals rp_have_xinerama, xine_screen_num.
* src/events.c (new_window): when using xinerama, the new window's
screen is the current screen.
(key_press): when using xinerama, use the current screen.
* src/data.h (struct rp_screen): remove root_attr and add left,
top, width, height. All dependant code updated. Add xine_screen_num.
* src/actions.c (cmd_remove): show the frame indicator in the new
current frame after removing the frame.
* src/Makefile.am (ratpoison_SOURCES): add xinerama.c and xinerama.h
Diffstat (limited to 'src/screen.c')
-rw-r--r-- | src/screen.c | 219 |
1 files changed, 215 insertions, 4 deletions
diff --git a/src/screen.c b/src/screen.c index dec512a..f46e3ca 100644 --- a/src/screen.c +++ b/src/screen.c @@ -19,23 +19,27 @@ */ #include "ratpoison.h" +#include <string.h> +#include <X11/cursorfont.h> + +static void init_screen (rp_screen *s, int screen_num); int screen_width (rp_screen *s) { - return DisplayWidth (dpy, s->screen_num) - defaults.padding_right - defaults.padding_left; + return s->width - defaults.padding_right - defaults.padding_left; } int screen_height (rp_screen *s) { - return DisplayHeight (dpy, s->screen_num) - defaults.padding_bottom - defaults.padding_top; + return s->height - defaults.padding_bottom - defaults.padding_top; } int screen_left (rp_screen *s) { - return defaults.padding_left; + return s->left + defaults.padding_left; } int @@ -47,7 +51,7 @@ screen_right (rp_screen *s) int screen_top (rp_screen *s) { - return defaults.padding_top; + return s->top + defaults.padding_top; } int @@ -116,3 +120,210 @@ screen_get_frame (rp_screen *s, int frame_num) return NULL; } + +/* Given a root window, return the rp_screen struct */ +rp_screen * +find_screen (Window w) +{ + int i; + + for (i=0; i<num_screens; i++) + if (screens[i].root == w) return &screens[i]; + + return NULL; + } + +void +init_screens (int screen_arg, int screen_num) +{ + int i; + + /* Get the number of screens */ + if (rp_have_xinerama) + num_screens = xine_screen_count; + else + num_screens = ScreenCount (dpy); + + /* make sure the screen specified is valid. */ + if (screen_arg) + { + /* Using just a single Xinerama screen doesn't really make sense. So we + * disable Xinerama in this case. + */ + if (rp_have_xinerama) + { + fprintf (stderr, "Warning: selecting a specific Xinerama screen is not implemented.\n"); + rp_have_xinerama = 0; + screen_num = 0; + num_screens = ScreenCount(dpy); + } + + if (screen_num < 0 || screen_num >= num_screens) + { + fprintf (stderr, "%d is an invalid screen for the display\n", screen_num); + exit (EXIT_FAILURE); + } + + /* we're only going to use one screen. */ + num_screens = 1; + } + + /* Initialize the screens */ + screens = (rp_screen *)xmalloc (sizeof (rp_screen) * num_screens); + PRINT_DEBUG (("%d screens.\n", num_screens)); + + if (screen_arg) + { + init_screen (&screens[0], screen_num); + } + else + { + for (i=0; i<num_screens; i++) + { + init_screen (&screens[i], i); + } + } + +} + +static void +init_rat_cursor (rp_screen *s) +{ + s->rat = XCreateFontCursor( dpy, XC_icon ); +} + +static void +init_screen (rp_screen *s, int screen_num) +{ + XGCValues gv; + int xine_screen_num; + + /* We use screen_num below to refer to the real X screen number, but + * if we're using Xinerama, it will only be the Xinerama logical screen + * number. So we shuffle it away and replace it with the real one now, + * to cause confusion. -- CP + */ + if (rp_have_xinerama) + { + xine_screen_num = screen_num; + screen_num = DefaultScreen(dpy); + xinerama_get_screen_info(xine_screen_num, + &s->left, &s->top, &s->width, &s->height); + } + else + { + xine_screen_num = screen_num; + s->left = 0; + s->top = 0; + s->width = DisplayWidth(dpy, screen_num); + s->height = DisplayHeight(dpy, screen_num); + } + + /* Select on some events on the root window, if this fails, then + there is already a WM running and the X Error handler will catch + it, terminating ratpoison. */ + XSelectInput(dpy, RootWindow (dpy, screen_num), + PropertyChangeMask | ColormapChangeMask + | SubstructureRedirectMask | SubstructureNotifyMask ); + XSync (dpy, False); + + /* Create the numset for the frames. */ + s->frames_numset = numset_new (); + + /* Build the display string for each screen */ + s->display_string = xmalloc (strlen(DisplayString (dpy)) + 21); + sprintf (s->display_string, "DISPLAY=%s", DisplayString (dpy)); + if (strrchr (DisplayString (dpy), ':')) + { + char *dot; + + dot = strrchr(s->display_string, '.'); + if (dot) + sprintf(dot, ".%i", screen_num); + } + + PRINT_DEBUG (("%s\n", s->display_string)); + + s->screen_num = screen_num; + s->xine_screen_num = xine_screen_num; + s->root = RootWindow (dpy, screen_num); + s->def_cmap = DefaultColormap (dpy, screen_num); + + init_rat_cursor (s); + + s->fg_color = BlackPixel (dpy, s->screen_num); + s->bg_color = WhitePixel (dpy, s->screen_num); + + /* Setup the GC for drawing the font. */ + gv.foreground = s->fg_color; + gv.background = s->bg_color; + gv.function = GXcopy; + gv.line_width = 1; + gv.subwindow_mode = IncludeInferiors; + gv.font = defaults.font->fid; + s->normal_gc = XCreateGC(dpy, s->root, + GCForeground | GCBackground | GCFunction + | GCLineWidth | GCSubwindowMode | GCFont, + &gv); + + /* Create the program bar window. */ + s->bar_is_raised = 0; + s->bar_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, + defaults.bar_border_width, + s->fg_color, s->bg_color); + + /* Setup the window that will receive all keystrokes once the prefix + key has been pressed. */ + s->key_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, 0, + WhitePixel (dpy, s->screen_num), + BlackPixel (dpy, s->screen_num)); + XSelectInput (dpy, s->key_window, KeyPressMask | KeyReleaseMask); + XMapWindow (dpy, s->key_window); + + /* Create the input window. */ + s->input_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, + defaults.bar_border_width, + s->fg_color, s->bg_color); + XSelectInput (dpy, s->input_window, KeyPressMask | KeyReleaseMask); + + /* Create the frame indicator window */ + s->frame_window = XCreateSimpleWindow (dpy, s->root, 1, 1, 1, 1, defaults.bar_border_width, + s->fg_color, s->bg_color); + + /* Create the help window */ + s->help_window = XCreateSimpleWindow (dpy, s->root, s->left, s->top, s->width, + s->height, 0, s->fg_color, s->bg_color); + XSelectInput (dpy, s->help_window, KeyPressMask); + + XSync (dpy, 0); +} + +static int +is_rp_window_for_given_screen (Window w, rp_screen *s) +{ + if (w != s->key_window && + w != s->bar_window && + w != s->input_window && + w != s->frame_window && + w != s->help_window) + return 0; + return 1; +} + +int +is_rp_window_for_screen(Window w, rp_screen *s) +{ + int i; + + if (rp_have_xinerama) + { + for (i=0; i<num_screens; i++) + if (is_rp_window_for_given_screen(w, &screens[i])) return 1; + return 0; + } + else + { + return is_rp_window_for_given_screen(w, s); + } +} + |