Mercurial > mplayer.hg
annotate gui/wm/ws.c @ 33998:ca20e4098c1d
Preserve x and y position of a double-size window if possible.
Only change position in an evDoubleSize event if necessary.
Do so by "dragging" the window towards the upper left if it
no longer fits into the screen.
Add a new function wsMoveWindowWithin() to accomplish this.
author | ib |
---|---|
date | Thu, 08 Sep 2011 15:31:25 +0000 |
parents | acf8545dc4b5 |
children | 3cf824f66821 |
rev | line source |
---|---|
26458 | 1 /* |
2 * AutoSpace Window System for Linux/Win32 v0.85 | |
3 * written by pontscho/fresh!mindworkz | |
4 * | |
5 * This file is part of MPlayer. | |
6 * | |
7 * MPlayer is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * MPlayer is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License along | |
18 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
20 */ | |
23077 | 21 |
22 #include <X11/Xlib.h> | |
23 #include <X11/Xproto.h> | |
24 #include <X11/Xutil.h> | |
25 #include <X11/keysym.h> | |
26 #include <X11/Xatom.h> | |
27 | |
28 #include <stdio.h> | |
29 #include <stdlib.h> | |
30 #include <string.h> | |
31 #include <unistd.h> | |
32 #include <errno.h> | |
33 | |
33123
9566100d88a1
Replace inttypes.h by stdint.h and remove inttypes.h where unneeded.
ib
parents:
32833
diff
changeset
|
34 #include <stdint.h> |
23077 | 35 |
33264 | 36 #include "gui/interface.h" |
26382
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
37 #include "config.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
38 #include "libvo/x11_common.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
39 #include "libvo/video_out.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
40 #include "cpudetect.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
41 #include "libswscale/swscale.h" |
32833
c4891d10ddbb
Adjust #include paths after the merge of libavcore into libavutil in FFmpeg.
diego
parents:
32741
diff
changeset
|
42 #include "libavutil/imgutils.h" |
26382
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
43 #include "libmpcodecs/vf_scale.h" |
33264 | 44 #include "mp_core.h" |
26382
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
45 #include "mp_msg.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
46 #include "help_mp.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
47 #include "mplayer.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
48 #include "mpbswap.h" |
23077 | 49 #include "ws.h" |
50 #include "wsxdnd.h" | |
51 | |
52 #include <X11/extensions/XShm.h> | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
53 #ifdef CONFIG_XSHAPE |
23077 | 54 #include <X11/extensions/shape.h> |
55 #endif | |
56 | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
57 #ifdef CONFIG_XINERAMA |
23077 | 58 #include <X11/extensions/Xinerama.h> |
59 #endif | |
60 | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
61 #ifdef CONFIG_XF86VM |
23077 | 62 #include <X11/extensions/xf86vmode.h> |
63 #endif | |
64 | |
65 #include <sys/ipc.h> | |
66 #include <sys/shm.h> | |
67 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27377
diff
changeset
|
68 #undef ENABLE_DPMS |
23077 | 69 |
33539 | 70 typedef struct { |
71 unsigned long flags; | |
72 unsigned long functions; | |
73 unsigned long decorations; | |
74 long input_mode; | |
75 unsigned long status; | |
23077 | 76 } MotifWmHints; |
77 | |
33539 | 78 Atom wsMotifHints; |
23077 | 79 |
33539 | 80 int wsMaxX = 0; // Screen width. |
81 int wsMaxY = 0; // Screen height. | |
82 int wsOrgX = 0; // Screen origin x. | |
83 int wsOrgY = 0; // Screen origin y. | |
23077 | 84 |
33539 | 85 Display *wsDisplay; |
86 int wsScreen; | |
87 Window wsRootWin; | |
88 XEvent wsEvent; | |
89 int wsWindowDepth; | |
90 GC wsHGC; | |
91 MotifWmHints wsMotifWmHints; | |
92 Atom wsTextProperlyAtom = None; | |
93 int wsLayer = 0; | |
23077 | 94 |
33539 | 95 int wsDepthOnScreen = 0; |
96 int wsRedMask = 0; | |
97 int wsGreenMask = 0; | |
98 int wsBlueMask = 0; | |
99 int wsOutMask = 0; | |
100 int wsNonNativeOrder = 0; | |
23077 | 101 |
33539 | 102 int wsTrue = True; |
23077 | 103 |
33539 | 104 #define wsWLCount 5 |
105 wsTWindow *wsWindowList[wsWLCount] = { NULL, NULL, NULL, NULL, NULL }; | |
106 | |
107 unsigned long wsKeyTable[512]; | |
23077 | 108 |
33539 | 109 int wsUseXShm = 1; |
110 int wsUseXShape = 1; | |
23077 | 111 |
33539 | 112 static int wsSearch(Window win) |
113 { | |
114 int i; | |
23077 | 115 |
33539 | 116 for (i = 0; i < wsWLCount; i++) |
117 if (wsWindowList[i] && wsWindowList[i]->WindowID == win) | |
118 return i; | |
119 | |
120 return -1; | |
31325 | 121 } |
122 | |
23077 | 123 // --- |
124 | |
33539 | 125 #define PACK_RGB16(r, g, b, pixel) pixel = (b >> 3); \ |
126 pixel <<= 6; \ | |
127 pixel |= (g >> 2); \ | |
128 pixel <<= 5; \ | |
129 pixel |= (r >> 3) | |
23077 | 130 |
33539 | 131 #define PACK_RGB15(r, g, b, pixel) pixel = (b >> 3); \ |
132 pixel <<= 5; \ | |
133 pixel |= (g >> 3); \ | |
134 pixel <<= 5; \ | |
135 pixel |= (r >> 3) | |
23077 | 136 |
33539 | 137 struct SwsContext *sws_ctx = NULL; |
32028
9e6fdede8ece
gui: remove direct usage of rgb2rgb interface, use swscale instead
ramiro
parents:
31325
diff
changeset
|
138 enum PixelFormat out_pix_fmt = PIX_FMT_NONE; |
23077 | 139 |
140 // --- | |
141 | |
142 #define MWM_HINTS_FUNCTIONS (1L << 0) | |
143 #define MWM_HINTS_DECORATIONS (1L << 1) | |
144 #define MWM_HINTS_INPUT_MODE (1L << 2) | |
145 #define MWM_HINTS_STATUS (1L << 3) | |
146 | |
147 #define MWM_FUNC_ALL (1L << 0) | |
148 #define MWM_FUNC_RESIZE (1L << 1) | |
149 #define MWM_FUNC_MOVE (1L << 2) | |
150 #define MWM_FUNC_MINIMIZE (1L << 3) | |
151 #define MWM_FUNC_MAXIMIZE (1L << 4) | |
152 #define MWM_FUNC_CLOSE (1L << 5) | |
153 | |
154 #define MWM_DECOR_ALL (1L << 0) | |
155 #define MWM_DECOR_BORDER (1L << 1) | |
156 #define MWM_DECOR_RESIZEH (1L << 2) | |
157 #define MWM_DECOR_TITLE (1L << 3) | |
158 #define MWM_DECOR_MENU (1L << 4) | |
159 #define MWM_DECOR_MINIMIZE (1L << 5) | |
160 #define MWM_DECOR_MAXIMIZE (1L << 6) | |
161 | |
162 #define MWM_INPUT_MODELESS 0 | |
163 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 | |
164 #define MWM_INPUT_SYSTEM_MODAL 2 | |
165 #define MWM_INPUT_FULL_APPLICATION_MODAL 3 | |
166 #define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL | |
167 | |
33539 | 168 #define MWM_TEAROFF_WINDOW (1L << 0) |
23077 | 169 |
33539 | 170 void wsWindowDecoration(wsTWindow *win, long d) |
23077 | 171 { |
33539 | 172 wsMotifHints = XInternAtom(wsDisplay, "_MOTIF_WM_HINTS", 0); |
173 | |
174 if (wsMotifHints == None) | |
175 return; | |
23077 | 176 |
33539 | 177 memset(&wsMotifWmHints, 0, sizeof(MotifWmHints)); |
178 wsMotifWmHints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; | |
179 | |
180 if (d) { | |
181 wsMotifWmHints.functions = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE; | |
182 wsMotifWmHints.decorations = MWM_DECOR_ALL; | |
183 } | |
184 | |
185 XChangeProperty(wsDisplay, win->WindowID, wsMotifHints, wsMotifHints, 32, | |
186 PropModeReplace, (unsigned char *)&wsMotifWmHints, 5); | |
23077 | 187 } |
188 | |
189 // ---------------------------------------------------------------------------------------------- | |
190 // Init X Window System. | |
191 // ---------------------------------------------------------------------------------------------- | |
192 | |
33539 | 193 static int wsErrorHandler(Display *dpy, XErrorEvent *Event) |
23077 | 194 { |
33539 | 195 char type[128]; |
196 | |
33541 | 197 XGetErrorText(dpy, Event->error_code, type, 128); |
33539 | 198 fprintf(stderr, "[ws] Error in display.\n"); |
199 fprintf(stderr, "[ws] Error code: %d ( %s )\n", Event->error_code, type); | |
200 fprintf(stderr, "[ws] Request code: %d\n", Event->request_code); | |
201 fprintf(stderr, "[ws] Minor code: %d\n", Event->minor_code); | |
202 fprintf(stderr, "[ws] Modules: %s\n", current_module ? current_module : "(NULL)"); | |
203 return 0; | |
23077 | 204 } |
205 | |
33994
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
206 /** |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
207 * @brief Update screen width, screen height and screen origin x and y |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
208 * from xinerama information. |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
209 * |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
210 * Set wsOrgX, wsOrgY, wsMaxX and wsMaxY as well as |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
211 * win->X, win->Y, win->Width and win->Height. |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
212 * |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
213 * @param win pointer to a ws window structure or NULL |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
214 */ |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
215 static void wsUpdateXineramaInfo(wsTWindow *win) |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
216 { |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
217 if (win) { |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
218 vo_dx = win->X; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
219 vo_dy = win->Y; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
220 vo_dwidth = win->Width; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
221 vo_dheight = win->Height; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
222 } |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
223 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
224 vo_screenwidth = wsMaxX; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
225 vo_screenheight = wsMaxY; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
226 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
227 update_xinerama_info(); |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
228 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
229 wsMaxX = vo_screenwidth; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
230 wsMaxY = vo_screenheight; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
231 wsOrgX = xinerama_x; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
232 wsOrgY = xinerama_y; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
233 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
234 if (win) { |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
235 win->X = wsOrgX; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
236 win->Y = wsOrgY; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
237 win->Width = wsMaxX; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
238 win->Height = wsMaxY; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
239 } |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
240 } |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
241 |
33539 | 242 void wsXInit(Display *mDisplay) |
23077 | 243 { |
33539 | 244 int eventbase; |
245 int errorbase; | |
23077 | 246 |
33539 | 247 // NOTE TO MYSELF: Use global mDisplay, get rid of wsDisplay. |
248 wsDisplay = mDisplay; | |
23077 | 249 |
33539 | 250 XSetErrorHandler(wsErrorHandler); |
31323
c674bb16fa6d
Install error handler as early as possible to avoid crashing.
reimar
parents:
31314
diff
changeset
|
251 |
23077 | 252 /* enable DND atoms */ |
33539 | 253 wsXDNDInitialize(); |
254 | |
255 { /* on remote display XShm will be disabled - LGB */ | |
256 char *dispname = DisplayString(wsDisplay); | |
257 int localdisp = 1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27377
diff
changeset
|
258 |
33539 | 259 if (dispname && *dispname != ':') { |
260 localdisp = 0; | |
261 wsUseXShm = 0; | |
262 } | |
263 | |
33985 | 264 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] display name: %s => %s display.\n", dispname, localdisp ? "local" : "REMOTE"); |
23077 | 265 |
33539 | 266 if (!localdisp) |
33549 | 267 mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_WS_RemoteDisplay); |
33539 | 268 } |
269 | |
270 if (!XShmQueryExtension(wsDisplay)) { | |
33549 | 271 mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_WS_NoXshm); |
33539 | 272 wsUseXShm = 0; |
273 } | |
274 | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
275 #ifdef CONFIG_XSHAPE |
33539 | 276 |
277 if (!XShapeQueryExtension(wsDisplay, &eventbase, &errorbase)) { | |
33549 | 278 mp_msg(MSGT_GPLAYER, MSGL_WARN, MSGTR_WS_NoXshape); |
33539 | 279 wsUseXShape = 0; |
280 } | |
281 | |
23077 | 282 #else |
33539 | 283 wsUseXShape = 0; |
23077 | 284 #endif |
285 | |
33539 | 286 XSynchronize(wsDisplay, True); |
23077 | 287 |
33539 | 288 wsScreen = DefaultScreen(wsDisplay); |
289 wsRootWin = RootWindow(wsDisplay, wsScreen); | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
290 #ifdef CONFIG_XF86VM |
23077 | 291 { |
33539 | 292 int clock; |
293 XF86VidModeModeLine modeline; | |
23077 | 294 |
33539 | 295 XF86VidModeGetModeLine(wsDisplay, wsScreen, &clock, &modeline); |
296 wsMaxX = modeline.hdisplay; | |
297 wsMaxY = modeline.vdisplay; | |
23077 | 298 } |
299 #endif | |
33539 | 300 { |
301 wsOrgX = wsOrgY = 0; | |
23077 | 302 |
33539 | 303 if (!wsMaxX) |
304 wsMaxX = DisplayWidth(wsDisplay, wsScreen); | |
305 | |
306 if (!wsMaxY) | |
307 wsMaxY = DisplayHeight(wsDisplay, wsScreen); | |
23077 | 308 } |
33994
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
309 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
310 wsUpdateXineramaInfo(NULL); |
33539 | 311 |
312 wsGetDepthOnScreen(); | |
33549 | 313 |
33985 | 314 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] Screen depth: %d\n", wsDepthOnScreen); |
315 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] size: %dx%d\n", wsMaxX, wsMaxY); | |
33549 | 316 |
33539 | 317 #ifdef CONFIG_XINERAMA |
33985 | 318 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] origin: +%d+%d\n", wsOrgX, wsOrgY); |
33539 | 319 #endif |
33549 | 320 |
33985 | 321 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] red mask: 0x%x\n", wsRedMask); |
322 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] green mask: 0x%x\n", wsGreenMask); | |
323 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] blue mask: 0x%x\n", wsBlueMask); | |
33539 | 324 |
33549 | 325 #ifdef MP_DEBUG |
33550 | 326 if (wsUseXShm) { |
327 int minor, major, shp; | |
33549 | 328 |
33550 | 329 XShmQueryVersion(wsDisplay, &major, &minor, &shp); |
33985 | 330 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] XShm version is %d.%d\n", major, minor); |
33550 | 331 } |
33539 | 332 |
333 #ifdef CONFIG_XSHAPE | |
33550 | 334 if (wsUseXShape) { |
335 int minor, major; | |
33549 | 336 |
33550 | 337 XShapeQueryVersion(wsDisplay, &major, &minor); |
33985 | 338 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] XShape version is %d.%d\n", major, minor); |
33550 | 339 } |
23077 | 340 #endif |
33539 | 341 #endif |
33549 | 342 |
33539 | 343 wsOutMask = wsGetOutMask(); |
344 | |
345 switch (wsOutMask) { | |
346 case wsRGB32: | |
347 out_pix_fmt = PIX_FMT_RGB32; | |
348 break; | |
349 | |
350 case wsBGR32: | |
351 out_pix_fmt = PIX_FMT_BGR32; | |
352 break; | |
353 | |
354 case wsRGB24: | |
355 out_pix_fmt = PIX_FMT_RGB24; | |
356 break; | |
357 | |
358 case wsBGR24: | |
359 out_pix_fmt = PIX_FMT_BGR24; | |
360 break; | |
361 | |
362 case wsRGB16: | |
363 out_pix_fmt = PIX_FMT_RGB565; | |
364 break; | |
365 | |
366 case wsBGR16: | |
367 out_pix_fmt = PIX_FMT_BGR565; | |
368 break; | |
369 | |
370 case wsRGB15: | |
371 out_pix_fmt = PIX_FMT_RGB555; | |
372 break; | |
373 | |
374 case wsBGR15: | |
375 out_pix_fmt = PIX_FMT_BGR555; | |
376 break; | |
377 } | |
23077 | 378 } |
379 | |
33995 | 380 /** |
381 * @brief Calculate and store the x and y position for a window. | |
382 * | |
383 * @param win pointer to a ws window structure | |
384 * @param x x position of the window (real/absolute or mock) | |
385 * @param y y position of the window (real/absolute or mock) | |
386 * @param width width of the area to place the window in | |
387 * @param height height of the area to place the window in | |
388 */ | |
389 static void wsWindowPosition(wsTWindow *win, int x, int y, int width, int height) | |
390 { | |
391 switch (x) { | |
392 case -1: | |
393 win->X = wsOrgX + (wsMaxX - width) / 2; | |
394 break; | |
395 | |
396 case -2: | |
397 win->X = wsOrgX + wsMaxX - width; | |
398 break; | |
399 | |
400 default: | |
401 win->X = x; | |
402 break; | |
403 } | |
404 | |
405 switch (y) { | |
406 case -1: | |
407 win->Y = wsOrgY + (wsMaxY - height) / 2; | |
408 break; | |
409 | |
410 case -2: | |
411 win->Y = wsOrgY + wsMaxY - height; | |
412 break; | |
413 | |
414 default: | |
415 win->Y = y; | |
416 break; | |
417 } | |
418 } | |
419 | |
23077 | 420 // ---------------------------------------------------------------------------------------------- |
421 // Create window. | |
422 // X,Y : window position | |
423 // wX,wY : size of window | |
424 // bW : border width | |
425 // cV : visible mouse cursor on window | |
426 // D : visible frame, title, etc. | |
427 // sR : screen ratio | |
428 // ---------------------------------------------------------------------------------------------- | |
429 | |
33539 | 430 XClassHint wsClassHint; |
431 XTextProperty wsTextProperty; | |
432 Window LeaderWindow; | |
23077 | 433 |
33539 | 434 void wsCreateWindow(wsTWindow *win, int X, int Y, int wX, int hY, int bW, int cV, unsigned char D, char *label) |
23077 | 435 { |
33539 | 436 int depth; |
437 | |
438 win->Property = D; | |
23077 | 439 |
33539 | 440 if (D & wsShowFrame) |
441 win->Decorations = 1; | |
442 | |
443 wsHGC = DefaultGC(wsDisplay, wsScreen); | |
444 | |
33995 | 445 wsWindowPosition(win, X, Y, wX, hY); |
33539 | 446 |
447 win->Width = wX; | |
448 win->Height = hY; | |
449 win->OldX = win->X; | |
450 win->OldY = win->Y; | |
451 win->OldWidth = win->Width; | |
452 win->OldHeight = win->Height; | |
23077 | 453 |
454 // Border size for window. | |
33539 | 455 win->BorderWidth = bW; |
23077 | 456 // Hide Mouse Cursor |
33539 | 457 win->wsCursor = None; |
458 win->wsMouseEventType = cV; | |
459 win->wsCursorData[0] = 0; | |
460 win->wsCursorPixmap = XCreateBitmapFromData(wsDisplay, wsRootWin, win->wsCursorData, 1, 1); | |
23077 | 461 |
33539 | 462 if (!(cV & wsShowMouseCursor)) |
463 win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0); | |
464 | |
465 depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, NULL); | |
466 | |
467 if (depth < 15) { | |
468 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ColorDepthTooLow); | |
33768 | 469 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 470 } |
471 | |
472 XMatchVisualInfo(wsDisplay, wsScreen, depth, TrueColor, &win->VisualInfo); | |
23077 | 473 |
474 // --- | |
33539 | 475 win->AtomLeaderClient = XInternAtom(wsDisplay, "WM_CLIENT_LEADER", False); |
476 win->AtomDeleteWindow = XInternAtom(wsDisplay, "WM_DELETE_WINDOW", False); | |
477 win->AtomTakeFocus = XInternAtom(wsDisplay, "WM_TAKE_FOCUS", False); | |
478 win->AtomRolle = XInternAtom(wsDisplay, "WM_WINDOW_ROLE", False); | |
479 win->AtomWMSizeHint = XInternAtom(wsDisplay, "WM_SIZE_HINT", False); | |
480 win->AtomWMNormalHint = XInternAtom(wsDisplay, "WM_NORMAL_HINT", False); | |
481 win->AtomProtocols = XInternAtom(wsDisplay, "WM_PROTOCOLS", False); | |
482 win->AtomsProtocols[0] = win->AtomDeleteWindow; | |
483 win->AtomsProtocols[1] = win->AtomTakeFocus; | |
484 win->AtomsProtocols[2] = win->AtomRolle; | |
23077 | 485 // --- |
486 | |
33539 | 487 win->WindowAttrib.background_pixel = BlackPixel(wsDisplay, wsScreen); |
488 win->WindowAttrib.border_pixel = WhitePixel(wsDisplay, wsScreen); | |
489 win->WindowAttrib.colormap = XCreateColormap(wsDisplay, wsRootWin, win->VisualInfo.visual, AllocNone); | |
490 win->WindowAttrib.event_mask = StructureNotifyMask | FocusChangeMask | | |
491 ExposureMask | PropertyChangeMask | | |
492 EnterWindowMask | LeaveWindowMask | | |
493 VisibilityChangeMask | | |
494 KeyPressMask | KeyReleaseMask; | |
23077 | 495 |
33539 | 496 if ((cV & wsHandleMouseButton)) |
497 win->WindowAttrib.event_mask |= ButtonPressMask | ButtonReleaseMask; | |
498 | |
499 if ((cV & wsHandleMouseMove)) | |
500 win->WindowAttrib.event_mask |= PointerMotionMask; | |
501 | |
502 win->WindowAttrib.cursor = win->wsCursor; | |
503 win->WindowAttrib.override_redirect = False; | |
504 | |
505 if (D & wsOverredirect) | |
506 win->WindowAttrib.override_redirect = True; | |
23077 | 507 |
33539 | 508 win->WindowMask = CWBackPixel | CWBorderPixel | |
509 CWColormap | CWEventMask | CWCursor | | |
510 CWOverrideRedirect; | |
23077 | 511 |
33539 | 512 win->WindowID = XCreateWindow(wsDisplay, |
513 (win->Parent != 0 ? win->Parent : wsRootWin), | |
514 win->X, win->Y, win->Width, win->Height, win->BorderWidth, | |
515 win->VisualInfo.depth, | |
516 InputOutput, | |
517 win->VisualInfo.visual, | |
518 win->WindowMask, &win->WindowAttrib); | |
23077 | 519 |
33539 | 520 wsClassHint.res_name = "MPlayer"; |
521 | |
522 wsClassHint.res_class = "MPlayer"; | |
523 XSetClassHint(wsDisplay, win->WindowID, &wsClassHint); | |
524 | |
525 win->SizeHint.flags = PPosition | PSize | PResizeInc | PWinGravity; // | PBaseSize; | |
526 win->SizeHint.x = win->X; | |
527 win->SizeHint.y = win->Y; | |
528 win->SizeHint.width = win->Width; | |
529 win->SizeHint.height = win->Height; | |
23077 | 530 |
33539 | 531 if (D & wsMinSize) { |
532 win->SizeHint.flags |= PMinSize; | |
533 win->SizeHint.min_width = win->Width; | |
534 win->SizeHint.min_height = win->Height; | |
535 } | |
536 | |
537 if (D & wsMaxSize) { | |
538 win->SizeHint.flags |= PMaxSize; | |
539 win->SizeHint.max_width = win->Width; | |
540 win->SizeHint.max_height = win->Height; | |
541 } | |
23077 | 542 |
33539 | 543 win->SizeHint.height_inc = 1; |
544 win->SizeHint.width_inc = 1; | |
545 win->SizeHint.base_width = win->Width; | |
546 win->SizeHint.base_height = win->Height; | |
547 win->SizeHint.win_gravity = StaticGravity; | |
548 XSetWMNormalHints(wsDisplay, win->WindowID, &win->SizeHint); | |
23077 | 549 |
33539 | 550 win->WMHints.flags = InputHint | StateHint; |
551 win->WMHints.input = True; | |
552 win->WMHints.initial_state = NormalState; | |
553 XSetWMHints(wsDisplay, win->WindowID, &win->WMHints); | |
23077 | 554 |
33539 | 555 wsWindowDecoration(win, win->Decorations); |
556 XStoreName(wsDisplay, win->WindowID, label); | |
557 XmbSetWMProperties(wsDisplay, win->WindowID, label, label, NULL, 0, NULL, NULL, NULL); | |
23077 | 558 |
33539 | 559 XSetWMProtocols(wsDisplay, win->WindowID, win->AtomsProtocols, 3); |
560 XChangeProperty(wsDisplay, win->WindowID, | |
561 win->AtomLeaderClient, | |
562 XA_WINDOW, 32, PropModeReplace, | |
563 (unsigned char *)&LeaderWindow, 1); | |
23077 | 564 |
33539 | 565 wsTextProperty.value = label; |
566 wsTextProperty.encoding = XA_STRING; | |
567 wsTextProperty.format = 8; | |
568 wsTextProperty.nitems = strlen(label); | |
569 XSetWMIconName(wsDisplay, win->WindowID, &wsTextProperty); | |
570 | |
571 win->wGC = XCreateGC(wsDisplay, win->WindowID, | |
572 GCForeground | GCBackground, | |
573 &win->wGCV); | |
23077 | 574 |
33539 | 575 win->Visible = 0; |
576 win->Focused = 0; | |
577 win->Mapped = 0; | |
578 win->Rolled = 0; | |
23077 | 579 |
33539 | 580 if (D & wsShowWindow) |
581 XMapWindow(wsDisplay, win->WindowID); | |
23077 | 582 |
33539 | 583 wsCreateImage(win, win->Width, win->Height); |
23077 | 584 // --- End of creating -------------------------------------------------------------------------- |
585 | |
33539 | 586 { |
587 int i; | |
588 | |
589 for (i = 0; i < wsWLCount; i++) | |
590 if (wsWindowList[i] == NULL) | |
591 break; | |
592 | |
593 if (i == wsWLCount) { | |
594 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_TooManyOpenWindows); | |
33768 | 595 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 596 } |
23077 | 597 |
33539 | 598 wsWindowList[i] = win; |
599 } | |
600 | |
601 XFlush(wsDisplay); | |
602 XSync(wsDisplay, False); | |
23077 | 603 |
33539 | 604 win->ReDraw = NULL; |
605 win->ReSize = NULL; | |
606 win->Idle = NULL; | |
607 win->MouseHandler = NULL; | |
608 win->KeyHandler = NULL; | |
33985 | 609 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] window is created. ( %s ).\n", label); |
23077 | 610 } |
611 | |
33539 | 612 void wsDestroyWindow(wsTWindow *win) |
23077 | 613 { |
33539 | 614 int l; |
615 | |
616 l = wsSearch(win->WindowID); | |
617 wsWindowList[l] = NULL; | |
618 | |
619 if (win->wsCursor != None) { | |
620 XFreeCursor(wsDisplay, win->wsCursor); | |
621 win->wsCursor = None; | |
622 } | |
623 | |
624 XFreeGC(wsDisplay, win->wGC); | |
625 XUnmapWindow(wsDisplay, win->WindowID); | |
626 wsDestroyImage(win); | |
627 XDestroyWindow(wsDisplay, win->WindowID); | |
23077 | 628 #if 0 |
33539 | 629 win->ReDraw = NULL; |
630 win->ReSize = NULL; | |
631 win->Idle = NULL; | |
632 win->MouseHandler = NULL; | |
633 win->KeyHandler = NULL; | |
634 win->Visible = 0; | |
635 win->Focused = 0; | |
636 win->Mapped = 0; | |
637 win->Rolled = 0; | |
23077 | 638 #endif |
639 } | |
640 | |
641 // ---------------------------------------------------------------------------------------------- | |
642 // Handle events. | |
643 // ---------------------------------------------------------------------------------------------- | |
644 | |
33541 | 645 Bool wsEvents(Display *display, XEvent *Event) |
23077 | 646 { |
33539 | 647 unsigned long i = 0; |
648 int l; | |
649 int x, y; | |
650 Window child_window = 0; | |
651 | |
652 l = wsSearch(Event->xany.window); | |
653 | |
654 if (l == -1) | |
655 return !wsTrue; | |
656 | |
657 wsWindowList[l]->State = 0; | |
658 | |
659 switch (Event->type) { | |
660 case ClientMessage: | |
23077 | 661 |
33539 | 662 if (Event->xclient.message_type == wsWindowList[l]->AtomProtocols) { |
663 if ((Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow) { | |
664 i = wsWindowClosed; | |
665 goto expose; | |
666 } | |
667 | |
668 if ((Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus) { | |
669 i = wsWindowFocusIn; | |
670 wsWindowList[l]->Focused = wsFocused; | |
671 goto expose; | |
672 } | |
673 | |
674 if ((Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomRolle) { | |
675 mp_msg(MSGT_GPLAYER, MSGL_V, "[ws] role set.\n"); | |
676 } | |
677 } else { | |
678 /* try to process DND events */ | |
679 wsXDNDProcessClientMessage(wsWindowList[l], &Event->xclient); | |
680 } | |
681 | |
23077 | 682 break; |
683 | |
33539 | 684 case MapNotify: |
685 i = wsWindowMapped; | |
686 wsWindowList[l]->Mapped = wsMapped; | |
687 goto expose; | |
688 | |
689 case UnmapNotify: | |
690 i = wsWindowUnmapped; | |
691 wsWindowList[l]->Mapped = wsNone; | |
692 goto expose; | |
693 | |
694 case FocusIn: | |
695 | |
696 if (wsWindowList[l]->Focused == wsFocused) | |
697 break; | |
698 | |
699 i = wsWindowFocusIn; | |
700 wsWindowList[l]->Focused = wsFocused; | |
701 goto expose; | |
702 | |
703 case FocusOut: | |
704 | |
705 if (wsWindowList[l]->Focused == wsNone) | |
706 break; | |
707 | |
708 i = wsWindowFocusOut; | |
709 wsWindowList[l]->Focused = wsNone; | |
23077 | 710 goto expose; |
33539 | 711 |
712 case VisibilityNotify: | |
713 | |
714 switch (Event->xvisibility.state) { | |
715 case VisibilityUnobscured: | |
716 i = wsWindowVisible; | |
717 wsWindowList[l]->Visible = wsVisible; | |
718 goto expose; | |
719 | |
720 case VisibilityFullyObscured: | |
721 i = wsWindowNotVisible; | |
722 wsWindowList[l]->Visible = wsNotVisible; | |
723 goto expose; | |
724 | |
725 case VisibilityPartiallyObscured: | |
726 i = wsWindowPartialVisible; | |
727 wsWindowList[l]->Visible = wsPVisible; | |
728 goto expose; | |
729 } | |
730 | |
23077 | 731 expose: |
33539 | 732 wsWindowList[l]->State = i; |
733 | |
734 if (wsWindowList[l]->ReDraw) | |
735 wsWindowList[l]->ReDraw(); | |
736 | |
23077 | 737 break; |
738 | |
33539 | 739 case Expose: |
740 wsWindowList[l]->State = wsWindowExpose; | |
741 | |
742 if ((wsWindowList[l]->ReDraw) && (!Event->xexpose.count)) | |
743 wsWindowList[l]->ReDraw(); | |
744 | |
23077 | 745 break; |
746 | |
33539 | 747 case ConfigureNotify: |
748 XTranslateCoordinates(wsDisplay, wsWindowList[l]->WindowID, wsRootWin, 0, 0, &x, &y, &child_window); | |
749 | |
750 if ((wsWindowList[l]->X != x) || (wsWindowList[l]->Y != y) || (wsWindowList[l]->Width != Event->xconfigure.width) || (wsWindowList[l]->Height != Event->xconfigure.height)) { | |
751 wsWindowList[l]->X = x; | |
752 wsWindowList[l]->Y = y; | |
753 wsWindowList[l]->Width = Event->xconfigure.width; | |
754 wsWindowList[l]->Height = Event->xconfigure.height; | |
23077 | 755 |
33539 | 756 if (wsWindowList[l]->ReSize) |
757 wsWindowList[l]->ReSize(wsWindowList[l]->X, wsWindowList[l]->Y, wsWindowList[l]->Width, wsWindowList[l]->Height); | |
758 } | |
759 | |
760 wsWindowList[l]->Rolled = wsNone; | |
761 | |
762 if (Event->xconfigure.y < 0) { | |
763 i = wsWindowRolled; | |
764 wsWindowList[l]->Rolled = wsRolled; | |
765 goto expose; | |
766 } | |
23077 | 767 |
768 break; | |
769 | |
33539 | 770 case KeyPress: |
771 i = wsKeyPressed; | |
772 goto keypressed; | |
773 | |
774 case KeyRelease: | |
775 i = wsKeyReleased; | |
23077 | 776 keypressed: |
33539 | 777 wsWindowList[l]->Alt = 0; |
778 wsWindowList[l]->Shift = 0; | |
779 wsWindowList[l]->NumLock = 0; | |
780 wsWindowList[l]->Control = 0; | |
781 wsWindowList[l]->CapsLock = 0; | |
782 | |
783 if (Event->xkey.state & Mod1Mask) | |
784 wsWindowList[l]->Alt = 1; | |
785 | |
786 if (Event->xkey.state & Mod2Mask) | |
787 wsWindowList[l]->NumLock = 1; | |
788 | |
789 if (Event->xkey.state & ControlMask) | |
790 wsWindowList[l]->Control = 1; | |
791 | |
792 if (Event->xkey.state & ShiftMask) | |
793 wsWindowList[l]->Shift = 1; | |
794 | |
795 if (Event->xkey.state & LockMask) | |
796 wsWindowList[l]->CapsLock = 1; | |
797 | |
23077 | 798 #if 0 |
799 { | |
33539 | 800 KeySym keySym; |
801 keySym = XKeycodeToKeysym(wsDisplay, Event->xkey.keycode, 0); | |
802 | |
803 if (keySym != NoSymbol) { | |
804 keySym = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym)); | |
805 wsKeyTable[keySym] = i; | |
806 | |
807 if (wsWindowList[l]->KeyHandler) | |
808 wsWindowList[l]->KeyHandler(Event->xkey.state, i, keySym); | |
809 } | |
810 } | |
23077 | 811 #else |
33539 | 812 { |
813 int key; | |
814 char buf[100]; | |
815 KeySym keySym; | |
816 static XComposeStatus stat; | |
23077 | 817 |
33539 | 818 XLookupString(&Event->xkey, buf, sizeof(buf), &keySym, &stat); |
819 key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym)); | |
820 wsKeyTable[key] = i; | |
821 | |
822 if (wsWindowList[l]->KeyHandler) | |
823 wsWindowList[l]->KeyHandler(Event->xkey.keycode, i, key); | |
824 } | |
23077 | 825 #endif |
826 break; | |
827 | |
33539 | 828 case MotionNotify: |
829 i = wsMoveMouse; | |
830 { | |
831 /* pump all motion events from the display queue: | |
832 * this way it works faster when moving the window */ | |
833 static XEvent e; | |
834 | |
835 if (Event->xmotion.state) { | |
836 while (XCheckTypedWindowEvent(display, Event->xany.window, MotionNotify, &e)) { | |
837 /* FIXME: need to make sure we didn't release/press the button in between...*/ | |
838 /* FIXME: do we need some timeout here to make sure we don't spend too much time | |
839 * removing events from the queue? */ | |
840 Event = &e; | |
841 } | |
842 } | |
23077 | 843 } |
33539 | 844 goto buttonreleased; |
845 | |
846 case ButtonRelease: | |
847 i = Event->xbutton.button + 128; | |
848 goto buttonreleased; | |
849 | |
850 case ButtonPress: | |
851 i = Event->xbutton.button; | |
852 goto buttonreleased; | |
853 | |
854 case EnterNotify: | |
855 i = wsEnterWindow; | |
856 goto buttonreleased; | |
857 | |
858 case LeaveNotify: | |
859 i = wsLeaveWindow; | |
23077 | 860 buttonreleased: |
33539 | 861 |
862 if (wsWindowList[l]->MouseHandler) | |
863 wsWindowList[l]->MouseHandler(i, Event->xbutton.x, Event->xbutton.y, Event->xmotion.x_root, Event->xmotion.y_root); | |
864 | |
23077 | 865 break; |
866 | |
33539 | 867 case SelectionNotify: |
868 /* Handle DandD */ | |
869 wsXDNDProcessSelection(wsWindowList[l], Event); | |
870 break; | |
871 } | |
872 | |
873 XFlush(wsDisplay); | |
874 XSync(wsDisplay, False); | |
875 return !wsTrue; | |
23077 | 876 } |
877 | |
33539 | 878 void wsHandleEvents(void) |
879 { | |
880 // handle pending events | |
881 while (XPending(wsDisplay)) { | |
882 XNextEvent(wsDisplay, &wsEvent); | |
23077 | 883 // printf("### X event: %d [%d]\n",wsEvent.type,delay); |
33541 | 884 wsEvents(wsDisplay, &wsEvent); |
33539 | 885 } |
23077 | 886 } |
887 | |
33539 | 888 void wsMainLoop(void) |
23077 | 889 { |
33539 | 890 int delay = 20; |
891 | |
892 mp_msg(MSGT_GPLAYER, MSGL_V, "[ws] init threads: %d\n", XInitThreads()); | |
893 XSynchronize(wsDisplay, False); | |
894 XLockDisplay(wsDisplay); | |
33541 | 895 // XIfEvent( wsDisplay,&wsEvent,wsEvents ); |
23077 | 896 |
33539 | 897 while (wsTrue) { |
898 // handle pending events | |
899 while (XPending(wsDisplay)) { | |
900 XNextEvent(wsDisplay, &wsEvent); | |
33541 | 901 wsEvents(wsDisplay, &wsEvent); |
33539 | 902 delay = 0; |
903 } | |
23077 | 904 |
33539 | 905 usleep(delay * 1000); // FIXME! |
906 | |
907 if (delay < 10 * 20) | |
908 delay += 20; // pump up delay up to 0.2 sec (low activity) | |
909 } | |
910 | |
911 XUnlockDisplay(wsDisplay); | |
23077 | 912 } |
913 | |
914 // ---------------------------------------------------------------------------------------------- | |
915 // Move window to selected layer | |
916 // ---------------------------------------------------------------------------------------------- | |
917 | |
918 #define WIN_LAYER_ONBOTTOM 2 | |
919 #define WIN_LAYER_NORMAL 4 | |
920 #define WIN_LAYER_ONTOP 10 | |
921 | |
33539 | 922 void wsSetLayer(Display *wsDisplay, Window win, int layer) |
923 { | |
924 vo_x11_setlayer(wsDisplay, win, layer); | |
925 } | |
23077 | 926 |
927 // ---------------------------------------------------------------------------------------------- | |
928 // Switch to fullscreen. | |
929 // ---------------------------------------------------------------------------------------------- | |
33539 | 930 void wsFullScreen(wsTWindow *win) |
23077 | 931 { |
33539 | 932 if (win->isFullScreen) { |
33937 | 933 vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH |
23077 | 934 |
33539 | 935 if (!(vo_fs_type & vo_wm_FULLSCREEN)) { // shouldn't be needed with EWMH fs |
936 win->X = win->OldX; | |
937 win->Y = win->OldY; | |
938 win->Width = win->OldWidth; | |
939 win->Height = win->OldHeight; | |
940 } | |
23077 | 941 |
33954 | 942 win->isFullScreen = False; |
943 | |
23077 | 944 #ifdef ENABLE_DPMS |
33539 | 945 wsScreenSaverOn(wsDisplay); |
23077 | 946 #endif |
33954 | 947 } else { |
948 vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_ADD); // adds fullscreen state if wm supports EWMH | |
23077 | 949 |
33539 | 950 if (!(vo_fs_type & vo_wm_FULLSCREEN)) { // shouldn't be needed with EWMH fs |
951 win->OldX = win->X; | |
952 win->OldY = win->Y; | |
953 win->OldWidth = win->Width; | |
954 win->OldHeight = win->Height; | |
33955
f56df2bcfc7b
Move a misplaced closing brace to its correct position.
ib
parents:
33954
diff
changeset
|
955 } |
f56df2bcfc7b
Move a misplaced closing brace to its correct position.
ib
parents:
33954
diff
changeset
|
956 |
33994
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
957 wsUpdateXineramaInfo(win); |
23077 | 958 |
33539 | 959 win->isFullScreen = True; |
33954 | 960 |
23077 | 961 #ifdef ENABLE_DPMS |
33539 | 962 wsScreenSaverOff(wsDisplay); |
23077 | 963 #endif |
33539 | 964 } |
23077 | 965 |
33539 | 966 if (!(vo_fs_type & vo_wm_FULLSCREEN)) { // shouldn't be needed with EWMH fs |
33996 | 967 vo_x11_decoration(wsDisplay, win->WindowID, win->Decorations && !win->isFullScreen); |
33539 | 968 vo_x11_sizehint(win->X, win->Y, win->Width, win->Height, 0); |
969 vo_x11_setlayer(wsDisplay, win->WindowID, win->isFullScreen); | |
23077 | 970 |
33539 | 971 if ((!(win->isFullScreen)) & vo_ontop) |
972 vo_x11_setlayer(wsDisplay, win->WindowID, 1); | |
23077 | 973 |
33539 | 974 XMoveResizeWindow(wsDisplay, win->WindowID, win->X, win->Y, win->Width, win->Height); |
975 } | |
23077 | 976 |
33539 | 977 if (vo_wm_type == 0 && !(vo_fsmode & 16)) { |
978 XWithdrawWindow(wsDisplay, win->WindowID, wsScreen); | |
979 } | |
23077 | 980 |
33992 | 981 wsRaiseWindowTop(wsDisplay, win->WindowID); |
33539 | 982 XFlush(wsDisplay); |
23077 | 983 } |
984 | |
985 // ---------------------------------------------------------------------------------------------- | |
986 // Redraw screen. | |
987 // ---------------------------------------------------------------------------------------------- | |
33539 | 988 void wsPostRedisplay(wsTWindow *win) |
23077 | 989 { |
33539 | 990 if (win->ReDraw) { |
991 win->State = wsWindowExpose; | |
992 win->ReDraw(); | |
993 XFlush(wsDisplay); | |
994 } | |
23077 | 995 } |
996 | |
997 // ---------------------------------------------------------------------------------------------- | |
998 // Do Exit. | |
999 // ---------------------------------------------------------------------------------------------- | |
33539 | 1000 void wsDoExit(void) |
1001 { | |
1002 wsTrue = False; | |
1003 wsResizeWindow(wsWindowList[0], 32, 32); | |
1004 } | |
23077 | 1005 |
1006 // ---------------------------------------------------------------------------------------------- | |
1007 // Put 'Image' to window. | |
1008 // ---------------------------------------------------------------------------------------------- | |
33548 | 1009 void wsConvert(wsTWindow *win, unsigned char *Image) |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1010 { |
33539 | 1011 const uint8_t *src[4] = { Image, NULL, NULL, NULL }; |
1012 int src_stride[4] = { 4 * win->xImage->width, 0, 0, 0 }; | |
1013 uint8_t *dst[4] = { win->ImageData, NULL, NULL, NULL }; | |
1014 int dst_stride[4]; | |
1015 int i; | |
1016 | |
1017 sws_ctx = sws_getCachedContext(sws_ctx, win->xImage->width, win->xImage->height, PIX_FMT_RGB32, | |
1018 win->xImage->width, win->xImage->height, out_pix_fmt, | |
1019 SWS_POINT, NULL, NULL, NULL); | |
1020 av_image_fill_linesizes(dst_stride, out_pix_fmt, win->xImage->width); | |
1021 sws_scale(sws_ctx, src, src_stride, 0, win->xImage->height, dst, dst_stride); | |
1022 | |
1023 if (!wsNonNativeOrder) | |
1024 return; | |
1025 | |
1026 switch (win->xImage->bits_per_pixel) { | |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1027 case 32: |
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1028 { |
33539 | 1029 uint32_t *d = (uint32_t *)win->ImageData; |
1030 | |
1031 for (i = 0; i < win->xImage->width * win->xImage->height; i++) | |
1032 d[i] = bswap_32(d[i]); | |
1033 | |
1034 break; | |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1035 } |
33539 | 1036 |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1037 case 16: |
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1038 case 15: |
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1039 { |
33539 | 1040 uint16_t *d = (uint16_t *)win->ImageData; |
1041 | |
1042 for (i = 0; i < win->xImage->width * win->xImage->height; i++) | |
1043 d[i] = bswap_16(d[i]); | |
1044 | |
1045 break; | |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1046 } |
33539 | 1047 } |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1048 } |
23077 | 1049 |
33539 | 1050 void wsPutImage(wsTWindow *win) |
23077 | 1051 { |
33539 | 1052 if (wsUseXShm) { |
1053 XShmPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage, | |
1054 0, 0, | |
1055 (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2, | |
1056 win->xImage->width, win->xImage->height, 0); | |
1057 } else { | |
1058 XPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage, | |
1059 0, 0, | |
1060 (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2, | |
1061 win->xImage->width, win->xImage->height); | |
1062 } | |
23077 | 1063 } |
1064 | |
1065 // ---------------------------------------------------------------------------------------------- | |
1066 // Move window to x, y. | |
1067 // ---------------------------------------------------------------------------------------------- | |
33993 | 1068 void wsMoveWindow(wsTWindow *win, Bool abs, int x, int y) |
23077 | 1069 { |
33993 | 1070 if (abs) { |
1071 win->X = x; | |
1072 win->Y = y; | |
33995 | 1073 } else |
1074 wsWindowPosition(win, x, y, win->Width, win->Height); | |
23077 | 1075 |
33539 | 1076 win->SizeHint.flags = PPosition | PWinGravity; |
1077 win->SizeHint.x = win->X; | |
1078 win->SizeHint.y = win->Y; | |
1079 win->SizeHint.win_gravity = StaticGravity; | |
1080 XSetWMNormalHints(wsDisplay, win->WindowID, &win->SizeHint); | |
23077 | 1081 |
33539 | 1082 XMoveWindow(wsDisplay, win->WindowID, win->X, win->Y); |
1083 | |
1084 if (win->ReSize) | |
1085 win->ReSize(win->X, win->Y, win->Width, win->Height); | |
23077 | 1086 } |
1087 | |
33998
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1088 /** |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1089 * @brief Move the window to the x and y position, but if it no longer fits |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1090 * into the screen, reposition it towards the upper left. |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1091 * |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1092 * @param win pointer to a ws window structure |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1093 * @param abs flag whether the position is real/absolute (True) or mock (False) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1094 * @param x x position of the window (real/absolute or mock) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1095 * @param y y position of the window (real/absolute or mock) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1096 */ |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1097 void wsMoveWindowWithin(wsTWindow *win, Bool abs, int x, int y) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1098 { |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1099 Bool fitting = True; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1100 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1101 wsMoveWindow(win, abs, x, y); |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1102 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1103 if (win->X + win->Width + 1 > wsMaxX) { |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1104 fitting = False; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1105 win->X = wsMaxX - win->Width; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1106 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1107 if (win->X < 0) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1108 win->X = 0; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1109 } |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1110 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1111 if (win->Y + win->Height + 1 > wsMaxY) { |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1112 fitting = False; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1113 win->Y = wsMaxY - win->Height; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1114 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1115 if (win->Y < 0) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1116 win->Y = 0; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1117 } |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1118 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1119 if (!fitting) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1120 wsMoveWindow(win, True, win->X, win->Y); |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1121 } |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1122 |
23077 | 1123 // ---------------------------------------------------------------------------------------------- |
1124 // Resize window to sx, sy. | |
1125 // ---------------------------------------------------------------------------------------------- | |
33539 | 1126 void wsResizeWindow(wsTWindow *win, int sx, int sy) |
23077 | 1127 { |
33539 | 1128 win->Width = sx; |
1129 win->Height = sy; | |
23077 | 1130 |
33539 | 1131 win->SizeHint.flags = PPosition | PSize | PWinGravity; // | PBaseSize; |
1132 win->SizeHint.x = win->X; | |
1133 win->SizeHint.y = win->Y; | |
1134 win->SizeHint.width = win->Width; | |
1135 win->SizeHint.height = win->Height; | |
1136 | |
1137 if (win->Property & wsMinSize) { | |
1138 win->SizeHint.flags |= PMinSize; | |
1139 win->SizeHint.min_width = win->Width; | |
1140 win->SizeHint.min_height = win->Height; | |
1141 } | |
23077 | 1142 |
33539 | 1143 if (win->Property & wsMaxSize) { |
1144 win->SizeHint.flags |= PMaxSize; | |
1145 win->SizeHint.max_width = win->Width; | |
1146 win->SizeHint.max_height = win->Height; | |
1147 } | |
1148 | |
1149 win->SizeHint.win_gravity = StaticGravity; | |
1150 win->SizeHint.base_width = sx; | |
1151 win->SizeHint.base_height = sy; | |
23077 | 1152 |
33539 | 1153 if (vo_wm_type == 0) |
1154 XUnmapWindow(wsDisplay, win->WindowID); | |
23077 | 1155 |
33539 | 1156 XSetWMNormalHints(wsDisplay, win->WindowID, &win->SizeHint); |
1157 XResizeWindow(wsDisplay, win->WindowID, sx, sy); | |
1158 | |
1159 if (win->ReSize) | |
1160 win->ReSize(win->X, win->Y, win->Width, win->Height); | |
23077 | 1161 } |
1162 | |
1163 // ---------------------------------------------------------------------------------------------- | |
1164 // Iconify window. | |
1165 // ---------------------------------------------------------------------------------------------- | |
33539 | 1166 void wsIconify(wsTWindow win) |
1167 { | |
1168 XIconifyWindow(wsDisplay, win.WindowID, 0); | |
1169 } | |
23077 | 1170 |
33991
58b5bca840a8
Replace comment for wsRaiseWindowTop() by doxygen comment.
ib
parents:
33990
diff
changeset
|
1171 /** |
58b5bca840a8
Replace comment for wsRaiseWindowTop() by doxygen comment.
ib
parents:
33990
diff
changeset
|
1172 * @brief Map a window and raise it to the top. |
58b5bca840a8
Replace comment for wsRaiseWindowTop() by doxygen comment.
ib
parents:
33990
diff
changeset
|
1173 * |
58b5bca840a8
Replace comment for wsRaiseWindowTop() by doxygen comment.
ib
parents:
33990
diff
changeset
|
1174 * @param dsp display |
58b5bca840a8
Replace comment for wsRaiseWindowTop() by doxygen comment.
ib
parents:
33990
diff
changeset
|
1175 * @param win window |
58b5bca840a8
Replace comment for wsRaiseWindowTop() by doxygen comment.
ib
parents:
33990
diff
changeset
|
1176 */ |
33990
3a93b9227b01
Cosmetic: Rename wsMoveTopWindow() wsRaiseWindowTop().
ib
parents:
33985
diff
changeset
|
1177 void wsRaiseWindowTop(Display *dsp, Window win) |
23077 | 1178 { |
33990
3a93b9227b01
Cosmetic: Rename wsMoveTopWindow() wsRaiseWindowTop().
ib
parents:
33985
diff
changeset
|
1179 XMapRaised(dsp, win); |
3a93b9227b01
Cosmetic: Rename wsMoveTopWindow() wsRaiseWindowTop().
ib
parents:
33985
diff
changeset
|
1180 XRaiseWindow(dsp, win); |
23077 | 1181 } |
1182 | |
1183 // ---------------------------------------------------------------------------------------------- | |
1184 // Set window background to 'color'. | |
1185 // ---------------------------------------------------------------------------------------------- | |
33539 | 1186 void wsSetBackground(wsTWindow *win, int color) |
23077 | 1187 { |
33539 | 1188 XSetWindowBackground(wsDisplay, win->WindowID, color); |
23077 | 1189 } |
1190 | |
33539 | 1191 void wsSetBackgroundRGB(wsTWindow *win, int r, int g, int b) |
23077 | 1192 { |
33539 | 1193 int color = 0; |
1194 | |
1195 switch (wsOutMask) { | |
1196 case wsRGB32: | |
1197 case wsRGB24: | |
1198 color = (r << 16) + (g << 8) + b; | |
1199 break; | |
1200 | |
1201 case wsBGR32: | |
1202 case wsBGR24: | |
1203 color = (b << 16) + (g << 8) + r; | |
1204 break; | |
1205 | |
1206 case wsRGB16: | |
1207 PACK_RGB16(b, g, r, color); | |
1208 break; | |
1209 | |
1210 case wsBGR16: | |
1211 PACK_RGB16(r, g, b, color); | |
1212 break; | |
1213 | |
1214 case wsRGB15: | |
1215 PACK_RGB15(b, g, r, color); | |
1216 break; | |
1217 | |
1218 case wsBGR15: | |
1219 PACK_RGB15(r, g, b, color); | |
1220 break; | |
1221 } | |
1222 | |
1223 XSetWindowBackground(wsDisplay, win->WindowID, color); | |
1224 } | |
1225 | |
1226 void wsSetForegroundRGB(wsTWindow *win, int r, int g, int b) | |
1227 { | |
1228 int color = 0; | |
1229 | |
1230 switch (wsOutMask) { | |
1231 case wsRGB32: | |
1232 case wsRGB24: | |
1233 color = (r << 16) + (g << 8) + b; | |
1234 break; | |
1235 | |
1236 case wsBGR32: | |
1237 case wsBGR24: | |
1238 color = (b << 16) + (g << 8) + r; | |
1239 break; | |
1240 | |
1241 case wsRGB16: | |
1242 PACK_RGB16(b, g, r, color); | |
1243 break; | |
1244 | |
1245 case wsBGR16: | |
1246 PACK_RGB16(r, g, b, color); | |
1247 break; | |
1248 | |
1249 case wsRGB15: | |
1250 PACK_RGB15(b, g, r, color); | |
1251 break; | |
1252 | |
1253 case wsBGR15: | |
1254 PACK_RGB15(r, g, b, color); | |
1255 break; | |
1256 } | |
1257 | |
1258 XSetForeground(wsDisplay, win->wGC, color); | |
23077 | 1259 } |
1260 | |
1261 // ---------------------------------------------------------------------------------------------- | |
1262 // Draw string at x,y with fc ( foreground color ) and bc ( background color ). | |
1263 // ---------------------------------------------------------------------------------------------- | |
33539 | 1264 void wsDrawString(wsTWindow win, int x, int y, char *str, int fc, int bc) |
23077 | 1265 { |
33539 | 1266 XSetForeground(wsDisplay, win.wGC, bc); |
1267 XFillRectangle(wsDisplay, win.WindowID, win.wGC, x, y, | |
1268 XTextWidth(win.Font, str, strlen(str)) + 20, | |
1269 win.FontHeight + 2); | |
1270 XSetForeground(wsDisplay, win.wGC, fc); | |
1271 XDrawString(wsDisplay, win.WindowID, win.wGC, x + 10, y + 13, str, strlen(str)); | |
23077 | 1272 } |
1273 | |
1274 // ---------------------------------------------------------------------------------------------- | |
1275 // Calculation string width. | |
1276 // ---------------------------------------------------------------------------------------------- | |
33539 | 1277 int wsTextWidth(wsTWindow win, char *str) |
1278 { | |
1279 return XTextWidth(win.Font, str, strlen(str)) + 20; | |
1280 } | |
23077 | 1281 |
1282 // ---------------------------------------------------------------------------------------------- | |
1283 // Show / hide mouse cursor. | |
1284 // ---------------------------------------------------------------------------------------------- | |
33539 | 1285 void wsVisibleMouse(wsTWindow *win, int m) |
23077 | 1286 { |
33539 | 1287 switch (m) { |
1288 case wsShowMouseCursor: | |
1289 | |
1290 if (win->wsCursor != None) { | |
1291 XFreeCursor(wsDisplay, win->wsCursor); | |
1292 win->wsCursor = None; | |
1293 } | |
1294 | |
1295 XDefineCursor(wsDisplay, win->WindowID, 0); | |
1296 break; | |
1297 | |
1298 case wsHideMouseCursor: | |
1299 win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0); | |
1300 XDefineCursor(wsDisplay, win->WindowID, win->wsCursor); | |
1301 break; | |
1302 } | |
1303 | |
1304 XFlush(wsDisplay); | |
23077 | 1305 } |
1306 | |
33539 | 1307 int wsGetDepthOnScreen(void) |
23077 | 1308 { |
33539 | 1309 int depth; |
1310 XImage *mXImage; | |
1311 Visual *visual; | |
23077 | 1312 |
33539 | 1313 if ((depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, &visual)) > 0) { |
1314 mXImage = XCreateImage(wsDisplay, visual, depth, ZPixmap, 0, NULL, | |
1315 1, 1, 32, 0); | |
1316 wsDepthOnScreen = mXImage->bits_per_pixel; | |
1317 wsRedMask = mXImage->red_mask; | |
1318 wsGreenMask = mXImage->green_mask; | |
1319 wsBlueMask = mXImage->blue_mask; | |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29263
diff
changeset
|
1320 #if HAVE_BIGENDIAN |
33539 | 1321 wsNonNativeOrder = mXImage->byte_order == LSBFirst; |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1322 #else |
33539 | 1323 wsNonNativeOrder = mXImage->byte_order == MSBFirst; |
23453
3e18bed9618a
Make gmplayer show right colors if X server does not use native byteorder.
reimar
parents:
23077
diff
changeset
|
1324 #endif |
33539 | 1325 XDestroyImage(mXImage); |
1326 } else { | |
1327 int bpp, ibpp; | |
1328 XWindowAttributes attribs; | |
23077 | 1329 |
33539 | 1330 mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); |
1331 bpp = mXImage->bits_per_pixel; | |
23077 | 1332 |
33539 | 1333 XGetWindowAttributes(wsDisplay, wsRootWin, &attribs); |
1334 ibpp = attribs.depth; | |
1335 mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); | |
1336 bpp = mXImage->bits_per_pixel; | |
1337 | |
1338 if ((ibpp + 7) / 8 != (bpp + 7) / 8) | |
1339 ibpp = bpp; | |
1340 | |
1341 wsDepthOnScreen = ibpp; | |
1342 wsRedMask = mXImage->red_mask; | |
1343 wsGreenMask = mXImage->green_mask; | |
1344 wsBlueMask = mXImage->blue_mask; | |
1345 XDestroyImage(mXImage); | |
1346 } | |
1347 | |
1348 return wsDepthOnScreen; | |
23077 | 1349 } |
1350 | |
33539 | 1351 void wsXDone(void) |
23077 | 1352 { |
33539 | 1353 XCloseDisplay(wsDisplay); |
23077 | 1354 } |
1355 | |
33539 | 1356 void wsVisibleWindow(wsTWindow *win, int show) |
23077 | 1357 { |
33539 | 1358 switch (show) { |
1359 case wsShowWindow: | |
1360 XMapRaised(wsDisplay, win->WindowID); | |
33952 | 1361 if (vo_fs_type & vo_wm_FULLSCREEN) |
1362 win->isFullScreen = False; | |
33539 | 1363 break; |
1364 | |
1365 case wsHideWindow: | |
1366 XUnmapWindow(wsDisplay, win->WindowID); | |
1367 break; | |
1368 } | |
1369 | |
1370 XFlush(wsDisplay); | |
23077 | 1371 } |
1372 | |
33539 | 1373 void wsDestroyImage(wsTWindow *win) |
23077 | 1374 { |
33539 | 1375 if (win->xImage) { |
1376 XDestroyImage(win->xImage); | |
1377 | |
1378 if (wsUseXShm) { | |
1379 XShmDetach(wsDisplay, &win->Shminfo); | |
1380 shmdt(win->Shminfo.shmaddr); | |
1381 } | |
23077 | 1382 } |
33539 | 1383 |
1384 win->xImage = NULL; | |
23077 | 1385 } |
1386 | |
33539 | 1387 void wsCreateImage(wsTWindow *win, int Width, int Height) |
23077 | 1388 { |
33539 | 1389 if (wsUseXShm) { |
1390 win->xImage = XShmCreateImage(wsDisplay, win->VisualInfo.visual, | |
1391 win->VisualInfo.depth, ZPixmap, NULL, &win->Shminfo, Width, Height); | |
1392 | |
1393 if (win->xImage == NULL) { | |
1394 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); | |
33768 | 1395 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1396 } |
1397 | |
1398 win->Shminfo.shmid = shmget(IPC_PRIVATE, win->xImage->bytes_per_line * win->xImage->height, IPC_CREAT | 0777); | |
1399 | |
1400 if (win->Shminfo.shmid < 0) { | |
1401 XDestroyImage(win->xImage); | |
1402 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); | |
33768 | 1403 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1404 } |
1405 | |
1406 win->Shminfo.shmaddr = (char *)shmat(win->Shminfo.shmid, 0, 0); | |
1407 | |
1408 if (win->Shminfo.shmaddr == ((char *)-1)) { | |
1409 XDestroyImage(win->xImage); | |
23077 | 1410 |
33539 | 1411 if (win->Shminfo.shmaddr != ((char *)-1)) |
1412 shmdt(win->Shminfo.shmaddr); | |
1413 | |
1414 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); | |
33768 | 1415 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1416 } |
1417 | |
1418 win->xImage->data = win->Shminfo.shmaddr; | |
1419 win->Shminfo.readOnly = 0; | |
1420 XShmAttach(wsDisplay, &win->Shminfo); | |
1421 XSync(wsDisplay, False); | |
1422 shmctl(win->Shminfo.shmid, IPC_RMID, 0); | |
1423 } else { | |
1424 win->xImage = XCreateImage(wsDisplay, win->VisualInfo.visual, win->VisualInfo.depth, | |
1425 ZPixmap, 0, 0, Width, Height, | |
1426 (wsDepthOnScreen == 3) ? 32 : wsDepthOnScreen, | |
1427 0); | |
1428 | |
1429 if ((win->xImage->data = malloc(win->xImage->bytes_per_line * win->xImage->height)) == NULL) { | |
1430 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_NotEnoughMemoryDrawBuffer); | |
33768 | 1431 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1432 } |
23077 | 1433 } |
33539 | 1434 |
1435 win->ImageData = (unsigned char *)win->xImage->data; | |
1436 win->ImageDataw = (unsigned short int *)win->xImage->data; | |
1437 win->ImageDatadw = (unsigned int *)win->xImage->data; | |
23077 | 1438 } |
1439 | |
33539 | 1440 void wsResizeImage(wsTWindow *win, int Width, int Height) |
1441 { | |
1442 wsDestroyImage(win); | |
1443 wsCreateImage(win, Width, Height); | |
1444 } | |
23077 | 1445 |
33539 | 1446 int wsGetOutMask(void) |
23077 | 1447 { |
33539 | 1448 if ((wsDepthOnScreen == 32) && (wsRedMask == 0xff0000) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0x0000ff)) |
1449 return wsRGB32; | |
1450 | |
1451 if ((wsDepthOnScreen == 32) && (wsRedMask == 0x0000ff) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0xff0000)) | |
1452 return wsBGR32; | |
1453 | |
1454 if ((wsDepthOnScreen == 24) && (wsRedMask == 0xff0000) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0x0000ff)) | |
1455 return wsRGB24; | |
1456 | |
1457 if ((wsDepthOnScreen == 24) && (wsRedMask == 0x0000ff) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0xff0000)) | |
1458 return wsBGR24; | |
1459 | |
1460 if ((wsDepthOnScreen == 16) && (wsRedMask == 0xf800) && (wsGreenMask == 0x7e0) && (wsBlueMask == 0x1f)) | |
1461 return wsRGB16; | |
1462 | |
1463 if ((wsDepthOnScreen == 16) && (wsRedMask == 0x1f) && (wsGreenMask == 0x7e0) && (wsBlueMask == 0xf800)) | |
1464 return wsBGR16; | |
1465 | |
1466 if ((wsDepthOnScreen == 15) && (wsRedMask == 0x7c00) && (wsGreenMask == 0x3e0) && (wsBlueMask == 0x1f)) | |
1467 return wsRGB15; | |
1468 | |
1469 if ((wsDepthOnScreen == 15) && (wsRedMask == 0x1f) && (wsGreenMask == 0x3e0) && (wsBlueMask == 0x7c00)) | |
1470 return wsBGR15; | |
1471 | |
1472 return 0; | |
23077 | 1473 } |
1474 | |
33539 | 1475 void wsSetTitle(wsTWindow *win, char *name) |
1476 { | |
1477 XStoreName(wsDisplay, win->WindowID, name); | |
1478 } | |
23077 | 1479 |
33539 | 1480 void wsSetMousePosition(wsTWindow *win, int x, int y) |
1481 { | |
1482 XWarpPointer(wsDisplay, wsRootWin, win->WindowID, 0, 0, 0, 0, x, y); | |
1483 } | |
23077 | 1484 |
1485 #ifdef ENABLE_DPMS | |
33539 | 1486 static int dpms_disabled = 0; |
1487 static int timeout_save = 0; | |
23077 | 1488 |
33539 | 1489 void wsScreenSaverOn(Display *mDisplay) |
23077 | 1490 { |
33539 | 1491 int nothing; |
1492 | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
1493 #ifdef CONFIG_XDPMS |
33539 | 1494 |
1495 if (dpms_disabled) { | |
1496 if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) { | |
1497 if (!DPMSEnable(mDisplay)) | |
1498 mp_msg(MSGT_GPLAYER, MSGL_ERR, MSGTR_WS_DpmsUnavailable); // restoring power saving settings | |
1499 else { | |
1500 // DPMS does not seem to be enabled unless we call DPMSInfo | |
1501 BOOL onoff; | |
1502 CARD16 state; | |
1503 DPMSInfo(mDisplay, &state, &onoff); | |
1504 | |
1505 if (onoff) | |
1506 mp_msg(MSGT_GPLAYER, MSGL_V, "Successfully enabled DPMS.\n"); | |
1507 else | |
1508 mp_msg(MSGT_GPLAYER, MSGL_STATUS, MSGTR_WS_DpmsNotEnabled); | |
1509 } | |
1510 } | |
1511 } | |
1512 | |
1513 #endif | |
1514 | |
1515 if (timeout_save) { | |
1516 int dummy, interval, prefer_blank, allow_exp; | |
1517 XGetScreenSaver(mDisplay, &dummy, &interval, &prefer_blank, &allow_exp); | |
1518 XSetScreenSaver(mDisplay, timeout_save, interval, prefer_blank, allow_exp); | |
1519 XGetScreenSaver(mDisplay, &timeout_save, &interval, &prefer_blank, &allow_exp); | |
1520 } | |
1521 } | |
1522 | |
1523 void wsScreenSaverOff(Display *mDisplay) | |
1524 { | |
1525 int interval, prefer_blank, allow_exp, nothing; | |
1526 | |
1527 #ifdef CONFIG_XDPMS | |
1528 | |
1529 if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) { | |
23077 | 1530 BOOL onoff; |
1531 CARD16 state; | |
33539 | 1532 DPMSInfo(mDisplay, &state, &onoff); |
1533 | |
1534 if (onoff) { | |
1535 Status stat; | |
33985 | 1536 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "Disabling DPMS.\n"); |
33539 | 1537 dpms_disabled = 1; |
1538 stat = DPMSDisable(mDisplay); // monitor powersave off | |
33985 | 1539 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "stat: %d.\n", stat); |
33539 | 1540 } |
23077 | 1541 } |
33539 | 1542 |
23077 | 1543 #endif |
33539 | 1544 XGetScreenSaver(mDisplay, &timeout_save, &interval, &prefer_blank, &allow_exp); |
1545 | |
1546 if (timeout_save) | |
1547 XSetScreenSaver(mDisplay, 0, interval, prefer_blank, allow_exp); // turning off screensaver | |
23077 | 1548 } |
1549 | |
1550 #endif | |
1551 | |
33539 | 1552 void wsSetShape(wsTWindow *win, char *data) |
23077 | 1553 { |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
1554 #ifdef CONFIG_XSHAPE |
33539 | 1555 |
1556 if (!wsUseXShape) | |
1557 return; | |
1558 | |
1559 if (data) { | |
1560 win->Mask = XCreateBitmapFromData(wsDisplay, win->WindowID, data, win->Width, win->Height); | |
1561 XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, win->Mask, ShapeSet); | |
1562 XFreePixmap(wsDisplay, win->Mask); | |
1563 } else | |
1564 XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, None, ShapeSet); | |
1565 | |
23077 | 1566 #endif |
1567 } | |
1568 | |
33975 | 1569 /** |
33977 | 1570 * @brief Set differently sized icons to a window. |
33975 | 1571 * |
1572 * This function sets the X icon hint as well as | |
1573 * the properties KWM_WIN_ICON and _NET_WM_ICON. | |
1574 * | |
1575 * @param dsp display | |
1576 * @param win window | |
1577 * @param icon pointer to the icons | |
1578 */ | |
33539 | 1579 void wsSetIcon(Display *dsp, Window win, guiIcon_t *icon) |
23077 | 1580 { |
33539 | 1581 XWMHints *wm; |
33540 | 1582 Atom iconatom; |
33925 | 1583 long data[2]; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27377
diff
changeset
|
1584 |
33544 | 1585 if (icon->normal) { |
33545 | 1586 wm = XGetWMHints(dsp, win); |
33539 | 1587 |
33545 | 1588 if (!wm) |
1589 wm = XAllocWMHints(); | |
23077 | 1590 |
33545 | 1591 wm->icon_pixmap = icon->normal; |
1592 wm->icon_mask = icon->normal_mask; | |
1593 wm->flags |= IconPixmapHint | IconMaskHint; | |
23077 | 1594 |
33545 | 1595 XSetWMHints(dsp, win, wm); |
1596 XFree(wm); | |
33544 | 1597 } |
23077 | 1598 |
33544 | 1599 if (icon->small || icon->normal) { |
33545 | 1600 iconatom = XInternAtom(dsp, "KWM_WIN_ICON", False); |
1601 data[0] = (icon->small ? icon->small : icon->normal); | |
1602 data[1] = (icon->small ? icon->small_mask : icon->normal_mask); | |
33540 | 1603 |
33545 | 1604 XChangeProperty(dsp, win, iconatom, iconatom, 32, PropModeReplace, (unsigned char *)data, 2); |
33544 | 1605 } |
33542 | 1606 |
1607 if (icon->collection) { | |
1608 iconatom = XInternAtom(dsp, "_NET_WM_ICON", False); | |
1609 XChangeProperty(dsp, win, iconatom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)icon->collection, icon->collection_size); | |
1610 } | |
23077 | 1611 } |