• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * GStreamer
3  * Copyright (C) 2013 Matthew Waters <ystreet00@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 /**
22  * SECTION:gstgldisplay_wayland
23  * @short_description: Wayland display connection
24  * @title: GstGLDisplayWayland
25  * @see_also: #GstGLDisplay
26  *
27  * #GstGLDisplayWayland represents a connection to a Wayland `wl_display` handle
28  * created internally (gst_gl_display_wayland_new()) or wrapped by the application
29  * (gst_gl_display_wayland_new_with_display())
30  */
31 
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35 
36 #include "gstgldisplay_wayland.h"
37 
38 GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
39 #define GST_CAT_DEFAULT gst_gl_display_debug
40 
41 /* We can't define these in the public struct, or we'd break ABI */
42 typedef struct _GstGLDisplayWaylandPrivate
43 {
44   gint dummy;
45 } GstGLDisplayWaylandPrivate;
46 
47 G_DEFINE_TYPE_WITH_PRIVATE (GstGLDisplayWayland, gst_gl_display_wayland,
48     GST_TYPE_GL_DISPLAY);
49 
50 static void gst_gl_display_wayland_finalize (GObject * object);
51 static guintptr gst_gl_display_wayland_get_handle (GstGLDisplay * display);
52 
53 static void
gst_gl_display_wayland_class_init(GstGLDisplayWaylandClass * klass)54 gst_gl_display_wayland_class_init (GstGLDisplayWaylandClass * klass)
55 {
56   GST_GL_DISPLAY_CLASS (klass)->get_handle =
57       GST_DEBUG_FUNCPTR (gst_gl_display_wayland_get_handle);
58 
59   G_OBJECT_CLASS (klass)->finalize = gst_gl_display_wayland_finalize;
60 }
61 
62 static void
gst_gl_display_wayland_init(GstGLDisplayWayland * display_wayland)63 gst_gl_display_wayland_init (GstGLDisplayWayland * display_wayland)
64 {
65   GstGLDisplay *display = (GstGLDisplay *) display_wayland;
66 
67   display->type = GST_GL_DISPLAY_TYPE_WAYLAND;
68   display_wayland->foreign_display = FALSE;
69 }
70 
71 static void
gst_gl_display_wayland_finalize(GObject * object)72 gst_gl_display_wayland_finalize (GObject * object)
73 {
74   GstGLDisplayWayland *display_wayland = GST_GL_DISPLAY_WAYLAND (object);
75 
76   /* Cause eglTerminate() to occur before wl_display_disconnect()
77    * https://bugzilla.gnome.org/show_bug.cgi?id=787293 */
78   g_object_set_data (object, "gst.gl.display.egl", NULL);
79 
80   if (!display_wayland->foreign_display && display_wayland->display) {
81     wl_display_flush (display_wayland->display);
82     wl_display_disconnect (display_wayland->display);
83   }
84 
85   G_OBJECT_CLASS (gst_gl_display_wayland_parent_class)->finalize (object);
86 }
87 
88 /**
89  * gst_gl_display_wayland_new:
90  * @name: (allow-none): a display name
91  *
92  * Create a new #GstGLDisplayWayland from the wayland display name.  See `wl_display_connect`()
93  * for details on what is a valid name.
94  *
95  * Returns: (transfer full): a new #GstGLDisplayWayland or %NULL
96  */
97 GstGLDisplayWayland *
gst_gl_display_wayland_new(const gchar * name)98 gst_gl_display_wayland_new (const gchar * name)
99 {
100   GstGLDisplayWayland *ret;
101 
102   GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
103 
104   ret = g_object_new (GST_TYPE_GL_DISPLAY_WAYLAND, NULL);
105   gst_object_ref_sink (ret);
106   ret->display = wl_display_connect (name);
107 
108   if (!ret->display) {
109     if (name != NULL) {
110       GST_ERROR ("Failed to open Wayland display connection with name \'%s\'",
111           name);
112     } else {
113       GST_INFO ("Failed to open Wayland display connection.");
114     }
115     gst_object_unref (ret);
116     return NULL;
117   }
118 
119   return ret;
120 }
121 
122 /**
123  * gst_gl_display_wayland_new_with_display:
124  * @display: an existing, wayland display
125  *
126  * Creates a new display connection from a wl_display Display.
127  *
128  * Returns: (transfer full): a new #GstGLDisplayWayland
129  */
130 GstGLDisplayWayland *
gst_gl_display_wayland_new_with_display(struct wl_display * display)131 gst_gl_display_wayland_new_with_display (struct wl_display * display)
132 {
133   GstGLDisplayWayland *ret;
134 
135   g_return_val_if_fail (display != NULL, NULL);
136 
137   GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
138 
139   ret = g_object_new (GST_TYPE_GL_DISPLAY_WAYLAND, NULL);
140   gst_object_ref_sink (ret);
141 
142   ret->display = display;
143   ret->foreign_display = TRUE;
144 
145   return ret;
146 }
147 
148 static guintptr
gst_gl_display_wayland_get_handle(GstGLDisplay * display)149 gst_gl_display_wayland_get_handle (GstGLDisplay * display)
150 {
151   return (guintptr) GST_GL_DISPLAY_WAYLAND (display)->display;
152 }
153