Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5362 serge 1
/*
2
 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the
6
 * "Software"), to deal in the Software without restriction, including
7
 * without limitation the rights to use, copy, modify, merge, publish,
8
 * distribute, sub license, and/or sell copies of the Software, and to
9
 * permit persons to whom the Software is furnished to do so, subject to
10
 * the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the
13
 * next paragraph) shall be included in all copies or substantial portions
14
 * of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 */
24
 
25
#include 
26
#include 
27
#include 
28
#ifdef IN_LIBVA
29
# include "va/wayland/va_wayland.h"
30
#else
31
# include 
32
#endif
33
#include 
34
 
35
static void *open_display(void);
36
static void close_display(void *win_display);
37
static int create_window(void *win_display,
38
             int x, int y, int width, int height);
39
static int check_window_event(void *win_display, void *drawable,
40
                  int *width, int *height, int *quit);
41
 
42
struct display;
43
struct drawable;
44
 
45
static VAStatus
46
va_put_surface(
47
    VADisplay           dpy,
48
    struct drawable    *wl_drawable,
49
    VASurfaceID         va_surface,
50
    const VARectangle  *src_rect,
51
    const VARectangle  *dst_rect,
52
    const VARectangle  *cliprects,
53
    unsigned int        num_cliprects,
54
    unsigned int        flags
55
);
56
 
57
/* Glue code for the current PutSurface test design */
58
#define CAST_DRAWABLE(a)  (struct drawable *)(a)
59
 
60
static inline VADisplay
61
vaGetDisplay(VANativeDisplay native_dpy)
62
{
63
    return vaGetDisplayWl(native_dpy);
64
}
65
 
66
static VAStatus
67
vaPutSurface(
68
    VADisplay           dpy,
69
    VASurfaceID         surface,
70
    struct drawable    *wl_drawable,
71
    short               src_x,
72
    short               src_y,
73
    unsigned short      src_w,
74
    unsigned short      src_h,
75
    short               dst_x,
76
    short               dst_y,
77
    unsigned short      dst_w,
78
    unsigned short      dst_h,
79
    const VARectangle  *cliprects,
80
    unsigned int        num_cliprects,
81
    unsigned int        flags
82
)
83
{
84
    VARectangle src_rect, dst_rect;
85
 
86
    src_rect.x      = src_x;
87
    src_rect.y      = src_y;
88
    src_rect.width  = src_w;
89
    src_rect.height = src_h;
90
 
91
    dst_rect.x      = src_x;
92
    dst_rect.y      = src_y;
93
    dst_rect.width  = src_w;
94
    dst_rect.height = src_h;
95
    return va_put_surface(dpy, wl_drawable, surface, &src_rect, &dst_rect,
96
                          cliprects, num_cliprects, flags);
97
}
98
 
99
#include "putsurface_common.c"
100
 
101
struct display {
102
    struct wl_display  *display;
103
    struct wl_compositor *compositor;
104
    struct wl_shell    *shell;
105
    struct wl_registry *registry;
106
    int                 event_fd;
107
};
108
 
109
struct drawable {
110
    struct wl_display  *display;
111
    struct wl_surface  *surface;
112
    unsigned int        redraw_pending  : 1;
113
};
114
 
115
static void
116
frame_redraw_callback(void *data, struct wl_callback *callback, uint32_t time)
117
{
118
    struct drawable * const drawable = data;
119
 
120
    drawable->redraw_pending = 0;
121
    wl_callback_destroy(callback);
122
}
123
 
124
static const struct wl_callback_listener frame_callback_listener = {
125
    frame_redraw_callback
126
};
127
 
128
static VAStatus
129
va_put_surface(
130
    VADisplay           dpy,
131
    struct drawable    *wl_drawable,
132
    VASurfaceID         va_surface,
133
    const VARectangle  *src_rect,
134
    const VARectangle  *dst_rect,
135
    const VARectangle  *cliprects,
136
    unsigned int        num_cliprects,
137
    unsigned int        flags
138
)
139
{
140
    struct display *d;
141
    struct wl_callback *callback;
142
    VAStatus va_status;
143
    struct wl_buffer *buffer;
144
 
145
    if (!wl_drawable)
146
        return VA_STATUS_ERROR_INVALID_SURFACE;
147
 
148
    d = wl_display_get_user_data(wl_drawable->display);
149
    if (!d)
150
        return VA_STATUS_ERROR_INVALID_DISPLAY;
151
 
152
    /* Wait for the previous frame to complete redraw */
153
    if (wl_drawable->redraw_pending) {
154
        wl_display_flush(d->display);
155
        while (wl_drawable->redraw_pending)
156
            wl_display_dispatch(wl_drawable->display);
157
    }
158
 
159
    va_status = vaGetSurfaceBufferWl(va_dpy, va_surface, VA_FRAME_PICTURE, &buffer);
160
    if (va_status != VA_STATUS_SUCCESS)
161
        return va_status;
162
 
163
    wl_surface_attach(wl_drawable->surface, buffer, 0, 0);
164
    wl_surface_damage(
165
        wl_drawable->surface,
166
        dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height
167
    );
168
 
169
    wl_display_flush(d->display);
170
    wl_drawable->redraw_pending = 1;
171
    callback = wl_surface_frame(wl_drawable->surface);
172
    wl_surface_commit(wl_drawable->surface);
173
    wl_callback_add_listener(callback, &frame_callback_listener, wl_drawable);
174
    return VA_STATUS_SUCCESS;
175
}
176
 
177
static void
178
registry_handle_global(
179
    void               *data,
180
    struct wl_registry *registry,
181
    uint32_t            id,
182
    const char         *interface,
183
    uint32_t            version
184
)
185
{
186
    struct display * const d = data;
187
 
188
    if (strcmp(interface, "wl_compositor") == 0)
189
        d->compositor =
190
            wl_registry_bind(registry, id, &wl_compositor_interface, 1);
191
    else if (strcmp(interface, "wl_shell") == 0)
192
        d->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
193
}
194
 
195
static const struct wl_registry_listener registry_listener = {
196
    registry_handle_global,
197
    NULL,
198
};
199
 
200
static void *
201
open_display(void)
202
{
203
    struct display *d;
204
 
205
    d = calloc(1, sizeof *d);
206
    if (!d)
207
        return NULL;
208
 
209
    d->display = wl_display_connect(NULL);
210
    if (!d->display)
211
        return NULL;
212
 
213
    wl_display_set_user_data(d->display, d);
214
    d->registry = wl_display_get_registry(d->display);
215
    wl_registry_add_listener(d->registry, ®istry_listener, d);
216
    d->event_fd = wl_display_get_fd(d->display);
217
    wl_display_dispatch(d->display);
218
    return d->display;
219
}
220
 
221
static void
222
close_display(void *win_display)
223
{
224
    struct display * const d = wl_display_get_user_data(win_display);
225
 
226
    if (d->shell) {
227
        wl_shell_destroy(d->shell);
228
        d->shell = NULL;
229
    }
230
 
231
    if (d->compositor) {
232
        wl_compositor_destroy(d->compositor);
233
        d->compositor = NULL;
234
    }
235
 
236
    if (d->display) {
237
        wl_display_disconnect(d->display);
238
        d->display = NULL;
239
    }
240
    free(d);
241
}
242
 
243
static int
244
create_window(void *win_display, int x, int y, int width, int height)
245
{
246
    struct wl_display * const display = win_display;
247
    struct display * const d = wl_display_get_user_data(display);
248
    struct wl_surface *surface1, *surface2;
249
    struct wl_shell_surface *shell_surface;
250
    struct wl_shell_surface *shell_surface_2;
251
    struct drawable *drawable1, *drawable2;
252
 
253
    surface1 = wl_compositor_create_surface(d->compositor);
254
    shell_surface = wl_shell_get_shell_surface(d->shell, surface1);
255
    wl_shell_surface_set_toplevel(shell_surface);
256
 
257
    drawable1 = malloc(sizeof(*drawable1));
258
    drawable1->display          = display;
259
    drawable1->surface          = surface1;
260
    drawable1->redraw_pending   = 0;
261
 
262
    /* global out */
263
    drawable_thread0 = drawable1;
264
 
265
    if (multi_thread == 0)
266
        return 0;
267
 
268
    surface2 = wl_compositor_create_surface(d->compositor);
269
    shell_surface_2 = wl_shell_get_shell_surface(d->shell, surface2);
270
    wl_shell_surface_set_toplevel(shell_surface_2);
271
 
272
    drawable2 = malloc(sizeof(*drawable2));
273
    drawable2->display          = display;
274
    drawable1->surface          = surface2;
275
    drawable2->redraw_pending   = 0;
276
 
277
    /* global out */
278
    drawable_thread1 = drawable2;
279
    return 0;
280
}
281
 
282
static int
283
check_window_event(
284
    void *win_display,
285
    void *drawable,
286
    int  *width,
287
    int  *height,
288
    int  *quit
289
)
290
{
291
    struct wl_display * const display = win_display;
292
    struct display * const d = wl_display_get_user_data(display);
293
    struct timeval tv;
294
    fd_set rfds;
295
    int retval;
296
 
297
    if (check_event == 0)
298
        return 0;
299
 
300
    tv.tv_sec  = 0;
301
    tv.tv_usec = 0;
302
    do {
303
        FD_ZERO(&rfds);
304
        FD_SET(d->event_fd, &rfds);
305
 
306
        retval = select(d->event_fd + 1, &rfds, NULL, NULL, &tv);
307
        if (retval < 0) {
308
            perror("select");
309
            break;
310
        }
311
        if (retval == 1)
312
            wl_display_dispatch(d->display);
313
    } while (retval > 0);
314
 
315
#if 0
316
    /* bail on any focused key press */
317
    if(event.type == KeyPress) {
318
        *quit = 1;
319
        return 0;
320
    }
321
#endif
322
 
323
#if 0
324
    /* rescale the video to fit the window */
325
    if(event.type == ConfigureNotify) {
326
        *width = event.xconfigure.width;
327
        *height = event.xconfigure.height;
328
        printf("Scale window to %dx%d\n", width, height);
329
    }
330
#endif
331
    return 0;
332
}