370 lines
11 KiB
C
370 lines
11 KiB
C
#include "xlib.h"
|
|
#include "scheme48.h"
|
|
|
|
#define ECAST(name, type) type* name = (type*)e
|
|
#define sidx 4
|
|
#define SET(i, v) S48_VECTOR_SET(r, i, v)
|
|
#define SETSIZE(i) r = s48_make_vector(sidx+i, S48_FALSE)
|
|
|
|
s48_value scx_enter_event(XEvent* e) {
|
|
s48_value r = S48_FALSE;
|
|
s48_value temp = S48_FALSE;
|
|
int i;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
S48_GC_PROTECT_2(r, temp);
|
|
|
|
switch (e->type) {
|
|
|
|
case KeyPress : case KeyRelease :
|
|
case ButtonPress : case ButtonRelease :
|
|
case MotionNotify : {
|
|
ECAST(q, XKeyEvent);
|
|
SETSIZE(10);
|
|
// all equal in the beginning
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->root));
|
|
SET(sidx+1, SCX_ENTER_WINDOW(q->subwindow));
|
|
SET(sidx+2, SCX_ENTER_TIME(q->time));
|
|
SET(sidx+3, s48_enter_integer(q->x));
|
|
SET(sidx+4, s48_enter_integer(q->y));
|
|
SET(sidx+5, s48_enter_integer(q->x_root));
|
|
SET(sidx+6, s48_enter_integer(q->y_root));
|
|
SET(sidx+7, Bits_To_Symbols(q->state, State_Syms));
|
|
// now they are different
|
|
switch (e->type) {
|
|
case KeyPress : case KeyRelease : {
|
|
SET(sidx+8, s48_enter_integer(q->keycode));
|
|
SET(sidx+9, S48_ENTER_BOOLEAN(q->same_screen));
|
|
} break;
|
|
case ButtonPress : case ButtonRelease : {
|
|
ECAST(q, XButtonEvent);
|
|
SET(sidx+8, Bit_To_Symbol(q->button, Button_Syms));
|
|
SET(sidx+9, S48_ENTER_BOOLEAN(q->same_screen));
|
|
} break;
|
|
case MotionNotify : {
|
|
ECAST(q, XMotionEvent);
|
|
SET(sidx+8, S48_ENTER_BOOLEAN(q->is_hint));
|
|
SET(sidx+9, S48_ENTER_BOOLEAN(q->same_screen));
|
|
} break;
|
|
}
|
|
} break;
|
|
|
|
case EnterNotify : case LeaveNotify : {
|
|
ECAST(q, XCrossingEvent);
|
|
SETSIZE(12);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->root));
|
|
SET(sidx+1, SCX_ENTER_WINDOW(q->subwindow));
|
|
SET(sidx+2, SCX_ENTER_TIME(q->time));
|
|
SET(sidx+3, s48_enter_integer(q->x));
|
|
SET(sidx+4, s48_enter_integer(q->y));
|
|
SET(sidx+5, s48_enter_integer(q->x_root));
|
|
SET(sidx+6, s48_enter_integer(q->y_root));
|
|
SET(sidx+7, Bit_To_Symbol(q->mode, Cross_Mode_Syms));
|
|
SET(sidx+8, Bit_To_Symbol(q->detail, Cross_Detail_Syms));
|
|
SET(sidx+9, S48_ENTER_BOOLEAN(q->same_screen));
|
|
SET(sidx+10, S48_ENTER_BOOLEAN(q->focus));
|
|
// Elk does this; but why not State_Syms??
|
|
SET(sidx+11, Bit_To_Symbol(q->state, Button_Syms));
|
|
} break;
|
|
|
|
case FocusIn : case FocusOut : {
|
|
ECAST(q, XFocusChangeEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, Bit_To_Symbol(q->mode, Cross_Mode_Syms));
|
|
SET(sidx+1, Bit_To_Symbol(q->detail, Focus_Detail_Syms));
|
|
} break;
|
|
|
|
case KeymapNotify : {
|
|
ECAST(q, XKeymapEvent);
|
|
SETSIZE(1);
|
|
temp = s48_make_string(32, (char)0);
|
|
for (i=0; i < 32; i++)
|
|
S48_STRING_SET(temp, i, q->key_vector[i]);
|
|
SET(sidx+0, temp);
|
|
} break;
|
|
|
|
case Expose : {
|
|
ECAST(q, XExposeEvent);
|
|
SETSIZE(5);
|
|
SET(sidx+0, s48_enter_integer(q->x));
|
|
SET(sidx+1, s48_enter_integer(q->y));
|
|
SET(sidx+2, s48_enter_integer(q->width));
|
|
SET(sidx+3, s48_enter_integer(q->height));
|
|
SET(sidx+4, s48_enter_integer(q->count));
|
|
} break;
|
|
|
|
case GraphicsExpose : {
|
|
ECAST(q, XGraphicsExposeEvent);
|
|
SETSIZE(7);
|
|
// the ->window member is only a drawable here! ??
|
|
SET(sidx+0, s48_enter_integer(q->x));
|
|
SET(sidx+1, s48_enter_integer(q->y));
|
|
SET(sidx+2, s48_enter_integer(q->width));
|
|
SET(sidx+3, s48_enter_integer(q->height));
|
|
SET(sidx+4, s48_enter_integer(q->count));
|
|
SET(sidx+5, s48_enter_integer(q->major_code));
|
|
SET(sidx+6, s48_enter_integer(q->minor_code));
|
|
} break;
|
|
|
|
case NoExpose : {
|
|
ECAST(q, XNoExposeEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, s48_enter_integer(q->major_code));
|
|
SET(sidx+1, s48_enter_integer(q->minor_code));
|
|
} break;
|
|
|
|
case VisibilityNotify : {
|
|
ECAST(q, XVisibilityEvent);
|
|
SETSIZE(1);
|
|
SET(sidx+0, Bit_To_Symbol(q->state, Visibility_Syms));
|
|
} break;
|
|
|
|
case CreateNotify : {
|
|
ECAST(q, XCreateWindowEvent);
|
|
SETSIZE(7);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, s48_enter_integer(q->x));
|
|
SET(sidx+2, s48_enter_integer(q->y));
|
|
SET(sidx+3, s48_enter_integer(q->width));
|
|
SET(sidx+4, s48_enter_integer(q->height));
|
|
SET(sidx+5, s48_enter_integer(q->border_width));
|
|
SET(sidx+6, S48_ENTER_BOOLEAN(q->override_redirect));
|
|
} break;
|
|
|
|
case DestroyNotify : {
|
|
ECAST(q, XDestroyWindowEvent);
|
|
SETSIZE(1);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
} break;
|
|
|
|
case UnmapNotify : {
|
|
ECAST(q, XUnmapEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, S48_ENTER_BOOLEAN(q->from_configure));
|
|
} break;
|
|
|
|
case MapNotify : {
|
|
ECAST(q, XMapEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, S48_ENTER_BOOLEAN(q->override_redirect));
|
|
} break;
|
|
|
|
case MapRequest : {
|
|
ECAST(q, XMapRequestEvent);
|
|
SETSIZE(1);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
} break;
|
|
|
|
case ReparentNotify : {
|
|
ECAST(q, XReparentEvent);
|
|
SETSIZE(5);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, SCX_ENTER_WINDOW(q->parent));
|
|
SET(sidx+2, s48_enter_integer(q->x));
|
|
SET(sidx+3, s48_enter_integer(q->y));
|
|
SET(sidx+4, S48_ENTER_BOOLEAN(q->override_redirect));
|
|
} break;
|
|
|
|
case ConfigureNotify : {
|
|
ECAST(q, XConfigureEvent);
|
|
SETSIZE(8);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, s48_enter_integer(q->x));
|
|
SET(sidx+2, s48_enter_integer(q->y));
|
|
SET(sidx+3, s48_enter_integer(q->width));
|
|
SET(sidx+4, s48_enter_integer(q->height));
|
|
SET(sidx+5, s48_enter_integer(q->border_width));
|
|
SET(sidx+6, SCX_ENTER_WINDOW(q->above));
|
|
SET(sidx+7, S48_ENTER_BOOLEAN(q->override_redirect));
|
|
} break;
|
|
|
|
case ConfigureRequest : {
|
|
ECAST(q, XConfigureRequestEvent);
|
|
SETSIZE(9);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, s48_enter_integer(q->x));
|
|
SET(sidx+2, s48_enter_integer(q->y));
|
|
SET(sidx+3, s48_enter_integer(q->width));
|
|
SET(sidx+4, s48_enter_integer(q->height));
|
|
SET(sidx+5, s48_enter_integer(q->border_width));
|
|
SET(sidx+6, SCX_ENTER_WINDOW(q->above));
|
|
SET(sidx+7, Bit_To_Symbol(q->detail, Stack_Mode_Syms));
|
|
SET(sidx+8, s48_enter_integer(q->value_mask));
|
|
} break;
|
|
|
|
case GravityNotify : {
|
|
ECAST(q, XGravityEvent);
|
|
SETSIZE(3);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, s48_enter_integer(q->x));
|
|
SET(sidx+2, s48_enter_integer(q->y));
|
|
} break;
|
|
|
|
case ResizeRequest : {
|
|
ECAST(q, XResizeRequestEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, s48_enter_integer(q->width));
|
|
SET(sidx+1, s48_enter_integer(q->height));
|
|
} break;
|
|
|
|
case CirculateRequest : {
|
|
ECAST(q, XCirculateEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->window));
|
|
SET(sidx+1, Bit_To_Symbol(q->place, Place_Syms));
|
|
} break;
|
|
|
|
case PropertyNotify : {
|
|
ECAST(q, XPropertyEvent);
|
|
SETSIZE(3);
|
|
SET(sidx+0, SCX_ENTER_ATOM(q->atom));
|
|
SET(sidx+1, SCX_ENTER_TIME(q->time));
|
|
SET(sidx+2, Bit_To_Symbol(q->state, Prop_Syms));
|
|
} break;
|
|
|
|
case SelectionClear : {
|
|
ECAST(q, XSelectionClearEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, SCX_ENTER_ATOM(q->selection));
|
|
SET(sidx+1, SCX_ENTER_TIME(q->time));
|
|
} break;
|
|
|
|
case SelectionRequest : {
|
|
ECAST(q, XSelectionRequestEvent);
|
|
SETSIZE(5);
|
|
SET(sidx+0, SCX_ENTER_WINDOW(q->requestor));
|
|
SET(sidx+1, SCX_ENTER_ATOM(q->selection));
|
|
SET(sidx+2, SCX_ENTER_ATOM(q->target));
|
|
SET(sidx+3, SCX_ENTER_ATOM(q->property));
|
|
SET(sidx+4, SCX_ENTER_TIME(q->time));
|
|
} break;
|
|
|
|
case SelectionNotify : {
|
|
ECAST(q, XSelectionEvent);
|
|
SETSIZE(4);
|
|
SET(sidx+0, SCX_ENTER_ATOM(q->selection));
|
|
SET(sidx+1, SCX_ENTER_ATOM(q->target));
|
|
SET(sidx+2, SCX_ENTER_ATOM(q->property));
|
|
SET(sidx+3, SCX_ENTER_TIME(q->time));
|
|
} break;
|
|
|
|
case ColormapNotify : {
|
|
ECAST(q, XColormapEvent);
|
|
SETSIZE(3);
|
|
SET(sidx+0, SCX_ENTER_COLORMAP(q->colormap));
|
|
SET(sidx+1, S48_ENTER_BOOLEAN(q->new));
|
|
SET(sidx+2, q->state == ColormapInstalled ? S48_TRUE : S48_FALSE);
|
|
} break;
|
|
|
|
case ClientMessage : {
|
|
ECAST(q, XClientMessageEvent);
|
|
SETSIZE(2);
|
|
SET(sidx+0, SCX_ENTER_ATOM(q->message_type));
|
|
switch (q->format) {
|
|
case 8 : {
|
|
temp = s48_make_string(20, (char)0);
|
|
for (i=0; i < 20; i++)
|
|
S48_STRING_SET(temp, i, q->data.b[i]);
|
|
} break;
|
|
case 16 : {
|
|
temp = s48_make_vector(10, S48_FALSE);
|
|
for (i=0; i < 10; i++)
|
|
S48_VECTOR_SET(temp, i, s48_enter_integer(q->data.s[i]));
|
|
} break;
|
|
case 32 : {
|
|
temp = s48_make_vector(5, S48_FALSE);
|
|
for (i=0; i < 5; i++)
|
|
S48_VECTOR_SET(temp, i, s48_enter_integer(q->data.l[i]));
|
|
} break;
|
|
default : temp = s48_enter_integer(q->format); //??
|
|
}
|
|
|
|
SET(sidx+1, temp);
|
|
}
|
|
|
|
case MappingNotify : {
|
|
ECAST(q, XMappingEvent);
|
|
SETSIZE(3);
|
|
SET(sidx+0, Bit_To_Symbol(q->request, Mapping_Syms));
|
|
SET(sidx+1, s48_enter_integer(q->first_keycode));
|
|
SET(sidx+2, s48_enter_integer(q->count));
|
|
} break;
|
|
|
|
} // switch end
|
|
|
|
// XAnyEvent entries
|
|
{
|
|
ECAST(q, XAnyEvent);
|
|
SET(0, s48_enter_integer(q->serial));
|
|
SET(1, S48_ENTER_BOOLEAN(q->send_event));
|
|
SET(2, SCX_ENTER_DISPLAY(q->display));
|
|
SET(3, SCX_ENTER_WINDOW(q->window));
|
|
}
|
|
// more??
|
|
|
|
// And the Event-Name
|
|
r = s48_cons( Bit_To_Symbol(e->type, Event_Syms), r );
|
|
|
|
S48_GC_UNPROTECT();
|
|
return r;
|
|
}
|
|
|
|
s48_value scx_Next_Event(s48_value Xdisplay) {
|
|
XEvent e;
|
|
XNextEvent(SCX_EXTRACT_DISPLAY(Xdisplay), &e);
|
|
return scx_enter_event(&e);
|
|
}
|
|
|
|
s48_value scx_Peek_Event(s48_value Xdisplay) {
|
|
XEvent e;
|
|
XPeekEvent(SCX_EXTRACT_DISPLAY(Xdisplay), &e);
|
|
return scx_enter_event(&e);
|
|
}
|
|
|
|
s48_value scx_Events_Pending(s48_value Xdisplay) {
|
|
return s48_enter_integer(XPending(SCX_EXTRACT_DISPLAY(Xdisplay)));
|
|
}
|
|
|
|
s48_value scx_Get_Motion_Events(s48_value Xdisplay, s48_value Xwindow,
|
|
s48_value from, s48_value to) {
|
|
int n,i;
|
|
XTimeCoord *p = XGetMotionEvents(SCX_EXTRACT_DISPLAY(Xdisplay),
|
|
SCX_EXTRACT_WINDOW(Xwindow),
|
|
SCX_EXTRACT_TIME(from),
|
|
SCX_EXTRACT_TIME(to),
|
|
&n);
|
|
s48_value v = s48_make_vector(n, S48_FALSE);
|
|
s48_value l = S48_NULL;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
S48_GC_PROTECT_2(v,l);
|
|
for (i = 0; i < n; i++) {
|
|
l = s48_cons(SCX_ENTER_TIME(p[i].time),
|
|
s48_cons(s48_enter_integer(p[i].x),
|
|
s48_cons(s48_enter_integer(p[i].y), S48_NULL)));
|
|
S48_VECTOR_SET(v, i, l);
|
|
}
|
|
S48_GC_UNPROTECT();
|
|
XFree((char*)p);
|
|
return v;
|
|
}
|
|
|
|
s48_value scx_add_pending_channel (channel){
|
|
int socket_fd;
|
|
S48_CHECK_CHANNEL(channel);
|
|
socket_fd = S48_UNSAFE_EXTRACT_FIXNUM(S48_UNSAFE_CHANNEL_OS_INDEX(channel));
|
|
|
|
if (! s48_add_pending_fd(socket_fd, 1)) // 1 for: yes, is input
|
|
s48_raise_out_of_memory_error();
|
|
|
|
return S48_UNSPECIFIC;
|
|
}
|
|
void scx_init_event(void) {
|
|
S48_EXPORT_FUNCTION(scx_Next_Event);
|
|
S48_EXPORT_FUNCTION(scx_Peek_Event);
|
|
S48_EXPORT_FUNCTION(scx_Events_Pending);
|
|
S48_EXPORT_FUNCTION(scx_Get_Motion_Events);
|
|
S48_EXPORT_FUNCTION(scx_add_pending_channel);
|
|
}
|
|
|