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_bitmap, bitmap);
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
aa_renderpalette (context, palette, params, 0, 0, aa_scrwidth (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_RELEASE = 0x08000000, /**< A mouse button was released. */
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. */
};

@@ -258,6 +259,8 @@ void caca_end(void);
* @{ */
unsigned int caca_get_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


+ 3
- 0
src/caca_internals.h View File

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

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



+ 122
- 51
src/event.c View File

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

static unsigned int mouse_x = 0, mouse_y = 0;

#if !defined(_DOXYGEN_SKIP_ME)
/* If no new key was pressed after AUTOREPEAT_THRESHOLD usec, assume the
* 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.
*/
@@ -216,16 +246,28 @@ static unsigned int _lowlevel_event(void)
if(_caca_driver == CACA_DRIVER_X11)
{
XEvent xevent;
static unsigned int x11_x = 0, x11_y = 0;
long int xevent_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask
| ButtonReleaseMask | PointerMotionMask;
char key;

while(XCheckWindowEvent(x11_dpy, x11_window, xevent_mask, &xevent)
while(XCheckWindowEvent(x11_dpy, x11_window, x11_event_mask, &xevent)
== True)
{
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 */
if(xevent.type == MotionNotify)
{
@@ -237,13 +279,13 @@ static unsigned int _lowlevel_event(void)
if(newy >= _caca_height)
newy = _caca_height - 1;

if(x11_x == newx && x11_y == newy)
if(mouse_x == newx && mouse_y == newy)
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 */
@@ -427,7 +469,14 @@ static unsigned int _lowlevel_event(void)
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;
@@ -492,11 +541,18 @@ static unsigned int _lowlevel_event(void)
if(intkey == 0x3e9)
{
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_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;
@@ -551,55 +607,70 @@ static unsigned int _lowlevel_event(void)
INPUT_RECORD rec;
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
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
}

/* Unknown event */
return CACA_EVENT_NONE;
}

/* No event */
return CACA_EVENT_NONE;
}
else


+ 81
- 3
src/graphics.c View File

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

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

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

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

XSync(x11_dpy, False);

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

_caca_scratch_line = malloc(_caca_width + 1);

_caca_new_width = _caca_width;
_caca_new_height = _caca_height;

_caca_delay = 0;
_caca_rendertime = 0;

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

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

/* Wait until _caca_delay + time of last call */
ticks += _caca_getticks(&timer);
for(ticks += _caca_getticks(&timer);
@@ -1181,6 +1191,73 @@ void caca_refresh(void)
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)
static void slang_init_palette(void)
{
@@ -1229,6 +1306,7 @@ static void slang_init_palette(void)
#if defined(USE_X11)
static int x11_error_handler(Display *dpy, XErrorEvent *event)
{
/* Ignore the error */
return 0;
}
#endif


Loading…
Cancel
Save