]> git.sesse.net Git - vlc/commitdiff
Wayland/shell: implement basic window size handling
authorRémi Denis-Courmont <remi@remlab.net>
Thu, 16 Oct 2014 17:21:21 +0000 (20:21 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Thu, 16 Oct 2014 17:24:06 +0000 (20:24 +0300)
modules/video_output/wayland/shell_surface.c

index efa9a29c6005773223f8487af0d5552d4536f600..60d06359bc145d3fce33377c15f175bb907068c8 100644 (file)
@@ -43,6 +43,13 @@ struct vout_window_sys_t
     struct wl_shell *shell;
     struct wl_shell_surface *shell_surface;
 
+    uint32_t top_width;
+    uint32_t top_height;
+    uint32_t fs_width;
+    uint32_t fs_height;
+    bool fullscreen;
+
+    vlc_mutex_t lock;
     vlc_thread_t thread;
 };
 
@@ -100,7 +107,13 @@ static int Control(vout_window_t *wnd, int cmd, va_list ap)
             unsigned width = va_arg (ap, unsigned);
             unsigned height = va_arg (ap, unsigned);
 
-            vout_window_ReportSize(wnd, width, height);
+            vlc_mutex_lock(&sys->lock);
+            sys->top_width = width;
+            sys->top_height = height;
+
+            if (!sys->fullscreen)
+                vout_window_ReportSize(wnd, width, height);
+            vlc_mutex_unlock(&sys->lock);
             break;
         }
         case VOUT_WINDOW_SET_FULLSCREEN:
@@ -108,10 +121,23 @@ static int Control(vout_window_t *wnd, int cmd, va_list ap)
             bool fs = va_arg(ap, int);
 
             if (fs && sys->output != NULL)
+            {
                 wl_shell_surface_set_fullscreen(sys->shell_surface, 1, 0,
                                                 sys->output);
+                vlc_mutex_lock(&sys->lock);
+                sys->fullscreen = true;
+                vout_window_ReportSize(wnd, sys->fs_width, sys->fs_height);
+                vlc_mutex_unlock(&sys->lock);
+            }
             else
+            {
                 wl_shell_surface_set_toplevel(sys->shell_surface);
+
+                vlc_mutex_lock(&sys->lock);
+                sys->fullscreen = false;
+                vout_window_ReportSize(wnd, sys->top_width, sys->top_height);
+                vlc_mutex_unlock(&sys->lock);
+            }
             break;
         }
 
@@ -124,6 +150,52 @@ static int Control(vout_window_t *wnd, int cmd, va_list ap)
     return VLC_SUCCESS;
 }
 
+static void output_geometry_cb(void *data, struct wl_output *output, int32_t x,
+                               int32_t y, int32_t width, int32_t height,
+                               int32_t subpixel, const char *vendor,
+                               const char *model, int32_t transform)
+{
+    vout_window_t *wnd = data;
+
+    msg_Dbg(wnd, "output geometry: %s %s %"PRId32"x%"PRId32"mm "
+            "@ %"PRId32"x%"PRId32" subpixel: %"PRId32" transform: %"PRId32,
+            vendor, model, width, height, x, y, subpixel, transform);
+    (void) output;
+}
+
+static void output_mode_cb(void *data, struct wl_output *output,
+                           uint32_t flags, int32_t width, int32_t height,
+                           int32_t refresh)
+{
+    vout_window_t *wnd = data;
+    vout_window_sys_t *sys = wnd->sys;
+
+    msg_Dbg(wnd, "output mode: 0x%08"PRIX32" %"PRId32"x%"PRId32
+            " %"PRId32"mHz%s", flags, width, height, refresh,
+            (flags & WL_OUTPUT_MODE_CURRENT) ? " (current)" : "");
+
+    if (!(flags & WL_OUTPUT_MODE_CURRENT))
+        return;
+
+    vlc_mutex_lock(&sys->lock);
+    sys->fs_width = width;
+    sys->fs_height = height;
+
+    if (sys->fullscreen)
+        vout_window_ReportSize(wnd, width, height);
+    vlc_mutex_unlock(&sys->lock);
+
+    (void) output;
+}
+
+const struct wl_output_listener output_cbs =
+{
+    output_geometry_cb,
+    output_mode_cb,
+    NULL,
+    NULL,
+};
+
 static void shell_surface_ping_cb(void *data,
                                   struct wl_shell_surface *shell_surface,
                                   uint32_t serial)
@@ -138,8 +210,17 @@ static void shell_surface_configure_cb(void *data,
                                        int32_t width, int32_t height)
 {
     vout_window_t *wnd = data;
+    vout_window_sys_t *sys = wnd->sys;
+
+    msg_Dbg(wnd, "new configuration: %"PRId32"x%"PRId32, width, height);
+    vlc_mutex_lock(&sys->lock);
+    sys->top_width = width;
+    sys->top_height = height;
+
+    if (!sys->fullscreen)
+        vout_window_ReportSize(wnd,  width, height);
+    vlc_mutex_unlock(&sys->lock);
 
-    msg_Err(wnd, "FIXME resize to %"PRId32"x%"PRId32, width, height);
     (void) shell_surface;
     (void) edges;
 }
@@ -210,6 +291,12 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
     sys->output = NULL;
     sys->shell = NULL;
     sys->shell_surface = NULL;
+    sys->top_width = cfg->width;
+    sys->top_height = cfg->height;
+    sys->fs_width = cfg->width;
+    sys->fs_height = cfg->height;
+    sys->fullscreen = false;
+    vlc_mutex_init(&sys->lock);
     wnd->sys = sys;
 
     /* Connect to the display server */
@@ -220,6 +307,7 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
 
     if (display == NULL)
     {
+        vlc_mutex_destroy(&sys->lock);
         free(sys);
         return VLC_EGENERIC;
     }
@@ -236,6 +324,9 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
     if (sys->compositor == NULL || sys->shell == NULL)
         goto error;
 
+    if (sys->output != NULL)
+        wl_output_add_listener(sys->output, &output_cbs, wnd);
+
     /* Create a surface */
     struct wl_surface *surface = wl_compositor_create_surface(sys->compositor);
     if (surface == NULL)
@@ -283,6 +374,7 @@ error:
     if (sys->compositor != NULL)
         wl_compositor_destroy(sys->compositor);
     wl_display_disconnect(display);
+    vlc_mutex_destroy(&sys->lock);
     free(sys);
     return VLC_EGENERIC;
 }
@@ -304,6 +396,7 @@ static void Close(vout_window_t *wnd)
         wl_output_destroy(sys->output);
     wl_compositor_destroy(sys->compositor);
     wl_display_disconnect(wnd->display.wl);
+    vlc_mutex_destroy(&sys->lock);
     free(sys);
 }