From 83cb7fd92587a66f780ee8950121727b4f6188fd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 20 Feb 2002 01:05:51 +0000 Subject: [PATCH] Date: Mon, 18 Feb 2002 16:46:59 +1200 From: Julian Kinraid Subject: Patches for photon port of SDL Hi, A couple more patches for photon and the nto audio. Adds mouse grabbing support, fixed cursor images, unicode keyboard events (though no unicode data on kye release, is that a problem?), hopefully fixing some audio lag problems, and a few other fixes. Thanks, Julian Kinraid --- src/audio/nto/SDL_nto_audio.c | 6 +- src/video/photon/SDL_ph_events.c | 130 ++++++++++++++----------------- src/video/photon/SDL_ph_image.c | 10 ++- src/video/photon/SDL_ph_mouse.c | 50 ++++++++---- src/video/photon/SDL_ph_video.c | 13 ++-- src/video/photon/SDL_ph_wm.c | 44 +++++++---- 6 files changed, 138 insertions(+), 115 deletions(-) diff --git a/src/audio/nto/SDL_nto_audio.c b/src/audio/nto/SDL_nto_audio.c index 8f5fdc5f8..68753f5f8 100644 --- a/src/audio/nto/SDL_nto_audio.c +++ b/src/audio/nto/SDL_nto_audio.c @@ -55,7 +55,7 @@ static int device_no = 0; #define DEFAULT_CPARAMS_VOICES 1 #define DEFAULT_CPARAMS_FRAG_SIZE 4096 //was 512 #define DEFAULT_CPARAMS_FRAGS_MIN 1 -#define DEFAULT_CPARAMS_FRAGS_MAX -1 +#define DEFAULT_CPARAMS_FRAGS_MAX 1 /* Open the audio device for playback, and don't block if busy */ #define OPEN_FLAGS SND_PCM_OPEN_PLAYBACK @@ -384,9 +384,9 @@ static int NTO_OpenAudio(_THIS, SDL_AudioSpec *spec) } /* enable count status parameter */ - if ((rval = snd_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP))<0) + if ((rval = snd_pcm_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP))<0) { - SDL_SetError("snd_plugin_set_disable failed: %s\n", snd_strerror(rval)); + SDL_SetError("snd_pcm_plugin_set_disable failed: %s\n", snd_strerror(rval)); return(-1); } diff --git a/src/video/photon/SDL_ph_events.c b/src/video/photon/SDL_ph_events.c index 4c9c8e55c..733a08201 100644 --- a/src/video/photon/SDL_ph_events.c +++ b/src/video/photon/SDL_ph_events.c @@ -55,7 +55,7 @@ SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym); (idea shamelessly lifted from GII -- thanks guys! :) */ -/* +#if 0 static int ph_KeyRepeat(_THIS, PhKeyEvent_t* keyevent) { // PhEvent_t* peekevent; @@ -89,78 +89,33 @@ static int ph_KeyRepeat(_THIS, PhKeyEvent_t* keyevent) } return(repeated); } +#endif -*/ - -/* Note: The X server buffers and accumulates mouse motion events, so - the motion event generated by the warp may not appear exactly as we - expect it to. We work around this (and improve performance) by only - warping the pointer when it reaches the edge, and then wait for it. -*/ -/* -#define MOUSE_FUDGE_FACTOR 8 - -static inline int X11_WarpedMotion(_THIS, XEvent *xevent) +static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent) { - int w, h, i; - int deltax, deltay; + PhPointerEvent_t *pointer = PhGetData( winEvent ); + PhRect_t *rect = PhGetRects( winEvent ); + + int centre_x, centre_y; + int dx, dy, abs_x, abs_y; int posted; - w = SDL_VideoSurface->w; - h = SDL_VideoSurface->h; - deltax = xevent->xmotion.x - mouse_last.x; - deltay = xevent->xmotion.y - mouse_last.y; -#ifdef DEBUG_MOTION - printf("Warped mouse motion: %d,%d\n", deltax, deltay); -#endif - mouse_last.x = xevent->xmotion.x; - mouse_last.y = xevent->xmotion.y; - posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay); - - if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) || - (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) || - (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) || - (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) { - // Get the events that have accumulated -/* while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) { - deltax = xevent->xmotion.x - mouse_last.x; - deltay = xevent->xmotion.y - mouse_last.y; -#ifdef DEBUG_MOTION - printf("Extra mouse motion: %d,%d\n", deltax, deltay); -#endif - mouse_last.x = xevent->xmotion.x; - mouse_last.y = xevent->xmotion.y; - posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay); - } - mouse_last.x = w/2; - mouse_last.y = h/2; - XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0, - mouse_last.x, mouse_last.y); - for ( i=0; i<10; ++i ) { - XMaskEvent(SDL_Display, PointerMotionMask, xevent); - if ( (xevent->xmotion.x > - (mouse_last.x-MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.x < - (mouse_last.x+MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.y > - (mouse_last.y-MOUSE_FUDGE_FACTOR)) && - (xevent->xmotion.y < - (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) { - break; - } -#ifdef DEBUG_XEVENTS - printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y); -#endif - } -#ifdef DEBUG_XEVENTS - if ( i == 10 ) { - printf("Warning: didn't detect mouse warp motion\n"); - } -#endif - } + 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 */ @@ -226,8 +181,13 @@ static int ph_DispatchEvent(_THIS) if ( SDL_VideoSurface ) { pointerEvent = PhGetData( event ); rect = PhGetRects( event ); - posted = SDL_PrivateMouseMotion(0, 0, - rect->ul.x, rect->ul.y); + if( mouse_relative ) + { + posted = ph_WarpedMotion(this, event); + } + else + posted = SDL_PrivateMouseMotion(0, 0, + rect->ul.x, rect->ul.y); } } break; @@ -291,10 +251,11 @@ static int ph_DispatchEvent(_THIS) { set_motion_sensitivity(this, -1); posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); - +#if 0 /* Queue entry into fullscreen mode */ switch_waiting = 0x01 | SDL_FULLSCREEN; switch_time = SDL_GetTicks() + 1500; +#endif } /* request to quit */ @@ -302,6 +263,13 @@ static int ph_DispatchEvent(_THIS) { posted = SDL_PrivateQuit(); } + else if (winEvent->event_f==Ph_WM_RESIZE) + { + PhDim_t *size; + + PtGetResource( window, Pt_ARG_DIM, &size, 0 ); + SDL_PrivateResize(size->w,size->h); + } } break; @@ -445,6 +413,7 @@ void ph_PumpEvents(_THIS) Uint32 now; now = SDL_GetTicks(); +#if 0 if ( pending || !SDL_VideoSurface ) { /* Try again later... */ if ( switch_waiting & SDL_FULLSCREEN ) { @@ -473,6 +442,7 @@ void ph_PumpEvents(_THIS) } */ } +#endif } } @@ -573,6 +543,7 @@ SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym) This member is valid only if Pk_KF_Sym_Valid is set in the key_flags. We will assume it is valid. */ + /* FIXME: This needs to check whether the cap & scancode is valid */ cap = key->key_cap; switch (cap>>8) { case 0x00: /* Latin 1 */ @@ -599,10 +570,27 @@ SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym) keysym->sym = MISC_keymap[cap&0xFF]; break; default: - fprintf(stderr,"Photon: Unknown key_cap, cap = 0x%.4x\n", (unsigned int)cap); +/* fprintf(stderr,"Photon: Unknown key_cap, cap = 0x%.4x\n", (unsigned int)cap); */ + keysym->sym = SDLK_UNKNOWN; break; } keysym->scancode = key->key_scan; + keysym->unicode = 0; + if( SDL_TranslateUNICODE ) + { + char utf8[MB_CUR_MAX]; + int utf8len; + wchar_t unicode; + + utf8len = PhKeyToMb( utf8, key ); + if( utf8len > 0 ) + { + utf8len = mbtowc( &unicode, utf8, utf8len ); + if( utf8len > 0) + keysym->unicode = unicode; + } + } + return (keysym); } diff --git a/src/video/photon/SDL_ph_image.c b/src/video/photon/SDL_ph_image.c index 9afd36115..636787183 100644 --- a/src/video/photon/SDL_ph_image.c +++ b/src/video/photon/SDL_ph_image.c @@ -175,8 +175,10 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) //Offscreen context void ph_DestroyImage(_THIS, SDL_Surface *screen) { +#if 0 if(SDL_Image == NULL) return; +#endif if (OCImage.offscreen_context != NULL) { @@ -188,21 +190,21 @@ void ph_DestroyImage(_THIS, SDL_Surface *screen) OCImage.FrameData1 = NULL; } - if (SDL_Image->image) + if (SDL_Image) { // SDL_Image->flags=Ph_RELEASE_IMAGE; // PhReleaseImage(SDL_Image); - PgShmemDestroy(SDL_Image->image); // Use this if you using shared memory, or uncomment + if (SDL_Image->image) + PgShmemDestroy(SDL_Image->image); // Use this if you using shared memory, or uncomment // lines above if not (and comment this line ;-) free(SDL_Image); + SDL_Image = NULL; } if ( screen ) { screen->pixels = NULL; } - - SDL_Image = NULL; } int ph_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) diff --git a/src/video/photon/SDL_ph_mouse.c b/src/video/photon/SDL_ph_mouse.c index 089d44143..ecb1c16eb 100644 --- a/src/video/photon/SDL_ph_mouse.c +++ b/src/video/photon/SDL_ph_mouse.c @@ -62,6 +62,7 @@ WMcursor *ph_CreateWMCursor(_THIS, { WMcursor* cursor; int clen, i; + unsigned char bit, databit, maskbit; /* Allocate and initialize the cursor memory */ if ((cursor = (WMcursor*)malloc(sizeof(WMcursor))) == NULL) @@ -70,13 +71,13 @@ WMcursor *ph_CreateWMCursor(_THIS, return(NULL); } memset(cursor,0,sizeof(WMcursor)); - + cursor->ph_cursor = (PhCursorDef_t *) malloc(sizeof(PhCursorDef_t) + 32*4*2); if(cursor->ph_cursor == NULL) printf("cursor malloc failed\n"); memset(cursor->ph_cursor,0,(sizeof(PhCursorDef_t) + 32*4*2)); - + cursor->ph_cursor->hdr.type =Ph_RDATA_CURSOR; cursor->ph_cursor->size1.x = (short)w; cursor->ph_cursor->size1.y = (short)h; @@ -90,18 +91,27 @@ WMcursor *ph_CreateWMCursor(_THIS, cursor->ph_cursor->offset2.y = (short)hot_y; cursor->ph_cursor->bytesperline2 = (char)w/8; cursor->ph_cursor->color2 = Pg_BLACK; - + clen = (w/8)*h; /* Copy the mask and the data to different bitmap planes */ for ( i=0; iph_cursor->images[i] = data[i]; - cursor->ph_cursor->images[i+clen] = mask[i]; - } - - //#bytes following the hdr struct + { + for ( bit = 0; bit < 8; bit++ ) + { + databit = data[i] & (1 << bit); + maskbit = mask[i] & (1 << bit); + + cursor->ph_cursor->images[i] |= + (databit == 0) ? maskbit : 0; + /* If the databit != 0, treat it as a black pixel and + * ignore the maskbit (can't do an inverted color) */ + cursor->ph_cursor->images[i+clen] |= databit; + } + } + + /* #bytes following the hdr struct */ cursor->ph_cursor->hdr.len =sizeof(PhCursorDef_t) + clen*2 - sizeof(PhRegionDataHdr_t); return (cursor); @@ -113,7 +123,6 @@ PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor) return(*cursor->ph_cursor); } - int ph_ShowWMCursor(_THIS, WMcursor *cursor) { PtArg_t args[3]; @@ -130,13 +139,13 @@ int ph_ShowWMCursor(_THIS, WMcursor *cursor) if ( cursor != NULL ) { PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0 ); - // Could set next to any PgColor_t value + /* Could set next to any PgColor_t value */ PtSetArg( &args[1], Pt_ARG_CURSOR_COLOR,Ph_CURSOR_DEFAULT_COLOR , 0 ); PtSetArg( &args[2], Pt_ARG_BITMAP_CURSOR, cursor->ph_cursor, (cursor->ph_cursor->hdr.len + sizeof(PhRegionDataHdr_t)) ); nargs = 3; cursor_is_defined = 1; } - else // Ph_CURSOR_NONE + else /* Ph_CURSOR_NONE */ { PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE,Ph_CURSOR_NONE, 0); nargs = 1; @@ -161,13 +170,22 @@ int ph_ShowWMCursor(_THIS, WMcursor *cursor) void ph_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { - SDL_Lock_EventThread(); - PhMoveCursorRel( PhInputGroup(NULL), x, y ); - SDL_Unlock_EventThread(); + short abs_x, abs_y; + + SDL_Lock_EventThread(); + PtGetAbsPosition( window, &abs_x, &abs_y ); + PhMoveCursorAbs( PhInputGroup(NULL), x + abs_x, y + abs_y ); + SDL_Unlock_EventThread(); } void ph_CheckMouseMode(_THIS) { - mouse_relative = 1; + /* If the mouse is hidden and input is grabbed, we use relative mode */ + if ( !(SDL_cursorstate & CURSOR_VISIBLE) && + (this->input_grab != SDL_GRAB_OFF) ) { + mouse_relative = 1; + } else { + mouse_relative = 0; + } } diff --git a/src/video/photon/SDL_ph_video.c b/src/video/photon/SDL_ph_video.c index af73276ce..fc454a11c 100644 --- a/src/video/photon/SDL_ph_video.c +++ b/src/video/photon/SDL_ph_video.c @@ -111,7 +111,7 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) device->SetCaption = ph_SetCaption; device->SetIcon = NULL; device->IconifyWindow = ph_IconifyWindow; - device->GrabInput = NULL; + device->GrabInput = ph_GrabInput; device->GetWMInfo = NULL; device->FreeWMCursor = ph_FreeWMCursor; device->CreateWMCursor = ph_CreateWMCursor; @@ -329,7 +329,7 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, /* Get the true height and width */ - current->flags = (flags|(~SDL_RESIZABLE)); /* no resize for Direct Context */ + current->flags = (flags & (~SDL_RESIZABLE)); /* no resize for Direct Context */ /* Begin direct mode */ ph_EnterFullScreen(this); @@ -342,11 +342,11 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, if (flags & SDL_HWSURFACE) /* Use offscreen memory iff SDL_HWSURFACE flag is set */ { /* Hardware surface is Offsceen Context. ph_ResizeImage handles the switch */ - current->flags = (flags|(~SDL_RESIZABLE)); /* no stretch blit in offscreen context */ + current->flags = (flags & (~SDL_RESIZABLE)); /* no stretch blit in offscreen context */ } else /* must be SDL_SWSURFACE */ { - current->flags = (flags|SDL_RESIZABLE); /* yes we can resize as this is a software surface */ + current->flags = (flags | SDL_RESIZABLE); /* yes we can resize as this is a software surface */ } #ifdef HAVE_OPENGL @@ -415,10 +415,7 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, static void ph_VideoQuit(_THIS) { - if (SDL_Image != NULL) - { - ph_DestroyImage(this, SDL_VideoSurface); - } + ph_DestroyImage(this, SDL_VideoSurface); if (currently_fullscreen) { diff --git a/src/video/photon/SDL_ph_wm.c b/src/video/photon/SDL_ph_wm.c index 48ce063eb..08e7171a5 100644 --- a/src/video/photon/SDL_ph_wm.c +++ b/src/video/photon/SDL_ph_wm.c @@ -233,19 +233,15 @@ void ph_SetCaption(_THIS, const char *title, const char *icon) /* Iconify current window */ int ph_IconifyWindow(_THIS) { - WmApiContext_t context=WmCreateContext(); - WmWindowDefinition_t **wininfo=malloc(sizeof(WmWindowDefinition_t)*2); - int num; + PhWindowEvent_t windowevent; - SDL_Lock_EventThread(); - WmGetFocusList(context,2,&num,wininfo); - WmPerformFrameAction(context, wininfo[0]->rid,Pt_ACTION_MIN); - - WmDestroyContext (context); - SDL_Unlock_EventThread(); - free(wininfo); - - return (0); + SDL_Lock_EventThread(); + memset( &windowevent, 0, sizeof (event) ); + windowevent.event_f = Ph_WM_HIDE; + windowevent.event_state = Ph_WM_EVSTATE_HIDE; + windowevent.rid = PtWidgetRid( window ); + PtForwardWindowEvent( &windowevent ); + SDL_Unlock_EventThread(); } SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode) @@ -255,7 +251,29 @@ SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode) SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode) { - return(mode); + short abs_x, abs_y; + + SDL_Lock_EventThread(); +/* mode = ph_GrabInputNoLock(this, mode);*/ + + if( mode == SDL_GRAB_OFF ) + { + PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_FALSE, + Ph_WM_STATE_ISALTKEY ); + } + else + { + PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_TRUE, + Ph_WM_STATE_ISALTKEY ); + + PtGetAbsPosition( window, &abs_x, &abs_y ); + PhMoveCursorAbs( PhInputGroup( NULL ), + abs_x + SDL_VideoSurface->w/2, + abs_y + SDL_VideoSurface->h/2 ); + } + + SDL_Unlock_EventThread(); + return(mode); } int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)