diff options
author | Jesse Hall <jessehall@google.com> | 2012-07-23 10:13:06 -0700 |
---|---|---|
committer | android code review <noreply-gerritcodereview@google.com> | 2012-07-23 10:13:06 -0700 |
commit | d95f84da47d4e5c1f9bce2770400fd0d61b0c0b6 (patch) | |
tree | b39ee901bb528b7e3593117cde724ef75d438b67 /distrib/sdl-1.2.15/src | |
parent | 2b3a42e7d0b441f71fc2e2b07269dd1f8151c977 (diff) | |
parent | e4c5d95ed37611acc6a186522315195b4ebfb9ef (diff) | |
download | external_qemu-d95f84da47d4e5c1f9bce2770400fd0d61b0c0b6.zip external_qemu-d95f84da47d4e5c1f9bce2770400fd0d61b0c0b6.tar.gz external_qemu-d95f84da47d4e5c1f9bce2770400fd0d61b0c0b6.tar.bz2 |
Merge "Apply Android changes from sdl-1.2.12 to sdl-1.2.15"
Diffstat (limited to 'distrib/sdl-1.2.15/src')
18 files changed, 686 insertions, 39 deletions
diff --git a/distrib/sdl-1.2.15/src/audio/macosx/SDL_coreaudio.h b/distrib/sdl-1.2.15/src/audio/macosx/SDL_coreaudio.h index c11bc03..3f0e218 100644 --- a/distrib/sdl-1.2.15/src/audio/macosx/SDL_coreaudio.h +++ b/distrib/sdl-1.2.15/src/audio/macosx/SDL_coreaudio.h @@ -25,6 +25,7 @@ #define _SDL_coreaudio_h #include "../SDL_sysaudio.h" +#include <AudioUnit/AUNTComponent.h> /* Hidden "this" pointer for the video functions */ #define _THIS SDL_AudioDevice *this diff --git a/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.c b/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.c index 51a9a4d..b218ff9 100644 --- a/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.c +++ b/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.c @@ -45,6 +45,10 @@ static void DIB_PlayAudio(_THIS); static void DIB_WaitDone(_THIS); static void DIB_CloseAudio(_THIS); +int volatile dibaudio_thread_debug = 0; +int volatile dibaudio_cb_debug = 0; +int volatile dibaudio_main_debug = 0; + /* Audio driver bootstrap functions */ static int Audio_Available(void) @@ -109,11 +113,13 @@ static void CALLBACK FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, return; /* Signal that we are done playing a buffer */ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - ReleaseSemaphoreCE(audio_sem, 1, NULL); -#else - ReleaseSemaphore(audio_sem, 1, NULL); -#endif + dibaudio_cb_debug = 1; + EnterCriticalSection(&audio_cs); + dibaudio_cb_debug = 2; + SetEvent(audio_event); + dibaudio_cb_debug = 3; + LeaveCriticalSection(&audio_cs); + dibaudio_cb_debug = 4; } static void SetMMerror(char *function, MMRESULT code) @@ -147,17 +153,20 @@ static void DIB_ThreadInit(_THIS) void DIB_WaitAudio(_THIS) { /* Wait for an audio chunk to finish */ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - WaitForSemaphoreCE(audio_sem, INFINITE); -#else - WaitForSingleObject(audio_sem, INFINITE); -#endif + dibaudio_thread_debug = 1; + WaitForSingleObject(audio_event, INFINITE); + dibaudio_thread_debug = 2; + ResetEvent(audio_event); + dibaudio_thread_debug = 3; } Uint8 *DIB_GetAudioBuf(_THIS) { Uint8 *retval; + dibaudio_thread_debug = 4; + EnterCriticalSection(&audio_cs); + dibaudio_thread_debug = 5; retval = (Uint8 *)(wavebuf[next_buffer].lpData); return retval; } @@ -165,14 +174,23 @@ Uint8 *DIB_GetAudioBuf(_THIS) void DIB_PlayAudio(_THIS) { /* Queue it up */ + dibaudio_thread_debug = 6; waveOutWrite(sound, &wavebuf[next_buffer], sizeof(wavebuf[0])); + dibaudio_thread_debug = 7; next_buffer = (next_buffer+1)%NUM_BUFFERS; + LeaveCriticalSection(&audio_cs); + dibaudio_thread_debug = 8; } void DIB_WaitDone(_THIS) { - int i, left; + int i, left, tries = 5; + dibaudio_thread_debug = 9; + + /* give some time for the wave output to send the last buffer, + but don't hang if one was cancelled + */ do { left = NUM_BUFFERS; for ( i=0; i<NUM_BUFFERS; ++i ) { @@ -180,10 +198,13 @@ void DIB_WaitDone(_THIS) --left; } } - if ( left > 0 ) { - SDL_Delay(100); - } - } while ( left > 0 ); + if ( left == 0 ) + break; + + SDL_Delay(100); + } while ( --tries > 0 ); + + dibaudio_thread_debug = 10; } void DIB_CloseAudio(_THIS) @@ -191,15 +212,15 @@ void DIB_CloseAudio(_THIS) int i; /* Close up audio */ - if ( audio_sem ) { + if (audio_event != INVALID_HANDLE_VALUE ) { #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - CloseSynchHandle(audio_sem); + CloseSynchHandle(audio_event); #else - CloseHandle(audio_sem); + CloseHandle(audio_event); #endif } if ( sound ) { - waveOutClose(sound); + waveOutReset(sound); } /* Clean up mixing buffers */ @@ -215,6 +236,9 @@ void DIB_CloseAudio(_THIS) SDL_free(mixbuf); mixbuf = NULL; } + + if ( sound ) + waveOutClose(sound); } int DIB_OpenAudio(_THIS, SDL_AudioSpec *spec) @@ -225,7 +249,8 @@ int DIB_OpenAudio(_THIS, SDL_AudioSpec *spec) /* Initialize the wavebuf structures for closing */ sound = NULL; - audio_sem = NULL; + InitializeCriticalSection(&audio_cs); + audio_event = INVALID_HANDLE_VALUE; for ( i = 0; i < NUM_BUFFERS; ++i ) wavebuf[i].dwUser = 0xFFFF; mixbuf = NULL; @@ -287,12 +312,8 @@ int DIB_OpenAudio(_THIS, SDL_AudioSpec *spec) #endif /* Create the audio buffer semaphore */ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - audio_sem = CreateSemaphoreCE(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL); -#else - audio_sem = CreateSemaphore(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL); -#endif - if ( audio_sem == NULL ) { + audio_event = CreateEvent( NULL, TRUE, FALSE, NULL ); + if (audio_event == NULL) { SDL_SetError("Couldn't create semaphore"); return(-1); } diff --git a/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.h b/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.h index d2c6228..16fd078 100644 --- a/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.h +++ b/distrib/sdl-1.2.15/src/audio/windib/SDL_dibaudio.h @@ -33,17 +33,21 @@ struct SDL_PrivateAudioData { HWAVEOUT sound; - HANDLE audio_sem; - Uint8 *mixbuf; /* The raw allocated mixing buffer */ + CRITICAL_SECTION audio_cs; + HANDLE audio_event; + Uint8* mixbuf; /* The raw allocated mixing buffer */ WAVEHDR wavebuf[NUM_BUFFERS]; /* Wave audio fragments */ + int cur_buffer; int next_buffer; }; /* Old variable names */ #define sound (this->hidden->sound) -#define audio_sem (this->hidden->audio_sem) +#define audio_event (this->hidden->audio_event) +#define audio_cs (this->hidden->audio_cs) #define mixbuf (this->hidden->mixbuf) #define wavebuf (this->hidden->wavebuf) +#define cur_buffer (this->hidden->cur_buffer) #define next_buffer (this->hidden->next_buffer) #endif /* _SDL_lowaudio_h */ diff --git a/distrib/sdl-1.2.15/src/main/macosx/SDLMain.m b/distrib/sdl-1.2.15/src/main/macosx/SDLMain.m index 2434f81..7da74b6 100644 --- a/distrib/sdl-1.2.15/src/main/macosx/SDLMain.m +++ b/distrib/sdl-1.2.15/src/main/macosx/SDLMain.m @@ -371,6 +371,20 @@ int main (int argc, char **argv) gFinderLaunch = NO; } +/* ANDROID_BEGIN */ + /* if -no-window is used, we don't want to launch a graphical + * application that creates a Menu bar and steals the focus. + */ + { + int nn; + for (nn = 0; nn < argc; nn++) { + if ( !strcmp( argv[nn], "-no-window" ) ) { + return SDL_main (argc, argv); + } + } + } +/* ANDROID_END */ + #if SDL_USE_NIB_FILE NSApplicationMain (argc, argv); #else diff --git a/distrib/sdl-1.2.15/src/video/SDL_sysvideo.h b/distrib/sdl-1.2.15/src/video/SDL_sysvideo.h index 436450e..65287b4 100644 --- a/distrib/sdl-1.2.15/src/video/SDL_sysvideo.h +++ b/distrib/sdl-1.2.15/src/video/SDL_sysvideo.h @@ -217,6 +217,21 @@ struct SDL_VideoDevice { /* Get some platform dependent window information */ int (*GetWMInfo)(_THIS, SDL_SysWMinfo *info); + /* set window position */ + void (*SetWindowPos)(_THIS, int x, int y); + + /* get window position */ + void (*GetWindowPos)(_THIS, int *px, int *py); + + /* determine if the window is fully visible on screen */ + int (*IsWindowVisible)(_THIS, int recenter); + + /* get main monitor's resolution */ + int (*GetMonitorDPI)(_THIS, int *xdpi, int *ydpi); + + /* get nearest monitor's rectangle */ + int (*GetMonitorRect)(_THIS, SDL_Rect* rect); + /* * * */ /* Cursor manager functions */ diff --git a/distrib/sdl-1.2.15/src/video/SDL_video.c b/distrib/sdl-1.2.15/src/video/SDL_video.c index 46285c9..43c1826 100644 --- a/distrib/sdl-1.2.15/src/video/SDL_video.c +++ b/distrib/sdl-1.2.15/src/video/SDL_video.c @@ -1963,6 +1963,66 @@ int SDL_WM_ToggleFullScreen(SDL_Surface *surface) } /* + * Set window position + */ +void SDL_WM_SetPos(int x, int y) +{ + SDL_VideoDevice* video = current_video; + + if (video && video->SetWindowPos) + video->SetWindowPos(video, x, y); +} + +/* + * Get window position + */ +void SDL_WM_GetPos(int *px, int *py) +{ + SDL_VideoDevice* video = current_video; + + if (video && video->GetWindowPos) + video->GetWindowPos(video, px, py); + else { + *px = 100; + *py = 100; + } +} + +int SDL_WM_IsFullyVisible( int recenter ) +{ + int result = 1; + + SDL_VideoDevice* video = current_video; + + if (video && video->IsWindowVisible) { + result = video->IsWindowVisible(video, recenter); + } + return result; +} + +int SDL_WM_GetMonitorDPI( int *xDpi, int *yDpi ) +{ + int result = -1; + SDL_VideoDevice* video = current_video; + + if (video && video->GetMonitorDPI) { + result = video->GetMonitorDPI(video, xDpi, yDpi); + } + return result; +} + +int SDL_WM_GetMonitorRect( SDL_Rect *rect ) +{ + int result = -1; + SDL_VideoDevice* video = current_video; + + if (video && video->GetMonitorRect) { + result = video->GetMonitorRect(video, rect); + } + return result; +} + +/* * Get some platform dependent window manager information */ int SDL_GetWMInfo (SDL_SysWMinfo *info) diff --git a/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c b/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c index fc729f1..f2210e4 100644 --- a/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c +++ b/distrib/sdl-1.2.15/src/video/Xext/Xxf86dga/XF86DGA.c @@ -605,10 +605,10 @@ SDL_NAME(XF86DGAForkApp)(int screen) SDL_NAME(XF86DGADirectVideoLL)(sp->display, sp->screen, 0); XSync(sp->display, False); } - if (WIFEXITED(status)) - _exit(0); + if (WIFEXITED(status)) + exit(0); else - _exit(-1); + exit(-1); } return pid; } @@ -657,7 +657,7 @@ XF86cleanup(int sig) static char beenhere = 0; if (beenhere) - _exit(3); + exit(3); beenhere = 1; for (i = 0; i < numScrs; i++) { @@ -665,7 +665,7 @@ XF86cleanup(int sig) SDL_NAME(XF86DGADirectVideo)(sp->display, sp->screen, 0); XSync(sp->display, False); } - _exit(3); + exit(3); } Bool diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h index 7506e0c..d00e496 100644 --- a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h +++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.h @@ -215,6 +215,12 @@ void QZ_PumpEvents (_THIS); void QZ_SetCaption (_THIS, const char *title, const char *icon); void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask); int QZ_IconifyWindow (_THIS); +void QZ_SetWindowPos (_THIS, int x, int y); +void QZ_GetWindowPos (_THIS, int *px, int *py); +int QZ_IsWindowVisible (_THIS, int recenter); +int QZ_GetMonitorDPI (_THIS, int *xDpi, int *yDpi); +int QZ_GetMonitorRect (_THIS, SDL_Rect *rect); + SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode); /*int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/ diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m index fa04e9d..bb20172 100644 --- a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m +++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzVideo.m @@ -23,6 +23,7 @@ #include "SDL_QuartzVideo.h" #include "SDL_QuartzWindow.h" +#include "SDL_QuartzWM.h" /* These APIs aren't just deprecated; they're gone from the headers in the 10.7 SDK. If we're using a >= 10.7 SDK, but targeting < 10.7, then we @@ -220,7 +221,12 @@ static SDL_VideoDevice* QZ_CreateDevice (int device_index) device->SetCaption = QZ_SetCaption; device->SetIcon = QZ_SetIcon; device->IconifyWindow = QZ_IconifyWindow; - /*device->GetWMInfo = QZ_GetWMInfo;*/ + device->SetWindowPos = QZ_SetWindowPos; + device->GetWindowPos = QZ_GetWindowPos; + device->IsWindowVisible = QZ_IsWindowVisible; + device->GetMonitorDPI = QZ_GetMonitorDPI; + device->GetMonitorRect = QZ_GetMonitorRect; + device->GetWMInfo = QZ_GetWMInfo; device->GrabInput = QZ_GrabInput; /* diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h index 0b0767e..5219a59 100644 --- a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h +++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.h @@ -25,3 +25,4 @@ struct WMcursor { }; void QZ_UpdateCursor(_THIS); +int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info); diff --git a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m index d526424..b40abf8 100644 --- a/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m +++ b/distrib/sdl-1.2.15/src/video/quartz/SDL_QuartzWM.m @@ -278,6 +278,137 @@ void QZ_SetCaption (_THIS, const char *title, const char *icon) { } } +void QZ_SetWindowPos (_THIS, int x, int y) +{ + if ( qz_window == nil ) { + //printf( "%s(%d,%d): called for NULL window\n", __FUNCTION__, x, y ); + return; + } + + [ qz_window setFrameTopLeftPoint:NSMakePoint( x, this->hidden->height - y ) ]; + //printf( "%s(%d,%d): done\n", __FUNCTION__, x, y ); +} + +void QZ_GetWindowPos(_THIS, int *px, int *py) +{ + NSPoint pt; + + *px = *py = 0; + + if ( qz_window == NULL ) { + //printf( "%s: called on NULL window\n", __FUNCTION__ ); + } + + if ( qz_window != nil ) { + NSRect rect = [ qz_window frame ]; + *px = rect.origin.x; + *py = this->hidden->height - rect.origin.y - rect.size.height; + //printf( "%s: returning (%d,%d)\n", __FUNCTION__, *px, *py ); + } +} + +/* determine if the window is fully visible on the current screen configuration */ +int QZ_IsWindowVisible(_THIS, int recenter) +{ + int result = 0; + + //printf( "... enter %s\n", __FUNCTION__ ); + + if ( qz_window != NULL ) { + NSRect frame = [ qz_window frame ]; + NSArray* screens = [ NSScreen screens ]; + unsigned int count = [ screens count ]; + unsigned int n; + //printf( "window frame (%d,%d) (%d,%d)\n", frame.origin.x, frame.origin.y, + // frame.size.width, frame.size.height ); + for (n = 0; n < count; n++) { + NSScreen* screen = [ screens objectAtIndex: n ]; + NSRect vis = [ screen visibleFrame ]; + + //printf( "screen %d/%d frame (%d,%d) (%d,%d)\n", n+1, count, + // vis.origin.x, vis.origin.y, vis.size.width, vis.size.height ); + + if (frame.origin.x >= vis.origin.x && + frame.origin.x + frame.size.width <= vis.origin.x + vis.size.width && + frame.origin.y >= vis.origin.y && + frame.origin.y + frame.size.height <= vis.origin.y + vis.size.height ) + { + result = 1; + break; + } + } + } + //printf ( "... exit %s, result = %d\n", __FUNCTION__, result ); + if ( !result && recenter ) { + [ qz_window center ] ; + } + return result; +} + +int QZ_GetMonitorDPI(_THIS, int *xDpi, int *yDpi) +{ + /* FIXME: how to get this information from Cocoa ? */ + return -1; +} + +int QZ_GetMonitorRect (_THIS, SDL_Rect *rect) +{ + NSWindow* window = qz_window; + NSRect frame = [ window frame ]; + int fx1 = frame.origin.x; + int fy1 = frame.origin.y; + int fx2 = frame.size.width + fx1; + int fy2 = frame.size.height + fy1; + NSArray* screens = [ NSScreen screens ]; + unsigned int count = [ screens count ]; + int bestScreen = -1; + int bestArea = 0; + + unsigned int n; + + /* we need to compute which screen has the most window pixels */ + for (n = 0; n < count; n++) { + NSScreen* screen = [ screens objectAtIndex: n ]; + NSRect vis = [ screen visibleFrame ]; + int vx1 = vis.origin.x; + int vy1 = vis.origin.y; + int vx2 = vis.size.width + vx1; + int vy2 = vis.size.height + vy1; + int cx1, cx2, cy1, cy2, cArea; + + if (fx1 >= vx2 || vx1 >= fx2 || fy1 >= vy2 || vy1 >= fy2) + continue; + + cx1 = (fx1 < vx1) ? vx1 : fx1; + cx2 = (fx2 > vx2) ? vx2 : fx2; + cy1 = (fy1 < vy1) ? vy1 : fy1; + cy2 = (fy2 > vy2) ? vy2 : fy2; + + if (cx1 >= cx2 || cy1 >= cy2) + continue; + + cArea = (cx2-cx1)*(cy2-cy1); + + if (bestScreen < 0 || cArea > bestArea) { + bestScreen = n; + bestArea = cArea; + } + } + if (bestScreen < 0) + bestScreen = 0; + + { + NSScreen* screen = [ screens objectAtIndex: bestScreen ]; + NSRect vis = [ screen visibleFrame ]; + + rect->x = vis.origin.x; + rect->y = vis.origin.y; + rect->w = vis.size.width; + rect->h = vis.size.height; + } + return 0; +} + void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask) { NSBitmapImageRep *imgrep; @@ -362,11 +493,10 @@ int QZ_IconifyWindow (_THIS) { } } -/* int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) { info->nsWindowPtr = qz_window; return 0; -}*/ +} void QZ_ChangeGrabState (_THIS, int action) { diff --git a/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c b/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c index 6187bfc..9f1ffff 100644 --- a/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c +++ b/distrib/sdl-1.2.15/src/video/windib/SDL_dibvideo.c @@ -115,6 +115,12 @@ static void DIB_RealizePalette(_THIS); static void DIB_PaletteChanged(_THIS, HWND window); static void DIB_WinPAINT(_THIS, HDC hdc); +static void DIB_GetWinPos(_THIS, int* px, int *py); +static void DIB_SetWinPos(_THIS, int x, int y); +static int DIB_IsWinVisible(_THIS, int recenter); +static int DIB_GetMonitorDPI(_THIS, int* xDpi, int *yDpi); +static int DIB_GetMonitorRect(_THIS, SDL_Rect* rect); + /* helper fn */ static int DIB_SussScreenDepth(); @@ -212,6 +218,12 @@ static SDL_VideoDevice *DIB_CreateDevice(int devindex) device->InitOSKeymap = DIB_InitOSKeymap; device->PumpEvents = DIB_PumpEvents; + device->GetWindowPos = DIB_GetWinPos; + device->SetWindowPos = DIB_SetWinPos; + device->IsWindowVisible = DIB_IsWinVisible; + device->GetMonitorDPI = DIB_GetMonitorDPI; + device->GetMonitorRect = DIB_GetMonitorRect; + /* Set up the windows message handling functions */ WIN_Activate = DIB_Activate; WIN_RealizePalette = DIB_RealizePalette; @@ -1314,6 +1326,170 @@ static void DIB_WinPAINT(_THIS, HDC hdc) DeleteDC(mdc); } +static void DIB_GetWinPos(_THIS, int* px, int *py) +{ + RECT rect; + GetWindowRect(SDL_Window, &rect); + *px = rect.left; + *py = rect.top; +} + +static void DIB_SetWinPos(_THIS, int x, int y) +{ + SetWindowPos(SDL_Window, HWND_TOPMOST, + x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER); +} + +typedef struct { + int result; + int first; + RECT wrect; + RECT primary; +} VisibilityData; + + +BOOL CALLBACK visibility_cb(HMONITOR hMonitor, + HDC hdcMonitor, + LPRECT mrect, + LPARAM dwData) +{ + VisibilityData* data = (VisibilityData*)dwData; + + if ( data->first ) { + data->first = 0; + data->primary = mrect[0]; + } + + if ( data->wrect.left >= mrect->left && + data->wrect.right <= mrect->right && + data->wrect.top >= mrect->top && + data->wrect.bottom <= mrect->bottom ) + { + data->result = 1; + return FALSE; + } + return TRUE; +} + +static int DIB_IsWinVisible(_THIS, int recenter) +{ + VisibilityData data; + data.result = 0; + data.first = 1; + + GetWindowRect(SDL_Window, &data.wrect); + + EnumDisplayMonitors(NULL, NULL, visibility_cb, (LPARAM)&data); + + if ( !data.result && recenter ) { + int new_x = 10; + int new_y = 10; + + if ( !data.first ) { + int primary_w = data.primary.right - data.primary.left; + int primary_h = data.primary.bottom - data.primary.top; + + new_x = data.primary.left + (primary_w - this->screen->w)/2; + new_y = data.primary.top + (primary_h - this->screen->h)/2; + } + DIB_SetWinPos(this, new_x, new_y); + } + return data.result; +} + +static int DIB_GetMonitorDPI(_THIS, int* xDpi, int *yDpi) +{ + HDC displayDC = CreateDC( "DISPLAY", NULL, NULL, NULL ); + int xdpi, ydpi; + + if (displayDC == NULL) { + return -1; + } + xdpi = GetDeviceCaps( displayDC, LOGPIXELSX ); + ydpi = GetDeviceCaps( displayDC, LOGPIXELSY ); + + DeleteDC(displayDC); + + /* sanity checks */ + if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) { + return -1; + } + + *xDpi = xdpi; + *yDpi = ydpi; + return 0; +} + + +typedef struct { + int first; + RECT wrect; + long bestArea; + RECT bestRect; + RECT primary; +} ProximityData; + +BOOL CALLBACK proximity_cb(HMONITOR hMonitor, + HDC hdcMonitor, + LPRECT mrect, + LPARAM dwData) +{ + ProximityData* data = (ProximityData*)dwData; + int x1, y1, x2, y2, area; + + x1 = mrect->left; + x2 = mrect->right; + y1 = mrect->top; + y2 = mrect->bottom; + + if (data->first) { + data->primary = mrect[0]; + } + + if (x1 < data->wrect.left) + x1 = data->wrect.left; + if (x2 > data->wrect.right) + x2 = data->wrect.right; + if (y1 < data->wrect.top) + y1 = data->wrect.top; + if (y2 > data->wrect.bottom) + y2 = data->wrect.bottom; + + if (x1 >= x2 || y1 >= y2) + return TRUE; + + area = (x2-x1)*(y2-y1); + if (data->first || area > data->bestArea) { + data->first = 0; + data->bestRect = mrect[0]; + data->bestArea = area; + } + return TRUE; +} + +static int DIB_GetMonitorRect(_THIS, SDL_Rect* rect) +{ + ProximityData data; + RECT* sr; + + data.first = 1; + GetWindowRect(SDL_Window, &data.wrect); + + EnumDisplayMonitors(NULL, NULL, proximity_cb, (LPARAM)&data); + + if (data.first) + return -1; + + sr = &data.bestRect; + + rect->x = sr->left; + rect->y = sr->top; + rect->w = sr->right - sr->left; + rect->h = sr->bottom - sr->top; + + return 0; +} + /* Stub in case DirectX isn't available */ #if !SDL_AUDIO_DRIVER_DSOUND void DX5_SoundFocus(HWND hwnd) diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c index 7058add..7d4acbb 100644 --- a/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c +++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11dyn.c @@ -200,6 +200,7 @@ int SDL_X11_LoadSymbols(void) if (SDL_X11_HAVE_BASEXLIB) { /* all required symbols loaded. */ SDL_ClearError(); + XInitThreads(); } else { SDL_X11_UnloadSymbols(); /* in case something got loaded... */ rc = 0; diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h index 4875b98..f9c7df3 100644 --- a/distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h +++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11sym.h @@ -31,6 +31,7 @@ SDL_X11_SYM(int,XChangeWindowAttributes,(Display* a,Window b,unsigned long c,XSe SDL_X11_SYM(Bool,XCheckTypedEvent,(Display* a,int b,XEvent* c),(a,b,c),return) SDL_X11_SYM(int,XClearWindow,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XCloseDisplay,(Display* a),(a),return) +SDL_X11_SYM(int,XConfigureWindow,(Display* a,Window b,unsigned int c,XWindowChanges* d),(a,b,c,d),return) SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return) SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,XColor* e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return) SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return) @@ -39,6 +40,11 @@ SDL_X11_SYM(Pixmap,XCreatePixmap,(Display* a,Drawable b,unsigned int c,unsigned SDL_X11_SYM(Pixmap,XCreatePixmapFromBitmapData,(Display* a,Drawable b,char* c,unsigned int d,unsigned int e,unsigned long f,unsigned long g,unsigned int h),(a,b,c,d,e,f,g,h),return) SDL_X11_SYM(Window,XCreateSimpleWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,unsigned long h,unsigned long i),(a,b,c,d,e,f,g,h,i),return) SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l),(a,b,c,d,e,f,g,h,i,j,k,l),return) +SDL_X11_SYM(int,XDefaultScreen,(Display* a),(a),return) +SDL_X11_SYM(int,XDisplayWidth,(Display* a,int b),(a,b),return) +SDL_X11_SYM(int,XDisplayWidthMM,(Display* a, int b),(a, b),return) +SDL_X11_SYM(int,XDisplayHeight,(Display* a,int b),(a,b),return) +SDL_X11_SYM(int,XDisplayHeightMM,(Display* a, int b),(a, b),return) SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c),(a,b,c),return) SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c),(a,b,c),return) SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b),(a,b),return) @@ -54,6 +60,7 @@ SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return) SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return) SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return) SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return) +SDL_X11_SYM(int,XGetGeometry,(Display* a,Drawable b,Window* c,int* d,int* e,unsigned int* f,unsigned int* g,unsigned int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return) SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return) SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return) SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return) @@ -62,6 +69,7 @@ SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* SDL_X11_SYM(int,XGrabKeyboard,(Display* a,Window b,Bool c,int d,int e,Time f),(a,b,c,d,e,f),return) SDL_X11_SYM(int,XGrabPointer,(Display* a,Window b,Bool c,unsigned int d,int e,int f,Window g,Cursor h,Time i),(a,b,c,d,e,f,g,h,i),return) SDL_X11_SYM(Status,XIconifyWindow,(Display* a,Window b,int c),(a,b,c),return) +SDL_X11_SYM(Status,XInitThreads,(void),(),return) SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return) SDL_X11_SYM(KeyCode,XKeysymToKeycode,(Display* a,KeySym b),(a,b),return) SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return) @@ -82,6 +90,7 @@ SDL_X11_SYM(int,XPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int SDL_X11_SYM(int,XQueryColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return) SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return) SDL_X11_SYM(Bool,XQueryPointer,(Display* a,Window b,Window* c,Window* d,int* e,int* f,int* g,int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return) +SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return) SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return) SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return) @@ -124,6 +133,7 @@ SDL_X11_SYM(void,_XSend,(Display* a,_Xconst char* b,long c),(a,b,c),) SDL_X11_SYM(Status,_XReply,(Display* a,xReply* b,int c,Bool d),(a,b,c,d),return) SDL_X11_SYM(unsigned long,_XSetLastRequestRead,(Display* a,xGenericReply* b),(a,b),return) SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),return) +SDL_X11_SYM(int,XTranslateCoordinates,(Display* a,Window b,Window c,int d,int e,int* f,int* g,Window* h),(a,b,c,d,e,f,g,h),return) SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,SDL_X11_XESetWireToEventRetType c),(a,b,c),return) SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return) SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return) diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c index f7d8073..6d24422 100644 --- a/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c +++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.c @@ -68,6 +68,8 @@ static int X11_SetColors(_THIS, int firstcolor, int ncolors, static int X11_SetGammaRamp(_THIS, Uint16 *ramp); static void X11_VideoQuit(_THIS); +int X11_wmXAdjust; +int X11_wmYAdjust; /* X11 driver bootstrap functions */ @@ -164,6 +166,11 @@ static SDL_VideoDevice *X11_CreateDevice(int devindex) device->SetIcon = X11_SetIcon; device->IconifyWindow = X11_IconifyWindow; device->GrabInput = X11_GrabInput; + device->GetWindowPos = X11_GetWindowPos; + device->SetWindowPos = X11_SetWindowPos; + device->IsWindowVisible = X11_IsWindowVisible; + device->GetMonitorDPI = X11_GetMonitorDPI; + device->GetMonitorRect = X11_GetMonitorRect; device->GetWMInfo = X11_GetWMInfo; device->FreeWMCursor = X11_FreeWMCursor; device->CreateWMCursor = X11_CreateWMCursor; @@ -350,7 +357,9 @@ static void create_aux_windows(_THIS) xattr.colormap = SDL_XColorMap; FSwindow = XCreateWindow(SDL_Display, SDL_Root, - x, y, 32, 32, 0, + x + X11_wmXAdjust, + y + X11_wmYAdjust, + 32, 32, 0, this->hidden->depth, InputOutput, SDL_Visual, CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWColormap, diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h index f347560..18cf497 100644 --- a/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h +++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11video.h @@ -156,6 +156,9 @@ struct SDL_PrivateVideoData { int allow_screensaver; }; +extern int X11_wmXAdjust; +extern int X11_wmYAdjust; + /* Old variable names */ #define local_X11 (this->hidden->local_X11) #define SDL_Display (this->hidden->X11_Display) diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c index 14c816b..2fd59e9 100644 --- a/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c +++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm.c @@ -325,6 +325,147 @@ int X11_IconifyWindow(_THIS) return(result); } +#if 0 +#define D(...) printf(__VA_ARGS__) +#define E(...) D(__VA_ARGS__) +#else +#define D(...) ((void)0) +#define E(...) ((void)0) +#endif + +static void set_window_pos_nolock(_THIS, int x, int y) +{ + int xNew, yNew; + Window child; + int xAdjust = X11_wmXAdjust; + int yAdjust = X11_wmYAdjust; + + /* don't do anything in full-screen mode, because the FSwindow is used + * instead of the WMwindow, which will make the adjustment go wild + */ + if (this->screen->flags & SDL_FULLSCREEN) + return; + + /* this code is tricky because some window managers, but not all, + * will translate the final window position by a given offset + * corresponding to the frame decoration. + * + * so we first try to move the window, get the position that the + * window manager has set, and if they are different, re-position the + * window again with an adjustment. + * + * this causes a slight flicker since the window 'jumps' very + * quickly from one position to the other. + */ + + D("%s: move to [%d,%d] adjusted to [%d,%d]\n", __FUNCTION__, + x, y, x+xAdjust, y+yAdjust); + XMoveWindow(SDL_Display, WMwindow, x + xAdjust, y + yAdjust); + XSync(SDL_Display, True); + XTranslateCoordinates( SDL_Display, WMwindow, SDL_Root, 0, 0, &xNew, &yNew, &child ); + if (xNew != x || yNew != y) { + X11_wmXAdjust = xAdjust = x - xNew; + X11_wmYAdjust = yAdjust = y - yNew; + D("%s: read pos [%d,%d], recomputing adjust=[%d,%d] moving to [%d,%d]\n", + __FUNCTION__, xNew, yNew, xAdjust, yAdjust, x+xAdjust, y+yAdjust); + XMoveWindow(SDL_Display, WMwindow, x + xAdjust, y + yAdjust ); + } + XSync(SDL_Display, False); +} + +/* Set window position */ +void X11_SetWindowPos(_THIS, int x, int y) +{ + SDL_Lock_EventThread(); + set_window_pos_nolock(this, x, y); + SDL_Unlock_EventThread(); +} + +/* Get window position */ +void X11_GetWindowPos(_THIS, int *px, int *py) +{ + /* in full-screen mode, you can't move the window */ + if (this->screen->flags & SDL_FULLSCREEN) { + *px = *py = 0; + return; + } + + + SDL_Lock_EventThread(); + { + Window child; + + XTranslateCoordinates( SDL_Display, WMwindow, SDL_Root, 0, 0, px, py, &child ); + } + SDL_Unlock_EventThread(); +} + +static int +is_window_visible(_THIS, int screen_x, int screen_y, int screen_w, int screen_h ) +{ + XWindowAttributes attr; + int x, y; + Window child; + + XGetWindowAttributes( SDL_Display, WMwindow, &attr ); + XTranslateCoordinates( SDL_Display, WMwindow, SDL_Root, 0, 0, &x, &y, &child ); + + return ( x >= screen_x && x + attr.width <= screen_x + screen_w && + y >= screen_y && y + attr.height <= screen_y + screen_h ); +} + +int X11_IsWindowVisible(_THIS, int recenter) +{ + int result = 0; + XWindowAttributes attr; + int screen_w, screen_h; + + SDL_Lock_EventThread(); + XGetWindowAttributes( SDL_Display, SDL_Root, &attr ); + screen_w = attr.width; + screen_h = attr.height; + +#if SDL_VIDEO_DRIVER_X11_XINERAMA + if (use_xinerama) { + SDL_NAME(XineramaScreenInfo) *xinerama; + int i, screens; + + xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens); + for (i = 0; i < screens; i++) { + if ( is_window_visible( this, + xinerama[i].x_org, xinerama[i].y_org, + xinerama[i].width, xinerama[i].height ) ) + { + result = 1; + break; + } + } + + if ( !result && recenter ) { + set_window_pos_nolock(this, + xinerama[0].x_org + (xinerama[0].width - this->screen->w)/2, + xinerama[0].y_org + (xinerama[0].height - this->screen->h)/2 ); + } + XFree(xinerama); + goto Exit; + } +#endif + if ( is_window_visible( this, 0, 0, screen_w, screen_h ) ) { + result = 1; + } + + if ( !result && recenter ) { + set_window_pos_nolock( this, + (screen_w - this->screen->w)/2, + (screen_h - this->screen->h)/2 ); + } +#ifdef SDL_VIDEO_DRIVER_X11_XINERAMA +Exit: +#endif + SDL_Unlock_EventThread(); + return result; +} + SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode) { int result; @@ -387,6 +528,51 @@ SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode) return(mode); } +#define MM_PER_INCH 25.4 + +int +X11_GetMonitorDPI(_THIS, int *px_dpi, int *py_dpi) +{ + Display* display = SDL_Display; + int screen = XDefaultScreen(display); + int xdpi, ydpi; + + int width = XDisplayWidth(display, screen); + int width_mm = XDisplayWidthMM(display, screen); + int height = XDisplayHeight(display, screen); + int height_mm = XDisplayHeightMM(display, screen); + + if (width_mm <= 0 || height_mm <= 0) { + return -1; + } + + xdpi = (int)(width * MM_PER_INCH / width_mm + 0.5); + ydpi = (int)(height * MM_PER_INCH / height_mm + 0.5); + + if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) { + return -1; + } + + *px_dpi = xdpi; + *py_dpi = ydpi; + + return 0; +} + +int +X11_GetMonitorRect(_THIS, SDL_Rect *rect) +{ + Display* display = SDL_Display; + int screen = XDefaultScreen(display); + + rect->x = 0; + rect->y = 0; + rect->w = XDisplayWidth(display, screen); + rect->h = XDisplayHeight(display, screen); + + return 0; +} + /* If 'info' is the right version, this function fills it and returns 1. Otherwise, in case of a version mismatch, it returns -1. */ diff --git a/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h index f85477b..c0f938b 100644 --- a/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h +++ b/distrib/sdl-1.2.15/src/video/x11/SDL_x11wm_c.h @@ -31,4 +31,8 @@ extern int X11_IconifyWindow(_THIS); extern SDL_GrabMode X11_GrabInputNoLock(_THIS, SDL_GrabMode mode); extern SDL_GrabMode X11_GrabInput(_THIS, SDL_GrabMode mode); extern int X11_GetWMInfo(_THIS, SDL_SysWMinfo *info); - +extern void X11_GetWindowPos(_THIS, int *px, int *py); +extern void X11_SetWindowPos(_THIS, int x, int y); +extern int X11_IsWindowVisible(_THIS, int recenter); +extern int X11_GetMonitorDPI(_THIS, int* xdpi, int *ydpi); +extern int X11_GetMonitorRect(_THIS, SDL_Rect *rect); |