1/*
2 * Copyright (c) 2012 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 <stdio.h>
26#include <stdbool.h>
27#include <va/va_x11.h>
28#include "va_display.h"
29
30static Display *x11_display;
31static Window   x11_window;
32
33static VADisplay
34va_open_display_x11(void)
35{
36    x11_display = XOpenDisplay(NULL);
37    if (!x11_display) {
38        fprintf(stderr, "error: can't connect to X server!\n");
39        return NULL;
40    }
41    return vaGetDisplay(x11_display);
42}
43
44static void
45va_close_display_x11(VADisplay va_dpy)
46{
47    if (!x11_display)
48        return;
49
50    if (x11_window) {
51        XUnmapWindow(x11_display, x11_window);
52        XDestroyWindow(x11_display, x11_window);
53        x11_window = None;
54    }
55    XCloseDisplay(x11_display);
56    x11_display = NULL;
57}
58
59static int
60ensure_window(unsigned int width, unsigned int height)
61{
62    Window win, rootwin;
63    unsigned int black_pixel, white_pixel;
64    int screen;
65
66    if (!x11_display)
67        return 0;
68
69    if (x11_window) {
70        XResizeWindow(x11_display, x11_window, width, height);
71        return 1;
72    }
73
74    screen      = DefaultScreen(x11_display);
75    rootwin     = RootWindow(x11_display, screen);
76    black_pixel = BlackPixel(x11_display, screen);
77    white_pixel = WhitePixel(x11_display, screen);
78
79    win = XCreateSimpleWindow(
80        x11_display,
81        rootwin,
82        0, 0, width, height,
83        1, black_pixel, white_pixel
84    );
85    if (!win)
86        return 0;
87    x11_window = win;
88
89    XMapWindow(x11_display, x11_window);
90    XSync(x11_display, False);
91    return 1;
92}
93
94static inline bool
95validate_rect(const VARectangle *rect)
96{
97    return (rect            &&
98            rect->x >= 0    &&
99            rect->y >= 0    &&
100            rect->width > 0 &&
101            rect->height > 0);
102}
103
104static VAStatus
105va_put_surface_x11(
106    VADisplay          va_dpy,
107    VASurfaceID        surface,
108    const VARectangle *src_rect,
109    const VARectangle *dst_rect
110)
111{
112    unsigned int win_width, win_height;
113
114    if (!va_dpy)
115        return VA_STATUS_ERROR_INVALID_DISPLAY;
116    if (surface == VA_INVALID_SURFACE)
117        return VA_STATUS_ERROR_INVALID_SURFACE;
118    if (!validate_rect(src_rect) || !validate_rect(dst_rect))
119        return VA_STATUS_ERROR_INVALID_PARAMETER;
120
121    win_width  = dst_rect->x + dst_rect->width;
122    win_height = dst_rect->y + dst_rect->height;
123    if (!ensure_window(win_width, win_height))
124        return VA_STATUS_ERROR_ALLOCATION_FAILED;
125    return vaPutSurface(va_dpy, surface, x11_window,
126                        src_rect->x, src_rect->y,
127                        src_rect->width, src_rect->height,
128                        dst_rect->x, dst_rect->y,
129                        dst_rect->width, dst_rect->height,
130                        NULL, 0,
131                        VA_FRAME_PICTURE);
132}
133
134const VADisplayHooks va_display_hooks_x11 = {
135    "x11",
136    va_open_display_x11,
137    va_close_display_x11,
138    va_put_surface_x11,
139};
140