1409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/*
2409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Copyright (c) 2012 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 <stdio.h>
26409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <stdbool.h>
27409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <va/va_x11.h>
28409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include "va_display.h"
29409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
30409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic Display *x11_display;
31409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic Window   x11_window;
32409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
33409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic VADisplay
34409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanva_open_display_x11(void)
35409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
36409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    x11_display = XOpenDisplay(NULL);
37409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!x11_display) {
38409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        fprintf(stderr, "error: can't connect to X server!\n");
39409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return NULL;
40409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
41409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return vaGetDisplay(x11_display);
42409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
43409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
44409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
45409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanva_close_display_x11(VADisplay va_dpy)
46409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
47409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!x11_display)
48409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return;
49409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
50409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (x11_window) {
51409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        XUnmapWindow(x11_display, x11_window);
52409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        XDestroyWindow(x11_display, x11_window);
53409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        x11_window = None;
54409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
55409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    XCloseDisplay(x11_display);
56409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    x11_display = NULL;
57409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
58409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
59409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int
60409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanensure_window(unsigned int width, unsigned int height)
61409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
62409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    Window win, rootwin;
63409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int black_pixel, white_pixel;
64409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int screen;
65409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
66409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!x11_display)
67409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 0;
68409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
69409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (x11_window) {
70409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        XResizeWindow(x11_display, x11_window, width, height);
71409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 1;
72409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
73409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
74409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    screen      = DefaultScreen(x11_display);
75409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    rootwin     = RootWindow(x11_display, screen);
76409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    black_pixel = BlackPixel(x11_display, screen);
77409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    white_pixel = WhitePixel(x11_display, screen);
78409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
79409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    win = XCreateSimpleWindow(
80409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        x11_display,
81409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rootwin,
82409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        0, 0, width, height,
83409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        1, black_pixel, white_pixel
84409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    );
85409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!win)
86409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 0;
87409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    x11_window = win;
88409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
89409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    XMapWindow(x11_display, x11_window);
90409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    XSync(x11_display, False);
91409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 1;
92409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
93409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
94409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic inline bool
95409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanvalidate_rect(const VARectangle *rect)
96409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
97409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return (rect            &&
98409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            rect->x >= 0    &&
99409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            rect->y >= 0    &&
100409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            rect->width > 0 &&
101409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            rect->height > 0);
102409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
103409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
104409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic VAStatus
105409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanva_put_surface_x11(
106409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VADisplay          va_dpy,
107409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VASurfaceID        surface,
108409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle *src_rect,
109409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const VARectangle *dst_rect
110409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan)
111409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
112409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int win_width, win_height;
113409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
114409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!va_dpy)
115409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return VA_STATUS_ERROR_INVALID_DISPLAY;
116409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (surface == VA_INVALID_SURFACE)
117409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return VA_STATUS_ERROR_INVALID_SURFACE;
118409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!validate_rect(src_rect) || !validate_rect(dst_rect))
119409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return VA_STATUS_ERROR_INVALID_PARAMETER;
120409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
121409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    win_width  = dst_rect->x + dst_rect->width;
122409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    win_height = dst_rect->y + dst_rect->height;
123409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!ensure_window(win_width, win_height))
124409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return VA_STATUS_ERROR_ALLOCATION_FAILED;
125409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return vaPutSurface(va_dpy, surface, x11_window,
126409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                        src_rect->x, src_rect->y,
127409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                        src_rect->width, src_rect->height,
128409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                        dst_rect->x, dst_rect->y,
129409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                        dst_rect->width, dst_rect->height,
130409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                        NULL, 0,
131409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                        VA_FRAME_PICTURE);
132409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
133409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
134409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanconst VADisplayHooks va_display_hooks_x11 = {
135409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    "x11",
136409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_open_display_x11,
137409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_close_display_x11,
138409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_put_surface_x11,
139409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan};
140