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