1 /***************************************************************** 2 * gmerlin - a general purpose multimedia framework and applications 3 * 4 * Copyright (c) 2001 - 2011 Members of the Gmerlin project 5 * gmerlin-general@lists.sourceforge.net 6 * http://gmerlin.sourceforge.net 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * *****************************************************************/ 21 22 #include <config.h> 23 24 #include <X11/Xlib.h> 25 #include <X11/Xutil.h> 26 27 #ifdef HAVE_LIBXINERAMA 28 #include <X11/extensions/Xinerama.h> 29 #endif 30 31 #ifdef HAVE_XDPMS 32 #include <X11/extensions/dpms.h> 33 #endif 34 35 #define SCREENSAVER_MODE_XLIB 0 // MUST be 0 (fallback) 36 #define SCREENSAVER_MODE_GNOME 1 37 #define SCREENSAVER_MODE_KDE 2 38 #define SCREENSAVER_MODE_XTEST 3 39 40 #ifdef HAVE_GLX 41 #include <GL/glx.h> 42 #endif 43 44 #include <X11/extensions/XShm.h> 45 46 /* Screensaver module */ 47 48 typedef struct 49 { 50 Display * dpy; 51 int mode; 52 int disabled; 53 int was_enabled; 54 int saved_timeout; 55 int64_t last_ping_time; 56 57 int fake_motion; 58 59 gavl_timer_t * timer; 60 61 #ifdef HAVE_XDPMS 62 int dpms_disabled; 63 #endif 64 } bg_x11_screensaver_t; 65 66 void 67 bg_x11_screensaver_init(bg_x11_screensaver_t *, Display * dpy); 68 69 void 70 bg_x11_screensaver_enable(bg_x11_screensaver_t *); 71 72 void 73 bg_x11_screensaver_disable(bg_x11_screensaver_t *); 74 75 void 76 bg_x11_screensaver_ping(bg_x11_screensaver_t *); 77 78 void 79 bg_x11_screensaver_cleanup(bg_x11_screensaver_t *); 80 81 82 typedef struct video_driver_s video_driver_t; 83 84 #define DRIVER_FLAG_BRIGHTNESS (1<<0) 85 #define DRIVER_FLAG_SATURATION (1<<1) 86 #define DRIVER_FLAG_CONTRAST (1<<2) 87 88 typedef struct 89 { 90 int flags; 91 const video_driver_t * driver; 92 gavl_pixelformat_t * pixelformats; 93 void * priv; 94 int can_scale; 95 bg_x11_window_t * win; 96 97 /* Selected pixelformat (used by the core only) */ 98 gavl_pixelformat_t pixelformat; 99 int penalty; 100 } driver_data_t; 101 102 extern const video_driver_t ximage_driver; 103 104 #ifdef HAVE_LIBXV 105 extern const video_driver_t xv_driver; 106 #endif 107 108 #ifdef HAVE_GLX 109 extern const video_driver_t gl_driver; 110 #endif 111 112 #define MAX_DRIVERS 3 113 114 struct video_driver_s 115 { 116 const char * name; 117 118 int can_scale; 119 int (*init)(driver_data_t* data); 120 int (*open)(driver_data_t* data); 121 122 void (*add_overlay_stream)(driver_data_t* data); 123 void (*set_overlay)(driver_data_t* data, int stream, gavl_overlay_t * ovl); 124 125 gavl_video_frame_t * (*create_overlay)(driver_data_t* data, int stream); 126 void (*destroy_overlay)(driver_data_t* data, int stream, gavl_video_frame_t*); 127 128 gavl_video_frame_t * (*create_frame)(driver_data_t* data); 129 130 void (*destroy_frame)(driver_data_t* data, gavl_video_frame_t *); 131 132 void (*put_frame)(driver_data_t* data, 133 gavl_video_frame_t * frame); 134 135 void (*set_brightness)(driver_data_t* data,float brightness); 136 void (*set_saturation)(driver_data_t* data,float saturation); 137 void (*set_contrast)(driver_data_t* data,float contrast); 138 139 void (*close)(driver_data_t* data); 140 void (*cleanup)(driver_data_t* data); 141 }; 142 143 /* 144 * We have 2 windows: One normal window and one 145 * fullscreen window. We optionally talk to both the 146 * children and parents through the XEmbed protocol 147 */ 148 149 typedef struct 150 { 151 Window win; /* Actual window */ 152 Window parent; /* Parent (if non-root we are embedded) */ 153 Window child; /* Child window */ 154 155 /* Toplevel window we are inside (e.g. window manager decoration) */ 156 Window toplevel; 157 158 /* Subwindow (created with another visual than the default) */ 159 Window subwin; 160 161 Window focus_child; /* Focus proxy */ 162 #ifdef HAVE_GLX 163 GLXWindow glx_win; 164 #endif 165 int parent_xembed; 166 int child_xembed; 167 int mapped; 168 int fullscreen; 169 bg_accelerator_map_t * child_accel_map; 170 int modality; 171 } window_t; 172 173 struct bg_x11_window_s 174 { 175 /* User settable stuff (initialized before x11_window_create) */ 176 177 int min_width; 178 int min_height; 179 180 #ifdef HAVE_LIBXINERAMA 181 XineramaScreenInfo *xinerama; 182 int nxinerama; 183 #endif 184 185 unsigned long black; 186 Display * dpy; 187 GC gc; 188 189 int is_fullscreen; 190 191 window_t normal; 192 window_t fullscreen; 193 window_t * current; 194 195 Window root; 196 int window_width, window_height; 197 198 int normal_width, normal_height; 199 int screen; 200 int window_x, window_y; 201 202 /* Event types (set by x11_window_handle_event()) */ 203 204 int do_delete; 205 206 /* Fullscreen stuff */ 207 208 int fullscreen_mode; 209 Pixmap fullscreen_cursor_pixmap; 210 Cursor fullscreen_cursor; 211 212 Atom WM_DELETE_WINDOW; 213 Atom WM_TAKE_FOCUS; 214 Atom _NET_SUPPORTED; 215 Atom _NET_WM_STATE; 216 Atom _NET_WM_STATE_FULLSCREEN; 217 Atom _NET_WM_STATE_STAYS_ON_TOP; 218 Atom _NET_WM_STATE_ABOVE; 219 Atom _NET_MOVERESIZE_WINDOW; 220 Atom WIN_PROTOCOLS; 221 Atom WM_PROTOCOLS; 222 Atom WIN_LAYER; 223 Atom _XEMBED_INFO; 224 Atom _XEMBED; 225 Atom STRING; 226 Atom WM_CLASS; 227 228 /* For hiding the mouse pointer */ 229 int idle_counter; 230 int pointer_hidden; 231 232 /* Screensaver stuff */ 233 234 int disable_screensaver_normal; 235 int disable_screensaver_fullscreen; 236 237 char * display_string_parent; 238 char * display_string_child; 239 240 int auto_resize; 241 242 Colormap colormap; 243 Colormap sub_colormap; 244 245 bg_x11_window_callbacks_t * callbacks; 246 247 Visual * visual; 248 int depth; 249 250 /* OpenGL stuff */ 251 #ifdef HAVE_GLX 252 GLXContext glxcontext; 253 254 GLXFBConfig * gl_fbconfigs; 255 256 struct 257 { 258 int value; 259 int changed; 260 } gl_attributes[BG_GL_ATTRIBUTE_NUM]; 261 262 float background_color[3]; 263 #endif 264 265 /* XShm */ 266 267 int have_shm; 268 int shm_completion_type; 269 int wait_for_completion; 270 271 gavl_video_format_t video_format; 272 int video_open; 273 274 /* Scaling stuff */ 275 gavl_video_format_t window_format; 276 gavl_video_frame_t * window_frame; 277 gavl_video_scaler_t * scaler; 278 int do_sw_scale; 279 int scaler_options_changed; 280 281 gavl_rectangle_f_t src_rect; 282 gavl_rectangle_i_t dst_rect; 283 284 driver_data_t drivers[MAX_DRIVERS]; 285 286 driver_data_t * current_driver; 287 288 int drivers_initialized; 289 290 /* For asynchronous focus grabbing */ 291 int need_focus; 292 Time focus_time; 293 294 int need_fullscreen; 295 296 int force_hw_scale; 297 298 /* Overlay stuff */ 299 int num_overlay_streams; 300 301 int has_overlay; /* 1 if there are overlays to blend, 0 else */ 302 303 struct 304 { 305 gavl_overlay_t * ovl; 306 unsigned long texture; /* For OpenGL only */ 307 gavl_video_format_t format; 308 } * overlay_streams; 309 310 float brightness; 311 float saturation; 312 float contrast; 313 314 gavl_video_frame_t * still_frame; 315 int still_mode; 316 317 Pixmap icon; 318 Pixmap icon_mask; 319 320 /* Screensaver */ 321 bg_x11_screensaver_t scr; 322 323 }; 324 325 void bg_x11_window_put_frame_internal(bg_x11_window_t * win, 326 gavl_video_frame_t * frame); 327 328 /* Private functions */ 329 330 void bg_x11_window_handle_event(bg_x11_window_t * win, XEvent * evt); 331 void bg_x11_window_ping_screensaver(bg_x11_window_t * w); 332 void bg_x11_window_get_coords(Display * dpy, 333 Window win, 334 int * x, int * y, int * width, 335 int * height); 336 void bg_x11_window_init(bg_x11_window_t * w); 337 338 gavl_pixelformat_t 339 bg_x11_window_get_pixelformat(Display * dpy, Visual * visual, int depth); 340 341 void bg_x11_window_make_icon(bg_x11_window_t * win, 342 const gavl_video_frame_t * icon, 343 const gavl_video_format_t * icon_format, 344 Pixmap * icon_ret, Pixmap * mask_ret); 345 346 347 int bg_x11_window_check_shm(Display * dpy, int * completion_type); 348 349 int bg_x11_window_create_shm(bg_x11_window_t * w, 350 XShmSegmentInfo * shminfo, int size); 351 352 void bg_x11_window_destroy_shm(bg_x11_window_t * w, 353 XShmSegmentInfo * shminfo); 354 355 void bg_x11_window_size_changed(bg_x11_window_t * w); 356 357 void bg_x11_window_cleanup_video(bg_x11_window_t * w); 358 359 Window bg_x11_window_get_toplevel(bg_x11_window_t * w, Window win); 360 361 void bg_x11_window_send_xembed_message(bg_x11_window_t * w, Window win, long time, 362 int type, int detail, int data1, int data2); 363 364 void bg_x11_window_embed_parent(bg_x11_window_t * win, 365 window_t * w); 366 void bg_x11_window_embed_child(bg_x11_window_t * win, 367 window_t * w); 368 369 int bg_x11_window_check_embed_property(bg_x11_window_t * win, 370 window_t * w); 371 372 void bg_x11_window_set_fullscreen_mapped(bg_x11_window_t * win, 373 window_t * w); 374 375 void 376 bg_x11_window_set_netwm_state(Display * dpy, Window win, Window root, int action, Atom state); 377 378 379 void bg_x11_window_create_subwins(bg_x11_window_t * w, 380 int depth, Visual * v); 381 382 void bg_x11_window_destroy_subwins(bg_x11_window_t * w); 383 384 /* For OpenGL support */ 385 386 int bg_x11_window_init_gl(bg_x11_window_t *); 387 388 #define XEMBED_MAPPED (1 << 0) 389 390 /* XEMBED messages */ 391 #define XEMBED_EMBEDDED_NOTIFY 0 392 #define XEMBED_WINDOW_ACTIVATE 1 393 #define XEMBED_WINDOW_DEACTIVATE 2 394 #define XEMBED_REQUEST_FOCUS 3 395 #define XEMBED_FOCUS_IN 4 396 #define XEMBED_FOCUS_OUT 5 397 #define XEMBED_FOCUS_NEXT 6 398 #define XEMBED_FOCUS_PREV 7 399 /* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */ 400 #define XEMBED_MODALITY_ON 10 401 #define XEMBED_MODALITY_OFF 11 402 #define XEMBED_REGISTER_ACCELERATOR 12 403 #define XEMBED_UNREGISTER_ACCELERATOR 13 404 #define XEMBED_ACTIVATE_ACCELERATOR 14 405 406 /* Modifiers field for XEMBED_REGISTER_ACCELERATOR */ 407 #define XEMBED_MODIFIER_SHIFT (1 << 0) 408 #define XEMBED_MODIFIER_CONTROL (1 << 1) 409 #define XEMBED_MODIFIER_ALT (1 << 2) 410 #define XEMBED_MODIFIER_SUPER (1 << 3) 411 #define XEMBED_MODIFIER_HYPER (1 << 4) 412 413