jtk.c: support multiple threads
This commit is contained in:
parent
d3d6fd0fbf
commit
6cf36a852f
@ -28,6 +28,12 @@ bool jtk_init()
|
|||||||
None,
|
None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (XInitThreads() != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "XInitThreads() failure\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
g_display = XOpenDisplay(NULL);
|
g_display = XOpenDisplay(NULL);
|
||||||
if (g_display == NULL)
|
if (g_display == NULL)
|
||||||
{
|
{
|
||||||
@ -35,6 +41,8 @@ bool jtk_init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XLockDisplay(g_display);
|
||||||
|
|
||||||
g_vi = glXChooseVisual(g_display, DefaultScreen(g_display),
|
g_vi = glXChooseVisual(g_display, DefaultScreen(g_display),
|
||||||
glx_attribute_list);
|
glx_attribute_list);
|
||||||
if (g_vi == NULL)
|
if (g_vi == NULL)
|
||||||
@ -58,6 +66,8 @@ bool jtk_init()
|
|||||||
KeyPressMask | KeyReleaseMask |
|
KeyPressMask | KeyReleaseMask |
|
||||||
ButtonPressMask | ButtonReleaseMask;
|
ButtonPressMask | ButtonReleaseMask;
|
||||||
|
|
||||||
|
XUnlockDisplay(g_display);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,44 +99,56 @@ static Bool wait_for_notify(Display * display, XEvent * event, XPointer arg)
|
|||||||
void * jtk_window_create()
|
void * jtk_window_create()
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
|
|
||||||
|
XLockDisplay(g_display);
|
||||||
Window window = XCreateWindow(g_display,
|
Window window = XCreateWindow(g_display,
|
||||||
RootWindow(g_display, g_vi->screen),
|
RootWindow(g_display, g_vi->screen),
|
||||||
0, 0, 800u, 800u, 0u, g_vi->depth, InputOutput, g_vi->visual,
|
0, 0, 800u, 800u, 0u, g_vi->depth, InputOutput, g_vi->visual,
|
||||||
CWBorderPixel | CWColormap | CWEventMask, &g_swa);
|
CWBorderPixel | CWColormap | CWEventMask, &g_swa);
|
||||||
XMapWindow(g_display, window);
|
XMapWindow(g_display, window);
|
||||||
XIfEvent(g_display, &event, wait_for_notify, (XPointer)window);
|
XIfEvent(g_display, &event, wait_for_notify, (XPointer)window);
|
||||||
if (glXMakeCurrent(g_display, window, g_context) == False)
|
if (glXMakeCurrent(g_display, window, g_context) != False)
|
||||||
|
{
|
||||||
|
/* Disable the window close button. */
|
||||||
|
Atom wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", False);
|
||||||
|
XSetWMProtocols(g_display, window, &wm_delete_window_atom, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "glXMakeCurrent() failure\n");
|
fprintf(stderr, "glXMakeCurrent() failure\n");
|
||||||
XDestroyWindow(g_display, window);
|
XDestroyWindow(g_display, window);
|
||||||
return NULL;
|
window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable the window close button. */
|
XUnlockDisplay(g_display);
|
||||||
Atom wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", False);
|
|
||||||
XSetWMProtocols(g_display, window, &wm_delete_window_atom, 1);
|
|
||||||
|
|
||||||
return (void *)window;
|
return (void *)window;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jtk_window_swap_buffers(void * window)
|
void jtk_window_swap_buffers(void * window)
|
||||||
{
|
{
|
||||||
|
XLockDisplay(g_display);
|
||||||
glXSwapBuffers(g_display, (Window)window);
|
glXSwapBuffers(g_display, (Window)window);
|
||||||
|
XUnlockDisplay(g_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jtk_window_close(void * window)
|
void jtk_window_close(void * window)
|
||||||
{
|
{
|
||||||
|
XLockDisplay(g_display);
|
||||||
XDestroyWindow(g_display, (Window)window);
|
XDestroyWindow(g_display, (Window)window);
|
||||||
|
XUnlockDisplay(g_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jtk_window_set_title(void * window, const char * title)
|
void jtk_window_set_title(void * window, const char * title)
|
||||||
{
|
{
|
||||||
|
XLockDisplay(g_display);
|
||||||
XTextProperty title_property;
|
XTextProperty title_property;
|
||||||
if (XStringListToTextProperty((char **)&title, 1, &title_property) != 0)
|
if (XStringListToTextProperty((char **)&title, 1, &title_property) != 0)
|
||||||
{
|
{
|
||||||
XSetTextProperty(g_display, (Window)window, &title_property, XA_WM_NAME);
|
XSetTextProperty(g_display, (Window)window, &title_property, XA_WM_NAME);
|
||||||
XFree(title_property.value);
|
XFree(title_property.value);
|
||||||
}
|
}
|
||||||
|
XUnlockDisplay(g_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,6 +167,7 @@ void jtk_window_set_title(void * window, const char * title)
|
|||||||
void jtk_window_set_icon(void * window, const uint8_t * data,
|
void jtk_window_set_icon(void * window, const uint8_t * data,
|
||||||
size_t width, size_t height)
|
size_t width, size_t height)
|
||||||
{
|
{
|
||||||
|
XLockDisplay(g_display);
|
||||||
Atom net_wm_icon_atom = XInternAtom(g_display, "_NET_WM_ICON", False);
|
Atom net_wm_icon_atom = XInternAtom(g_display, "_NET_WM_ICON", False);
|
||||||
size_t property_size = (2u + width * height) * sizeof(long);
|
size_t property_size = (2u + width * height) * sizeof(long);
|
||||||
unsigned long * property_data = (unsigned long *)malloc(property_size);
|
unsigned long * property_data = (unsigned long *)malloc(property_size);
|
||||||
@ -163,6 +186,7 @@ void jtk_window_set_icon(void * window, const uint8_t * data,
|
|||||||
32, PropModeReplace, (uint8_t *)property_data, property_size);
|
32, PropModeReplace, (uint8_t *)property_data, property_size);
|
||||||
XFlush(g_display);
|
XFlush(g_display);
|
||||||
free(property_data);
|
free(property_data);
|
||||||
|
XUnlockDisplay(g_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
@ -631,16 +655,25 @@ static bool process_x_event(XEvent * x_event, jtk_event_t * event)
|
|||||||
|
|
||||||
bool jtk_check_event(jtk_event_t * event)
|
bool jtk_check_event(jtk_event_t * event)
|
||||||
{
|
{
|
||||||
|
bool event_found = false;
|
||||||
|
|
||||||
|
XLockDisplay(g_display);
|
||||||
|
|
||||||
/* First check for an X event. */
|
/* First check for an X event. */
|
||||||
while (XPending(g_display) > 0)
|
while (XPending(g_display) > 0)
|
||||||
{
|
{
|
||||||
XEvent x_event;
|
XEvent x_event;
|
||||||
XNextEvent(g_display, &x_event);
|
XNextEvent(g_display, &x_event);
|
||||||
if (process_x_event(&x_event, event))
|
if (process_x_event(&x_event, event))
|
||||||
return true;
|
{
|
||||||
|
event_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
XUnlockDisplay(g_display);
|
||||||
|
|
||||||
|
return event_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jtk_wait_event(jtk_event_t * event, uint64_t time_to_wait)
|
void jtk_wait_event(jtk_event_t * event, uint64_t time_to_wait)
|
||||||
@ -656,7 +689,9 @@ void jtk_wait_event(jtk_event_t * event, uint64_t time_to_wait)
|
|||||||
time_to_wait = MAX_WAIT_TIME;
|
time_to_wait = MAX_WAIT_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XLockDisplay(g_display);
|
||||||
int x_fd = ConnectionNumber(g_display);
|
int x_fd = ConnectionNumber(g_display);
|
||||||
|
XUnlockDisplay(g_display);
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(x_fd, &fds);
|
FD_SET(x_fd, &fds);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user