Skip to content

Commit

Permalink
Merge pull request #56 from gridpoint-com/fix-cairo-gtk-race
Browse files Browse the repository at this point in the history
Fix cairo gtk race
  • Loading branch information
crertel authored Oct 21, 2023
2 parents 5c67832 + ecdc828 commit 3ca1d5a
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 9 deletions.
75 changes: 69 additions & 6 deletions c_src/device/cairo/cairo_gtk.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cairo.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
Expand All @@ -20,6 +21,7 @@ typedef struct {
GThread* main;
GtkWidget* window;
GMutex render_mutex;
GMutex cmd_mutex;
float last_x;
float last_y;
} cairo_gtk_t;
Expand Down Expand Up @@ -58,10 +60,13 @@ static gboolean on_motion_event(GtkWidget* widget,
GdkEventMotion* event,
gpointer data)
{
if ((g_cairo_gtk.last_x != event->x) && (g_cairo_gtk.last_y != event->y)) {
send_cursor_pos(event->x, event->y);
g_cairo_gtk.last_x = event->x;
g_cairo_gtk.last_y = event->y;
float x = floorf(event->x);
float y = floorf(event->y);

if ((g_cairo_gtk.last_x != x) && (g_cairo_gtk.last_y != y)) {
send_cursor_pos(x, y);
g_cairo_gtk.last_x = x;
g_cairo_gtk.last_y = y;
}

return TRUE;
Expand All @@ -83,11 +88,14 @@ static gboolean on_button_event(GtkWidget* widget,
return FALSE;
}

float x = floorf(event->x);
float y = floorf(event->y);

send_mouse_button(KEYMAP_GDK,
event->button,
action,
event->state,
event->x, event->y);
x, y);

return TRUE;
}
Expand All @@ -105,6 +113,32 @@ static gboolean on_key_event(GtkWidget* widget,
return TRUE;
}

static gboolean on_enter_leave_event(GtkWidget* widget,
GdkEventCrossing* event,
gpointer data)
{
int action = (event->type == GDK_ENTER_NOTIFY) ? 1 : 0;
float x = floorf(event->x);
float y = floorf(event->y);

send_cursor_enter(action, x, y);

return TRUE;
}

static gboolean on_scroll_event(GtkWidget* widget,
GdkEventScroll* event,
gpointer data)
{
float x = floorf(event->x);
float y = floorf(event->y);
float xoffset = floorf(event->delta_x);
float yoffset = floorf(event->delta_y);
send_scroll(xoffset, yoffset, x, y);

return TRUE;
}

int device_init(const device_opts_t* p_opts,
device_info_t* p_info,
driver_data_t* p_data)
Expand Down Expand Up @@ -134,14 +168,20 @@ int device_init(const device_opts_t* p_opts,
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK);
GDK_KEY_RELEASE_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_SCROLL_MASK );

g_signal_connect(G_OBJECT(g_cairo_gtk.window), "motion-notify-event", G_CALLBACK(on_motion_event), NULL);
g_signal_connect(G_OBJECT(g_cairo_gtk.window), "button-press-event", G_CALLBACK(on_button_event), NULL);
g_signal_connect(G_OBJECT(g_cairo_gtk.window), "button-release-event", G_CALLBACK(on_button_event), NULL);
g_signal_connect(G_OBJECT(g_cairo_gtk.window), "key-press-event", G_CALLBACK(on_key_event), NULL);
g_signal_connect(G_OBJECT(g_cairo_gtk.window), "key-release-event", G_CALLBACK(on_key_event), NULL);
g_signal_connect(G_OBJECT(g_cairo_gtk.window), "enter-notify-event", G_CALLBACK(on_enter_leave_event), NULL);
g_signal_connect(G_OBJECT(g_cairo_gtk.window), "leave-notify-event", G_CALLBACK(on_enter_leave_event), NULL);
g_signal_connect(G_OBJECT(g_cairo_gtk.window), "scroll-event", G_CALLBACK(on_scroll_event), NULL);

GtkDrawingArea* drawing_area = (GtkDrawingArea*)gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(g_cairo_gtk.window), (GtkWidget*)drawing_area);
Expand Down Expand Up @@ -203,10 +243,33 @@ void device_end_render(driver_data_t* p_data)
g_idle_add((GSourceFunc)gtk_widget_queue_draw, (void*)g_cairo_gtk.window);
}

void glib_print(const gchar* string)
{
log_info("glib: %s", string);
}

void glib_error(const gchar* string)
{
log_error("glib: %s", string);
}

void scenic_cmd_lock()
{
g_mutex_lock(&g_cairo_gtk.cmd_mutex);
}

void scenic_cmd_unlock()
{
g_mutex_unlock(&g_cairo_gtk.cmd_mutex);
}

void device_loop(driver_data_t* p_data)
{
g_cairo_gtk.main = g_thread_new("scenic_loop", scenic_loop, p_data);

g_set_print_handler(glib_print);
g_set_printerr_handler(glib_error);

gtk_widget_show_all((GtkWidget*)g_cairo_gtk.window);
gtk_main();
}
18 changes: 16 additions & 2 deletions c_src/scenic/comms.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,24 @@ The caller will typically be erlang, so use the 2-byte length indicator

extern device_info_t g_device_info;


//=============================================================================
// raw comms with host app
// from erl_comm.c
// http://erlang.org/doc/tutorial/c_port.html#id64377

//---------------------------------------------------------
// the length indicator from erlang is always big-endian
int write_cmd(uint8_t* buf, unsigned int len)
int write_cmd(uint8_t* buf, uint32_t len)
{
int written = 0;

uint32_t cmd_len = len;
cmd_len = hton_ui32(cmd_len);

scenic_cmd_lock();
write_exact((uint8_t*) &cmd_len, sizeof(uint32_t));
written = write_exact(buf, len);
scenic_cmd_unlock();

return written;
}
Expand Down Expand Up @@ -89,9 +91,11 @@ void logv(uint32_t cmd, const char* msg, va_list args)
uint32_t msg_len = vasprintf(&output, msg, args);
uint32_t cmd_len = ntoh_ui32(msg_len + sizeof(uint32_t));

scenic_cmd_lock();
write_exact((uint8_t*) &cmd_len, sizeof(uint32_t));
write_exact((uint8_t*) &cmd, sizeof(uint32_t));
write_exact((uint8_t*) output, msg_len);
scenic_cmd_unlock();
free(output);
}

Expand Down Expand Up @@ -163,9 +167,11 @@ void send_write(const char* msg)

cmd_len = ntoh_ui32(cmd_len);

scenic_cmd_lock();
write_exact((uint8_t*) &cmd_len, sizeof(uint32_t));
write_exact((uint8_t*) &cmd, sizeof(uint32_t));
write_exact((uint8_t*) msg, msg_len);
scenic_cmd_unlock();
}

//---------------------------------------------------------
Expand All @@ -176,9 +182,11 @@ void send_inspect(void* data, int length)

ntoh_ui32(cmd_len);

scenic_cmd_lock();
write_exact((uint8_t*) &cmd_len, sizeof(uint32_t));
write_exact((uint8_t*) &cmd, sizeof(uint32_t));
write_exact(data, length);
scenic_cmd_unlock();
}

//---------------------------------------------------------
Expand All @@ -190,9 +198,11 @@ void send_static_texture_miss(const char* key)

ntoh_ui32(cmd_len);

scenic_cmd_lock();
write_exact((uint8_t*) &cmd_len, sizeof(uint32_t));
write_exact((uint8_t*) &cmd, sizeof(uint32_t));
write_exact((uint8_t*) key, msg_len);
scenic_cmd_unlock();
}

//---------------------------------------------------------
Expand All @@ -204,9 +214,11 @@ void send_dynamic_texture_miss(const char* key)

ntoh_ui32(cmd_len);

scenic_cmd_lock();
write_exact((uint8_t*) &cmd_len, sizeof(uint32_t));
write_exact((uint8_t*) &cmd, sizeof(uint32_t));
write_exact((uint8_t*) key, msg_len);
scenic_cmd_unlock();
}

//---------------------------------------------------------
Expand All @@ -218,9 +230,11 @@ void send_font_miss(const char* key)

ntoh_ui32(cmd_len);

scenic_cmd_lock();
write_exact((uint8_t*) &cmd_len, sizeof(uint32_t));
write_exact((uint8_t*) &cmd, sizeof(uint32_t));
write_exact((uint8_t*) key, msg_len);
scenic_cmd_unlock();
}

//---------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions c_src/scenic/scenic_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,8 @@ void* scenic_loop(void* user_data)
return NULL;
}

__attribute__((weak))
void scenic_cmd_lock() { }

__attribute__((weak))
void scenic_cmd_unlock() { }
5 changes: 4 additions & 1 deletion c_src/scenic/scenic_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,7 @@ void scenic_ops_put_image(uint32_t* p_msg_length, driver_data_t* p_data);
void scenic_ops_crash();

void dispatch_scenic_ops(uint32_t msg_length, driver_data_t* p_data);
void* scenic_loop(void* user_data);
void* scenic_loop(void* user_data);

void scenic_cmd_lock();
void scenic_cmd_unlock();

0 comments on commit 3ca1d5a

Please sign in to comment.