Lot of small fixes.
authorJulien Moutte <julien@moutte.net>
Mon, 17 Nov 2003 16:32:29 +0000 (16:32 +0000)
committerJulien Moutte <julien@moutte.net>
Mon, 17 Nov 2003 16:32:29 +0000 (16:32 +0000)
Original commit message from CVS:
Lot of small fixes.
Implemented XOverlay interface.

sys/ximage/ximagesink.c
sys/ximage/ximagesink.h
sys/xvimage/xvimagesink.c
sys/xvimage/xvimagesink.h

index 9b60baa..94a7a9b 100644 (file)
@@ -56,63 +56,6 @@ static GstElementClass *parent_class = NULL;
 /*                                                               */
 /* ============================================================= */
 
-/* Interfaces stuff */
-
-static gboolean
-gst_ximagesink_interface_supported (GstInterface *iface, GType type)
-{
-  g_assert (type == GST_TYPE_NAVIGATION ||
-           type == GST_TYPE_X_OVERLAY);
-
-  return (GST_STATE (iface) != GST_STATE_NULL);
-}
-
-static void
-gst_ximagesink_interface_init (GstInterfaceClass *klass)
-{
-  klass->supported = gst_ximagesink_interface_supported;
-}
-
-static void
-gst_ximagesink_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
-{
-  GstXImageSink *ximagesink = GST_XIMAGESINK (navigation);
-  GstEvent *event;
-  gint x_offset, y_offset;
-  double x,y;
-  
-  event = gst_event_new (GST_EVENT_NAVIGATION);
-  event->event_data.structure.structure = structure;
-
-  /* We are not converting the pointer coordinates as there's no hardware 
-     scaling done here. The only possible scaling is done by videoscale and
-     videoscale will have to catch those events and tranform the coordinates
-     to match the applied scaling. So here we just add the offset if the image
-     is centered in the window.  */
-  
-  x_offset = ximagesink->xwindow->width - ximagesink->width;
-  y_offset = ximagesink->xwindow->height - ximagesink->height;
-  
-  if (gst_structure_get_double (structure, "pointer_x", &x))
-    {
-      x += x_offset;
-      gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
-    }
-  if (gst_structure_get_double (structure, "pointer_y", &y))
-    {
-      y += y_offset;
-      gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
-    }
-    
-  gst_pad_send_event (gst_pad_get_peer (ximagesink->sinkpad), event);
-}
-
-static void
-gst_ximagesink_navigation_init (GstNavigationInterface *iface)
-{
-  iface->send_event = gst_ximagesink_navigation_send_event;
-}
-
 /* X11 stuff */
 
 /* This function handles GstXImage creation depending on XShm availability */
@@ -281,7 +224,6 @@ static GstXWindow *
 gst_ximagesink_xwindow_new (GstXImageSink *ximagesink, gint width, gint height)
 {
   GstXWindow *xwindow = NULL;
-  XGCValues values;
   
   g_return_val_if_fail (ximagesink != NULL, NULL);
   g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), NULL);
@@ -290,6 +232,7 @@ gst_ximagesink_xwindow_new (GstXImageSink *ximagesink, gint width, gint height)
   
   xwindow->width = width;
   xwindow->height = height;
+  xwindow->internal = TRUE;
   
   g_mutex_lock (ximagesink->x_lock);
   
@@ -303,7 +246,7 @@ gst_ximagesink_xwindow_new (GstXImageSink *ximagesink, gint width, gint height)
                 KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
   
   xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
-                           xwindow->win, 0, &values);
+                           xwindow->win, 0, NULL);
   
   XMapRaised (ximagesink->xcontext->disp, xwindow->win);
   
@@ -322,7 +265,9 @@ gst_ximagesink_xwindow_destroy (GstXImageSink *ximagesink, GstXWindow *xwindow)
   
   g_mutex_lock (ximagesink->x_lock);
   
-  XDestroyWindow (ximagesink->xcontext->disp, xwindow->win);
+  /* If we did not create that window we just free the GC and let it live */
+  if (xwindow->internal)
+    XDestroyWindow (ximagesink->xcontext->disp, xwindow->win);
   
   XFreeGC (ximagesink->xcontext->disp, xwindow->gc);
   
@@ -331,22 +276,6 @@ gst_ximagesink_xwindow_destroy (GstXImageSink *ximagesink, GstXWindow *xwindow)
   g_free (xwindow);
 }
 
-/* This function resizes a GstXWindow */
-/*static void
-gst_ximagesink_xwindow_resize (GstXImageSink *ximagesink, GstXWindow  *xwindow,
-                               gint width, gint height)
-{
-  g_return_if_fail (xwindow != NULL);
-  g_return_if_fail (ximagesink != NULL);
-  g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
-  
-  g_mutex_lock (ximagesink->x_lock);
-  
-  XResizeWindow (ximagesink->xcontext->disp, xwindow->win, width, height);
-  
-  g_mutex_unlock (ximagesink->x_lock);
-} */
-
 /* This function handles XEvents that might be in the queue. It generates
    GstEvent that will be sent upstream in the pipeline to handle interactivity
    and navigation. It will also listen for configure events on the window to
@@ -420,6 +349,10 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad)
                                                             ximagesink->width,
                                                             ximagesink->height);
                       }
+                      
+                    gst_x_overlay_got_video_size (
+                                        GST_X_OVERLAY (ximagesink),
+                                        ximagesink->width, ximagesink->height);
                   }
               }
             break;
@@ -640,14 +573,6 @@ gst_ximagesink_sinkconnect (GstPad *pad, GstCaps *caps)
     ximagesink->xwindow = gst_ximagesink_xwindow_new (ximagesink,
                                                       ximagesink->width,
                                                       ximagesink->height);
-  else
-    { /* We resize our window only if size has changed, preventing us from
-         infinite loops with XConfigure events.
-      if ( (ximagesink->width != ximagesink->xwindow->width) ||
-           (ximagesink->height != ximagesink->xwindow->height) )
-        gst_ximagesink_xwindow_resize (ximagesink, ximagesink->xwindow,
-                                       ximagesink->width, ximagesink->height);*/
-    }
   
   if ( (ximagesink->ximage) &&
        ( (ximagesink->width != ximagesink->ximage->width) ||
@@ -664,6 +589,9 @@ gst_ximagesink_sinkconnect (GstPad *pad, GstCaps *caps)
                                                     ximagesink->width,
                                                     ximagesink->height);
   
+  gst_x_overlay_got_video_size (GST_X_OVERLAY (ximagesink),
+                                ximagesink->width, ximagesink->height);
+  
   return GST_PAD_LINK_OK;
 }
 
@@ -677,7 +605,8 @@ gst_ximagesink_change_state (GstElement *element)
   switch (GST_STATE_TRANSITION (element)) {
     case GST_STATE_NULL_TO_READY:
       /* Initializing the XContext */
-      ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink);
+      if (!ximagesink->xcontext)
+        ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink);
       if (!ximagesink->xcontext)
         return GST_STATE_FAILURE;
       break;
@@ -897,6 +826,111 @@ gst_ximagesink_get_bufferpool (GstPad *pad)
   return ximagesink->bufferpool;
 }
 
+/* Interfaces stuff */
+
+static gboolean
+gst_ximagesink_interface_supported (GstInterface *iface, GType type)
+{
+  g_assert (type == GST_TYPE_NAVIGATION || type == GST_TYPE_X_OVERLAY);
+  return TRUE;
+}
+
+static void
+gst_ximagesink_interface_init (GstInterfaceClass *klass)
+{
+  klass->supported = gst_ximagesink_interface_supported;
+}
+
+static void
+gst_ximagesink_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
+{
+  GstXImageSink *ximagesink = GST_XIMAGESINK (navigation);
+  GstEvent *event;
+  gint x_offset, y_offset;
+  double x,y;
+  
+  event = gst_event_new (GST_EVENT_NAVIGATION);
+  event->event_data.structure.structure = structure;
+
+  /* We are not converting the pointer coordinates as there's no hardware 
+     scaling done here. The only possible scaling is done by videoscale and
+     videoscale will have to catch those events and tranform the coordinates
+     to match the applied scaling. So here we just add the offset if the image
+     is centered in the window.  */
+  
+  x_offset = ximagesink->xwindow->width - ximagesink->width;
+  y_offset = ximagesink->xwindow->height - ximagesink->height;
+  
+  if (gst_structure_get_double (structure, "pointer_x", &x))
+    {
+      x += x_offset;
+      gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
+    }
+  if (gst_structure_get_double (structure, "pointer_y", &y))
+    {
+      y += y_offset;
+      gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
+    }
+    
+  gst_pad_send_event (gst_pad_get_peer (ximagesink->sinkpad), event);
+}
+
+static void
+gst_ximagesink_navigation_init (GstNavigationInterface *iface)
+{
+  iface->send_event = gst_ximagesink_navigation_send_event;
+}
+
+static void
+gst_ximagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
+{
+  GstXImageSink *ximagesink = GST_XIMAGESINK (overlay);
+  GstXWindow *xwindow = NULL;
+  XWindowAttributes attr;
+  
+  g_return_if_fail (ximagesink != NULL);
+  g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
+  
+  if (!ximagesink->xcontext)
+    {
+      ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink);
+    }
+  
+  if ( (ximagesink->xwindow) && (ximagesink->ximage) )
+    { /* If we are replacing a window we destroy pictures and window as they
+         are associated */
+      gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
+      gst_ximagesink_imagepool_clear (ximagesink);
+      gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow);
+    }
+    
+  xwindow = g_new0 (GstXWindow, 1);
+  
+  xwindow->win = xwindow_id;
+  
+  /* We get window geometry, set the event we want to receive, and create a GC */
+  g_mutex_lock (ximagesink->x_lock);
+  XGetWindowAttributes (ximagesink->xcontext->disp, xwindow->win, &attr);
+  xwindow->width = attr.width;
+  xwindow->height = attr.height;
+  xwindow->internal = FALSE;
+  XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
+                StructureNotifyMask | PointerMotionMask | KeyPressMask |
+                KeyReleaseMask /*| ButtonPressMask | ButtonReleaseMask*/);
+  
+  xwindow->gc = XCreateGC (ximagesink->xcontext->disp,
+                           xwindow->win, 0, NULL);
+  g_mutex_unlock (ximagesink->x_lock);
+    
+  ximagesink->xwindow = xwindow;
+}
+
+static void
+gst_ximagesink_xoverlay_init (GstXOverlayClass *iface)
+{
+  iface->set_xwindow_id = gst_ximagesink_set_xwindow_id;
+}
+
 /* =========================================== */
 /*                                             */
 /*              Init & Class init              */
@@ -1039,22 +1073,22 @@ gst_ximagesink_get_type (void)
         NULL,
         NULL,
       };
-      /*static const GInterfaceInfo xoverlay_info = {
+      static const GInterfaceInfo overlay_info = {
         (GInterfaceInitFunc) gst_ximagesink_xoverlay_init,
         NULL,
         NULL,
-      };*/
+      };
       
       ximagesink_type = g_type_register_static (GST_TYPE_ELEMENT,
                                                 "GstXImageSink",
                                                 &ximagesink_info, 0);
       
       g_type_add_interface_static (ximagesink_type, GST_TYPE_INTERFACE,
-        &iface_info);
+                                   &iface_info);
       g_type_add_interface_static (ximagesink_type, GST_TYPE_NAVIGATION,
-        &navigation_info);
-      /*g_type_add_interface_static (ximagesink_type, GST_TYPE_X_OVERLAY,
-        &xoverlay_info);*/
+                                   &navigation_info);
+      g_type_add_interface_static (ximagesink_type, GST_TYPE_X_OVERLAY,
+                                   &overlay_info);
     }
     
   return ximagesink_type;
index 45a3a19..69b372e 100644 (file)
@@ -86,6 +86,7 @@ struct _GstXContext {
 struct _GstXWindow {
   Window win;
   gint width, height;
+  gboolean internal;
   GC gc;
 };
 
index 828855a..deb6678 100644 (file)
@@ -60,56 +60,6 @@ static GstElementClass *parent_class = NULL;
 /*                                                               */
 /* ============================================================= */
 
-/* Interfaces stuff */
-
-static gboolean
-gst_xvimagesink_interface_supported (GstInterface *iface, GType type)
-{
-  g_assert (type == GST_TYPE_NAVIGATION ||
-           type == GST_TYPE_X_OVERLAY);
-
-  return (GST_STATE (iface) != GST_STATE_NULL);
-}
-
-static void
-gst_xvimagesink_interface_init (GstInterfaceClass *klass)
-{
-  klass->supported = gst_xvimagesink_interface_supported;
-}
-
-static void
-gst_xvimagesink_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
-{
-  GstXvImageSink *xvimagesink = GST_XVIMAGESINK (navigation);
-  GstEvent *event;
-  double x,y;
-
-  event = gst_event_new (GST_EVENT_NAVIGATION);
-  event->event_data.structure.structure = structure;
-  
-  /* Converting pointer coordinates to the non scaled geometry */
-  if (gst_structure_get_double (structure, "pointer_x", &x))
-    {
-      x *= xvimagesink->width;
-      x /= xvimagesink->xwindow->width;
-      gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
-    }
-  if (gst_structure_get_double (structure, "pointer_y", &y))
-    {
-      y *= xvimagesink->height;
-      y /= xvimagesink->xwindow->height;
-      gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
-    }
-
-  gst_pad_send_event (gst_pad_get_peer (xvimagesink->sinkpad), event);
-}
-
-static void
-gst_xvimagesink_navigation_init (GstNavigationInterface *iface)
-{
-  iface->send_event = gst_xvimagesink_navigation_send_event;
-}
-
 /* X11 stuff */
 
 /* This function handles GstXvImage creation depending on XShm availability */
@@ -293,6 +243,7 @@ gst_xvimagesink_xwindow_new (GstXvImageSink *xvimagesink,
   
   xwindow->width = width;
   xwindow->height = height;
+  xwindow->internal = TRUE;
   
   g_mutex_lock (xvimagesink->x_lock);
   
@@ -325,7 +276,9 @@ gst_xvimagesink_xwindow_destroy (GstXvImageSink *xvimagesink, GstXWindow *xwindo
   
   g_mutex_lock (xvimagesink->x_lock);
   
-  XDestroyWindow (xvimagesink->xcontext->disp, xwindow->win);
+  /* If we did not create that window we just free the GC and let it live */
+  if (xwindow->internal)
+    XDestroyWindow (xvimagesink->xcontext->disp, xwindow->win);
   
   XFreeGC (xvimagesink->xcontext->disp, xwindow->gc);
   
@@ -334,23 +287,6 @@ gst_xvimagesink_xwindow_destroy (GstXvImageSink *xvimagesink, GstXWindow *xwindo
   g_free (xwindow);
 }
 
-/* This function resizes a GstXWindow */
-/*static void
-gst_xvimagesink_xwindow_resize (GstXvImageSink *xvimagesink,
-                                GstXWindow  *xwindow,
-                                gint width, gint height)
-{
-  g_return_if_fail (xwindow != NULL);
-  g_return_if_fail (xvimagesink != NULL);
-  g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
-  
-  g_mutex_lock (xvimagesink->x_lock);
-  
-  XResizeWindow (xvimagesink->xcontext->disp, xwindow->win, width, height);
-  
-  g_mutex_unlock (xvimagesink->x_lock);
-} */
-
 /* This function handles XEvents that might be in the queue. It generates
    GstEvent that will be sent upstream in the pipeline to handle interactivity
    and navigation. It will also listen for configure events on the window to
@@ -709,14 +645,6 @@ gst_xvimagesink_sinkconnect (GstPad *pad, GstCaps *caps)
     xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink,
                                                       xvimagesink->width,
                                                       xvimagesink->height);
-  else
-    { /* We resize our window only if size has changed, preventing us from
-         infinite loops with XConfigure events.
-      if ( (xvimagesink->width != xvimagesink->xwindow->width) ||
-           (xvimagesink->height != xvimagesink->xwindow->height) )
-        gst_xvimagesink_xwindow_resize (xvimagesink, xvimagesink->xwindow,
-                                       xvimagesink->width, xvimagesink->height);*/
-    }
   
   if ( (xvimagesink->xvimage) &&
        ( (xvimagesink->width != xvimagesink->xvimage->width) ||
@@ -733,6 +661,9 @@ gst_xvimagesink_sinkconnect (GstPad *pad, GstCaps *caps)
                                                     xvimagesink->width,
                                                     xvimagesink->height);
   
+  gst_x_overlay_got_video_size (GST_X_OVERLAY (xvimagesink),
+                                xvimagesink->width, xvimagesink->height);
+  
   return GST_PAD_LINK_OK;
 }
 
@@ -746,7 +677,8 @@ gst_xvimagesink_change_state (GstElement *element)
   switch (GST_STATE_TRANSITION (element)) {
     case GST_STATE_NULL_TO_READY:
       /* Initializing the XContext */
-      xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
+      if (!xvimagesink->xcontext)
+        xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
       if (!xvimagesink->xcontext)
         return GST_STATE_FAILURE;
       break;
@@ -966,6 +898,104 @@ gst_xvimagesink_get_bufferpool (GstPad *pad)
   return xvimagesink->bufferpool;
 }
 
+/* Interfaces stuff */
+
+static gboolean
+gst_xvimagesink_interface_supported (GstInterface *iface, GType type)
+{
+  g_assert (type == GST_TYPE_NAVIGATION || type == GST_TYPE_X_OVERLAY);
+  return TRUE;
+}
+
+static void
+gst_xvimagesink_interface_init (GstInterfaceClass *klass)
+{
+  klass->supported = gst_xvimagesink_interface_supported;
+}
+
+static void
+gst_xvimagesink_navigation_send_event (GstNavigation *navigation, GstStructure *structure)
+{
+  GstXvImageSink *xvimagesink = GST_XVIMAGESINK (navigation);
+  GstEvent *event;
+  double x,y;
+
+  event = gst_event_new (GST_EVENT_NAVIGATION);
+  event->event_data.structure.structure = structure;
+  
+  /* Converting pointer coordinates to the non scaled geometry */
+  if (gst_structure_get_double (structure, "pointer_x", &x))
+    {
+      x *= xvimagesink->width;
+      x /= xvimagesink->xwindow->width;
+      gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
+    }
+  if (gst_structure_get_double (structure, "pointer_y", &y))
+    {
+      y *= xvimagesink->height;
+      y /= xvimagesink->xwindow->height;
+      gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
+    }
+
+  gst_pad_send_event (gst_pad_get_peer (xvimagesink->sinkpad), event);
+}
+
+static void
+gst_xvimagesink_navigation_init (GstNavigationInterface *iface)
+{
+  iface->send_event = gst_xvimagesink_navigation_send_event;
+}
+
+static void
+gst_xvimagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id)
+{
+  GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay);
+  GstXWindow *xwindow = NULL;
+  XWindowAttributes attr;
+  
+  g_return_if_fail (xvimagesink != NULL);
+  g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
+  
+  if (!xvimagesink->xcontext)
+    {
+      xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink);
+    }
+  
+  if ( (xvimagesink->xwindow) && (xvimagesink->xvimage) )
+    { /* If we are replacing a window we destroy pictures and window as they
+         are associated */
+      gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
+      gst_xvimagesink_imagepool_clear (xvimagesink);
+      gst_xvimagesink_xwindow_destroy (xvimagesink, xvimagesink->xwindow);
+    }
+    
+  xwindow = g_new0 (GstXWindow, 1);
+  
+  xwindow->win = xwindow_id;
+  
+  /* We get window geometry, set the event we want to receive, and create a GC */
+  g_mutex_lock (xvimagesink->x_lock);
+  XGetWindowAttributes (xvimagesink->xcontext->disp, xwindow->win, &attr);
+  xwindow->width = attr.width;
+  xwindow->height = attr.height;
+  xwindow->internal = FALSE;
+  XSelectInput (xvimagesink->xcontext->disp, xwindow->win, ExposureMask |
+                StructureNotifyMask | PointerMotionMask | KeyPressMask |
+                KeyReleaseMask /*| ButtonPressMask | ButtonReleaseMask*/);
+  
+  xwindow->gc = XCreateGC (xvimagesink->xcontext->disp,
+                           xwindow->win, 0, NULL);
+  g_mutex_unlock (xvimagesink->x_lock);
+    
+  xvimagesink->xwindow = xwindow;
+}
+
+static void
+gst_xvimagesink_xoverlay_init (GstXOverlayClass *iface)
+{
+  iface->set_xwindow_id = gst_xvimagesink_set_xwindow_id;
+}
+
 /* =========================================== */
 /*                                             */
 /*              Init & Class init              */
@@ -1108,22 +1138,22 @@ gst_xvimagesink_get_type (void)
         NULL,
         NULL,
       };
-      /*static const GInterfaceInfo xoverlay_info = {
+      static const GInterfaceInfo overlay_info = {
         (GInterfaceInitFunc) gst_xvimagesink_xoverlay_init,
         NULL,
         NULL,
-      };*/
+      };
       
       xvimagesink_type = g_type_register_static (GST_TYPE_ELEMENT,
                                                  "GstXvImageSink",
                                                  &xvimagesink_info, 0);
       
       g_type_add_interface_static (xvimagesink_type, GST_TYPE_INTERFACE,
-        &iface_info);
+                                   &iface_info);
       g_type_add_interface_static (xvimagesink_type, GST_TYPE_NAVIGATION,
-        &navigation_info);
-      /*g_type_add_interface_static (xvimagesink_type, GST_TYPE_X_OVERLAY,
-        &xoverlay_info);*/
+                                   &navigation_info);
+      g_type_add_interface_static (xvimagesink_type, GST_TYPE_X_OVERLAY,
+                                   &overlay_info);
     }
     
   return xvimagesink_type;
index 4296a0e..070f269 100644 (file)
@@ -94,6 +94,7 @@ struct _GstXContext {
 struct _GstXWindow {
   Window win;
   gint width, height;
+  gboolean internal;
   GC gc;
 };