Added logging and X11 Keymap translation. Also various bugfixes.
This commit is contained in:
parent
56f7cd1875
commit
54a0f5eb4e
16 changed files with 181 additions and 57 deletions
|
|
@ -2,7 +2,9 @@
|
|||
#define PGPL_H
|
||||
|
||||
#include <pgpl/gui.h>
|
||||
#include <pgpl/log.h>
|
||||
#include <pgpl/render.h>
|
||||
#include <pgpl/string.h>
|
||||
#include <pgpl/thread.h>
|
||||
#include <pgpl/timer.h>
|
||||
#include <pgpl/vector.h>
|
||||
|
|
|
|||
27
include/pgpl/log.h
Normal file
27
include/pgpl/log.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef PGPL_LOG_H
|
||||
#define PGPL_LOG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum PGPL_LogLevel {
|
||||
PGPL_LOG_LEVEL_DEBUG,
|
||||
PGPL_LOG_LEVEL_INFO,
|
||||
PGPL_LOG_LEVEL_WARN,
|
||||
PGPL_LOG_LEVEL_ERROR,
|
||||
} PGPL_LogLevel;
|
||||
|
||||
void pgpl_log_set_minimum_level(PGPL_LogLevel level);
|
||||
|
||||
void pgpl_log_output_file(FILE *file);
|
||||
|
||||
void pgpl_log_message(PGPL_LogLevel level, const char *message, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
18
include/pgpl/string.h
Normal file
18
include/pgpl/string.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef PGPL_STRING_H
|
||||
#define PGPL_STRING_H
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Converts a string to a wide string, don't forget to call free() on the
|
||||
* returned pointer. */
|
||||
wchar_t *pgpl_string_to_wide_string(const char *str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -18,7 +18,7 @@ typedef struct PGPL_Window PGPL_Window;
|
|||
/* This is an input event which is returned on PGPL_WINDOW_EVENT_KEY_* and
|
||||
* PGPL_WINDOW_EVENT_MOUSE_* events. */
|
||||
typedef struct PGPL_WindowInputEvent {
|
||||
uint32_t key;
|
||||
int32_t key;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} PGPL_WindowInputEvent;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ lib = both_libraries(
|
|||
'src/thread.c',
|
||||
'src/timer.c',
|
||||
'src/vector.c',
|
||||
'src/string.c',
|
||||
'src/log.c',
|
||||
'src/window/window.c',
|
||||
'src/window/window-x11.c',
|
||||
'src/window/window-win32.c',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
#include <pgpl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static bool pgpl_gui_internal_event_loop(PGPL_Window *window,
|
||||
|
|
@ -37,7 +35,8 @@ static bool pgpl_gui_internal_event_loop(PGPL_Window *window,
|
|||
pgpl_gui_destroy(gui, true);
|
||||
return false;
|
||||
} else if (event_type == PGPL_WINDOW_EVENT_ERROR) {
|
||||
printf("PGPL_Window has experienced an unexpected error!\nExiting...");
|
||||
pgpl_log_message(PGPL_LOG_LEVEL_ERROR,
|
||||
"PGPL_Window has experienced an unexpected error!");
|
||||
} else {
|
||||
uint32_t width, height;
|
||||
uint32_t length = pgpl_vector_get_length(gui->widgets);
|
||||
|
|
|
|||
|
|
@ -45,25 +45,22 @@ static void event(PGPL_GuiWidget *widget, PGPL_GuiTheme *theme, PGPL_Gui *gui,
|
|||
if (event_type == PGPL_WINDOW_EVENT_MOUSE_PRESS &&
|
||||
event_data->input_event.key == PGPL_WINDOW_MOUSE_BUTTON_LEFT) {
|
||||
widget->gui_color = PGPL_GUI_STATUS_COLOR_ACTIVE;
|
||||
return;
|
||||
} else if (event_type == PGPL_WINDOW_EVENT_MOUSE_RELEASE &&
|
||||
event_data->input_event.key == PGPL_WINDOW_MOUSE_BUTTON_LEFT) {
|
||||
if (widget->gui_color == PGPL_GUI_STATUS_COLOR_ACTIVE) {
|
||||
button_widget->click_callback(gui->app_data);
|
||||
}
|
||||
widget->gui_color = PGPL_GUI_STATUS_COLOR_HOVER;
|
||||
return;
|
||||
} else {
|
||||
if (widget->gui_color != PGPL_GUI_STATUS_COLOR_ACTIVE) {
|
||||
widget->gui_color = PGPL_GUI_STATUS_COLOR_HOVER;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
widget->gui_color = PGPL_GUI_STATUS_COLOR_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void destroy(PGPL_GuiWidget *widget) {
|
||||
pgpl_gui_button_widget_destroy((PGPL_GuiButtonWidget *)widget);
|
||||
|
|
|
|||
46
src/log.c
Normal file
46
src/log.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include <pgpl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern PGPL_Mutex *pgpl_internal_log_lock;
|
||||
|
||||
extern FILE *pgpl_internal_log_file;
|
||||
|
||||
static PGPL_LogLevel pgpl_log_internal_minimum_level = PGPL_LOG_LEVEL_ERROR;
|
||||
|
||||
void pgpl_log_set_minimum_level(PGPL_LogLevel level) {
|
||||
pgpl_log_internal_minimum_level = level;
|
||||
}
|
||||
|
||||
void pgpl_log_output_file(FILE *file) { pgpl_internal_log_file = file; }
|
||||
|
||||
void pgpl_log_message(PGPL_LogLevel level, const char *format, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
pgpl_mutex_lock(pgpl_internal_log_lock);
|
||||
if (level >= pgpl_log_internal_minimum_level) {
|
||||
switch (level) {
|
||||
case PGPL_LOG_LEVEL_DEBUG:
|
||||
fprintf(pgpl_internal_log_file, "[DEBUG] ");
|
||||
break;
|
||||
case PGPL_LOG_LEVEL_INFO:
|
||||
fprintf(pgpl_internal_log_file, "[INFO] ");
|
||||
break;
|
||||
case PGPL_LOG_LEVEL_WARN:
|
||||
fprintf(pgpl_internal_log_file, "[WARN] ");
|
||||
break;
|
||||
case PGPL_LOG_LEVEL_ERROR:
|
||||
fprintf(pgpl_internal_log_file, "[ERROR] ");
|
||||
break;
|
||||
}
|
||||
|
||||
vfprintf(pgpl_internal_log_file, format, args);
|
||||
fputc('\n', pgpl_internal_log_file);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
pgpl_mutex_unlock(pgpl_internal_log_lock);
|
||||
}
|
||||
15
src/pgpl.c
15
src/pgpl.c
|
|
@ -1,7 +1,16 @@
|
|||
#include <pgpl.h>
|
||||
|
||||
PGPL_Mutex *render_lock;
|
||||
PGPL_Mutex *pgpl_internal_render_lock;
|
||||
PGPL_Mutex *pgpl_internal_log_lock;
|
||||
FILE *pgpl_internal_log_file;
|
||||
|
||||
void pgpl_init(void) { render_lock = pgpl_mutex_create(); }
|
||||
void pgpl_init(void) {
|
||||
pgpl_internal_render_lock = pgpl_mutex_create();
|
||||
pgpl_internal_log_lock = pgpl_mutex_create();
|
||||
pgpl_internal_log_file = stderr;
|
||||
}
|
||||
|
||||
void pgpl_deinit(void) { pgpl_mutex_destroy(render_lock); }
|
||||
void pgpl_deinit(void) {
|
||||
pgpl_mutex_destroy(pgpl_internal_render_lock);
|
||||
pgpl_mutex_destroy(pgpl_internal_log_lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@
|
|||
#define STBTT_STATIC
|
||||
#include <stb/stb_truetype.h>
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define CHAR_AMOUNT 256
|
||||
#define BANK_AMOUNT 256
|
||||
|
||||
|
|
@ -30,26 +26,6 @@ struct PGPL_Font {
|
|||
uint8_t *data;
|
||||
};
|
||||
|
||||
/* Converts a string to a wide string, don't forget to call free() on the
|
||||
* returned pointer. */
|
||||
static wchar_t *str_to_wstr(const char *str) {
|
||||
size_t length = strlen(str);
|
||||
wchar_t *wstr = malloc((length + 1) * sizeof(*wstr));
|
||||
|
||||
setlocale(LC_ALL, "en_US.UTF-8");
|
||||
|
||||
/* mbstowcs works just fine with UTF-8 strings on most platforms, except on
|
||||
* Windows, where we have to use MultiByteToWideChar to do the exact same
|
||||
* thing. */
|
||||
#if defined(__WIN32__)
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, str, -1, wstr, length + 1);
|
||||
#else
|
||||
mbstowcs(wstr, str, length + 1);
|
||||
#endif
|
||||
|
||||
return wstr;
|
||||
}
|
||||
|
||||
PGPL_Font *pgpl_font_create_from_file(const char *filename,
|
||||
uint32_t glyph_size) {
|
||||
PGPL_Font *font;
|
||||
|
|
@ -58,7 +34,7 @@ PGPL_Font *pgpl_font_create_from_file(const char *filename,
|
|||
uint8_t *font_data;
|
||||
|
||||
if (font_file == NULL) {
|
||||
perror("Failed to open font");
|
||||
pgpl_log_message(PGPL_LOG_LEVEL_ERROR, "Failed to open font!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +134,7 @@ void pgpl_font_render_glyph(PGPL_Renderer *renderer, PGPL_Font *font, wchar_t c,
|
|||
void pgpl_font_render_string(PGPL_Renderer *renderer, PGPL_Font *font,
|
||||
const char *str, PGPL_Color color, double x,
|
||||
double y, double size) {
|
||||
wchar_t *wstr = str_to_wstr(str);
|
||||
wchar_t *wstr = pgpl_string_to_wide_string(str);
|
||||
|
||||
pgpl_font_render_wstring(renderer, font, wstr, color, x, y, size);
|
||||
|
||||
|
|
@ -213,11 +189,10 @@ void pgpl_font_glyph_dimensions(PGPL_Font *font, wchar_t c, double size,
|
|||
}
|
||||
|
||||
/* Calculates the coordinates of an entire string. Also returns them in the
|
||||
* passed pointers.
|
||||
*/
|
||||
* passed pointers. */
|
||||
void pgpl_font_string_dimensions(PGPL_Font *font, const char *str, double size,
|
||||
PGPL_Rectangle *rectangle) {
|
||||
wchar_t *wstr = str_to_wstr(str);
|
||||
wchar_t *wstr = pgpl_string_to_wide_string(str);
|
||||
|
||||
pgpl_font_wstring_dimensions(font, wstr, size, rectangle);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ pgpl_render_create_texture_file_memory(PGPL_Renderer *renderer,
|
|||
texture = pgpl_render_create_texture(renderer, data, x, y, filter,
|
||||
PGPL_TEXTURE_FORMAT_RGBA);
|
||||
} else {
|
||||
fprintf(stderr, "Failed to open image: %s\n", stbi_failure_reason());
|
||||
pgpl_log_message(PGPL_LOG_LEVEL_ERROR, "Failed to open image: %s\n",
|
||||
stbi_failure_reason());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +39,8 @@ PGPL_Texture *pgpl_render_create_texture_file(PGPL_Renderer *renderer,
|
|||
texture = pgpl_render_create_texture(renderer, data, x, y, filter,
|
||||
PGPL_TEXTURE_FORMAT_RGBA);
|
||||
} else {
|
||||
fprintf(stderr, "Failed to open image: %s\n", stbi_failure_reason());
|
||||
pgpl_log_message(PGPL_LOG_LEVEL_ERROR, "Failed to open image: %s\n",
|
||||
stbi_failure_reason());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
26
src/string.c
Normal file
26
src/string.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include <locale.h>
|
||||
#include <pgpl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
wchar_t *pgpl_string_to_wide_string(const char *str) {
|
||||
size_t length = strlen(str);
|
||||
wchar_t *wstr = malloc((length + 1) * sizeof(*wstr));
|
||||
|
||||
setlocale(LC_ALL, "en_US.UTF-8");
|
||||
|
||||
/* mbstowcs works just fine with UTF-8 strings on most platforms, except on
|
||||
* Windows, where we have to use MultiByteToWideChar to do the exact same
|
||||
* thing. */
|
||||
#if defined(__WIN32__)
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, str, -1, wstr, length + 1);
|
||||
#else
|
||||
mbstowcs(wstr, str, length + 1);
|
||||
#endif
|
||||
|
||||
return wstr;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
/* This is needed if there are multiple windows open. Created by pgpl_init,
|
||||
* destroyed by pgpl_deinit. */
|
||||
extern PGPL_Mutex *render_lock;
|
||||
extern PGPL_Mutex *pgpl_internal_render_lock;
|
||||
|
||||
typedef struct PGPL_WindowShared {
|
||||
double scale;
|
||||
|
|
|
|||
|
|
@ -319,13 +319,13 @@ void pgpl_window_reparent_to(PGPL_Window *window, void *parent) {
|
|||
void *pgpl_window_get_raw_window(PGPL_Window *window) { return window->hwnd; }
|
||||
|
||||
void pgpl_window_internal_start_render(PGPL_Window *window) {
|
||||
pgpl_mutex_lock(render_lock);
|
||||
pgpl_mutex_lock(pgpl_internal_render_lock);
|
||||
wglMakeCurrent(window->hdc, window->wgl_context);
|
||||
}
|
||||
|
||||
void pgpl_window_internal_finish_render(PGPL_Window *window) {
|
||||
wglSwapLayerBuffers(window->hdc, WGL_SWAP_MAIN_PLANE);
|
||||
pgpl_mutex_unlock(render_lock);
|
||||
pgpl_mutex_unlock(pgpl_internal_render_lock);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "internal.h"
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct PGPL_Window {
|
||||
|
|
@ -144,10 +145,29 @@ void pgpl_window_set_position(PGPL_Window *window, int32_t x, int32_t y) {
|
|||
XFlush(window->display);
|
||||
}
|
||||
|
||||
static int32_t pgpl_window_internal_get_key(XKeyEvent *key_event) {
|
||||
KeySym key_sym;
|
||||
char buffer[32];
|
||||
wchar_t *wbuffer;
|
||||
int32_t character = 0;
|
||||
|
||||
int length =
|
||||
XLookupString(key_event, buffer, sizeof(buffer) - 1, &key_sym, NULL);
|
||||
|
||||
buffer[length] = '\0';
|
||||
|
||||
if (length != 0) {
|
||||
wbuffer = pgpl_string_to_wide_string(buffer);
|
||||
character = wbuffer[0];
|
||||
} else {
|
||||
/* TODO: Handle control characters. */
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
/* This fetches the event from X11 and translates it to our own format, returns
|
||||
* an Error if the Event was unknown.
|
||||
*
|
||||
* TODO: Translate the keymaps */
|
||||
* an Error if the Event was unknown. */
|
||||
PGPL_WindowEventType
|
||||
pgpl_window_internal_fetch_window_event(PGPL_Window *window,
|
||||
PGPL_WindowEventData *event_data) {
|
||||
|
|
@ -159,7 +179,7 @@ pgpl_window_internal_fetch_window_event(PGPL_Window *window,
|
|||
if (event_data != NULL) {
|
||||
event_data->input_event.x = event.xkey.x;
|
||||
event_data->input_event.y = event.xkey.y;
|
||||
event_data->input_event.key = event.xkey.keycode;
|
||||
event_data->input_event.key = pgpl_window_internal_get_key(&event.xkey);
|
||||
}
|
||||
return PGPL_WINDOW_EVENT_KEY_PRESS;
|
||||
break;
|
||||
|
|
@ -167,7 +187,7 @@ pgpl_window_internal_fetch_window_event(PGPL_Window *window,
|
|||
if (event_data != NULL) {
|
||||
event_data->input_event.x = event.xkey.x;
|
||||
event_data->input_event.y = event.xkey.y;
|
||||
event_data->input_event.key = event.xkey.keycode;
|
||||
event_data->input_event.key = pgpl_window_internal_get_key(&event.xkey);
|
||||
}
|
||||
return PGPL_WINDOW_EVENT_KEY_RELEASE;
|
||||
break;
|
||||
|
|
@ -221,12 +241,12 @@ void *pgpl_window_get_raw_window(PGPL_Window *window) {
|
|||
}
|
||||
|
||||
void pgpl_window_internal_start_render(PGPL_Window *window) {
|
||||
pgpl_mutex_lock(render_lock);
|
||||
pgpl_mutex_lock(pgpl_internal_render_lock);
|
||||
glXMakeCurrent(window->display, window->window, window->glx_context);
|
||||
}
|
||||
|
||||
void pgpl_window_internal_finish_render(PGPL_Window *window) {
|
||||
glXSwapBuffers(window->display, window->window);
|
||||
pgpl_mutex_unlock(render_lock);
|
||||
pgpl_mutex_unlock(pgpl_internal_render_lock);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
9
todo.md
9
todo.md
|
|
@ -1,12 +1,13 @@
|
|||
# TODO
|
||||
|
||||
Farther Blockers:
|
||||
Translate keymaps properly so that they can be used by programs.
|
||||
Further error handling on X11, Win32 API and more.
|
||||
Logging library for this error handling, so that outputs can be supressed. (or remove the current prints...)
|
||||
Win32 Blockers:
|
||||
Translate keymaps on windows.
|
||||
Fix the windows scrolling
|
||||
|
||||
Fun Features:
|
||||
|
||||
- Further error handling on X11, Win32 API and more.
|
||||
- Create some mappings for special keys
|
||||
- Allow not automatically freeing
|
||||
- get the framerate controllable and gettable, and then we can get animations.
|
||||
- Allow resizing the window with the scale.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue