1 /*
2 * Copyright (C) 2000-2019 the xine project
3 *
4 * This file is part of xine, a free video player.
5 *
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * video window handling functions
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/time.h>
31 #include <sys/wait.h>
32 #include <X11/Xlib.h>
33 #include <X11/cursorfont.h>
34 #include <X11/keysym.h>
35 #ifdef HAVE_XINERAMA
36 #include <X11/extensions/Xinerama.h>
37 #endif
38 #ifdef HAVE_XF86VIDMODE
39 #include <X11/extensions/xf86vmode.h>
40 #endif
41 #ifdef HAVE_XTESTEXTENSION
42 #include <X11/extensions/XTest.h>
43 #endif
44 #ifdef HAVE_XSSAVEREXTENSION
45 #include <X11/extensions/scrnsaver.h>
46 #endif
47
48 #include "common.h"
49 #include "oxine/oxine.h"
50
51 #define EST_KEEP_VALID 10 /* #frames to allow for changing fps */
52 #define EST_MAX_JITTER 0.01 /* maximum jitter to detect valid fps */
53 #define EST_MAX_DIFF 0.01 /* maximum diff to detect valid fps */
54 #define ABS(x) ((x)>0?(x):-(x))
55
56
57 /* Video window private structure */
58 struct xui_vwin_st {
59 gGui_t *gui;
60
61 xitk_widget_list_t *wl;
62
63 char window_title[1024];
64 int current_cursor; /* arrow or hand */
65 int cursor_visible;
66 int cursor_timer;
67 Visual *visual; /* Visual for video window */
68 Colormap colormap; /* Colormap for video window */
69 XClassHint *xclasshint;
70 XClassHint *xclasshint_fullscreen;
71 XClassHint *xclasshint_borderless;
72 GC gc;
73
74 int video_width; /* size of currently displayed video */
75 int video_height;
76
77 int frame_width; /* frame size, from xine-lib */
78 int frame_height;
79
80 double video_duration; /* frame duratrion in seconds */
81 double video_average; /* average frame duration in seconds */
82 double use_duration; /* duration used for tv mode selection */
83 int video_duration_valid; /* is use_duration trustable? */
84 int win_width; /* size of non-fullscreen window */
85 int win_height;
86 int old_win_width;
87 int old_win_height;
88 int output_width; /* output video window width/height */
89 int output_height;
90
91 int stream_resize_window; /* Boolean, 1 if new stream resize output window */
92 int zoom_small_stream; /* Boolean, 1 to double size small streams */
93
94 int fullscreen_mode; /* bitfield: */
95 int fullscreen_req; /* WINDOWED_MODE, FULLSCR_MODE or FULLSCR_XI_MODE */
96 int fullscreen_width;
97 int fullscreen_height;
98
99 int xinerama_fullscreen_x; /* will contain paramaters for very
100 fullscreen in xinerama mode */
101 int xinerama_fullscreen_y;
102 int xinerama_fullscreen_width;
103 int xinerama_fullscreen_height;
104
105 int visible_width; /* Size of currently visible portion of screen */
106 int visible_height; /* May differ from fullscreen_* e.g. for TV mode */
107 double visible_aspect; /* Pixel ratio of currently visible screen */
108
109 int using_xinerama;
110 #ifdef HAVE_XINERAMA
111 XineramaScreenInfo *xinerama; /* pointer to xinerama struct, or NULL */
112 int xinerama_cnt; /* number of screens in Xinerama */
113 #endif
114
115 int xwin; /* current X location */
116 int ywin; /* current Y location */
117 int old_xwin;
118 int old_ywin;
119
120 int desktopWidth; /* desktop width */
121 int desktopHeight; /* desktop height */
122 int depth;
123 int show;
124 int borderless; /* borderless window (for windowed mode)? */
125
126 Bool have_xtest;
127 #ifdef HAVE_XTESTEXTENSION
128 int fake_key_cur;
129 KeyCode fake_keys[2]; /* Fake key to send */
130 #endif
131
132 XWMHints *wm_hint;
133
134 xitk_register_key_t widget_key;
135 xitk_register_key_t old_widget_key;
136
137 #ifdef HAVE_XF86VIDMODE
138 /* XF86VidMode Extension stuff */
139 XF86VidModeModeInfo** XF86_modelines;
140 int XF86_modelines_count;
141 #endif
142
143 int hide_on_start; /* user use '-H' arg, don't map
144 video window the first time */
145
146 struct timeval click_time;
147
148 pthread_t second_display_thread;
149 int second_display_running;
150
151 int logo_synthetic;
152
153 pthread_mutex_t mutex;
154
155 };
156
157 /* safe external actions */
video_window_lock(xui_vwin_t * vwin,int lock_or_unlock)158 void video_window_lock (xui_vwin_t *vwin, int lock_or_unlock) {
159 if (!vwin)
160 return;
161 if (lock_or_unlock == 1)
162 pthread_mutex_lock (&vwin->mutex);
163 else if (lock_or_unlock == 0)
164 pthread_mutex_unlock (&vwin->mutex);
165 }
166
video_window_set_transient_for(xui_vwin_t * vwin,Window w)167 void video_window_set_transient_for (xui_vwin_t *vwin, Window w) {
168 if (!vwin)
169 return;
170 if (vwin->gui->use_root_window || (vwin->gui->video_display != vwin->gui->display))
171 return;
172 pthread_mutex_lock (&vwin->mutex);
173 vwin->gui->x_lock_display (vwin->gui->display);
174 XSetTransientForHint (vwin->gui->display, w, vwin->gui->video_window);
175 vwin->gui->x_unlock_display (vwin->gui->display);
176 pthread_mutex_unlock (&vwin->mutex);
177 }
178
179
180 static void video_window_handle_event (XEvent *event, void *data);
181 static void video_window_adapt_size (xui_vwin_t *vwin);
182 static int video_window_check_mag (xui_vwin_t *vwin);
183 static void video_window_calc_mag_win_size (xui_vwin_t *vwin, float xmag, float ymag);
184
_video_window_resize_cb(void * data,xine_cfg_entry_t * cfg)185 static void _video_window_resize_cb(void *data, xine_cfg_entry_t *cfg) {
186 xui_vwin_t *vwin = data;
187 vwin->stream_resize_window = cfg->num_value;
188 }
189
_video_window_zoom_small_cb(void * data,xine_cfg_entry_t * cfg)190 static void _video_window_zoom_small_cb(void *data, xine_cfg_entry_t *cfg) {
191 xui_vwin_t *vwin = data;
192 vwin->zoom_small_stream = cfg->num_value;
193 }
194
have_xtestextention(xui_vwin_t * vwin)195 static Bool have_xtestextention (xui_vwin_t *vwin) {
196 Bool xtestext = False;
197 #ifdef HAVE_XTESTEXTENSION
198 int dummy1 = 0, dummy2 = 0, dummy3 = 0, dummy4 = 0;
199
200 vwin->gui->x_lock_display (vwin->gui->video_display);
201 xtestext = XTestQueryExtension (vwin->gui->video_display, &dummy1, &dummy2, &dummy3, &dummy4);
202 vwin->gui->x_unlock_display (vwin->gui->video_display);
203 #else
204 (void)vwin;
205 #endif
206 return xtestext;
207 }
208
_set_window_title(xui_vwin_t * vwin)209 static void _set_window_title (xui_vwin_t *vwin) {
210 XmbSetWMProperties (vwin->gui->video_display, vwin->gui->video_window,
211 vwin->window_title, vwin->window_title, NULL, 0, NULL, NULL, NULL);
212 XSync (vwin->gui->video_display, False);
213 }
214
215 /*
216 * very small X event loop for the second display
217 */
second_display_loop(void * data)218 static __attribute__((noreturn)) void *second_display_loop (void *data) {
219 xui_vwin_t *vwin = data;
220
221 while (vwin->second_display_running) {
222 XEvent xevent;
223 int got_event;
224
225 xine_usec_sleep(20000);
226
227 do {
228 vwin->gui->x_lock_display (vwin->gui->video_display);
229 got_event = XPending (vwin->gui->video_display);
230 if( got_event )
231 XNextEvent (vwin->gui->video_display, &xevent);
232 vwin->gui->x_unlock_display (vwin->gui->video_display);
233
234 if (got_event && vwin->gui->stream) {
235 video_window_handle_event (&xevent, vwin);
236 }
237 } while (got_event);
238
239 }
240
241 pthread_exit(NULL);
242 }
243
244
video_window_find_visual(xui_vwin_t * vwin,Visual ** visual_return,int * depth_return)245 static void video_window_find_visual (xui_vwin_t *vwin, Visual **visual_return, int *depth_return) {
246 XWindowAttributes attribs;
247 XVisualInfo *vinfo;
248 XVisualInfo vinfo_tmpl;
249 int num_visuals;
250 int depth = 0;
251 Visual *visual = NULL;
252
253 if (vwin->gui->prefered_visual_id == None) {
254 /*
255 * List all available TrueColor visuals, pick the best one for xine.
256 * We prefer visuals of depth 15/16 (fast). Depth 24/32 may be OK,
257 * but could be slow.
258 */
259 vinfo_tmpl.screen = vwin->gui->video_screen;
260 vinfo_tmpl.class = (vwin->gui->prefered_visual_class != -1
261 ? vwin->gui->prefered_visual_class : TrueColor);
262 vinfo = XGetVisualInfo (vwin->gui->video_display,
263 VisualScreenMask | VisualClassMask,
264 &vinfo_tmpl, &num_visuals);
265 if (vinfo != NULL) {
266 int i, pref;
267 int best_visual_index = -1;
268 int best_visual = -1;
269
270 for (i = 0; i < num_visuals; i++) {
271 if (vinfo[i].depth == 15 || vinfo[i].depth == 16)
272 pref = 3;
273 else if (vinfo[i].depth > 16)
274 pref = 2;
275 else
276 pref = 1;
277
278 if (pref > best_visual) {
279 best_visual = pref;
280 best_visual_index = i;
281 }
282 }
283
284 if (best_visual_index != -1) {
285 depth = vinfo[best_visual_index].depth;
286 visual = vinfo[best_visual_index].visual;
287 }
288
289 XFree(vinfo);
290 }
291 } else {
292 /*
293 * Use the visual specified by the user.
294 */
295 vinfo_tmpl.visualid = vwin->gui->prefered_visual_id;
296 vinfo = XGetVisualInfo (vwin->gui->video_display,
297 VisualIDMask, &vinfo_tmpl,
298 &num_visuals);
299 if (vinfo == NULL) {
300 printf(_("gui_main: selected visual %#lx does not exist, trying default visual\n"),
301 (long) vwin->gui->prefered_visual_id);
302 } else {
303 depth = vinfo[0].depth;
304 visual = vinfo[0].visual;
305 XFree(vinfo);
306 }
307 }
308
309 if (depth == 0) {
310 XVisualInfo vinfo;
311
312 XGetWindowAttributes (vwin->gui->video_display, (DefaultRootWindow (vwin->gui->video_display)), &attribs);
313
314 depth = attribs.depth;
315
316 if (XMatchVisualInfo (vwin->gui->video_display, vwin->gui->video_screen, depth, TrueColor, &vinfo)) {
317 visual = vinfo.visual;
318 } else {
319 printf (_("gui_main: couldn't find true color visual.\n"));
320
321 depth = DefaultDepth (vwin->gui->video_display, vwin->gui->video_screen);
322 visual = DefaultVisual (vwin->gui->video_display, vwin->gui->video_screen);
323 }
324 }
325
326 if (depth_return != NULL)
327 *depth_return = depth;
328 if (visual_return != NULL)
329 *visual_return = visual;
330 }
331
332
333 /*
334 * Let the video driver override the selected visual
335 */
video_window_select_visual(xui_vwin_t * vwin)336 void video_window_select_visual (xui_vwin_t *vwin) {
337 XVisualInfo *vinfo = (XVisualInfo *) -1;
338
339 if (vwin->gui->vo_port && vwin->gui->video_display == vwin->gui->display) {
340
341 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_SELECT_VISUAL, &vinfo);
342
343 if (vinfo != (XVisualInfo *) -1) {
344 if (! vinfo) {
345 fprintf (stderr, _("videowin: output driver cannot select a working visual\n"));
346 exit (1);
347 }
348 vwin->gui->visual = vinfo->visual;
349 vwin->gui->depth = vinfo->depth;
350 }
351 if (vwin->gui->visual != vwin->visual) {
352 printf (_("videowin: output driver overrides selected visual to visual id 0x%lx\n"), vwin->gui->visual->visualid);
353 vwin->gui->x_lock_display (vwin->gui->display);
354 gui_init_imlib (vwin->gui, vwin->gui->visual);
355 vwin->gui->x_unlock_display (vwin->gui->display);
356 pthread_mutex_lock (&vwin->mutex);
357 video_window_adapt_size (vwin);
358 pthread_mutex_unlock (&vwin->mutex);
359 }
360 }
361 }
362
363 /*
364 * Lock the video window against WM-initiated transparency changes.
365 * At the time of writing (2006-06-29), only xfwm4 SVN understands this.
366 * Ref. http://bugzilla.xfce.org/show_bug.cgi?id=1958
367 */
video_window_lock_opacity(xui_vwin_t * vwin)368 static void video_window_lock_opacity (xui_vwin_t *vwin) {
369 Atom opacity_lock = XInternAtom (vwin->gui->video_display, "_NET_WM_WINDOW_OPACITY_LOCKED", False);
370
371 /* This shouldn't happen, but was reported in bug #1573056 */
372 if (opacity_lock == None)
373 return;
374
375 XChangeProperty (vwin->gui->video_display, vwin->gui->video_window,
376 opacity_lock,
377 XA_CARDINAL, 32, PropModeReplace,
378 (unsigned char *)vwin->gui, 1);
379 }
380
381 /*
382 * will modify/create video output window based on
383 *
384 * - fullscreen flags
385 * - win_width/win_height
386 *
387 * will set
388 * output_width/output_height
389 * visible_width/visible_height/visible_aspect
390 */
video_window_adapt_size(xui_vwin_t * vwin)391 static void video_window_adapt_size (xui_vwin_t *vwin) {
392 XSizeHints hint;
393 XWMHints *wm_hint;
394 XSetWindowAttributes attr;
395 Atom prop;
396 Atom wm_delete_window;
397 MWMHints mwmhints;
398 XGCValues xgcv;
399 Window old_video_window = None;
400 int border_width;
401
402 vwin->gui->x_lock_display (vwin->gui->video_display);
403
404 if (vwin->gui->use_root_window) { /* Using root window, but not really */
405
406 vwin->xwin = vwin->ywin = 0;
407 vwin->output_width = vwin->fullscreen_width;
408 vwin->output_height = vwin->fullscreen_height;
409 vwin->visible_width = vwin->fullscreen_width;
410 vwin->visible_height = vwin->fullscreen_height;
411 vwin->visible_aspect = vwin->gui->pixel_aspect = 1.0;
412
413 if (vwin->gui->video_window == None) {
414 XGCValues gcv;
415 Window wparent;
416 Window rootwindow = None;
417
418 vwin->fullscreen_mode = FULLSCR_MODE;
419 vwin->visual = vwin->gui->visual;
420 vwin->depth = vwin->gui->depth;
421 vwin->colormap = vwin->gui->colormap;
422
423 if (vwin->gui->video_display != vwin->gui->display) {
424 video_window_find_visual (vwin, &vwin->visual, &vwin->depth);
425 vwin->colormap = DefaultColormap (vwin->gui->video_display, vwin->gui->video_screen);
426 }
427
428 /* This couldn't happen, but we're paranoid ;-) */
429 if ((rootwindow = xitk_get_desktop_root_window (vwin->gui->video_display,
430 vwin->gui->video_screen, &wparent)) == None)
431 rootwindow = DefaultRootWindow (vwin->gui->video_display);
432
433 attr.override_redirect = True;
434 attr.background_pixel = vwin->gui->black.pixel;
435
436 border_width = 0;
437
438 if (vwin->gui->wid)
439 vwin->gui->video_window = vwin->gui->wid;
440 else
441 vwin->gui->video_window = XCreateWindow (vwin->gui->video_display, rootwindow,
442 0, 0, vwin->fullscreen_width, vwin->fullscreen_height, border_width,
443 CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWOverrideRedirect, &attr);
444
445 if (vwin->gui->video_display == vwin->gui->display)
446 xitk_widget_list_set (vwin->wl, WIDGET_LIST_WINDOW, (void *)vwin->gui->video_window);
447
448 if (vwin->gui->vo_port) {
449 vwin->gui->x_unlock_display (vwin->gui->video_display);
450 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void*)vwin->gui->video_window);
451 vwin->gui->x_lock_display (vwin->gui->video_display);
452 }
453
454 if (!(vwin->gui->no_mouse))
455 XSelectInput (vwin->gui->video_display, vwin->gui->video_window, ExposureMask);
456 else
457 XSelectInput (vwin->gui->video_display, vwin->gui->video_window,
458 ExposureMask & (~(ButtonPressMask | ButtonReleaseMask)));
459
460 _set_window_title (vwin);
461
462 gcv.foreground = vwin->gui->black.pixel;
463 gcv.background = vwin->gui->black.pixel;
464 gcv.graphics_exposures = False;
465 vwin->gc = XCreateGC (vwin->gui->video_display, vwin->gui->video_window,
466 GCForeground | GCBackground | GCGraphicsExposures, &gcv);
467
468 if (vwin->gui->video_display == vwin->gui->display)
469 xitk_widget_list_set (vwin->wl, WIDGET_LIST_GC, vwin->gc);
470
471 hint.flags = USSize | USPosition | PPosition | PSize;
472 hint.x = 0;
473 hint.y = 0;
474 hint.width = vwin->fullscreen_width;
475 hint.height = vwin->fullscreen_height;
476 XSetNormalHints (vwin->gui->video_display, vwin->gui->video_window, &hint);
477
478 video_window_lock_opacity (vwin);
479
480 XClearWindow (vwin->gui->video_display, vwin->gui->video_window);
481
482 XMapWindow (vwin->gui->video_display, vwin->gui->video_window);
483
484 XLowerWindow (vwin->gui->video_display, vwin->gui->video_window);
485
486 vwin->old_widget_key = vwin->widget_key;
487
488 vwin->gui->x_unlock_display (vwin->gui->video_display);
489
490 if (vwin->gui->video_display == vwin->gui->display)
491 vwin->widget_key = xitk_register_event_handler ("video_window",
492 vwin->gui->video_window, video_window_handle_event,
493 NULL, gui_dndcallback, NULL, vwin);
494
495 return;
496 }
497
498 vwin->gui->x_unlock_display (vwin->gui->video_display);
499
500 return;
501 }
502
503
504 #ifdef HAVE_XF86VIDMODE
505 /* XF86VidMode Extension
506 * In case a fullscreen request is received or if already in fullscreen, the
507 * appropriate modeline will be looked up and used.
508 */
509 if (((!(vwin->fullscreen_req & WINDOWED_MODE)) || (!(vwin->fullscreen_mode & WINDOWED_MODE)))
510 && (vwin->XF86_modelines_count > 1)) {
511 int search = 0;
512
513 /* skipping first entry because it is the current modeline */
514 for (search = 1; search < vwin->XF86_modelines_count; search++) {
515 if (vwin->XF86_modelines[search]->hdisplay >= vwin->video_width)
516 break;
517 }
518
519 /*
520 * in case we have a request for a resolution higher than any available
521 * ones we take the highest currently available.
522 */
523 if ((!(vwin->fullscreen_mode & WINDOWED_MODE)) && (search >= vwin->XF86_modelines_count))
524 search = 0;
525
526 /* just switching to a different modeline if necessary */
527 if (!(search >= vwin->XF86_modelines_count)) {
528 if (XF86VidModeSwitchToMode (vwin->gui->video_display, XDefaultScreen (vwin->gui->video_display),
529 vwin->XF86_modelines[search])) {
530 double res_h, res_v;
531 #ifdef HAVE_XINERAMA
532 int dummy_event, dummy_error;
533 #endif
534
535 vwin->gui->XF86VidMode_fullscreen = 1;
536 vwin->fullscreen_width = vwin->XF86_modelines[search]->hdisplay;
537 vwin->fullscreen_height = vwin->XF86_modelines[search]->vdisplay;
538
539 /* update pixel aspect */
540 res_h = (DisplayWidth (vwin->gui->video_display, vwin->gui->video_screen) * 1000
541 / DisplayWidthMM (vwin->gui->video_display, vwin->gui->video_screen));
542 res_v = (DisplayHeight (vwin->gui->video_display, vwin->gui->video_screen) * 1000
543 / DisplayHeightMM (vwin->gui->video_display, vwin->gui->video_screen));
544
545 vwin->gui->pixel_aspect = res_v / res_h;
546 #ifdef HAVE_XINERAMA
547 if (XineramaQueryExtension (vwin->gui->video_display, &dummy_event, &dummy_error)) {
548 int count = 1;
549 XineramaQueryScreens (vwin->gui->video_display, &count);
550 if (count > 1)
551 /* multihead -> assuming square pixels */
552 vwin->gui->pixel_aspect = 1.0;
553 }
554 #endif
555 #ifdef DEBUG
556 printf ("pixel_aspect: %f\n", vwin->gui->pixel_aspect);
557 #endif
558
559 // TODO
560 /*
561 * just in case the mouse pointer is off the visible area, move it
562 * to the middle of the video window
563 */
564 XWarpPointer (vwin->gui->video_display, None, vwin->gui->video_window,
565 0, 0, 0, 0, vwin->fullscreen_width / 2, vwin->fullscreen_height / 2);
566
567 XF86VidModeSetViewPort (vwin->gui->video_display, XDefaultScreen (vwin->gui->video_display), 0, 0);
568
569 /*
570 * if this is true, we are back at the original resolution, so there
571 * is no need to further worry about anything.
572 */
573 if ((!(vwin->fullscreen_mode & WINDOWED_MODE)) && (search == 0))
574 vwin->gui->XF86VidMode_fullscreen = 0;
575 } else {
576 xine_error(_("XF86VidMode Extension: modeline switching failed.\n"));
577 }
578 }
579 }
580 #endif/* HAVE_XF86VIDMODE */
581
582 #ifdef HAVE_XINERAMA
583 if (vwin->xinerama) {
584 int i;
585 int knowLocation = 0;
586 Window root_win, dummy_win;
587 int x_mouse,y_mouse;
588 int dummy_x,dummy_y;
589 unsigned int dummy_opts;
590
591 /* someday this could also use the centre of the window as the
592 * test point I guess. Right now it's the upper-left.
593 */
594 if (vwin->gui->video_window != None) {
595 if (vwin->xwin >= 0 && vwin->ywin >= 0 &&
596 vwin->xwin < vwin->desktopWidth && vwin->ywin < vwin->desktopHeight) {
597 knowLocation = 1;
598 }
599 }
600
601 if (vwin->fullscreen_req & FULLSCR_XI_MODE) {
602 hint.x = vwin->xinerama_fullscreen_x;
603 hint.y = vwin->xinerama_fullscreen_y;
604 hint.width = vwin->xinerama_fullscreen_width;
605 hint.height = vwin->xinerama_fullscreen_height;
606 vwin->fullscreen_width = hint.width;
607 vwin->fullscreen_height = hint.height;
608 }
609 else {
610 /* Get mouse cursor position */
611 XQueryPointer (vwin->gui->video_display, RootWindow (vwin->gui->video_display, vwin->gui->video_screen),
612 &root_win, &dummy_win, &x_mouse, &y_mouse, &dummy_x, &dummy_y, &dummy_opts);
613
614 for (i = 0; i < vwin->xinerama_cnt; i++) {
615 if (
616 (knowLocation == 1 &&
617 vwin->xwin >= vwin->xinerama[i].x_org &&
618 vwin->ywin >= vwin->xinerama[i].y_org &&
619 vwin->xwin < vwin->xinerama[i].x_org + vwin->xinerama[i].width &&
620 vwin->ywin < vwin->xinerama[i].y_org + vwin->xinerama[i].height) ||
621 (knowLocation == 0 &&
622 x_mouse >= vwin->xinerama[i].x_org &&
623 y_mouse >= vwin->xinerama[i].y_org &&
624 x_mouse < vwin->xinerama[i].x_org + vwin->xinerama[i].width &&
625 y_mouse < vwin->xinerama[i].y_org + vwin->xinerama[i].height)) {
626 /* vwin->xinerama[i].screen_number ==
627 XScreenNumberOfScreen (XDefaultScreenOfDisplay (vwin->gui->video_display)))) {*/
628 hint.x = vwin->xinerama[i].x_org;
629 hint.y = vwin->xinerama[i].y_org;
630
631 if(knowLocation == 0) {
632 vwin->old_xwin = hint.x;
633 vwin->old_ywin = hint.y;
634 }
635
636 if (!(vwin->fullscreen_req & WINDOWED_MODE)) {
637 hint.width = vwin->xinerama[i].width;
638 hint.height = vwin->xinerama[i].height;
639 vwin->fullscreen_width = hint.width;
640 vwin->fullscreen_height = hint.height;
641 }
642 else {
643 hint.width = vwin->video_width;
644 hint.height = vwin->video_height;
645 }
646 break;
647 }
648 }
649 }
650 }
651 else {
652 hint.x = 0;
653 hint.y = 0;
654 if (!(vwin->fullscreen_req & WINDOWED_MODE)) {
655 hint.width = vwin->fullscreen_width;
656 hint.height = vwin->fullscreen_height;
657 } else {
658 hint.width = vwin->win_width;
659 hint.height = vwin->win_height;
660 }
661 }
662 #else /* HAVE_XINERAMA */
663 hint.x = 0;
664 hint.y = 0; /* for now -- could change later */
665 #endif /* HAVE_XINERAMA */
666
667 vwin->visible_width = vwin->fullscreen_width;
668 vwin->visible_height = vwin->fullscreen_height;
669 vwin->visible_aspect = vwin->gui->pixel_aspect;
670
671 /* Retrieve size/aspect from tvout backend, if it should be set */
672 if (vwin->gui->tvout) {
673 tvout_get_size_and_aspect (vwin->gui->tvout,
674 &vwin->visible_width, &vwin->visible_height, &vwin->visible_aspect);
675 tvout_get_size_and_aspect (vwin->gui->tvout,
676 &hint.width, &hint.height, NULL);
677 tvout_set_fullscreen_mode (vwin->gui->tvout,
678 !(vwin->fullscreen_req & WINDOWED_MODE) ? 1 : 0, vwin->visible_width, vwin->visible_height);
679 }
680
681 #ifdef HAVE_XINERAMA
682 /* ask for xinerama fullscreen mode */
683 if (vwin->xinerama && (vwin->fullscreen_req & FULLSCR_XI_MODE)) {
684
685 if (vwin->gui->video_window) {
686 int dummy;
687
688 if ((vwin->fullscreen_mode & FULLSCR_XI_MODE) && vwin->gui->visual == vwin->visual) {
689 if (vwin->visible_width != vwin->output_width || vwin->visible_height != vwin->output_height) {
690 /*
691 * resizing the video window may be necessary if the modeline or tv mode has
692 * just been switched
693 */
694 XMoveResizeWindow (vwin->gui->video_display, vwin->gui->video_window, hint.x, hint.y,
695 vwin->visible_width, vwin->visible_height);
696 vwin->output_width = vwin->visible_width;
697 vwin->output_height = vwin->visible_height;
698 }
699 vwin->fullscreen_mode = vwin->fullscreen_req;
700 vwin->gui->x_unlock_display (vwin->gui->video_display);
701
702 return;
703 }
704
705 xitk_get_window_position (vwin->gui->video_display, vwin->gui->video_window,
706 &vwin->old_xwin, &vwin->old_ywin, &dummy, &dummy);
707
708 if (vwin->gui->video_display == vwin->gui->display)
709 xitk_unregister_event_handler (&vwin->old_widget_key);
710 old_video_window = vwin->gui->video_window;
711 }
712
713 vwin->fullscreen_mode = vwin->fullscreen_req;
714 vwin->visual = vwin->gui->visual;
715 vwin->depth = vwin->gui->depth;
716 vwin->colormap = vwin->gui->colormap;
717 if (vwin->gui->video_display != vwin->gui->display) {
718 video_window_find_visual (vwin, &vwin->visual, &vwin->depth);
719 vwin->colormap = DefaultColormap (vwin->gui->video_display, vwin->gui->video_screen);
720 }
721 /*
722 * open fullscreen window
723 */
724
725 attr.background_pixel = vwin->gui->black.pixel;
726 attr.border_pixel = vwin->gui->black.pixel;
727 attr.colormap = vwin->colormap;
728
729 border_width = 0;
730 if(vwin->gui->wid)
731 vwin->gui->video_window = vwin->gui->wid;
732 else
733 vwin->gui->video_window = XCreateWindow (vwin->gui->video_display,
734 DefaultRootWindow (vwin->gui->video_display),
735 hint.x, hint.y, vwin->visible_width, vwin->visible_height,
736 border_width, vwin->depth, InputOutput, vwin->visual, CWBackPixel | CWBorderPixel | CWColormap, &attr);
737
738 if (vwin->gui->video_display == vwin->gui->display)
739 xitk_widget_list_set (vwin->wl, WIDGET_LIST_WINDOW, (void *)vwin->gui->video_window);
740
741 if (vwin->gui->vo_port) {
742 vwin->gui->x_unlock_display (vwin->gui->video_display);
743 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void*)vwin->gui->video_window);
744 vwin->gui->x_lock_display (vwin->gui->video_display);
745 }
746
747 if (vwin->xclasshint_fullscreen != NULL)
748 XSetClassHint (vwin->gui->video_display, vwin->gui->video_window, vwin->xclasshint_fullscreen);
749
750 hint.win_gravity = StaticGravity;
751 hint.flags = PPosition | PSize | PWinGravity;
752
753 _set_window_title (vwin);
754
755 XSetWMNormalHints (vwin->gui->video_display, vwin->gui->video_window, &hint);
756
757 XSetWMHints (vwin->gui->video_display, vwin->gui->video_window, vwin->wm_hint);
758
759 video_window_lock_opacity (vwin);
760
761 vwin->output_width = hint.width;
762 vwin->output_height = hint.height;
763
764 /*
765 * wm, no borders please
766 */
767 memset(&mwmhints, 0, sizeof(mwmhints));
768 prop = XInternAtom (vwin->gui->video_display, "_MOTIF_WM_HINTS", False);
769 mwmhints.flags = MWM_HINTS_DECORATIONS;
770 mwmhints.decorations = 0;
771 XChangeProperty (vwin->gui->video_display, vwin->gui->video_window, prop, prop, 32,
772 PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS);
773
774 } else
775 #endif /* HAVE_XINERAMA */
776 if (!(vwin->fullscreen_req & WINDOWED_MODE)) {
777
778 if (vwin->gui->video_window) {
779 int dummy;
780
781 if ((!(vwin->fullscreen_mode & WINDOWED_MODE)) && (vwin->gui->visual == vwin->visual)) {
782 //#ifdef HAVE_XF86VIDMODE
783 // if(vwin->XF86_modelines_count > 1) {
784 if ((vwin->visible_width != vwin->output_width) || (vwin->visible_height != vwin->output_height)) {
785 /*
786 * resizing the video window may be necessary if the modeline or tv mode has
787 * just been switched
788 */
789 XResizeWindow (vwin->gui->video_display, vwin->gui->video_window,
790 vwin->visible_width, vwin->visible_height);
791 vwin->output_width = vwin->visible_width;
792 vwin->output_height = vwin->visible_height;
793 }
794 //#endif
795 vwin->fullscreen_mode = vwin->fullscreen_req;
796 vwin->gui->x_unlock_display (vwin->gui->video_display);
797
798 return;
799 }
800
801 xitk_get_window_position (vwin->gui->video_display, vwin->gui->video_window,
802 &vwin->old_xwin, &vwin->old_ywin, &dummy, &dummy);
803
804 if (vwin->gui->video_display == vwin->gui->display)
805 xitk_unregister_event_handler(&vwin->old_widget_key);
806 old_video_window = vwin->gui->video_window;
807 }
808
809 vwin->fullscreen_mode = vwin->fullscreen_req;
810 vwin->visual = vwin->gui->visual;
811 vwin->depth = vwin->gui->depth;
812 vwin->colormap = vwin->gui->colormap;
813
814 if (vwin->gui->video_display != vwin->gui->display) {
815 video_window_find_visual (vwin, &vwin->visual, &vwin->depth);
816 vwin->colormap = DefaultColormap (vwin->gui->video_display, vwin->gui->video_screen);
817 }
818
819 /*
820 * open fullscreen window
821 */
822
823 attr.background_pixel = vwin->gui->black.pixel;
824 attr.border_pixel = vwin->gui->black.pixel;
825 attr.colormap = vwin->colormap;
826
827 border_width = 0;
828
829 if (vwin->gui->wid)
830 vwin->gui->video_window = vwin->gui->wid;
831 else
832 vwin->gui->video_window = XCreateWindow (vwin->gui->video_display,
833 DefaultRootWindow(vwin->gui->video_display),
834 hint.x, hint.y, vwin->visible_width, vwin->visible_height,
835 border_width, vwin->depth, InputOutput, vwin->visual,
836 CWBackPixel | CWBorderPixel | CWColormap, &attr);
837
838 if (vwin->gui->video_display == vwin->gui->display)
839 xitk_widget_list_set (vwin->wl, WIDGET_LIST_WINDOW, (void *) vwin->gui->video_window);
840
841 if (vwin->gui->vo_port) {
842 vwin->gui->x_unlock_display (vwin->gui->video_display);
843 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void*)vwin->gui->video_window);
844 vwin->gui->x_lock_display (vwin->gui->video_display);
845 }
846
847 if (vwin->xclasshint_fullscreen != NULL)
848 XSetClassHint (vwin->gui->video_display, vwin->gui->video_window, vwin->xclasshint_fullscreen);
849
850 #ifndef HAVE_XINERAMA
851 hint.x = 0;
852 hint.y = 0;
853 hint.width = vwin->visible_width;
854 hint.height = vwin->visible_height;
855 #endif
856 hint.win_gravity = StaticGravity;
857 hint.flags = PPosition | PSize | PWinGravity;
858
859 _set_window_title (vwin);
860
861 XSetWMNormalHints (vwin->gui->video_display, vwin->gui->video_window, &hint);
862
863 XSetWMHints (vwin->gui->video_display, vwin->gui->video_window, vwin->wm_hint);
864
865 video_window_lock_opacity (vwin);
866
867 vwin->output_width = hint.width;
868 vwin->output_height = hint.height;
869
870 /*
871 * wm, no borders please
872 */
873 memset(&mwmhints, 0, sizeof(mwmhints));
874 prop = XInternAtom (vwin->gui->video_display, "_MOTIF_WM_HINTS", False);
875 mwmhints.flags = MWM_HINTS_DECORATIONS;
876 mwmhints.decorations = 0;
877 XChangeProperty (vwin->gui->video_display, vwin->gui->video_window, prop, prop, 32,
878 PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS);
879
880 }
881 else {
882
883 #ifndef HAVE_XINERAMA
884 hint.x = 0;
885 hint.y = 0;
886 hint.width = vwin->win_width;
887 hint.height = vwin->win_height;
888 #endif
889 hint.flags = PPosition | PSize;
890
891 /*
892 * user sets window geom, move back to original location.
893 */
894 if (vwin->stream_resize_window == 0) {
895 hint.x = vwin->old_xwin;
896 hint.y = vwin->old_ywin;
897 }
898
899 vwin->old_win_width = hint.width;
900 vwin->old_win_height = hint.height;
901
902 vwin->output_width = hint.width;
903 vwin->output_height = hint.height;
904
905 if (vwin->gui->video_window) {
906
907 if ((!(vwin->fullscreen_mode & WINDOWED_MODE)) || (vwin->visual != vwin->gui->visual)) {
908 #ifdef HAVE_XF86VIDMODE
909 /*
910 * toggling from fullscreen to window mode - time to switch back to
911 * the original modeline
912 */
913 if (vwin->XF86_modelines_count > 1) {
914 double res_h, res_v;
915 #ifdef HAVE_XINERAMA
916 int dummy_event, dummy_error;
917 #endif
918
919 XF86VidModeSwitchToMode (vwin->gui->video_display, XDefaultScreen (vwin->gui->video_display), vwin->XF86_modelines[0]);
920 XF86VidModeSetViewPort (vwin->gui->video_display, XDefaultScreen (vwin->gui->video_display), 0, 0);
921
922 vwin->gui->XF86VidMode_fullscreen = 0;
923
924 vwin->fullscreen_width = vwin->XF86_modelines[0]->hdisplay;
925 vwin->fullscreen_height = vwin->XF86_modelines[0]->vdisplay;
926
927 /* update pixel aspect */
928 res_h = (DisplayWidth (vwin->gui->video_display, vwin->gui->video_screen) * 1000
929 / DisplayWidthMM (vwin->gui->video_display, vwin->gui->video_screen));
930 res_v = (DisplayHeight (vwin->gui->video_display, vwin->gui->video_screen) * 1000
931 / DisplayHeightMM (vwin->gui->video_display, vwin->gui->video_screen));
932
933 vwin->gui->pixel_aspect = res_v / res_h;
934 #ifdef HAVE_XINERAMA
935 if (XineramaQueryExtension (vwin->gui->video_display, &dummy_event, &dummy_error)) {
936 int count = 1;
937 XineramaQueryScreens (vwin->gui->video_display, &count);
938 if (count > 1)
939 /* multihead -> assuming square pixels */
940 vwin->gui->pixel_aspect = 1.0;
941 }
942 #endif
943 #ifdef DEBUG
944 printf ("pixel_aspect: %f\n", vwin->gui->pixel_aspect);
945 #endif
946 }
947 #endif
948
949 if (vwin->gui->video_display == vwin->gui->display)
950 xitk_unregister_event_handler (&vwin->old_widget_key);
951 old_video_window = vwin->gui->video_window;
952 }
953 else {
954
955 /* Update window size hints with the new size */
956 XSetNormalHints (vwin->gui->video_display, vwin->gui->video_window, &hint);
957
958 XResizeWindow (vwin->gui->video_display, vwin->gui->video_window,
959 vwin->win_width, vwin->win_height);
960
961 vwin->gui->x_unlock_display (vwin->gui->video_display);
962
963 return;
964 }
965 }
966
967 vwin->fullscreen_mode = WINDOWED_MODE;
968 vwin->visual = vwin->gui->visual;
969 vwin->depth = vwin->gui->depth;
970 vwin->colormap = vwin->gui->colormap;
971
972 if (vwin->gui->video_display != vwin->gui->display) {
973 video_window_find_visual (vwin, &vwin->visual, &vwin->depth);
974 vwin->colormap = DefaultColormap (vwin->gui->video_display, vwin->gui->video_screen);
975 }
976 attr.background_pixel = vwin->gui->black.pixel;
977 attr.border_pixel = vwin->gui->black.pixel;
978 attr.colormap = vwin->colormap;
979
980 if (vwin->borderless)
981 border_width = 0;
982 else
983 border_width = 4;
984
985 if (vwin->gui->wid)
986 vwin->gui->video_window = vwin->gui->wid;
987 else
988 vwin->gui->video_window = XCreateWindow (vwin->gui->video_display,
989 DefaultRootWindow (vwin->gui->video_display),
990 hint.x, hint.y, hint.width, hint.height, border_width,
991 vwin->depth, InputOutput, vwin->visual, CWBackPixel | CWBorderPixel | CWColormap, &attr);
992
993 if (vwin->gui->video_display == vwin->gui->display)
994 xitk_widget_list_set (vwin->wl, WIDGET_LIST_WINDOW, (void *) vwin->gui->video_window);
995
996 if (vwin->gui->vo_port) {
997 vwin->gui->x_unlock_display (vwin->gui->video_display);
998 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void*)vwin->gui->video_window);
999 vwin->gui->x_lock_display (vwin->gui->video_display);
1000 }
1001
1002 if (vwin->borderless) {
1003 if (vwin->xclasshint_borderless != NULL)
1004 XSetClassHint (vwin->gui->video_display, vwin->gui->video_window, vwin->xclasshint_borderless);
1005 }
1006 else {
1007
1008 if (vwin->xclasshint != NULL)
1009 XSetClassHint (vwin->gui->video_display, vwin->gui->video_window, vwin->xclasshint);
1010 }
1011
1012 _set_window_title (vwin);
1013
1014 XSetWMNormalHints (vwin->gui->video_display, vwin->gui->video_window, &hint);
1015
1016 XSetWMHints (vwin->gui->video_display, vwin->gui->video_window, vwin->wm_hint);
1017
1018 video_window_lock_opacity (vwin);
1019
1020 if (vwin->borderless) {
1021 memset(&mwmhints, 0, sizeof(mwmhints));
1022 prop = XInternAtom (vwin->gui->video_display, "_MOTIF_WM_HINTS", False);
1023 mwmhints.flags = MWM_HINTS_DECORATIONS;
1024 mwmhints.decorations = 0;
1025 XChangeProperty (vwin->gui->video_display, vwin->gui->video_window, prop, prop, 32,
1026 PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS);
1027 }
1028 }
1029
1030 if (!(vwin->gui->no_mouse))
1031 XSelectInput (vwin->gui->video_display, vwin->gui->video_window, INPUT_MOTION | KeymapStateMask);
1032 else
1033 XSelectInput (vwin->gui->video_display, vwin->gui->video_window,
1034 (INPUT_MOTION | KeymapStateMask) & (~(ButtonPressMask | ButtonReleaseMask)));
1035
1036 wm_hint = XAllocWMHints();
1037 if (wm_hint != NULL) {
1038 wm_hint->input = True;
1039 wm_hint->initial_state = NormalState;
1040 wm_hint->icon_pixmap = vwin->gui->icon;
1041 wm_hint->flags = InputHint | StateHint | IconPixmapHint;
1042 XSetWMHints (vwin->gui->video_display, vwin->gui->video_window, wm_hint);
1043 XFree(wm_hint);
1044 }
1045
1046 wm_delete_window = XInternAtom (vwin->gui->video_display, "WM_DELETE_WINDOW", False);
1047 XSetWMProtocols (vwin->gui->video_display, vwin->gui->video_window, &wm_delete_window, 1);
1048
1049 if (vwin->hide_on_start == 1) {
1050 vwin->hide_on_start = -1;
1051 vwin->show = 0;
1052 }
1053 else {
1054 /* Map window. */
1055
1056 if ((vwin->gui->always_layer_above ||
1057 ((!(vwin->fullscreen_mode & WINDOWED_MODE)) && is_layer_above())) && !wm_not_ewmh_only()) {
1058 xitk_set_layer_above (vwin->gui->video_window);
1059 }
1060
1061 XRaiseWindow (vwin->gui->video_display, vwin->gui->video_window);
1062 XMapWindow (vwin->gui->video_display, vwin->gui->video_window);
1063
1064 while (!xitk_is_window_visible (vwin->gui->video_display, vwin->gui->video_window))
1065 xine_usec_sleep(5000);
1066
1067 if ((vwin->gui->always_layer_above ||
1068 ((!(vwin->fullscreen_mode & WINDOWED_MODE)) && is_layer_above())) && wm_not_ewmh_only()) {
1069 xitk_set_layer_above (vwin->gui->video_window);
1070 }
1071
1072 /* inform the window manager that we are fullscreen. This info musn't be set for xinerama-fullscreen,
1073 otherwise there are 2 different window size for one fullscreen mode ! (kwin doesn't accept this) */
1074 if (!(vwin->fullscreen_mode & WINDOWED_MODE)
1075 && !(vwin->fullscreen_mode & FULLSCR_XI_MODE)
1076 && wm_not_ewmh_only())
1077 xitk_set_ewmh_fullscreen (vwin->gui->video_window);
1078
1079 }
1080
1081 XSync (vwin->gui->video_display, False);
1082
1083 if (vwin->gc != None)
1084 XFreeGC (vwin->gui->video_display, vwin->gc);
1085
1086 vwin->gc = XCreateGC (vwin->gui->video_display, vwin->gui->video_window, 0L, &xgcv);
1087 if (vwin->gui->video_display == vwin->gui->display)
1088 xitk_widget_list_set (vwin->wl, WIDGET_LIST_GC, vwin->gc);
1089
1090 if ((!(vwin->fullscreen_mode & WINDOWED_MODE))) {
1091 /* Waiting for visibility, avoid X error on some cases */
1092
1093 try_to_set_input_focus (vwin->gui->video_window);
1094
1095 #ifdef HAVE_XINERAMA
1096 if (vwin->xinerama)
1097 XMoveWindow (vwin->gui->video_display, vwin->gui->video_window, hint.x, hint.y);
1098 else
1099 XMoveWindow (vwin->gui->video_display, vwin->gui->video_window, 0, 0);
1100 #else
1101 XMoveWindow (vwin->gui->video_display, vwin->gui->video_window, 0, 0);
1102 #endif
1103 }
1104
1105 /* Update WM_TRANSIENT_FOR hints on other windows for the new video_window */
1106 if ((vwin->gui->panel_window != None) && (!vwin->gui->use_root_window))
1107 XSetTransientForHint (vwin->gui->video_display, vwin->gui->panel_window,vwin->gui->video_window);
1108
1109 /* The old window should be destroyed now */
1110 if(old_video_window != None) {
1111 XDestroyWindow (vwin->gui->video_display, old_video_window);
1112
1113 if (vwin->gui->cursor_grabbed)
1114 XGrabPointer (vwin->gui->video_display, vwin->gui->video_window, 1,
1115 None, GrabModeAsync, GrabModeAsync, vwin->gui->video_window, None, CurrentTime);
1116 }
1117
1118 vwin->gui->x_unlock_display (vwin->gui->video_display);
1119
1120 vwin->old_widget_key = vwin->widget_key;
1121
1122 if (vwin->gui->video_display == vwin->gui->display)
1123 vwin->widget_key = xitk_register_event_handler ("video_window",
1124 vwin->gui->video_window, video_window_handle_event, NULL, gui_dndcallback,
1125 NULL, vwin);
1126
1127 /* take care about window decoration/pos */
1128 {
1129 Window tmp_win;
1130
1131 vwin->gui->x_lock_display (vwin->gui->video_display);
1132 XTranslateCoordinates (vwin->gui->video_display, vwin->gui->video_window,
1133 DefaultRootWindow (vwin->gui->video_display), 0, 0, &vwin->xwin, &vwin->ywin, &tmp_win);
1134 vwin->gui->x_unlock_display (vwin->gui->video_display);
1135 }
1136
1137 oxine_adapt();
1138 }
1139
get_default_mag(xui_vwin_t * vwin,int video_width,int video_height,float * xmag,float * ymag)1140 static void get_default_mag (xui_vwin_t *vwin, int video_width, int video_height, float *xmag, float *ymag) {
1141 if (vwin->zoom_small_stream && video_width < 300 && video_height < 300)
1142 *xmag = *ymag = 2.0f;
1143 else
1144 *xmag = *ymag = 1.0f;
1145 }
1146
1147 /*
1148 *
1149 */
video_window_dest_size_cb(void * data,int video_width,int video_height,double video_pixel_aspect,int * dest_width,int * dest_height,double * dest_pixel_aspect)1150 void video_window_dest_size_cb (void *data,
1151 int video_width, int video_height,
1152 double video_pixel_aspect,
1153 int *dest_width, int *dest_height,
1154 double *dest_pixel_aspect) {
1155 xui_vwin_t *vwin = data;
1156
1157 if (!vwin)
1158 return;
1159 pthread_mutex_lock (&vwin->mutex);
1160
1161 vwin->frame_width = video_width;
1162 vwin->frame_height = video_height;
1163
1164 /* correct size with video_pixel_aspect */
1165 if (video_pixel_aspect >= vwin->gui->pixel_aspect)
1166 video_width = video_width * video_pixel_aspect / vwin->gui->pixel_aspect + .5;
1167 else
1168 video_height = video_height * vwin->gui->pixel_aspect / video_pixel_aspect + .5;
1169
1170 if (vwin->stream_resize_window && (vwin->fullscreen_mode & WINDOWED_MODE)) {
1171
1172 if (vwin->video_width != video_width || vwin->video_height != video_height) {
1173
1174 if ((video_width > 0) && (video_height > 0)) {
1175 float xmag, ymag;
1176
1177 get_default_mag (vwin, video_width, video_height, &xmag, &ymag);
1178
1179 /* FIXME: this is supposed to give the same results as if a
1180 * video_window_set_mag(xmag, ymag) was called. Since video_window_adapt_size()
1181 * check several other details (like border, xinerama, etc) this
1182 * may produce wrong values in some cases. (?)
1183 */
1184 *dest_width = (int) ((float) video_width * xmag + 0.5f);
1185 *dest_height = (int) ((float) video_height * ymag + 0.5f);
1186 *dest_pixel_aspect = vwin->gui->pixel_aspect;
1187 pthread_mutex_unlock (&vwin->mutex);
1188 return;
1189 }
1190 }
1191 }
1192
1193 if (!(vwin->fullscreen_mode & WINDOWED_MODE)) {
1194 *dest_width = vwin->visible_width;
1195 *dest_height = vwin->visible_height;
1196 *dest_pixel_aspect = vwin->visible_aspect;
1197 } else {
1198 *dest_width = vwin->output_width;
1199 *dest_height = vwin->output_height;
1200 *dest_pixel_aspect = vwin->gui->pixel_aspect;
1201 }
1202
1203 pthread_mutex_unlock (&vwin->mutex);
1204 }
1205
1206 /*
1207 *
1208 */
video_window_frame_output_cb(void * data,int video_width,int video_height,double video_pixel_aspect,int * dest_x,int * dest_y,int * dest_width,int * dest_height,double * dest_pixel_aspect,int * win_x,int * win_y)1209 void video_window_frame_output_cb (void *data,
1210 int video_width, int video_height,
1211 double video_pixel_aspect,
1212 int *dest_x, int *dest_y,
1213 int *dest_width, int *dest_height,
1214 double *dest_pixel_aspect,
1215 int *win_x, int *win_y) {
1216 xui_vwin_t *vwin = data;
1217
1218 if (!vwin)
1219 return;
1220 pthread_mutex_lock (&vwin->mutex);
1221
1222 vwin->frame_width = video_width;
1223 vwin->frame_height = video_height;
1224
1225 /* correct size with video_pixel_aspect */
1226 if (video_pixel_aspect >= vwin->gui->pixel_aspect)
1227 video_width = video_width * video_pixel_aspect / vwin->gui->pixel_aspect + .5;
1228 else
1229 video_height = video_height * vwin->gui->pixel_aspect / video_pixel_aspect + .5;
1230
1231 /* Please do NOT remove, support will be added soon! */
1232 #if 0
1233 double jitter;
1234 vwin->video_duration = video_duration;
1235 vwin->video_average = 0.5 * vwin->video_average + 0.5 video_duration;
1236 jitter = ABS (video_duration - vwin->video_average) / vwin->video_average;
1237 if (jitter > EST_MAX_JITTER) {
1238 if (vwin->duration_valid > -EST_KEEP_VALID)
1239 vwin->duration_valid--;
1240 } else {
1241 if (vwin->duration_valid < EST_KEEP_VALID)
1242 vwin->duration_valid++;
1243 if (ABS (video_duration - vwin->use_duration) / video_duration > EST_MAX_DIFF)
1244 vwin->use_duration = video_duration;
1245 }
1246 #endif
1247
1248 if (vwin->video_width != video_width || vwin->video_height != video_height) {
1249
1250 vwin->video_width = video_width;
1251 vwin->video_height = video_height;
1252
1253 if (vwin->stream_resize_window && video_width > 0 && video_height > 0) {
1254 float xmag, ymag;
1255
1256 /* Prepare window size */
1257 get_default_mag (vwin, video_width, video_height, &xmag, &ymag);
1258 video_window_calc_mag_win_size (vwin, xmag, ymag);
1259 /* If actually ready to adapt window size, do it now */
1260 if (video_window_check_mag (vwin))
1261 video_window_adapt_size (vwin);
1262 }
1263
1264 oxine_adapt();
1265 }
1266
1267 *dest_x = 0;
1268 *dest_y = 0;
1269
1270 if (!(vwin->fullscreen_mode & WINDOWED_MODE)) {
1271 *dest_width = vwin->visible_width;
1272 *dest_height = vwin->visible_height;
1273 *dest_pixel_aspect = vwin->visible_aspect;
1274 /* TODO: check video size/fps/ar if tv mode and call video_window_adapt_size if necessary */
1275 } else {
1276 *dest_width = vwin->output_width;
1277 *dest_height = vwin->output_height;
1278 *dest_pixel_aspect = vwin->gui->pixel_aspect;
1279 }
1280
1281 *win_x = (vwin->xwin < 0) ? 0 : vwin->xwin;
1282 *win_y = (vwin->ywin < 0) ? 0 : vwin->ywin;
1283
1284 pthread_mutex_unlock (&vwin->mutex);
1285 }
1286
1287 /*
1288 *
1289 */
video_window_set_fullscreen_mode(xui_vwin_t * vwin,int req_fullscreen)1290 void video_window_set_fullscreen_mode (xui_vwin_t *vwin, int req_fullscreen) {
1291
1292 if (!vwin)
1293 return;
1294 pthread_mutex_lock (&vwin->mutex);
1295
1296 if (!(vwin->fullscreen_mode & req_fullscreen)) {
1297
1298 #ifdef HAVE_XINERAMA
1299 if ((req_fullscreen & FULLSCR_XI_MODE) && (!vwin->xinerama)) {
1300 if (vwin->fullscreen_mode & FULLSCR_MODE)
1301 vwin->fullscreen_req = WINDOWED_MODE;
1302 else
1303 vwin->fullscreen_req = FULLSCR_MODE;
1304 }
1305 else
1306 #endif
1307 vwin->fullscreen_req = req_fullscreen;
1308
1309 }
1310 else {
1311
1312 if ((req_fullscreen & FULLSCR_MODE) && (vwin->fullscreen_mode & FULLSCR_MODE))
1313 vwin->fullscreen_req = WINDOWED_MODE;
1314 #ifdef HAVE_XINERAMA
1315 else if ((req_fullscreen & FULLSCR_XI_MODE) && (vwin->fullscreen_mode & FULLSCR_XI_MODE))
1316 vwin->fullscreen_req = WINDOWED_MODE;
1317 #endif
1318
1319 }
1320
1321 video_window_adapt_size (vwin);
1322
1323 try_to_set_input_focus (vwin->gui->video_window);
1324 osd_update_osd();
1325
1326 pthread_mutex_unlock (&vwin->mutex);
1327 }
1328
1329 /*
1330 *
1331 */
video_window_get_fullscreen_mode(xui_vwin_t * vwin)1332 int video_window_get_fullscreen_mode (xui_vwin_t *vwin) {
1333 return vwin ? vwin->fullscreen_mode : 0;
1334 }
1335
1336 #if 0
1337 /*
1338 * set/reset xine in xinerama fullscreen
1339 * ie: try to expend display on further screens
1340 */
1341 void video_window_set_xinerama_fullscreen_mode (xui_vwin_t *vwin, int req_fullscreen) {
1342
1343 pthread_mutex_lock (&vwin->mutex);
1344 vwin->fullscreen_req = req_fullscreen;
1345 video_window_adapt_size (vwin);
1346 pthread_mutex_unlock (&vwin->mutex);
1347 }
1348
1349 /*
1350 *
1351 */
1352 int video_window_get_xinerama_fullscreen_mode (xui_vwin_t *vwin) {
1353 return vwin->fullscreen_mode;
1354 }
1355 #endif
1356
1357 /*
1358 * Set cursor
1359 */
video_window_set_cursor(xui_vwin_t * vwin,int cursor)1360 void video_window_set_cursor (xui_vwin_t *vwin, int cursor) {
1361
1362 if (vwin && cursor) {
1363 vwin->current_cursor = cursor;
1364
1365 if (vwin->cursor_visible) {
1366 vwin->cursor_timer = 0;
1367 switch (vwin->current_cursor) {
1368 case 0:
1369 xitk_cursors_define_window_cursor (vwin->gui->video_display, vwin->gui->video_window, xitk_cursor_invisible);
1370 break;
1371 case CURSOR_ARROW:
1372 xitk_cursors_restore_window_cursor (vwin->gui->video_display, vwin->gui->video_window);
1373 break;
1374 case CURSOR_HAND:
1375 xitk_cursors_define_window_cursor (vwin->gui->video_display, vwin->gui->video_window, xitk_cursor_hand2);
1376 break;
1377 }
1378 }
1379 }
1380
1381 }
1382
1383 /*
1384 * hide/show cursor in video window
1385 */
video_window_set_cursor_visibility(xui_vwin_t * vwin,int show_cursor)1386 void video_window_set_cursor_visibility (xui_vwin_t *vwin, int show_cursor) {
1387
1388 if (!vwin)
1389 return;
1390 if (vwin->gui->use_root_window)
1391 return;
1392
1393 vwin->cursor_visible = show_cursor;
1394
1395 if (show_cursor)
1396 vwin->cursor_timer = 0;
1397
1398 if (show_cursor) {
1399 if (vwin->current_cursor == CURSOR_ARROW)
1400 xitk_cursors_restore_window_cursor (vwin->gui->video_display, vwin->gui->video_window);
1401 else
1402 xitk_cursors_define_window_cursor (vwin->gui->video_display, vwin->gui->video_window, xitk_cursor_hand1);
1403 }
1404 else
1405 xitk_cursors_define_window_cursor (vwin->gui->video_display, vwin->gui->video_window, xitk_cursor_invisible);
1406
1407 }
1408
1409 /*
1410 * Get cursor visiblity (boolean)
1411 */
video_window_is_cursor_visible(xui_vwin_t * vwin)1412 int video_window_is_cursor_visible (xui_vwin_t *vwin) {
1413 return vwin ? vwin->cursor_visible : 0;
1414 }
1415
video_window_get_cursor_timer(xui_vwin_t * vwin)1416 int video_window_get_cursor_timer (xui_vwin_t *vwin) {
1417 return vwin ? vwin->cursor_timer : 0;
1418 }
1419
video_window_set_cursor_timer(xui_vwin_t * vwin,int timer)1420 void video_window_set_cursor_timer (xui_vwin_t *vwin, int timer) {
1421 if (vwin)
1422 vwin->cursor_timer = timer;
1423 }
1424
1425 /*
1426 * hide/show video window
1427 */
video_window_set_visibility(xui_vwin_t * vwin,int show_window)1428 void video_window_set_visibility (xui_vwin_t *vwin, int show_window) {
1429
1430 if (!vwin)
1431 return;
1432 if (vwin->gui->use_root_window)
1433 return;
1434
1435 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_VIDEOWIN_VISIBLE, (void *)(intptr_t)show_window);
1436
1437 pthread_mutex_lock (&vwin->mutex);
1438
1439 vwin->show = show_window;
1440
1441 /* Switching to visible: If new window size requested meanwhile, adapt window */
1442 if ((vwin->show) && (vwin->fullscreen_mode & WINDOWED_MODE) &&
1443 (vwin->win_width != vwin->old_win_width || vwin->win_height != vwin->old_win_height))
1444 video_window_adapt_size (vwin);
1445
1446 vwin->gui->x_lock_display (vwin->gui->video_display);
1447
1448 if (vwin->show == 1) {
1449
1450 if ((vwin->gui->always_layer_above ||
1451 (((!(vwin->fullscreen_mode & WINDOWED_MODE)) && is_layer_above()) &&
1452 (vwin->hide_on_start == 0))) && (!wm_not_ewmh_only())) {
1453 xitk_set_layer_above (vwin->gui->video_window);
1454 }
1455
1456 XRaiseWindow (vwin->gui->video_display, vwin->gui->video_window);
1457 XMapWindow (vwin->gui->video_display, vwin->gui->video_window);
1458
1459 if ((vwin->gui->always_layer_above ||
1460 (((!(vwin->fullscreen_mode & WINDOWED_MODE)) && is_layer_above()) &&
1461 (vwin->hide_on_start == 0))) && (wm_not_ewmh_only())) {
1462 xitk_set_layer_above(vwin->gui->video_window);
1463 }
1464
1465 /* inform the window manager that we are fullscreen. This info musn't be set for xinerama-fullscreen,
1466 otherwise there are 2 different window size for one fullscreen mode ! (kwin doesn't accept this) */
1467 if (!(vwin->fullscreen_mode & WINDOWED_MODE)
1468 && !(vwin->fullscreen_mode & FULLSCR_XI_MODE)
1469 && wm_not_ewmh_only())
1470 xitk_set_ewmh_fullscreen (vwin->gui->video_window);
1471 }
1472 else
1473 XUnmapWindow (vwin->gui->video_display, vwin->gui->video_window);
1474
1475 vwin->gui->x_unlock_display (vwin->gui->video_display);
1476
1477 /* User used '-H', now he want to show video window */
1478 if (vwin->hide_on_start == -1)
1479 vwin->hide_on_start = 0;
1480
1481 pthread_mutex_unlock (&vwin->mutex);
1482 }
1483
1484 /*
1485 *
1486 */
video_window_is_visible(xui_vwin_t * vwin)1487 int video_window_is_visible (xui_vwin_t *vwin) {
1488 return vwin ? vwin->show : 0;
1489 }
1490
1491 /*
1492 * check if screen_number is in the list
1493 */
screen_is_in_xinerama_fullscreen_list(const char * list,int screen_number)1494 static int screen_is_in_xinerama_fullscreen_list (const char *list, int screen_number) {
1495 const char *buffer;
1496 int dummy;
1497
1498 buffer = list;
1499
1500 do {
1501 if((sscanf(buffer,"%d", &dummy) == 1) && (screen_number == dummy))
1502 return 1;
1503 } while((buffer = strchr(buffer,' ')) && (++buffer < (list + strlen(list))));
1504
1505 return 0;
1506 }
1507
1508 /*
1509 *
1510 */
video_window_init(gGui_t * gui,window_attributes_t * window_attribute,int hide_on_start)1511 xui_vwin_t *video_window_init (gGui_t *gui, window_attributes_t *window_attribute, int hide_on_start) {
1512 xui_vwin_t *vwin;
1513 int i;
1514 #ifdef HAVE_XINERAMA
1515 int screens;
1516 int dummy_a, dummy_b;
1517 XineramaScreenInfo *screeninfo = NULL;
1518 const char *screens_list;
1519 #endif
1520 #ifdef HAVE_XF86VIDMODE
1521 int dummy_query_event, dummy_query_error;
1522 #endif
1523
1524 if (!gui)
1525 return NULL;
1526 vwin = calloc (1, sizeof (*vwin));
1527 if (!vwin)
1528 return NULL;
1529
1530 vwin->gui = gui;
1531 pthread_mutex_init (&vwin->mutex, NULL);
1532
1533 if (vwin->gui->video_display == vwin->gui->display) {
1534 vwin->wl = xitk_widget_list_new ();
1535 }
1536
1537 vwin->fullscreen_req = WINDOWED_MODE;
1538 vwin->fullscreen_mode = WINDOWED_MODE;
1539 vwin->gui->video_window = None;
1540 vwin->show = 1;
1541 vwin->widget_key =
1542 vwin->old_widget_key = 0;
1543 vwin->gc = None;
1544 vwin->borderless = window_attribute->borderless;
1545 vwin->have_xtest = have_xtestextention (vwin);
1546 vwin->hide_on_start = hide_on_start;
1547
1548 vwin->depth = vwin->gui->depth;
1549 vwin->visual = vwin->gui->visual;
1550 vwin->colormap = vwin->gui->colormap;
1551 /* Currently, there no plugin loaded so far, but that might change */
1552 video_window_select_visual (vwin);
1553
1554 if (vwin->gui->video_display != vwin->gui->display) {
1555 video_window_find_visual (vwin, &vwin->visual, &vwin->depth);
1556 vwin->colormap = DefaultColormap (vwin->gui->video_display, vwin->gui->video_screen);
1557 }
1558
1559 vwin->xwin = window_attribute->x;
1560 vwin->ywin = window_attribute->y;
1561
1562 vwin->gui->x_lock_display (vwin->gui->video_display);
1563 vwin->desktopWidth = DisplayWidth(vwin->gui->video_display, vwin->gui->video_screen);
1564 vwin->desktopHeight = DisplayHeight(vwin->gui->video_display, vwin->gui->video_screen);
1565
1566 #ifdef HAVE_XTESTEXTENSION
1567 vwin->fake_keys[0] = XKeysymToKeycode (vwin->gui->video_display, XK_Shift_L);
1568 vwin->fake_keys[1] = XKeysymToKeycode (vwin->gui->video_display, XK_Control_L);
1569 vwin->fake_key_cur = 0;
1570 #endif
1571
1572 memcpy (vwin->window_title, "xine", 5);
1573
1574 gettimeofday (&vwin->click_time, 0);
1575
1576 vwin->using_xinerama = 0;
1577 #ifdef HAVE_XINERAMA
1578 vwin->xinerama = NULL;
1579 vwin->xinerama_cnt = 0;
1580 /* Spark
1581 * some Xinerama stuff
1582 * I want to figure out what fullscreen means for this setup
1583 */
1584
1585 if ((XineramaQueryExtension (vwin->gui->video_display, &dummy_a, &dummy_b))
1586 && (screeninfo = XineramaQueryScreens (vwin->gui->video_display, &screens))) {
1587 /* Xinerama Detected */
1588 #ifdef DEBUG
1589 printf ("videowin: display is using xinerama with %d screens\n", screens);
1590 printf ("videowin: going to assume we are using the first screen.\n");
1591 printf ("videowin: size of the first screen is %dx%d.\n",
1592 screeninfo[0].width, screeninfo[0].height);
1593 #endif
1594 if (XineramaIsActive(vwin->gui->video_display)) {
1595 vwin->using_xinerama = 1;
1596 vwin->fullscreen_width = screeninfo[0].width;
1597 vwin->fullscreen_height = screeninfo[0].height;
1598 vwin->xinerama = screeninfo;
1599 vwin->xinerama_cnt = screens;
1600
1601 screens_list = xine_config_register_string (vwin->gui->xine, "gui.xinerama_use_screens",
1602 "0 1",
1603 _("Screens to use in order to do a very fullscreen in xinerama mode. (example 0 2 3)"),
1604 _("Example, if you want the display to expand on screen 0, 2 and 3, enter 0 2 3"),
1605 CONFIG_LEVEL_EXP, CONFIG_NO_CB, CONFIG_NO_DATA);
1606
1607 if((sscanf(screens_list,"%d",&dummy_a) == 1) && (dummy_a >= 0) && (dummy_a < screens)) {
1608
1609 /* try to calculate the best maximum size for xinerama fullscreen */
1610 vwin->xinerama_fullscreen_x = screeninfo[dummy_a].x_org;
1611 vwin->xinerama_fullscreen_y = screeninfo[dummy_a].y_org;
1612 vwin->xinerama_fullscreen_width = screeninfo[dummy_a].width;
1613 vwin->xinerama_fullscreen_height = screeninfo[dummy_a].height;
1614
1615 i = dummy_a;
1616 while(i < screens) {
1617
1618 if(screen_is_in_xinerama_fullscreen_list(screens_list, i)) {
1619 if(screeninfo[i].x_org < vwin->xinerama_fullscreen_x)
1620 vwin->xinerama_fullscreen_x = screeninfo[i].x_org;
1621 if(screeninfo[i].y_org < vwin->xinerama_fullscreen_y)
1622 vwin->xinerama_fullscreen_y = screeninfo[i].y_org;
1623 }
1624
1625 i++;
1626 }
1627
1628 i = dummy_a;
1629 while(i < screens) {
1630
1631 if(screen_is_in_xinerama_fullscreen_list(screens_list, i)) {
1632 if((screeninfo[i].width + screeninfo[i].x_org) >
1633 (vwin->xinerama_fullscreen_x + vwin->xinerama_fullscreen_width)) {
1634 vwin->xinerama_fullscreen_width =
1635 screeninfo[i].width + screeninfo[i].x_org - vwin->xinerama_fullscreen_x;
1636 }
1637
1638 if((screeninfo[i].height + screeninfo[i].y_org) >
1639 (vwin->xinerama_fullscreen_y + vwin->xinerama_fullscreen_height)) {
1640 vwin->xinerama_fullscreen_height =
1641 screeninfo[i].height + screeninfo[i].y_org - vwin->xinerama_fullscreen_y;
1642 }
1643 }
1644
1645 i++;
1646 }
1647 } else {
1648 /* we can't find screens to use, so we use screen 0 */
1649 vwin->xinerama_fullscreen_x = screeninfo[0].x_org;
1650 vwin->xinerama_fullscreen_y = screeninfo[0].y_org;
1651 vwin->xinerama_fullscreen_width = screeninfo[0].width;
1652 vwin->xinerama_fullscreen_height = screeninfo[0].height;
1653 }
1654
1655 dummy_a = xine_config_register_num (vwin->gui->xine, "gui.xinerama_fullscreen_x",
1656 -8192,
1657 _("x coordinate for xinerama fullscreen (-8192 = autodetect)"),
1658 CONFIG_NO_HELP, CONFIG_LEVEL_EXP, CONFIG_NO_CB, CONFIG_NO_DATA);
1659 if(dummy_a > -8192)
1660 vwin->xinerama_fullscreen_x = dummy_a;
1661
1662 dummy_a = xine_config_register_num (vwin->gui->xine, "gui.xinerama_fullscreen_y",
1663 -8192,
1664 _("y coordinate for xinerama fullscreen (-8192 = autodetect)"),
1665 CONFIG_NO_HELP, CONFIG_LEVEL_EXP, CONFIG_NO_CB, CONFIG_NO_DATA);
1666 if(dummy_a > -8192)
1667 vwin->xinerama_fullscreen_y = dummy_a;
1668
1669 dummy_a = xine_config_register_num (vwin->gui->xine, "gui.xinerama_fullscreen_width",
1670 -8192,
1671 _("width for xinerama fullscreen (-8192 = autodetect)"),
1672 CONFIG_NO_HELP, CONFIG_LEVEL_EXP, CONFIG_NO_CB, CONFIG_NO_DATA);
1673 if(dummy_a > -8192)
1674 vwin->xinerama_fullscreen_width = dummy_a;
1675
1676 dummy_a = xine_config_register_num (vwin->gui->xine, "gui.xinerama_fullscreen_height",
1677 -8192,
1678 _("height for xinerama fullscreen (-8192 = autodetect)"),
1679 CONFIG_NO_HELP, CONFIG_LEVEL_EXP, CONFIG_NO_CB, CONFIG_NO_DATA);
1680 if(dummy_a > -8192)
1681 vwin->xinerama_fullscreen_height = dummy_a;
1682
1683 #ifdef DEBUG
1684 printf ("videowin: Xinerama fullscreen parameters: X_origin=%d Y_origin=%d Width=%d Height=%d\n",
1685 vwin->xinerama_fullscreen_x, vwin->xinerama_fullscreen_y,
1686 vwin->xinerama_fullscreen_width, vwin->xinerama_fullscreen_height);
1687 #endif
1688 }
1689 else {
1690 vwin->fullscreen_width = DisplayWidth (vwin->gui->video_display, vwin->gui->video_screen);
1691 vwin->fullscreen_height = DisplayHeight (vwin->gui->video_display, vwin->gui->video_screen);
1692 vwin->xinerama_fullscreen_x = 0;
1693 vwin->xinerama_fullscreen_y = 0;
1694 vwin->xinerama_fullscreen_width = vwin->fullscreen_width;
1695 vwin->xinerama_fullscreen_height = vwin->fullscreen_height;
1696 }
1697
1698 } else
1699 #endif
1700 {
1701 /* no Xinerama */
1702 if (__xineui_global_verbosity)
1703 printf ("Display is not using Xinerama.\n");
1704 vwin->fullscreen_width = DisplayWidth (vwin->gui->video_display, vwin->gui->video_screen);
1705 vwin->fullscreen_height = DisplayHeight (vwin->gui->video_display, vwin->gui->video_screen);
1706 }
1707 vwin->visible_width = vwin->fullscreen_width;
1708 vwin->visible_height = vwin->fullscreen_height;
1709
1710 /* create xclass hint for video window */
1711
1712 if ((vwin->xclasshint = XAllocClassHint()) != NULL) {
1713 vwin->xclasshint->res_name = _("xine Video Window");
1714 vwin->xclasshint->res_class = "xine";
1715 }
1716 if ((vwin->xclasshint_fullscreen = XAllocClassHint()) != NULL) {
1717 vwin->xclasshint_fullscreen->res_name = _("xine Video Fullscreen Window");
1718 vwin->xclasshint_fullscreen->res_class = "xine";
1719 }
1720 if ((vwin->xclasshint_borderless = XAllocClassHint()) != NULL) {
1721 vwin->xclasshint_borderless->res_name = _("xine Video Borderless Window");
1722 vwin->xclasshint_borderless->res_class = "xine";
1723 }
1724
1725 vwin->current_cursor = CURSOR_ARROW;
1726 vwin->cursor_timer = 0;
1727
1728 /*
1729 * wm hints
1730 */
1731
1732 vwin->wm_hint = XAllocWMHints();
1733 if (!vwin->wm_hint) {
1734 printf (_("XAllocWMHints() failed\n"));
1735 exit (1);
1736 }
1737
1738 vwin->wm_hint->input = True;
1739 vwin->wm_hint->initial_state = NormalState;
1740 vwin->wm_hint->icon_pixmap = vwin->gui->icon;
1741 vwin->wm_hint->flags = InputHint | StateHint | IconPixmapHint;
1742
1743 vwin->gui->x_unlock_display (vwin->gui->video_display);
1744
1745 vwin->stream_resize_window = xine_config_register_bool (vwin->gui->xine, "gui.stream_resize_window",
1746 1,
1747 _("New stream sizes resize output window"),
1748 CONFIG_NO_HELP, CONFIG_LEVEL_ADV, _video_window_resize_cb, vwin);
1749
1750 vwin->zoom_small_stream = xine_config_register_bool (vwin->gui->xine, "gui.zoom_small_stream",
1751 0,
1752 _("Double size for small streams (require stream_resize_window)"),
1753 CONFIG_NO_HELP, CONFIG_LEVEL_ADV, _video_window_zoom_small_cb, vwin);
1754
1755 if ((window_attribute->width > 0) && (window_attribute->height > 0)) {
1756 vwin->video_width = window_attribute->width;
1757 vwin->video_height = window_attribute->height;
1758 /*
1759 * Force to keep window size.
1760 * I don't update the config file, i think this window geometry
1761 * user defined can be temporary.
1762 */
1763 vwin->stream_resize_window = 0;
1764 }
1765 else {
1766 vwin->video_width = 768;
1767 vwin->video_height = 480;
1768 }
1769 vwin->old_win_width = vwin->win_width = vwin->video_width;
1770 vwin->old_win_height = vwin->win_height = vwin->video_height;
1771
1772 #ifdef HAVE_XF86VIDMODE
1773 if (xine_config_register_bool (vwin->gui->xine, "gui.use_xvidext",
1774 0,
1775 _("use XVidModeExtension when switching to fullscreen"),
1776 CONFIG_NO_HELP, CONFIG_LEVEL_EXP, CONFIG_NO_CB, CONFIG_NO_DATA)) {
1777 /*
1778 * without the "stream resizes window" behavior, the XVidMode support
1779 * won't work correctly, so we force it for each session the user wants
1780 * to have XVideMode on...
1781 *
1782 * FIXME: maybe display a warning message or so?!
1783 */
1784 vwin->stream_resize_window = 1;
1785
1786 vwin->gui->x_lock_display (vwin->gui->video_display);
1787
1788 if (XF86VidModeQueryExtension (vwin->gui->video_display, &dummy_query_event, &dummy_query_error)) {
1789 XF86VidModeModeInfo* XF86_modelines_swap;
1790 int mode, major, minor, sort_x, sort_y;
1791
1792 XF86VidModeQueryVersion (vwin->gui->video_display, &major, &minor);
1793 printf (_("XF86VidMode Extension (%d.%d) detected, trying to use it.\n"), major, minor);
1794
1795 if (XF86VidModeGetAllModeLines (vwin->gui->video_display, XDefaultScreen(vwin->gui->video_display),
1796 &(vwin->XF86_modelines_count), &(vwin->XF86_modelines))) {
1797 printf (_("XF86VidMode Extension: %d modelines found.\n"), vwin->XF86_modelines_count);
1798
1799 /* first, kick off unsupported modes */
1800 for (mode = 1; mode < vwin->XF86_modelines_count; mode++) {
1801
1802 if (!XF86VidModeValidateModeLine (vwin->gui->video_display, vwin->gui->video_screen,
1803 vwin->XF86_modelines[mode])) {
1804 int wrong_mode;
1805
1806 printf(_("XF86VidModeModeLine %dx%d isn't valid: discarded.\n"),
1807 vwin->XF86_modelines[mode]->hdisplay,
1808 vwin->XF86_modelines[mode]->vdisplay);
1809
1810 for (wrong_mode = mode; wrong_mode < vwin->XF86_modelines_count; wrong_mode++)
1811 vwin->XF86_modelines[wrong_mode] = vwin->XF86_modelines[wrong_mode + 1];
1812
1813 vwin->XF86_modelines[wrong_mode] = NULL;
1814 vwin->XF86_modelines_count--;
1815 mode--;
1816 }
1817 }
1818
1819 /*
1820 * sorting modelines, skipping first entry because it is the current
1821 * modeline in use - this is important so we know to which modeline
1822 * we have to switch to when toggling fullscreen mode.
1823 */
1824 for (sort_x = 1; sort_x < vwin->XF86_modelines_count; sort_x++) {
1825
1826 for (sort_y = sort_x+1; sort_y < vwin->XF86_modelines_count; sort_y++) {
1827
1828 if (vwin->XF86_modelines[sort_x]->hdisplay > vwin->XF86_modelines[sort_y]->hdisplay) {
1829 XF86_modelines_swap = vwin->XF86_modelines[sort_y];
1830 vwin->XF86_modelines[sort_y] = vwin->XF86_modelines[sort_x];
1831 vwin->XF86_modelines[sort_x] = XF86_modelines_swap;
1832 }
1833 }
1834 }
1835 } else {
1836 vwin->XF86_modelines_count = 0;
1837 printf(_("XF86VidMode Extension: could not get list of available modelines. Failed.\n"));
1838 }
1839 } else {
1840 printf(_("XF86VidMode Extension: initialization failed, not using it.\n"));
1841 }
1842 vwin->gui->x_unlock_display (vwin->gui->video_display);
1843 }
1844 else
1845 vwin->XF86_modelines_count = 0;
1846
1847 #endif
1848
1849 /*
1850 * Create initial video window with the geometry constructed above.
1851 */
1852 video_window_adapt_size (vwin);
1853
1854 /*
1855 * for plugins that aren't really bind to the window, it's necessary that the
1856 * vwin->xwin and vwin->ywin variables are set to *real* values, otherwise the
1857 * overlay will be displayed somewhere outside the window
1858 */
1859 if (vwin->gui->video_window) {
1860 Window tmp_win;
1861
1862 vwin->gui->x_lock_display (vwin->gui->video_display);
1863 if((window_attribute->x > -8192) && (window_attribute->y > -8192)) {
1864 vwin->xwin = vwin->old_xwin = window_attribute->x;
1865 vwin->ywin = vwin->old_ywin = window_attribute->y;
1866
1867 XMoveResizeWindow (vwin->gui->video_display, vwin->gui->video_window,
1868 vwin->xwin, vwin->ywin, vwin->video_width, vwin->video_height);
1869
1870 }
1871 else {
1872
1873 XTranslateCoordinates (vwin->gui->video_display, vwin->gui->video_window,
1874 DefaultRootWindow (vwin->gui->video_display), 0, 0, &vwin->xwin, &vwin->ywin, &tmp_win);
1875 }
1876 vwin->gui->x_unlock_display (vwin->gui->video_display);
1877
1878 }
1879
1880 if (vwin->gui->video_display != vwin->gui->display) {
1881 vwin->second_display_running = 1;
1882 pthread_create (&vwin->second_display_thread, NULL, second_display_loop, vwin);
1883 }
1884
1885 vwin->gui->vwin = vwin;
1886 return vwin;
1887 }
1888
1889
1890 /*
1891 * Necessary cleanup
1892 */
video_window_exit(xui_vwin_t * vwin)1893 void video_window_exit (xui_vwin_t *vwin) {
1894
1895 if (!vwin)
1896 return;
1897
1898 #ifdef HAVE_XINE_CONFIG_UNREGISTER_CALLBACKS
1899 xine_config_unregister_callbacks (vwin->gui->xine, NULL, NULL, vwin, sizeof (*vwin));
1900 #endif
1901
1902 #ifdef HAVE_XF86VIDMODE
1903 /* Restore original VidMode */
1904 if (vwin->gui->XF86VidMode_fullscreen) {
1905 vwin->gui->x_lock_display (vwin->gui->video_display);
1906 XF86VidModeSwitchToMode (vwin->gui->video_display, XDefaultScreen (vwin->gui->video_display), vwin->XF86_modelines[0]);
1907 XF86VidModeSetViewPort (vwin->gui->video_display, XDefaultScreen (vwin->gui->video_display), 0, 0);
1908 vwin->gui->x_unlock_display (vwin->gui->video_display);
1909 }
1910 #endif
1911
1912 vwin->second_display_running = 0;
1913 if (vwin->gui->use_root_window || vwin->gui->video_display != vwin->gui->display) {
1914 union {
1915 XExposeEvent expose;
1916 XEvent event;
1917 } event;
1918
1919 vwin->gui->x_lock_display (vwin->gui->video_display);
1920 XClearWindow (vwin->gui->video_display, vwin->gui->video_window);
1921 event.expose.type = Expose;
1922 event.expose.send_event = True;
1923 event.expose.display = vwin->gui->video_display;
1924 event.expose.window = vwin->gui->video_window;
1925 event.expose.x = 0;
1926 event.expose.y = 0;
1927 event.expose.width = vwin->video_width;
1928 event.expose.height = vwin->video_height;
1929 XSendEvent (vwin->gui->video_display, vwin->gui->video_window, False, Expose, &event.event);
1930 vwin->gui->x_unlock_display (vwin->gui->video_display);
1931 }
1932
1933 if (vwin->gui->video_display == vwin->gui->display) {
1934 xitk_unregister_event_handler (&vwin->widget_key);
1935 XITK_WIDGET_LIST_FREE (vwin->wl);
1936 vwin->wl = NULL;
1937 } else
1938 pthread_join (vwin->second_display_thread, NULL);
1939
1940 pthread_mutex_destroy (&vwin->mutex);
1941 vwin->gui->vwin = NULL;
1942
1943 if (vwin->xclasshint != NULL)
1944 XFree (vwin->xclasshint);
1945 if (vwin->xclasshint_fullscreen != NULL)
1946 XFree (vwin->xclasshint_fullscreen);
1947 if (vwin->xclasshint_borderless != NULL)
1948 XFree (vwin->xclasshint_borderless);
1949 if (vwin->wm_hint != NULL)
1950 XFree (vwin->wm_hint);
1951
1952 free (vwin);
1953 }
1954
1955
1956 /*
1957 * Translate screen coordinates to video coordinates
1958 */
video_window_translate_point(xui_vwin_t * vwin,int gui_x,int gui_y,int * video_x,int * video_y)1959 static int video_window_translate_point (xui_vwin_t *vwin,
1960 int gui_x, int gui_y, int *video_x, int *video_y) {
1961 x11_rectangle_t rect;
1962 int xwin, ywin;
1963 unsigned int wwin, hwin, bwin, dwin;
1964 float xf,yf;
1965 float scale, width_scale, height_scale,aspect;
1966 Window rootwin;
1967
1968 if (!vwin)
1969 return 0;
1970
1971 rect.x = gui_x;
1972 rect.y = gui_y;
1973 rect.w = 0;
1974 rect.h = 0;
1975
1976 if (xine_port_send_gui_data (vwin->gui->vo_port,
1977 XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO, (void*)&rect) != -1) {
1978 /* driver implements vwin->gui->video coordinate space translation, use it */
1979 *video_x = rect.x;
1980 *video_y = rect.y;
1981 return 1;
1982 }
1983
1984 /* Driver cannot convert vwin->gui->video space, fall back to old code... */
1985
1986 pthread_mutex_lock (&vwin->mutex);
1987
1988 vwin->gui->x_lock_display (vwin->gui->video_display);
1989 if (XGetGeometry (vwin->gui->video_display, vwin->gui->video_window, &rootwin,
1990 &xwin, &ywin, &wwin, &hwin, &bwin, &dwin) == BadDrawable) {
1991 vwin->gui->x_unlock_display (vwin->gui->video_display);
1992 pthread_mutex_unlock (&vwin->mutex);
1993 return 0;
1994 }
1995 vwin->gui->x_unlock_display (vwin->gui->video_display);
1996
1997 /* Scale co-ordinate to image dimensions. */
1998 height_scale = (float)vwin->video_height / (float)hwin;
1999 width_scale = (float)vwin->video_width / (float)wwin;
2000 aspect = (float)vwin->video_width / (float)vwin->video_height;
2001 if (((float)wwin / (float)hwin) < aspect) {
2002 scale = width_scale;
2003 xf = (float)gui_x * scale;
2004 yf = (float)gui_y * scale;
2005 /* wwin=wwin * scale; */
2006 hwin = hwin * scale;
2007 /* FIXME: The 1.25 should really come from the NAV packets. */
2008 *video_x = xf * 1.25 / aspect;
2009 *video_y = yf - ((hwin - vwin->video_height) / 2);
2010 /* printf("wscale:a=%f, s=%f, x=%d, y=%d\n",aspect, scale,*video_x,*video_y); */
2011 } else {
2012 scale = height_scale;
2013 xf = (float)gui_x * scale;
2014 yf = (float)gui_y * scale;
2015 wwin = wwin * scale;
2016 /* FIXME: The 1.25 should really come from the NAV packets. */
2017 *video_x = (xf - ((wwin - vwin->video_width) /2)) * 1.25 / aspect;
2018 *video_y = yf;
2019 /* printf("hscale:a=%f s=%f x=%d, y=%d\n",aspect,scale,*video_x,*video_y); */
2020 }
2021
2022 pthread_mutex_unlock (&vwin->mutex);
2023
2024 return 1;
2025 }
2026
2027 /*
2028 * Set/Get magnification.
2029 */
video_window_check_mag(xui_vwin_t * vwin)2030 static int video_window_check_mag (xui_vwin_t *vwin) {
2031 if (!vwin)
2032 return 0;
2033
2034 if ((!(vwin->fullscreen_mode & WINDOWED_MODE))
2035 /*
2036 * Currently, no support for magnification in fullscreen mode.
2037 * Commented out in order to not mess up current mag for windowed mode.
2038 *
2039 #ifdef HAVE_XF86VIDMODE
2040 && !(vwin->XF86_modelines_count > 1)
2041 #endif
2042 */
2043 )
2044 return 0;
2045
2046 /* Allow mag only if video win is visible, so don't do something we can't see. */
2047 return (xitk_is_window_visible (vwin->gui->video_display, vwin->gui->video_window));
2048 }
2049
video_window_calc_mag_win_size(xui_vwin_t * vwin,float xmag,float ymag)2050 static void video_window_calc_mag_win_size (xui_vwin_t *vwin, float xmag, float ymag) {
2051 vwin->win_width = (int) ((float) vwin->video_width * xmag + 0.5f);
2052 vwin->win_height = (int) ((float) vwin->video_height * ymag + 0.5f);
2053 }
2054
video_window_set_mag(xui_vwin_t * vwin,float xmag,float ymag)2055 int video_window_set_mag (xui_vwin_t *vwin, float xmag, float ymag) {
2056 if (!vwin)
2057 return 0;
2058
2059 pthread_mutex_lock (&vwin->mutex);
2060
2061 if (!video_window_check_mag (vwin)) {
2062 pthread_mutex_unlock (&vwin->mutex);
2063 return 0;
2064 }
2065 video_window_calc_mag_win_size (vwin, xmag, ymag);
2066 video_window_adapt_size (vwin);
2067
2068 pthread_mutex_unlock (&vwin->mutex);
2069
2070 return 1;
2071 }
2072
video_window_get_mag(xui_vwin_t * vwin,float * xmag,float * ymag)2073 void video_window_get_mag (xui_vwin_t *vwin, float *xmag, float *ymag) {
2074 if (!vwin)
2075 return;
2076
2077 /* compute current mag */
2078 pthread_mutex_lock (&vwin->mutex);
2079 *xmag = (float) vwin->output_width / (float) vwin->video_width;
2080 *ymag = (float) vwin->output_height / (float) vwin->video_height;
2081 pthread_mutex_unlock (&vwin->mutex);
2082 }
2083
2084 /*
2085 * Change displayed logo, if selected skin want to customize it.
2086 */
video_window_update_logo(xui_vwin_t * vwin)2087 void video_window_update_logo (xui_vwin_t *vwin) {
2088 xine_cfg_entry_t cfg_entry;
2089 const char *skin_logo;
2090 int cfg_err_result;
2091
2092 if (!vwin)
2093 return;
2094
2095 cfg_err_result = xine_config_lookup_entry (vwin->gui->xine, "gui.logo_mrl", &cfg_entry);
2096 skin_logo = xitk_skin_get_logo (vwin->gui->skin_config);
2097
2098 if(skin_logo) {
2099
2100 if((cfg_err_result) && cfg_entry.str_value) {
2101 /* Old and new logo are same, don't reload */
2102 if(!strcmp(cfg_entry.str_value, skin_logo))
2103 goto __done;
2104 }
2105
2106 config_update_string("gui.logo_mrl", skin_logo);
2107 goto __play_logo_now;
2108
2109 }
2110 else { /* Skin don't use logo feature, set to xine's default */
2111
2112 /*
2113 * Back to default logo only on a skin
2114 * change, not at the first skin loading.
2115 **/
2116 #ifdef XINE_LOGO2_MRL
2117 # define USE_XINE_LOGO_MRL XINE_LOGO2_MRL
2118 #else
2119 # define USE_XINE_LOGO_MRL XINE_LOGO_MRL
2120 #endif
2121 if (vwin->logo_synthetic && (cfg_err_result) && (strcmp (cfg_entry.str_value, USE_XINE_LOGO_MRL))) {
2122 config_update_string ("gui.logo_mrl", USE_XINE_LOGO_MRL);
2123
2124 __play_logo_now:
2125
2126 sleep(1);
2127
2128 if (vwin->gui->logo_mode) {
2129 if (xine_get_status (vwin->gui->stream) == XINE_STATUS_PLAY) {
2130 vwin->gui->ignore_next = 1;
2131 xine_stop (vwin->gui->stream);
2132 vwin->gui->ignore_next = 0;
2133 }
2134 if (vwin->gui->display_logo) {
2135 if ((!xine_open (vwin->gui->stream, vwin->gui->logo_mrl))
2136 || (!xine_play (vwin->gui->stream, 0, 0))) {
2137 gui_handle_xine_error (vwin->gui->stream, (char *)vwin->gui->logo_mrl);
2138 goto __done;
2139 }
2140 }
2141 vwin->gui->logo_mode = 1;
2142 }
2143 }
2144 }
2145
2146 __done:
2147 vwin->gui->logo_has_changed--;
2148 }
2149
video_window_change_skins(xui_vwin_t * vwin,int synthetic)2150 void video_window_change_skins (xui_vwin_t *vwin, int synthetic) {
2151 if (!vwin)
2152 return;
2153 vwin->logo_synthetic = (synthetic ? 1 : 0);
2154 vwin->gui->logo_has_changed++;
2155 }
2156
2157 /*
2158 *
2159 */
video_window_handle_event(XEvent * event,void * data)2160 static void video_window_handle_event (XEvent *event, void *data) {
2161 xui_vwin_t *vwin = data;
2162
2163 switch(event->type) {
2164
2165 case DestroyNotify:
2166 if (vwin->gui->video_window == event->xany.window)
2167 gui_exit (NULL, vwin->gui);
2168 break;
2169
2170 case KeyPress:
2171 gui_handle_event (event, vwin->gui);
2172 break;
2173
2174 case MotionNotify: {
2175 XMotionEvent *mevent = (XMotionEvent *) event;
2176 xine_event_t event;
2177 xine_input_data_t input;
2178 int x, y;
2179
2180 /* printf("Mouse event:mx=%d my=%d\n",mevent->x, mevent->y); */
2181
2182 if (!vwin->gui->cursor_visible) {
2183 vwin->gui->cursor_visible = !vwin->gui->cursor_visible;
2184 video_window_set_cursor_visibility (vwin, vwin->gui->cursor_visible);
2185 }
2186
2187 event.type = XINE_EVENT_INPUT_MOUSE_MOVE;
2188 if (!oxine_mouse_event(event.type, mevent->x, mevent->y) ) {
2189 if (video_window_translate_point (vwin, mevent->x, mevent->y, &x, &y)) {
2190 event.stream = vwin->gui->stream;
2191 event.data = &input;
2192 event.data_length = sizeof(input);
2193 gettimeofday(&event.tv, NULL);
2194 input.button = 0; /* No buttons, just motion. */
2195 input.x = x;
2196 input.y = y;
2197
2198 xine_event_send (vwin->gui->stream, &event);
2199 }
2200 }
2201 }
2202 break;
2203
2204 case ButtonPress: {
2205 XButtonEvent *bevent = (XButtonEvent *) event;
2206 xine_input_data_t input;
2207 xine_event_t event;
2208 int x, y;
2209
2210 if (!vwin->gui->cursor_visible) {
2211 vwin->gui->cursor_visible = !vwin->gui->cursor_visible;
2212 video_window_set_cursor_visibility (vwin, vwin->gui->cursor_visible);
2213 }
2214
2215 if (bevent->button == Button3 && vwin->gui->display == vwin->gui->video_display)
2216 video_window_menu (vwin->gui, vwin->wl);
2217 else if (bevent->button == Button2)
2218 panel_toggle_visibility (NULL, vwin->gui->panel);
2219 else if (bevent->button == Button1) {
2220 struct timeval old_click_time, tm_diff;
2221 long int click_diff;
2222
2223 timercpy (&vwin->click_time, &old_click_time);
2224 gettimeofday (&vwin->click_time, 0);
2225
2226 timercpy (&old_click_time, &event.tv);
2227
2228 timersub (&vwin->click_time, &old_click_time, &tm_diff);
2229 click_diff = (tm_diff.tv_sec * 1000) + (tm_diff.tv_usec / 1000.0);
2230
2231 if (click_diff < (xitk_get_timer_dbl_click())) {
2232 gui_execute_action_id (vwin->gui, ACTID_TOGGLE_FULLSCREEN);
2233 vwin->click_time.tv_sec -= (xitk_get_timer_dbl_click() / 1000.0);
2234 vwin->click_time.tv_usec -= (xitk_get_timer_dbl_click() * 1000.0);
2235 }
2236
2237 }
2238
2239 event.type = XINE_EVENT_INPUT_MOUSE_BUTTON;
2240 if( bevent->button != Button1 ||
2241 !oxine_mouse_event(event.type, bevent->x, bevent->y) ) {
2242 if (video_window_translate_point (vwin, bevent->x, bevent->y, &x, &y)) {
2243 event.stream = vwin->gui->stream;
2244 event.data = &input;
2245 event.data_length = sizeof(input);
2246 input.button = bevent->button;
2247 input.x = x;
2248 input.y = y;
2249
2250 xine_event_send (vwin->gui->stream, &event);
2251 }
2252 }
2253 }
2254 break;
2255
2256 case ButtonRelease:
2257 gui_handle_event (event, vwin->gui);
2258 break;
2259
2260 case Expose: {
2261 XExposeEvent * xev = (XExposeEvent *) event;
2262
2263 if (xev->count == 0) {
2264
2265 if (event->xany.window == vwin->gui->video_window) {
2266 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_EXPOSE_EVENT, event);
2267 }
2268 }
2269 }
2270 break;
2271
2272 case ConfigureNotify:
2273 if (event->xany.window == vwin->gui->video_window) {
2274 XConfigureEvent *cev = (XConfigureEvent *) event;
2275 Window tmp_win;
2276 int h, w;
2277
2278 pthread_mutex_lock (&vwin->mutex);
2279
2280 h = vwin->output_height;
2281 w = vwin->output_width;
2282 vwin->output_width = cev->width;
2283 vwin->output_height = cev->height;
2284
2285 if ((cev->x == 0) && (cev->y == 0)) {
2286 vwin->gui->x_lock_display (cev->display);
2287 XTranslateCoordinates(cev->display, cev->window, DefaultRootWindow(cev->display),
2288 0, 0, &vwin->xwin, &vwin->ywin, &tmp_win);
2289 vwin->gui->x_unlock_display (cev->display);
2290 }
2291 else {
2292 vwin->xwin = cev->x;
2293 vwin->ywin = cev->y;
2294 }
2295
2296 /* Keep geometry memory of windowed mode in sync. */
2297 if (vwin->fullscreen_mode & WINDOWED_MODE) {
2298 vwin->old_win_width = vwin->win_width = vwin->output_width;
2299 vwin->old_win_height = vwin->win_height = vwin->output_height;
2300 }
2301
2302 if ((h != vwin->output_height) || (w != vwin->output_width))
2303 osd_update_osd();
2304
2305 oxine_adapt();
2306
2307 pthread_mutex_unlock (&vwin->mutex);
2308 }
2309 break;
2310
2311 }
2312 }
2313
video_window_get_ssaver_idle(xui_vwin_t * vwin)2314 long int video_window_get_ssaver_idle (xui_vwin_t *vwin) {
2315 if (!vwin)
2316 return 0;
2317
2318 #ifdef HAVE_XSSAVEREXTENSION
2319 {
2320 long int ssaver_idle = -1;
2321 int dummy = 0;
2322 vwin->gui->x_lock_display (vwin->gui->video_display);
2323 if (XScreenSaverQueryExtension (vwin->gui->video_display, &dummy, &dummy)) {
2324 XScreenSaverInfo *ssaverinfo = XScreenSaverAllocInfo();
2325 XScreenSaverQueryInfo (vwin->gui->video_display, (DefaultRootWindow (vwin->gui->video_display)), ssaverinfo);
2326 ssaver_idle = ssaverinfo->idle / 1000;
2327 XFree(ssaverinfo);
2328 }
2329 vwin->gui->x_unlock_display (vwin->gui->video_display);
2330 if (ssaver_idle != -1)
2331 return ssaver_idle;
2332 }
2333 #endif
2334
2335 return xitk_get_last_keypressed_time();
2336 }
2337
2338
video_window_reset_ssaver(xui_vwin_t * vwin)2339 long int video_window_reset_ssaver (xui_vwin_t *vwin) {
2340
2341 /* fprintf(stderr, "Idletime %d, timeout %d\n", video_window_get_ssaver_idle(), (long int) vwin->gui->ssaver_timeout); */
2342
2343 long int idle = 0;
2344
2345 if (!vwin)
2346 return 0;
2347
2348 if (vwin->gui->ssaver_enabled && ((idle = video_window_get_ssaver_idle (vwin)) >= (long int) vwin->gui->ssaver_timeout)) {
2349 idle = 0;
2350 /* fprintf(stderr, "resetting ssaver\n"); */
2351
2352 #ifdef HAVE_XTESTEXTENSION
2353 if (vwin->have_xtest == True) {
2354
2355 vwin->fake_key_cur++;
2356
2357 if (vwin->fake_key_cur >= 2)
2358 vwin->fake_key_cur = 0;
2359
2360 vwin->gui->x_lock_display (vwin->gui->video_display);
2361 XTestFakeKeyEvent (vwin->gui->video_display, vwin->fake_keys[vwin->fake_key_cur], True, CurrentTime);
2362 XTestFakeKeyEvent (vwin->gui->video_display, vwin->fake_keys[vwin->fake_key_cur], False, CurrentTime);
2363 XSync (vwin->gui->video_display, False);
2364 vwin->gui->x_unlock_display (vwin->gui->video_display);
2365 }
2366 else
2367 #endif
2368 {
2369 /* Reset the gnome screensaver. Look up the command in PATH only once to save time, */
2370 /* assuming its location and permission will not change during run time of xine-ui. */
2371 {
2372 static char *const gssaver_args[] = { "gnome-screensaver-command", "--poke", NULL };
2373 static const char *gssaver_path = NULL;
2374
2375 if(!gssaver_path) {
2376 const char *path = getenv("PATH");
2377
2378 if(!path)
2379 path = "/usr/local/bin:/usr/bin";
2380 do {
2381 const char *p;
2382 char *pbuf;
2383 int plen;
2384
2385 for(p = path; *path && *path != ':'; path++)
2386 ;
2387 if(p == path)
2388 plen = 1, p = ".";
2389 else
2390 plen = path - p;
2391 pbuf = xitk_asprintf("%.*s/%s", plen, p, gssaver_args[0]);
2392 if ( pbuf && access(pbuf, X_OK) ) {
2393 free(pbuf);
2394 gssaver_path = "";
2395 } else
2396 gssaver_path = pbuf;
2397 } while(!gssaver_path[0] && *path++);
2398 }
2399 if (gssaver_path[0]) {
2400 pid_t pid = fork();
2401
2402 if (pid == 0) {
2403 if (fork() == 0) {
2404 execv(gssaver_path, gssaver_args);
2405 }
2406 _exit(0);
2407 } else if (pid > 0) {
2408 waitpid(pid, NULL, 0);
2409 }
2410 }
2411 }
2412
2413 vwin->gui->x_lock_display (vwin->gui->video_display);
2414 XResetScreenSaver (vwin->gui->video_display);
2415 vwin->gui->x_unlock_display (vwin->gui->video_display);
2416 }
2417 }
2418 return idle;
2419 }
2420
video_window_get_frame_size(xui_vwin_t * vwin,int * w,int * h)2421 void video_window_get_frame_size (xui_vwin_t *vwin, int *w, int *h) {
2422 if (!vwin)
2423 return;
2424
2425 if(w)
2426 *w = vwin->frame_width;
2427 if(h)
2428 *h = vwin->frame_height;
2429 if (!vwin->frame_width && !vwin->frame_height) {
2430 /* fall back to meta info */
2431 if (w) {
2432 *w = xine_get_stream_info (vwin->gui->stream, XINE_STREAM_INFO_VIDEO_WIDTH);
2433 }
2434 if (h) {
2435 *h = xine_get_stream_info (vwin->gui->stream, XINE_STREAM_INFO_VIDEO_HEIGHT);
2436 }
2437 }
2438 }
2439
video_window_get_visible_size(xui_vwin_t * vwin,int * w,int * h)2440 void video_window_get_visible_size (xui_vwin_t *vwin, int *w, int *h) {
2441 if (!vwin)
2442 return;
2443 if(w)
2444 *w = vwin->visible_width;
2445 if(h)
2446 *h = vwin->visible_height;
2447 }
2448
video_window_get_output_size(xui_vwin_t * vwin,int * w,int * h)2449 void video_window_get_output_size (xui_vwin_t *vwin, int *w, int *h) {
2450 if (!vwin)
2451 return;
2452 if(w)
2453 *w = vwin->output_width;
2454 if(h)
2455 *h = vwin->output_height;
2456 }
2457
video_window_set_mrl(xui_vwin_t * vwin,char * mrl)2458 void video_window_set_mrl (xui_vwin_t *vwin, char *mrl) {
2459 if (!vwin || !mrl)
2460 return;
2461 if (!mrl[0])
2462 return;
2463 if (!memcmp (vwin->window_title, "xine: ", 6) && !strcmp (vwin->window_title + 6, mrl))
2464 return;
2465 memcpy (vwin->window_title, "xine: ", 6);
2466 strlcpy (vwin->window_title + 6, mrl, sizeof (vwin->window_title) - 6);
2467 vwin->gui->x_lock_display (vwin->gui->video_display);
2468 _set_window_title (vwin);
2469 vwin->gui->x_unlock_display (vwin->gui->video_display);
2470 }
2471
video_window_toggle_border(xui_vwin_t * vwin)2472 void video_window_toggle_border (xui_vwin_t *vwin) {
2473 if (!vwin)
2474 return;
2475
2476 if (!vwin->gui->use_root_window && (vwin->fullscreen_mode & WINDOWED_MODE)) {
2477 Atom prop;
2478 MWMHints mwmhints;
2479 XClassHint *xclasshint;
2480
2481 vwin->borderless = !vwin->borderless;
2482
2483 vwin->gui->x_lock_display (vwin->gui->video_display);
2484
2485 memset(&mwmhints, 0, sizeof(mwmhints));
2486 prop = XInternAtom (vwin->gui->video_display, "_MOTIF_WM_HINTS", False);
2487 mwmhints.flags = MWM_HINTS_DECORATIONS;
2488 mwmhints.decorations = vwin->borderless ? 0 : 1;
2489 xclasshint = vwin->borderless ? vwin->xclasshint_borderless : vwin->xclasshint;
2490
2491 XChangeProperty (vwin->gui->video_display, vwin->gui->video_window, prop, prop, 32,
2492 PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS);
2493
2494 if(xclasshint != NULL)
2495 XSetClassHint (vwin->gui->video_display, vwin->gui->video_window, xclasshint);
2496
2497 vwin->gui->x_unlock_display (vwin->gui->video_display);
2498
2499 xine_port_send_gui_data (vwin->gui->vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void *)vwin->gui->video_window);
2500 }
2501 }
2502
2503