146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/*
246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    SDL - Simple DirectMedia Layer
346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Copyright (C) 1997-2006 Sam Lantinga
446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    This library is free software; you can redistribute it and/or
646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    modify it under the terms of the GNU Lesser General Public
746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    License as published by the Free Software Foundation; either
846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    version 2.1 of the License, or (at your option) any later version.
946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    This library is distributed in the hope that it will be useful,
1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    but WITHOUT ANY WARRANTY; without even the implied warranty of
1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Lesser General Public License for more details.
1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    You should have received a copy of the GNU Lesser General Public
1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    License along with this library; if not, write to the Free Software
1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    Sam Lantinga
2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner    slouken@libsdl.org
2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/
2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h"
2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Handle the event stream, converting DGA events into SDL events */
2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <stdio.h>
2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <X11/Xlib.h>
2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../Xext/extensions/xf86dga.h"
2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_sysvideo.h"
3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../../events/SDL_events_c.h"
3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_dgavideo.h"
3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_dgaevents_c.h"
3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* get function pointers... */
3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../x11/SDL_x11dyn.h"
3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Heheh we're using X11 event code */
3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerextern int X11_Pending(Display *display);
4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerextern void X11_InitKeymap(void);
4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerextern SDLKey X11_TranslateKeycode(Display *display, KeyCode kc);
4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int DGA_DispatchEvent(_THIS)
4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	int posted;
4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	SDL_NAME(XDGAEvent) xevent;
4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	XNextEvent(DGA_Display, (XEvent *)&xevent);
4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	posted = 0;
5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	xevent.type -= DGA_event_base;
5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	switch (xevent.type) {
5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    /* Mouse motion? */
5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    case MotionNotify: {
5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if ( SDL_VideoSurface ) {
5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			posted = SDL_PrivateMouseMotion(0, 1,
5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					xevent.xmotion.dx, xevent.xmotion.dy);
5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    }
6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    break;
6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    /* Mouse button press? */
6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    case ButtonPress: {
6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		posted = SDL_PrivateMouseButton(SDL_PRESSED,
6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					xevent.xbutton.button, 0, 0);
6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    }
6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    break;
6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    /* Mouse button release? */
7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    case ButtonRelease: {
7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		posted = SDL_PrivateMouseButton(SDL_RELEASED,
7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner					xevent.xbutton.button, 0, 0);
7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    }
7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    break;
7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    /* Key press? */
7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    case KeyPress: {
7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		SDL_keysym keysym;
8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		KeyCode keycode;
8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		XKeyEvent xkey;
8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		SDL_NAME(XDGAKeyEventToXKeyEvent)(&xevent.xkey, &xkey);
8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keycode = xkey.keycode;
8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_XEVENTS
8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerprintf("KeyPress (X11 keycode = 0x%X)\n", xkey.keycode);
8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif
8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		/* Get the translated SDL virtual keysym */
8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.scancode = keycode;
9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.sym = X11_TranslateKeycode(DGA_Display, keycode);
9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.mod = KMOD_NONE;
9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.unicode = 0;
9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		/* Look up the translated value for the key event */
9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		if ( SDL_TranslateUNICODE ) {
9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			static XComposeStatus state;
9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			char keybuf[32];
9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			if ( XLookupString(&xkey, keybuf, sizeof(keybuf), NULL, &state) ) {
10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				/*
10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				* FIXME: XLookupString() may yield more than one
10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				* character, so we need a mechanism to allow for
10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				* this (perhaps null keypress events with a
10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				* unicode value)
10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				*/
10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner				keysym.unicode = (Uint8)keybuf[0];
10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner			}
10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		}
10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    }
11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    break;
11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    /* Key release? */
11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    case KeyRelease: {
11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		SDL_keysym keysym;
11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		KeyCode keycode;
11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		XKeyEvent xkey;
11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		SDL_NAME(XDGAKeyEventToXKeyEvent)(&xevent.xkey, &xkey);
12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keycode = xkey.keycode;
12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef DEBUG_XEVENTS
12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerprintf("KeyRelease (X11 keycode = 0x%X)\n", xkey.keycode);
12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif
12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		/* Get the translated SDL virtual keysym */
12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.scancode = keycode;
12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.sym = X11_TranslateKeycode(DGA_Display, keycode);
12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.mod = KMOD_NONE;
12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		keysym.unicode = 0;
12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym);
13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    }
13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	    break;
13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	return(posted);
13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid DGA_PumpEvents(_THIS)
13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	/* Keep processing pending events */
13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	LOCK_DISPLAY();
14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	while ( X11_Pending(DGA_Display) ) {
14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner		DGA_DispatchEvent(this);
14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	}
14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	UNLOCK_DISPLAY();
14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid DGA_InitOSKeymap(_THIS)
14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{
14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner	X11_InitKeymap();
14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner}
15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner
151