Begin processing X events

This commit is contained in:
Josh Holtrop 2017-09-30 20:17:22 -04:00
parent 2348d7ede1
commit 095d8d440e
5 changed files with 150 additions and 40 deletions

View File

@ -1,18 +1,14 @@
#include "Jtk.h"
#ifdef JTK_X
#include "Jtk.h"
#include <GL/glx.h>
#include <stdio.h>
static Display * g_display;
static XVisualInfo * g_vi;
static XSetWindowAttributes g_swa;
static GLXContext g_context;
static Bool WaitForNotify(Display * display, XEvent * event, XPointer arg)
{
return (event->type == MapNotify) && (event->xmap.window == (Window)arg);
}
Display * g_display;
XVisualInfo * g_vi;
XSetWindowAttributes g_swa;
GLXContext g_context;
/**
* Initialize the Jtk subsystem.
@ -60,33 +56,4 @@ bool Jtk_Init()
return true;
}
void * Jtk_CreateWindow()
{
XEvent event;
Window window = XCreateWindow(g_display,
RootWindow(g_display, g_vi->screen),
0, 0, 800, 800, 0, g_vi->depth, InputOutput, g_vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &g_swa);
XMapWindow(g_display, window);
XIfEvent(g_display, &event, WaitForNotify, (XPointer)window);
if (glXMakeCurrent(g_display, window, g_context) == False)
{
fprintf(stderr, "glXMakeCurrent() failure\n");
XDestroyWindow(g_display, window);
return nullptr;
}
return (void *)window;
}
void Jtk_SwapBuffers(void * window)
{
glXSwapBuffers(g_display, (Window)window);
}
void Jtk_CloseWindow(void * window)
{
XDestroyWindow(g_display, (Window)window);
}
#endif

View File

@ -1,5 +1,94 @@
#include "Jtk.h"
#ifdef JTK_X
#include <GL/glx.h>
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include "Jtk_internal.h"
/** Do not wait longer than 100ms */
#define MAX_WAIT_TIME 100000u
/**
* Process an X event.
*
* @param x_event
* Pointer to the X event.
* @param event
* Pointer to the Jtk event.
*
* @retval true
* The event should be passed to the user and event has been filled in.
* @retval false
* The event should not be passed to the user.
*/
static bool ProcessXEvent(XEvent * x_event, Jtk_Event * event)
{
switch (x_event->type)
{
case KeyPress:
break;
case KeyRelease:
break;
case ButtonPress:
break;
case ButtonRelease:
break;
case Expose:
break;
case MappingNotify:
XRefreshKeyboardMapping(&x_event->xmapping);
return false;
}
return false;
}
void Jtk_WaitForEvent(Jtk_Event * event)
{
for (;;)
{
/* First check if any timer has expired. */
size_t timer_id = Jtk_GetExpiredTimer();
if (timer_id != (size_t)-1)
{
event->type = JTK_EVENT_TIMER;
event->timer.timer_id = timer_id;
return;
}
/* Next check for an X event. */
if (XPending(g_display) > 0)
{
XEvent x_event;
XNextEvent(g_display, &x_event);
if (ProcessXEvent(&x_event, event))
return;
}
/* Finally, wait for something to happen. */
uint64_t time_to_wait = Jtk_TimeToNextTimerExpiration();
if (time_to_wait > MAX_WAIT_TIME)
{
time_to_wait = MAX_WAIT_TIME;
}
int x_fd = ConnectionNumber(g_display);
fd_set fds;
FD_ZERO(&fds);
FD_SET(x_fd, &fds);
struct timeval tv;
tv.tv_sec = time_to_wait / 1000000u;
tv.tv_usec = time_to_wait % 1000000u;
select(x_fd + 1, &fds, nullptr, nullptr, &tv);
}
}
#endif

View File

@ -5,11 +5,12 @@
#include <stdlib.h>
#define JTK_EVENT_CLOSE_WINDOW 1u
#define JTK_EVENT_EXPOSE 2u
#define JTK_EVENT_WINDOW_EXPOSE 2u
#define JTK_EVENT_KEY_PRESS 3u
#define JTK_EVENT_KEY_RELEASE 4u
#define JTK_EVENT_BUTTON_PRESS 5u
#define JTK_EVENT_BUTTON_RELEASE 6u
#define JTK_EVENT_TIMER 7u
typedef struct
{

View File

@ -0,0 +1,9 @@
#ifndef JTK_INTERNAL_H
#define JTK_INTERNAL_H
extern Display * g_display;
extern XVisualInfo * g_vi;
extern XSetWindowAttributes g_swa;
extern GLXContext g_context;
#endif

44
src/gui/jtk/Jtk_window.cc Normal file
View File

@ -0,0 +1,44 @@
#include "Jtk.h"
#ifdef JTK_X
#include <GL/glx.h>
#include "Jtk_internal.h"
#include <stdio.h>
static Bool WaitForNotify(Display * display, XEvent * event, XPointer arg)
{
return (event->type == MapNotify) && (event->xmap.window == (Window)arg);
}
void * Jtk_CreateWindow()
{
XEvent event;
Window window = XCreateWindow(g_display,
RootWindow(g_display, g_vi->screen),
0, 0, 800, 800, 0, g_vi->depth, InputOutput, g_vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &g_swa);
XMapWindow(g_display, window);
XIfEvent(g_display, &event, WaitForNotify, (XPointer)window);
if (glXMakeCurrent(g_display, window, g_context) == False)
{
fprintf(stderr, "glXMakeCurrent() failure\n");
XDestroyWindow(g_display, window);
return nullptr;
}
return (void *)window;
}
void Jtk_SwapBuffers(void * window)
{
glXSwapBuffers(g_display, (Window)window);
}
void Jtk_CloseWindow(void * window)
{
XDestroyWindow(g_display, (Window)window);
}
#endif