sinek/src gtkxine_x11.c,NONE,1.1
[email protected] Mon, 17 Feb 2003 00:45:14 -0800
| Newsgroups | gmane.comp.video.sinek.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/sinek/sinek/src In directory sc8-pr-cvs1:/tmp/cvs-serv31002/src Added Files: gtkxine_x11.c Log Message: x11-specific stuff for gtkxine, broken out into its own file --- NEW FILE: gtkxine_x11.c --- /* ** Sinek (Media Player) ** Copyright (c) 2002 Andres Salomon <[email protected]> ** ** This code is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License. ** ** $Id: gtkxine_x11.c,v 1.1 2003/02/17 08:45:12 dilinger Exp $ */ #include "gtkxine.h" #include "gtkxine_x11.h" #include <X11/Xlib.h> #include <X11/extensions/XTest.h> #include <X11/extensions/XShm.h> #include <X11/keysym.h> #include <gdk/gdkx.h> #include <pthread.h> #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "i18n.h" struct gtk_xine_x11_visual_t { x11_visual_t vis; pthread_t event_thread; int complete; /* screensaver stuff */ int keycode; int have_xtest, disabled, timeout, interval; int prefer_blanking, allow_exposures; }; static void frame_output_cb (void *user_data, int vid_w, int vid_h, double vidp_aspect, int *dest_x, int *dest_y, int *dest_w, int *dest_h, double *dest_vidp_aspect, int *win_x, int *win_y) { GtkWidget *widget = (GtkWidget *) user_data; *win_x = widget->allocation.x; *win_y = widget->allocation.y; *dest_x = 0; *dest_y = 0; *dest_w = widget->allocation.width; *dest_h = widget->allocation.height; *dest_vidp_aspect = vidp_aspect; } static void dest_size_cb (void *user_data, int vid_w, int vid_h, double vidp_aspect, int *dest_w, int *dest_h, double *dest_vidp_aspect) { GtkWidget *widget = (GtkWidget *) user_data; *dest_w = widget->allocation.width; *dest_h = widget->allocation.height; *dest_vidp_aspect = vidp_aspect; } static int translate_point (GtkXine *xine, int x, int y, int *vid_x, int *vid_y) { x11_rectangle_t rect; rect.x = x; rect.y = y; rect.w = 0; rect.h = 0; if (xine_gui_send_vo_data (xine->stream, XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO, (void *) &rect) != -1) { *vid_x = rect.x; *vid_y = rect.y; return 1; } return 0; } static int send_input_event (GtkXine *xine, XEvent *ev) { xine_event_t xine_event; xine_input_data_t xine_data; int x, y, ret = 0; switch (ev->type) { case MotionNotify: if (translate_point (xine, ((XMotionEvent *) ev)->x, ((XMotionEvent *) ev)->y, &x, &y)) { xine_event.type = XINE_EVENT_INPUT_MOUSE_MOVE; xine_data.button = 0; ret = 1; } break; case ButtonPress: if (((XButtonEvent *) ev)->button == 1 && translate_point (xine, ((XButtonEvent *) ev)->x, ((XButtonEvent *) ev)->y, &x, &y)) { xine_event.type = XINE_EVENT_INPUT_MOUSE_BUTTON; xine_data.button = 1; ret = 1; } break; } if (ret) { xine_event.stream = xine->stream; xine_event.data = (void *) &xine_data; xine_data.event = xine_event; xine_data.x = x; xine_data.y = y; xine_event_send (xine->stream, &xine_event); } return ret; } static void gtk_xine_event_handler (GtkXine *xine, XEvent *ev) { if (ev->type == ((struct gtk_xine_x11_visual_t *) xine->video_driver_data)->complete) { xine_gui_send_vo_data (xine->stream, XINE_GUI_SEND_COMPLETION_EVENT, ev); return; } switch (ev->type) { case MotionNotify: case ButtonPress: case KeyPress: send_input_event (xine, ev); break; case Expose: xine_gui_send_vo_data (xine->stream, XINE_GUI_SEND_EXPOSE_EVENT, (void *) ev); break; } } static void *gtk_xine_input_thread (void *data) { GtkXine *xine = GTK_XINE (data); x11_visual_t *vis = (x11_visual_t *) xine->video_driver_data; XEvent xev; pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); while (xine->video_driver_data) { XNextEvent (vis->display, &xev); gtk_xine_event_handler ((GtkXine *) data, &xev); } return NULL; } #if HAVE_XTEST static gboolean fake_event (gpointer data) { struct gtk_xine_x11_visual_t *vis = (struct gtk_xine_x11_visual_t *) ((GtkXine *) data)->video_driver_data; if (vis->disabled) { XTestFakeKeyEvent (vis->vis.display, vis->keycode, True, CurrentTime); XTestFakeKeyEvent (vis->vis.display, vis->keycode, False, CurrentTime); } return TRUE; } #endif static void gtk_xine_x11_scrsaver_init (GtkXine *xine) { struct gtk_xine_x11_visual_t *vis = (struct gtk_xine_x11_visual_t *) xine->video_driver_data; #if HAVE_XTEST int a, b, c, d; vis->have_xtest = XTestQueryExtension (vis->vis.display, &a, &b, &c, &d); if (vis->have_xtest) { vis->keycode = XKeysymToKeycode (vis->vis.display, XK_Shift_L); g_timeout_add (15000, (GSourceFunc) fake_event, xine); } #else vis->have_xtest = 0; #endif } void gtk_xine_x11_video_init (GtkXine *xine) { struct gtk_xine_x11_visual_t *gvis; x11_visual_t *vis; g_return_if_fail (xine != NULL); if (!XInitThreads ()) g_error (_("XInitThreads() failed, your X library is not thread-safe!")); if (!g_thread_supported ()) g_thread_init (NULL); gvis = g_malloc (sizeof (*gvis)); xine->video_driver_data = (void *) gvis; vis = (x11_visual_t *) gvis; vis->display = XOpenDisplay (NULL); XLockDisplay (vis->display); vis->screen = DefaultScreen (vis->display); vis->d = GDK_WINDOW_XID (GTK_WIDGET (xine)->window); vis->user_data = (void *) xine; vis->dest_size_cb = dest_size_cb; vis->frame_output_cb = frame_output_cb; gvis->complete = 0; if (XShmQueryExtension (vis->display)) gvis->complete = XShmGetEventBase (vis->display) + ShmCompletion; XSelectInput (vis->display, vis->d, StructureNotifyMask | ExposureMask | ButtonPressMask | PointerMotionMask | KeyPressMask); gtk_xine_x11_scrsaver_init (xine); XUnlockDisplay (vis->display); pthread_create (&gvis->event_thread, NULL, gtk_xine_input_thread, (void *) xine); } void gtk_xine_x11_video_finalize (GtkXine *xine) { pthread_t thr; g_return_if_fail (xine != NULL); thr = ((struct gtk_xine_x11_visual_t *) xine->video_driver_data)->event_thread; g_free (xine->video_driver_data); xine->video_driver_data = NULL; pthread_cancel (thr); pthread_join (thr, NULL); } int gtk_xine_x11_video_scrsaver_set (GtkXine *xine, gboolean enable) { struct gtk_xine_x11_visual_t *vis = (struct gtk_xine_x11_visual_t *) xine->video_driver_data; if (enable && vis->disabled) { if (!vis->have_xtest) XSetScreenSaver (vis->vis.display, vis->timeout, vis->interval, vis->prefer_blanking, vis->allow_exposures); vis->disabled = 0; } else if (!enable && !vis->disabled) { if (!vis->have_xtest) { XGetScreenSaver (vis->vis.display, &vis->timeout, &vis->interval, &vis->prefer_blanking, &vis->allow_exposures); XSetScreenSaver (vis->vis.display, 0, 0, DontPreferBlanking, DontAllowExposures); } vis->disabled = 1; } return enable; } int gtk_xine_x11_video_visual_type (GtkXine *xine) { return XINE_VISUAL_TYPE_X11; } ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf