Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Diff of /src/gtkvideo.c [3d5e16] .. [4ef159] Maximize Restore

  Switch to side-by-side view

--- a/src/gtkvideo.c
+++ b/src/gtkvideo.c
@@ -38,6 +38,7 @@
 #include <sys/types.h>
 #include <pthread.h>
 #include <sched.h>
+#include <sys/time.h>
 
 #include <X11/Xlib.h>
 #include <X11/keysym.h>
@@ -169,12 +170,18 @@
   gboolean		   idle_resized:8;
   gboolean		   hinted:8;
 
-  /* fullscreen stuff */
+  /* fullscreen & pointer stuff */
 
   gboolean		   fullscreen_mode:8, pointer_visible:8;
   GtkRequisition	   fullscreen;
-  Cursor                   pointer[2];
-  guint			   pointer_hide_timeout, screen_blanker_timeout;
+  Cursor		   pointer[3];
+  int			   pointer_shape;
+  struct {
+    struct timeval	   time;
+    gboolean		   in:8;
+  }			   spu;
+  guint			   pointer_hide_timeout;
+  guint			   screen_blanker_timeout;
   guint			   unblock_timeout;
 
   gint			   screen_signal;
@@ -423,9 +430,10 @@
 static void gtv_set_pointer (GtkVideo *gtv, gboolean state)
 {
   Display *display = gtv_get_xdisplay (gtv);
+  XLockDisplay (display);
   gtv->priv->pointer_visible = state;
-  XLockDisplay (display);
-  XDefineCursor (display, gtv->priv->video_window, gtv->priv->pointer[!!state]);
+  XDefineCursor (display, gtv->priv->video_window,
+		 gtv->priv->pointer[state ? gtv->priv->pointer_shape : 0]);
   XFlush (display);
   XUnlockDisplay (display);
 }
@@ -434,6 +442,12 @@
 {
   gtv->priv->pointer_hide_timeout = 0;
   gtv_set_pointer (gtv, FALSE);
+  return FALSE;
+}
+
+static gboolean gtv_set_pointer_cb (GtkVideo *gtv)
+{
+  gtv_set_pointer (gtv, gtv->priv->pointer_visible);
   return FALSE;
 }
 
@@ -458,6 +472,12 @@
     gtv->priv->pointer_hide_timeout = 0;
   }
   gtv_set_pointer (gtv, FALSE);
+}
+
+static void gtv_set_pointer_shape (GtkVideo *gtv, int shape)
+{
+  gtv->priv->pointer_shape = shape + 1;
+  g_idle_add ((GSourceFunc)gtv_set_pointer_cb, gtv);
 }
 
 #ifdef HAVE_XTESTEXTENSION
@@ -902,6 +922,33 @@
   return priv->video_port->get_capabilities (priv->video_port);
 }
 
+static inline double mkdtime (const struct timeval *tv)
+{
+  return tv->tv_sec + tv->tv_usec / 1000000.0;
+}
+
+gboolean gtk_video_in_spu_button (GtkVideo *gtv, int dir)
+{
+  gtk_video_private_t *priv = gtv->priv;
+
+  if (dir >= 0)
+  {
+    priv->spu.in = !!dir;
+    gtv_set_pointer_shape (gtv, !!dir);
+    if (dir)
+      gettimeofday (&priv->spu.time, NULL);
+  }
+
+  if (priv->spu.in)
+    return TRUE;
+
+  /* timeout of 1s from when a button is entered */
+  struct timeval now;
+  gettimeofday (&now, NULL);
+
+  return mkdtime (&now) - mkdtime (&priv->spu.time) <= 1.0;
+}
+
 static void gtv_send_xine_mouse_event (gtk_video_private_t *priv,
 				       int x, int y, int button)
 {
@@ -1001,7 +1048,7 @@
       if (xev->xbutton.state & ShiftMask)
 	priv->button_event_shifted |= 1 << xev->xbutton.button;
     }
-    return GDK_FILTER_REMOVE;
+    return gtk_video_in_spu_button (gtv, -1) ? GDK_FILTER_REMOVE : GDK_FILTER_CONTINUE;
 
   case ButtonRelease:
     /* permit the GTK event if allowed *and* Shift wasn't pressed when
@@ -1320,6 +1367,7 @@
   priv->pointer[0] = XCreatePixmapCursor (xdisplay, bm_no, bm_no,
 					  &black_pixel, &black_pixel, 0, 0);
   priv->pointer[1] = XCreateFontCursor (xdisplay, XC_left_ptr);
+  priv->pointer[2] = XCreateFontCursor (xdisplay, XC_hand1);
   priv->pointer_visible = TRUE;
   XUnlockDisplay (xdisplay);
 
@@ -1644,6 +1692,16 @@
 
     priv->fullscreen_mode = FALSE;
   }
+/* pointer motion will take care of this
+  struct {
+    Window root, child;
+    int rx, ry, x, y, mask;
+  } pos;
+  XQueryPointer (display, GDK_WINDOW_XWINDOW (gtv->widget.window),
+		 &pos.root, &pos.child, &pos.rx, &pos.ry,
+		 &pos.x, &pos.y, &pos.mask);
+  gtv_send_xine_mouse_event (priv, pos.x, pos.y, 0);
+*/
 
   XUnlockDisplay (display);
   g_static_rec_mutex_unlock (&engine_lock);