| /* |
| * Copyright (c) 2012 Intel Corporation. All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sub license, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the |
| * next paragraph) shall be included in all copies or substantial portions |
| * of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR |
| * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| #include "va_dricommon.h" |
| |
| // X error trap |
| static int x11_error_code = 0; |
| static int (*old_error_handler)(Display *, XErrorEvent *); |
| |
| static int |
| error_handler(Display *dpy, XErrorEvent *error) |
| { |
| x11_error_code = error->error_code; |
| return 0; |
| } |
| |
| static void |
| x11_trap_errors(void) |
| { |
| x11_error_code = 0; |
| old_error_handler = XSetErrorHandler(error_handler); |
| } |
| |
| static int |
| x11_untrap_errors(void) |
| { |
| XSetErrorHandler(old_error_handler); |
| return x11_error_code; |
| } |
| |
| static int |
| is_window(Display *dpy, Drawable drawable) |
| { |
| XWindowAttributes wattr; |
| |
| x11_trap_errors(); |
| XGetWindowAttributes(dpy, drawable, &wattr); |
| return x11_untrap_errors() == 0; |
| } |
| |
| static struct dri_drawable * |
| do_drawable_hash(VADriverContextP ctx, XID drawable) |
| { |
| struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; |
| int index = drawable % DRAWABLE_HASH_SZ; |
| struct dri_drawable *dri_drawable = dri_state->drawable_hash[index]; |
| |
| while (dri_drawable) { |
| if (dri_drawable->x_drawable == drawable) |
| return dri_drawable; |
| dri_drawable = dri_drawable->next; |
| } |
| |
| dri_drawable = dri_state->createDrawable(ctx, drawable); |
| dri_drawable->x_drawable = drawable; |
| dri_drawable->is_window = is_window(ctx->native_dpy, drawable); |
| dri_drawable->next = dri_state->drawable_hash[index]; |
| dri_state->drawable_hash[index] = dri_drawable; |
| |
| return dri_drawable; |
| } |
| |
| void |
| va_dri_free_drawable(VADriverContextP ctx, struct dri_drawable* dri_drawable) |
| { |
| struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; |
| int i = 0; |
| |
| while (i < DRAWABLE_HASH_SZ) { |
| if (dri_drawable == dri_state->drawable_hash[i]) { |
| dri_state->destroyDrawable(ctx, dri_drawable); |
| dri_state->drawable_hash[i] = NULL; |
| } |
| i++; |
| } |
| } |
| |
| void |
| va_dri_free_drawable_hashtable(VADriverContextP ctx) |
| { |
| struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; |
| int i; |
| struct dri_drawable *dri_drawable, *prev; |
| |
| for (i = 0; i < DRAWABLE_HASH_SZ; i++) { |
| dri_drawable = dri_state->drawable_hash[i]; |
| |
| while (dri_drawable) { |
| prev = dri_drawable; |
| dri_drawable = prev->next; |
| dri_state->destroyDrawable(ctx, prev); |
| } |
| |
| dri_state->drawable_hash[i] = NULL; |
| } |
| } |
| |
| struct dri_drawable * |
| va_dri_get_drawable(VADriverContextP ctx, XID drawable) |
| { |
| return do_drawable_hash(ctx, drawable); |
| } |
| |
| void |
| va_dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) |
| { |
| struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; |
| |
| dri_state->swapBuffer(ctx, dri_drawable); |
| } |
| |
| union dri_buffer * |
| va_dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) |
| { |
| struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; |
| |
| return dri_state->getRenderingBuffer(ctx, dri_drawable); |
| } |