📄 x11_out.c
字号:
/* * GPAC Multimedia Framework * * Authors: DINH Anh Min - Jean le Feuvre * Copyright (c) 2005-200X ENST * All rights reserved * * This file is part of GPAC / X11 video output module * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "x11_out.h"#include <gpac/constants.h>void X11_SetupWindow (GF_VideoOutput * vout);//=====================================/* * Flush video: draw main image(surface/pixmap) -> os_handle *///=====================================GF_Err X11_Flush(struct _video_out *vout, GF_Window * dest){ Window cur_wnd; /* * write backbuffer to screen */ X11VID (); XSync(xWindow->display, False); if (!xWindow->is_init) return GF_OK; cur_wnd = xWindow->fullscreen ? xWindow->full_wnd : xWindow->wnd; if (xWindow->is_3D_out) {#ifdef GPAC_HAS_OPENGL glXSwapBuffers(xWindow->display, cur_wnd);#endif return GF_OK; } switch (xWindow->videoaccesstype) {#ifdef GPAC_HAS_X11_SHM case VIDEO_XI_SHMSTD: XShmPutImage (xWindow->display, cur_wnd, xWindow->the_gc, xWindow->surface, 0, 0, dest->x, dest->y, dest->w, dest->h, True); break; case VIDEO_XI_SHMPIXMAP: XClearWindow(xWindow->display, cur_wnd); break;#endif case VIDEO_XI_STANDARD: XRaiseWindow(xWindow->display, xWindow->wnd); XPutImage (xWindow->display, cur_wnd, xWindow->the_gc, xWindow->surface, 0, 0, dest->x, dest->y, dest->w, dest->h); break; } return GF_OK;}//=====================================/* * Translate X_Key to GF_Key *///=====================================static void x11_translate_key(u32 X11Key, GF_EventKey *evt){ evt->flags = 0; evt->hw_code = X11Key & 0xFF; switch (X11Key) { case XK_BackSpace: evt->key_code = GF_KEY_BACKSPACE; break; case XK_Tab: evt->key_code = GF_KEY_TAB; break; //case XK_Linefeed: evt->key_code = GF_KEY_LINEFEED; break; case XK_Clear: evt->key_code = GF_KEY_CLEAR; break; case XK_KP_Enter: evt->flags = GF_KEY_EXT_NUMPAD; case XK_Return: evt->key_code = GF_KEY_ENTER; break; case XK_Pause: evt->key_code = GF_KEY_PAUSE; break; case XK_Caps_Lock: evt->key_code = GF_KEY_CAPSLOCK; break; case XK_Scroll_Lock: evt->key_code = GF_KEY_SCROLL; break; case XK_Escape: evt->key_code = GF_KEY_ESCAPE; break; case XK_Delete: evt->key_code = GF_KEY_DEL; break; case XK_Kanji: evt->key_code = GF_KEY_KANJIMODE; break; case XK_Katakana: evt->key_code = GF_KEY_JAPANESEKATAKANA; break; case XK_Romaji: evt->key_code = GF_KEY_JAPANESEROMAJI; break; case XK_Hiragana: evt->key_code = GF_KEY_JAPANESEHIRAGANA; break; case XK_Kana_Lock: evt->key_code = GF_KEY_KANAMODE; break; case XK_Home: evt->key_code = GF_KEY_HOME; break; case XK_Left: evt->key_code = GF_KEY_LEFT; break; case XK_Up: evt->key_code = GF_KEY_UP; break; case XK_Right: evt->key_code = GF_KEY_RIGHT; break; case XK_Down: evt->key_code = GF_KEY_DOWN; break; case XK_Page_Up: evt->key_code = GF_KEY_PAGEUP; break; case XK_Page_Down: evt->key_code = GF_KEY_PAGEDOWN; break; case XK_End: evt->key_code = GF_KEY_END; break; //case XK_Begin: evt->key_code = GF_KEY_BEGIN; break; case XK_Select: evt->key_code = GF_KEY_SELECT; break; case XK_Print: evt->key_code = GF_KEY_PRINTSCREEN; break; case XK_Execute: evt->key_code = GF_KEY_EXECUTE; break; case XK_Insert: evt->key_code = GF_KEY_INSERT; break; case XK_Undo: evt->key_code = GF_KEY_UNDO; break; //case XK_Redo: evt->key_code = GF_KEY_BEGIN; break; //case XK_Menu: evt->key_code = GF_KEY_BEGIN; break; case XK_Find: evt->key_code = GF_KEY_FIND; break; case XK_Cancel: evt->key_code = GF_KEY_CANCEL; break; case XK_Help: evt->key_code = GF_KEY_HELP; break; //case XK_Break: evt->key_code = GF_KEY_BREAK; break; //case XK_Mode_switch: evt->key_code = GF_KEY_BEGIN; break; case XK_Num_Lock: evt->key_code = GF_KEY_NUMLOCK; break; case XK_F1: evt->key_code = GF_KEY_F1; break; case XK_F2: evt->key_code = GF_KEY_F2; break; case XK_F3: evt->key_code = GF_KEY_F3; break; case XK_F4: evt->key_code = GF_KEY_F4; break; case XK_F5: evt->key_code = GF_KEY_F5; break; case XK_F6: evt->key_code = GF_KEY_F6; break; case XK_F7: evt->key_code = GF_KEY_F7; break; case XK_F8: evt->key_code = GF_KEY_F8; break; case XK_F9: evt->key_code = GF_KEY_F9; break; case XK_F10: evt->key_code = GF_KEY_F10; break; case XK_F11: evt->key_code = GF_KEY_F11; break; case XK_F12: evt->key_code = GF_KEY_F12; break; case XK_F13: evt->key_code = GF_KEY_F13; break; case XK_F14: evt->key_code = GF_KEY_F14; break; case XK_F15: evt->key_code = GF_KEY_F15; break; case XK_F16: evt->key_code = GF_KEY_F16; break; case XK_F17: evt->key_code = GF_KEY_F17; break; case XK_F18: evt->key_code = GF_KEY_F18; break; case XK_F19: evt->key_code = GF_KEY_F19; break; case XK_F20: evt->key_code = GF_KEY_F20; break; case XK_F21: evt->key_code = GF_KEY_F21; break; case XK_F22: evt->key_code = GF_KEY_F22; break; case XK_F23: evt->key_code = GF_KEY_F23; break; case XK_F24: evt->key_code = GF_KEY_F24; break; case XK_KP_Delete: case XK_KP_Decimal: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_COMMA; break; case XK_KP_Insert: case XK_KP_0: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_0; break; case XK_KP_End: case XK_KP_1: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_1; break; case XK_KP_Down: case XK_KP_2: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_2; break; case XK_KP_Page_Down: case XK_KP_3: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_3; break; case XK_KP_Left: case XK_KP_4: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_4; break; case XK_KP_Begin: case XK_KP_5: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_5; break; case XK_KP_Right: case XK_KP_6: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_6; break; case XK_KP_Home: case XK_KP_7: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_7; break; case XK_KP_Up: case XK_KP_8: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_8; break; case XK_KP_Page_Up: case XK_KP_9: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_9; break; case XK_KP_Add: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_PLUS; break; case XK_KP_Subtract: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_HYPHEN; break; case XK_KP_Multiply: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_STAR; break; case XK_KP_Divide: evt->flags = GF_KEY_EXT_NUMPAD; evt->key_code = GF_KEY_SLASH; break; case XK_Shift_R: evt->flags = GF_KEY_EXT_RIGHT; case XK_Shift_L: evt->key_code = GF_KEY_SHIFT; break; case XK_Control_R: evt->flags = GF_KEY_EXT_RIGHT; case XK_Control_L: evt->key_code = GF_KEY_CONTROL; break; case XK_Alt_R: evt->flags = GF_KEY_EXT_RIGHT; case XK_Alt_L: evt->key_code = GF_KEY_ALT; break; case XK_Super_R: evt->flags = GF_KEY_EXT_RIGHT; case XK_Super_L: evt->key_code = GF_KEY_WIN; break; case XK_Menu: evt->key_code = GF_KEY_META; break;#ifdef XK_XKB_KEYS case XK_ISO_Level3_Shift: evt->key_code = GF_KEY_ALTGRAPH; break;#endif case '!': evt->key_code = GF_KEY_EXCLAMATION; break; case '"': evt->key_code = GF_KEY_QUOTATION; break; case '#': evt->key_code = GF_KEY_NUMBER; break; case '$': evt->key_code = GF_KEY_DOLLAR; break; case '&': evt->key_code = GF_KEY_AMPERSAND; break; case '\'': evt->key_code = GF_KEY_APOSTROPHE; break; case '(': evt->key_code = GF_KEY_LEFTPARENTHESIS; break; case ')': evt->key_code = GF_KEY_RIGHTPARENTHESIS; break; case ',': evt->key_code = GF_KEY_COMMA; break; case ':': evt->key_code = GF_KEY_COLON; break; case ';': evt->key_code = GF_KEY_SEMICOLON; break; case '<': evt->key_code = GF_KEY_LESSTHAN; break; case '>': evt->key_code = GF_KEY_GREATERTHAN; break; case '?': evt->key_code = GF_KEY_QUESTION; break; case '@': evt->key_code = GF_KEY_AT; break; case '[': evt->key_code = GF_KEY_LEFTSQUAREBRACKET; break; case ']': evt->key_code = GF_KEY_RIGHTSQUAREBRACKET; break; case '\\': evt->key_code = GF_KEY_BACKSLASH; break; case '_': evt->key_code = GF_KEY_UNDERSCORE; break; case '`': evt->key_code = GF_KEY_GRAVEACCENT; break; case ' ': evt->key_code = GF_KEY_SPACE; break; case '/': evt->key_code = GF_KEY_SLASH; break; case '*': evt->key_code = GF_KEY_STAR; break; case '-': evt->key_code = GF_KEY_HYPHEN; break; case '+': evt->key_code = GF_KEY_PLUS; break; case '=': evt->key_code = GF_KEY_EQUALS; break; case '^': evt->key_code = GF_KEY_CIRCUM; break; case '{': evt->key_code = GF_KEY_LEFTCURLYBRACKET; break; case '}': evt->key_code = GF_KEY_RIGHTCURLYBRACKET; break; case '|': evt->key_code = GF_KEY_PIPE; break; default: if ((X11Key>='0') && (X11Key<='9')) evt->key_code = GF_KEY_0 + X11Key - '0'; else if ((X11Key>='A') && (X11Key<='Z')) evt->key_code = GF_KEY_A + X11Key - 'A'; /*DOM3: translate to A -> Z, not a -> z*/ else if ((X11Key>='a') && (X11Key<='z')) { evt->key_code = GF_KEY_A + X11Key - 'a'; evt->hw_code = X11Key - 'a' + 'A'; } else { evt->key_code = 0; GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[X11] Unrecognized key %X\n", X11Key)); } break; }}/* taken from SDL Ack! XPending() actually performs a blocking read if no events available */static int X11_Pending(Display *display){ /* Flush the display connection and look to see if events are queued */ XFlush(display); if ( XEventsQueued(display, QueuedAlready) ) return(1); /* More drastic measures are required -- see if X is ready to talk */ { static struct timeval zero_time; /* static == 0 */ int x11_fd; fd_set fdset; x11_fd = ConnectionNumber(display); FD_ZERO(&fdset); FD_SET(x11_fd, &fdset); if ( select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1 ) { return(XPending(display)); } } /* Oh well, nothing is ready .. */ return(0);}/* * handle X11 events * here we handle key, mouse, repaint and window sizing events */static void X11_HandleEvents(GF_VideoOutput *vout){ GF_Event evt; Window the_window; XComposeStatus state; X11VID(); unsigned char keybuf[32]; XEvent xevent; the_window = xWindow->fullscreen ? xWindow->full_wnd : xWindow->wnd; XSync(xWindow->display, False); while (X11_Pending(xWindow->display)) { XNextEvent(xWindow->display, &xevent); if (xevent.xany.window!=the_window) continue; switch (xevent.type) { /* * X11 window resized event * must inform GPAC to resize os_handle wnd */ case ConfigureNotify: if ((unsigned int) xevent.xconfigure.width != xWindow->w_width || (unsigned int) xevent.xconfigure.height != xWindow->w_height) { evt.type = GF_EVENT_SIZE; xWindow->w_width = evt.size.width = xevent.xconfigure.width; xWindow->w_height = evt.size.height = xevent.xconfigure.height; vout->on_event(vout->evt_cbk_hdl, &evt); } break; /* * Windows need repaint */ case Expose: if (xevent.xexpose.count > 0) break; evt.type = GF_EVENT_REFRESH; vout->on_event (vout->evt_cbk_hdl, &evt); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -