From 111f0ba3f4a4f14d39c8e3f7c00f13e852f47a51 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 31 Oct 2021 12:50:05 +0100 Subject: Start on syntax highlighting, output correct key button event --- TODO | 13 ++--- include/mgl/graphics/text.h | 23 ++++++++- include/mgl/mgl.h | 3 +- include/mgl/window/event.h | 54 +++++++++++++++++++- include/mgl/window/key.h | 109 ++++++++++++++++++++++++++++++++++++++++ include/mgl/window/window.h | 3 ++ src/graphics/font.c | 9 ++-- src/graphics/text.c | 67 +++++++++++++++++++++---- src/mgl.c | 25 +++++++-- src/window/window.c | 120 +++++++++++++++++++++++++++++++++++++++++--- 10 files changed, 390 insertions(+), 36 deletions(-) create mode 100644 include/mgl/window/key.h diff --git a/TODO b/TODO index 611b9c1..a4715d0 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,8 @@ Handle window close (window destroyed event, disconnected from server and socket becomes invalid (check select return?)).\ -Bind texture and cache the bound texture to reduce calls to opengl. -Use gl triangle instead of quad. -Fix crash on exit. -Support using multiple textures in shaders by using glActiveTexture for each one and set the uniform sampler2D value for each as as the index. -Make sure clock is monotonic (there has been some issues with CLOCK\_MONOTONIC not being monotonic on linux). -Verify if using a separate glx context for every window is the correct approach. \ No newline at end of file +Bind texture and cache the bound texture to reduce calls to opengl.\ +Use gl triangle instead of quad.\ +Fix crash on exit.\ +Support using multiple textures in shaders by using glActiveTexture for each one and set the uniform sampler2D value for each as as the index.\ +Make sure clock is monotonic (there has been some issues with CLOCK\_MONOTONIC not being monotonic on linux).\ +Verify if using a separate glx context for every window is the correct approach.\ +Respond to wm ping. \ No newline at end of file diff --git a/include/mgl/graphics/text.h b/include/mgl/graphics/text.h index 2c2eeaf..9169ab0 100644 --- a/include/mgl/graphics/text.h +++ b/include/mgl/graphics/text.h @@ -1,28 +1,47 @@ #ifndef MGL_TEXT_H #define MGL_TEXT_H +/* + TODO: Do not render text outside the window and start from the visible part. + Support 64-bit text length on 32-bit systems, and use mmap to optimize loading very large files, + and munmap the text parts that are not visible on the screen. +*/ + #include "../system/vec.h" #include "color.h" +#include +#include typedef struct mgl_font mgl_font; typedef struct mgl_context mgl_context; +typedef struct { + /* Optional */ + void (*before_syntax_highlight)(void *userdata); + /* Return true if the text format should be changed. Optional */ + bool (*syntax_highlight)(void *userdata, const char *str, size_t size, mgl_color *color); + void *userdata; +} mgl_text_options; + typedef struct { mgl_font *font; /* nullable */ const char *text; /* nullable */ + size_t text_size; mgl_color color; mgl_vec2f position; + mgl_text_options options; } mgl_text; /* Note: keeps a reference to |text|. |text| needs to be valid as long as |self| is used. |font| and |text| may be NULL. + |load_options| can be NULL, in which case the default options are used. */ -int mgl_text_init(mgl_text *self, mgl_font *font, const char *text, float x, float y); +int mgl_text_init(mgl_text *self, mgl_font *font, const char *str, size_t str_size, mgl_text_options *options); void mgl_text_deinit(mgl_text *self); /* Note: keeps a reference to |text|. |text| needs to be valid as long as |self| is used. |text| may be NULL. */ -void mgl_text_set_string(mgl_text *self, const char *str); +void mgl_text_set_string(mgl_text *self, const char *str, size_t str_size); /* |font| may be NULL */ void mgl_text_set_font(mgl_text *self, mgl_font *font); void mgl_text_set_position(mgl_text *self, mgl_vec2f position); diff --git a/include/mgl/mgl.h b/include/mgl/mgl.h index 8e5e2a4..b9d007e 100644 --- a/include/mgl/mgl.h +++ b/include/mgl/mgl.h @@ -9,8 +9,9 @@ typedef struct mgl_context mgl_context; struct mgl_context { mgl_connection connection; - _XVisualInfo *visual_info; mgl_gl gl; + _XVisualInfo *visual_info; + unsigned long wm_delete_window_atom; }; /* diff --git a/include/mgl/window/event.h b/include/mgl/window/event.h index 2aea478..020d5c9 100644 --- a/include/mgl/window/event.h +++ b/include/mgl/window/event.h @@ -1,10 +1,62 @@ #ifndef MGL_EVENT_H #define MGL_EVENT_H +#include "key.h" +#include + typedef struct mgl_event mgl_event; +typedef struct { + int width; + int height; +} mgl_size_event; + +typedef struct { + int code; /* mgl_key */ + bool alt; + bool control; + bool shift; + bool system; +} mgl_key_event; + +typedef struct { + int x; /* relative to left of the window */ + int y; /* relative to the top of the window */ +} mgl_mouse_move_event; + +typedef enum { + MGL_BUTTON_UNKNOWN, + MGL_BUTTON_LEFT, + MGL_BUTTON_RIGHT, + MGL_BUTTON_MIDDLE, + MGL_BUTTON_XBUTTON1, + MGL_BUTTON_XBUTTON2 +} mgl_mouse_button; + +typedef struct { + int button; /* mgl_mouse_button */ + int x; /* relative to left of the window */ + int y; /* relative to top of the window */ +} mgl_mouse_button_event; + +typedef enum { + MGL_EVENT_UNKNOWN, + MGL_EVENT_RESIZED, + MGL_EVENT_KEY_PRESSED, + MGL_EVENT_KEY_RELEASED, + MGL_EVENT_MOUSE_BUTTON_PRESSED, + MGL_EVENT_MOUSE_BUTTON_RELEASED, + MGL_EVENT_MOUSE_MOVED +} mgl_event_type; + struct mgl_event { - int type; + int type; /* mgl_event_type */ + union { + mgl_size_event size; + mgl_key_event key; + mgl_mouse_button_event mouse_button; + mgl_mouse_move_event mouse_move; + }; }; #endif /* MGL_EVENT_H */ diff --git a/include/mgl/window/key.h b/include/mgl/window/key.h new file mode 100644 index 0000000..90a3366 --- /dev/null +++ b/include/mgl/window/key.h @@ -0,0 +1,109 @@ +#ifndef _MGL_KEY_H_ +#define _MGL_KEY_H_ + +typedef enum { + MGL_KEY_UNKNOWN, + MGL_KEY_A, + MGL_KEY_B, + MGL_KEY_C, + MGL_KEY_D, + MGL_KEY_E, + MGL_KEY_F, + MGL_KEY_G, + MGL_KEY_H, + MGL_KEY_I, + MGL_KEY_J, + MGL_KEY_K, + MGL_KEY_L, + MGL_KEY_M, + MGL_KEY_N, + MGL_KEY_O, + MGL_KEY_P, + MGL_KEY_Q, + MGL_KEY_R, + MGL_KEY_S, + MGL_KEY_T, + MGL_KEY_U, + MGL_KEY_V, + MGL_KEY_W, + MGL_KEY_X, + MGL_KEY_Y, + MGL_KEY_Z, + MGL_KEY_NUM0, + MGL_KEY_NUM1, + MGL_KEY_NUM2, + MGL_KEY_NUM3, + MGL_KEY_NUM4, + MGL_KEY_NUM5, + MGL_KEY_NUM6, + MGL_KEY_NUM7, + MGL_KEY_NUM8, + MGL_KEY_NUM9, + MGL_KEY_ESCAPE, + MGL_KEY_LCONTROL, + MGL_KEY_LSHIFT, + MGL_KEY_LALT, + MGL_KEY_LSYSTEM, + MGL_KEY_RCONTROL, + MGL_KEY_RSHIFT, + MGL_KEY_RALT, + MGL_KEY_RSYSTEM, + MGL_KEY_MENU, + MGL_KEY_LBRACKET, + MGL_KEY_RBRACKET, + MGL_KEY_SEMICOLON, + MGL_KEY_COMMA, + MGL_KEY_PERIOD, + MGL_KEY_QUOTE, + MGL_KEY_SLASH, + MGL_KEY_BACKSLASH, + MGL_KEY_TILDE, + MGL_KEY_EQUAL, + MGL_KEY_HYPHEN, + MGL_KEY_SPACE, + MGL_KEY_ENTER, + MGL_KEY_BACKSPACE, + MGL_KEY_TAB, + MGL_KEY_PAGEUP, + MGL_KEY_PAGEDOWN, + MGL_KEY_END, + MGL_KEY_HOME, + MGL_KEY_INSERT, + MGL_KEY_DELETE, + MGL_KEY_ADD, + MGL_KEY_SUBTRACT, + MGL_KEY_MULTIPLY, + MGL_KEY_DIVIDE, + MGL_KEY_LEFT, + MGL_KEY_RIGHT, + MGL_KEY_UP, + MGL_KEY_DOWN, + MGL_KEY_NUMPAD0, + MGL_KEY_NUMPAD1, + MGL_KEY_NUMPAD2, + MGL_KEY_NUMPAD3, + MGL_KEY_NUMPAD4, + MGL_KEY_NUMPAD5, + MGL_KEY_NUMPAD6, + MGL_KEY_NUMPAD7, + MGL_KEY_NUMPAD8, + MGL_KEY_NUMPAD9, + MGL_KEY_F1, + MGL_KEY_F2, + MGL_KEY_F3, + MGL_KEY_F4, + MGL_KEY_F5, + MGL_KEY_F6, + MGL_KEY_F7, + MGL_KEY_F8, + MGL_KEY_F9, + MGL_KEY_F10, + MGL_KEY_F11, + MGL_KEY_F12, + MGL_KEY_F13, + MGL_KEY_F14, + MGL_KEY_F15, + MGL_KEY_PAUSE +} mgl_key; + +#endif /* _MGL_KEY_H_ */ diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h index b30583b..297ccb9 100644 --- a/include/mgl/window/window.h +++ b/include/mgl/window/window.h @@ -5,6 +5,8 @@ #include "../system/vec.h" #include +/* Vsync is automatically set for windows created, if supported by the system */ + typedef struct __GLXcontextRec *GLXContext; typedef struct mgl_event mgl_event; /* x11 window handle. TODO: Add others when wayland, etc is added */ @@ -16,6 +18,7 @@ struct mgl_window { mgl_window_handle window; GLXContext glx_context; mgl_vec2i size; + /* relative to the top left of the window. only updates when the cursor is inside the window */ mgl_vec2i cursor_position; }; diff --git a/src/graphics/font.c b/src/graphics/font.c index 8344a04..2ed54d2 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -47,8 +47,8 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int c /* TODO: Optimize */ /* Find optimal size for atlas, starting from small to large */ for(int i = 0; i < 4; ++i) { - self->font_atlas.width = (8 + (8 * i)) * self->character_size; - self->font_atlas.height = (8 + (8 * i)) * self->character_size; + self->font_atlas.width = (14 + (8 * i)) * self->character_size; + self->font_atlas.height = (14 + (8 * i)) * self->character_size; unsigned char *new_atlas = realloc(self->font_atlas.atlas, self->font_atlas.width * self->font_atlas.height); if(!new_atlas) { fprintf(stderr, "Error: failed to load font %s, error: out of memory\n", filepath); @@ -67,6 +67,8 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int c return -1; } + stbtt_PackSetOversampling(&pc, 2, 2); + if(!stbtt_PackFontRange(&pc, filedata.data, 0, self->character_size, 0, self->num_packed_chars, self->packed_chars)) { stbtt_PackEnd(&pc); continue; @@ -92,7 +94,6 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int c } /* TODO: Use stbtt_GetCodepointSDF */ - /* TODO: Use stbtt_PackSetOversampling */ mgl_filedata_free(&filedata); return 0; @@ -119,7 +120,7 @@ int mgl_font_get_glyph(const mgl_font *self, uint32_t codepoint, mgl_font_glyph float x = 0.0f; float y = 0.0f; stbtt_aligned_quad quad; - stbtt_GetPackedQuad(packed_chars, self->font_atlas.width, self->font_atlas.height, codepoint, &x, &y, &quad, 1); + stbtt_GetPackedQuad(packed_chars, self->font_atlas.width, self->font_atlas.height, codepoint, &x, &y, &quad, 0); glyph->position = (mgl_vec2f){ quad.x0, quad.y0 }; glyph->size = (mgl_vec2f){ quad.x1 - quad.x0, quad.y1 - quad.y0 }; diff --git a/src/graphics/text.c b/src/graphics/text.c index 76fd852..9a849a9 100644 --- a/src/graphics/text.c +++ b/src/graphics/text.c @@ -2,20 +2,48 @@ #include "../../include/mgl/graphics/font.h" #include "../../include/mgl/mgl.h" -int mgl_text_init(mgl_text *self, mgl_font *font, const char *text, float x, float y) { +/* + TODO: Do syntax highlight in constructor/mgl_text_set_string for optimization. + Syntax highlighting should the first text that is visible in the text editor and find the start and end, + and start syntax highlight from there until the last visible text. + In that case there should also be a function to rerun the syntax highlighting, to update it + when an asynchronous process finishes that parses code, such as a lsp client parsing C++ code which + takes a while. +*/ + +static bool default_syntax_highlight(void *userdata, const char *str, size_t size, mgl_color *color) { + (void)userdata; + (void)str; + (void)size; + (void)color; + return false; +} + +int mgl_text_init(mgl_text *self, mgl_font *font, const char *str, size_t str_size, mgl_text_options *options) { self->font = font; - self->text = text; + self->text = str; + self->text_size = str_size; self->color = (mgl_color){ 255, 255, 255, 255 }; - self->position = (mgl_vec2f){ x, y }; + self->position = (mgl_vec2f){ 0.0f, 0.0f }; + + if(options) + self->options = *options; + else + self->options.userdata = NULL; + + if(!options || !options->syntax_highlight) + self->options.syntax_highlight = default_syntax_highlight; + return 0; } void mgl_text_deinit(mgl_text *self) { - + (void)self; } -void mgl_text_set_string(mgl_text *self, const char *str) { +void mgl_text_set_string(mgl_text *self, const char *str, size_t str_size) { self->text = str; + self->text_size = str_size; } void mgl_text_set_font(mgl_text *self, mgl_font *font) { @@ -44,25 +72,43 @@ static void mgl_text_draw_glyph(mgl_context *context, mgl_font_glyph *glyph, mgl context->gl.glVertex3f(position.x + glyph->position.x, position.y + glyph->position.y + glyph->size.y, 0.0f); } +static void mgl_text_run_syntax_highlight(mgl_context *context, mgl_text *text, const char *str, size_t size, mgl_color *color, bool *color_changed) { + if(text->options.syntax_highlight(text->options.userdata, str, size, color)) { + context->gl.glColor4ub(color->r, color->g, color->b, color->a); + *color_changed = true; + } else { + if(*color_changed) { + *color = text->color; + context->gl.glColor4ub(color->r, color->g, color->b, color->a); + *color_changed = false; + } + } +} + /* TODO: Use opengl buffer object instead */ /* TODO: Cache texture bind to not bind texture if its already bound and do not bind texture 0 */ void mgl_text_draw(mgl_context *context, mgl_text *text) { - if(!text->text || !text->font) + if(!text->text || text->text_size == 0 || !text->font) return; - const char *str = text->text; - mgl_font_glyph glyph; mgl_vec2f position = text->position; position.y += text->font->character_size; + mgl_color color = text->color; + bool color_changed = false; + + if(text->options.before_syntax_highlight) + text->options.before_syntax_highlight(text->options.userdata); + context->gl.glColor4ub(text->color.r, text->color.g, text->color.b, text->color.a); context->gl.glBindTexture(GL_TEXTURE_2D, text->font->texture.id); context->gl.glBegin(GL_QUADS); - while(*str) { - unsigned char c = *(unsigned char*)str; + for(size_t i = 0; i < text->text_size; ++i) { + unsigned char c = *(unsigned char*)&text->text[i]; if((c >= 32 && c < 128)) { if(mgl_font_get_glyph(text->font, c, &glyph) == 0) { + mgl_text_run_syntax_highlight(context, text, (const char*)&c, 1, &color, &color_changed); mgl_text_draw_glyph(context, &glyph, position); position.x += glyph.advance; } @@ -78,7 +124,6 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) { position.x = text->position.x; position.y += text->font->character_size; } - ++str; } context->gl.glEnd(); context->gl.glBindTexture(GL_TEXTURE_2D, 0); diff --git a/src/mgl.c b/src/mgl.c index 6407d9e..7940def 100644 --- a/src/mgl.c +++ b/src/mgl.c @@ -8,6 +8,7 @@ static mgl_context context; static int init_count = 0; static XErrorHandler prev_xerror = NULL; +static XIOErrorHandler prev_xioerror = NULL; static int ignore_xerror(Display *display, XErrorEvent *ee) { (void)display; @@ -15,6 +16,11 @@ static int ignore_xerror(Display *display, XErrorEvent *ee) { return 0; } +static int ignore_xioerror(Display *display) { + (void)display; + return 0; +} + static int glx_context_init() { const int attr[] = { GLX_RGBA, @@ -60,6 +66,13 @@ int mgl_init(void) { } prev_xerror = XSetErrorHandler(ignore_xerror); + prev_xioerror = XSetIOErrorHandler(ignore_xioerror); + + context.wm_delete_window_atom = XInternAtom(context.connection, "WM_DELETE_WINDOW", False); + if(!context.wm_delete_window_atom) { + mgl_deinit(); + return -1; + } if(mgl_gl_load(&context.gl) != 0) { mgl_deinit(); @@ -76,10 +89,16 @@ int mgl_init(void) { void mgl_deinit(void) { if(init_count == 1) { - glx_context_deinit(); - mgl_gl_unload(&context.gl); - XSetErrorHandler(prev_xerror); if(context.connection) { + glx_context_deinit(); + mgl_gl_unload(&context.gl); + + XSetIOErrorHandler(prev_xioerror); + prev_xioerror = NULL; + + XSetErrorHandler(prev_xerror); + prev_xerror = NULL; + XCloseDisplay(context.connection); context.connection = NULL; } 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 #include @@ -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; -- cgit v1.2.3