2 * screen.c - screen management
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 extern Client
*sel
, *clients
;
30 * \param disp Display ref
31 * \param screen Screen number
32 * \param statusbar statusbar
33 * \param screen_number int pointer filled with number of screens
34 * \return ScreenInfo struct array with all screens info
37 get_screen_info(Display
*disp
, int screen
, Statusbar
*statusbar
, int *screen_number
)
39 int i
, fake_screen_number
= 0;
42 if(XineramaIsActive(disp
))
44 si
= XineramaQueryScreens(disp
, screen_number
);
45 fake_screen_number
= *screen_number
;
49 /* emulate Xinerama info but only fill the screen we want */
51 si
= p_new(ScreenInfo
, screen
+ 1);
52 si
[screen
].width
= DisplayWidth(disp
, screen
);
53 si
[screen
].height
= DisplayHeight(disp
, screen
);
56 fake_screen_number
= screen
+ 1;
60 for(i
= 0; i
< fake_screen_number
; i
++)
62 if(statusbar
->position
== BarTop
63 || statusbar
->position
== BarBot
)
64 si
[i
].height
-= statusbar
->height
;
65 if(statusbar
->position
== BarTop
)
66 si
[i
].y_org
+= statusbar
->height
;
73 * \param disp Display ref
74 * \param screen Screen number
75 * \param statusbar the statusbar
76 * \return ScreenInfo struct pointer with all display info
79 get_display_info(Display
*disp
, int screen
, Statusbar
*statusbar
)
83 si
= p_new(ScreenInfo
, 1);
86 si
->y_org
= statusbar
&& statusbar
->position
== BarTop
? statusbar
->height
: 0;
87 si
->width
= DisplayWidth(disp
, screen
);
88 si
->height
= DisplayHeight(disp
, screen
) -
89 (statusbar
&& (statusbar
->position
== BarTop
|| statusbar
->position
== BarBot
) ? statusbar
->height
: 0);
94 /** Return the Xinerama screen number where the coordinates belongs to
95 * \param disp Display ref
96 * \param x x coordinate of the window
97 * \param y y coordinate of the window
98 * \return screen number or -1 on no match
101 get_screen_bycoord(Display
*disp
, int x
, int y
)
104 int screen_number
, i
;
106 /* don't waste our time */
107 if(!XineramaIsActive(disp
))
108 return DefaultScreen(disp
);
110 si
= get_screen_info(disp
, 0, NULL
, &screen_number
);
112 for(i
= 0; i
< screen_number
; i
++)
113 if(x
>= si
[i
].x_org
&& x
< si
[i
].x_org
+ si
[i
].width
114 && y
>= si
[i
].y_org
&& y
< si
[i
].y_org
+ si
[i
].height
)
121 return DefaultScreen(disp
);
124 /** Return the actual screen count
125 * \param disp Display ref
126 * \return the number of screen available
129 get_screen_count(Display
*disp
)
133 if(XineramaIsActive(disp
))
134 XineramaQueryScreens(disp
, &screen_number
);
136 return ScreenCount(disp
);
138 return screen_number
;
141 /** This returns the real X screen number for a logical
142 * screen if Xinerama is active.
143 * \param disp Display ref
144 * \param screen the logical screen
145 * \return the X screen
148 get_phys_screen(Display
*disp
, int screen
)
150 if(XineramaIsActive(disp
))
151 return DefaultScreen(disp
);
156 move_client_to_screen(Client
*c
, awesome_config
*acf_new
, Bool doresize
)
161 c
->screen
= acf_new
->screen
;
162 p_realloc(&c
->tags
, acf_new
->ntags
);
163 for(i
= 0; i
< acf_new
->ntags
; i
++)
164 c
->tags
[i
] = acf_new
->tags
[i
].selected
;
166 si
= get_screen_info(c
->display
, c
->screen
, &acf_new
->statusbar
, &i
);
167 c
->rx
= si
[c
->screen
].x_org
;
168 c
->ry
= si
[c
->screen
].y_org
;
170 resize(c
, c
->rx
, c
->ry
, c
->rw
, c
->rh
, acf_new
, True
);
175 move_mouse_pointer_to_screen(Display
*disp
, int screen
)
177 if(XineramaIsActive(disp
))
180 ScreenInfo
*si
= get_screen_info(disp
, screen
, NULL
, &dummy
);
181 XWarpPointer(disp
, None
, DefaultRootWindow(disp
), 0, 0, 0, 0, si
[screen
].x_org
, si
[screen
].y_org
);
185 XWarpPointer(disp
, None
, RootWindow(disp
, screen
), 0, 0, 0, 0, 0, 0);
189 uicb_focusnextscreen(Display
*disp
,
191 awesome_config
* awesomeconf
,
192 const char *arg
__attribute__ ((unused
)))
195 int next_screen
= awesomeconf
->screen
+ 1 >= get_screen_count(disp
) ? 0 : awesomeconf
->screen
+ 1;
197 for(c
= clients
; c
&& !isvisible(c
, next_screen
, awesomeconf
[next_screen
- awesomeconf
->screen
].tags
, awesomeconf
[next_screen
- awesomeconf
->screen
].ntags
); c
= c
->next
);
200 focus(c
->display
, &drawcontext
[next_screen
- awesomeconf
->screen
], c
, True
, &awesomeconf
[next_screen
- awesomeconf
->screen
]);
201 restack(c
->display
, &drawcontext
[next_screen
- awesomeconf
->screen
], &awesomeconf
[next_screen
- awesomeconf
->screen
]);
203 move_mouse_pointer_to_screen(disp
, next_screen
);
207 uicb_focusprevscreen(Display
*disp
,
209 awesome_config
* awesomeconf
,
210 const char *arg
__attribute__ ((unused
)))
213 int prev_screen
= awesomeconf
->screen
- 1 < 0 ? get_screen_count(disp
) - 1 : awesomeconf
->screen
- 1;
215 for(c
= clients
; c
&& !isvisible(c
, prev_screen
, awesomeconf
[prev_screen
- awesomeconf
->screen
].tags
, awesomeconf
[prev_screen
- awesomeconf
->screen
].ntags
); c
= c
->next
);
218 focus(c
->display
, &drawcontext
[prev_screen
- awesomeconf
->screen
], c
, True
, &awesomeconf
[prev_screen
- awesomeconf
->screen
]);
219 restack(c
->display
, &drawcontext
[prev_screen
- awesomeconf
->screen
], &awesomeconf
[prev_screen
- awesomeconf
->screen
]);
221 move_mouse_pointer_to_screen(disp
, prev_screen
);
225 uicb_movetoscreen(Display
*disp
,
227 awesome_config
* awesomeconf
,
230 int new_screen
, prev_screen
;
232 if(!XineramaIsActive(disp
) || !sel
)
237 new_screen
= strtol(arg
, NULL
, 10);
238 if(new_screen
>= get_screen_count(disp
) || new_screen
< 0)
242 new_screen
= sel
->screen
+ 1 >= get_screen_count(disp
) ? 0 : sel
->screen
+ 1;
244 prev_screen
= sel
->screen
;
245 move_client_to_screen(sel
, &awesomeconf
[new_screen
- awesomeconf
->screen
], True
);
246 move_mouse_pointer_to_screen(disp
, new_screen
);
247 arrange(disp
, drawcontext
, &awesomeconf
[prev_screen
- awesomeconf
->screen
]);
248 arrange(disp
, &drawcontext
[new_screen
- awesomeconf
->screen
], &awesomeconf
[new_screen
- awesomeconf
->screen
]);