Home | History | Annotate | Download | only in common
      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 
     30 static Display *x11_display;
     31 static Window   x11_window;
     32 
     33 static VADisplay
     34 va_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 
     44 static void
     45 va_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 
     59 static int
     60 ensure_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 
     94 static inline bool
     95 validate_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 
    104 static VAStatus
    105 va_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 
    134 const VADisplayHooks va_display_hooks_x11 = {
    135     "x11",
    136     va_open_display_x11,
    137     va_close_display_x11,
    138     va_put_surface_x11,
    139 };
    140