xenv: allow reading mouse through callbacks, for SDL project

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@947 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2012-03-12 22:50:05 +00:00
parent d73e3285b9
commit 1a37501488
2 changed files with 68 additions and 26 deletions

View file

@ -1,5 +1,5 @@
/* /*
* (C) Gražvydas "notaz" Ignotas, 2009-2011 * (C) Gražvydas "notaz" Ignotas, 2009-2012
* *
* This work is licensed under the terms of any of these licenses * This work is licensed under the terms of any of these licenses
* (at your option): * (at your option):
@ -142,7 +142,8 @@ static int x11h_init(void)
attributes.cursor = transparent_cursor(&g_xstuff, display, win); attributes.cursor = transparent_cursor(&g_xstuff, display, win);
g_xstuff.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes); g_xstuff.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
g_xstuff.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask); g_xstuff.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask
| KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
g_xstuff.pXMapWindow(display, win); g_xstuff.pXMapWindow(display, win);
g_xstuff.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); g_xstuff.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL); g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL);
@ -157,9 +158,13 @@ fail:
return -1; return -1;
} }
static int x11h_update(int *is_down) static void x11h_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
int (*mousem_cb)(void *cb_arg, int x, int y),
void *cb_arg)
{ {
XEvent evt; XEvent evt;
int keysym;
while (g_xstuff.pXPending(g_xstuff.display)) while (g_xstuff.pXPending(g_xstuff.display))
{ {
@ -172,17 +177,35 @@ static int x11h_update(int *is_down)
break; break;
case KeyPress: case KeyPress:
*is_down = 1; keysym = g_xstuff.pXLookupKeysym(&evt.xkey, 0);
return g_xstuff.pXLookupKeysym(&evt.xkey, 0); if (key_cb != NULL)
key_cb(cb_arg, keysym, 1);
break;
case KeyRelease: case KeyRelease:
*is_down = 0; keysym = g_xstuff.pXLookupKeysym(&evt.xkey, 0);
return g_xstuff.pXLookupKeysym(&evt.xkey, 0); if (key_cb != NULL)
// printf("press %d\n", evt.xkey.keycode); key_cb(cb_arg, keysym, 0);
} break;
}
return NoSymbol; case ButtonPress:
if (mouseb_cb != NULL)
mouseb_cb(cb_arg, evt.xbutton.x, evt.xbutton.y,
evt.xbutton.button, 1);
break;
case ButtonRelease:
if (mouseb_cb != NULL)
mouseb_cb(cb_arg, evt.xbutton.x, evt.xbutton.y,
evt.xbutton.button, 0);
break;
case MotionNotify:
if (mousem_cb != NULL)
mousem_cb(cb_arg, evt.xmotion.x, evt.xmotion.y);
break;
}
}
} }
static struct termios g_kbd_termios_saved; static struct termios g_kbd_termios_saved;
@ -249,26 +272,38 @@ static void tty_end(void)
g_kbdfd = -1; g_kbdfd = -1;
} }
int xenv_init(void) int xenv_init(int *have_mouse_events)
{ {
int have_mouse = 0;
int ret; int ret;
ret = x11h_init(); ret = x11h_init();
if (ret == 0) if (ret == 0) {
return 0; have_mouse = 1;
goto out;
}
ret = tty_init(); ret = tty_init();
if (ret == 0) if (ret == 0)
return 0; goto out;
fprintf(stderr, PFX "error: both x11h_init and tty_init failed\n"); fprintf(stderr, PFX "error: both x11h_init and tty_init failed\n");
return -1; ret = -1;
out:
if (have_mouse_events != NULL)
*have_mouse_events = have_mouse;
return ret;
} }
int xenv_update(int *is_down) int xenv_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
int (*mousem_cb)(void *cb_arg, int x, int y),
void *cb_arg)
{ {
if (g_xstuff.display) if (g_xstuff.display) {
return x11h_update(is_down); x11h_update(key_cb, mouseb_cb, mousem_cb, cb_arg);
return 0;
}
// TODO: read tty? // TODO: read tty?
return -1; return -1;

View file

@ -1,5 +1,12 @@
int xenv_init(void); int xenv_init(int *have_mouse_events);
int xenv_update(int *is_down);
/* read events from X, calling key_cb for key, mouseb_cb for mouse button
* and mousem_cb for mouse motion events */
int xenv_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
int (*mousem_cb)(void *cb_arg, int x, int y),
void *cb_arg);
void xenv_finish(void); void xenv_finish(void);