From: Daniel Caujolle-B. <f1...@us...> - 2002-03-27 15:05:31
|
Update of /cvsroot/xine/toxine/src/plugins In directory usw-pr-cvs1:/tmp/cvs-serv21342/src/plugins Modified Files: Makefile.am vo_x11.c Log Message: (X11)Add screensaver handling, mouse pointer visiblity toggle. Add 3 pseudo xine events (none, forever, nothing). Deinit vo_plugin on quit. Index: Makefile.am =================================================================== RCS file: /cvsroot/xine/toxine/src/plugins/Makefile.am,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- Makefile.am 6 Feb 2002 01:34:04 -0000 1.1.1.1 +++ Makefile.am 27 Mar 2002 15:05:27 -0000 1.2 @@ -14,13 +14,14 @@ lib_LTLIBRARIES = $(aa_plugin) toxine_vo_plugin_x11.la -toxine_vo_plugin_x11_la_SOURCES = vo_x11.c -toxine_vo_plugin_x11_la_LDFLAGS = -avoid-version -module $(X_LIBS) -lX11 -lm -lXext $(X_EXTRA_LIBS) +toxine_vo_plugin_x11_la_SOURCES = vo_x11.c xscreensaver-remote.c +toxine_vo_plugin_x11_la_LDFLAGS = -avoid-version -module $(X_LIBS) $(DPMS_LIBS) \ + -lX11 -lm -lXext $(X_EXTRA_LIBS) toxine_vo_plugin_aa_la_SOURCES = vo_aa.c toxine_vo_plugin_aa_la_LDFLAGS = -avoid-version -module $(AALIB_LIBS) -lm -noinst_HEADERS = vo_plugin.h +noinst_HEADERS = vo_plugin.h xscreensaver-remote.h debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)" Index: vo_x11.c =================================================================== RCS file: /cvsroot/xine/toxine/src/plugins/vo_x11.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- vo_x11.c 25 Mar 2002 23:59:57 -0000 1.5 +++ vo_x11.c 27 Mar 2002 15:05:27 -0000 1.6 @@ -16,20 +16,32 @@ ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <math.h> #include <pthread.h> +#include <errno.h> +#include <sys/types.h> +#include <signal.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <X11/Xutil.h> +#include <X11/Xproto.h> #include <X11/keysym.h> +#include <X11/cursorfont.h> #include <X11/extensions/XShm.h> +#ifdef HAVE_DPMS +# include <X11/extensions/dpms.h> +#endif #include "common.h" +#include "xscreensaver-remote.h" #include <xine/video_out_x11.h> @@ -37,6 +49,8 @@ extern int XShmGetEventBase(Display *); #endif +extern int errno; + #define MWM_HINTS_DECORATIONS (1L << 1) #define PROP_MWM_HINTS_ELEMENTS 5 typedef struct { @@ -47,12 +61,39 @@ uint32_t status; } MWMHints; -#define WINDOW_MODE 0 -#define FULLSCREEN_MODE 1 +/* + * Screensavers parameters + */ +typedef struct { + /* XFree86 */ + struct { + int timeout; + int interval; + int prefer_blanking; + int allow_exposures; + } screensaver; + + /* Jamie's Zawinski xscreensaver */ + struct { + int was_running; + } xscreensaver; + +#ifdef HAVE_DPMS + /* XFree DPMS */ + struct { + int was_running; + CARD16 standby; + CARD16 suspend; + CARD16 off; + CARD16 level; + } xdpms; +#endif +} screen_savers_t; typedef struct { Window video_window; GC gc; + Atom XA_DELETE_WINDOW; int x; int y; int video_width; @@ -60,20 +101,20 @@ } x11_drawable_t; typedef struct { + Cursor cursors[2]; + int visible; +} cursors_t; + +typedef struct { Display *display; int fullscreen; x11_drawable_t x11_drawable[2]; - /* - Window video_window; - int x; - int y; - int video_width; - int video_height; - */ + + cursors_t cursor; int screen; - XColor black; + XColor black, white; int completion_event; Visual *visual; Colormap colormap; @@ -81,9 +122,182 @@ XWMHints *wm_hint; + screen_savers_t screen_savers; + pthread_t timed_thread; + } x11_private_t; +/* Cursor's bitmap datas */ +static unsigned char curs_no[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static unsigned char curs_yes[] = { + 0x00, 0x00, 0x0e, 0x70, 0xfa, 0x5f, 0x0e, 0x70, 0x0a, 0x50, 0x0e, 0x70, + 0x0a, 0x50, 0x0e, 0x70, 0xfa, 0x5f, 0x0e, 0x70, 0x0a, 0x50, 0x0e, 0x70, + 0x0a, 0x50, 0x0e, 0x70, 0xfa, 0x5f, 0x00, 0x00 +}; +static unsigned char curs_yes_bg[] = { + 0x1f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xf8, 0x1f, 0xf8, + 0x1f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xf8, 0x1f, 0xf8, + 0x1f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xdf +}; + +/* + * Update cursor apparence, reflected by cursor.visible value. + */ +static void update_cursor_visibility(toxine_t *tox) { + toxine_vo_plugin_t *vop = (toxine_vo_plugin_t *) tox->video.cur_plugin; + x11_private_t *private = (x11_private_t *) vop->private; + + XLockDisplay(private->display); + XDefineCursor(private->display, + private->x11_drawable[private->fullscreen].video_window, + private->cursor.cursors[private->cursor.visible]); + XFlush(private->display); + XUnlockDisplay(private->display); +} + +/* + * Thread that just hide the cursor pointer, each 2 secs, if needed. + */ +static void *timed_loop(void *data) { + toxine_t *tox = (toxine_t *) data; + toxine_vo_plugin_t *vop = (toxine_vo_plugin_t *) tox->video.cur_plugin; + x11_private_t *private = (x11_private_t *) vop->private; + + pthread_detach(pthread_self()); + + while(tox->running) { + + if(private->cursor.visible) { + private->cursor.visible = !private->cursor.visible; + update_cursor_visibility(tox); + } + + sleep(2); + } + + pthread_exit(NULL); +} + +/* + * Disable all screensaver. + */ +static void disable_screensavers(toxine_vo_plugin_t *vop) { + x11_private_t *private = (x11_private_t *) vop->private; + + XLockDisplay(private->display); + +#ifdef HAVE_DPMS + { /* XFree DPMS */ + + int dummy; + + private->screen_savers.xdpms.was_running = 0; + + if(DPMSQueryExtension(private->display, &dummy, &dummy)) { + BOOL enabled; + + DPMSInfo(private->display, &private->screen_savers.xdpms.level, &enabled); + + if(enabled) { + + if(DPMSGetTimeouts(private->display, + &private->screen_savers.xdpms.standby, + &private->screen_savers.xdpms.suspend, &private->screen_savers.xdpms.off) != True) { + fprintf(stderr, "DPMSGetTimeouts() failed\n"); + } + + /* monitor powersave off */ + (void) DPMSDisable(private->display); + private->screen_savers.xdpms.was_running = 1; + } + } + } +#endif + + /* XFree screensaver */ + XGetScreenSaver(private->display ,&private->screen_savers.screensaver.timeout, + &private->screen_savers.screensaver.interval, + &private->screen_savers.screensaver.prefer_blanking, + &private->screen_savers.screensaver.allow_exposures); + + if((XSetScreenSaver(private->display, 0, 0, + DontPreferBlanking, DontAllowExposures)) == BadValue) { + fprintf(stderr, "XSetScreenSaver() failed: %s\n", strerror(errno)); + } + + /* XScreenSaver specific. */ + xscreensaver_remote_init(private->display); + private->screen_savers.xscreensaver.was_running = is_xscreensaver_running(private->display); + + if(private->screen_savers.xscreensaver.was_running == 1) { + if(xscreensaver_kill_server(private->display) < 0) + private->screen_savers.xscreensaver.was_running = 0; + } + + XUnlockDisplay(private->display); +} + +/* + * Reenable previously disabled screensaver. + */ +static void reenable_screensavers(toxine_vo_plugin_t *vop) { + x11_private_t *private = (x11_private_t *) vop->private; + + XLockDisplay(private->display); + +#ifdef HAVE_DPMS + { /* XFree DPMS */ + + int dummy; + + if(private->screen_savers.xdpms.was_running) { + + if(DPMSQueryExtension(private->display, &dummy, &dummy)) { + + /* restoring power saving settings */ + if((DPMSEnable(private->display)) == True) { + CARD16 state; + BOOL enabled; + + (void) DPMSSetTimeouts(private->display, + private->screen_savers.xdpms.standby, + private->screen_savers.xdpms.suspend, + private->screen_savers.xdpms.off); + + (void) DPMSForceLevel(private->display, private->screen_savers.xdpms.level); + + /* DPMS does not seem to be enabled unless we call DPMSInfo */ + DPMSInfo(private->display, &state, &enabled); + + if(enabled) + private->screen_savers.xdpms.was_running = 0; + + } + } + } + } +#endif + + /* XFree screensaver */ + if((XSetScreenSaver(private->display, private->screen_savers.screensaver.timeout, + private->screen_savers.screensaver.interval, + private->screen_savers.screensaver.prefer_blanking, + private->screen_savers.screensaver.allow_exposures)) == BadValue) { + fprintf(stderr, "XSetScreenSaver() failed: %s\n", strerror(errno)); + } + + /* Restart XScreenSaver. */ + if(private->screen_savers.xscreensaver.was_running == 1) + xscreensaver_start_server(); + + XUnlockDisplay(private->display); +} +/* + * + */ static int video_window_translate_point(toxine_t *tox, toxine_vo_plugin_t *vop, int gui_x, int gui_y, int *video_x, int *video_y) { x11_private_t *private = (x11_private_t *) vop->private; @@ -140,8 +354,9 @@ return 1; } - - +/* + * + */ static void video_out_frame_output_cb(void *data, int video_width, int video_height, int *dest_x, int *dest_y, @@ -189,6 +404,9 @@ } +/* + * + */ static void video_out_dest_size_cb(void *data, int video_width, int video_height, int *dest_width, int *dest_height) { @@ -196,6 +414,9 @@ *dest_height = video_height; } +/* + * + */ static void video_out_select_visual (toxine_t *tox, toxine_vo_plugin_t *vop) { XVisualInfo *vinfo = (XVisualInfo *) -1; x11_private_t *private = (x11_private_t *) vop->private; @@ -216,18 +437,22 @@ XUnlockDisplay (private->display); } - +/* + * + */ static void video_window_init(toxine_t *tox, toxine_vo_plugin_t *vop) { + Pixmap cursor_no, cursor_yes, cursor_yes_bg; char *display_name = ":0.0"; XColor dummy; x11_private_t *private = (x11_private_t *) vop->private; static char *window_title = "toxine video output"; XSizeHints hint; XSetWindowAttributes attr; - Atom XA_DELETE_WINDOW, XA_NO_BORDER, XA_WIN_LAYER; + Atom XA_NO_BORDER, XA_WIN_LAYER; XEvent xev; XGCValues xgcv; MWMHints mwmhints; + XWMHints *wm_hint; long propvalue[1]; if(!XInitThreads()) { @@ -250,15 +475,15 @@ private->colormap = DefaultColormap(private->display, private->screen); private->depth = DefaultDepth(private->display, private->screen); - // private->colormap = XCreateColormap(private->display, - // RootWindow(private->display, private->screen), - // private->visual, AllocNone); - + video_out_select_visual(tox, vop); XAllocNamedColor(private->display, DefaultColormap(private->display, private->screen), "black", &private->black, &dummy); + XAllocNamedColor(private->display, + DefaultColormap(private->display, private->screen), + "white", &private->white, &dummy); private->wm_hint = XAllocWMHints(); if(!private->wm_hint) { @@ -342,7 +567,7 @@ XSetWMHints(private->display, private->x11_drawable[private->fullscreen].video_window, private->wm_hint); - /* Tell other applications about gGui window */ + /* Tell other applications about window */ XSetStandardProperties(private->display, private->x11_drawable[private->fullscreen].video_window, window_title, window_title, None, NULL, 0, 0); @@ -354,14 +579,26 @@ StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask); - XA_DELETE_WINDOW = XInternAtom(private->display, "WM_DELETE_WINDOW", False); + private->x11_drawable[private->fullscreen].XA_DELETE_WINDOW = + XInternAtom(private->display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(private->display, - private->x11_drawable[private->fullscreen].video_window, &XA_DELETE_WINDOW, 1); - + private->x11_drawable[private->fullscreen].video_window, + &private->x11_drawable[private->fullscreen].XA_DELETE_WINDOW, 1); + private->x11_drawable[private->fullscreen].gc = XCreateGC(private->display, private->x11_drawable[private->fullscreen].video_window, 0L, &xgcv); + wm_hint = XAllocWMHints(); + if (wm_hint != NULL) { + wm_hint->input = True; + wm_hint->flags = InputHint; + XSetWMHints(private->display, + private->x11_drawable[private->fullscreen].video_window, wm_hint); + XFree(wm_hint); + } + private->fullscreen++; } while(private->fullscreen < 2); @@ -369,7 +606,30 @@ /* Start in windowed mode. */ private->fullscreen = 0; + /* Create mouse cursors */ + cursor_no = XCreateBitmapFromData(private->display, + (DefaultRootWindow(private->display)), curs_no, 8, 8); + cursor_yes = XCreateBitmapFromData(private->display, + (DefaultRootWindow(private->display)), curs_yes, 16, 16); + cursor_yes_bg = XCreateBitmapFromData(private->display, + (DefaultRootWindow(private->display)), curs_yes_bg, 16, 16); + + private->cursor.cursors[0] = XCreatePixmapCursor(private->display, + cursor_no, cursor_no, + &private->black, &private->black, 0, 0); + private->cursor.cursors[1] = XCreatePixmapCursor(private->display, + cursor_yes, cursor_yes_bg, + &private->black, &private->white, 0, 0); + private->cursor.visible = 1; + update_cursor_visibility(tox); + + XFreePixmap(private->display, cursor_no); + XFreePixmap(private->display, cursor_yes); + XFreePixmap(private->display, cursor_yes_bg); + /* Map window. */ + XSetTransientForHint(private->display, + private->x11_drawable[private->fullscreen].video_window, None); XMapRaised(private->display, private->x11_drawable[private->fullscreen].video_window); /* Wait for map. */ @@ -388,13 +648,6 @@ GUI_DATA_EX_DRAWABLE_CHANGED, (void*)private->x11_drawable[private->fullscreen].video_window); - /* - XGrabKeyboard(private->display, private->video_window, - True, GrabModeASync, GrabModeASync, CurrentTime); - */ - - //XAllowEvents(private->display, AsyncBoth, CurrentTime); - { double res_h, res_v; x11_visual_t vis; @@ -421,8 +674,6 @@ vis.dest_size_cb = video_out_dest_size_cb; vis.frame_output_cb = video_out_frame_output_cb; - // vis.calc_dest_size = video_out_calc_dest_size; - // vis.request_dest_size = video_out_adapt_size; vis.user_data = (void *) tox; tox->video.driver = xine_load_video_output_plugin(tox->config, @@ -439,24 +690,38 @@ fprintf(stderr, "video driver '%s' successfuly loaded.\n", tox->video.name); } + + { + pthread_attr_t pth_attrs; + struct sched_param pth_params; + + pthread_attr_init(&pth_attrs); + pthread_attr_getschedparam(&pth_attrs, &pth_params); + pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER); + pthread_attr_setschedparam(&pth_attrs, &pth_params); + + pthread_create(&private->timed_thread, &pth_attrs, timed_loop, (void *)tox); + } + + disable_screensavers(vop); } +/* + * + */ static void init_video_out(toxine_t *tox, toxine_vo_plugin_t *vop) { video_window_init (tox, vop); } - +/* + * + */ static void video_window_handle_event(XEvent *xev, toxine_t *tox) { toxine_vo_plugin_t *vop = (toxine_vo_plugin_t *) tox->video.cur_plugin; x11_private_t *private = (x11_private_t *) vop->private; switch(xev->type) { - case DestroyNotify: - if(private->x11_drawable[private->fullscreen].video_window == xev->xany.window) - // gui_exit(NULL, NULL); - break; - case KeyPress: { XKeyEvent kevent; @@ -464,6 +729,11 @@ char kbuf[256]; int len; + if(!private->cursor.visible) { + private->cursor.visible = !private->cursor.visible; + update_cursor_visibility(tox); + } + kevent = xev->xkey; XLockDisplay(private->display); @@ -495,6 +765,11 @@ xine_input_event_t xine_event; int x, y; + if(!private->cursor.visible) { + private->cursor.visible = !private->cursor.visible; + update_cursor_visibility(tox); + } + /* printf("Mouse event:mx=%d my=%d\n",mevent->x, mevent->y); */ if((tox->xine) && (video_window_translate_point(tox, vop, mevent->x, mevent->y, &x, &y))) { @@ -512,6 +787,11 @@ xine_input_event_t xine_event; int x, y; + if(!private->cursor.visible) { + private->cursor.visible = !private->cursor.visible; + update_cursor_visibility(tox); + } + if(bevent->button == Button1) { if((tox->xine) && (video_window_translate_point(tox, vop, bevent->x, bevent->y, &x, &y))) { xine_event.event.type = XINE_EVENT_MOUSE_BUTTON; @@ -542,11 +822,6 @@ if(xev->xany.window == private->x11_drawable[private->fullscreen].video_window) { XConfigureEvent *cev = (XConfigureEvent *) xev; - /* - private->video_width = cev->width; - private->video_height = cev->height; - */ - private->x11_drawable[private->fullscreen].x = cev->x; private->x11_drawable[private->fullscreen].y = cev->y; @@ -562,6 +837,9 @@ } +/* + * + */ static void *event_loop(void *data) { toxine_t *tox = (toxine_t *) data; toxine_vo_plugin_t *vop = (toxine_vo_plugin_t *) tox->video.cur_plugin; @@ -570,39 +848,57 @@ pthread_detach(pthread_self()); - // XFlush(private->display); - //XSync(private->display, False); while (tox->running) { - // XLockDisplay(private->display); - XNextEvent (private->display, &myevent); - // pthread_testcancel(); - // XUnlockDisplay(private->display); + XNextEvent(private->display, &myevent); video_window_handle_event(&myevent, tox) ; } pthread_exit(NULL); } +/* + * + */ static void deinit_video_out(toxine_t *tox, toxine_vo_plugin_t *vop) { x11_private_t *private = (x11_private_t *) vop->private; XLockDisplay(private->display); + XUnmapWindow(private->display, private->x11_drawable[private->fullscreen].video_window); + XFreeGC(private->display, private->x11_drawable[private->fullscreen].gc); XDestroyWindow(private->display, private->x11_drawable[private->fullscreen].video_window); + private->fullscreen = !private->fullscreen; + + XFreeGC(private->display, private->x11_drawable[private->fullscreen].gc); XDestroyWindow(private->display, private->x11_drawable[private->fullscreen].video_window); + + XFreeCursor(private->display, private->cursor.cursors[0]); + XFreeCursor(private->display, private->cursor.cursors[1]); + XUnlockDisplay(private->display); + + reenable_screensavers(vop); } +/* + * + */ static char *get_identifier(void) { return "X11 video out"; } +/* + * + */ static char *_vo_x11_names[] = { "Xv", "XShm", NULL }; static char **get_names(void) { return _vo_x11_names; } +/* + * + */ static uint32_t get_capabilities(toxine_t *tox) { if(tox->video.driver) @@ -611,6 +907,9 @@ return 0; } +/* + * + */ static int get_property(toxine_t *tox, int property) { if(tox->video.driver) @@ -619,6 +918,9 @@ return 0; } +/* + * + */ static void get_property_min_max(toxine_t *tox, int property, int *min, int *max) { if(tox->video.driver) @@ -626,6 +928,9 @@ } +/* + * + */ static int set_property(toxine_t *tox, int property, int value) { if(tox->video.driver) @@ -634,6 +939,9 @@ return value; } +/* + * + */ static char *get_help(void) { return "Video out plugin supporting Xv and Xshm X11 drivers.\n" @@ -641,6 +949,9 @@ "\tf,F\t\tFullscreen toggle.\n"; } +/* + * + */ toxine_vo_plugin_t *toxine_load_vo_plugin(toxine_t *tox) { toxine_vo_plugin_t *x11; x11_private_t *private; @@ -662,6 +973,3 @@ return x11; } - - - |