summaryrefslogtreecommitdiff
path: root/src/screen.c
diff options
context:
space:
mode:
authorsabetts <sabetts>2004-02-27 08:28:16 +0000
committersabetts <sabetts>2004-02-27 08:28:16 +0000
commitfab11adc940f3258dc53c823903f242d9c65da91 (patch)
treeb1057b031c67173189c0c60dbf93fe2b2f8c1210 /src/screen.c
parenta5c30aed8f3d73ac39e997a11068d12b82eab42e (diff)
downloadratpoison-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.c219
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);
+ }
+}
+