Files
kichikuou_xsystem35-sdl2/src/xcore_event.c
T
2017-02-11 19:03:05 +09:00

260 lines
6.1 KiB
C

/*
* xcore_event.c X11 event handler
*
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
* 1998- <masaki-c@is.aist-nara.ac.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* $Id: xcore_event.c,v 1.12 2004/10/31 04:18:06 chikama Exp $ */
#include "config.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "portab.h"
#include "system.h"
#include "xcore.h"
#include "xcore_private.h"
#include "nact.h"
#include "counter.h"
#include "imput.h"
#include "menu.h"
#include "joystick.h"
#include "xcore_input.c"
static boolean xcore_getEvent(void);
static int check_button(void);
/* pointer の状態 */
static int mousex, mousey;
static boolean xcore_getEvent(void) {
XEvent e;
Window root, child;
int rx, ry, wx, wy;
int mask;
boolean getkey = FALSE, msg_skip = FALSE;
while(XPending(x11_display)) {
XNextEvent(x11_display, &e);
switch(e.type) {
case LeaveNotify:
mousex = -1; mousey = -1; // mouseb = 0;
memset(RawKeyInfo, 0, sizeof(RawKeyInfo));
getkey = TRUE;
if (x11_fs_on) {
XUngrabPointer(x11_display, CurrentTime);
XSync(x11_display, False);
}
break;
case EnterNotify:
if (x11_fs_on) {
XGrabPointer(x11_display, x11_window, True, 0,
GrabModeAsync, GrabModeAsync,
x11_window, None, CurrentTime);
XSync(x11_display, False);
}
break;
case MotionNotify:
if (!XQueryPointer(x11_display, x11_window, &root, &child, &rx, &ry, &wx, &wy, &mask))
break;
mousex = wx; mousey = wy;
if (nact->ags.eventcb) {
agsevent_t agse;
agse.type = AGSEVENT_MOUSE_MOTION;
agse.d1 = wx; agse.d2 = wy; agse.d3 = 0;
nact->ags.eventcb(&agse);
}
break;
#if 0
case ButtonPress:
mouseb |= (1 << e.xbutton.button);
getkey = TRUE;
break;
case ButtonRelease:
mouseb &= (0xffffffff ^ (1 << e.xbutton.button));
getkey = TRUE;
break;
#endif
case ButtonPress:
case ButtonRelease:
buttonEventProcess((XButtonEvent *)&e);
getkey = TRUE;
break;
case Expose: {
MyRectangle src;
MyPoint dst;
XExposeEvent *ev = (XExposeEvent *)&e;
if (ev->count == 0) {
src.x = view_x + ev->x - winoffset_x;
src.y = view_y + ev->y - winoffset_y;
src.width = min(DIB->width, ev->width);
src.height = min(DIB->height, ev->height);
dst.x = ev->x - winoffset_x;
dst.y = ev->y - winoffset_y;
if (src.x > view_w || src.x < 0) break;
if (src.y > view_h || src.y < 0) break;
Xcore_updateArea(&src, &dst);
}
break;
}
case KeyPress:
keyEventProsess((XKeyEvent *)&e);
getkey = TRUE;
break;
case KeyRelease: {
KeySym sym;
keyEventProsess((XKeyEvent *)&e);
sym = XKeycodeToKeysym(x11_display, e.xkey.keycode, 0);
if (sym == XK_F4) {
Xcore_fullScreen(!x11_fs_on);
} else if (sym == XK_F1) {
msg_skip = TRUE;
}
getkey = TRUE;
break;
}
case ClientMessage:
if (e.xclient.message_type == atom_wmprot &&
e.xclient.data.l[0] == atom_delwin) {
menu_quitmenu_open();
}
break;
}
}
if (msg_skip) set_skipMode(!get_skipMode());
return getkey;
}
int Xcore_keywait(int msec, boolean cancel) {
boolean bool = FALSE;
int key = 0, retval, rest = msec;
int cnt = get_high_counter(SYSTEMCOUNTER_MSEC);
if (msec < 0) return 0;
#if 1
while (msec > (get_high_counter(SYSTEMCOUNTER_MSEC) - cnt)) {
bool = xcore_getEvent();
//key = check_button() | Xcore_getKeyInfo() | joy_getinfo();
key |= check_button() | Xcore_getKeyInfo() | joy_getinfo();
if( cancel && key ) break;
rest = msec - (get_high_counter(SYSTEMCOUNTER_MSEC) - cnt);
if (rest < 0) break;
if (rest < 10) {
usleep(1000 * rest);
} else {
usleep(10000);
}
nact->callback();
}
#endif
#if 0
while (rest > 0) {
struct timeval tv;
fd_set fdset;
int x11_fd = ConnectionNumber(x11_display);
FD_ZERO(&fdset);
FD_SET(x11_fd, &fdset);
cnt = get_high_counter(SYSTEMCOUNTER_MSEC);
tv.tv_sec = 0;
if (rest < 100) {
tv.tv_usec = rest * 1000;
} else {
tv.tv_usec = 100 * 1000;
}
retval = select(x11_fd + 1, &fdset, NULL, NULL, &tv);
if (retval > 0) {
if (FD_ISSET(x11_fd, &fdset)) {
bool = xcore_getEvent();
}
} else if (retval < 0) {
perror("select");
}
if (bool) {
key |= (check_button() | Xcore_getKeyInfo());
if (cancel) break;
}
rest -= (get_high_counter(SYSTEMCOUNTER_MSEC) - cnt);
nact->callback();
}
#endif
return key;
}
/* キー情報の取得 */
int Xcore_getKeyInfo() {
xcore_getEvent();
return ((RawKeyInfo[KEY_UP] || RawKeyInfo[KEY_PAD_8]) |
((RawKeyInfo[KEY_DOWN] || RawKeyInfo[KEY_PAD_2]) << 1) |
((RawKeyInfo[KEY_LEFT] || RawKeyInfo[KEY_PAD_4]) << 2) |
((RawKeyInfo[KEY_RIGHT] || RawKeyInfo[KEY_PAD_6]) << 3) |
(RawKeyInfo[KEY_ENTER] << 4) |
(RawKeyInfo[KEY_SPACE] << 5) |
(RawKeyInfo[KEY_ESC] << 6) |
(RawKeyInfo[KEY_TAB] << 7));
}
/* mouse 情報の取得 */
int Xcore_getMouseInfo(MyPoint *p) {
xcore_getEvent();
if (mousex < 0) {
if (p) {
p->x=0; p->y=0;
}
return 0;
}
if (p) {
p->x = mousex - winoffset_x;
p->y = mousey - winoffset_y;
}
return check_button();
}
/* mouse のボタン状態の取得 */
static int check_button(void) {
int m1, m2;
if (RawKeyInfo[KEY_MOUSE_MIDDLE]) {
menu_open();
} else {
m1 = RawKeyInfo[KEY_MOUSE_LEFT] ? SYS35KEY_RET : 0;
m2 = RawKeyInfo[KEY_MOUSE_RIGHT] ? SYS35KEY_SPC : 0;
return m1|m2;
}
return 0;
}