Mercurial > mplayer.hg
annotate gui/wm/ws.c @ 36298:353055b6213d
Remove remaining XFlush() calls.
These should have been already removed in r36386,
but they were mistakenly considered necessary.
We can rely on the implicit flushes of the output buffer.
author | ib |
---|---|
date | Fri, 02 Aug 2013 22:40:25 +0000 |
parents | 6f543c795c4b |
children | f5e428d7991b |
rev | line source |
---|---|
26458 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
4 * MPlayer is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * MPlayer is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License along | |
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
35666
01ac3cd2f101
Cosmetic: Relocate and revise comments on code origin.
ib
parents:
35665
diff
changeset
|
17 * |
01ac3cd2f101
Cosmetic: Relocate and revise comments on code origin.
ib
parents:
35665
diff
changeset
|
18 * based on: AutoSpace Window System for Linux/Win32, |
01ac3cd2f101
Cosmetic: Relocate and revise comments on code origin.
ib
parents:
35665
diff
changeset
|
19 * written by pontscho/fresh!mindworkz |
26458 | 20 */ |
23077 | 21 |
35702 | 22 #include <stdint.h> |
23077 | 23 #include <stdlib.h> |
24 #include <string.h> | |
35702 | 25 #include <sys/ipc.h> |
26 #include <X11/Xatom.h> | |
23077 | 27 |
35702 | 28 #include "ws.h" |
29 #include "wsxdnd.h" | |
30 #include "gui/interface.h" | |
36053 | 31 #include "gui/app/gui.h" |
23077 | 32 |
26382
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
33 #include "config.h" |
35702 | 34 #include "help_mp.h" |
36032 | 35 #include "mp_core.h" |
36 #include "mp_msg.h" | |
37 #include "mpbswap.h" | |
38 #include "mplayer.h" | |
35702 | 39 #include "libavutil/imgutils.h" |
40 #include "libavutil/pixfmt.h" | |
41 #include "libswscale/swscale.h" | |
26382
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
23795
diff
changeset
|
42 #include "libvo/video_out.h" |
35702 | 43 #include "libvo/x11_common.h" |
34033 | 44 #include "osdep/timer.h" |
23077 | 45 |
35702 | 46 #ifdef HAVE_SHM |
47 #include <sys/shm.h> | |
48 #endif | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
49 #ifdef CONFIG_XSHAPE |
23077 | 50 #include <X11/extensions/shape.h> |
51 #endif | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
52 #ifdef CONFIG_XF86VM |
23077 | 53 #include <X11/extensions/xf86vmode.h> |
54 #endif | |
55 | |
34034
8c75091726d8
Replace numeric constant for cursor autohide time by symbolic constant.
ib
parents:
34033
diff
changeset
|
56 #define MOUSEHIDE_DELAY 1000 // in milliseconds |
8c75091726d8
Replace numeric constant for cursor autohide time by symbolic constant.
ib
parents:
34033
diff
changeset
|
57 |
35656 | 58 static wsWindow *mouse_win; |
34081 | 59 static unsigned int mouse_time; |
60 | |
35667 | 61 int wsMaxX; // Screen width. |
62 int wsMaxY; // Screen height. | |
63 int wsOrgX; // Screen origin x. | |
64 int wsOrgY; // Screen origin y. | |
23077 | 65 |
33539 | 66 Display *wsDisplay; |
35667 | 67 static int wsScreen; |
68 static Window wsRootWin; | |
23077 | 69 |
35678 | 70 static int wsScreenDepth; |
35667 | 71 static int wsRedMask; |
72 static int wsGreenMask; | |
73 static int wsBlueMask; | |
74 static int wsNonNativeOrder; | |
23077 | 75 |
33539 | 76 #define wsWLCount 5 |
35667 | 77 static wsWindow *wsWindowList[wsWLCount]; |
33539 | 78 |
35667 | 79 static int wsUseXShm = True; |
80 static int wsUseXShape = True; | |
23077 | 81 |
35707
4ba6b8d3197e
Replace PixelFormat and PIX_FMT_FOO by their AV_-prefixed counterparts.
diego
parents:
35702
diff
changeset
|
82 static enum AVPixelFormat out_pix_fmt = PIX_FMT_NONE; |
23077 | 83 |
34684 | 84 /* --- */ |
23077 | 85 |
86 #define MWM_HINTS_FUNCTIONS (1L << 0) | |
87 #define MWM_HINTS_DECORATIONS (1L << 1) | |
88 | |
89 #define MWM_FUNC_RESIZE (1L << 1) | |
90 #define MWM_FUNC_MOVE (1L << 2) | |
91 #define MWM_FUNC_MINIMIZE (1L << 3) | |
92 #define MWM_FUNC_MAXIMIZE (1L << 4) | |
93 #define MWM_FUNC_CLOSE (1L << 5) | |
94 | |
95 #define MWM_DECOR_ALL (1L << 0) | |
96 | |
33994
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
97 /** |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
98 * @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
|
99 * from xinerama information. |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
100 * |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
101 * Set wsOrgX, wsOrgY, wsMaxX and wsMaxY as well as |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
102 * win->X, win->Y, win->Width and win->Height. |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
103 * |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
104 * @param win pointer to a ws window structure or NULL |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
105 */ |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
106 static void wsWindowUpdateXinerama(wsWindow *win) |
33994
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
107 { |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
108 if (win) { |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
109 vo_dx = win->X; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
110 vo_dy = win->Y; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
111 vo_dwidth = win->Width; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
112 vo_dheight = win->Height; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
113 } |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
114 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
115 vo_screenwidth = wsMaxX; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
116 vo_screenheight = wsMaxY; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
117 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
118 update_xinerama_info(); |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
119 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
120 wsMaxX = vo_screenwidth; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
121 wsMaxY = vo_screenheight; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
122 wsOrgX = xinerama_x; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
123 wsOrgY = xinerama_y; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
124 |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
125 if (win) { |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
126 win->X = wsOrgX; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
127 win->Y = wsOrgY; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
128 win->Width = wsMaxX; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
129 win->Height = wsMaxY; |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
130 } |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
131 } |
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
132 |
35676 | 133 static int wsGetScreenDepth(void) |
35636 | 134 { |
35672 | 135 int depth; |
136 XImage *mXImage; | |
137 Visual *visual; | |
138 | |
139 if ((depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, &visual)) > 0) { | |
140 mXImage = XCreateImage(wsDisplay, visual, depth, ZPixmap, 0, NULL, | |
141 1, 1, 32, 0); | |
35676 | 142 wsScreenDepth = mXImage->bits_per_pixel; |
35677 | 143 wsRedMask = mXImage->red_mask; |
144 wsGreenMask = mXImage->green_mask; | |
145 wsBlueMask = mXImage->blue_mask; | |
35672 | 146 #if HAVE_BIGENDIAN |
147 wsNonNativeOrder = mXImage->byte_order == LSBFirst; | |
148 #else | |
149 wsNonNativeOrder = mXImage->byte_order == MSBFirst; | |
150 #endif | |
151 XDestroyImage(mXImage); | |
152 } else { | |
153 int bpp, ibpp; | |
154 XWindowAttributes attribs; | |
155 | |
156 mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); | |
157 bpp = mXImage->bits_per_pixel; | |
158 | |
159 XGetWindowAttributes(wsDisplay, wsRootWin, &attribs); | |
160 ibpp = attribs.depth; | |
161 mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); | |
162 bpp = mXImage->bits_per_pixel; | |
163 | |
164 if ((ibpp + 7) / 8 != (bpp + 7) / 8) | |
165 ibpp = bpp; | |
166 | |
35676 | 167 wsScreenDepth = ibpp; |
35677 | 168 wsRedMask = mXImage->red_mask; |
169 wsGreenMask = mXImage->green_mask; | |
170 wsBlueMask = mXImage->blue_mask; | |
35672 | 171 XDestroyImage(mXImage); |
172 } | |
173 | |
35676 | 174 return wsScreenDepth; |
35672 | 175 } |
176 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
177 void wsInit(Display *display) |
23077 | 178 { |
33539 | 179 int eventbase; |
180 int errorbase; | |
23077 | 181 |
35622
59456592c6d1
Add a message indicating start of initialization of X.
ib
parents:
35541
diff
changeset
|
182 mp_msg(MSGT_GPLAYER, MSGL_V, "X init.\n"); |
59456592c6d1
Add a message indicating start of initialization of X.
ib
parents:
35541
diff
changeset
|
183 |
35631 | 184 wsDisplay = display; |
23077 | 185 |
35636 | 186 wsSetErrorHandler(); |
31323
c674bb16fa6d
Install error handler as early as possible to avoid crashing.
reimar
parents:
31314
diff
changeset
|
187 |
23077 | 188 /* enable DND atoms */ |
33539 | 189 wsXDNDInitialize(); |
190 | |
191 { /* on remote display XShm will be disabled - LGB */ | |
192 char *dispname = DisplayString(wsDisplay); | |
193 int localdisp = 1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27377
diff
changeset
|
194 |
33539 | 195 if (dispname && *dispname != ':') { |
196 localdisp = 0; | |
35493 | 197 wsUseXShm = False; |
33539 | 198 } |
199 | |
33985 | 200 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] display name: %s => %s display.\n", dispname, localdisp ? "local" : "REMOTE"); |
23077 | 201 |
33539 | 202 if (!localdisp) |
33549 | 203 mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_WS_RemoteDisplay); |
33539 | 204 } |
205 | |
34465 | 206 #ifdef HAVE_SHM |
34461 | 207 if (!XShmQueryExtension(wsDisplay)) |
34465 | 208 #endif |
35493 | 209 wsUseXShm = False; |
33539 | 210 |
34460
c4731df07bfe
Always inform / warn about missing shared memory / shape extension
ib
parents:
34459
diff
changeset
|
211 if (!wsUseXShm) |
c4731df07bfe
Always inform / warn about missing shared memory / shape extension
ib
parents:
34459
diff
changeset
|
212 mp_msg(MSGT_GPLAYER, MSGL_INFO, MSGTR_WS_NoXshm); |
c4731df07bfe
Always inform / warn about missing shared memory / shape extension
ib
parents:
34459
diff
changeset
|
213 |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
214 #ifdef CONFIG_XSHAPE |
34461 | 215 if (!XShapeQueryExtension(wsDisplay, &eventbase, &errorbase)) |
34462 | 216 #endif |
35493 | 217 wsUseXShape = False; |
23077 | 218 |
34460
c4731df07bfe
Always inform / warn about missing shared memory / shape extension
ib
parents:
34459
diff
changeset
|
219 if (!wsUseXShape) |
c4731df07bfe
Always inform / warn about missing shared memory / shape extension
ib
parents:
34459
diff
changeset
|
220 mp_msg(MSGT_GPLAYER, MSGL_WARN, MSGTR_WS_NoXshape); |
c4731df07bfe
Always inform / warn about missing shared memory / shape extension
ib
parents:
34459
diff
changeset
|
221 |
33539 | 222 wsScreen = DefaultScreen(wsDisplay); |
223 wsRootWin = RootWindow(wsDisplay, wsScreen); | |
27377
d58d06eafe83
Change a bunch of X11-specific preprocessor directives.
diego
parents:
26458
diff
changeset
|
224 #ifdef CONFIG_XF86VM |
23077 | 225 { |
33539 | 226 int clock; |
227 XF86VidModeModeLine modeline; | |
23077 | 228 |
33539 | 229 XF86VidModeGetModeLine(wsDisplay, wsScreen, &clock, &modeline); |
230 wsMaxX = modeline.hdisplay; | |
231 wsMaxY = modeline.vdisplay; | |
23077 | 232 } |
233 #endif | |
33539 | 234 { |
235 wsOrgX = wsOrgY = 0; | |
23077 | 236 |
33539 | 237 if (!wsMaxX) |
238 wsMaxX = DisplayWidth(wsDisplay, wsScreen); | |
239 | |
240 if (!wsMaxY) | |
241 wsMaxY = DisplayHeight(wsDisplay, wsScreen); | |
23077 | 242 } |
33994
8e5680eccf54
Move common code to new function wsUpdateXineramaInfo().
ib
parents:
33993
diff
changeset
|
243 |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
244 wsWindowUpdateXinerama(NULL); |
33539 | 245 |
35676 | 246 wsGetScreenDepth(); |
33549 | 247 |
35676 | 248 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] Screen depth: %d\n", wsScreenDepth); |
33985 | 249 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] size: %dx%d\n", wsMaxX, wsMaxY); |
33549 | 250 |
33539 | 251 #ifdef CONFIG_XINERAMA |
33985 | 252 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] origin: +%d+%d\n", wsOrgX, wsOrgY); |
33539 | 253 #endif |
33549 | 254 |
33985 | 255 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] red mask: 0x%x\n", wsRedMask); |
256 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] green mask: 0x%x\n", wsGreenMask); | |
257 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] blue mask: 0x%x\n", wsBlueMask); | |
33539 | 258 |
34465 | 259 #ifdef HAVE_SHM |
33550 | 260 if (wsUseXShm) { |
261 int minor, major, shp; | |
33549 | 262 |
33550 | 263 XShmQueryVersion(wsDisplay, &major, &minor, &shp); |
33985 | 264 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] XShm version is %d.%d\n", major, minor); |
33550 | 265 } |
34465 | 266 #endif |
33539 | 267 |
268 #ifdef CONFIG_XSHAPE | |
33550 | 269 if (wsUseXShape) { |
270 int minor, major; | |
33549 | 271 |
33550 | 272 XShapeQueryVersion(wsDisplay, &major, &minor); |
33985 | 273 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] XShape version is %d.%d\n", major, minor); |
33550 | 274 } |
23077 | 275 #endif |
33549 | 276 |
35733 | 277 if (wsScreenDepth == 32 && wsRedMask == 0xff0000 && wsGreenMask == 0x00ff00 && wsBlueMask == 0x0000ff) |
33539 | 278 out_pix_fmt = PIX_FMT_RGB32; |
35733 | 279 else if (wsScreenDepth == 32 && wsRedMask == 0x0000ff && wsGreenMask == 0x00ff00 && wsBlueMask == 0xff0000) |
33539 | 280 out_pix_fmt = PIX_FMT_BGR32; |
35733 | 281 else if (wsScreenDepth == 24 && wsRedMask == 0xff0000 && wsGreenMask == 0x00ff00 && wsBlueMask == 0x0000ff) |
33539 | 282 out_pix_fmt = PIX_FMT_RGB24; |
35733 | 283 else if (wsScreenDepth == 24 && wsRedMask == 0x0000ff && wsGreenMask == 0x00ff00 && wsBlueMask == 0xff0000) |
33539 | 284 out_pix_fmt = PIX_FMT_BGR24; |
35733 | 285 else if (wsScreenDepth == 16 && wsRedMask == 0xf800 && wsGreenMask == 0x7e0 && wsBlueMask == 0x1f) |
33539 | 286 out_pix_fmt = PIX_FMT_RGB565; |
35733 | 287 else if (wsScreenDepth == 16 && wsRedMask == 0x1f && wsGreenMask == 0x7e0 && wsBlueMask == 0xf800) |
33539 | 288 out_pix_fmt = PIX_FMT_BGR565; |
35733 | 289 else if (wsScreenDepth == 15 && wsRedMask == 0x7c00 && wsGreenMask == 0x3e0 && wsBlueMask == 0x1f) |
33539 | 290 out_pix_fmt = PIX_FMT_RGB555; |
35733 | 291 else if (wsScreenDepth == 15 && wsRedMask == 0x1f && wsGreenMask == 0x3e0 && wsBlueMask == 0x7c00) |
33539 | 292 out_pix_fmt = PIX_FMT_BGR555; |
23077 | 293 } |
294 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
295 void wsDone(void) |
35672 | 296 { |
35746 | 297 // NOTE TO MYSELF: uninit wsInit stuff? |
35680 | 298 //XCloseDisplay(wsDisplay); |
35672 | 299 } |
300 | |
301 /** | |
302 * @brief Inform about an X error that has occurred. | |
303 * | |
304 * @param display display | |
305 * @param event pointer to an X error event structure | |
306 * | |
307 * @return 0 | |
308 */ | |
309 static int wsErrorHandler(Display *display, XErrorEvent *event) | |
310 { | |
311 char type[128]; | |
312 | |
313 XGetErrorText(display, event->error_code, type, sizeof(type)); | |
314 | |
315 mp_msg(MSGT_GPLAYER, MSGL_ERR, "[ws] " MSGTR_WS_XError); | |
316 mp_msg(MSGT_GPLAYER, MSGL_ERR, "[ws] Error code: %d - %s\n", event->error_code, type); | |
317 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] Request code: %d (minor code: %d)\n", event->request_code, event->minor_code); | |
318 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] MPlayer module: %s\n", current_module ? current_module : "(none)"); | |
319 | |
320 return 0; | |
321 } | |
322 | |
323 /** | |
324 * @brief Set the X error handler. | |
325 */ | |
326 void wsSetErrorHandler(void) | |
327 { | |
328 XSetErrorHandler(wsErrorHandler); | |
329 } | |
330 | |
331 // ---------------------------------------------------------------------------------------------- | |
332 // Handle events. | |
333 // ---------------------------------------------------------------------------------------------- | |
334 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
335 static int wsWindowListSearch(Window win) |
35672 | 336 { |
337 int i; | |
338 | |
339 for (i = 0; i < wsWLCount; i++) | |
340 if (wsWindowList[i] && wsWindowList[i]->WindowID == win) | |
341 return i; | |
342 | |
343 return -1; | |
344 } | |
345 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
346 void wsEvent(XEvent *event) |
35672 | 347 { |
348 unsigned long i = 0; | |
349 int l; | |
350 int x, y; | |
351 Window child_window = 0; | |
352 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
353 l = wsWindowListSearch(event->xany.window); |
35672 | 354 |
355 if (l == -1) | |
356 return; | |
357 | |
358 wsWindowList[l]->State = wsNone; | |
359 | |
360 switch (event->type) { | |
361 case ClientMessage: | |
362 | |
363 if (event->xclient.message_type == wsWindowList[l]->AtomProtocols) { | |
364 if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow) { | |
365 i = wsWindowClosed; | |
366 goto expose; | |
367 } | |
368 | |
369 if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus) { | |
370 i = wsWindowFocusIn; | |
371 wsWindowList[l]->Focused = wsFocused; | |
372 goto expose; | |
373 } | |
374 | |
375 if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomRolle) { | |
376 mp_msg(MSGT_GPLAYER, MSGL_V, "[ws] role set.\n"); | |
377 } | |
378 } else { | |
379 /* try to process DND events */ | |
380 wsXDNDProcessClientMessage(&event->xclient); | |
381 } | |
382 | |
383 break; | |
384 | |
385 case MapNotify: | |
386 | |
387 i = wsWindowMapped; | |
388 wsWindowList[l]->Mapped = wsMapped; | |
389 goto expose; | |
390 | |
391 case UnmapNotify: | |
392 | |
393 i = wsWindowUnmapped; | |
394 wsWindowList[l]->Mapped = wsNo; | |
395 goto expose; | |
396 | |
397 case FocusIn: | |
398 | |
399 if (wsWindowList[l]->Focused == wsFocused) | |
400 break; | |
401 | |
402 i = wsWindowFocusIn; | |
403 wsWindowList[l]->Focused = wsFocused; | |
404 goto expose; | |
405 | |
406 case FocusOut: | |
407 | |
408 if (wsWindowList[l]->Focused == wsNo) | |
409 break; | |
410 | |
411 i = wsWindowFocusOut; | |
412 wsWindowList[l]->Focused = wsNo; | |
413 goto expose; | |
414 | |
415 case VisibilityNotify: | |
416 | |
417 switch (event->xvisibility.state) { | |
418 case VisibilityUnobscured: | |
419 i = wsWindowVisible; | |
420 wsWindowList[l]->Visible = wsVisible; | |
421 goto expose; | |
422 | |
423 case VisibilityFullyObscured: | |
424 i = wsWindowNotVisible; | |
425 wsWindowList[l]->Visible = wsNotVisible; | |
426 goto expose; | |
427 | |
428 case VisibilityPartiallyObscured: | |
429 i = wsWindowPartialVisible; | |
430 wsWindowList[l]->Visible = wsPVisible; | |
431 goto expose; | |
432 } | |
433 | |
434 expose: | |
435 wsWindowList[l]->State = i; | |
436 | |
35760 | 437 if (wsWindowList[l]->DrawHandler) |
438 wsWindowList[l]->DrawHandler(); | |
35672 | 439 |
440 break; | |
441 | |
442 case Expose: | |
443 | |
444 wsWindowList[l]->State = wsWindowExpose; | |
445 | |
35760 | 446 if ((wsWindowList[l]->DrawHandler) && (!event->xexpose.count)) |
447 wsWindowList[l]->DrawHandler(); | |
35672 | 448 |
449 break; | |
450 | |
451 case ConfigureNotify: | |
452 | |
453 XTranslateCoordinates(wsDisplay, wsWindowList[l]->WindowID, wsRootWin, 0, 0, &x, &y, &child_window); | |
454 | |
455 if ((wsWindowList[l]->X != x) || (wsWindowList[l]->Y != y) || (wsWindowList[l]->Width != event->xconfigure.width) || (wsWindowList[l]->Height != event->xconfigure.height)) { | |
456 wsWindowList[l]->X = x; | |
457 wsWindowList[l]->Y = y; | |
458 wsWindowList[l]->Width = event->xconfigure.width; | |
459 wsWindowList[l]->Height = event->xconfigure.height; | |
460 } | |
461 | |
462 wsWindowList[l]->Rolled = wsNo; | |
463 | |
464 if (event->xconfigure.y < 0) { | |
465 i = wsWindowRolled; | |
466 wsWindowList[l]->Rolled = wsRolled; | |
467 goto expose; | |
468 } | |
469 | |
470 break; | |
471 | |
472 case KeyPress: | |
473 | |
474 i = wsKeyPressed; | |
475 goto keypressed; | |
476 | |
477 case KeyRelease: | |
478 | |
479 i = wsKeyReleased; | |
480 keypressed: | |
481 wsWindowList[l]->Alt = False; | |
482 wsWindowList[l]->Shift = False; | |
483 wsWindowList[l]->NumLock = False; | |
484 wsWindowList[l]->Control = False; | |
485 wsWindowList[l]->CapsLock = False; | |
486 | |
487 if (event->xkey.state & Mod1Mask) | |
488 wsWindowList[l]->Alt = True; | |
489 | |
490 if (event->xkey.state & Mod2Mask) | |
491 wsWindowList[l]->NumLock = True; | |
492 | |
493 if (event->xkey.state & ControlMask) | |
494 wsWindowList[l]->Control = True; | |
495 | |
496 if (event->xkey.state & ShiftMask) | |
497 wsWindowList[l]->Shift = True; | |
498 | |
499 if (event->xkey.state & LockMask) | |
500 wsWindowList[l]->CapsLock = True; | |
501 | |
502 #if 0 | |
503 { | |
504 KeySym keySym; | |
505 keySym = XKeycodeToKeysym(wsDisplay, event->xkey.keycode, 0); | |
506 | |
507 if (keySym != NoSymbol) { | |
508 keySym = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym)); | |
509 | |
510 if (wsWindowList[l]->KeyHandler) | |
511 wsWindowList[l]->KeyHandler(event->xkey.state, i, keySym); | |
512 } | |
513 } | |
514 #else | |
515 { | |
516 int key; | |
517 char buf[100]; | |
518 KeySym keySym; | |
519 static XComposeStatus stat; | |
520 | |
521 XLookupString(&event->xkey, buf, sizeof(buf), &keySym, &stat); | |
522 key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym)); | |
523 | |
524 if (wsWindowList[l]->KeyHandler) | |
525 wsWindowList[l]->KeyHandler(event->xkey.keycode, i, key); | |
526 } | |
527 #endif | |
528 break; | |
529 | |
530 case MotionNotify: | |
531 | |
532 i = wsMoveMouse; | |
533 { | |
534 /* pump all motion events from the display queue: | |
535 * this way it works faster when moving the window */ | |
536 static XEvent e; | |
537 | |
538 if (event->xmotion.state) { | |
539 while (XCheckTypedWindowEvent(wsDisplay, event->xany.window, MotionNotify, &e)) { | |
540 /* FIXME: need to make sure we didn't release/press the button in between...*/ | |
541 /* FIXME: do we need some timeout here to make sure we don't spend too much time | |
542 * removing events from the queue? */ | |
543 event = &e; | |
544 } | |
545 } | |
546 } | |
547 | |
548 if (wsWindowList[l]->wsCursor != None) { | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
549 wsMouseVisibility(wsWindowList[l], wsShowMouseCursor); |
35672 | 550 mouse_win = wsWindowList[l]; |
551 mouse_time = GetTimerMS(); | |
552 } | |
553 | |
554 goto buttonreleased; | |
555 | |
556 case ButtonRelease: | |
557 | |
558 i = event->xbutton.button + 128; | |
559 | |
560 if (wsWindowList[l]->wsCursor != None) { | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
561 wsMouseVisibility(wsWindowList[l], wsShowMouseCursor); |
35672 | 562 mouse_win = wsWindowList[l]; |
563 mouse_time = GetTimerMS(); | |
564 } | |
565 | |
566 goto buttonreleased; | |
567 | |
568 case ButtonPress: | |
569 | |
570 i = event->xbutton.button; | |
571 | |
572 if (wsWindowList[l]->wsCursor != None) { | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
573 wsMouseVisibility(wsWindowList[l], wsShowMouseCursor); |
35672 | 574 mouse_win = wsWindowList[l]; |
575 mouse_time = GetTimerMS(); | |
576 } | |
577 | |
578 goto buttonreleased; | |
579 | |
580 case EnterNotify: | |
581 | |
582 i = wsEnterWindow; | |
583 goto buttonreleased; | |
584 | |
585 case LeaveNotify: | |
586 | |
587 i = wsLeaveWindow; | |
588 buttonreleased: | |
589 | |
590 if (wsWindowList[l]->MouseHandler) | |
591 wsWindowList[l]->MouseHandler(i, event->xbutton.x, event->xbutton.y, event->xmotion.x_root, event->xmotion.y_root); | |
592 | |
593 break; | |
594 | |
595 case SelectionNotify: | |
596 | |
35759 | 597 /* Handle drag & drop */ |
35672 | 598 wsXDNDProcessSelection(wsWindowList[l], event); |
599 break; | |
600 } | |
601 } | |
602 | |
36072 | 603 /** |
604 * @brief Process all pending events. | |
605 */ | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
606 void wsEvents(void) |
35672 | 607 { |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
608 XEvent xev; |
36072 | 609 |
35672 | 610 while (XPending(wsDisplay)) { |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
611 XNextEvent(wsDisplay, &xev); |
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
612 wsEvent(&xev); |
35672 | 613 } |
614 } | |
615 | |
33995 | 616 /** |
617 * @brief Calculate and store the x and y position for a window. | |
618 * | |
619 * @param win pointer to a ws window structure | |
620 * @param x x position of the window (real/absolute or mock) | |
621 * @param y y position of the window (real/absolute or mock) | |
622 * @param width width of the area to place the window in | |
623 * @param height height of the area to place the window in | |
624 */ | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
625 static void wsWindowUpdatePosition(wsWindow *win, int x, int y, int width, int height) |
33995 | 626 { |
627 switch (x) { | |
628 case -1: | |
629 win->X = wsOrgX + (wsMaxX - width) / 2; | |
630 break; | |
631 | |
632 case -2: | |
633 win->X = wsOrgX + wsMaxX - width; | |
634 break; | |
635 | |
636 default: | |
637 win->X = x; | |
638 break; | |
639 } | |
640 | |
641 switch (y) { | |
642 case -1: | |
643 win->Y = wsOrgY + (wsMaxY - height) / 2; | |
644 break; | |
645 | |
646 case -2: | |
647 win->Y = wsOrgY + wsMaxY - height; | |
648 break; | |
649 | |
650 default: | |
651 win->Y = y; | |
652 break; | |
653 } | |
654 } | |
655 | |
35645 | 656 /** |
657 * @brief Replace the size hints for the WM_NORMAL_HINTS property of a window. | |
658 * | |
659 * @param win pointer to a ws window structure | |
660 */ | |
35700
7820bad7c1f8
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35699
diff
changeset
|
661 static void wsWindowSizeHint(wsWindow *win) |
35645 | 662 { |
35660 | 663 XSizeHints size; |
664 | |
665 size.flags = 0; | |
35645 | 666 |
35648 | 667 /* obsolete, solely for compatibility reasons */ |
35660 | 668 size.flags |= PPosition; |
669 size.x = win->X; | |
670 size.y = win->Y; | |
35645 | 671 |
35648 | 672 /* obsolete, solely for compatibility reasons */ |
35660 | 673 size.flags |= PSize; |
674 size.width = win->Width; | |
675 size.height = win->Height; | |
35645 | 676 |
35648 | 677 /* a minimum of 4 is said to avoid off-by-one errors and be required by mga_vid */ |
35660 | 678 size.flags |= PMinSize; |
679 size.min_width = 4; | |
680 size.min_height = 4; | |
35648 | 681 |
682 if (win->Property & wsMinSize) { | |
35660 | 683 size.min_width = win->Width; |
684 size.min_height = win->Height; | |
35645 | 685 } |
686 | |
35648 | 687 if (win->Property & wsMaxSize) { |
35660 | 688 size.flags |= PMaxSize; |
689 size.max_width = win->Width; | |
690 size.max_height = win->Height; | |
35645 | 691 } |
692 | |
35657 | 693 if (vo_keepaspect && (win->Property & wsAspect)) { |
35660 | 694 size.flags |= PAspect; |
695 size.min_aspect.x = win->Width; | |
696 size.min_aspect.y = win->Height; | |
697 size.max_aspect.x = win->Width; | |
698 size.max_aspect.y = win->Height; | |
35645 | 699 } |
700 | |
35660 | 701 size.flags |= PBaseSize; |
702 size.base_width = 0; | |
703 size.base_height = 0; | |
35645 | 704 |
35660 | 705 size.flags |= PWinGravity; |
706 size.win_gravity = StaticGravity; | |
35645 | 707 |
35660 | 708 XSetWMNormalHints(wsDisplay, win->WindowID, &size); |
35645 | 709 } |
710 | |
35699 | 711 static void wsWindowDecoration(wsWindow *win) |
35698 | 712 { |
713 Atom wsMotifHints; | |
714 struct { | |
715 unsigned long flags; | |
716 unsigned long functions; | |
717 unsigned long decorations; | |
718 long input_mode; | |
719 unsigned long status; | |
720 } wsMotifWmHints; | |
721 | |
722 wsMotifHints = XInternAtom(wsDisplay, "_MOTIF_WM_HINTS", 0); | |
723 | |
724 if (wsMotifHints == None) | |
725 return; | |
726 | |
727 memset(&wsMotifWmHints, 0, sizeof(wsMotifWmHints)); | |
728 wsMotifWmHints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; | |
729 | |
730 if (win->Decoration) { | |
731 wsMotifWmHints.functions = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE; | |
732 | |
733 if (!(win->Property & wsMinSize) || !(win->Property & wsMaxSize)) | |
734 wsMotifWmHints.functions |= MWM_FUNC_RESIZE; | |
735 | |
736 wsMotifWmHints.decorations = MWM_DECOR_ALL; | |
737 } | |
738 | |
739 XChangeProperty(wsDisplay, win->WindowID, wsMotifHints, wsMotifHints, 32, | |
740 PropModeReplace, (unsigned char *)&wsMotifWmHints, 5); | |
741 } | |
742 | |
23077 | 743 // ---------------------------------------------------------------------------------------------- |
744 // Create window. | |
745 // X,Y : window position | |
746 // wX,wY : size of window | |
747 // bW : border width | |
748 // cV : visible mouse cursor on window | |
749 // D : visible frame, title, etc. | |
750 // sR : screen ratio | |
751 // ---------------------------------------------------------------------------------------------- | |
752 | |
33539 | 753 XClassHint wsClassHint; |
754 XTextProperty wsTextProperty; | |
755 Window LeaderWindow; | |
23077 | 756 |
35655 | 757 // ---------------------------------------------------------------------------------------------- |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
758 // wsWindowCreate: create a new window on the screen. |
35655 | 759 // x,y : window position |
760 // w,h : window size | |
761 // c : mouse cursor visible | |
762 // p : properties - "decoration", visible titlebar, etc ... | |
763 // ---------------------------------------------------------------------------------------------- | |
35687 | 764 void wsWindowCreate(wsWindow *win, int x, int y, int w, int h, int p, int c, char *label) |
23077 | 765 { |
36193 | 766 int i, depth; |
33539 | 767 |
36193 | 768 for (i = 0; i < wsWLCount; i++) |
769 if (wsWindowList[i] == NULL) | |
770 break; | |
36192 | 771 |
36193 | 772 if (i == wsWLCount) { |
773 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_TooManyOpenWindows); | |
774 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); | |
775 } | |
36192 | 776 |
36193 | 777 wsWindowList[i] = win; |
36192 | 778 |
35655 | 779 win->Property = p; |
23077 | 780 |
35697 | 781 win->Decoration = ((p & wsShowFrame) != 0); |
33539 | 782 |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
783 wsWindowUpdatePosition(win, x, y, w, h); |
33539 | 784 |
35655 | 785 win->Width = w; |
786 win->Height = h; | |
33539 | 787 win->OldX = win->X; |
788 win->OldY = win->Y; | |
789 win->OldWidth = win->Width; | |
790 win->OldHeight = win->Height; | |
23077 | 791 |
34684 | 792 /* Hide Mouse Cursor */ |
33539 | 793 win->wsCursor = None; |
35655 | 794 win->wsMouseEventType = c; |
33539 | 795 win->wsCursorData[0] = 0; |
796 win->wsCursorPixmap = XCreateBitmapFromData(wsDisplay, wsRootWin, win->wsCursorData, 1, 1); | |
23077 | 797 |
35655 | 798 if (!(c & wsShowMouseCursor)) |
33539 | 799 win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0); |
800 | |
801 depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, NULL); | |
802 | |
803 if (depth < 15) { | |
804 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ColorDepthTooLow); | |
33768 | 805 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 806 } |
807 | |
808 XMatchVisualInfo(wsDisplay, wsScreen, depth, TrueColor, &win->VisualInfo); | |
23077 | 809 |
36258 | 810 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] visual: ID %#lx\n", win->VisualInfo.visualid); |
811 | |
34684 | 812 /* --- */ |
33539 | 813 win->AtomLeaderClient = XInternAtom(wsDisplay, "WM_CLIENT_LEADER", False); |
814 win->AtomDeleteWindow = XInternAtom(wsDisplay, "WM_DELETE_WINDOW", False); | |
815 win->AtomTakeFocus = XInternAtom(wsDisplay, "WM_TAKE_FOCUS", False); | |
816 win->AtomRolle = XInternAtom(wsDisplay, "WM_WINDOW_ROLE", False); | |
817 win->AtomWMSizeHint = XInternAtom(wsDisplay, "WM_SIZE_HINT", False); | |
818 win->AtomWMNormalHint = XInternAtom(wsDisplay, "WM_NORMAL_HINT", False); | |
819 win->AtomProtocols = XInternAtom(wsDisplay, "WM_PROTOCOLS", False); | |
820 win->AtomsProtocols[0] = win->AtomDeleteWindow; | |
821 win->AtomsProtocols[1] = win->AtomTakeFocus; | |
822 win->AtomsProtocols[2] = win->AtomRolle; | |
34684 | 823 /* --- */ |
23077 | 824 |
35737 | 825 win->WindowAttrib.border_pixel = WhitePixel(wsDisplay, wsScreen); |
826 win->WindowAttrib.colormap = XCreateColormap(wsDisplay, wsRootWin, win->VisualInfo.visual, AllocNone); | |
827 win->WindowAttrib.event_mask = StructureNotifyMask | FocusChangeMask | | |
828 ExposureMask | PropertyChangeMask | | |
829 EnterWindowMask | LeaveWindowMask | | |
830 VisibilityChangeMask | | |
831 KeyPressMask | KeyReleaseMask; | |
23077 | 832 |
35655 | 833 if ((c & wsHandleMouseButton)) |
33539 | 834 win->WindowAttrib.event_mask |= ButtonPressMask | ButtonReleaseMask; |
835 | |
35655 | 836 if ((c & wsHandleMouseMove)) |
33539 | 837 win->WindowAttrib.event_mask |= PointerMotionMask; |
838 | |
839 win->WindowAttrib.cursor = win->wsCursor; | |
840 win->WindowAttrib.override_redirect = False; | |
841 | |
35655 | 842 if (p & wsOverredirect) |
33539 | 843 win->WindowAttrib.override_redirect = True; |
23077 | 844 |
35736
f1a696672425
Remove setting pointless window attribute CWBackPixel.
ib
parents:
35734
diff
changeset
|
845 win->WindowMask = CWBorderPixel | |
33539 | 846 CWColormap | CWEventMask | CWCursor | |
847 CWOverrideRedirect; | |
23077 | 848 |
33539 | 849 win->WindowID = XCreateWindow(wsDisplay, |
850 (win->Parent != 0 ? win->Parent : wsRootWin), | |
35683
75155d8a9c7e
Remove parameter for border_width from wsWindowCreate().
ib
parents:
35682
diff
changeset
|
851 win->X, win->Y, win->Width, win->Height, 0, |
33539 | 852 win->VisualInfo.depth, |
853 InputOutput, | |
854 win->VisualInfo.visual, | |
855 win->WindowMask, &win->WindowAttrib); | |
23077 | 856 |
36055 | 857 wsClassHint.res_name = "GUI"; |
33539 | 858 |
36053 | 859 wsClassHint.res_class = MPlayer; |
33539 | 860 XSetClassHint(wsDisplay, win->WindowID, &wsClassHint); |
861 | |
35700
7820bad7c1f8
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35699
diff
changeset
|
862 wsWindowSizeHint(win); |
23077 | 863 |
33539 | 864 win->WMHints.flags = InputHint | StateHint; |
865 win->WMHints.input = True; | |
866 win->WMHints.initial_state = NormalState; | |
867 XSetWMHints(wsDisplay, win->WindowID, &win->WMHints); | |
23077 | 868 |
35697 | 869 wsWindowDecoration(win); |
33539 | 870 XStoreName(wsDisplay, win->WindowID, label); |
871 XmbSetWMProperties(wsDisplay, win->WindowID, label, label, NULL, 0, NULL, NULL, NULL); | |
23077 | 872 |
33539 | 873 XSetWMProtocols(wsDisplay, win->WindowID, win->AtomsProtocols, 3); |
874 XChangeProperty(wsDisplay, win->WindowID, | |
875 win->AtomLeaderClient, | |
876 XA_WINDOW, 32, PropModeReplace, | |
877 (unsigned char *)&LeaderWindow, 1); | |
23077 | 878 |
33539 | 879 wsTextProperty.value = label; |
880 wsTextProperty.encoding = XA_STRING; | |
881 wsTextProperty.format = 8; | |
882 wsTextProperty.nitems = strlen(label); | |
883 XSetWMIconName(wsDisplay, win->WindowID, &wsTextProperty); | |
884 | |
885 win->wGC = XCreateGC(wsDisplay, win->WindowID, | |
35679 | 886 0, |
887 NULL); | |
23077 | 888 |
35498
c505a4aa9582
Rename wsNone wsNo and use it instead of a numeric constant.
ib
parents:
35497
diff
changeset
|
889 win->Visible = wsNo; |
c505a4aa9582
Rename wsNone wsNo and use it instead of a numeric constant.
ib
parents:
35497
diff
changeset
|
890 win->Focused = wsNo; |
c505a4aa9582
Rename wsNone wsNo and use it instead of a numeric constant.
ib
parents:
35497
diff
changeset
|
891 win->Mapped = wsNo; |
c505a4aa9582
Rename wsNone wsNo and use it instead of a numeric constant.
ib
parents:
35497
diff
changeset
|
892 win->Rolled = wsNo; |
23077 | 893 |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
894 wsImageCreate(win, win->Width, win->Height); |
34684 | 895 /* End of creating -------------------------------------------------------------------------- */ |
23077 | 896 |
35760 | 897 win->DrawHandler = NULL; |
33539 | 898 win->MouseHandler = NULL; |
899 win->KeyHandler = NULL; | |
36259 | 900 mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] window successfully created: %s\n", label); |
23077 | 901 } |
902 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
903 void wsWindowDestroy(wsWindow *win) |
23077 | 904 { |
33539 | 905 int l; |
906 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
907 l = wsWindowListSearch(win->WindowID); |
35354 | 908 |
909 if (l != -1) | |
910 wsWindowList[l] = NULL; | |
33539 | 911 |
35760 | 912 win->DrawHandler = NULL; |
35752 | 913 win->MouseHandler = NULL; |
914 win->KeyHandler = NULL; | |
35759 | 915 win->DNDHandler = NULL; |
35752 | 916 |
33539 | 917 if (win->wsCursor != None) { |
918 XFreeCursor(wsDisplay, win->wsCursor); | |
919 win->wsCursor = None; | |
920 } | |
921 | |
922 XFreeGC(wsDisplay, win->wGC); | |
923 XUnmapWindow(wsDisplay, win->WindowID); | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
924 wsImageDestroy(win); |
33539 | 925 XDestroyWindow(wsDisplay, win->WindowID); |
23077 | 926 #if 0 |
35753 | 927 win->Visible = wsNo; |
928 win->Focused = wsNo; | |
929 win->Mapped = wsNo; | |
930 win->Rolled = wsNo; | |
23077 | 931 #endif |
932 } | |
933 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
934 void wsWindowShape(wsWindow *win, char *data) |
35672 | 935 { |
936 #ifdef CONFIG_XSHAPE | |
937 if (!wsUseXShape) | |
938 return; | |
939 | |
940 if (data) { | |
941 win->Mask = XCreateBitmapFromData(wsDisplay, win->WindowID, data, win->Width, win->Height); | |
942 XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, win->Mask, ShapeSet); | |
943 XFreePixmap(wsDisplay, win->Mask); | |
944 } else | |
945 XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, None, ShapeSet); | |
946 #endif | |
947 } | |
948 | |
34081 | 949 /** |
35672 | 950 * @brief Set differently sized icons to a window. |
951 * | |
952 * This function sets the X icon hint as well as | |
953 * the properties KWM_WIN_ICON and _NET_WM_ICON. | |
954 * | |
955 * @param display display | |
956 * @param Win window | |
957 * @param icon pointer to the icons | |
34081 | 958 */ |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
959 void wsWindowIcon(Display *display, Window Win, guiIcon_t *icon) |
34081 | 960 { |
35672 | 961 XWMHints *wm; |
962 Atom iconatom; | |
963 long data[2]; | |
964 | |
965 if (icon->normal) { | |
966 wm = XGetWMHints(display, Win); | |
967 | |
968 if (!wm) | |
969 wm = XAllocWMHints(); | |
970 | |
971 wm->icon_pixmap = icon->normal; | |
972 wm->icon_mask = icon->normal_mask; | |
973 wm->flags |= IconPixmapHint | IconMaskHint; | |
974 | |
975 XSetWMHints(display, Win, wm); | |
976 XFree(wm); | |
977 } | |
978 | |
979 if (icon->small || icon->normal) { | |
980 iconatom = XInternAtom(display, "KWM_WIN_ICON", False); | |
981 data[0] = (icon->small ? icon->small : icon->normal); | |
982 data[1] = (icon->small ? icon->small_mask : icon->normal_mask); | |
983 | |
984 XChangeProperty(display, Win, iconatom, iconatom, 32, PropModeReplace, (unsigned char *)data, 2); | |
985 } | |
986 | |
987 if (icon->collection) { | |
988 iconatom = XInternAtom(display, "_NET_WM_ICON", False); | |
989 XChangeProperty(display, Win, iconatom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)icon->collection, icon->collection_size); | |
34081 | 990 } |
991 } | |
992 | |
35730 | 993 /** |
994 * @brief Pack color components @a r, @a g and @a b into 15 bits. | |
995 * | |
996 * @param r red (0 - 255) | |
997 * @param g green (0 - 255) | |
998 * @param b blue (0 - 255) | |
999 * | |
1000 * @return pixel suitable for a RGB 15 bits color format | |
1001 */ | |
1002 static int pack_rgb15(int r, int g, int b) | |
1003 { | |
1004 int pixel; | |
1005 | |
35734 | 1006 pixel = r >> 3; |
35730 | 1007 pixel <<= 5; |
35734 | 1008 pixel |= g >> 3; |
35730 | 1009 pixel <<= 5; |
35734 | 1010 pixel |= b >> 3; |
35730 | 1011 |
1012 return pixel; | |
1013 } | |
1014 | |
1015 /** | |
1016 * @brief Pack color components @a r, @a g and @a b into 16 bits. | |
1017 * | |
1018 * @param r red (0 - 255) | |
1019 * @param g green (0 - 255) | |
1020 * @param b blue (0 - 255) | |
1021 * | |
1022 * @return pixel suitable for a RGB 16 bits color format | |
1023 */ | |
1024 static int pack_rgb16(int r, int g, int b) | |
1025 { | |
1026 int pixel; | |
1027 | |
35734 | 1028 pixel = r >> 3; |
35730 | 1029 pixel <<= 6; |
35734 | 1030 pixel |= g >> 2; |
35730 | 1031 pixel <<= 5; |
35734 | 1032 pixel |= b >> 3; |
35730 | 1033 |
1034 return pixel; | |
1035 } | |
1036 | |
35755
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1037 /** |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1038 * @brief Set and fill, or unset a window background. |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1039 * |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1040 * @param win pointer to a ws window structure |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1041 * @param r red (0 - 255, or -1) |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1042 * @param g green (0 - 255, or -1) |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1043 * @param b blue (0 - 255, or -1) |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1044 * |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1045 * @note Passing -1 for @a r, @a g and @a b unsets the background. |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1046 */ |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1047 void wsWindowBackground(wsWindow *win, int r, int g, int b) |
23077 | 1048 { |
35672 | 1049 int color = 0; |
35541 | 1050 |
35733 | 1051 switch (out_pix_fmt) { |
1052 case PIX_FMT_RGB32: | |
1053 case PIX_FMT_RGB24: | |
35672 | 1054 color = (r << 16) + (g << 8) + b; |
23077 | 1055 break; |
1056 | |
35733 | 1057 case PIX_FMT_BGR32: |
1058 case PIX_FMT_BGR24: | |
35672 | 1059 color = (b << 16) + (g << 8) + r; |
1060 break; | |
33539 | 1061 |
35733 | 1062 case PIX_FMT_RGB565: |
35730 | 1063 color = pack_rgb16(r, g, b); |
23077 | 1064 break; |
1065 | |
35733 | 1066 case PIX_FMT_BGR565: |
35730 | 1067 color = pack_rgb16(b, g, r); |
35728 | 1068 break; |
1069 | |
35733 | 1070 case PIX_FMT_RGB555: |
35730 | 1071 color = pack_rgb15(r, g, b); |
23077 | 1072 break; |
1073 | |
35733 | 1074 case PIX_FMT_BGR555: |
35730 | 1075 color = pack_rgb15(b, g, r); |
33539 | 1076 break; |
35733 | 1077 |
1078 default: | |
1079 ; | |
33539 | 1080 } |
1081 | |
35755
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1082 if (r == -1 && g == -1 && b == -1) |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1083 XSetWindowBackgroundPixmap(wsDisplay, win->WindowID, None); |
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1084 else { |
35756 | 1085 XSetWindowBackground(wsDisplay, win->WindowID, color); |
1086 XClearWindow(wsDisplay, win->WindowID); | |
35755
589cf8a5f165
Realize a smooth and flicker-free video when resizing during playback.
ib
parents:
35754
diff
changeset
|
1087 } |
23077 | 1088 } |
1089 | |
1090 // ---------------------------------------------------------------------------------------------- | |
1091 // Move window to x, y. | |
1092 // ---------------------------------------------------------------------------------------------- | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1093 void wsWindowMove(wsWindow *win, Bool abs, int x, int y) |
23077 | 1094 { |
33993 | 1095 if (abs) { |
1096 win->X = x; | |
1097 win->Y = y; | |
33995 | 1098 } else |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1099 wsWindowUpdatePosition(win, x, y, win->Width, win->Height); |
23077 | 1100 |
35700
7820bad7c1f8
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35699
diff
changeset
|
1101 wsWindowSizeHint(win); |
33539 | 1102 XMoveWindow(wsDisplay, win->WindowID, win->X, win->Y); |
23077 | 1103 } |
1104 | |
33998
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1105 /** |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1106 * @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
|
1107 * 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
|
1108 * |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1109 * @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
|
1110 * @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
|
1111 * @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
|
1112 * @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
|
1113 */ |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1114 void wsWindowMoveWithin(wsWindow *win, Bool abs, int x, int y) |
33998
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1115 { |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1116 Bool fitting = True; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1117 |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1118 wsWindowMove(win, abs, x, y); |
33998
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1119 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1120 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
|
1121 fitting = False; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1122 win->X = wsMaxX - win->Width; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1123 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1124 if (win->X < 0) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1125 win->X = 0; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1126 } |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1127 |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1128 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
|
1129 fitting = False; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1130 win->Y = wsMaxY - win->Height; |
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 if (win->Y < 0) |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1133 win->Y = 0; |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1134 } |
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 (!fitting) |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1137 wsWindowMove(win, True, win->X, win->Y); |
33998
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1138 } |
ca20e4098c1d
Preserve x and y position of a double-size window if possible.
ib
parents:
33996
diff
changeset
|
1139 |
23077 | 1140 // ---------------------------------------------------------------------------------------------- |
1141 // Resize window to sx, sy. | |
1142 // ---------------------------------------------------------------------------------------------- | |
35682 | 1143 void wsWindowResize(wsWindow *win, int w, int h) |
23077 | 1144 { |
35682 | 1145 win->Width = w; |
1146 win->Height = h; | |
23077 | 1147 |
33539 | 1148 if (vo_wm_type == 0) |
1149 XUnmapWindow(wsDisplay, win->WindowID); | |
23077 | 1150 |
35700
7820bad7c1f8
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35699
diff
changeset
|
1151 wsWindowSizeHint(win); |
35682 | 1152 XResizeWindow(wsDisplay, win->WindowID, w, h); |
33539 | 1153 |
34124 | 1154 if (vo_wm_type == 0) |
1155 XMapWindow(wsDisplay, win->WindowID); | |
23077 | 1156 } |
1157 | |
35355 | 1158 /** |
35672 | 1159 * @brief Switch window fullscreen state. |
1160 * | |
1161 * Switch normal window to fullscreen and fullscreen window to normal. | |
1162 * | |
1163 * @param win pointer to a ws window structure | |
1164 */ | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1165 void wsWindowFullscreen(wsWindow *win) |
35672 | 1166 { |
1167 if (win->isFullScreen) { | |
1168 if (vo_fs_type & vo_wm_FULLSCREEN) | |
1169 /* window manager supports EWMH */ | |
1170 vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_REMOVE); | |
1171 else { | |
1172 win->X = win->OldX; | |
1173 win->Y = win->OldY; | |
1174 win->Width = win->OldWidth; | |
1175 win->Height = win->OldHeight; | |
1176 } | |
1177 | |
1178 win->isFullScreen = False; | |
1179 } else { | |
1180 if (vo_fs_type & vo_wm_FULLSCREEN) | |
1181 /* window manager supports EWMH */ | |
1182 vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_ADD); | |
1183 else { | |
1184 win->OldX = win->X; | |
1185 win->OldY = win->Y; | |
1186 win->OldWidth = win->Width; | |
1187 win->OldHeight = win->Height; | |
1188 } | |
1189 | |
1190 win->isFullScreen = True; | |
1191 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1192 wsWindowUpdateXinerama(win); |
35672 | 1193 } |
1194 | |
1195 /* unknown window manager and obsolete option -fsmode used */ | |
1196 if (vo_wm_type == 0 && !(vo_fsmode & 16)) { | |
1197 XUnmapWindow(wsDisplay, win->WindowID); // required for MWM | |
1198 XWithdrawWindow(wsDisplay, win->WindowID, wsScreen); | |
1199 } | |
1200 | |
1201 /* restore window if window manager doesn't support EWMH */ | |
1202 if (!(vo_fs_type & vo_wm_FULLSCREEN)) { | |
35697 | 1203 if (!win->isFullScreen) |
1204 wsWindowDecoration(win); | |
1205 | |
35700
7820bad7c1f8
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35699
diff
changeset
|
1206 wsWindowSizeHint(win); |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1207 wsWindowLayer(wsDisplay, win->WindowID, win->isFullScreen); |
35672 | 1208 XMoveResizeWindow(wsDisplay, win->WindowID, win->X, win->Y, win->Width, win->Height); |
1209 } | |
1210 | |
1211 /* some window managers lose ontop after fullscreen */ | |
1212 if (!win->isFullScreen & vo_ontop) | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1213 wsWindowLayer(wsDisplay, win->WindowID, vo_ontop); |
35672 | 1214 |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1215 wsWindowRaiseTop(wsDisplay, win->WindowID); |
35672 | 1216 } |
1217 | |
1218 /** | |
35355 | 1219 * @brief Iconify a window. |
1220 * | |
1221 * @param win pointer to a ws window structure | |
1222 */ | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1223 void wsWindowIconify(wsWindow *win) |
33539 | 1224 { |
35355 | 1225 XIconifyWindow(wsDisplay, win->WindowID, 0); |
33539 | 1226 } |
23077 | 1227 |
35682 | 1228 void wsWindowVisibility(wsWindow *win, int vis) |
23077 | 1229 { |
35682 | 1230 switch (vis) { |
33539 | 1231 case wsShowWindow: |
35541 | 1232 |
33539 | 1233 XMapRaised(wsDisplay, win->WindowID); |
35541 | 1234 |
33952 | 1235 if (vo_fs_type & vo_wm_FULLSCREEN) |
1236 win->isFullScreen = False; | |
35541 | 1237 |
33539 | 1238 break; |
1239 | |
1240 case wsHideWindow: | |
35541 | 1241 |
33539 | 1242 XUnmapWindow(wsDisplay, win->WindowID); |
1243 break; | |
1244 } | |
23077 | 1245 } |
1246 | |
35672 | 1247 /** |
1248 * @brief Map a window and raise it to the top. | |
1249 * | |
1250 * @param display display | |
1251 * @param Win window | |
1252 */ | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1253 void wsWindowRaiseTop(Display *display, Window Win) |
23077 | 1254 { |
35672 | 1255 XMapRaised(display, Win); // NOTE TO MYSELF: is that really enough? |
1256 XRaiseWindow(display, Win); // NOTE TO MYSELF: is that really enough? | |
23077 | 1257 } |
1258 | |
35672 | 1259 // ---------------------------------------------------------------------------------------------- |
1260 // Move window to selected layer | |
1261 // ---------------------------------------------------------------------------------------------- | |
1262 | |
1263 /** | |
1264 * @brief Set the layer for a window. | |
1265 * | |
1266 * @param display display | |
1267 * @param Win window | |
1268 * @param fullscreen whether to set fullscreen or normal layer | |
1269 */ | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1270 void wsWindowLayer(Display *display, Window Win, Bool fullscreen) |
35672 | 1271 { |
1272 vo_x11_setlayer(display, Win, fullscreen); | |
1273 } | |
1274 | |
1275 // ---------------------------------------------------------------------------------------------- | |
1276 // Redraw screen. | |
1277 // ---------------------------------------------------------------------------------------------- | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1278 void wsWindowRedraw(wsWindow *win) |
35672 | 1279 { |
35760 | 1280 if (win->DrawHandler) { |
35672 | 1281 win->State = wsWindowExpose; |
35760 | 1282 win->DrawHandler(); |
35672 | 1283 } |
1284 } | |
1285 | |
1286 // ---------------------------------------------------------------------------------------------- | |
1287 // Put 'Image' to window. | |
1288 // ---------------------------------------------------------------------------------------------- | |
35682 | 1289 void wsImageCreate(wsWindow *win, int w, int h) |
23077 | 1290 { |
34465 | 1291 #ifdef HAVE_SHM |
33539 | 1292 if (wsUseXShm) { |
1293 win->xImage = XShmCreateImage(wsDisplay, win->VisualInfo.visual, | |
35682 | 1294 win->VisualInfo.depth, ZPixmap, NULL, &win->Shminfo, w, h); |
33539 | 1295 |
1296 if (win->xImage == NULL) { | |
1297 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); | |
33768 | 1298 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1299 } |
1300 | |
1301 win->Shminfo.shmid = shmget(IPC_PRIVATE, win->xImage->bytes_per_line * win->xImage->height, IPC_CREAT | 0777); | |
1302 | |
1303 if (win->Shminfo.shmid < 0) { | |
1304 XDestroyImage(win->xImage); | |
1305 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); | |
33768 | 1306 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1307 } |
1308 | |
1309 win->Shminfo.shmaddr = (char *)shmat(win->Shminfo.shmid, 0, 0); | |
1310 | |
1311 if (win->Shminfo.shmaddr == ((char *)-1)) { | |
1312 XDestroyImage(win->xImage); | |
23077 | 1313 |
33539 | 1314 if (win->Shminfo.shmaddr != ((char *)-1)) |
1315 shmdt(win->Shminfo.shmaddr); | |
1316 | |
1317 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_ShmError); | |
33768 | 1318 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1319 } |
1320 | |
1321 win->xImage->data = win->Shminfo.shmaddr; | |
35493 | 1322 win->Shminfo.readOnly = False; |
33539 | 1323 XShmAttach(wsDisplay, &win->Shminfo); |
1324 shmctl(win->Shminfo.shmid, IPC_RMID, 0); | |
34465 | 1325 } else |
1326 #endif | |
1327 { | |
33539 | 1328 win->xImage = XCreateImage(wsDisplay, win->VisualInfo.visual, win->VisualInfo.depth, |
35682 | 1329 ZPixmap, 0, 0, w, h, |
35676 | 1330 (wsScreenDepth == 3) ? 32 : wsScreenDepth, |
33539 | 1331 0); |
1332 | |
1333 if ((win->xImage->data = malloc(win->xImage->bytes_per_line * win->xImage->height)) == NULL) { | |
1334 mp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_WS_NotEnoughMemoryDrawBuffer); | |
33768 | 1335 mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); |
33539 | 1336 } |
23077 | 1337 } |
33539 | 1338 |
1339 win->ImageData = (unsigned char *)win->xImage->data; | |
1340 win->ImageDataw = (unsigned short int *)win->xImage->data; | |
1341 win->ImageDatadw = (unsigned int *)win->xImage->data; | |
23077 | 1342 } |
1343 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1344 void wsImageDestroy(wsWindow *win) |
35672 | 1345 { |
1346 if (win->xImage) { | |
1347 XDestroyImage(win->xImage); | |
1348 | |
1349 #ifdef HAVE_SHM | |
1350 if (wsUseXShm) { | |
1351 XShmDetach(wsDisplay, &win->Shminfo); | |
1352 shmdt(win->Shminfo.shmaddr); | |
1353 } | |
1354 #endif | |
1355 } | |
1356 | |
1357 win->xImage = NULL; | |
1358 } | |
1359 | |
35744 | 1360 void wsImageRender(wsWindow *win, unsigned char *img) |
35672 | 1361 { |
1362 static struct SwsContext *sws_ctx; | |
35682 | 1363 const uint8_t *src[4] = { img, NULL, NULL, NULL }; |
35672 | 1364 int src_stride[4] = { 4 * win->xImage->width, 0, 0, 0 }; |
1365 uint8_t *dst[4] = { win->ImageData, NULL, NULL, NULL }; | |
1366 int dst_stride[4]; | |
1367 int i; | |
1368 | |
1369 sws_ctx = sws_getCachedContext(sws_ctx, win->xImage->width, win->xImage->height, PIX_FMT_RGB32, | |
1370 win->xImage->width, win->xImage->height, out_pix_fmt, | |
1371 SWS_POINT, NULL, NULL, NULL); | |
1372 av_image_fill_linesizes(dst_stride, out_pix_fmt, win->xImage->width); | |
1373 sws_scale(sws_ctx, src, src_stride, 0, win->xImage->height, dst, dst_stride); | |
1374 | |
1375 if (!wsNonNativeOrder) | |
1376 return; | |
1377 | |
1378 switch (win->xImage->bits_per_pixel) { | |
1379 case 32: | |
1380 { | |
1381 uint32_t *d = (uint32_t *)win->ImageData; | |
1382 | |
1383 for (i = 0; i < win->xImage->width * win->xImage->height; i++) | |
1384 d[i] = bswap_32(d[i]); | |
1385 | |
1386 break; | |
1387 } | |
1388 | |
1389 case 16: | |
1390 case 15: | |
1391 { | |
1392 uint16_t *d = (uint16_t *)win->ImageData; | |
1393 | |
1394 for (i = 0; i < win->xImage->width * win->xImage->height; i++) | |
1395 d[i] = bswap_16(d[i]); | |
1396 | |
1397 break; | |
1398 } | |
1399 } | |
1400 } | |
1401 | |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1402 void wsImageDraw(wsWindow *win) |
35672 | 1403 { |
1404 #ifdef HAVE_SHM | |
1405 if (wsUseXShm) { | |
1406 XShmPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage, | |
1407 0, 0, | |
1408 (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2, | |
1409 win->xImage->width, win->xImage->height, 0); | |
1410 } else | |
1411 #endif | |
1412 { | |
1413 XPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage, | |
1414 0, 0, | |
1415 (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2, | |
1416 win->xImage->width, win->xImage->height); | |
1417 } | |
1418 } | |
1419 | |
35682 | 1420 void wsImageResize(wsWindow *win, int w, int h) |
33539 | 1421 { |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1422 wsImageDestroy(win); |
35682 | 1423 wsImageCreate(win, w, h); |
33539 | 1424 } |
23077 | 1425 |
35672 | 1426 // ---------------------------------------------------------------------------------------------- |
1427 // Show / hide mouse cursor. | |
1428 // ---------------------------------------------------------------------------------------------- | |
35682 | 1429 void wsMouseVisibility(wsWindow *win, int vis) |
23077 | 1430 { |
35682 | 1431 switch (vis) { |
35672 | 1432 case wsShowMouseCursor: |
33539 | 1433 |
35672 | 1434 if (win->wsCursor != None) { |
1435 XFreeCursor(wsDisplay, win->wsCursor); | |
1436 win->wsCursor = None; | |
1437 } | |
33539 | 1438 |
35672 | 1439 XDefineCursor(wsDisplay, win->WindowID, 0); |
1440 break; | |
33539 | 1441 |
35672 | 1442 case wsHideMouseCursor: |
33539 | 1443 |
35672 | 1444 win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0); |
1445 XDefineCursor(wsDisplay, win->WindowID, win->wsCursor); | |
1446 break; | |
1447 } | |
23077 | 1448 } |
1449 | |
35639 | 1450 /** |
35672 | 1451 * @brief Handle automatic hiding of the cursor. |
35639 | 1452 */ |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1453 void wsMouseAutohide(void) |
23077 | 1454 { |
35672 | 1455 if (mouse_win && (GetTimerMS() - mouse_time >= MOUSEHIDE_DELAY)) { |
35681
80c5c89f77d6
Cosmetic: Rename ws functions for the sake of consistency.
ib
parents:
35680
diff
changeset
|
1456 wsMouseVisibility(mouse_win, wsHideMouseCursor); |
35672 | 1457 mouse_win = NULL; |
33542 | 1458 } |
23077 | 1459 } |