Преглед на файлове

* Split event.c into the appropriate driver_*.c files.

tags/v0.99.beta14
Sam Hocevar sam преди 18 години
родител
ревизия
2936525ab7
променени са 8 файла, в които са добавени 547 реда и са изтрити 579 реда
  1. +1
    -0
      caca/caca_internals.h
  2. +13
    -0
      caca/driver_conio.c
  3. +63
    -0
      caca/driver_gl.c
  4. +184
    -0
      caca/driver_ncurses.c
  5. +83
    -0
      caca/driver_slang.c
  6. +75
    -0
      caca/driver_win32.c
  7. +122
    -4
      caca/driver_x11.c
  8. +6
    -575
      caca/event.c

+ 1
- 0
caca/caca_internals.h Целия файл

@@ -119,6 +119,7 @@ struct caca_context
unsigned int (* get_window_height) (caca_t *);
void (* display) (caca_t *);
void (* handle_resize) (caca_t *, unsigned int *, unsigned int *);
unsigned int (* get_event) (caca_t *);
} driver;

//unsigned int width, height;


+ 13
- 0
caca/driver_conio.c Целия файл

@@ -120,6 +120,18 @@ static void conio_handle_resize(caca_t *kk, unsigned int *new_width,
*new_height = kk->qq->height;
}

static unsigned int conio_get_event(caca_t *kk)
{
unsigned int event;

if(!_conio_kbhit())
return CACA_EVENT_NONE;

event = getch();
_push_event(kk, CACA_EVENT_KEY_RELEASE | event);
return CACA_EVENT_KEY_PRESS | event;
}

/*
* Driver initialisation
*/
@@ -135,6 +147,7 @@ void conio_init_driver(caca_t *kk)
kk->driver.get_window_height = conio_get_window_height;
kk->driver.display = conio_display;
kk->driver.handle_resize = conio_handle_resize;
kk->driver.get_event = conio_get_event;
}

#endif /* USE_CONIO */


+ 63
- 0
caca/driver_gl.c Целия файл

@@ -292,6 +292,68 @@ static void gl_handle_resize(caca_t *kk, unsigned int *new_width,
glMatrixMode(GL_MODELVIEW);
}

static unsigned int gl_get_event(caca_t *kk)
{
unsigned int event = 0;

glutMainLoopEvent();

if(kk->gl.resized && !kk->resize)
{
kk->resize = 1;
kk->gl.resized = 0;
return CACA_EVENT_RESIZE;
}

if(kk->gl.mouse_changed)
{
if(kk->gl.mouse_clicked)
{
event |= CACA_EVENT_MOUSE_PRESS | kk->gl.mouse_button;
kk->gl.mouse_clicked = 0;
}
kk->mouse_x = kk->gl.mouse_x;
kk->mouse_y = kk->gl.mouse_y;
event |= CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
kk->gl.mouse_changed = 0;
}

if(kk->gl.key != 0)
{
event |= CACA_EVENT_KEY_PRESS;
event |= kk->gl.key;
kk->gl.key = 0;
return event;
}

if(kk->gl.special_key != 0)
{
event |= CACA_EVENT_KEY_PRESS;

switch(kk->gl.special_key)
{
case GLUT_KEY_F1 : kk->gl.special_key = 0; return event | CACA_KEY_F1;
case GLUT_KEY_F2 : kk->gl.special_key = 0; return event | CACA_KEY_F2;
case GLUT_KEY_F3 : kk->gl.special_key = 0; return event | CACA_KEY_F3;
case GLUT_KEY_F4 : kk->gl.special_key = 0; return event | CACA_KEY_F4;
case GLUT_KEY_F5 : kk->gl.special_key = 0; return event | CACA_KEY_F5;
case GLUT_KEY_F6 : kk->gl.special_key = 0; return event | CACA_KEY_F6;
case GLUT_KEY_F7 : kk->gl.special_key = 0; return event | CACA_KEY_F7;
case GLUT_KEY_F8 : kk->gl.special_key = 0; return event | CACA_KEY_F8;
case GLUT_KEY_F9 : kk->gl.special_key = 0; return event | CACA_KEY_F9;
case GLUT_KEY_F10: kk->gl.special_key = 0; return event | CACA_KEY_F10;
case GLUT_KEY_F11: kk->gl.special_key = 0; return event | CACA_KEY_F11;
case GLUT_KEY_F12: kk->gl.special_key = 0; return event | CACA_KEY_F12;
case GLUT_KEY_LEFT : kk->gl.special_key = 0; return event | CACA_KEY_LEFT;
case GLUT_KEY_RIGHT: kk->gl.special_key = 0; return event | CACA_KEY_RIGHT;
case GLUT_KEY_UP : kk->gl.special_key = 0; return event | CACA_KEY_UP;
case GLUT_KEY_DOWN : kk->gl.special_key = 0; return event | CACA_KEY_DOWN;
default: return CACA_EVENT_NONE;
}
}
return CACA_EVENT_NONE;
}

/*
* XXX: following functions are local
*/
@@ -361,6 +423,7 @@ void gl_init_driver(caca_t *kk)
kk->driver.get_window_height = gl_get_window_height;
kk->driver.display = gl_display;
kk->driver.handle_resize = gl_handle_resize;
kk->driver.get_event = gl_get_event;
}

#endif /* USE_GL */


+ 184
- 0
caca/driver_ncurses.c Целия файл

@@ -208,6 +208,189 @@ static void ncurses_handle_resize(caca_t *kk, unsigned int *new_width,
}
}

static unsigned int ncurses_get_event(caca_t *kk)
{
unsigned int event;
int intkey;

if(kk->resize_event)
{
kk->resize_event = 0;
kk->resize = 1;
return CACA_EVENT_RESIZE;
}

intkey = getch();
if(intkey == ERR)
return CACA_EVENT_NONE;

if(intkey < 0x100)
{
return CACA_EVENT_KEY_PRESS | intkey;
}

if(intkey == KEY_MOUSE)
{
MEVENT mevent;
getmouse(&mevent);

switch(mevent.bstate)
{
case BUTTON1_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
break;
case BUTTON1_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_RESERVED_EVENT:
break;

case BUTTON2_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
break;
case BUTTON2_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_RESERVED_EVENT:
break;

case BUTTON3_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
break;
case BUTTON3_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_RESERVED_EVENT:
break;

case BUTTON4_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
break;
case BUTTON4_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_RESERVED_EVENT:
break;

default:
break;
}

if(kk->mouse_x == (unsigned int)mevent.x &&
kk->mouse_y == (unsigned int)mevent.y)
return _pop_event(kk);

kk->mouse_x = mevent.x;
kk->mouse_y = mevent.y;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}

event = CACA_EVENT_KEY_PRESS;

switch(intkey)
{
case KEY_UP: return event | CACA_KEY_UP;
case KEY_DOWN: return event | CACA_KEY_DOWN;
case KEY_LEFT: return event | CACA_KEY_LEFT;
case KEY_RIGHT: return event | CACA_KEY_RIGHT;

case KEY_IC: return event | CACA_KEY_INSERT;
case KEY_DC: return event | CACA_KEY_DELETE;
case KEY_HOME: return event | CACA_KEY_HOME;
case KEY_END: return event | CACA_KEY_END;
case KEY_PPAGE: return event | CACA_KEY_PAGEUP;
case KEY_NPAGE: return event | CACA_KEY_PAGEDOWN;

case KEY_F(1): return event | CACA_KEY_F1;
case KEY_F(2): return event | CACA_KEY_F2;
case KEY_F(3): return event | CACA_KEY_F3;
case KEY_F(4): return event | CACA_KEY_F4;
case KEY_F(5): return event | CACA_KEY_F5;
case KEY_F(6): return event | CACA_KEY_F6;
case KEY_F(7): return event | CACA_KEY_F7;
case KEY_F(8): return event | CACA_KEY_F8;
case KEY_F(9): return event | CACA_KEY_F9;
case KEY_F(10): return event | CACA_KEY_F10;
case KEY_F(11): return event | CACA_KEY_F11;
case KEY_F(12): return event | CACA_KEY_F12;
}

return CACA_EVENT_NONE;
}

/*
* XXX: following functions are local
*/
@@ -236,6 +419,7 @@ void ncurses_init_driver(caca_t *kk)
kk->driver.get_window_height = ncurses_get_window_height;
kk->driver.display = ncurses_display;
kk->driver.handle_resize = ncurses_handle_resize;
kk->driver.get_event = ncurses_get_event;
}

#endif /* USE_NCURSES */


+ 83
- 0
caca/driver_slang.c Целия файл

@@ -245,6 +245,88 @@ static void slang_handle_resize(caca_t *kk, unsigned int *new_width,
SLsmg_reinit_smg();
}

static unsigned int slang_get_event(caca_t *kk)
{
unsigned int event;
int intkey;

if(kk->resize_event)
{
kk->resize_event = 0;
kk->resize = 1;
return CACA_EVENT_RESIZE;
}

if(!SLang_input_pending(0))
return CACA_EVENT_NONE;

/* We first use SLang_getkey() to see whether Esc was pressed
* alone, then (if it wasn't) we unget the key and use SLkp_getkey()
* instead, so that escape sequences are interpreted. */
intkey = SLang_getkey();

if(intkey != 0x1b /* Esc */ || SLang_input_pending(0))
{
SLang_ungetkey(intkey);
intkey = SLkp_getkey();
}

/* If the key was ASCII, return it immediately */
if(intkey < 0x100)
{
return CACA_EVENT_KEY_PRESS | intkey;
}

if(intkey == 0x3e9)
{
int button = (SLang_getkey() - ' ' + 1) & 0xf;
unsigned int x = SLang_getkey() - '!';
unsigned int y = SLang_getkey() - '!';
_push_event(kk, CACA_EVENT_MOUSE_PRESS | button);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | button);

if(kk->mouse_x == x && kk->mouse_y == y)
return _pop_event(kk);

kk->mouse_x = x;
kk->mouse_y = y;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}

event = CACA_EVENT_KEY_PRESS;

switch(intkey)
{
case SL_KEY_UP: return event | CACA_KEY_UP;
case SL_KEY_DOWN: return event | CACA_KEY_DOWN;
case SL_KEY_LEFT: return event | CACA_KEY_LEFT;
case SL_KEY_RIGHT: return event | CACA_KEY_RIGHT;

case SL_KEY_IC: return event | CACA_KEY_INSERT;
case SL_KEY_DELETE: return event | CACA_KEY_DELETE;
case SL_KEY_HOME: return event | CACA_KEY_HOME;
case SL_KEY_END: return event | CACA_KEY_END;
case SL_KEY_PPAGE: return event | CACA_KEY_PAGEUP;
case SL_KEY_NPAGE: return event | CACA_KEY_PAGEDOWN;

case SL_KEY_F(1): return event | CACA_KEY_F1;
case SL_KEY_F(2): return event | CACA_KEY_F2;
case SL_KEY_F(3): return event | CACA_KEY_F3;
case SL_KEY_F(4): return event | CACA_KEY_F4;
case SL_KEY_F(5): return event | CACA_KEY_F5;
case SL_KEY_F(6): return event | CACA_KEY_F6;
case SL_KEY_F(7): return event | CACA_KEY_F7;
case SL_KEY_F(8): return event | CACA_KEY_F8;
case SL_KEY_F(9): return event | CACA_KEY_F9;
case SL_KEY_F(10): return event | CACA_KEY_F10;
case SL_KEY_F(11): return event | CACA_KEY_F11;
case SL_KEY_F(12): return event | CACA_KEY_F12;
}

return CACA_EVENT_NONE;
}

/*
* XXX: following functions are local
*/
@@ -316,6 +398,7 @@ void slang_init_driver(caca_t *kk)
kk->driver.get_window_height = slang_get_window_height;
kk->driver.display = slang_display;
kk->driver.handle_resize = slang_handle_resize;
kk->driver.get_event = slang_get_event;
}

#endif /* USE_SLANG */


+ 75
- 0
caca/driver_win32.c Целия файл

@@ -216,6 +216,80 @@ static void win32_handle_resize(caca_t *kk, unsigned int *new_width,
*new_height = kk->qq->height;
}

static unsigned int win32_get_event(caca_t *kk)
{
INPUT_RECORD rec;
DWORD num;

for( ; ; )
{
GetNumberOfConsoleInputEvents(kk->win32.hin, &num);
if(num == 0)
break;

ReadConsoleInput(kk->win32.hin, &rec, 1, &num);
if(rec.EventType == KEY_EVENT)
{
unsigned int event;

if(rec.Event.KeyEvent.bKeyDown)
event = CACA_EVENT_KEY_PRESS;
else
event = CACA_EVENT_KEY_RELEASE;

if(rec.Event.KeyEvent.uChar.AsciiChar)
return event | rec.Event.KeyEvent.uChar.AsciiChar;
}

if(rec.EventType == MOUSE_EVENT)
{
if(rec.Event.MouseEvent.dwEventFlags == 0)
{
if(rec.Event.MouseEvent.dwButtonState & 0x01)
return CACA_EVENT_MOUSE_PRESS | 0x000001;

if(rec.Event.MouseEvent.dwButtonState & 0x02)
return CACA_EVENT_MOUSE_PRESS | 0x000002;
}
else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
{
COORD pos = rec.Event.MouseEvent.dwMousePosition;

if(kk->mouse_x == (unsigned int)pos.X &&
kk->mouse_y == (unsigned int)pos.Y)
continue;

kk->mouse_x = pos.X;
kk->mouse_y = pos.Y;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}
#if 0
else if(rec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)
{
cout << rec.Event.MouseEvent.dwMousePosition.X << "," <<
rec.Event.MouseEvent.dwMousePosition.Y << " " << flush;
}
else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED)
{
SetConsoleCursorPosition(hOut,
WheelWhere);
if(rec.Event.MouseEvent.dwButtonState & 0xFF000000)
cout << "Down" << flush;
else
cout << "Up " << flush;
}
#endif
}

/* Unknown event */
return CACA_EVENT_NONE;
}

/* No event */
return CACA_EVENT_NONE;
}

/*
* Driver initialisation
*/
@@ -231,6 +305,7 @@ void win32_init_driver(caca_t *kk)
kk->driver.get_window_height = win32_get_window_height;
kk->driver.display = win32_display;
kk->driver.handle_resize = win32_handle_resize;
kk->driver.get_event = win32_get_event;
}

#endif /* USE_WIN32 */


+ 122
- 4
caca/driver_x11.c Целия файл

@@ -22,6 +22,8 @@
#if defined(USE_X11)

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#if defined(HAVE_X11_XKBLIB_H)
# include <X11/XKBlib.h>
#endif
@@ -162,9 +164,9 @@ static int x11_init_graphics(caca_t *kk)

for(;;)
{
XEvent event;
XNextEvent(kk->x11.dpy, &event);
if (event.type == MapNotify)
XEvent xevent;
XNextEvent(kk->x11.dpy, &xevent);
if (xevent.type == MapNotify)
break;
}

@@ -311,11 +313,126 @@ static void x11_handle_resize(caca_t *kk, unsigned int *new_width,
kk->x11.pixmap = new_pixmap;
}

static unsigned int x11_get_event(caca_t *kk)
{
unsigned int event = 0;
XEvent xevent;
char key;

while(XCheckWindowEvent(kk->x11.dpy, kk->x11.window,
kk->x11.event_mask, &xevent) == True)
{
KeySym keysym;

/* Expose event */
if(xevent.type == Expose)
{
XCopyArea(kk->x11.dpy, kk->x11.pixmap,
kk->x11.window, kk->x11.gc, 0, 0,
kk->qq->width * kk->x11.font_width,
kk->qq->height * kk->x11.font_height, 0, 0);
continue;
}

/* Resize event */
if(xevent.type == ConfigureNotify)
{
unsigned int w, h;

w = (xevent.xconfigure.width + kk->x11.font_width / 3)
/ kk->x11.font_width;
h = (xevent.xconfigure.height + kk->x11.font_height / 3)
/ kk->x11.font_height;

if(!w || !h || (w == kk->qq->width && h == kk->qq->height))
continue;

kk->x11.new_width = w;
kk->x11.new_height = h;

/* If we are already resizing, ignore the new signal */
if(kk->resize)
continue;

kk->resize = 1;

return CACA_EVENT_RESIZE;
}

/* Check for mouse motion events */
if(xevent.type == MotionNotify)
{
unsigned int newx = xevent.xmotion.x / kk->x11.font_width;
unsigned int newy = xevent.xmotion.y / kk->x11.font_height;

if(newx >= kk->qq->width)
newx = kk->qq->width - 1;
if(newy >= kk->qq->height)
newy = kk->qq->height - 1;

if(kk->mouse_x == newx && kk->mouse_y == newy)
continue;

kk->mouse_x = newx;
kk->mouse_y = newy;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}

/* Check for mouse press and release events */
if(xevent.type == ButtonPress)
return CACA_EVENT_MOUSE_PRESS
| ((XButtonEvent *)&xevent)->button;

if(xevent.type == ButtonRelease)
return CACA_EVENT_MOUSE_RELEASE
| ((XButtonEvent *)&xevent)->button;

/* Check for key press and release events */
if(xevent.type == KeyPress)
event |= CACA_EVENT_KEY_PRESS;
else if(xevent.type == KeyRelease)
event |= CACA_EVENT_KEY_RELEASE;
else
continue;

if(XLookupString(&xevent.xkey, &key, 1, NULL, NULL))
return event | key;

keysym = XKeycodeToKeysym(kk->x11.dpy, xevent.xkey.keycode, 0);
switch(keysym)
{
case XK_F1: return event | CACA_KEY_F1;
case XK_F2: return event | CACA_KEY_F2;
case XK_F3: return event | CACA_KEY_F3;
case XK_F4: return event | CACA_KEY_F4;
case XK_F5: return event | CACA_KEY_F5;
case XK_F6: return event | CACA_KEY_F6;
case XK_F7: return event | CACA_KEY_F7;
case XK_F8: return event | CACA_KEY_F8;
case XK_F9: return event | CACA_KEY_F9;
case XK_F10: return event | CACA_KEY_F10;
case XK_F11: return event | CACA_KEY_F11;
case XK_F12: return event | CACA_KEY_F12;
case XK_F13: return event | CACA_KEY_F13;
case XK_F14: return event | CACA_KEY_F14;
case XK_F15: return event | CACA_KEY_F15;
case XK_Left: return event | CACA_KEY_LEFT;
case XK_Right: return event | CACA_KEY_RIGHT;
case XK_Up: return event | CACA_KEY_UP;
case XK_Down: return event | CACA_KEY_DOWN;
default: return CACA_EVENT_NONE;
}
}

return CACA_EVENT_NONE;
}

/*
* XXX: following functions are local
*/

static int x11_error_handler(Display *dpy, XErrorEvent *event)
static int x11_error_handler(Display *dpy, XErrorEvent *xevent)
{
/* Ignore the error */
return 0;
@@ -336,6 +453,7 @@ void x11_init_driver(caca_t *kk)
kk->driver.get_window_height = x11_get_window_height;
kk->driver.display = x11_display;
kk->driver.handle_resize = x11_handle_resize;
kk->driver.get_event = x11_get_event;
}

#endif /* USE_X11 */


+ 6
- 575
caca/event.c Целия файл

@@ -19,37 +19,6 @@

#include "config.h"

#if defined(USE_SLANG)
# if defined(HAVE_SLANG_SLANG_H)
# include <slang/slang.h>
# else
# include <slang.h>
# endif
#endif
#if defined(USE_NCURSES)
# if defined(HAVE_NCURSES_H)
# include <ncurses.h>
# else
# include <curses.h>
# endif
#endif
#if defined(USE_CONIO)
# include <conio.h>
#endif
#if defined(USE_X11)
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/keysym.h>
#endif
#if defined(USE_WIN32)
# include <windows.h>
#endif
#if defined(USE_GL)
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/freeglut_ext.h>
#endif

#include "cucul.h"
#include "cucul_internals.h"
#include "caca.h"
@@ -58,8 +27,8 @@
static unsigned int _get_next_event(caca_t *);
static unsigned int _lowlevel_event(caca_t *);
#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
static void _push_event(caca_t *, unsigned int);
static unsigned int _pop_event(caca_t *);
void _push_event(caca_t *, unsigned int);
unsigned int _pop_event(caca_t *);
#endif

#if !defined(_DOXYGEN_SKIP_ME)
@@ -229,556 +198,18 @@ static unsigned int _get_next_event(caca_t *kk)

static unsigned int _lowlevel_event(caca_t *kk)
{
unsigned int event;

#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
event = _pop_event(kk);
unsigned int event = _pop_event(kk);

if(event)
return event;
#endif

#if defined(USE_X11)
/* The X11 event check routine */
if(kk->driver.driver == CACA_DRIVER_X11)
{
XEvent xevent;
char key;

while(XCheckWindowEvent(kk->x11.dpy, kk->x11.window, kk->x11.event_mask, &xevent)
== True)
{
KeySym keysym;

/* Expose event */
if(xevent.type == Expose)
{
XCopyArea(kk->x11.dpy, kk->x11.pixmap,
kk->x11.window, kk->x11.gc, 0, 0,
kk->qq->width * kk->x11.font_width,
kk->qq->height * kk->x11.font_height, 0, 0);
continue;
}

/* Resize event */
if(xevent.type == ConfigureNotify)
{
unsigned int w, h;

w = (xevent.xconfigure.width + kk->x11.font_width / 3)
/ kk->x11.font_width;
h = (xevent.xconfigure.height + kk->x11.font_height / 3)
/ kk->x11.font_height;

if(!w || !h || (w == kk->qq->width && h == kk->qq->height))
continue;

kk->x11.new_width = w;
kk->x11.new_height = h;

/* If we are already resizing, ignore the new signal */
if(kk->resize)
continue;

kk->resize = 1;

return CACA_EVENT_RESIZE;
}

/* Check for mouse motion events */
if(xevent.type == MotionNotify)
{
unsigned int newx = xevent.xmotion.x / kk->x11.font_width;
unsigned int newy = xevent.xmotion.y / kk->x11.font_height;

if(newx >= kk->qq->width)
newx = kk->qq->width - 1;
if(newy >= kk->qq->height)
newy = kk->qq->height - 1;

if(kk->mouse_x == newx && kk->mouse_y == newy)
continue;

kk->mouse_x = newx;
kk->mouse_y = newy;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}

/* Check for mouse press and release events */
if(xevent.type == ButtonPress)
return CACA_EVENT_MOUSE_PRESS
| ((XButtonEvent *)&xevent)->button;

if(xevent.type == ButtonRelease)
return CACA_EVENT_MOUSE_RELEASE
| ((XButtonEvent *)&xevent)->button;

/* Check for key press and release events */
if(xevent.type == KeyPress)
event |= CACA_EVENT_KEY_PRESS;
else if(xevent.type == KeyRelease)
event |= CACA_EVENT_KEY_RELEASE;
else
continue;

if(XLookupString(&xevent.xkey, &key, 1, NULL, NULL))
return event | key;

keysym = XKeycodeToKeysym(kk->x11.dpy, xevent.xkey.keycode, 0);
switch(keysym)
{
case XK_F1: return event | CACA_KEY_F1;
case XK_F2: return event | CACA_KEY_F2;
case XK_F3: return event | CACA_KEY_F3;
case XK_F4: return event | CACA_KEY_F4;
case XK_F5: return event | CACA_KEY_F5;
case XK_F6: return event | CACA_KEY_F6;
case XK_F7: return event | CACA_KEY_F7;
case XK_F8: return event | CACA_KEY_F8;
case XK_F9: return event | CACA_KEY_F9;
case XK_F10: return event | CACA_KEY_F10;
case XK_F11: return event | CACA_KEY_F11;
case XK_F12: return event | CACA_KEY_F12;
case XK_F13: return event | CACA_KEY_F13;
case XK_F14: return event | CACA_KEY_F14;
case XK_F15: return event | CACA_KEY_F15;
case XK_Left: return event | CACA_KEY_LEFT;
case XK_Right: return event | CACA_KEY_RIGHT;
case XK_Up: return event | CACA_KEY_UP;
case XK_Down: return event | CACA_KEY_DOWN;
default: return CACA_EVENT_NONE;
}
}

return CACA_EVENT_NONE;
}
else
#endif
#if defined(USE_NCURSES)
if(kk->driver.driver == CACA_DRIVER_NCURSES)
{
int intkey;

if(kk->resize_event)
{
kk->resize_event = 0;
kk->resize = 1;
return CACA_EVENT_RESIZE;
}

intkey = getch();
if(intkey == ERR)
return CACA_EVENT_NONE;

if(intkey < 0x100)
{
return CACA_EVENT_KEY_PRESS | intkey;
}

if(intkey == KEY_MOUSE)
{
MEVENT mevent;
getmouse(&mevent);

switch(mevent.bstate)
{
case BUTTON1_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
break;
case BUTTON1_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 1);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 1);
break;
case BUTTON1_RESERVED_EVENT:
break;

case BUTTON2_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
break;
case BUTTON2_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 2);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 2);
break;
case BUTTON2_RESERVED_EVENT:
break;

case BUTTON3_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
break;
case BUTTON3_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 3);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 3);
break;
case BUTTON3_RESERVED_EVENT:
break;

case BUTTON4_PRESSED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
break;
case BUTTON4_RELEASED:
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_DOUBLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_TRIPLE_CLICKED:
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
_push_event(kk, CACA_EVENT_MOUSE_PRESS | 4);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | 4);
break;
case BUTTON4_RESERVED_EVENT:
break;

default:
break;
}

if(kk->mouse_x == (unsigned int)mevent.x &&
kk->mouse_y == (unsigned int)mevent.y)
return _pop_event(kk);

kk->mouse_x = mevent.x;
kk->mouse_y = mevent.y;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}

event = CACA_EVENT_KEY_PRESS;

switch(intkey)
{
case KEY_UP: return event | CACA_KEY_UP;
case KEY_DOWN: return event | CACA_KEY_DOWN;
case KEY_LEFT: return event | CACA_KEY_LEFT;
case KEY_RIGHT: return event | CACA_KEY_RIGHT;

case KEY_IC: return event | CACA_KEY_INSERT;
case KEY_DC: return event | CACA_KEY_DELETE;
case KEY_HOME: return event | CACA_KEY_HOME;
case KEY_END: return event | CACA_KEY_END;
case KEY_PPAGE: return event | CACA_KEY_PAGEUP;
case KEY_NPAGE: return event | CACA_KEY_PAGEDOWN;

case KEY_F(1): return event | CACA_KEY_F1;
case KEY_F(2): return event | CACA_KEY_F2;
case KEY_F(3): return event | CACA_KEY_F3;
case KEY_F(4): return event | CACA_KEY_F4;
case KEY_F(5): return event | CACA_KEY_F5;
case KEY_F(6): return event | CACA_KEY_F6;
case KEY_F(7): return event | CACA_KEY_F7;
case KEY_F(8): return event | CACA_KEY_F8;
case KEY_F(9): return event | CACA_KEY_F9;
case KEY_F(10): return event | CACA_KEY_F10;
case KEY_F(11): return event | CACA_KEY_F11;
case KEY_F(12): return event | CACA_KEY_F12;
}

return CACA_EVENT_NONE;
}
else
#endif
#if defined(USE_SLANG)
if(kk->driver.driver == CACA_DRIVER_SLANG)
{
int intkey;

if(kk->resize_event)
{
kk->resize_event = 0;
kk->resize = 1;
return CACA_EVENT_RESIZE;
}

if(!SLang_input_pending(0))
return CACA_EVENT_NONE;

/* We first use SLang_getkey() to see whether Esc was pressed
* alone, then (if it wasn't) we unget the key and use SLkp_getkey()
* instead, so that escape sequences are interpreted. */
intkey = SLang_getkey();

if(intkey != 0x1b /* Esc */ || SLang_input_pending(0))
{
SLang_ungetkey(intkey);
intkey = SLkp_getkey();
}

/* If the key was ASCII, return it immediately */
if(intkey < 0x100)
{
return CACA_EVENT_KEY_PRESS | intkey;
}

if(intkey == 0x3e9)
{
int button = (SLang_getkey() - ' ' + 1) & 0xf;
unsigned int x = SLang_getkey() - '!';
unsigned int y = SLang_getkey() - '!';
_push_event(kk, CACA_EVENT_MOUSE_PRESS | button);
_push_event(kk, CACA_EVENT_MOUSE_RELEASE | button);

if(kk->mouse_x == x && kk->mouse_y == y)
return _pop_event(kk);

kk->mouse_x = x;
kk->mouse_y = y;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}

event = CACA_EVENT_KEY_PRESS;

switch(intkey)
{
case SL_KEY_UP: return event | CACA_KEY_UP;
case SL_KEY_DOWN: return event | CACA_KEY_DOWN;
case SL_KEY_LEFT: return event | CACA_KEY_LEFT;
case SL_KEY_RIGHT: return event | CACA_KEY_RIGHT;

case SL_KEY_IC: return event | CACA_KEY_INSERT;
case SL_KEY_DELETE: return event | CACA_KEY_DELETE;
case SL_KEY_HOME: return event | CACA_KEY_HOME;
case SL_KEY_END: return event | CACA_KEY_END;
case SL_KEY_PPAGE: return event | CACA_KEY_PAGEUP;
case SL_KEY_NPAGE: return event | CACA_KEY_PAGEDOWN;

case SL_KEY_F(1): return event | CACA_KEY_F1;
case SL_KEY_F(2): return event | CACA_KEY_F2;
case SL_KEY_F(3): return event | CACA_KEY_F3;
case SL_KEY_F(4): return event | CACA_KEY_F4;
case SL_KEY_F(5): return event | CACA_KEY_F5;
case SL_KEY_F(6): return event | CACA_KEY_F6;
case SL_KEY_F(7): return event | CACA_KEY_F7;
case SL_KEY_F(8): return event | CACA_KEY_F8;
case SL_KEY_F(9): return event | CACA_KEY_F9;
case SL_KEY_F(10): return event | CACA_KEY_F10;
case SL_KEY_F(11): return event | CACA_KEY_F11;
case SL_KEY_F(12): return event | CACA_KEY_F12;
}

return CACA_EVENT_NONE;
}
else
#endif
#if defined(USE_CONIO)
if(kk->driver.driver == CACA_DRIVER_CONIO)
{
if(!_conio_kbhit())
return CACA_EVENT_NONE;

event = getch();
_push_event(kk, CACA_EVENT_KEY_RELEASE | event);
return CACA_EVENT_KEY_PRESS | event;
}
else
#endif
#if defined(USE_WIN32)
if(kk->driver.driver == CACA_DRIVER_WIN32)
{
INPUT_RECORD rec;
DWORD num;

for( ; ; )
{
GetNumberOfConsoleInputEvents(kk->win32.hin, &num);
if(num == 0)
break;

ReadConsoleInput(kk->win32.hin, &rec, 1, &num);
if(rec.EventType == KEY_EVENT)
{
if(rec.Event.KeyEvent.bKeyDown)
event = CACA_EVENT_KEY_PRESS;
else
event = CACA_EVENT_KEY_RELEASE;

if(rec.Event.KeyEvent.uChar.AsciiChar)
return event | rec.Event.KeyEvent.uChar.AsciiChar;
}

if(rec.EventType == MOUSE_EVENT)
{
if(rec.Event.MouseEvent.dwEventFlags == 0)
{
if(rec.Event.MouseEvent.dwButtonState & 0x01)
return CACA_EVENT_MOUSE_PRESS | 0x000001;

if(rec.Event.MouseEvent.dwButtonState & 0x02)
return CACA_EVENT_MOUSE_PRESS | 0x000002;
}
else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
{
COORD pos = rec.Event.MouseEvent.dwMousePosition;

if(kk->mouse_x == (unsigned int)pos.X &&
kk->mouse_y == (unsigned int)pos.Y)
continue;

kk->mouse_x = pos.X;
kk->mouse_y = pos.Y;

return CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
}
#if 0
else if(rec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)
{
cout << rec.Event.MouseEvent.dwMousePosition.X << "," <<
rec.Event.MouseEvent.dwMousePosition.Y << " " << flush;
}
else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED)
{
SetConsoleCursorPosition(hOut,
WheelWhere);
if(rec.Event.MouseEvent.dwButtonState & 0xFF000000)
cout << "Down" << flush;
else
cout << "Up " << flush;
}
#endif
}

/* Unknown event */
return CACA_EVENT_NONE;
}

/* No event */
return CACA_EVENT_NONE;
}
else
#endif
#if defined(USE_GL)
if(kk->driver.driver == CACA_DRIVER_GL)
{
glutMainLoopEvent();

if(kk->gl.resized && !kk->resize)
{
kk->resize = 1;
kk->gl.resized = 0;
return CACA_EVENT_RESIZE;
}

if(kk->gl.mouse_changed)
{
if(kk->gl.mouse_clicked)
{
event|= CACA_EVENT_MOUSE_PRESS | kk->gl.mouse_button;
kk->gl.mouse_clicked=0;
}
kk->mouse_x = kk->gl.mouse_x;
kk->mouse_y = kk->gl.mouse_y;
event |= CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y;
kk->gl.mouse_changed = 0;
}

if(kk->gl.key != 0)
{
event |= CACA_EVENT_KEY_PRESS;
event |= kk->gl.key;
kk->gl.key = 0;
return event;
}

if(kk->gl.special_key != 0)
{
event |= CACA_EVENT_KEY_PRESS;
switch(kk->gl.special_key)
{
case GLUT_KEY_F1 : kk->gl.special_key = 0; return event | CACA_KEY_F1;
case GLUT_KEY_F2 : kk->gl.special_key = 0; return event | CACA_KEY_F2;
case GLUT_KEY_F3 : kk->gl.special_key = 0; return event | CACA_KEY_F3;
case GLUT_KEY_F4 : kk->gl.special_key = 0; return event | CACA_KEY_F4;
case GLUT_KEY_F5 : kk->gl.special_key = 0; return event | CACA_KEY_F5;
case GLUT_KEY_F6 : kk->gl.special_key = 0; return event | CACA_KEY_F6;
case GLUT_KEY_F7 : kk->gl.special_key = 0; return event | CACA_KEY_F7;
case GLUT_KEY_F8 : kk->gl.special_key = 0; return event | CACA_KEY_F8;
case GLUT_KEY_F9 : kk->gl.special_key = 0; return event | CACA_KEY_F9;
case GLUT_KEY_F10: kk->gl.special_key = 0; return event | CACA_KEY_F10;
case GLUT_KEY_F11: kk->gl.special_key = 0; return event | CACA_KEY_F11;
case GLUT_KEY_F12: kk->gl.special_key = 0; return event | CACA_KEY_F12;
case GLUT_KEY_LEFT : kk->gl.special_key = 0; return event | CACA_KEY_LEFT;
case GLUT_KEY_RIGHT: kk->gl.special_key = 0; return event | CACA_KEY_RIGHT;
case GLUT_KEY_UP : kk->gl.special_key = 0; return event | CACA_KEY_UP;
case GLUT_KEY_DOWN : kk->gl.special_key = 0; return event | CACA_KEY_DOWN;
default: return CACA_EVENT_NONE;
}
}
return CACA_EVENT_NONE;
}
else
#endif
{
/* Dummy */
}

return CACA_EVENT_NONE;
return kk->driver.get_event(kk);
}

#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
static void _push_event(caca_t *kk, unsigned int event)
void _push_event(caca_t *kk, unsigned int event)
{
if(!event || kk->events.queue == EVENTBUF_LEN)
return;
@@ -786,7 +217,7 @@ static void _push_event(caca_t *kk, unsigned int event)
kk->events.queue++;
}

static unsigned int _pop_event(caca_t *kk)
unsigned int _pop_event(caca_t *kk)
{
int i;
unsigned int event;


Зареждане…
Отказ
Запис