1409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/*
2409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan *
4409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Permission is hereby granted, free of charge, to any person obtaining a
5409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * copy of this software and associated documentation files (the
6409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * "Software"), to deal in the Software without restriction, including
7409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * without limitation the rights to use, copy, modify, merge, publish,
8409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * distribute, sub license, and/or sell copies of the Software, and to
9409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * permit persons to whom the Software is furnished to do so, subject to
10409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * the following conditions:
11409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan *
12409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * The above copyright notice and this permission notice (including the
13409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * next paragraph) shall be included in all copies or substantial portions
14409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * of the Software.
15409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan *
16409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan */
24409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
25409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <stddef.h>
26409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <errno.h>
27409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <sys/select.h>
28409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#ifdef IN_LIBVA
29409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan# include "va/wayland/va_wayland.h"
30409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#else
31409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan# include <va/va_wayland.h>
32409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#endif
33409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <wayland-server.h>
34409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
35409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void *open_display(void);
36409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void close_display(void *win_display);
37409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int create_window(void *win_display,
38409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan             int x, int y, int width, int height);
39409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int check_window_event(void *win_display, void *drawable,
40409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                  int *width, int *height, int *quit);
41409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
42409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstruct display;
43409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstruct drawable;
44409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
45409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic VAStatus
46409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanva_put_surface(
47409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VADisplay           dpy,
48409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct drawable    *wl_drawable,
49409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VASurfaceID         va_surface,
50409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle  *src_rect,
51409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle  *dst_rect,
52409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle  *cliprects,
53409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int        num_cliprects,
54409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int        flags
55409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan);
56409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
57409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/* Glue code for the current PutSurface test design */
58409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define CAST_DRAWABLE(a)  (struct drawable *)(a)
59409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
60409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic inline VADisplay
61409de6acb4473c973ed2532e340831dc582e5e0eAustin YuanvaGetDisplay(VANativeDisplay native_dpy)
62409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
63409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return vaGetDisplayWl(native_dpy);
64409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
65409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
66409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic VAStatus
67409de6acb4473c973ed2532e340831dc582e5e0eAustin YuanvaPutSurface(
68409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VADisplay           dpy,
69409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VASurfaceID         surface,
70409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct drawable    *wl_drawable,
71409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    short               src_x,
72409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    short               src_y,
73409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned short      src_w,
74409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned short      src_h,
75409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    short               dst_x,
76409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    short               dst_y,
77409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned short      dst_w,
78409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned short      dst_h,
79409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle  *cliprects,
80409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int        num_cliprects,
81409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int        flags
82409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan)
83409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
84409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VARectangle src_rect, dst_rect;
85409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
86409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    src_rect.x      = src_x;
87409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    src_rect.y      = src_y;
88409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    src_rect.width  = src_w;
89409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    src_rect.height = src_h;
90409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
91409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    dst_rect.x      = src_x;
92409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    dst_rect.y      = src_y;
93409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    dst_rect.width  = src_w;
94409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    dst_rect.height = src_h;
95409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return va_put_surface(dpy, wl_drawable, surface, &src_rect, &dst_rect,
96409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                          cliprects, num_cliprects, flags);
97409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
98409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
99409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include "putsurface_common.c"
100409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
101409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstruct display {
102409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_display  *display;
103409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_compositor *compositor;
104409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_shell    *shell;
105409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_registry *registry;
106409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int                 event_fd;
107409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan};
108409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
109409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstruct drawable {
110409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_display  *display;
111409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_surface  *surface;
112409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int        redraw_pending  : 1;
113409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan};
114409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
115409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
116409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanframe_redraw_callback(void *data, struct wl_callback *callback, uint32_t time)
117409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
118409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct drawable * const drawable = data;
119409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
120409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable->redraw_pending = 0;
121409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_callback_destroy(callback);
122409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
123409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
124409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic const struct wl_callback_listener frame_callback_listener = {
125409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    frame_redraw_callback
126409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan};
127409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
128409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic VAStatus
129409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanva_put_surface(
130409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VADisplay           dpy,
131409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct drawable    *wl_drawable,
132409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VASurfaceID         va_surface,
133409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle  *src_rect,
134409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle  *dst_rect,
135409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle  *cliprects,
136409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int        num_cliprects,
137409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int        flags
138409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan)
139409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
140409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct display *d;
141409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_callback *callback;
142409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
143409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_buffer *buffer;
144409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
145409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!wl_drawable)
146409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return VA_STATUS_ERROR_INVALID_SURFACE;
147409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
148409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    d = wl_display_get_user_data(wl_drawable->display);
149409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!d)
150409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return VA_STATUS_ERROR_INVALID_DISPLAY;
151409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
152409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* Wait for the previous frame to complete redraw */
153409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (wl_drawable->redraw_pending) {
154409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        wl_display_flush(d->display);
155409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        while (wl_drawable->redraw_pending)
156409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            wl_display_dispatch(wl_drawable->display);
157409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
158409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
159409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaGetSurfaceBufferWl(va_dpy, va_surface, VA_FRAME_PICTURE, &buffer);
160409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (va_status != VA_STATUS_SUCCESS)
161409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return va_status;
162409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
163409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_surface_attach(wl_drawable->surface, buffer, 0, 0);
164409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_surface_damage(
165409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        wl_drawable->surface,
166409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height
167409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    );
168409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
169409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_display_flush(d->display);
170409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_drawable->redraw_pending = 1;
171409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    callback = wl_surface_frame(wl_drawable->surface);
172409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_surface_commit(wl_drawable->surface);
173409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_callback_add_listener(callback, &frame_callback_listener, wl_drawable);
174409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return VA_STATUS_SUCCESS;
175409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
176409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
177409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
178409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanregistry_handle_global(
179409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    void               *data,
180409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_registry *registry,
181409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    uint32_t            id,
182409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const char         *interface,
183409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    uint32_t            version
184409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan)
185409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
186409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct display * const d = data;
187409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
188409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (strcmp(interface, "wl_compositor") == 0)
189409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        d->compositor =
190409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
191409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (strcmp(interface, "wl_shell") == 0)
192409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        d->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
193409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
194409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
195409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic const struct wl_registry_listener registry_listener = {
196409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    registry_handle_global,
197409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    NULL,
198409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan};
199409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
200409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void *
201409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanopen_display(void)
202409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
203409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct display *d;
204409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
205409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    d = calloc(1, sizeof *d);
206409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!d)
207409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return NULL;
208409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
209409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    d->display = wl_display_connect(NULL);
210409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!d->display)
211409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return NULL;
212409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
213409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_display_set_user_data(d->display, d);
214409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    d->registry = wl_display_get_registry(d->display);
215409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_registry_add_listener(d->registry, &registry_listener, d);
216409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    d->event_fd = wl_display_get_fd(d->display);
217409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_display_dispatch(d->display);
218409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return d->display;
219409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
220409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
221409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
222409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanclose_display(void *win_display)
223409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
224409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct display * const d = wl_display_get_user_data(win_display);
225409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
226409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (d->shell) {
227409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        wl_shell_destroy(d->shell);
228409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        d->shell = NULL;
229409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
230409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
231409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (d->compositor) {
232409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        wl_compositor_destroy(d->compositor);
233409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        d->compositor = NULL;
234409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
235409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
236409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (d->display) {
237409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        wl_display_disconnect(d->display);
238409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        d->display = NULL;
239409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
240409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    free(d);
241409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
242409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
243409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int
244409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuancreate_window(void *win_display, int x, int y, int width, int height)
245409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
246409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_display * const display = win_display;
247409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct display * const d = wl_display_get_user_data(display);
248409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_surface *surface1, *surface2;
249409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_shell_surface *shell_surface;
250409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_shell_surface *shell_surface_2;
251409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct drawable *drawable1, *drawable2;
252409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
253409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    surface1 = wl_compositor_create_surface(d->compositor);
254409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    shell_surface = wl_shell_get_shell_surface(d->shell, surface1);
255409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_shell_surface_set_toplevel(shell_surface);
256409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
257409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable1 = malloc(sizeof(*drawable1));
258409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable1->display          = display;
259409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable1->surface          = surface1;
260409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable1->redraw_pending   = 0;
261409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
262409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* global out */
263409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable_thread0 = drawable1;
264409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
265409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (multi_thread == 0)
266409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 0;
267409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
268409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    surface2 = wl_compositor_create_surface(d->compositor);
269409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    shell_surface_2 = wl_shell_get_shell_surface(d->shell, surface2);
270409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    wl_shell_surface_set_toplevel(shell_surface_2);
271409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
272409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable2 = malloc(sizeof(*drawable2));
273409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable2->display          = display;
274409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable1->surface          = surface2;
275409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable2->redraw_pending   = 0;
276409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
277409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* global out */
278409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    drawable_thread1 = drawable2;
279409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
280409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
281409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
282409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int
283409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuancheck_window_event(
284409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    void *win_display,
285409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    void *drawable,
286409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int  *width,
287409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int  *height,
288409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int  *quit
289409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan)
290409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
291409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct wl_display * const display = win_display;
292409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct display * const d = wl_display_get_user_data(display);
293409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct timeval tv;
294409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    fd_set rfds;
295409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int retval;
296409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
297409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (check_event == 0)
298409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 0;
299409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
300409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tv.tv_sec  = 0;
301409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tv.tv_usec = 0;
302409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    do {
303409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        FD_ZERO(&rfds);
304409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        FD_SET(d->event_fd, &rfds);
305409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
306409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        retval = select(d->event_fd + 1, &rfds, NULL, NULL, &tv);
307409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (retval < 0) {
308409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            perror("select");
309409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
310409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
311409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (retval == 1)
312409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            wl_display_dispatch(d->display);
313409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } while (retval > 0);
314409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
315409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#if 0
316409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* bail on any focused key press */
317409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if(event.type == KeyPress) {
318409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        *quit = 1;
319409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 0;
320409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
321409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#endif
322409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
323409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#if 0
324409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* rescale the video to fit the window */
325409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if(event.type == ConfigureNotify) {
326409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        *width = event.xconfigure.width;
327409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        *height = event.xconfigure.height;
328409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Scale window to %dx%d\n", width, height);
329409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
330409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#endif
331409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
332409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
333