93eb83cba3debe7611dcc566227a8b1e981d8a42
[platform/upstream/gstreamer.git] / gst-libs / gst / gl / wayland / gstgldisplay_wayland.c
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 static gboolean gst_gl_display_wayland_get_foreign_display (GstGLDisplay *
53     display);
54
55 static void
56 gst_gl_display_wayland_class_init (GstGLDisplayWaylandClass * klass)
57 {
58   GST_GL_DISPLAY_CLASS (klass)->get_handle =
59       GST_DEBUG_FUNCPTR (gst_gl_display_wayland_get_handle);
60   GST_GL_DISPLAY_CLASS (klass)->get_foreign_display =
61       GST_DEBUG_FUNCPTR (gst_gl_display_wayland_get_foreign_display);
62
63   G_OBJECT_CLASS (klass)->finalize = gst_gl_display_wayland_finalize;
64 }
65
66 static void
67 gst_gl_display_wayland_init (GstGLDisplayWayland * display_wayland)
68 {
69   GstGLDisplay *display = (GstGLDisplay *) display_wayland;
70
71   display->type = GST_GL_DISPLAY_TYPE_WAYLAND;
72   display_wayland->foreign_display = FALSE;
73 }
74
75 static void
76 gst_gl_display_wayland_finalize (GObject * object)
77 {
78   GstGLDisplayWayland *display_wayland = GST_GL_DISPLAY_WAYLAND (object);
79
80   /* Cause eglTerminate() to occur before wl_display_disconnect()
81    * https://bugzilla.gnome.org/show_bug.cgi?id=787293 */
82   g_object_set_data (object, "gst.gl.display.egl", NULL);
83
84   if (!display_wayland->foreign_display && display_wayland->display) {
85     wl_display_flush (display_wayland->display);
86     wl_display_disconnect (display_wayland->display);
87   }
88
89   G_OBJECT_CLASS (gst_gl_display_wayland_parent_class)->finalize (object);
90 }
91
92 /**
93  * gst_gl_display_wayland_new:
94  * @name: (allow-none): a display name
95  *
96  * Create a new #GstGLDisplayWayland from the wayland display name.  See `wl_display_connect`()
97  * for details on what is a valid name.
98  *
99  * Returns: (transfer full): a new #GstGLDisplayWayland or %NULL
100  */
101 GstGLDisplayWayland *
102 gst_gl_display_wayland_new (const gchar * name)
103 {
104   GstGLDisplayWayland *ret;
105
106   GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
107
108   ret = g_object_new (GST_TYPE_GL_DISPLAY_WAYLAND, NULL);
109   gst_object_ref_sink (ret);
110   ret->display = wl_display_connect (name);
111
112   if (!ret->display) {
113     if (name != NULL) {
114       GST_ERROR ("Failed to open Wayland display connection with name \'%s\'",
115           name);
116     } else {
117       GST_INFO ("Failed to open Wayland display connection.");
118     }
119     gst_object_unref (ret);
120     return NULL;
121   }
122
123   return ret;
124 }
125
126 /**
127  * gst_gl_display_wayland_new_with_display:
128  * @display: an existing, wayland display
129  *
130  * Creates a new display connection from a wl_display Display.
131  *
132  * Returns: (transfer full): a new #GstGLDisplayWayland
133  */
134 GstGLDisplayWayland *
135 gst_gl_display_wayland_new_with_display (struct wl_display * display)
136 {
137   GstGLDisplayWayland *ret;
138
139   g_return_val_if_fail (display != NULL, NULL);
140
141   GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
142
143   ret = g_object_new (GST_TYPE_GL_DISPLAY_WAYLAND, NULL);
144   gst_object_ref_sink (ret);
145
146   ret->display = display;
147   ret->foreign_display = TRUE;
148
149   return ret;
150 }
151
152 static guintptr
153 gst_gl_display_wayland_get_handle (GstGLDisplay * display)
154 {
155   return (guintptr) GST_GL_DISPLAY_WAYLAND (display)->display;
156 }
157
158 static gboolean
159 gst_gl_display_wayland_get_foreign_display (GstGLDisplay * display)
160 {
161   return GST_GL_DISPLAY_WAYLAND (display)->foreign_display;
162 }