diff options
author | chriszero <zerov83@gmail.com> | 2015-01-11 15:14:03 +0100 |
---|---|---|
committer | chriszero <zerov83@gmail.com> | 2015-01-11 15:14:03 +0100 |
commit | 508ba3458094f0c30b278cc05abc626b6f3940e0 (patch) | |
tree | 12592e3fb841f80ad1c61d07b3f9242ad94d2cbe /video.c | |
parent | a9dd0c6a322f139e03a0ba4570e2a78508ddd6c3 (diff) | |
download | vdr-plugin-plex-508ba3458094f0c30b278cc05abc626b6f3940e0.tar.gz vdr-plugin-plex-508ba3458094f0c30b278cc05abc626b6f3940e0.tar.bz2 |
Removed Mplayer support.
Added HLS Streaming Player for directly play in VDR
Diffstat (limited to 'video.c')
-rw-r--r-- | video.c | 775 |
1 files changed, 0 insertions, 775 deletions
diff --git a/video.c b/video.c deleted file mode 100644 index 7fe2fff..0000000 --- a/video.c +++ /dev/null @@ -1,775 +0,0 @@ -/// -/// @file video.c @brief Video module -/// -/// Copyright (c) 2012, 2013 by Johns. All Rights Reserved. -/// -/// Contributor(s): -/// -/// License: AGPLv3 -/// -/// This program is free software: you can redistribute it and/or modify -/// it under the terms of the GNU Affero General Public License as -/// published by the Free Software Foundation, either version 3 of the -/// License. -/// -/// This program is distributed in the hope that it will be useful, -/// but WITHOUT ANY WARRANTY; without even the implied warranty of -/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -/// GNU Affero General Public License for more details. -/// -/// $Id: 54d117902655b23d2eff9ecaf59ce4eab5f46d42 $ -////////////////////////////////////////////////////////////////////////////// - -/// -/// @defgroup Video The video module. -/// -/// This module contains all video rendering functions. -/// - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <libintl.h> -#define _(str) gettext(str) ///< gettext shortcut -#define _N(str) str ///< gettext_noop shortcut - -#include "misc.h" -#include "video.h" - -////////////////////////////////////////////////////////////////////////////// -// X11 / XCB -////////////////////////////////////////////////////////////////////////////// - -#include <xcb/xcb.h> -#include <xcb/xcb_icccm.h> -#include <xcb/xcb_image.h> -#include <xcb/xcb_pixel.h> -#include <xcb/xcb_event.h> -#include <xcb/xcb_keysyms.h> -#include <X11/keysym.h> // keysym XK_ -#include <X11/XF86keysym.h> // XF86XK_ -#include <poll.h> - -static xcb_connection_t *Connection; ///< xcb connection -static xcb_colormap_t VideoColormap; ///< video colormap -static xcb_window_t VideoOsdWindow; ///< video osd window -static xcb_window_t VideoPlayWindow; ///< video player window -static xcb_screen_t const *VideoScreen; ///< video screen -static uint32_t VideoBlankTick; ///< blank cursor timer -static xcb_pixmap_t VideoPixmap; ///< blank cursor pixmap -static xcb_cursor_t VideoBlankCursor; ///< empty invisible cursor - -static uint32_t VideoColorKey; ///< color key pixel value - -static int VideoWindowX; ///< video output window x coordinate -static int VideoWindowY; ///< video outout window y coordinate -static unsigned VideoWindowWidth; ///< video output window width -static unsigned VideoWindowHeight; ///< video output window height - -static char Osd3DMode; ///< 3D OSD mode - -/// -/// Create X11 window. -/// -/// @param parent parent of new window -/// @param visual visual of parent -/// @param depth depth of parent -/// -/// @returns created X11 window id -/// -static xcb_window_t VideoCreateWindow(xcb_window_t parent, - xcb_visualid_t visual, uint8_t depth) -{ - uint32_t values[5]; - xcb_window_t window; - - Debug(3, "video: visual %#0x depth %d\n", visual, depth); - - // - // create color map - // - if (VideoColormap == XCB_NONE) { - VideoColormap = xcb_generate_id(Connection); - xcb_create_colormap(Connection, XCB_COLORMAP_ALLOC_NONE, VideoColormap, - parent, visual); - } - // - // create blank cursor - // - if (VideoBlankCursor == XCB_NONE) { - VideoPixmap = xcb_generate_id(Connection); - xcb_create_pixmap(Connection, 1, VideoPixmap, parent, 1, 1); - VideoBlankCursor = xcb_generate_id(Connection); - xcb_create_cursor(Connection, VideoBlankCursor, VideoPixmap, - VideoPixmap, 0, 0, 0, 0, 0, 0, 1, 1); - VideoBlankTick = 0; - } - - values[0] = VideoColorKey; // ARGB - values[1] = VideoColorKey; - values[2] = - XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY; - values[3] = VideoColormap; - values[4] = VideoBlankCursor; - window = xcb_generate_id(Connection); - xcb_create_window(Connection, depth, window, parent, VideoWindowX, - VideoWindowY, VideoWindowWidth, VideoWindowHeight, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, - XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | - XCB_CW_COLORMAP | XCB_CW_CURSOR, values); - - // define only available with xcb-utils-0.3.8 -#ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS - // FIXME: utf _NET_WM_NAME - xcb_icccm_set_wm_name(Connection, window, XCB_ATOM_STRING, 8, - sizeof("play control") - 1, "play control"); - xcb_icccm_set_wm_icon_name(Connection, window, XCB_ATOM_STRING, 8, - sizeof("play control") - 1, "play control"); -#endif - // define only available with xcb-utils-0.3.6 -#ifdef XCB_NUM_WM_HINTS_ELEMENTS - // FIXME: utf _NET_WM_NAME - xcb_set_wm_name(Connection, window, XCB_ATOM_STRING, - sizeof("play control") - 1, "play control"); - xcb_set_wm_icon_name(Connection, window, XCB_ATOM_STRING, - sizeof("play control") - 1, "play control"); -#endif - - // FIXME: size hints - - // window above parent - values[0] = parent; - values[1] = XCB_STACK_MODE_ABOVE; - xcb_configure_window(Connection, window, - XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, values); - - return window; -} - -/// -/// Enable OSD 3d mode. -/// -/// @param mode turn 3d mode on/off -/// -void VideoSetOsd3DMode(int mode) -{ - Osd3DMode = mode; -} - -/// -/// Draw a ARGB image. -/// -/// @param x x position of image in osd -/// @param y y position of image in osd -/// @param width width of image -/// @param height height of image -/// @param argb argb image -/// -void VideoDrawARGB(int x, int y, int width, int height, const uint8_t * argb) -{ - xcb_image_t *xcb_image; - xcb_gcontext_t gc; - int sx; - int sy; - int fs; - - if (!Connection) { - Debug(3, "play: FIXME: must restore osd provider\n"); - return; - } - - if (x + y < 1 && (unsigned)height == VideoWindowHeight - && (unsigned)width == VideoWindowWidth) { - fs = 1; - } else { - fs = 0; - } - - gc = xcb_generate_id(Connection); - xcb_create_gc(Connection, gc, VideoOsdWindow, 0, NULL); - - switch (Osd3DMode) { - case 1: // SBS - xcb_image = - xcb_image_create_native(Connection, width / 2, height, - XCB_IMAGE_FORMAT_Z_PIXMAP, VideoScreen->root_depth, NULL, 0L, - NULL); - break; - case 2: // TB - xcb_image = - xcb_image_create_native(Connection, width, height / 2, - XCB_IMAGE_FORMAT_Z_PIXMAP, VideoScreen->root_depth, NULL, 0L, - NULL); - break; - default: - xcb_image = - xcb_image_create_native(Connection, width, height, - XCB_IMAGE_FORMAT_Z_PIXMAP, VideoScreen->root_depth, NULL, 0L, - NULL); - } - - // fast 32it versions - if (xcb_image->bpp == 32) { - if (xcb_image->byte_order == XCB_IMAGE_ORDER_LSB_FIRST) { - for (sy = 0; sy < height; ++sy) { - for (sx = 0; sx < width; ++sx) { - uint32_t pixel; - - if (argb[(width * sy + sx) * 4 + 3] < 200) { - pixel = VideoColorKey; - } else { - pixel = argb[(width * sy + sx) * 4 + 0] << 0; - pixel |= argb[(width * sy + sx) * 4 + 1] << 8; - pixel |= argb[(width * sy + sx) * 4 + 2] << 16; - } - switch (Osd3DMode) { - case 1: // SBS - xcb_image_put_pixel_Z32L(xcb_image, sx / 2, sy, - pixel); - break; - case 2: // TB - xcb_image_put_pixel_Z32L(xcb_image, sx, sy / 2, - pixel); - break; - default: - xcb_image_put_pixel_Z32L(xcb_image, sx, sy, pixel); - } - } - } - } else { - Error(_("play: unsupported put_image\n")); - } - } else { - for (sy = 0; sy < height; ++sy) { - for (sx = 0; sx < width; ++sx) { - uint32_t pixel; - - if (argb[(width * sy + sx) * 4 + 3] < 200) { - pixel = argb[(width * sy + sx) * 4 + 3] << 0; - pixel |= argb[(width * sy + sx) * 4 + 3] << 8; - pixel |= argb[(width * sy + sx) * 4 + 3] << 16; - } else { - pixel = argb[(width * sy + sx) * 4 + 0] << 0; - pixel |= argb[(width * sy + sx) * 4 + 1] << 8; - pixel |= argb[(width * sy + sx) * 4 + 2] << 16; - } - switch (Osd3DMode) { - case 1: // SBS - xcb_image_put_pixel(xcb_image, sx / 2, sy, pixel); - break; - case 2: // TB - xcb_image_put_pixel(xcb_image, sx, sy / 2, pixel); - break; - default: - xcb_image_put_pixel(xcb_image, sx, sy, pixel); - } - } - } - } - - // render xcb_image to color data pixmap - switch (Osd3DMode) { - case 1: // SBS - if (fs) { - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, x, y, - 0); - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, - x + VideoWindowWidth / 2, y, 0); - } else { - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, x / 2, - y, 0); - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, - x / 2 + VideoWindowWidth / 2, y, 0); - } - break; - case 2: // TB - if (fs) { - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, x, y, - 0); - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, x, - y + VideoWindowHeight / 2, 0); - } else { - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, x, - y / 2, 0); - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, x, - y / 2 + VideoWindowHeight / 2, 0); - } - break; - default: - xcb_image_put(Connection, VideoOsdWindow, gc, xcb_image, x, y, 0); - } - // release xcb_image - xcb_image_destroy(xcb_image); - xcb_free_gc(Connection, gc); - xcb_flush(Connection); -} - -/// -/// Show window. -/// -void VideoWindowShow(void) -{ - if (!Connection) { - Debug(3, "play: FIXME: must restore osd provider\n"); - return; - } - xcb_map_window(Connection, VideoOsdWindow); -} - -/// -/// Hide window. -/// -void VideoWindowHide(void) -{ - if (!Connection) { - Debug(3, "play: FIXME: must restore osd provider\n"); - return; - } - xcb_unmap_window(Connection, VideoOsdWindow); -} - -/// -/// Clear window. -/// -void VideoWindowClear(void) -{ - if (!Connection) { - Debug(3, "play: FIXME: must restore osd provider\n"); - return; - } - xcb_clear_area(Connection, 0, VideoOsdWindow, 0, 0, VideoWindowWidth, - VideoWindowHeight); - xcb_flush(Connection); -} - -static xcb_key_symbols_t *XcbKeySymbols; ///< Keyboard symbols -static uint16_t NumLockMask; ///< mod mask for num-lock -static uint16_t ShiftLockMask; ///< mod mask for shift-lock -static uint16_t CapsLockMask; ///< mod mask for caps-lock -static uint16_t ModeSwitchMask; ///< mod mask for mode-switch - -/// -/// Handle key press event. -/// -static void VideoKeyPress(const xcb_key_press_event_t * event) -{ - char buf[2]; - xcb_keysym_t ks0; - xcb_keysym_t ks1; - xcb_keysym_t keysym; - xcb_keycode_t keycode; - unsigned modifier; - - if (!XcbKeySymbols) { - XcbKeySymbols = xcb_key_symbols_alloc(Connection); - if (!XcbKeySymbols) { - Error(_("play/event: can't read key symbols\n")); - return; - } - NumLockMask = ShiftLockMask = CapsLockMask = ModeSwitchMask = 0; - - // FIXME: lock and mode keys are not prepared! - } - - keycode = event->detail; - modifier = event->state; - // handle mode-switch - if (modifier & ModeSwitchMask) { - ks0 = xcb_key_symbols_get_keysym(XcbKeySymbols, keycode, 2); - ks1 = xcb_key_symbols_get_keysym(XcbKeySymbols, keycode, 3); - } else { - ks0 = xcb_key_symbols_get_keysym(XcbKeySymbols, keycode, 0); - ks1 = xcb_key_symbols_get_keysym(XcbKeySymbols, keycode, 1); - } - // use first keysym, if second keysym didn't exists - if (ks1 == XCB_NO_SYMBOL) { - ks1 = ks0; - } - // see xcb-util-0.3.6/keysyms/keysyms.c: - if (!(modifier & XCB_MOD_MASK_SHIFT) && !(modifier & XCB_MOD_MASK_LOCK)) { - keysym = ks0; - } else { - // FIXME: more cases - - keysym = ks0; - } - - // FIXME: use xcb_lookup_string - switch (keysym) { - case XK_space: - FeedKeyPress("XKeySym", "space", 0, 0); - break; - case XK_exclam ... XK_slash: - case XK_0 ... XK_9: - case XK_A ... XK_Z: - case XK_a ... XK_z: - buf[0] = keysym; - buf[1] = '\0'; - FeedKeyPress("XKeySym", buf, 0, 0); - break; - - case XK_BackSpace: - FeedKeyPress("XKeySym", "BackSpace", 0, 0); - break; - case XK_Tab: - FeedKeyPress("XKeySym", "Tab", 0, 0); - break; - case XK_Return: - FeedKeyPress("XKeySym", "Return", 0, 0); - break; - case XK_Escape: - FeedKeyPress("XKeySym", "Escape", 0, 0); - break; - case XK_Delete: - FeedKeyPress("XKeySym", "Delete", 0, 0); - break; - - case XK_Home: - FeedKeyPress("XKeySym", "Home", 0, 0); - break; - case XK_Left: - FeedKeyPress("XKeySym", "Left", 0, 0); - break; - case XK_Up: - FeedKeyPress("XKeySym", "Up", 0, 0); - break; - case XK_Right: - FeedKeyPress("XKeySym", "Right", 0, 0); - break; - case XK_Down: - FeedKeyPress("XKeySym", "Down", 0, 0); - break; - case XK_Page_Up: - FeedKeyPress("XKeySym", "Page_Up", 0, 0); - break; - case XK_Page_Down: - FeedKeyPress("XKeySym", "Page_Down", 0, 0); - break; - case XK_End: - FeedKeyPress("XKeySym", "End", 0, 0); - break; - case XK_Begin: - FeedKeyPress("XKeySym", "Begin", 0, 0); - break; - - case XK_F1: - FeedKeyPress("XKeySym", "F1", 0, 0); - break; - case XK_F2: - FeedKeyPress("XKeySym", "F2", 0, 0); - break; - case XK_F3: - FeedKeyPress("XKeySym", "F3", 0, 0); - break; - case XK_F4: - FeedKeyPress("XKeySym", "F4", 0, 0); - break; - case XK_F5: - FeedKeyPress("XKeySym", "F5", 0, 0); - break; - case XK_F6: - FeedKeyPress("XKeySym", "F6", 0, 0); - break; - case XK_F7: - FeedKeyPress("XKeySym", "F7", 0, 0); - break; - case XK_F8: - FeedKeyPress("XKeySym", "F8", 0, 0); - break; - case XK_F9: - FeedKeyPress("XKeySym", "F9", 0, 0); - break; - case XK_F10: - FeedKeyPress("XKeySym", "F10", 0, 0); - break; - case XK_F11: - FeedKeyPress("XKeySym", "F11", 0, 0); - break; - case XK_F12: - FeedKeyPress("XKeySym", "F12", 0, 0); - break; - - case XF86XK_Red: - FeedKeyPress("XKeySym", "Red", 0, 0); - break; - case XF86XK_Green: - FeedKeyPress("XKeySym", "Green", 0, 0); - break; - case XF86XK_Yellow: - FeedKeyPress("XKeySym", "Yellow", 0, 0); - break; - case XF86XK_Blue: - FeedKeyPress("XKeySym", "Blue", 0, 0); - break; - - case XF86XK_HomePage: - FeedKeyPress("XKeySym", "XF86HomePage", 0, 0); - break; - case XF86XK_AudioLowerVolume: - FeedKeyPress("XKeySym", "XF86AudioLowerVolume", 0, 0); - break; - case XF86XK_AudioMute: - FeedKeyPress("XKeySym", "XF86AudioMute", 0, 0); - break; - case XF86XK_AudioRaiseVolume: - FeedKeyPress("XKeySym", "XF86AudioRaiseVolume", 0, 0); - break; - case XF86XK_AudioPlay: - FeedKeyPress("XKeySym", "XF86AudioPlay", 0, 0); - break; - case XF86XK_AudioStop: - FeedKeyPress("XKeySym", "XF86AudioStop", 0, 0); - break; - case XF86XK_AudioPrev: - FeedKeyPress("XKeySym", "XF86AudioPrev", 0, 0); - break; - case XF86XK_AudioNext: - FeedKeyPress("XKeySym", "XF86AudioNext", 0, 0); - break; - - default: - Debug(3, "play/event: keycode %d\n", event->detail); - break; - - } -} - -/// -/// Poll video events. -/// -/// @param timeout timeout in milliseconds -/// -void VideoPollEvents(int timeout) -{ - struct pollfd fds[1]; - xcb_generic_event_t *event; - int n; - int delay; - - if (!Connection) { - Debug(3, "play: poll without connection\n"); - return; - } - - fds[0].fd = xcb_get_file_descriptor(Connection); - fds[0].events = POLLIN | POLLPRI; - - delay = timeout; - for (;;) { - xcb_flush(Connection); - - // wait for events or timeout - // FIXME: this can poll forever - if ((n = poll(fds, 1, delay)) <= 0) { - // error or timeout - if (n) { // error - Error(_("play/event: poll failed: %s\n"), strerror(errno)); - } - return; - } - if (fds[0].revents & (POLLIN | POLLPRI)) { - if ((event = xcb_poll_for_event(Connection))) { - - switch (XCB_EVENT_RESPONSE_TYPE(event)) { -#if 0 - // background pixmap no need to redraw - case XCB_EXPOSE: - // collapse multi expose - if (!((xcb_expose_event_t *) event)->count) { - xcb_clear_area(Connection, 0, Window, 0, 0, 64, - 64); - // flush the request - xcb_flush(Connection); - } - break; -#endif - case XCB_MAP_NOTIFY: - Debug(3, "video/event: MapNotify\n"); - // hide cursor after mapping - xcb_change_window_attributes(Connection, - VideoOsdWindow, XCB_CW_CURSOR, &VideoBlankCursor); - xcb_change_window_attributes(Connection, - VideoPlayWindow, XCB_CW_CURSOR, &VideoBlankCursor); - break; - case XCB_DESTROY_NOTIFY: - return; - case XCB_KEY_PRESS: - VideoKeyPress((xcb_key_press_event_t *) event); - break; - case XCB_KEY_RELEASE: - case XCB_BUTTON_PRESS: - case XCB_BUTTON_RELEASE: - break; - case XCB_MOTION_NOTIFY: - break; - - case 0: - // error_code - Debug(3, "play/event: error %x\n", - event->response_type); - break; - default: - // unknown event type, ignore it - Debug(3, "play/event: unknown %x\n", - event->response_type); - break; - } - - free(event); - } else { - // no event, can happen, but we must check for close - if (xcb_connection_has_error(Connection)) { - return; - } - } - } - } -} - -/// -/// Get OSD size. -/// -/// @param[out] width OSD width -/// @param[out] height OSD height -/// -void VideoGetOsdSize(int *width, int *height) -{ - *width = 1920; - *height = 1080; // unknown default - if (VideoWindowWidth && VideoWindowHeight) { - *width = VideoWindowWidth; - *height = VideoWindowHeight; - } -} - -/// -/// Get player video window id. -/// -int VideoGetPlayWindow(void) -{ - return VideoPlayWindow; -} - -/// -/// Set video geometry. -/// -/// @todo write/search the good version -/// -void VideoSetGeometry(const char *geometry) -{ - sscanf(geometry, "%dx%d%d%d", &VideoWindowWidth, &VideoWindowHeight, - &VideoWindowX, &VideoWindowY); -} - -/// -/// Set video color key. -/// -/// Should be called before VideoInit(). -/// -void VideoSetColorKey(uint32_t color_key) -{ - VideoColorKey = color_key; -} - -/// -/// Initialize video. -/// -int VideoInit(const char *display) -{ - const char *display_name; - xcb_connection_t *connection; - xcb_screen_iterator_t iter; - int screen_nr; - int i; - - display_name = display ? display : getenv("DISPLAY"); - - // Open the connection to the X server. - connection = xcb_connect(display_name, &screen_nr); - if (!connection || xcb_connection_has_error(connection)) { - fprintf(stderr, "play: can't connect to X11 server on %s\n", - display_name); - return -1; - } - Connection = connection; - - // Get the requested screen number - iter = xcb_setup_roots_iterator(xcb_get_setup(connection)); - for (i = 0; i < screen_nr; ++i) { - xcb_screen_next(&iter); - } - VideoScreen = iter.data; - - // - // Default window size - // - if (!VideoWindowHeight) { - if (VideoWindowWidth) { - VideoWindowHeight = (VideoWindowWidth * 9) / 16; - } else { // default to fullscreen - VideoWindowHeight = VideoScreen->height_in_pixels; - VideoWindowWidth = VideoScreen->width_in_pixels; - } - } - if (!VideoWindowWidth) { - VideoWindowWidth = (VideoWindowHeight * 16) / 9; - } - - VideoPlayWindow = - VideoCreateWindow(VideoScreen->root, VideoScreen->root_visual, - VideoScreen->root_depth); - xcb_map_window(Connection, VideoPlayWindow); - VideoOsdWindow = - VideoCreateWindow(VideoPlayWindow, VideoScreen->root_visual, - VideoScreen->root_depth); - Debug(3, "play: osd %x, play %x\n", VideoOsdWindow, VideoPlayWindow); - - VideoWindowClear(); - // done by clear: xcb_flush(Connection); - - return 0; -} - -/// -/// Cleanup video. -/// -void VideoExit(void) -{ - if (VideoOsdWindow != XCB_NONE) { - xcb_destroy_window(Connection, VideoOsdWindow); - VideoOsdWindow = XCB_NONE; - } - if (VideoPlayWindow != XCB_NONE) { - xcb_destroy_window(Connection, VideoPlayWindow); - VideoPlayWindow = XCB_NONE; - } - if (VideoColormap != XCB_NONE) { - xcb_free_colormap(Connection, VideoColormap); - VideoColormap = XCB_NONE; - } - if (VideoBlankCursor != XCB_NONE) { - xcb_free_cursor(Connection, VideoBlankCursor); - VideoBlankCursor = XCB_NONE; - } - if (VideoPixmap != XCB_NONE) { - xcb_free_pixmap(Connection, VideoPixmap); - VideoPixmap = XCB_NONE; - } - if (XcbKeySymbols != XCB_NONE) { - xcb_key_symbols_free(XcbKeySymbols); - XcbKeySymbols = XCB_NONE; - } - - if (Connection) { - xcb_flush(Connection); - xcb_disconnect(Connection); - Connection = NULL; - } -} |