147 lines
4 KiB
C++
147 lines
4 KiB
C++
// Released under the MIT license. X11 backend by Duuqnd.
|
|
// See LICENSE.txt for details.
|
|
|
|
#include "../Misc.h"
|
|
|
|
#include "../Rendering.h"
|
|
#include "../../Attributes.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <unistd.h>
|
|
#include <cstring>
|
|
#include <sys/time.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <X11/keysym.h>
|
|
|
|
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);
|
|
}
|