Browse Source

* src/event.c:

+ Added the CACA_EVENT_RESIZE event.
    + Added caca_get_mouse_x() and caca_get_mouse_y().
  * src/graphics.c:
    + Window resize handling in the X11 driver.
  * examples/aafire.c:
    + Fixed a bad assumption in the resize handling code.
tags/v0.99.beta14
Sam Hocevar sam 21 years ago
parent
commit
51a129a743
5 changed files with 211 additions and 56 deletions
  1. +2
    -2
      examples/aafire.c
  2. +3
    -0
      src/caca.h
  3. +3
    -0
      src/caca_internals.h
  4. +122
    -51
      src/event.c
  5. +81
    -3
      src/graphics.c

+ 2
- 2
examples/aafire.c View File

@@ -219,8 +219,8 @@ drawfire (void)
caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1, caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
caca_bitmap, bitmap); caca_bitmap, bitmap);
caca_refresh(); caca_refresh();
XSIZ = caca_get_width() * 2;
YSIZ = caca_get_height() * 2 - 4;
/*XSIZ = caca_get_width() * 2;
YSIZ = caca_get_height() * 2 - 4;*/
#else #else
aa_renderpalette (context, palette, params, 0, 0, aa_scrwidth (context), aa_renderpalette (context, palette, params, 0, 0, aa_scrwidth (context),
aa_scrheight (context)); aa_scrheight (context));


+ 3
- 0
src/caca.h View File

@@ -181,6 +181,7 @@ enum caca_event
CACA_EVENT_MOUSE_PRESS = 0x04000000, /**< A mouse button was pressed. */ CACA_EVENT_MOUSE_PRESS = 0x04000000, /**< A mouse button was pressed. */
CACA_EVENT_MOUSE_RELEASE = 0x08000000, /**< A mouse button was released. */ CACA_EVENT_MOUSE_RELEASE = 0x08000000, /**< A mouse button was released. */
CACA_EVENT_MOUSE_MOTION = 0x10000000, /**< The mouse was moved. */ CACA_EVENT_MOUSE_MOTION = 0x10000000, /**< The mouse was moved. */
CACA_EVENT_RESIZE = 0x20000000, /**< The window was resized. */
CACA_EVENT_ANY = 0xff000000 /**< Bitmask for any event. */ CACA_EVENT_ANY = 0xff000000 /**< Bitmask for any event. */
}; };


@@ -258,6 +259,8 @@ void caca_end(void);
* @{ */ * @{ */
unsigned int caca_get_event(unsigned int); unsigned int caca_get_event(unsigned int);
unsigned int caca_wait_event(unsigned int); unsigned int caca_wait_event(unsigned int);
unsigned int caca_get_mouse_x(void);
unsigned int caca_get_mouse_y(void);
/* @} */ /* @} */


/** \defgroup char Character printing /** \defgroup char Character printing


+ 3
- 0
src/caca_internals.h View File

@@ -73,6 +73,8 @@ extern unsigned int _caca_getticks(struct caca_timer *);
/* Cached screen size */ /* Cached screen size */
extern unsigned int _caca_width; extern unsigned int _caca_width;
extern unsigned int _caca_height; extern unsigned int _caca_height;
extern unsigned int _caca_new_width;
extern unsigned int _caca_new_height;


/* Internal libcaca features */ /* Internal libcaca features */
extern enum caca_feature _caca_background; extern enum caca_feature _caca_background;
@@ -83,6 +85,7 @@ extern enum caca_feature _caca_antialiasing;
#include <X11/Xlib.h> #include <X11/Xlib.h>
extern Display *x11_dpy; extern Display *x11_dpy;
extern Window x11_window; extern Window x11_window;
extern long int x11_event_mask;
extern int x11_font_width, x11_font_height; extern int x11_font_width, x11_font_height;
#endif #endif




+ 122
- 51
src/event.c View File

@@ -69,6 +69,8 @@ static unsigned int eventbuf[EVENTBUF_LEN];
static int events = 0; static int events = 0;
#endif #endif


static unsigned int mouse_x = 0, mouse_y = 0;

#if !defined(_DOXYGEN_SKIP_ME) #if !defined(_DOXYGEN_SKIP_ME)
/* If no new key was pressed after AUTOREPEAT_THRESHOLD usec, assume the /* If no new key was pressed after AUTOREPEAT_THRESHOLD usec, assume the
* key was released */ * key was released */
@@ -130,6 +132,34 @@ unsigned int caca_wait_event(unsigned int event_mask)
} }
} }


/** \brief Return the X mouse coordinate.
*
* This function returns the X coordinate of the mouse position last time
* it was detected. This function is not reliable if the ncurses or S-Lang
* drivers are being used, because mouse position is only detected when
* the mouse is clicked. Other drivers such as X11 work well.
*
* \return The X mouse coordinate.
*/
unsigned int caca_get_mouse_x(void)
{
return mouse_x;
}

/** \brief Return the Y mouse coordinate.
*
* This function returns the Y coordinate of the mouse position last time
* it was detected. This function is not reliable if the ncurses or S-Lang
* drivers are being used, because mouse position is only detected when
* the mouse is clicked. Other drivers such as X11 work well.
*
* \return The Y mouse coordinate.
*/
unsigned int caca_get_mouse_y(void)
{
return mouse_y;
}

/* /*
* XXX: The following functions are local. * XXX: The following functions are local.
*/ */
@@ -216,16 +246,28 @@ static unsigned int _lowlevel_event(void)
if(_caca_driver == CACA_DRIVER_X11) if(_caca_driver == CACA_DRIVER_X11)
{ {
XEvent xevent; XEvent xevent;
static unsigned int x11_x = 0, x11_y = 0;
long int xevent_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask
| ButtonReleaseMask | PointerMotionMask;
char key; char key;


while(XCheckWindowEvent(x11_dpy, x11_window, xevent_mask, &xevent)
while(XCheckWindowEvent(x11_dpy, x11_window, x11_event_mask, &xevent)
== True) == True)
{ {
KeySym keysym; KeySym keysym;


/* Resize event */
if(xevent.type == ConfigureNotify)
{
unsigned int w = xevent.xconfigure.width / x11_font_width;
unsigned int h = xevent.xconfigure.height / x11_font_height;

if(w == _caca_width && h == _caca_height)
continue;

_caca_new_width = w;
_caca_new_height = h;

return CACA_EVENT_RESIZE;
}

/* Check for mouse motion events */ /* Check for mouse motion events */
if(xevent.type == MotionNotify) if(xevent.type == MotionNotify)
{ {
@@ -237,13 +279,13 @@ static unsigned int _lowlevel_event(void)
if(newy >= _caca_height) if(newy >= _caca_height)
newy = _caca_height - 1; newy = _caca_height - 1;


if(x11_x == newx && x11_y == newy)
if(mouse_x == newx && mouse_y == newy)
continue; continue;


x11_x = newx & 0xfff;
x11_y = newy & 0xfff;
mouse_x = newx;
mouse_y = newy;


return CACA_EVENT_MOUSE_MOTION | (newx << 12) | (newy << 0);
return CACA_EVENT_MOUSE_MOTION | (mouse_x << 12) | mouse_y;
} }


/* Check for mouse press and release events */ /* Check for mouse press and release events */
@@ -427,7 +469,14 @@ static unsigned int _lowlevel_event(void)
break; break;
} }


return CACA_EVENT_MOUSE_MOTION | (mevent.x << 12) | mevent.y;
if(mouse_x == (unsigned int)mevent.x &&
mouse_y == (unsigned int)mevent.y)
return _pop_event();

mouse_x = mevent.x;
mouse_y = mevent.y;

return CACA_EVENT_MOUSE_MOTION | (mouse_x << 12) | mouse_y;
} }


event = CACA_EVENT_KEY_PRESS; event = CACA_EVENT_KEY_PRESS;
@@ -492,11 +541,18 @@ static unsigned int _lowlevel_event(void)
if(intkey == 0x3e9) if(intkey == 0x3e9)
{ {
int button = (SLang_getkey() - ' ' + 1) & 0xf; int button = (SLang_getkey() - ' ' + 1) & 0xf;
int x = SLang_getkey() - '!';
int y = SLang_getkey() - '!';
unsigned int x = SLang_getkey() - '!';
unsigned int y = SLang_getkey() - '!';
_push_event(CACA_EVENT_MOUSE_PRESS | button); _push_event(CACA_EVENT_MOUSE_PRESS | button);
_push_event(CACA_EVENT_MOUSE_RELEASE | button); _push_event(CACA_EVENT_MOUSE_RELEASE | button);
return CACA_EVENT_MOUSE_MOTION | (x << 12) | (y << 0);

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

mouse_x = x;
mouse_y = y;

return CACA_EVENT_MOUSE_MOTION | (mouse_x << 12) | mouse_y;
} }


event = CACA_EVENT_KEY_PRESS; event = CACA_EVENT_KEY_PRESS;
@@ -551,55 +607,70 @@ static unsigned int _lowlevel_event(void)
INPUT_RECORD rec; INPUT_RECORD rec;
DWORD num; DWORD num;


GetNumberOfConsoleInputEvents(win32_hin, &num);
if(num == 0)
return CACA_EVENT_NONE;

ReadConsoleInput(win32_hin, &rec, 1, &num);
if(rec.EventType == KEY_EVENT)
for( ; ; )
{ {
if(rec.Event.KeyEvent.bKeyDown)
event = CACA_EVENT_KEY_PRESS;
else
event = CACA_EVENT_KEY_RELEASE;
GetNumberOfConsoleInputEvents(win32_hin, &num);
if(num == 0)
break;


if(rec.Event.KeyEvent.uChar.AsciiChar)
return event | rec.Event.KeyEvent.uChar.AsciiChar;
}
else if(rec.EventType == MOUSE_EVENT)
{
if(rec.Event.MouseEvent.dwEventFlags == 0)
ReadConsoleInput(win32_hin, &rec, 1, &num);
if(rec.EventType == KEY_EVENT)
{ {
if(rec.Event.MouseEvent.dwButtonState & 0x01)
return CACA_EVENT_MOUSE_PRESS | 0x000001;
if(rec.Event.KeyEvent.bKeyDown)
event = CACA_EVENT_KEY_PRESS;
else
event = CACA_EVENT_KEY_RELEASE;


if(rec.Event.MouseEvent.dwButtonState & 0x02)
return CACA_EVENT_MOUSE_PRESS | 0x000002;
if(rec.Event.KeyEvent.uChar.AsciiChar)
return event | rec.Event.KeyEvent.uChar.AsciiChar;
} }
else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)

if(rec.EventType == MOUSE_EVENT)
{ {
return CACA_EVENT_MOUSE_MOTION
| (rec.Event.MouseEvent.dwMousePosition.X << 12)
| (rec.Event.MouseEvent.dwMousePosition.Y);
}
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(mouse_x == (unsigned int)pos.X &&
mouse_y == (unsigned int)pos.Y)
continue;

mouse_x = pos.X;
mouse_y = pos.Y;

return CACA_EVENT_MOUSE_MOTION | (mouse_x << 12) | mouse_y;
}
#if 0 #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;
}
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 #endif
}

/* Unknown event */
return CACA_EVENT_NONE;
} }


/* No event */
return CACA_EVENT_NONE; return CACA_EVENT_NONE;
} }
else else


+ 81
- 3
src/graphics.c View File

@@ -78,6 +78,8 @@ typedef unsigned char uint8_t;
#if !defined(_DOXYGEN_SKIP_ME) #if !defined(_DOXYGEN_SKIP_ME)
unsigned int _caca_width = 0; unsigned int _caca_width = 0;
unsigned int _caca_height = 0; unsigned int _caca_height = 0;
unsigned int _caca_new_width = 0;
unsigned int _caca_new_height = 0;
#endif #endif


/* /*
@@ -154,6 +156,8 @@ static char *conio_screen;
#if defined(USE_X11) && !defined(_DOXYGEN_SKIP_ME) #if defined(USE_X11) && !defined(_DOXYGEN_SKIP_ME)
Display *x11_dpy; Display *x11_dpy;
Window x11_window; Window x11_window;
long int x11_event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask
| ButtonReleaseMask | PointerMotionMask | StructureNotifyMask;
int x11_font_width, x11_font_height; int x11_font_width, x11_font_height;
static GC x11_gc; static GC x11_gc;
static Pixmap x11_pixmap; static Pixmap x11_pixmap;
@@ -229,6 +233,8 @@ static enum caca_color _caca_bgcolor = CACA_COLOR_BLACK;
/* /*
* Local functions * Local functions
*/ */
static void caca_handle_resize(void);

#if defined(USE_SLANG) #if defined(USE_SLANG)
static void slang_init_palette(void); static void slang_init_palette(void);
#endif #endif
@@ -796,9 +802,7 @@ int _caca_init_graphics(void)
XAutoRepeatOff(x11_dpy); XAutoRepeatOff(x11_dpy);
#endif #endif


XSelectInput(x11_dpy, x11_window,
KeyPressMask | KeyReleaseMask | ButtonPressMask
| ButtonReleaseMask | PointerMotionMask);
XSelectInput(x11_dpy, x11_window, x11_event_mask);


XSync(x11_dpy, False); XSync(x11_dpy, False);


@@ -888,6 +892,9 @@ int _caca_init_graphics(void)


_caca_scratch_line = malloc(_caca_width + 1); _caca_scratch_line = malloc(_caca_width + 1);


_caca_new_width = _caca_width;
_caca_new_height = _caca_height;

_caca_delay = 0; _caca_delay = 0;
_caca_rendertime = 0; _caca_rendertime = 0;


@@ -1162,6 +1169,9 @@ void caca_refresh(void)
/* Dummy */ /* Dummy */
} }


if(_caca_width != _caca_new_width || _caca_height != _caca_new_height)
caca_handle_resize();

/* Wait until _caca_delay + time of last call */ /* Wait until _caca_delay + time of last call */
ticks += _caca_getticks(&timer); ticks += _caca_getticks(&timer);
for(ticks += _caca_getticks(&timer); for(ticks += _caca_getticks(&timer);
@@ -1181,6 +1191,73 @@ void caca_refresh(void)
lastticks = 0; lastticks = 0;
} }


/*
* XXX: following functions are loca
*/
static void caca_handle_resize(void)
{
unsigned int old_width = _caca_width;
unsigned int old_height = _caca_height;

_caca_width = _caca_new_width;
_caca_height = _caca_new_height;

free(_caca_empty_line);
_caca_empty_line = malloc(_caca_width + 1);
memset(_caca_empty_line, ' ', _caca_width);
_caca_empty_line[_caca_width] = '\0';

free(_caca_scratch_line);
_caca_scratch_line = malloc(_caca_width + 1);

#if defined(USE_SLANG)
if(_caca_driver == CACA_DRIVER_SLANG)
{
}
else
#endif
#if defined(USE_NCURSES)
if(_caca_driver == CACA_DRIVER_NCURSES)
{
}
else
#endif
#if defined(USE_CONIO)
if(_caca_driver == CACA_DRIVER_CONIO)
{
}
else
#endif
#if defined(USE_X11)
if(_caca_driver == CACA_DRIVER_X11)
{
XFreePixmap(x11_dpy, x11_pixmap);
free(x11_char);
free(x11_attr);

x11_pixmap = XCreatePixmap(x11_dpy, x11_window,
_caca_width * x11_font_width,
_caca_height * x11_font_height,
DefaultDepth(x11_dpy,
DefaultScreen(x11_dpy)));
x11_char = malloc(_caca_width * _caca_height * sizeof(int));
memset(x11_char, 0, _caca_width * _caca_height * sizeof(int));
x11_attr = malloc(_caca_width * _caca_height * sizeof(int));
memset(x11_attr, 0, _caca_width * _caca_height * sizeof(int));
}
else
#endif
#if defined(USE_WIN32)
if(_caca_driver == CACA_DRIVER_WIN32)
{
}
else
#endif
{
/* Dummy */
}
}

#if defined(USE_SLANG) #if defined(USE_SLANG)
static void slang_init_palette(void) static void slang_init_palette(void)
{ {
@@ -1229,6 +1306,7 @@ static void slang_init_palette(void)
#if defined(USE_X11) #if defined(USE_X11)
static int x11_error_handler(Display *dpy, XErrorEvent *event) static int x11_error_handler(Display *dpy, XErrorEvent *event)
{ {
/* Ignore the error */
return 0; return 0;
} }
#endif #endif


Loading…
Cancel
Save