📄 sdl_ph_events.c
字号:
/* SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id$";#endif/* Handle the event stream, converting photon events into SDL events */#define DISABLE_X11#include <Ph.h>#include <stdio.h>#include <setjmp.h>#include <photon/PkKeyDef.h>#include <sys/time.h>#include "SDL.h"#include "SDL_syswm.h"#include "SDL_sysevents.h"#include "SDL_sysvideo.h"#include "SDL_events_c.h"#include "SDL_ph_video.h"#include "SDL_ph_modes_c.h"#include "SDL_ph_image_c.h"#include "SDL_ph_events_c.h"/* The translation tables from a photon keysym to a SDL keysym */static SDLKey ODD_keymap[256];static SDLKey MISC_keymap[0xFF + 1];SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym);/* Check to see if this is a repeated key. (idea shamelessly lifted from GII -- thanks guys! :) */#if 0static int ph_KeyRepeat(_THIS, PhKeyEvent_t* keyevent){// PhEvent_t* peekevent; PhKeyEvent_t* keyEvent; int repeated; repeated = 0; switch (PhEventPeek( peekevent, EVENT_SIZE )) { case Ph_EVENT_MSG: { if(peekevent->type == Ph_EV_KEY) { keyEvent = PhGetData( peekevent ); if ( !(Pk_KF_Key_Down & keyEvent->key_flags) && (keyEvent->key_cap == keyevent->key_cap) && (peekevent->timestamp == event->timestamp) ) { repeated = 1; /* PhEventNext( peekevent, EVENT_SIZE ); */ } } } break; case -1: { perror( "PhEventPeek failed" ); } break; default: /* no events pending */ } return(repeated);}#endifstatic int ph_WarpedMotion(_THIS, PhEvent_t *winEvent){/* PhPointerEvent_t *pointer = PhGetData( winEvent ); */ PhRect_t *rect = PhGetRects( winEvent ); int centre_x, centre_y; int dx, dy; short abs_x, abs_y; int posted; centre_x = SDL_VideoSurface->w / 2; centre_y = SDL_VideoSurface->h / 2; dx = rect->ul.x - centre_x; dy = rect->ul.y - centre_y; posted = SDL_PrivateMouseMotion( 0, 1, dx, dy ); /* Move mouse cursor to middle of the window */ PtGetAbsPosition( window, &abs_x, &abs_y ); PhMoveCursorAbs( PhInputGroup(NULL), abs_x + centre_x, abs_y + centre_y ); return(posted);}/* Control which motion flags the window has set, a flags value of -1 sets * MOTION_BUTTON and MOTION_NOBUTTON */static void set_motion_sensitivity(_THIS, unsigned int flags){ int rid, fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON; PhRegion_t region; if( window ) { rid = PtWidgetRid( window ); if( rid != 0 && PhRegionQuery( rid, ®ion, NULL, NULL, 0 ) == 0 ) { region.events_sense = ( region.events_sense & ~fields ) | ( flags & fields ); PhRegionChange( Ph_REGION_EV_SENSE, 0, ®ion, NULL, NULL ); } }}/* Convert the photon button state value to an SDL value */static Uint8 ph2sdl_mousebutton( unsigned short button_state ){ Uint8 mouse_button = 0; if( button_state & Ph_BUTTON_SELECT ) mouse_button |= SDL_BUTTON_LEFT; if( button_state & Ph_BUTTON_MENU ) mouse_button |= SDL_BUTTON_RIGHT; if( button_state & Ph_BUTTON_ADJUST ) mouse_button |= SDL_BUTTON_MIDDLE; return( mouse_button );}static int ph_DispatchEvent(_THIS){ int posted; PhRect_t* rect; PhPointerEvent_t* pointerEvent; PhKeyEvent_t* keyEvent; PhWindowEvent_t* winEvent; int i, buttons; SDL_Rect sdlrects[50]; posted = 0; switch (event->type) { case Ph_EV_BOUNDARY: { if (event->subtype == Ph_EV_PTR_ENTER) { posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); } else if (event->subtype ==Ph_EV_PTR_LEAVE) { posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); } } break; case Ph_EV_PTR_MOTION_BUTTON: case Ph_EV_PTR_MOTION_NOBUTTON: { if (SDL_VideoSurface) { pointerEvent = PhGetData(event); rect = PhGetRects(event); if (mouse_relative) { posted = ph_WarpedMotion(this, event); } else { posted = SDL_PrivateMouseMotion(0, 0, rect->ul.x, rect->ul.y); } } } break; case Ph_EV_BUT_PRESS: { pointerEvent = PhGetData( event ); buttons = ph2sdl_mousebutton( pointerEvent->buttons ); if (buttons != 0) { posted = SDL_PrivateMouseButton(SDL_PRESSED, buttons, 0, 0); } } break; case Ph_EV_BUT_RELEASE: { pointerEvent = PhGetData(event); buttons = ph2sdl_mousebutton(pointerEvent->buttons); if (event->subtype == Ph_EV_RELEASE_REAL && buttons != 0) { posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0); } else if(event->subtype == Ph_EV_RELEASE_PHANTOM) { /* If the mouse is outside the window, * only a phantom release event is sent, so * check if the window doesn't have mouse focus. * Not perfect, maybe checking the mouse button * state for Ph_EV_BOUNDARY events would be * better. */ if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) == 0) { posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0); } } } break; case Ph_EV_WM: { winEvent = PhGetData(event); /* losing focus */ if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUSLOST)) { set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON); posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); /* Queue leaving fullscreen mode */ switch_waiting = 0x01; switch_time = SDL_GetTicks() + 200; } /* gaining focus */ else if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUS)) { set_motion_sensitivity(this, -1); posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); } /* request to quit */ else if (winEvent->event_f==Ph_WM_CLOSE) { posted = SDL_PrivateQuit(); } /* request to resize */ else if (winEvent->event_f==Ph_WM_RESIZE) { SDL_PrivateResize(winEvent->size.w, winEvent->size.h); } /* request to maximize */ else if (winEvent->event_f==Ph_WM_MAX) { /* TODO: get screen resolution, set window pos to 0, 0 and resize it ! */ } } break; /* window has been resized, moved or removed */ case Ph_EV_EXPOSE: { if (SDL_VideoSurface) { rect = PhGetRects(event); for(i=0;i<event->num_rects;i++) { sdlrects[i].x = rect[i].ul.x; sdlrects[i].y = rect[i].ul.y; sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1; sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1; } this->UpdateRects(this, event->num_rects, sdlrects); } } break; case Ph_EV_KEY:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -