mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-03 20:27:58 +03:00
260 lines
6.1 KiB
C
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;
|
|
}
|