/* ScummVM - Scumm Interpreter * Copyright (C) 2001 Ludvig Strigeus * Copyright (C) 2001-2004 The ScummVM project * * 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. * * $Header$ * */ #include "stdafx.h" #include "palm.h" #include "common/scaler.h" #include #ifndef DISABLE_TAPWAVE // Tapwave code will come here #endif #define EXITDELAY (500) // delay to exit : calc button : double tap 1/500 sec void OSystem_PALMOS::SimulateArrowKeys(Event *event, Int8 iHoriz, Int8 iVert, Boolean repeat) { Int16 x = _mouseCurState.x; Int16 y = _mouseCurState.y; if (_lastKeyPressed != kLastKeyNone || repeat) { _lastKeyRepeat += 2; if (_lastKeyRepeat > 32) _lastKeyRepeat = 32; } else _lastKeyRepeat = 0; x = x + iHoriz * (_lastKeyRepeat >> 1); y = y + iVert * (_lastKeyRepeat >> 1); x = (x < 0 ) ? 0 : x; x = (x >= _screenWidth ) ? _screenWidth - 1 : x; y = (y < 0 ) ? 0 : y; y = (y >= _screenHeight ) ? _screenHeight - 1 : y; event->event_code = EVENT_MOUSEMOVE; event->mouse.x = x; event->mouse.y = y; set_mouse_pos(x, y); } void OSystem_PALMOS::getCoordinates(EventPtr event, Coord *x, Coord *y) { if (OPTIONS_TST(kOptModeHiDensity)) { Boolean dummy; EvtGetPenNative(WinGetDisplayWindow(), &event->screenX, &event->screenY, &dummy); } else { event->screenX <<= 1; event->screenY <<= 1; } if (_mode == GFX_WIDE) { // wide landscape if (OPTIONS_TST(kOptModeLandscape)) { // zodiac have mutliple ratio if (OPTIONS_TST(kOptDeviceZodiac)) { Int32 w,h; h = (_adjustAspectRatio ? ((_screenHeight == 200) ? 300 : 360) : 320); w = gVars->screenFullWidth; *x = ((event->screenX - _screenOffset.x) << 8) / ((w << 8) / _screenWidth); *y = ((event->screenY - _screenOffset.y) << 8) / ((h << 8) / _screenHeight); // default (NR, NZ, NX, UX50, TT3, ...), wide only for 320x200 } else { *x = ((event->screenX - _screenOffset.x) << 1) / 3; *y = ((event->screenY - _screenOffset.y) << 1) / 3; } // wide portrait, only for 320x200 } else { *y = ((event->screenX - _screenOffset.y) << 1) / 3; *x = 320 - ((event->screenY - _screenOffset.x) << 1) / 3 - 1; } // normal coord } else { *x = (event->screenX - _screenOffset.x); *y = (event->screenY - _screenOffset.y); } } bool OSystem_PALMOS::poll_event(Event *event) { EventType ev; Boolean handled; UInt32 keyCurrentState; Coord x, y; if(_quitCount) { if (_quitCount >= 10) SysReset(); else _quitCount++; event->event_code = EVENT_QUIT; exit(0); // resend an exit event return false; } // battery status battery_handler(); // sound handler sound_handler(); // timer handler timer_handler(get_msecs()); if (_selfQuit) quit(); for(;;) { EvtGetEvent(&ev, evtNoWait); // check for hardkey repeat for mouse emulation (no 5way only) keyCurrentState = KeyCurrentState(); if (_lastKeyPressed != kLastKeyNone && _lastKeyPressed != kLastKeyCalc && !( (keyCurrentState & keyBitHard2) || // left (keyCurrentState & keyBitPageUp) || // up (keyCurrentState & keyBitPageDown) || // down (keyCurrentState & keyBitHard3) // right ) ) { _lastKeyPressed = kLastKeyNone; } if (ev.eType == nilEvent) return false; if (ev.eType == keyDownEvent) { switch (ev.data.keyDown.chr) { // ESC key case vchrLaunch: _lastKeyPressed = kLastKeyNone; event->event_code = EVENT_KEYDOWN; event->kbd.keycode = 27; event->kbd.ascii = 27; event->kbd.flags = 0; return true; // F5 = menu case vchrJogPushRepeat: case vchrMenu: _lastKeyPressed = kLastKeyNone; event->event_code = EVENT_KEYDOWN; event->kbd.keycode = 319; event->kbd.ascii = 319; event->kbd.flags = 0; return true; case vchrCalc: if (_lastKeyPressed & kLastKeyCalc) if ((get_msecs() - _exit_delay) <= (EXITDELAY)) { event->event_code = EVENT_QUIT; _selfQuit = true; } _exit_delay = get_msecs(); _lastKeyPressed = kLastKeyCalc; return true; // mouse button case vchrJogBack: case vchrHard4: // right button event->event_code = EVENT_RBUTTONDOWN; event->mouse.x = _mouseCurState.x; event->mouse.y = _mouseCurState.y; _lastKeyPressed = kLastKeyNone; return true; case vchrJogPushedUp: case vchrJogPushedDown: // hot swap gfx mode if (_initMode == GFX_WIDE) hotswap_gfx_mode(_mode == GFX_WIDE ? GFX_NORMAL: GFX_WIDE); else setFeatureState(kFeatureFullscreenMode, !_fullscreen); return true; // wheel case vchrJogUp: event->event_code = EVENT_WHEELUP; return true; case vchrJogDown: event->event_code = EVENT_WHEELDOWN; return true; // if hotsync pressed case vchrHardCradle: case vchrHardCradle2: _selfQuit = true; break; case vchrLowBattery: case vchrFind: case vchrBrightness: case vchrContrast: // do nothing return true; // trun off case vchrAutoOff: case vchrPowerOff: // pause the sound thread if any if (OPTIONS_TST(kOptPalmSoundAPI) && _sound.active) SndStreamPause(*((SndStreamRef *)_sound.handle), true); break; case vchrLateWakeup: // resume the sound thread if any if (OPTIONS_TST(kOptPalmSoundAPI) && _sound.active) SndStreamPause(*((SndStreamRef *)_sound.handle), false); break; } if (OPTIONS_TST(kOpt5WayNavigator)) { // mouse emulation for device with 5-Way navigator switch (ev.data.keyDown.chr) { // hot swap gfx case vchrHard1: if (_initMode == GFX_WIDE) hotswap_gfx_mode(_mode == GFX_WIDE ? GFX_NORMAL: GFX_WIDE); else setFeatureState(kFeatureFullscreenMode, !_fullscreen); return true; // ESC key case vchrHard2: _lastKeyPressed = kLastKeyNone; event->event_code = EVENT_KEYDOWN; event->kbd.keycode = 27; event->kbd.ascii = 27; event->kbd.flags = 0; return true; // F5 = menu case vchrHard3: _lastKeyPressed = kLastKeyNone; event->event_code = EVENT_KEYDOWN; event->kbd.keycode = 319; event->kbd.ascii = 319; event->kbd.flags = 0; return true; case vchrPageUp: case vchrPageDown: case vchrNavChange: // left mouse button if (ev.data.keyDown.keyCode & (navBitSelect|navChangeSelect)) { event->event_code = EVENT_LBUTTONDOWN; event->mouse.x = _mouseCurState.x; event->mouse.y = _mouseCurState.y; _lastKeyPressed = kLastKeyNone; return true; // mouse move } else { Boolean kUp = (ev.data.keyDown.keyCode & navBitUp); Boolean kDown = (ev.data.keyDown.keyCode & navBitDown); Boolean kLeft = (ev.data.keyDown.keyCode & navBitLeft); Boolean kRight = (ev.data.keyDown.keyCode & navBitRight); Boolean kRepeat = (ev.data.keyDown.modifiers & autoRepeatKeyMask); Boolean process = (kUp || kDown || kLeft || kRight); if (process) { Int8 stepX = 0; Int8 stepY = 0; if (kLeft) stepX = -1; else if (kRight) stepX = +1; if (kUp) stepY = -1; else if (kDown) stepY = +1; SimulateArrowKeys(event, stepX, stepY, kRepeat); _lastKeyPressed = kLastKeyNone; // use only repeat flag return true; } } break; } } else { // mouse emulation for device without 5-Way navigator switch (ev.data.keyDown.chr) { case vchrHard1: // left button event->event_code = EVENT_LBUTTONDOWN; event->mouse.x = _mouseCurState.x; event->mouse.y = _mouseCurState.y; _lastKeyPressed = kLastKeyNone; return true; case vchrHard2: // move left SimulateArrowKeys(event, -1, 0); _lastKeyPressed = kLastKeyMouseLeft; return true; case vchrPageUp: // move up SimulateArrowKeys(event, 0, -1); _lastKeyPressed = kLastKeyMouseUp; return true; case vchrPageDown: // move down SimulateArrowKeys(event, 0, 1); _lastKeyPressed = kLastKeyMouseDown; return true; case vchrHard3: // move right SimulateArrowKeys(event, 1, 0); _lastKeyPressed = kLastKeyMouseRight; return true; } } } // prevent crash when alarm is raised handled = ((ev.eType == keyDownEvent) && (ev.data.keyDown.modifiers & commandKeyMask) && ((ev.data.keyDown.chr == vchrAttnStateChanged) || (ev.data.keyDown.chr == vchrAttnUnsnooze))); // graffiti strokes, auto-off, etc... if (!handled) if (SysHandleEvent(&ev)) continue; // others events switch(ev.eType) { case keyDownEvent: { _lastEvent = keyDownEvent; _lastKeyPressed = kLastKeyNone; if (ev.data.keyDown.chr == vchrCommand && (ev.data.keyDown.modifiers & commandKeyMask)) { _lastKeyModifier++; _lastKeyModifier %= 4; if (_lastKeyModifier) draw1BitGfx((kDrawKeyState + _lastKeyModifier - 1), 2, _screenHeight + 2, true); else draw1BitGfx(kDrawKeyState, 2, _screenHeight + 2, false); } else { int keycode; byte b = 0; if (_lastKeyModifier == MD_CMD) b = KBD_CTRL|KBD_ALT; if (_lastKeyModifier == MD_ALT) b = KBD_ALT; if (_lastKeyModifier == MD_CTRL) b = KBD_CTRL; keycode = ev.data.keyDown.chr; // F1 -> F10 key if (keycode >= '0' && keycode <= '9' && b == (KBD_CTRL|KBD_ALT)) { keycode = keycode == '0' ? 324 : (315 + keycode - '1'); b = 0; } else if ((keycode == 'z' && b == KBD_CTRL) || (b == KBD_ALT && keycode == 'x')) { event->event_code = EVENT_QUIT; _selfQuit = true; return true; } else if (keycode == 'n' && b == KBD_CTRL) { UInt8 *scr = _screenP + _screenWidth * (_screenHeight + 2); _useNumPad = !_useNumPad; draw1BitGfx(kDrawNumPad, (_screenWidth >> 1) - 32, _screenHeight + 2, _useNumPad); return true; #ifndef DISABLE_TAPWAVE // Tapwave code will come here #endif } event->event_code = EVENT_KEYDOWN; event->kbd.keycode = keycode; event->kbd.ascii = keycode; //(keycode>='a' && keycode<='z' && (event->kbd.flags & KBD_SHIFT) ? keycode &~ 0x20 : keycode); event->kbd.flags = b; if (_lastKeyModifier) { _lastKeyModifier = MD_NONE; draw1BitGfx(kDrawKeyState, 2, getHeight() + 2, false); } } return true; } case penMoveEvent: getCoordinates(&ev, &x, &y); if (y > _screenHeight || y < 0 || x > _screenWidth || x < 0) return true; if (_lastEvent != penMoveEvent && (abs(y - event->mouse.y) <= 2 || abs(x - event->mouse.x) <= 2)) // move only if return true; _lastEvent = penMoveEvent; event->event_code = EVENT_MOUSEMOVE; event->mouse.x = x; event->mouse.y = y; set_mouse_pos(event->mouse.x, event->mouse.y); return true; case penDownEvent: getCoordinates(&ev, &x, &y); if (_useNumPad) { Coord x2 = (_screenWidth >> 1) - 20; // - 64 / 2 + 12 Coord y2 = _screenHeight + 2; if (y >= y2 && y < (y2 + 34) && x >= x2 && x < (x2 + 40)) { // numpad location UInt8 key = '1'; key += 9 - ( (3 - ((x - x2) / 13)) + (3 * ((y - y2) / 11)) ); _lastEvent = keyDownEvent; _lastKeyPressed = kLastKeyNone; event->event_code = EVENT_KEYDOWN; event->kbd.keycode = key; event->kbd.ascii = key; event->kbd.flags = 0; return true; } } _lastEvent = penDownEvent; if (y > _screenHeight || y < 0 || x > _screenWidth || x < 0) return true; event->event_code = EVENT_LBUTTONDOWN; event->mouse.x = x; event->mouse.y = y; set_mouse_pos(event->mouse.x, event->mouse.y); return true; case penUpEvent: getCoordinates(&ev, &x, &y); event->event_code = EVENT_LBUTTONUP; if (y > _screenHeight || y < 0 || x > _screenWidth || x < 0) return true; event->mouse.x = x; event->mouse.y = y; set_mouse_pos(event->mouse.x, event->mouse.y); return true; default: return false; } } }