// Released under the MIT license. X11 backend by Duuqnd. // See LICENSE.txt for details. #include "../Misc.h" #include "../Rendering.h" #include "../../Attributes.h" #include #include #include #include #include #include #include #include #include #include static bool keyboardState[BACKEND_KEYBOARD_TOTAL]; Display* xDisplay; Visual* xVisual; static XVisualInfo xvisinfo; static unsigned long startTime; bool Backend_Init(void (*drag_and_drop_callback)(const char *path), void (*window_focus_callback)(bool focus)) { // we're ignoring the hell out of focus and drag & drop xDisplay = XOpenDisplay(NULL); //XMatchVisualInfo(xDisplay, DefaultScreen(xDisplay), 24, DirectColor, &xvisinfo); //xVisual = xvisinfo.visual; struct timeval time; // time.tv_usec is microseconds gettimeofday(&time, NULL); startTime = (time.tv_sec * 1000) + (time.tv_usec / 1000); return true; } void Backend_Deinit(void) { XCloseDisplay(xDisplay); } void Backend_PostWindowCreation(void) {} bool Backend_GetPaths(std::string *module_path, std::string *data_path) { return false; // I assume this means "do it yourself, lazy" } void Backend_HideMouse(void) {} void Backend_SetWindowIcon(const unsigned char *rgb_pixels, size_t width, size_t height) { // Oh we'll want this for sure! } void Backend_SetCursor(const unsigned char *rgb_pixels, size_t width, size_t height) {} void Backend_EnableDragAndDrop(void) {} #define DOKEY(keych, keymac) { if(keysym == keych) keyboardState[keymac] = press; } static void DoKeys(KeySym keysym, bool press) { // X keysyms are case sensitive. Isn't it great?! DOKEY(XK_z, BACKEND_KEYBOARD_Z); DOKEY(XK_x, BACKEND_KEYBOARD_X); DOKEY(XK_Z, BACKEND_KEYBOARD_Z); DOKEY(XK_X, BACKEND_KEYBOARD_X); DOKEY(XK_a, BACKEND_KEYBOARD_A); DOKEY(XK_s, BACKEND_KEYBOARD_S); DOKEY(XK_A, BACKEND_KEYBOARD_A); DOKEY(XK_S, BACKEND_KEYBOARD_S); DOKEY(XK_q, BACKEND_KEYBOARD_Q); DOKEY(XK_w, BACKEND_KEYBOARD_W); DOKEY(XK_Q, BACKEND_KEYBOARD_Q); DOKEY(XK_W, BACKEND_KEYBOARD_W); DOKEY(XK_Escape, BACKEND_KEYBOARD_ESCAPE); DOKEY(XK_F1, BACKEND_KEYBOARD_F1); DOKEY(XK_F2, BACKEND_KEYBOARD_F2); DOKEY(XK_Left, BACKEND_KEYBOARD_LEFT); DOKEY(XK_Right, BACKEND_KEYBOARD_RIGHT); DOKEY(XK_Up, BACKEND_KEYBOARD_UP); DOKEY(XK_Down, BACKEND_KEYBOARD_DOWN); } bool Backend_SystemTask(bool active) { if(!active) { return false; } XEvent e; while(XPending(xDisplay) > 0) { XNextEvent(xDisplay, &e); if(e.type == KeyPress) { KeySym keysym = XLookupKeysym((XKeyEvent*)&e, 0); if(keysym == XK_Insert) { return false; } DoKeys(keysym, true); } if(e.type == KeyRelease) { KeySym keysym = XLookupKeysym((XKeyEvent*)&e, 0); DoKeys(keysym, false); } } return true; } void Backend_GetKeyboardState(bool *out_keyboard_state) { memcpy(out_keyboard_state, keyboardState, sizeof(keyboardState)); } ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...) { va_list argumentList; va_start(argumentList, format); fputs("ERROR: ", stderr); vfprintf(stderr, format, argumentList); fputc('\n', stderr); va_end(argumentList); } ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...) { va_list argumentList; va_start(argumentList, format); fputs("INFO: ", stdout); vfprintf(stdout, format, argumentList); fputc('\n', stdout); va_end(argumentList); } void Backend_ShowMessageBox(const char* title, const char* message) { printf("ShowMessageBox: %s - %s\n", title, message); } unsigned long Backend_GetTicks(void) { struct timeval time; // time.tv_usec is microseconds gettimeofday(&time, NULL); unsigned long ticktime = ((time.tv_sec * 1000) + (time.tv_usec / 1000)) - startTime; return ticktime; } void Backend_Delay(unsigned int ticks) { usleep(ticks * 1000); }