aboutsummaryrefslogtreecommitdiff
path: root/src/window
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-10-31 12:50:05 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-02 02:23:54 +0100
commit111f0ba3f4a4f14d39c8e3f7c00f13e852f47a51 (patch)
treefc7317e332c7a56df7738a62110ad76d4fc8511c /src/window
parent8a316a12481282cb2ab966c4cbc770656c258383 (diff)
Start on syntax highlighting, output correct key button event
Diffstat (limited to 'src/window')
-rw-r--r--src/window/window.c120
1 files changed, 112 insertions, 8 deletions
diff --git a/src/window/window.c b/src/window/window.c
index 94756cd..9a650ae 100644
--- a/src/window/window.c
+++ b/src/window/window.c
@@ -1,4 +1,5 @@
#include "../../include/mgl/window/window.h"
+#include "../../include/mgl/window/event.h"
#include "../../include/mgl/mgl.h"
#include <X11/Xutil.h>
#include <errno.h>
@@ -140,23 +141,127 @@ void mgl_window_deinit(mgl_window *self) {
}
}
-static void mgl_window_on_receive_event(mgl_window *self, XEvent *xev) {
+static mgl_key x11_keysym_to_mgl_key(KeySym key_sym) {
+ if(key_sym >= XK_A && key_sym <= XK_Z)
+ return MGL_KEY_A + (key_sym - XK_A);
+ /* TODO: Check if this ever happens */
+ if(key_sym >= XK_a && key_sym <= XK_z)
+ return MGL_KEY_A + (key_sym - XK_a);
+ if(key_sym >= XK_0 && key_sym <= XK_9)
+ return MGL_KEY_NUM0 + (key_sym - XK_0);
+ if(key_sym >= XK_KP_0 && key_sym <= XK_KP_9)
+ return MGL_KEY_NUMPAD0 + (key_sym - XK_KP_0);
+
+ /* TODO: Fill in the rest */
+ switch(key_sym) {
+ case XK_space: return MGL_KEY_SPACE;
+ case XK_BackSpace: return MGL_KEY_BACKSPACE;
+ case XK_Tab: return MGL_KEY_TAB;
+ case XK_Return: return MGL_KEY_ENTER;
+ case XK_Delete: return MGL_KEY_DELETE;
+ case XK_Home: return MGL_KEY_HOME;
+ case XK_Left: return MGL_KEY_LEFT;
+ case XK_Up: return MGL_KEY_UP;
+ case XK_Right: return MGL_KEY_RIGHT;
+ case XK_Down: return MGL_KEY_DOWN;
+ case XK_Page_Up: return MGL_KEY_PAGEUP;
+ case XK_Page_Down: return MGL_KEY_PAGEDOWN;
+ case XK_End: return MGL_KEY_END;
+ case XK_F1: return MGL_KEY_F1;
+ case XK_F2: return MGL_KEY_F2;
+ case XK_F3: return MGL_KEY_F3;
+ case XK_F4: return MGL_KEY_F4;
+ case XK_F5: return MGL_KEY_F5;
+ case XK_F6: return MGL_KEY_F6;
+ case XK_F7: return MGL_KEY_F7;
+ case XK_F8: return MGL_KEY_F8;
+ case XK_F9: return MGL_KEY_F9;
+ case XK_F10: return MGL_KEY_F10;
+ case XK_F11: return MGL_KEY_F11;
+ case XK_F12: return MGL_KEY_F12;
+ case XK_F13: return MGL_KEY_F13;
+ case XK_F14: return MGL_KEY_F14;
+ case XK_F15: return MGL_KEY_F15;
+ }
+ return MGL_KEY_UNKNOWN;
+}
+
+static mgl_mouse_button x11_button_to_mgl_button(unsigned int button) {
+ switch(button) {
+ case 1: return MGL_BUTTON_LEFT;
+ case 2: return MGL_BUTTON_MIDDLE;
+ case 3: return MGL_BUTTON_RIGHT;
+ case 8: return MGL_BUTTON_XBUTTON1;
+ case 9: return MGL_BUTTON_XBUTTON2;
+ }
+ return MGL_BUTTON_UNKNOWN;
+}
+
+/* Returns true if processed */
+static bool mgl_window_on_receive_event(mgl_window *self, XEvent *xev, mgl_event *event, mgl_context *context) {
+ /* TODO: Handle wm_delete_window event */
switch(xev->type) {
+ case KeyPress: {
+ /* TODO: Fill with correct data */
+ event->type = MGL_EVENT_KEY_PRESSED;
+ event->key.code = x11_keysym_to_mgl_key(XKeycodeToKeysym(context->connection, xev->xkey.keycode, 0));
+ event->key.alt = ((xev->xkey.state & Mod1Mask) != 0);
+ event->key.control = ((xev->xkey.state & ControlMask) != 0);
+ event->key.shift = ((xev->xkey.state & ShiftMask) != 0);
+ event->key.system = ((xev->xkey.state & Mod5Mask) != 0); /* TODO: Fix, doesn't work */
+ return true;
+ }
+ case KeyRelease: {
+ /* TODO: Fill with correct data */
+ event->type = MGL_EVENT_KEY_RELEASED;
+ event->key.code = x11_keysym_to_mgl_key(XKeycodeToKeysym(context->connection, xev->xkey.keycode, 0));
+ event->key.alt = ((xev->xkey.state & Mod1Mask) != 0);
+ event->key.control = ((xev->xkey.state & ControlMask) != 0);
+ event->key.shift = ((xev->xkey.state & ShiftMask) != 0);
+ event->key.system = ((xev->xkey.state & Mod5Mask) != 0); /* TODO: Fix, doesn't work */
+ return true;
+ }
+ case ButtonPress: {
+ event->type = MGL_EVENT_MOUSE_BUTTON_PRESSED;
+ event->mouse_button.button = x11_button_to_mgl_button(xev->xbutton.button);
+ event->mouse_button.x = xev->xbutton.x;
+ event->mouse_button.y = xev->xbutton.y;
+ return true;
+ }
+ case ButtonRelease: {
+ event->type = MGL_EVENT_MOUSE_BUTTON_RELEASED;
+ event->mouse_button.button = x11_button_to_mgl_button(xev->xbutton.button);
+ event->mouse_button.x = xev->xbutton.x;
+ event->mouse_button.y = xev->xbutton.y;
+ return true;
+ }
case ConfigureNotify: {
while(XCheckTypedWindowEvent(mgl_get_context()->connection, self->window, ConfigureNotify, xev)) {}
if(xev->xconfigure.width != self->size.x || xev->xconfigure.height != self->size.x) {
mgl_window_on_resize(self, xev->xconfigure.width, xev->xconfigure.height);
- /*fprintf(stderr, "resize!\n");*/
+
+ event->type = MGL_EVENT_RESIZED;
+ event->size.width = self->size.x;
+ event->size.height = self->size.y;
+ event->mouse_move.y = self->cursor_position.y;
+ return true;
}
- break;
+ return false;
}
case MotionNotify: {
while(XCheckTypedWindowEvent(mgl_get_context()->connection, self->window, MotionNotify, xev)) {}
self->cursor_position.x = xev->xmotion.x;
self->cursor_position.y = xev->xmotion.y;
- break;
+
+ event->type = MGL_EVENT_MOUSE_MOVED;
+ event->mouse_move.x = self->cursor_position.x;
+ event->mouse_move.y = self->cursor_position.y;
+ return true;
}
}
+ /*fprintf(stderr, "unhandled event type: %d\n", xev->type);*/
+ event->type = MGL_EVENT_UNKNOWN;
+ return false;
}
void mgl_window_clear(mgl_window *self, mgl_color color) {
@@ -166,13 +271,12 @@ void mgl_window_clear(mgl_window *self, mgl_color color) {
}
bool mgl_window_poll_event(mgl_window *self, mgl_event *event) {
- /* TODO: Use |event| */
-
- Display *display = mgl_get_context()->connection;
+ mgl_context *context = mgl_get_context();
+ Display *display = context->connection;
if(XPending(display)) {
XEvent xev; /* TODO: Move to window struct */
XNextEvent(display, &xev);
- mgl_window_on_receive_event(self, &xev);
+ mgl_window_on_receive_event(self, &xev, event, context);
return true;
} else {
return false;