keys.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:7k
源码类别:

midi

开发平台:

Unix_Linux

  1. /**
  2.  * @file keys.c
  3.  * @brief X C Bindings VLC keyboard event handling
  4.  */
  5. /*****************************************************************************
  6.  * Copyright © 2009 Rémi Denis-Courmont
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License
  10.  * as published by the Free Software Foundation; either version 2.0
  11.  * of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with this library; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  21.  ****************************************************************************/
  22. #ifdef HAVE_CONFIG_H
  23. # include <config.h>
  24. #endif
  25. #include <stdlib.h>
  26. #include <inttypes.h>
  27. #include <ctype.h>
  28. #include <assert.h>
  29. #include <xcb/xcb.h>
  30. #include <xcb/xcb_keysyms.h>
  31. #include <X11/keysym.h>
  32. #include <X11/XF86keysym.h>
  33. #include <vlc_common.h>
  34. #include <vlc_keys.h>
  35. #include "xcb_vlc.h"
  36. struct key_handler_t
  37. {
  38.     vlc_object_t      *obj;
  39.     xcb_key_symbols_t *syms;
  40. };
  41. /**
  42.  * Create an X11 key event handler for a VLC window.
  43.  * The caller shall arrange receiving applicable X11 events, and pass them to
  44.  * ProcessKeyEvent() later.
  45.  *
  46.  * @param obj VLC object owning an X window
  47.  * @param conn XCB connection to the X server (to fetch key mappings)
  48.  * @return NULL on error, or a key handling context.
  49.  */
  50. key_handler_t *CreateKeyHandler (vlc_object_t *obj, xcb_connection_t *conn)
  51. {
  52.     key_handler_t *ctx = malloc (sizeof (*ctx));
  53.     if (!ctx)
  54.         return NULL;
  55.     ctx->obj = obj;
  56.     ctx->syms = xcb_key_symbols_alloc (conn);
  57.     return ctx;
  58. }
  59. void DestroyKeyHandler (key_handler_t *ctx)
  60. {
  61.     xcb_key_symbols_free (ctx->syms);
  62.     free (ctx);
  63. }
  64. static int keysymcmp (const void *pa, const void *pb)
  65. {
  66.     int a = *(const xcb_keysym_t *)pa;
  67.     int b = *(const xcb_keysym_t *)pb;
  68.     return a - b;
  69. }
  70. static int ConvertKeySym (xcb_keysym_t sym)
  71. {
  72.     static const struct
  73.     {
  74.         xcb_keysym_t x11;
  75.         uint32_t vlc;
  76.     } *res, tab[] = {
  77.     /* This list MUST be in XK_* incremental order (see keysymdef.h),
  78.      * so that binary search works.
  79.      * Multiple X keys can match the same VLC key.
  80.      * X key symbols must be in the first column of the struct. */
  81.         { XK_BackSpace,     KEY_BACKSPACE, },
  82.         { XK_Tab,           KEY_TAB, },
  83.         { XK_Return,        KEY_ENTER, },
  84.         { XK_Escape,        KEY_ESC, },
  85.         { XK_Home,          KEY_HOME, },
  86.         { XK_Left,          KEY_LEFT, },
  87.         { XK_Up,            KEY_UP, },
  88.         { XK_Right,         KEY_RIGHT, },
  89.         { XK_Down,          KEY_DOWN, },
  90.         { XK_Page_Up,       KEY_PAGEUP, },
  91.         { XK_Page_Down,     KEY_PAGEDOWN, },
  92.         { XK_End,           KEY_END, },
  93.         { XK_Begin,         KEY_HOME, },
  94.         { XK_Insert,        KEY_INSERT, },
  95.         { XK_Menu,          KEY_MENU },
  96.         { XK_KP_Space,      KEY_SPACE, },
  97.         { XK_KP_Tab,        KEY_TAB, },
  98.         { XK_KP_Enter,      KEY_ENTER, },
  99.         { XK_KP_F1,         KEY_F1, },
  100.         { XK_KP_F2,         KEY_F2, },
  101.         { XK_KP_F3,         KEY_F3, },
  102.         { XK_KP_F4,         KEY_F4, },
  103.         { XK_KP_Home,       KEY_HOME, },
  104.         { XK_KP_Left,       KEY_LEFT, },
  105.         { XK_KP_Up,         KEY_UP, },
  106.         { XK_KP_Right,      KEY_RIGHT, },
  107.         { XK_KP_Down,       KEY_DOWN, },
  108.         { XK_KP_Page_Up,    KEY_PAGEUP, },
  109.         { XK_KP_Page_Down,  KEY_PAGEDOWN, },
  110.         { XK_KP_End,        KEY_END, },
  111.         { XK_KP_Begin,      KEY_HOME, },
  112.         { XK_KP_Insert,     KEY_INSERT, },
  113.         { XK_KP_Delete,     KEY_DELETE, },
  114.         { XK_F1,            KEY_F1, },
  115.         { XK_F2,            KEY_F2, },
  116.         { XK_F3,            KEY_F3, },
  117.         { XK_F4,            KEY_F4, },
  118.         { XK_F5,            KEY_F5, },
  119.         { XK_F6,            KEY_F6, },
  120.         { XK_F7,            KEY_F7, },
  121.         { XK_F8,            KEY_F8, },
  122.         { XK_F9,            KEY_F9, },
  123.         { XK_F10,           KEY_F10, },
  124.         { XK_F11,           KEY_F11, },
  125.         { XK_F12,           KEY_F12, },
  126.         { XK_Delete,        KEY_DELETE, },
  127.         /* XFree86 extensions */
  128.         { XF86XK_AudioLowerVolume, KEY_VOLUME_DOWN, },
  129.         { XF86XK_AudioMute,        KEY_VOLUME_MUTE, },
  130.         { XF86XK_AudioRaiseVolume, KEY_VOLUME_UP, },
  131.         { XF86XK_AudioPlay,        KEY_MEDIA_PLAY_PAUSE, },
  132.         { XF86XK_AudioStop,        KEY_MEDIA_STOP, },
  133.         { XF86XK_AudioPrev,        KEY_MEDIA_PREV_TRACK, },
  134.         { XF86XK_AudioNext,        KEY_MEDIA_NEXT_TRACK, },
  135.         { XF86XK_HomePage,         KEY_BROWSER_HOME, },
  136.         { XF86XK_Search,           KEY_BROWSER_SEARCH, },
  137.         { XF86XK_Back,             KEY_BROWSER_BACK, },
  138.         { XF86XK_Forward,          KEY_BROWSER_FORWARD, },
  139.         { XF86XK_Stop,             KEY_BROWSER_STOP, },
  140.         { XF86XK_Refresh,          KEY_BROWSER_REFRESH, },
  141.         { XF86XK_Favorites,        KEY_BROWSER_FAVORITES, },
  142.         { XF86XK_AudioPause,       KEY_MEDIA_PLAY_PAUSE, },
  143.         { XF86XK_Reload,           KEY_BROWSER_REFRESH, },
  144.     };
  145.     /* X11 and VLC both use the ASCII code for printable ASCII characters,
  146.      * except for space (only X11). */
  147.     if (sym == XK_space)
  148.         return KEY_SPACE;
  149.     if (isascii(sym))
  150.         return sym;
  151.     /* Special keys */
  152.     res = bsearch (&sym, tab, sizeof (tab) / sizeof (tab[0]), sizeof (tab[0]),
  153.                    keysymcmp);
  154.     if (res != NULL)
  155.         return res->vlc;
  156.     return KEY_UNSET;
  157. }
  158. /**
  159.  * Process an X11 event, convert into VLC hotkey event if applicable.
  160.  *
  161.  * @param ctx key handler created with CreateKeyHandler()
  162.  * @param ev XCB event to process
  163.  * @return 0 if the event was handled and free()'d, non-zero otherwise
  164.  */
  165. int ProcessKeyEvent (key_handler_t *ctx, xcb_generic_event_t *ev)
  166. {
  167.     assert (ctx);
  168.     switch (ev->response_type & 0x7f)
  169.     {
  170.         case XCB_KEY_PRESS:
  171.         {
  172.             xcb_key_press_event_t *e = (xcb_key_press_event_t *)ev;
  173.             xcb_keysym_t sym = xcb_key_press_lookup_keysym (ctx->syms, e, 0);
  174.             int vk = ConvertKeySym (sym);
  175.             if (vk == KEY_UNSET)
  176.                 break;
  177.             if (e->state & XCB_MOD_MASK_SHIFT)
  178.                 vk |= KEY_MODIFIER_SHIFT;
  179.             if (e->state & XCB_MOD_MASK_CONTROL)
  180.                 vk |= KEY_MODIFIER_CTRL;
  181.             if (e->state & XCB_MOD_MASK_1)
  182.                 vk |= KEY_MODIFIER_ALT;
  183.             if (e->state & XCB_MOD_MASK_4)
  184.                 vk |= KEY_MODIFIER_COMMAND;
  185.             var_SetInteger (ctx->obj->p_libvlc, "key-pressed", vk);
  186.             break;
  187.         }
  188.         case XCB_KEY_RELEASE:
  189.             break;
  190.         /*TODO: key mappings update*/
  191.         default:
  192.             return -1;
  193.     }
  194.     free (ev);
  195.     return 0;
  196. }