The old windows video drivers are superceded by the unified win32 driver.
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401989
This commit is contained in:
parent
bd9931afdd
commit
dc3126175d
21 changed files with 0 additions and 9497 deletions
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_lowvideo_h
|
||||
#define _SDL_lowvideo_h
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef SetClassLongPtr
|
||||
#define SetClassLongPtr SetClassLong
|
||||
#endif
|
||||
#ifndef GetWindowLongPtr
|
||||
#define GetWindowLongPtr GetWindowLong
|
||||
#endif
|
||||
#ifndef SetWindowLongPtr
|
||||
#define SetWindowLongPtr SetWindowLong
|
||||
#endif
|
||||
#ifndef GWLP_WNDPROC
|
||||
#define GWLP_WNDPROC GWL_WNDPROC
|
||||
#endif
|
||||
#ifndef GCLP_HICON
|
||||
#define GCLP_HICON GCL_HICON
|
||||
#endif
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
/* Hidden "this" pointer for the video functions */
|
||||
#define _THIS SDL_VideoDevice *this
|
||||
|
||||
#define WINDIB_FULLSCREEN() \
|
||||
( \
|
||||
SDL_VideoSurface && \
|
||||
(SDL_VideoSurface->flags & SDL_FULLSCREEN) && \
|
||||
((SDL_VideoSurface->flags & SDL_INTERNALOPENGL) || \
|
||||
((SDL_strcmp(this->name, "windib") == 0) || \
|
||||
(SDL_strcmp(this->name, "gapi") == 0))) \
|
||||
)
|
||||
#define DDRAW_FULLSCREEN() \
|
||||
( \
|
||||
SDL_VideoSurface && \
|
||||
(SDL_VideoSurface->flags & SDL_FULLSCREEN) && \
|
||||
(SDL_VideoSurface->flags & SDL_INTERNALOPENGL) && \
|
||||
(SDL_strcmp(this->name, "directx") == 0) \
|
||||
)
|
||||
|
||||
#define DINPUT_FULLSCREEN() DDRAW_FULLSCREEN()
|
||||
|
||||
/* The main window -- and a function to set it for the audio */
|
||||
#ifdef _WIN32_WCE
|
||||
extern LPWSTR SDL_Appname;
|
||||
#else
|
||||
extern LPSTR SDL_Appname;
|
||||
#endif
|
||||
extern HINSTANCE SDL_Instance;
|
||||
extern HWND SDL_Window;
|
||||
extern BOOL SDL_windowid;
|
||||
|
||||
/* Variables and functions exported to other parts of the native video
|
||||
subsystem (SDL_sysevents.c)
|
||||
*/
|
||||
extern void WIN_FlushMessageQueue();
|
||||
|
||||
/* Called by windows message loop when system palette is available */
|
||||
extern void (*WIN_RealizePalette) (_THIS);
|
||||
|
||||
/* Called by windows message loop when the system palette changes */
|
||||
extern void (*WIN_PaletteChanged) (_THIS, HWND window);
|
||||
|
||||
/* Called by windows message loop when a portion of the screen needs update */
|
||||
extern void (*WIN_WinPAINT) (_THIS, HDC hdc);
|
||||
|
||||
/* Called by windows message loop when the message isn't handled */
|
||||
extern LONG(*HandleMessage) (_THIS, HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
/* The window cursor (from SDL_sysmouse.c) */
|
||||
extern HCURSOR SDL_hcursor;
|
||||
|
||||
/* The bounds of the window in screen coordinates */
|
||||
extern RECT SDL_bounds;
|
||||
|
||||
/* The position of the window in windowed mode */
|
||||
extern int SDL_windowX;
|
||||
extern int SDL_windowY;
|
||||
|
||||
/* Flag -- SDL is performing a resize, rather than the user */
|
||||
extern int SDL_resizing;
|
||||
|
||||
/* Flag -- the mouse is in relative motion mode */
|
||||
extern int mouse_relative;
|
||||
|
||||
/* The GDI fullscreen mode currently active */
|
||||
#ifndef NO_CHANGEDISPLAYSETTINGS
|
||||
extern DEVMODE SDL_desktop_mode;
|
||||
extern DEVMODE SDL_fullscreen_mode;
|
||||
#endif
|
||||
|
||||
/* The system gamma ramp for GDI modes */
|
||||
extern WORD *gamma_saved;
|
||||
|
||||
/* This is really from SDL_dx5audio.c */
|
||||
extern void DX5_SoundFocus(HWND window);
|
||||
|
||||
/* DJM: This is really from SDL_sysevents.c, we need it in
|
||||
GDL_CreateWindow as well */
|
||||
LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */
|
||||
typedef int (WINAPI * ToUnicodeFN) (UINT, UINT, PBYTE, LPWSTR, int, UINT);
|
||||
|
||||
extern ToUnicodeFN SDL_ToUnicode;
|
||||
|
||||
#endif /* SDL_lowvideo_h */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,928 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_sysevents.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "SDL_lowvideo.h"
|
||||
#include "SDL_syswm_c.h"
|
||||
#include "SDL_main.h"
|
||||
#include "SDL_loadso.h"
|
||||
|
||||
#ifdef WMMSG_DEBUG
|
||||
#include "wmmsg.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#include "../gapi/SDL_gapivideo.h"
|
||||
|
||||
#define IsZoomed(HWND) 1
|
||||
#define NO_GETKEYBOARDSTATE
|
||||
#if _WIN32_WCE < 420
|
||||
#define NO_CHANGEDISPLAYSETTINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The window we use for everything... */
|
||||
#ifdef _WIN32_WCE
|
||||
LPWSTR SDL_Appname = NULL;
|
||||
#else
|
||||
LPSTR SDL_Appname = NULL;
|
||||
#endif
|
||||
Uint32 SDL_Appstyle = 0;
|
||||
HINSTANCE SDL_Instance = NULL;
|
||||
HWND SDL_Window = NULL;
|
||||
RECT SDL_bounds = { 0, 0, 0, 0 };
|
||||
int SDL_windowX = 0;
|
||||
int SDL_windowY = 0;
|
||||
int SDL_resizing = 0;
|
||||
int mouse_relative = 0;
|
||||
int posted = 0;
|
||||
#ifndef NO_CHANGEDISPLAYSETTINGS
|
||||
DEVMODE SDL_desktop_mode;
|
||||
DEVMODE SDL_fullscreen_mode;
|
||||
#endif
|
||||
WORD *gamma_saved = NULL;
|
||||
|
||||
|
||||
/* Functions called by the message processing function */
|
||||
LONG(*HandleMessage) (_THIS, HWND hwnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam) = NULL;
|
||||
void (*WIN_RealizePalette) (_THIS);
|
||||
void (*WIN_PaletteChanged) (_THIS, HWND window);
|
||||
void (*WIN_WinPAINT) (_THIS, HDC hdc);
|
||||
extern void DIB_SwapGamma(_THIS);
|
||||
|
||||
#ifndef NO_GETKEYBOARDSTATE
|
||||
/* Variables and support functions for SDL_ToUnicode() */
|
||||
static int codepage;
|
||||
static int Is9xME();
|
||||
static int GetCodePage();
|
||||
static int WINAPI ToUnicode9xME(UINT vkey, UINT scancode, BYTE * keystate,
|
||||
LPWSTR wchars, int wsize, UINT flags);
|
||||
|
||||
ToUnicodeFN SDL_ToUnicode = ToUnicode9xME;
|
||||
#endif /* !NO_GETKEYBOARDSTATE */
|
||||
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
|
||||
// dynamically load aygshell dll because we want SDL to work on HPC and be300
|
||||
HINSTANCE aygshell = NULL;
|
||||
BOOL(WINAPI * SHFullScreen) (HWND hwndRequester, DWORD dwState) = 0;
|
||||
|
||||
#define SHFS_SHOWTASKBAR 0x0001
|
||||
#define SHFS_HIDETASKBAR 0x0002
|
||||
#define SHFS_SHOWSIPBUTTON 0x0004
|
||||
#define SHFS_HIDESIPBUTTON 0x0008
|
||||
#define SHFS_SHOWSTARTICON 0x0010
|
||||
#define SHFS_HIDESTARTICON 0x0020
|
||||
|
||||
static void
|
||||
LoadAygshell(void)
|
||||
{
|
||||
if (!aygshell)
|
||||
aygshell = SDL_LoadObject("aygshell.dll");
|
||||
if ((aygshell != 0) && (SHFullScreen == 0)) {
|
||||
SHFullScreen = (int (WINAPI *) (struct HWND__ *, unsigned long))
|
||||
SDL_LoadFunction(aygshell, "SHFullScreen");
|
||||
}
|
||||
}
|
||||
|
||||
/* for gapi landscape mode */
|
||||
static void
|
||||
GapiTransform(SDL_ScreenOrientation rotate, char hires, Sint16 * x,
|
||||
Sint16 * y)
|
||||
{
|
||||
Sint16 rotatedX;
|
||||
Sint16 rotatedY;
|
||||
|
||||
if (hires) {
|
||||
*x = *x * 2;
|
||||
*y = *y * 2;
|
||||
}
|
||||
|
||||
switch (rotate) {
|
||||
case SDL_ORIENTATION_UP:
|
||||
{
|
||||
/* this code needs testing on a real device!
|
||||
So it will be enabled later */
|
||||
/*
|
||||
#ifdef _WIN32_WCE
|
||||
#if _WIN32_WCE >= 420
|
||||
// test device orientation
|
||||
// FIXME: do not check every mouse message
|
||||
DEVMODE settings;
|
||||
SDL_memset(&settings, 0, sizeof(DEVMODE));
|
||||
settings.dmSize = sizeof(DEVMODE);
|
||||
settings.dmFields = DM_DISPLAYORIENTATION;
|
||||
ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
|
||||
if( settings.dmOrientation == DMDO_90 )
|
||||
{
|
||||
rotatedX = SDL_VideoSurface->h - *x;
|
||||
rotatedY = *y;
|
||||
*x = rotatedX;
|
||||
*y = rotatedY;
|
||||
}
|
||||
#endif
|
||||
#endif */
|
||||
}
|
||||
break;
|
||||
case SDL_ORIENTATION_RIGHT:
|
||||
if (!SDL_VideoSurface)
|
||||
break;
|
||||
rotatedX = SDL_VideoSurface->w - *y;
|
||||
rotatedY = *x;
|
||||
*x = rotatedX;
|
||||
*y = rotatedY;
|
||||
break;
|
||||
case SDL_ORIENTATION_LEFT:
|
||||
if (!SDL_VideoSurface)
|
||||
break;
|
||||
rotatedX = *y;
|
||||
rotatedY = SDL_VideoSurface->h - *x;
|
||||
*x = rotatedX;
|
||||
*y = rotatedY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* JC 14 Mar 2006
|
||||
This is used all over the place, in the windib driver and in the dx5 driver
|
||||
So we may as well stick it here instead of having multiple copies scattered
|
||||
about
|
||||
*/
|
||||
void
|
||||
WIN_FlushMessageQueue()
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_RestoreGameMode(void)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
SDL_VideoDevice *this = current_video;
|
||||
if (SDL_strcmp(this->name, "gapi") == 0) {
|
||||
if (this->hidden->suspended) {
|
||||
this->hidden->suspended = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
ShowWindow(SDL_Window, SW_RESTORE);
|
||||
#endif
|
||||
|
||||
#ifndef NO_CHANGEDISPLAYSETTINGS
|
||||
#ifndef _WIN32_WCE
|
||||
ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN);
|
||||
#endif
|
||||
#endif /* NO_CHANGEDISPLAYSETTINGS */
|
||||
}
|
||||
static void
|
||||
SDL_RestoreDesktopMode(void)
|
||||
{
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
SDL_VideoDevice *this = current_video;
|
||||
if (SDL_strcmp(this->name, "gapi") == 0) {
|
||||
if (!this->hidden->suspended) {
|
||||
this->hidden->suspended = 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* WinCE does not have a taskbar, so minimizing is not convenient */
|
||||
ShowWindow(SDL_Window, SW_MINIMIZE);
|
||||
#endif
|
||||
|
||||
#ifndef NO_CHANGEDISPLAYSETTINGS
|
||||
#ifndef _WIN32_WCE
|
||||
ChangeDisplaySettings(NULL, 0);
|
||||
#endif
|
||||
#endif /* NO_CHANGEDISPLAYSETTINGS */
|
||||
}
|
||||
|
||||
#ifdef WM_MOUSELEAVE
|
||||
/*
|
||||
Special code to handle mouse leave events - this sucks...
|
||||
http://support.microsoft.com/support/kb/articles/q183/1/07.asp
|
||||
|
||||
TrackMouseEvent() is only available on Win98 and WinNT.
|
||||
_TrackMouseEvent() is available on Win95, but isn't yet in the mingw32
|
||||
development environment, and only works on systems that have had IE 3.0
|
||||
or newer installed on them (which is not the case with the base Win95).
|
||||
Therefore, we implement our own version of _TrackMouseEvent() which
|
||||
uses our own implementation if TrackMouseEvent() is not available.
|
||||
*/
|
||||
static BOOL(WINAPI * _TrackMouseEvent) (TRACKMOUSEEVENT * ptme) = NULL;
|
||||
|
||||
static VOID CALLBACK
|
||||
TrackMouseTimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
|
||||
{
|
||||
RECT rect;
|
||||
POINT pt;
|
||||
|
||||
GetClientRect(hWnd, &rect);
|
||||
MapWindowPoints(hWnd, NULL, (LPPOINT) & rect, 2);
|
||||
GetCursorPos(&pt);
|
||||
if (!PtInRect(&rect, pt) || (WindowFromPoint(pt) != hWnd)) {
|
||||
if (!KillTimer(hWnd, idEvent)) {
|
||||
/* Error killing the timer! */
|
||||
}
|
||||
PostMessage(hWnd, WM_MOUSELEAVE, 0, 0);
|
||||
}
|
||||
}
|
||||
static BOOL WINAPI
|
||||
WIN_TrackMouseEvent(TRACKMOUSEEVENT * ptme)
|
||||
{
|
||||
if (ptme->dwFlags == TME_LEAVE) {
|
||||
return SetTimer(ptme->hwndTrack, ptme->dwFlags, 100,
|
||||
(TIMERPROC) TrackMouseTimerProc) != 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* WM_MOUSELEAVE */
|
||||
|
||||
/* Function to retrieve the current keyboard modifiers */
|
||||
static void
|
||||
WIN_GetKeyboardState(void)
|
||||
{
|
||||
#ifndef NO_GETKEYBOARDSTATE
|
||||
SDLMod state;
|
||||
BYTE keyboard[256];
|
||||
Uint8 *kstate = SDL_GetKeyState(NULL);
|
||||
|
||||
state = KMOD_NONE;
|
||||
if (GetKeyboardState(keyboard)) {
|
||||
if (keyboard[VK_LSHIFT] & 0x80) {
|
||||
state |= KMOD_LSHIFT;
|
||||
kstate[SDLK_LSHIFT] = SDL_PRESSED;
|
||||
}
|
||||
if (keyboard[VK_RSHIFT] & 0x80) {
|
||||
state |= KMOD_RSHIFT;
|
||||
kstate[SDLK_RSHIFT] = SDL_PRESSED;
|
||||
}
|
||||
if (keyboard[VK_LCONTROL] & 0x80) {
|
||||
state |= KMOD_LCTRL;
|
||||
kstate[SDLK_LCTRL] = SDL_PRESSED;
|
||||
}
|
||||
if (keyboard[VK_RCONTROL] & 0x80) {
|
||||
state |= KMOD_RCTRL;
|
||||
kstate[SDLK_RCTRL] = SDL_PRESSED;
|
||||
}
|
||||
if (keyboard[VK_LMENU] & 0x80) {
|
||||
state |= KMOD_LALT;
|
||||
kstate[SDLK_LALT] = SDL_PRESSED;
|
||||
}
|
||||
if (keyboard[VK_RMENU] & 0x80) {
|
||||
state |= KMOD_RALT;
|
||||
kstate[SDLK_RALT] = SDL_PRESSED;
|
||||
}
|
||||
if (keyboard[VK_NUMLOCK] & 0x01) {
|
||||
state |= KMOD_NUM;
|
||||
kstate[SDLK_NUMLOCK] = SDL_PRESSED;
|
||||
}
|
||||
if (keyboard[VK_CAPITAL] & 0x01) {
|
||||
state |= KMOD_CAPS;
|
||||
kstate[SDLK_CAPSLOCK] = SDL_PRESSED;
|
||||
}
|
||||
}
|
||||
SDL_SetModState(state);
|
||||
#endif /* !NO_GETKEYBOARDSTATE */
|
||||
}
|
||||
|
||||
/* The main Win32 event handler
|
||||
DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it
|
||||
*/
|
||||
LRESULT CALLBACK
|
||||
WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
SDL_VideoDevice *this = current_video;
|
||||
static int mouse_pressed = 0;
|
||||
static int in_window = 0;
|
||||
#ifdef WMMSG_DEBUG
|
||||
fprintf(stderr, "Received windows message: ");
|
||||
if (msg > MAX_WMMSG) {
|
||||
fprintf(stderr, "%d", msg);
|
||||
} else {
|
||||
fprintf(stderr, "%s", wmtab[msg]);
|
||||
}
|
||||
fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam);
|
||||
#endif
|
||||
switch (msg) {
|
||||
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
SDL_VideoDevice *this = current_video;
|
||||
BOOL minimized;
|
||||
Uint8 appstate;
|
||||
|
||||
minimized = HIWORD(wParam);
|
||||
if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
|
||||
/* Gain the following states */
|
||||
appstate = SDL_APPACTIVE | SDL_APPINPUTFOCUS;
|
||||
if (this->input_grab != SDL_GRAB_OFF) {
|
||||
WIN_GrabInput(this, SDL_GRAB_ON);
|
||||
}
|
||||
if (!(SDL_GetAppState() & SDL_APPINPUTFOCUS)) {
|
||||
if (!DDRAW_FULLSCREEN()) {
|
||||
DIB_SwapGamma(this);
|
||||
}
|
||||
if (WINDIB_FULLSCREEN()) {
|
||||
SDL_RestoreGameMode();
|
||||
}
|
||||
}
|
||||
#if defined(_WIN32_WCE)
|
||||
if (WINDIB_FULLSCREEN()) {
|
||||
LoadAygshell();
|
||||
if (SHFullScreen)
|
||||
SHFullScreen(SDL_Window,
|
||||
SHFS_HIDESTARTICON |
|
||||
SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
|
||||
else
|
||||
ShowWindow(FindWindow
|
||||
(TEXT("HHTaskBar"), NULL), SW_HIDE);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
posted = SDL_PrivateAppActive(1, appstate);
|
||||
WIN_GetKeyboardState();
|
||||
} else {
|
||||
/* Lose the following states */
|
||||
appstate = SDL_APPINPUTFOCUS;
|
||||
if (minimized) {
|
||||
appstate |= SDL_APPACTIVE;
|
||||
}
|
||||
if (this->input_grab != SDL_GRAB_OFF) {
|
||||
WIN_GrabInput(this, SDL_GRAB_OFF);
|
||||
}
|
||||
if (SDL_GetAppState() & SDL_APPINPUTFOCUS) {
|
||||
if (!DDRAW_FULLSCREEN()) {
|
||||
DIB_SwapGamma(this);
|
||||
}
|
||||
if (WINDIB_FULLSCREEN()) {
|
||||
SDL_RestoreDesktopMode();
|
||||
#if defined(_WIN32_WCE)
|
||||
LoadAygshell();
|
||||
if (SHFullScreen)
|
||||
SHFullScreen(SDL_Window,
|
||||
SHFS_SHOWSTARTICON |
|
||||
SHFS_SHOWTASKBAR |
|
||||
SHFS_SHOWSIPBUTTON);
|
||||
else
|
||||
ShowWindow(FindWindow
|
||||
(TEXT("HHTaskBar"), NULL), SW_SHOW);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
posted = SDL_PrivateAppActive(0, appstate);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
|
||||
/* Mouse is handled by DirectInput when fullscreen */
|
||||
if (SDL_VideoSurface && !DINPUT_FULLSCREEN()) {
|
||||
Sint16 x, y;
|
||||
|
||||
/* mouse has entered the window */
|
||||
if (!in_window) {
|
||||
#ifdef WM_MOUSELEAVE
|
||||
TRACKMOUSEEVENT tme;
|
||||
|
||||
tme.cbSize = sizeof(tme);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = SDL_Window;
|
||||
_TrackMouseEvent(&tme);
|
||||
#endif /* WM_MOUSELEAVE */
|
||||
in_window = TRUE;
|
||||
|
||||
posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
|
||||
}
|
||||
|
||||
/* mouse has moved within the window */
|
||||
x = LOWORD(lParam);
|
||||
y = HIWORD(lParam);
|
||||
if (mouse_relative) {
|
||||
POINT center;
|
||||
center.x = (SDL_VideoSurface->w / 2);
|
||||
center.y = (SDL_VideoSurface->h / 2);
|
||||
x -= (Sint16) center.x;
|
||||
y -= (Sint16) center.y;
|
||||
if (x || y) {
|
||||
ClientToScreen(SDL_Window, ¢er);
|
||||
SetCursorPos(center.x, center.y);
|
||||
posted = SDL_PrivateMouseMotion(0, 1, x, y);
|
||||
}
|
||||
} else {
|
||||
#ifdef _WIN32_WCE
|
||||
if (SDL_VideoSurface)
|
||||
GapiTransform(this->hidden->userOrientation,
|
||||
this->hidden->hiresFix, &x, &y);
|
||||
#endif
|
||||
posted = SDL_PrivateMouseMotion(0, 0, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
|
||||
#ifdef WM_MOUSELEAVE
|
||||
case WM_MOUSELEAVE:
|
||||
{
|
||||
|
||||
/* Mouse is handled by DirectInput when fullscreen */
|
||||
if (SDL_VideoSurface && !DINPUT_FULLSCREEN()) {
|
||||
/* mouse has left the window */
|
||||
/* or */
|
||||
/* Elvis has left the building! */
|
||||
posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
|
||||
}
|
||||
in_window = FALSE;
|
||||
}
|
||||
return (0);
|
||||
#endif /* WM_MOUSELEAVE */
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
/* Mouse is handled by DirectInput when fullscreen */
|
||||
if (SDL_VideoSurface && !DINPUT_FULLSCREEN()) {
|
||||
Sint16 x, y;
|
||||
Uint8 button, state;
|
||||
|
||||
/* DJM:
|
||||
We want the SDL window to take focus so that
|
||||
it acts like a normal windows "component"
|
||||
(e.g. gains keyboard focus on a mouse click).
|
||||
*/
|
||||
SetFocus(SDL_Window);
|
||||
|
||||
/* Figure out which button to use */
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
button = SDL_BUTTON_LEFT;
|
||||
state = SDL_PRESSED;
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
button = SDL_BUTTON_LEFT;
|
||||
state = SDL_RELEASED;
|
||||
break;
|
||||
case WM_MBUTTONDOWN:
|
||||
button = SDL_BUTTON_MIDDLE;
|
||||
state = SDL_PRESSED;
|
||||
break;
|
||||
case WM_MBUTTONUP:
|
||||
button = SDL_BUTTON_MIDDLE;
|
||||
state = SDL_RELEASED;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
button = SDL_BUTTON_RIGHT;
|
||||
state = SDL_PRESSED;
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
button = SDL_BUTTON_RIGHT;
|
||||
state = SDL_RELEASED;
|
||||
break;
|
||||
default:
|
||||
/* Eh? Unknown button? */
|
||||
return (0);
|
||||
}
|
||||
if (state == SDL_PRESSED) {
|
||||
/* Grab mouse so we get up events */
|
||||
if (++mouse_pressed > 0) {
|
||||
SetCapture(hwnd);
|
||||
}
|
||||
} else {
|
||||
/* Release mouse after all up events */
|
||||
if (--mouse_pressed <= 0) {
|
||||
ReleaseCapture();
|
||||
mouse_pressed = 0;
|
||||
}
|
||||
}
|
||||
if (mouse_relative) {
|
||||
/* RJR: March 28, 2000
|
||||
report internal mouse position if in relative mode */
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
x = (Sint16) LOWORD(lParam);
|
||||
y = (Sint16) HIWORD(lParam);
|
||||
#ifdef _WIN32_WCE
|
||||
if (SDL_VideoSurface)
|
||||
GapiTransform(this->hidden->userOrientation,
|
||||
this->hidden->hiresFix, &x, &y);
|
||||
#endif
|
||||
}
|
||||
posted = SDL_PrivateMouseButton(state, button, x, y);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
|
||||
case WM_MOUSEWHEEL:
|
||||
if (SDL_VideoSurface && !DINPUT_FULLSCREEN()) {
|
||||
int move = (short) HIWORD(wParam);
|
||||
if (move) {
|
||||
Uint8 button;
|
||||
if (move > 0)
|
||||
button = SDL_BUTTON_WHEELUP;
|
||||
else
|
||||
button = SDL_BUTTON_WHEELDOWN;
|
||||
posted = SDL_PrivateMouseButton(SDL_PRESSED, button, 0, 0);
|
||||
posted |= SDL_PrivateMouseButton(SDL_RELEASED, button, 0, 0);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
#ifdef WM_GETMINMAXINFO
|
||||
/* This message is sent as a way for us to "check" the values
|
||||
* of a position change. If we don't like it, we can adjust
|
||||
* the values before they are changed.
|
||||
*/
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
MINMAXINFO *info;
|
||||
RECT size;
|
||||
int x, y;
|
||||
int style;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/* We don't want to clobber an internal resize */
|
||||
if (SDL_resizing)
|
||||
return (0);
|
||||
|
||||
/* We allow resizing with the SDL_RESIZABLE flag */
|
||||
if (SDL_PublicSurface &&
|
||||
(SDL_PublicSurface->flags & SDL_RESIZABLE)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Get the current position of our window */
|
||||
GetWindowRect(SDL_Window, &size);
|
||||
x = size.left;
|
||||
y = size.top;
|
||||
|
||||
/* Calculate current width and height of our window */
|
||||
size.top = 0;
|
||||
size.left = 0;
|
||||
if (SDL_PublicSurface != NULL) {
|
||||
size.bottom = SDL_PublicSurface->h;
|
||||
size.right = SDL_PublicSurface->w;
|
||||
} else {
|
||||
size.bottom = 0;
|
||||
size.right = 0;
|
||||
}
|
||||
|
||||
/* DJM - according to the docs for GetMenu(), the
|
||||
return value is undefined if hwnd is a child window.
|
||||
Aparently it's too difficult for MS to check
|
||||
inside their function, so I have to do it here.
|
||||
*/
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
AdjustWindowRect(&size,
|
||||
style,
|
||||
style & WS_CHILDWINDOW ? FALSE
|
||||
: GetMenu(hwnd) != NULL);
|
||||
|
||||
width = size.right - size.left;
|
||||
height = size.bottom - size.top;
|
||||
|
||||
/* Fix our size to the current size */
|
||||
info = (MINMAXINFO *) lParam;
|
||||
info->ptMaxSize.x = width;
|
||||
info->ptMaxSize.y = height;
|
||||
info->ptMaxPosition.x = x;
|
||||
info->ptMaxPosition.y = y;
|
||||
info->ptMinTrackSize.x = width;
|
||||
info->ptMinTrackSize.y = height;
|
||||
info->ptMaxTrackSize.x = width;
|
||||
info->ptMaxTrackSize.y = height;
|
||||
}
|
||||
return (0);
|
||||
#endif /* WM_GETMINMAXINFO */
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
SDL_VideoDevice *this = current_video;
|
||||
int w, h;
|
||||
|
||||
GetClientRect(SDL_Window, &SDL_bounds);
|
||||
ClientToScreen(SDL_Window, (LPPOINT) & SDL_bounds);
|
||||
ClientToScreen(SDL_Window, (LPPOINT) & SDL_bounds + 1);
|
||||
if (!SDL_resizing && !IsZoomed(SDL_Window) &&
|
||||
SDL_PublicSurface &&
|
||||
!(SDL_PublicSurface->flags & SDL_FULLSCREEN)) {
|
||||
SDL_windowX = SDL_bounds.left;
|
||||
SDL_windowY = SDL_bounds.top;
|
||||
}
|
||||
w = SDL_bounds.right - SDL_bounds.left;
|
||||
h = SDL_bounds.bottom - SDL_bounds.top;
|
||||
if (this->input_grab != SDL_GRAB_OFF) {
|
||||
ClipCursor(&SDL_bounds);
|
||||
}
|
||||
if (SDL_PublicSurface &&
|
||||
(SDL_PublicSurface->flags & SDL_RESIZABLE)) {
|
||||
SDL_PrivateResize(w, h);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* We need to set the cursor */
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
Uint16 hittest;
|
||||
|
||||
hittest = LOWORD(lParam);
|
||||
if (hittest == HTCLIENT) {
|
||||
SetCursor(SDL_hcursor);
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* We are about to get palette focus! */
|
||||
case WM_QUERYNEWPALETTE:
|
||||
{
|
||||
WIN_RealizePalette(current_video);
|
||||
return (TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Another application changed the palette */
|
||||
case WM_PALETTECHANGED:
|
||||
{
|
||||
WIN_PaletteChanged(current_video, (HWND) wParam);
|
||||
}
|
||||
break;
|
||||
|
||||
/* We were occluded, refresh our display */
|
||||
case WM_PAINT:
|
||||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
|
||||
hdc = BeginPaint(SDL_Window, &ps);
|
||||
if (current_video->screen &&
|
||||
!(current_video->screen->flags & SDL_INTERNALOPENGL)) {
|
||||
WIN_WinPAINT(current_video, hdc);
|
||||
}
|
||||
EndPaint(SDL_Window, &ps);
|
||||
}
|
||||
return (0);
|
||||
|
||||
/* DJM: Send an expose event in this case */
|
||||
case WM_ERASEBKGND:
|
||||
{
|
||||
posted = SDL_PrivateExpose();
|
||||
}
|
||||
return (0);
|
||||
|
||||
case WM_CLOSE:
|
||||
{
|
||||
if ((posted = SDL_PrivateQuit()))
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
return (0);
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
return (0);
|
||||
|
||||
#ifndef NO_GETKEYBOARDSTATE
|
||||
case WM_INPUTLANGCHANGE:
|
||||
{
|
||||
codepage = GetCodePage();
|
||||
}
|
||||
return (TRUE);
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
/* Special handling by the video driver */
|
||||
if (HandleMessage) {
|
||||
return (HandleMessage(current_video,
|
||||
hwnd, msg, wParam, lParam));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (DefWindowProc(hwnd, msg, wParam, lParam));
|
||||
}
|
||||
|
||||
/* Allow the application handle to be stored and retrieved later */
|
||||
static void *SDL_handle = NULL;
|
||||
|
||||
void
|
||||
SDL_SetModuleHandle(void *handle)
|
||||
{
|
||||
SDL_handle = handle;
|
||||
}
|
||||
|
||||
void *
|
||||
SDL_GetModuleHandle(void)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
if (SDL_handle) {
|
||||
handle = SDL_handle;
|
||||
} else {
|
||||
handle = GetModuleHandle(NULL);
|
||||
}
|
||||
return (handle);
|
||||
}
|
||||
|
||||
/* This allows the SDL_WINDOWID hack */
|
||||
BOOL SDL_windowid = FALSE;
|
||||
|
||||
static int app_registered = 0;
|
||||
|
||||
/* Register the class for this application -- exported for winmain.c */
|
||||
int
|
||||
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
|
||||
{
|
||||
WNDCLASS class;
|
||||
#ifdef WM_MOUSELEAVE
|
||||
HMODULE handle;
|
||||
#endif
|
||||
|
||||
/* Only do this once... */
|
||||
if (app_registered) {
|
||||
++app_registered;
|
||||
return (0);
|
||||
}
|
||||
#ifndef CS_BYTEALIGNCLIENT
|
||||
#define CS_BYTEALIGNCLIENT 0
|
||||
#endif
|
||||
if (!name && !SDL_Appname) {
|
||||
name = "SDL_app";
|
||||
SDL_Appstyle = CS_BYTEALIGNCLIENT;
|
||||
SDL_Instance = hInst ? hInst : SDL_GetModuleHandle();
|
||||
}
|
||||
|
||||
if (name) {
|
||||
#ifdef _WIN32_WCE
|
||||
/* WinCE uses the UNICODE version */
|
||||
SDL_Appname = SDL_iconv_utf8_ucs2(name);
|
||||
#else
|
||||
SDL_Appname = SDL_iconv_utf8_latin1(name);
|
||||
#endif /* _WIN32_WCE */
|
||||
SDL_Appstyle = style;
|
||||
SDL_Instance = hInst ? hInst : SDL_GetModuleHandle();
|
||||
}
|
||||
|
||||
/* Register the application class */
|
||||
class.hCursor = NULL;
|
||||
class.hIcon = LoadImage(SDL_Instance, SDL_Appname,
|
||||
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
class.lpszMenuName = NULL;
|
||||
class.lpszClassName = SDL_Appname;
|
||||
class.hbrBackground = NULL;
|
||||
class.hInstance = SDL_Instance;
|
||||
class.style = SDL_Appstyle;
|
||||
#if SDL_VIDEO_OPENGL
|
||||
class.style |= CS_OWNDC;
|
||||
#endif
|
||||
class.lpfnWndProc = WinMessage;
|
||||
class.cbWndExtra = 0;
|
||||
class.cbClsExtra = 0;
|
||||
if (!RegisterClass(&class)) {
|
||||
SDL_SetError("Couldn't register application class");
|
||||
return (-1);
|
||||
}
|
||||
#ifdef WM_MOUSELEAVE
|
||||
/* Get the version of TrackMouseEvent() we use */
|
||||
_TrackMouseEvent = NULL;
|
||||
handle = GetModuleHandle("USER32.DLL");
|
||||
if (handle) {
|
||||
_TrackMouseEvent =
|
||||
(BOOL(WINAPI *) (TRACKMOUSEEVENT *)) GetProcAddress(handle,
|
||||
"TrackMouseEvent");
|
||||
}
|
||||
if (_TrackMouseEvent == NULL) {
|
||||
_TrackMouseEvent = WIN_TrackMouseEvent;
|
||||
}
|
||||
#endif /* WM_MOUSELEAVE */
|
||||
|
||||
#ifndef NO_GETKEYBOARDSTATE
|
||||
/* Initialise variables for SDL_ToUnicode() */
|
||||
codepage = GetCodePage();
|
||||
SDL_ToUnicode = Is9xME()? ToUnicode9xME : ToUnicode;
|
||||
#endif
|
||||
|
||||
app_registered = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Unregisters the windowclass registered in SDL_RegisterApp above. */
|
||||
void
|
||||
SDL_UnregisterApp()
|
||||
{
|
||||
WNDCLASS class;
|
||||
|
||||
/* SDL_RegisterApp might not have been called before */
|
||||
if (!app_registered) {
|
||||
return;
|
||||
}
|
||||
--app_registered;
|
||||
if (app_registered == 0) {
|
||||
/* Check for any registered window classes. */
|
||||
if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
|
||||
UnregisterClass(SDL_Appname, SDL_Instance);
|
||||
}
|
||||
SDL_free(SDL_Appname);
|
||||
SDL_Appname = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NO_GETKEYBOARDSTATE
|
||||
/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */
|
||||
|
||||
static int
|
||||
Is9xME()
|
||||
{
|
||||
OSVERSIONINFO info;
|
||||
|
||||
SDL_memset(&info, 0, sizeof(info));
|
||||
info.dwOSVersionInfoSize = sizeof(info);
|
||||
if (!GetVersionEx(&info)) {
|
||||
return 0;
|
||||
}
|
||||
return (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
|
||||
}
|
||||
|
||||
static int
|
||||
GetCodePage()
|
||||
{
|
||||
char buff[8];
|
||||
int lcid = MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT);
|
||||
int cp = GetACP();
|
||||
|
||||
if (GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, buff, sizeof(buff))) {
|
||||
cp = SDL_atoi(buff);
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
static int WINAPI
|
||||
ToUnicode9xME(UINT vkey, UINT scancode, PBYTE keystate, LPWSTR wchars,
|
||||
int wsize, UINT flags)
|
||||
{
|
||||
BYTE chars[2];
|
||||
|
||||
if (ToAsciiEx
|
||||
(vkey, scancode, keystate, (WORD *) chars, 0,
|
||||
GetKeyboardLayout(0)) == 1) {
|
||||
return MultiByteToWideChar(codepage, 0, chars, 1, wchars, wsize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !NO_GETKEYBOARDSTATE */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,274 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "SDL_mouse.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../SDL_cursor_c.h"
|
||||
#include "SDL_sysmouse_c.h"
|
||||
#include "SDL_lowvideo.h"
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#define USE_STATIC_CURSOR
|
||||
#endif
|
||||
|
||||
HCURSOR SDL_hcursor = NULL; /* Exported for SDL_eventloop.c */
|
||||
|
||||
/* The implementation dependent data for the window manager cursor */
|
||||
/* For some reason when creating a windows cursor, the ands and xors memory
|
||||
is not copied, so we need to keep track of it and free it when we are done
|
||||
with the cursor. If we free the memory prematurely, the app crashes. :-}
|
||||
*/
|
||||
struct WMcursor
|
||||
{
|
||||
HCURSOR curs;
|
||||
#ifndef USE_STATIC_CURSOR
|
||||
Uint8 *ands;
|
||||
Uint8 *xors;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Convert bits to padded bytes */
|
||||
#define PAD_BITS(bits) ((bits+7)/8)
|
||||
|
||||
#ifdef CURSOR_DEBUG
|
||||
static void
|
||||
PrintBITMAP(FILE * out, char *bits, int w, int h)
|
||||
{
|
||||
int i;
|
||||
unsigned char ch;
|
||||
|
||||
while (h-- > 0) {
|
||||
for (i = 0; i < w; ++i) {
|
||||
if ((i % 8) == 0)
|
||||
ch = *bits++;
|
||||
if (ch & 0x80)
|
||||
fprintf(out, "X");
|
||||
else
|
||||
fprintf(out, " ");
|
||||
ch <<= 1;
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_STATIC_CURSOR
|
||||
/* Local functions to convert the SDL cursor mask into Windows format */
|
||||
static void
|
||||
memnot(Uint8 * dst, Uint8 * src, int len)
|
||||
{
|
||||
while (len-- > 0)
|
||||
*dst++ = ~*src++;
|
||||
}
|
||||
static void
|
||||
memxor(Uint8 * dst, Uint8 * src1, Uint8 * src2, int len)
|
||||
{
|
||||
while (len-- > 0)
|
||||
*dst++ = (*src1++) ^ (*src2++);
|
||||
}
|
||||
#endif /* !USE_STATIC_CURSOR */
|
||||
|
||||
void
|
||||
WIN_FreeWMCursor(_THIS, WMcursor * cursor)
|
||||
{
|
||||
#ifndef USE_STATIC_CURSOR
|
||||
if (cursor->curs == GetCursor())
|
||||
SetCursor(NULL);
|
||||
if (cursor->curs != NULL)
|
||||
DestroyCursor(cursor->curs);
|
||||
if (cursor->ands != NULL)
|
||||
SDL_free(cursor->ands);
|
||||
if (cursor->xors != NULL)
|
||||
SDL_free(cursor->xors);
|
||||
#endif /* !USE_STATIC_CURSOR */
|
||||
SDL_free(cursor);
|
||||
}
|
||||
|
||||
WMcursor *
|
||||
WIN_CreateWMCursor(_THIS,
|
||||
Uint8 * data, Uint8 * mask, int w, int h, int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
#ifdef USE_STATIC_CURSOR
|
||||
WMcursor *cursor;
|
||||
|
||||
/* Allocate the cursor */
|
||||
cursor = (WMcursor *) SDL_malloc(sizeof(*cursor));
|
||||
if (cursor) {
|
||||
cursor->curs = LoadCursor(NULL, IDC_ARROW);
|
||||
}
|
||||
return (cursor);
|
||||
#else
|
||||
WMcursor *cursor;
|
||||
int allowed_x;
|
||||
int allowed_y;
|
||||
int run, pad, i;
|
||||
Uint8 *aptr, *xptr;
|
||||
|
||||
/* Check to make sure the cursor size is okay */
|
||||
allowed_x = GetSystemMetrics(SM_CXCURSOR);
|
||||
allowed_y = GetSystemMetrics(SM_CYCURSOR);
|
||||
if ((w > allowed_x) || (h > allowed_y)) {
|
||||
SDL_SetError("Only cursors of dimension (%dx%d) are allowed",
|
||||
allowed_x, allowed_y);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Allocate the cursor */
|
||||
cursor = (WMcursor *) SDL_malloc(sizeof(*cursor));
|
||||
if (cursor == NULL) {
|
||||
SDL_SetError("Out of memory");
|
||||
return (NULL);
|
||||
}
|
||||
cursor->curs = NULL;
|
||||
cursor->ands = NULL;
|
||||
cursor->xors = NULL;
|
||||
|
||||
/* Pad out to the normal cursor size */
|
||||
run = PAD_BITS(w);
|
||||
pad = PAD_BITS(allowed_x) - run;
|
||||
aptr = cursor->ands = (Uint8 *) SDL_malloc((run + pad) * allowed_y);
|
||||
xptr = cursor->xors = (Uint8 *) SDL_malloc((run + pad) * allowed_y);
|
||||
if ((aptr == NULL) || (xptr == NULL)) {
|
||||
WIN_FreeWMCursor(NULL, cursor);
|
||||
SDL_OutOfMemory();
|
||||
return (NULL);
|
||||
}
|
||||
for (i = 0; i < h; ++i) {
|
||||
memxor(xptr, data, mask, run);
|
||||
xptr += run;
|
||||
data += run;
|
||||
memnot(aptr, mask, run);
|
||||
mask += run;
|
||||
aptr += run;
|
||||
SDL_memset(xptr, 0, pad);
|
||||
xptr += pad;
|
||||
SDL_memset(aptr, ~0, pad);
|
||||
aptr += pad;
|
||||
}
|
||||
pad += run;
|
||||
for (; i < allowed_y; ++i) {
|
||||
SDL_memset(xptr, 0, pad);
|
||||
xptr += pad;
|
||||
SDL_memset(aptr, ~0, pad);
|
||||
aptr += pad;
|
||||
}
|
||||
|
||||
/* Create the cursor */
|
||||
cursor->curs = CreateCursor((HINSTANCE)
|
||||
GetWindowLongPtr(SDL_Window,
|
||||
GWLP_HINSTANCE), hot_x,
|
||||
hot_y, allowed_x, allowed_y, cursor->ands,
|
||||
cursor->xors);
|
||||
if (cursor->curs == NULL) {
|
||||
WIN_FreeWMCursor(NULL, cursor);
|
||||
SDL_SetError("Windows couldn't create the requested cursor");
|
||||
return (NULL);
|
||||
}
|
||||
return (cursor);
|
||||
#endif /* USE_STATIC_CURSOR */
|
||||
}
|
||||
|
||||
int
|
||||
WIN_ShowWMCursor(_THIS, WMcursor * cursor)
|
||||
{
|
||||
POINT mouse_pos;
|
||||
|
||||
/* The fullscreen cursor must be done in software with DirectInput */
|
||||
if (!this->screen || DDRAW_FULLSCREEN()) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Set the window cursor to our cursor, if applicable */
|
||||
if (cursor != NULL) {
|
||||
SDL_hcursor = cursor->curs;
|
||||
} else {
|
||||
SDL_hcursor = NULL;
|
||||
}
|
||||
GetCursorPos(&mouse_pos);
|
||||
if (PtInRect(&SDL_bounds, mouse_pos)) {
|
||||
SetCursor(SDL_hcursor);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
|
||||
{
|
||||
if (DDRAW_FULLSCREEN()) {
|
||||
SDL_PrivateMouseMotion(0, 0, x, y);
|
||||
} else if (mouse_relative) {
|
||||
/* RJR: March 28, 2000
|
||||
leave physical cursor at center of screen if
|
||||
mouse hidden and grabbed */
|
||||
SDL_PrivateMouseMotion(0, 0, x, y);
|
||||
} else {
|
||||
POINT pt;
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
ClientToScreen(SDL_Window, &pt);
|
||||
SetCursorPos(pt.x, pt.y);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the current mouse state and position */
|
||||
void
|
||||
WIN_UpdateMouse(_THIS)
|
||||
{
|
||||
RECT rect;
|
||||
POINT pt;
|
||||
|
||||
if (!DDRAW_FULLSCREEN()) {
|
||||
GetClientRect(SDL_Window, &rect);
|
||||
GetCursorPos(&pt);
|
||||
MapWindowPoints(NULL, SDL_Window, &pt, 1);
|
||||
if (PtInRect(&rect, pt) && (WindowFromPoint(pt) == SDL_Window)) {
|
||||
SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
|
||||
SDL_PrivateMouseMotion(0, 0, (Sint16) pt.x, (Sint16) pt.y);
|
||||
} else {
|
||||
SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if we need to enter or leave mouse relative mode */
|
||||
void
|
||||
WIN_CheckMouseMode(_THIS)
|
||||
{
|
||||
#ifndef _WIN32_WCE
|
||||
/* 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;
|
||||
}
|
||||
#else
|
||||
mouse_relative = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#include "SDL_lowvideo.h"
|
||||
|
||||
/* Functions to be exported */
|
||||
extern void WIN_FreeWMCursor(_THIS, WMcursor * cursor);
|
||||
extern WMcursor *WIN_CreateWMCursor(_THIS,
|
||||
Uint8 * data, Uint8 * mask, int w, int h,
|
||||
int hot_x, int hot_y);
|
||||
extern int WIN_ShowWMCursor(_THIS, WMcursor * cursor);
|
||||
extern void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
|
||||
extern void WIN_UpdateMouse(_THIS);
|
||||
extern void WIN_CheckMouseMode(_THIS);
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,334 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "SDL_version.h"
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_loadso.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include "../SDL_pixels_c.h"
|
||||
#include "../SDL_cursor_c.h"
|
||||
#include "SDL_syswm_c.h"
|
||||
#include "SDL_wingl_c.h"
|
||||
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#define DISABLE_ICON_SUPPORT
|
||||
#endif
|
||||
|
||||
/* The screen icon -- needs to be freed on SDL_VideoQuit() */
|
||||
HICON screen_icn = NULL;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
|
||||
BOOL(WINAPI * CoreCatchInput) (int flag) = NULL;
|
||||
int input_catched = 0;
|
||||
HINSTANCE coredll = NULL;
|
||||
|
||||
// the same API call that gx.dll does to catch the input
|
||||
void
|
||||
LoadInputCatchFunc()
|
||||
{
|
||||
coredll = SDL_LoadObject("coredll.dll");
|
||||
if (coredll) {
|
||||
CoreCatchInput =
|
||||
(int (WINAPI *) (int)) GetProcAddress(coredll,
|
||||
(const unsigned short *)
|
||||
1453);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Win32 icon mask semantics are different from those of SDL:
|
||||
SDL applies the mask to the icon and copies result to desktop.
|
||||
Win32 applies the mask to the desktop and XORs the icon on.
|
||||
This means that the SDL mask needs to be applied to the icon and
|
||||
then inverted and passed to Win32.
|
||||
*/
|
||||
void
|
||||
WIN_SetWMIcon(_THIS, SDL_Surface * icon, Uint8 * mask)
|
||||
{
|
||||
#ifdef DISABLE_ICON_SUPPORT
|
||||
return;
|
||||
#else
|
||||
SDL_Palette *pal_256;
|
||||
SDL_Surface *icon_256;
|
||||
Uint8 *pdata, *pwin32;
|
||||
Uint8 *mdata, *mwin32, m = 0;
|
||||
int icon_len;
|
||||
int icon_plen;
|
||||
int icon_mlen;
|
||||
int icon_pitch;
|
||||
int mask_pitch;
|
||||
SDL_Rect bounds;
|
||||
int i, skip;
|
||||
int row, col;
|
||||
struct /* quasi-BMP format */ Win32Icon
|
||||
{
|
||||
Uint32 biSize;
|
||||
Sint32 biWidth;
|
||||
Sint32 biHeight;
|
||||
Uint16 biPlanes;
|
||||
Uint16 biBitCount;
|
||||
Uint32 biCompression;
|
||||
Uint32 biSizeImage;
|
||||
Sint32 biXPelsPerMeter;
|
||||
Sint32 biYPelsPerMeter;
|
||||
Uint32 biClrUsed;
|
||||
Uint32 biClrImportant;
|
||||
struct /* RGBQUAD -- note it's BGR ordered */
|
||||
{
|
||||
Uint8 rgbBlue;
|
||||
Uint8 rgbGreen;
|
||||
Uint8 rgbRed;
|
||||
Uint8 rgbReserved;
|
||||
} biColors[256];
|
||||
/* Pixels:
|
||||
Uint8 pixels[]
|
||||
*/
|
||||
/* Mask:
|
||||
Uint8 mask[]
|
||||
*/
|
||||
} *icon_win32;
|
||||
|
||||
/* Allocate the win32 bmp icon and set everything to zero */
|
||||
icon_pitch = ((icon->w + 3) & ~3);
|
||||
mask_pitch = ((icon->w + 7) / 8);
|
||||
icon_plen = icon->h * icon_pitch;
|
||||
icon_mlen = icon->h * mask_pitch;
|
||||
icon_len = sizeof(*icon_win32) + icon_plen + icon_mlen;
|
||||
icon_win32 = (struct Win32Icon *) SDL_stack_alloc(Uint8, icon_len);
|
||||
if (icon_win32 == NULL) {
|
||||
return;
|
||||
}
|
||||
SDL_memset(icon_win32, 0, icon_len);
|
||||
|
||||
/* Set the basic BMP parameters */
|
||||
icon_win32->biSize = sizeof(*icon_win32) - sizeof(icon_win32->biColors);
|
||||
icon_win32->biWidth = icon->w;
|
||||
icon_win32->biHeight = icon->h * 2;
|
||||
icon_win32->biPlanes = 1;
|
||||
icon_win32->biBitCount = 8;
|
||||
icon_win32->biSizeImage = icon_plen + icon_mlen;
|
||||
|
||||
/* Allocate a standard 256 color icon surface */
|
||||
icon_256 = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
|
||||
icon_win32->biBitCount, 0, 0, 0, 0);
|
||||
if (icon_256 == NULL) {
|
||||
SDL_stack_free(icon_win32);
|
||||
return;
|
||||
}
|
||||
pal_256 = icon_256->format->palette;
|
||||
if (icon->format->palette &&
|
||||
(icon->format->BitsPerPixel == icon_256->format->BitsPerPixel)) {
|
||||
Uint8 black;
|
||||
SDL_memcpy(pal_256->colors, icon->format->palette->colors,
|
||||
pal_256->ncolors * sizeof(SDL_Color));
|
||||
/* Make sure that 0 is black! */
|
||||
black = SDL_FindColor(pal_256, 0x00, 0x00, 0x00);
|
||||
pal_256->colors[black] = pal_256->colors[0];
|
||||
pal_256->colors[0].r = 0x00;
|
||||
pal_256->colors[0].g = 0x00;
|
||||
pal_256->colors[0].b = 0x00;
|
||||
} else {
|
||||
SDL_DitherColors(pal_256->colors, icon_256->format->BitsPerPixel);
|
||||
}
|
||||
|
||||
/* Now copy color data to the icon BMP */
|
||||
for (i = 0; i < (1 << icon_win32->biBitCount); ++i) {
|
||||
icon_win32->biColors[i].rgbRed = pal_256->colors[i].r;
|
||||
icon_win32->biColors[i].rgbGreen = pal_256->colors[i].g;
|
||||
icon_win32->biColors[i].rgbBlue = pal_256->colors[i].b;
|
||||
}
|
||||
|
||||
/* Convert icon to a standard surface format. This may not always
|
||||
be necessary, as Windows supports a variety of BMP formats, but
|
||||
it greatly simplifies our code.
|
||||
*/
|
||||
bounds.x = 0;
|
||||
bounds.y = 0;
|
||||
bounds.w = icon->w;
|
||||
bounds.h = icon->h;
|
||||
if (SDL_LowerBlit(icon, &bounds, icon_256, &bounds) < 0) {
|
||||
SDL_stack_free(icon_win32);
|
||||
SDL_FreeSurface(icon_256);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy pixels upside-down to icon BMP, masked with the icon mask */
|
||||
if (SDL_MUSTLOCK(icon_256) || (icon_256->pitch != icon_pitch)) {
|
||||
SDL_stack_free(icon_win32);
|
||||
SDL_FreeSurface(icon_256);
|
||||
SDL_SetError("Warning: Unexpected icon_256 characteristics");
|
||||
return;
|
||||
}
|
||||
pdata = (Uint8 *) icon_256->pixels;
|
||||
mdata = mask;
|
||||
pwin32 =
|
||||
(Uint8 *) icon_win32 + sizeof(*icon_win32) + icon_plen - icon_pitch;
|
||||
skip = icon_pitch - icon->w;
|
||||
for (row = 0; row < icon->h; ++row) {
|
||||
for (col = 0; col < icon->w; ++col) {
|
||||
if ((col % 8) == 0) {
|
||||
m = *mdata++;
|
||||
}
|
||||
if ((m & 0x80) != 0x00) {
|
||||
*pwin32 = *pdata;
|
||||
}
|
||||
m <<= 1;
|
||||
++pdata;
|
||||
++pwin32;
|
||||
}
|
||||
pdata += skip;
|
||||
pwin32 += skip;
|
||||
pwin32 -= 2 * icon_pitch;
|
||||
}
|
||||
SDL_FreeSurface(icon_256);
|
||||
|
||||
/* Copy mask inverted and upside-down to icon BMP */
|
||||
mdata = mask;
|
||||
mwin32 = (Uint8 *) icon_win32
|
||||
+ sizeof(*icon_win32) + icon_plen + icon_mlen - mask_pitch;
|
||||
for (row = 0; row < icon->h; ++row) {
|
||||
for (col = 0; col < mask_pitch; ++col) {
|
||||
*mwin32++ = ~*mdata++;
|
||||
}
|
||||
mwin32 -= 2 * mask_pitch;
|
||||
}
|
||||
|
||||
/* Finally, create the icon handle and set the window icon */
|
||||
screen_icn = CreateIconFromResourceEx((Uint8 *) icon_win32, icon_len,
|
||||
TRUE, 0x00030000, icon->w, icon->h,
|
||||
LR_DEFAULTCOLOR);
|
||||
if (screen_icn == NULL) {
|
||||
SDL_SetError("Couldn't create Win32 icon handle");
|
||||
} else {
|
||||
SetClassLongPtr(SDL_Window, GCLP_HICON, (LONG_PTR) screen_icn);
|
||||
}
|
||||
SDL_stack_free(icon_win32);
|
||||
#endif /* DISABLE_ICON_SUPPORT */
|
||||
}
|
||||
|
||||
void
|
||||
WIN_SetWMCaption(_THIS, const char *title, const char *icon)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
/* WinCE uses the UNICODE version */
|
||||
LPWSTR lpszW = SDL_iconv_utf8_ucs2((char *) title);
|
||||
SetWindowText(SDL_Window, lpszW);
|
||||
SDL_free(lpszW);
|
||||
#else
|
||||
char *lpsz = SDL_iconv_utf8_latin1((char *) title);
|
||||
SetWindowText(SDL_Window, lpsz);
|
||||
SDL_free(lpsz);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
WIN_IconifyWindow(_THIS)
|
||||
{
|
||||
ShowWindow(SDL_Window, SW_MINIMIZE);
|
||||
return (1);
|
||||
}
|
||||
|
||||
SDL_GrabMode
|
||||
WIN_GrabInput(_THIS, SDL_GrabMode mode)
|
||||
{
|
||||
if (mode == SDL_GRAB_OFF) {
|
||||
ClipCursor(NULL);
|
||||
if (!(SDL_cursorstate & CURSOR_VISIBLE)) {
|
||||
/* RJR: March 28, 2000
|
||||
must be leaving relative mode, move mouse from
|
||||
center of window to where it belongs ... */
|
||||
POINT pt;
|
||||
int x, y;
|
||||
SDL_GetMouseState(&x, &y);
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
ClientToScreen(SDL_Window, &pt);
|
||||
SetCursorPos(pt.x, pt.y);
|
||||
}
|
||||
#ifdef _WIN32_WCE
|
||||
if (input_catched) {
|
||||
if (!CoreCatchInput)
|
||||
LoadInputCatchFunc();
|
||||
|
||||
if (CoreCatchInput)
|
||||
CoreCatchInput(0);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
ClipCursor(&SDL_bounds);
|
||||
if (!(SDL_cursorstate & CURSOR_VISIBLE)) {
|
||||
/* RJR: March 28, 2000
|
||||
must be entering relative mode, get ready by
|
||||
moving mouse to center of window ... */
|
||||
POINT pt;
|
||||
pt.x = (SDL_VideoSurface->w / 2);
|
||||
pt.y = (SDL_VideoSurface->h / 2);
|
||||
ClientToScreen(SDL_Window, &pt);
|
||||
SetCursorPos(pt.x, pt.y);
|
||||
}
|
||||
#ifdef _WIN32_WCE
|
||||
if (!input_catched) {
|
||||
if (!CoreCatchInput)
|
||||
LoadInputCatchFunc();
|
||||
|
||||
if (CoreCatchInput)
|
||||
CoreCatchInput(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (mode);
|
||||
}
|
||||
|
||||
/* If 'info' is the right version, this function fills it and returns 1.
|
||||
Otherwise, in case of a version mismatch, it returns -1.
|
||||
*/
|
||||
int
|
||||
WIN_GetWMInfo(_THIS, SDL_SysWMinfo * info)
|
||||
{
|
||||
if (info->version.major <= SDL_MAJOR_VERSION) {
|
||||
info->window = SDL_Window;
|
||||
if (SDL_VERSIONNUM(info->version.major,
|
||||
info->version.minor,
|
||||
info->version.patch) >= SDL_VERSIONNUM(1, 2, 5)) {
|
||||
#if SDL_VIDEO_OPENGL
|
||||
info->hglrc = GL_hrc;
|
||||
#else
|
||||
info->hglrc = NULL;
|
||||
#endif
|
||||
}
|
||||
return (1);
|
||||
} else {
|
||||
SDL_SetError("Application not compiled with SDL %d.%d\n",
|
||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#include "SDL_lowvideo.h"
|
||||
|
||||
/* Data that needs to be freed at SDL_SYS_VideoQuit() */
|
||||
extern HICON screen_icn;
|
||||
|
||||
/* Functions to be exported */
|
||||
extern void WIN_SetWMIcon(_THIS, SDL_Surface * icon, Uint8 * mask);
|
||||
extern void WIN_SetWMCaption(_THIS, const char *title, const char *icon);
|
||||
extern int WIN_IconifyWindow(_THIS);
|
||||
extern SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode);
|
||||
extern int WIN_GetWMInfo(_THIS, SDL_SysWMinfo * info);
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,671 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* WGL implementation of SDL OpenGL support */
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
#include "SDL_opengl.h"
|
||||
#endif
|
||||
#include "SDL_lowvideo.h"
|
||||
#include "SDL_wingl_c.h"
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
|
||||
#endif
|
||||
|
||||
/* If setting the HDC fails, we may need to recreate the window (MSDN) */
|
||||
static int
|
||||
WIN_GL_ResetWindow(_THIS)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
#ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */
|
||||
/* This doesn't work with DirectX code (see CVS comments) */
|
||||
/* If we were passed a window, then we can't create a new one */
|
||||
if (!SDL_windowid && SDL_strcmp(this->name, "windib") == 0) {
|
||||
/* Save the existing window attributes */
|
||||
LONG style;
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
style = GetWindowLong(SDL_Window, GWL_STYLE);
|
||||
GetWindowRect(SDL_Window, &rect);
|
||||
DestroyWindow(SDL_Window);
|
||||
WIN_FlushMessageQueue();
|
||||
|
||||
SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
|
||||
style,
|
||||
rect.left, rect.top,
|
||||
(rect.right - rect.left) + 1,
|
||||
(rect.top - rect.bottom) + 1,
|
||||
NULL, NULL, SDL_Instance, NULL);
|
||||
WIN_FlushMessageQueue();
|
||||
|
||||
if (SDL_Window) {
|
||||
this->SetCaption(this, this->wm_title, this->wm_icon);
|
||||
} else {
|
||||
SDL_SetError("Couldn't create window");
|
||||
status = -1;
|
||||
}
|
||||
} else
|
||||
#endif /* !_WIN32_WCE */
|
||||
{
|
||||
SDL_SetError("Unable to reset window for OpenGL context");
|
||||
status = -1;
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
|
||||
static int
|
||||
ExtensionSupported(const char *extension, const char *extensions)
|
||||
{
|
||||
const char *start;
|
||||
const char *where, *terminator;
|
||||
|
||||
/* Extension names should not have spaces. */
|
||||
where = SDL_strchr(extension, ' ');
|
||||
if (where || *extension == '\0')
|
||||
return 0;
|
||||
|
||||
if (!extensions)
|
||||
return 0;
|
||||
|
||||
/* It takes a bit of care to be fool-proof about parsing the
|
||||
* OpenGL extensions string. Don't be fooled by sub-strings,
|
||||
* etc. */
|
||||
|
||||
start = extensions;
|
||||
|
||||
for (;;) {
|
||||
where = SDL_strstr(start, extension);
|
||||
if (!where)
|
||||
break;
|
||||
|
||||
terminator = where + SDL_strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ')
|
||||
if (*terminator == ' ' || *terminator == '\0')
|
||||
return 1;
|
||||
|
||||
start = terminator;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Init_WGL_ARB_extensions(_THIS)
|
||||
{
|
||||
HWND hwnd;
|
||||
HDC hdc;
|
||||
HGLRC hglrc;
|
||||
int pformat;
|
||||
const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
|
||||
const char *extensions;
|
||||
|
||||
hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED,
|
||||
0, 0, 10, 10, NULL, NULL, SDL_Instance, NULL);
|
||||
WIN_FlushMessageQueue();
|
||||
|
||||
hdc = GetDC(hwnd);
|
||||
|
||||
pformat = ChoosePixelFormat(hdc, &GL_pfd);
|
||||
SetPixelFormat(hdc, pformat, &GL_pfd);
|
||||
|
||||
hglrc = this->gl_data->wglCreateContext(hdc);
|
||||
if (hglrc) {
|
||||
this->gl_data->wglMakeCurrent(hdc, hglrc);
|
||||
}
|
||||
|
||||
wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
|
||||
this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
|
||||
if (wglGetExtensionsStringARB) {
|
||||
extensions = wglGetExtensionsStringARB(hdc);
|
||||
} else {
|
||||
extensions = NULL;
|
||||
}
|
||||
|
||||
this->gl_data->WGL_ARB_pixel_format = 0;
|
||||
if (ExtensionSupported("WGL_ARB_pixel_format", extensions)) {
|
||||
this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
|
||||
(HDC, const int *,
|
||||
const FLOAT *, UINT, int *,
|
||||
UINT *))
|
||||
this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
this->gl_data->wglGetPixelFormatAttribivARB =
|
||||
(BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
|
||||
this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||
|
||||
if ((this->gl_data->wglChoosePixelFormatARB != NULL) &&
|
||||
(this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
|
||||
this->gl_data->WGL_ARB_pixel_format = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (hglrc) {
|
||||
this->gl_data->wglMakeCurrent(NULL, NULL);
|
||||
this->gl_data->wglDeleteContext(hglrc);
|
||||
}
|
||||
ReleaseDC(hwnd, hdc);
|
||||
DestroyWindow(hwnd);
|
||||
WIN_FlushMessageQueue();
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
|
||||
int
|
||||
WIN_GL_SetupWindow(_THIS)
|
||||
{
|
||||
int retval;
|
||||
#if SDL_VIDEO_OPENGL
|
||||
int i;
|
||||
unsigned int matching;
|
||||
int iAttribs[64];
|
||||
int *iAttr;
|
||||
float fAttribs[1] = { 0 };
|
||||
const GLubyte *(WINAPI * glGetStringFunc) (GLenum);
|
||||
const char *wglext;
|
||||
|
||||
/* load the gl driver from a default path */
|
||||
if (!this->gl_config.driver_loaded) {
|
||||
/* no driver has been loaded, use default (ourselves) */
|
||||
if (WIN_GL_LoadLibrary(this, NULL) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0;; ++i) {
|
||||
/* Get the window device context for our OpenGL drawing */
|
||||
GL_hdc = GetDC(SDL_Window);
|
||||
if (GL_hdc == NULL) {
|
||||
SDL_SetError("Unable to get DC for SDL_Window");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Set up the pixel format descriptor with our needed format */
|
||||
SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
|
||||
GL_pfd.nSize = sizeof(GL_pfd);
|
||||
GL_pfd.nVersion = 1;
|
||||
GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
|
||||
if (this->gl_config.double_buffer) {
|
||||
GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
|
||||
}
|
||||
if (this->gl_config.stereo) {
|
||||
GL_pfd.dwFlags |= PFD_STEREO;
|
||||
}
|
||||
GL_pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
GL_pfd.cColorBits = this->gl_config.buffer_size;
|
||||
GL_pfd.cRedBits = this->gl_config.red_size;
|
||||
GL_pfd.cGreenBits = this->gl_config.green_size;
|
||||
GL_pfd.cBlueBits = this->gl_config.blue_size;
|
||||
GL_pfd.cAlphaBits = this->gl_config.alpha_size;
|
||||
GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
|
||||
GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
|
||||
GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
|
||||
GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
|
||||
GL_pfd.cAccumBits =
|
||||
(GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
|
||||
GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
|
||||
GL_pfd.cDepthBits = this->gl_config.depth_size;
|
||||
GL_pfd.cStencilBits = this->gl_config.stencil_size;
|
||||
|
||||
/* initialize WGL_ARB_pixel_format */
|
||||
Init_WGL_ARB_extensions(this);
|
||||
|
||||
/* setup WGL_ARB_pixel_format attribs */
|
||||
iAttr = &iAttribs[0];
|
||||
|
||||
*iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
|
||||
*iAttr++ = GL_TRUE;
|
||||
*iAttr++ = WGL_ACCELERATION_ARB;
|
||||
*iAttr++ = WGL_FULL_ACCELERATION_ARB;
|
||||
*iAttr++ = WGL_RED_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.red_size;
|
||||
*iAttr++ = WGL_GREEN_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.green_size;
|
||||
*iAttr++ = WGL_BLUE_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.blue_size;
|
||||
|
||||
if (this->gl_config.alpha_size) {
|
||||
*iAttr++ = WGL_ALPHA_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.alpha_size;
|
||||
}
|
||||
|
||||
*iAttr++ = WGL_DOUBLE_BUFFER_ARB;
|
||||
*iAttr++ = this->gl_config.double_buffer;
|
||||
|
||||
*iAttr++ = WGL_DEPTH_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.depth_size;
|
||||
|
||||
if (this->gl_config.stencil_size) {
|
||||
*iAttr++ = WGL_STENCIL_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.stencil_size;
|
||||
}
|
||||
|
||||
if (this->gl_config.accum_red_size) {
|
||||
*iAttr++ = WGL_ACCUM_RED_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.accum_red_size;
|
||||
}
|
||||
|
||||
if (this->gl_config.accum_green_size) {
|
||||
*iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.accum_green_size;
|
||||
}
|
||||
|
||||
if (this->gl_config.accum_blue_size) {
|
||||
*iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.accum_blue_size;
|
||||
}
|
||||
|
||||
if (this->gl_config.accum_alpha_size) {
|
||||
*iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
|
||||
*iAttr++ = this->gl_config.accum_alpha_size;
|
||||
}
|
||||
|
||||
if (this->gl_config.stereo) {
|
||||
*iAttr++ = WGL_STEREO_ARB;
|
||||
*iAttr++ = GL_TRUE;
|
||||
}
|
||||
|
||||
if (this->gl_config.multisamplebuffers) {
|
||||
*iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
|
||||
*iAttr++ = this->gl_config.multisamplebuffers;
|
||||
}
|
||||
|
||||
if (this->gl_config.multisamplesamples) {
|
||||
*iAttr++ = WGL_SAMPLES_ARB;
|
||||
*iAttr++ = this->gl_config.multisamplesamples;
|
||||
}
|
||||
|
||||
if (this->gl_config.accelerated >= 0) {
|
||||
*iAttr++ = WGL_ACCELERATION_ARB;
|
||||
*iAttr++ =
|
||||
(this->gl_config.
|
||||
accelerated ? WGL_GENERIC_ACCELERATION_ARB :
|
||||
WGL_NO_ACCELERATION_ARB);
|
||||
}
|
||||
|
||||
*iAttr = 0;
|
||||
|
||||
/* Choose and set the closest available pixel format */
|
||||
if (!this->gl_data->WGL_ARB_pixel_format ||
|
||||
!this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs,
|
||||
fAttribs, 1,
|
||||
&pixel_format, &matching)
|
||||
|| !matching) {
|
||||
pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
|
||||
this->gl_data->WGL_ARB_pixel_format = 0;
|
||||
}
|
||||
if (!pixel_format) {
|
||||
SDL_SetError("No matching GL pixel format available");
|
||||
return (-1);
|
||||
}
|
||||
if (!SetPixelFormat(GL_hdc, pixel_format, &GL_pfd)) {
|
||||
if (i == 0) {
|
||||
/* First time through, try resetting the window */
|
||||
if (WIN_GL_ResetWindow(this) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
SDL_SetError("Unable to set HDC pixel format");
|
||||
return (-1);
|
||||
}
|
||||
/* We either succeeded or failed by this point */
|
||||
break;
|
||||
}
|
||||
DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
|
||||
|
||||
GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
|
||||
if (GL_hrc == NULL) {
|
||||
SDL_SetError("Unable to create GL context");
|
||||
return (-1);
|
||||
}
|
||||
if (WIN_GL_MakeCurrent(this) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
gl_active = 1;
|
||||
|
||||
/* Vsync control under Windows. Checking glGetString here is
|
||||
* somewhat a documented and reliable hack - it was originally
|
||||
* as a feature added by mistake, but since so many people rely
|
||||
* on it, it will not be removed. strstr should be safe here.*/
|
||||
glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
|
||||
if (glGetStringFunc) {
|
||||
wglext = (const char *) glGetStringFunc(GL_EXTENSIONS);
|
||||
} else {
|
||||
/* Uh oh, something is seriously wrong here... */
|
||||
wglext = NULL;
|
||||
}
|
||||
if (wglext && SDL_strstr(wglext, "WGL_EXT_swap_control")) {
|
||||
this->gl_data->wglSwapIntervalEXT =
|
||||
WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT");
|
||||
this->gl_data->wglGetSwapIntervalEXT =
|
||||
WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT");
|
||||
} else {
|
||||
this->gl_data->wglSwapIntervalEXT = NULL;
|
||||
this->gl_data->wglGetSwapIntervalEXT = NULL;
|
||||
}
|
||||
if (this->gl_config.swap_control >= 0) {
|
||||
if (this->gl_data->wglSwapIntervalEXT) {
|
||||
this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
|
||||
}
|
||||
}
|
||||
#else
|
||||
SDL_SetError("WIN driver not configured with OpenGL");
|
||||
#endif
|
||||
if (gl_active) {
|
||||
retval = 0;
|
||||
} else {
|
||||
retval = -1;
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
void
|
||||
WIN_GL_ShutDown(_THIS)
|
||||
{
|
||||
#if SDL_VIDEO_OPENGL
|
||||
/* Clean up OpenGL */
|
||||
if (GL_hrc) {
|
||||
this->gl_data->wglMakeCurrent(NULL, NULL);
|
||||
this->gl_data->wglDeleteContext(GL_hrc);
|
||||
GL_hrc = NULL;
|
||||
}
|
||||
if (GL_hdc) {
|
||||
ReleaseDC(SDL_Window, GL_hdc);
|
||||
GL_hdc = NULL;
|
||||
}
|
||||
gl_active = 0;
|
||||
|
||||
WIN_GL_UnloadLibrary(this);
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
|
||||
/* Make the current context active */
|
||||
int
|
||||
WIN_GL_MakeCurrent(_THIS)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = 0;
|
||||
if (!this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc)) {
|
||||
SDL_SetError("Unable to make GL context current");
|
||||
retval = -1;
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* Get attribute data from glX. */
|
||||
int
|
||||
WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (this->gl_data->WGL_ARB_pixel_format) {
|
||||
int wgl_attrib;
|
||||
|
||||
switch (attrib) {
|
||||
case SDL_GL_RED_SIZE:
|
||||
wgl_attrib = WGL_RED_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_GREEN_SIZE:
|
||||
wgl_attrib = WGL_GREEN_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_BLUE_SIZE:
|
||||
wgl_attrib = WGL_BLUE_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_ALPHA_SIZE:
|
||||
wgl_attrib = WGL_ALPHA_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_DOUBLEBUFFER:
|
||||
wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
|
||||
break;
|
||||
case SDL_GL_BUFFER_SIZE:
|
||||
wgl_attrib = WGL_COLOR_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_DEPTH_SIZE:
|
||||
wgl_attrib = WGL_DEPTH_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_STENCIL_SIZE:
|
||||
wgl_attrib = WGL_STENCIL_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_ACCUM_RED_SIZE:
|
||||
wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_ACCUM_GREEN_SIZE:
|
||||
wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_ACCUM_BLUE_SIZE:
|
||||
wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_ACCUM_ALPHA_SIZE:
|
||||
wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
|
||||
break;
|
||||
case SDL_GL_STEREO:
|
||||
wgl_attrib = WGL_STEREO_ARB;
|
||||
break;
|
||||
case SDL_GL_MULTISAMPLEBUFFERS:
|
||||
wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
|
||||
break;
|
||||
case SDL_GL_MULTISAMPLESAMPLES:
|
||||
wgl_attrib = WGL_SAMPLES_ARB;
|
||||
break;
|
||||
case SDL_GL_ACCELERATED_VISUAL:
|
||||
wgl_attrib = WGL_ACCELERATION_ARB;
|
||||
this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format,
|
||||
0, 1, &wgl_attrib,
|
||||
value);
|
||||
if (*value == WGL_NO_ACCELERATION_ARB) {
|
||||
*value = SDL_FALSE;
|
||||
} else {
|
||||
*value = SDL_TRUE;
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
case SDL_GL_SWAP_CONTROL:
|
||||
if (this->gl_data->wglGetSwapIntervalEXT) {
|
||||
*value = this->gl_data->wglGetSwapIntervalEXT();
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0,
|
||||
1, &wgl_attrib, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
switch (attrib) {
|
||||
case SDL_GL_RED_SIZE:
|
||||
*value = GL_pfd.cRedBits;
|
||||
break;
|
||||
case SDL_GL_GREEN_SIZE:
|
||||
*value = GL_pfd.cGreenBits;
|
||||
break;
|
||||
case SDL_GL_BLUE_SIZE:
|
||||
*value = GL_pfd.cBlueBits;
|
||||
break;
|
||||
case SDL_GL_ALPHA_SIZE:
|
||||
*value = GL_pfd.cAlphaBits;
|
||||
break;
|
||||
case SDL_GL_DOUBLEBUFFER:
|
||||
if (GL_pfd.dwFlags & PFD_DOUBLEBUFFER) {
|
||||
*value = 1;
|
||||
} else {
|
||||
*value = 0;
|
||||
}
|
||||
break;
|
||||
case SDL_GL_BUFFER_SIZE:
|
||||
*value = GL_pfd.cColorBits;
|
||||
break;
|
||||
case SDL_GL_DEPTH_SIZE:
|
||||
*value = GL_pfd.cDepthBits;
|
||||
break;
|
||||
case SDL_GL_STENCIL_SIZE:
|
||||
*value = GL_pfd.cStencilBits;
|
||||
break;
|
||||
case SDL_GL_ACCUM_RED_SIZE:
|
||||
*value = GL_pfd.cAccumRedBits;
|
||||
break;
|
||||
case SDL_GL_ACCUM_GREEN_SIZE:
|
||||
*value = GL_pfd.cAccumGreenBits;
|
||||
break;
|
||||
case SDL_GL_ACCUM_BLUE_SIZE:
|
||||
*value = GL_pfd.cAccumBlueBits;
|
||||
break;
|
||||
case SDL_GL_ACCUM_ALPHA_SIZE:
|
||||
*value = GL_pfd.cAccumAlphaBits;
|
||||
break;
|
||||
case SDL_GL_STEREO:
|
||||
if (GL_pfd.dwFlags & PFD_STEREO) {
|
||||
*value = 1;
|
||||
} else {
|
||||
*value = 0;
|
||||
}
|
||||
break;
|
||||
case SDL_GL_MULTISAMPLEBUFFERS:
|
||||
*value = 0;
|
||||
break;
|
||||
case SDL_GL_MULTISAMPLESAMPLES:
|
||||
*value = 1;
|
||||
break;
|
||||
case SDL_GL_SWAP_CONTROL:
|
||||
if (this->gl_data->wglGetSwapIntervalEXT) {
|
||||
*value = this->gl_data->wglGetSwapIntervalEXT();
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
WIN_GL_SwapBuffers(_THIS)
|
||||
{
|
||||
SwapBuffers(GL_hdc);
|
||||
}
|
||||
|
||||
void
|
||||
WIN_GL_UnloadLibrary(_THIS)
|
||||
{
|
||||
if (this->gl_config.driver_loaded) {
|
||||
FreeLibrary((HMODULE) this->gl_config.dll_handle);
|
||||
|
||||
this->gl_data->wglGetProcAddress = NULL;
|
||||
this->gl_data->wglCreateContext = NULL;
|
||||
this->gl_data->wglDeleteContext = NULL;
|
||||
this->gl_data->wglMakeCurrent = NULL;
|
||||
this->gl_data->wglChoosePixelFormatARB = NULL;
|
||||
this->gl_data->wglGetPixelFormatAttribivARB = NULL;
|
||||
this->gl_data->wglSwapIntervalEXT = NULL;
|
||||
this->gl_data->wglGetSwapIntervalEXT = NULL;
|
||||
|
||||
this->gl_config.dll_handle = NULL;
|
||||
this->gl_config.driver_loaded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Passing a NULL path means load pointers from the application */
|
||||
int
|
||||
WIN_GL_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
HMODULE handle;
|
||||
|
||||
if (gl_active) {
|
||||
SDL_SetError("OpenGL context already created");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (path == NULL) {
|
||||
path = DEFAULT_GL_DRIVER_PATH;
|
||||
}
|
||||
handle = LoadLibrary(path);
|
||||
if (handle == NULL) {
|
||||
SDL_SetError("Could not load OpenGL library");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Unload the old driver and reset the pointers */
|
||||
WIN_GL_UnloadLibrary(this);
|
||||
|
||||
/* Load new function pointers */
|
||||
SDL_memset(this->gl_data, 0, sizeof(*this->gl_data));
|
||||
this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
|
||||
GetProcAddress(handle, "wglGetProcAddress");
|
||||
this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
|
||||
GetProcAddress(handle, "wglCreateContext");
|
||||
this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
|
||||
GetProcAddress(handle, "wglDeleteContext");
|
||||
this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
|
||||
GetProcAddress(handle, "wglMakeCurrent");
|
||||
this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int))
|
||||
GetProcAddress(handle, "wglSwapIntervalEXT");
|
||||
this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void))
|
||||
GetProcAddress(handle, "wglGetSwapIntervalEXT");
|
||||
|
||||
if ((this->gl_data->wglGetProcAddress == NULL) ||
|
||||
(this->gl_data->wglCreateContext == NULL) ||
|
||||
(this->gl_data->wglDeleteContext == NULL) ||
|
||||
(this->gl_data->wglMakeCurrent == NULL)) {
|
||||
SDL_SetError("Could not retrieve OpenGL functions");
|
||||
FreeLibrary(handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
this->gl_config.dll_handle = handle;
|
||||
SDL_strlcpy(this->gl_config.driver_path, path,
|
||||
SDL_arraysize(this->gl_config.driver_path));
|
||||
this->gl_config.driver_loaded = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
WIN_GL_GetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
void *func;
|
||||
|
||||
/* This is to pick up extensions */
|
||||
func = this->gl_data->wglGetProcAddress(proc);
|
||||
if (!func) {
|
||||
/* This is probably a normal GL function */
|
||||
func = GetProcAddress(this->gl_config.dll_handle, proc);
|
||||
}
|
||||
return func;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* WGL implementation of SDL OpenGL support */
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
|
||||
struct SDL_PrivateGLData
|
||||
{
|
||||
int gl_active; /* to stop switching drivers while we have a valid context */
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
PIXELFORMATDESCRIPTOR GL_pfd;
|
||||
HDC GL_hdc;
|
||||
HGLRC GL_hrc;
|
||||
int pixel_format;
|
||||
int WGL_ARB_pixel_format;
|
||||
|
||||
void *(WINAPI * wglGetProcAddress) (const char *proc);
|
||||
|
||||
HGLRC(WINAPI * wglCreateContext) (HDC hdc);
|
||||
|
||||
BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc);
|
||||
|
||||
BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc);
|
||||
|
||||
BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc,
|
||||
const int *piAttribIList,
|
||||
const FLOAT * pfAttribFList,
|
||||
UINT nMaxFormats,
|
||||
int *piFormats,
|
||||
UINT * nNumFormats);
|
||||
BOOL(WINAPI * wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat,
|
||||
int iLayerPlane,
|
||||
UINT nAttributes,
|
||||
const int *piAttributes,
|
||||
int *piValues);
|
||||
void (WINAPI * wglSwapIntervalEXT) (int interval);
|
||||
int (WINAPI * wglGetSwapIntervalEXT) (void);
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
};
|
||||
|
||||
/* Old variable names */
|
||||
#define gl_active (this->gl_data->gl_active)
|
||||
#define GL_pfd (this->gl_data->GL_pfd)
|
||||
#define GL_hdc (this->gl_data->GL_hdc)
|
||||
#define GL_hrc (this->gl_data->GL_hrc)
|
||||
#define pixel_format (this->gl_data->pixel_format)
|
||||
|
||||
/* OpenGL functions */
|
||||
extern int WIN_GL_SetupWindow(_THIS);
|
||||
extern void WIN_GL_ShutDown(_THIS);
|
||||
#if SDL_VIDEO_OPENGL
|
||||
extern int WIN_GL_MakeCurrent(_THIS);
|
||||
extern int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value);
|
||||
extern void WIN_GL_SwapBuffers(_THIS);
|
||||
extern void WIN_GL_UnloadLibrary(_THIS);
|
||||
extern int WIN_GL_LoadLibrary(_THIS, const char *path);
|
||||
extern void *WIN_GL_GetProcAddress(_THIS, const char *proc);
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
|
||||
#ifndef WGL_ARB_pixel_format
|
||||
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
|
||||
#define WGL_ACCELERATION_ARB 0x2003
|
||||
#define WGL_NEED_PALETTE_ARB 0x2004
|
||||
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
|
||||
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
|
||||
#define WGL_SWAP_METHOD_ARB 0x2007
|
||||
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
|
||||
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
|
||||
#define WGL_TRANSPARENT_ARB 0x200A
|
||||
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
|
||||
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
|
||||
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
|
||||
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
|
||||
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
|
||||
#define WGL_SHARE_DEPTH_ARB 0x200C
|
||||
#define WGL_SHARE_STENCIL_ARB 0x200D
|
||||
#define WGL_SHARE_ACCUM_ARB 0x200E
|
||||
#define WGL_SUPPORT_GDI_ARB 0x200F
|
||||
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||
#define WGL_STEREO_ARB 0x2012
|
||||
#define WGL_PIXEL_TYPE_ARB 0x2013
|
||||
#define WGL_COLOR_BITS_ARB 0x2014
|
||||
#define WGL_RED_BITS_ARB 0x2015
|
||||
#define WGL_RED_SHIFT_ARB 0x2016
|
||||
#define WGL_GREEN_BITS_ARB 0x2017
|
||||
#define WGL_GREEN_SHIFT_ARB 0x2018
|
||||
#define WGL_BLUE_BITS_ARB 0x2019
|
||||
#define WGL_BLUE_SHIFT_ARB 0x201A
|
||||
#define WGL_ALPHA_BITS_ARB 0x201B
|
||||
#define WGL_ALPHA_SHIFT_ARB 0x201C
|
||||
#define WGL_ACCUM_BITS_ARB 0x201D
|
||||
#define WGL_ACCUM_RED_BITS_ARB 0x201E
|
||||
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
|
||||
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
||||
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
||||
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||
#define WGL_AUX_BUFFERS_ARB 0x2024
|
||||
#define WGL_NO_ACCELERATION_ARB 0x2025
|
||||
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
|
||||
#define WGL_FULL_ACCELERATION_ARB 0x2027
|
||||
#define WGL_SWAP_EXCHANGE_ARB 0x2028
|
||||
#define WGL_SWAP_COPY_ARB 0x2029
|
||||
#define WGL_SWAP_UNDEFINED_ARB 0x202A
|
||||
#define WGL_TYPE_RGBA_ARB 0x202B
|
||||
#define WGL_TYPE_COLORINDEX_ARB 0x202C
|
||||
#endif
|
||||
|
||||
#ifndef WGL_ARB_multisample
|
||||
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
File diff suppressed because it is too large
Load diff
|
@ -1,505 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "SDL_main.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include "../../events/SDL_sysevents.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../wincommon/SDL_lowvideo.h"
|
||||
#include "SDL_dibvideo.h"
|
||||
#include "SDL_vkeys.h"
|
||||
|
||||
#ifndef WM_APP
|
||||
#define WM_APP 0x8000
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#define NO_GETKEYBOARDSTATE
|
||||
#endif
|
||||
|
||||
/* The translation table from a Microsoft VK keysym to a SDL keysym */
|
||||
static SDLKey VK_keymap[SDLK_LAST];
|
||||
static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode,
|
||||
SDL_keysym * keysym, int pressed);
|
||||
|
||||
/* Masks for processing the windows KEYDOWN and KEYUP messages */
|
||||
#define REPEATED_KEYMASK (1<<30)
|
||||
#define EXTENDED_KEYMASK (1<<24)
|
||||
|
||||
/* DJM: If the user setup the window for us, we want to save his window proc,
|
||||
and give him a chance to handle some messages. */
|
||||
#ifdef STRICT
|
||||
#define WNDPROCTYPE WNDPROC
|
||||
#else
|
||||
#define WNDPROCTYPE FARPROC
|
||||
#endif
|
||||
static WNDPROCTYPE userWindowProc = NULL;
|
||||
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
|
||||
WPARAM
|
||||
rotateKey(WPARAM key, SDL_ScreenOrientation direction)
|
||||
{
|
||||
if (direction != SDL_ORIENTATION_LEFT)
|
||||
return key;
|
||||
|
||||
switch (key) {
|
||||
case 0x26: /* up */
|
||||
return 0x27;
|
||||
case 0x27: /* right */
|
||||
return 0x28;
|
||||
case 0x28: /* down */
|
||||
return 0x25;
|
||||
case 0x25: /* left */
|
||||
return 0x26;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* The main Win32 event handler */
|
||||
LRESULT
|
||||
DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
extern int posted;
|
||||
|
||||
switch (msg) {
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
SDL_keysym keysym;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
// Drop GAPI artefacts
|
||||
if (wParam == 0x84 || wParam == 0x5B)
|
||||
return 0;
|
||||
|
||||
// Rotate key if necessary
|
||||
if (this->hidden->orientation != SDL_ORIENTATION_UP)
|
||||
wParam = rotateKey(wParam, this->hidden->orientation);
|
||||
#endif
|
||||
/* Ignore repeated keys */
|
||||
if (lParam & REPEATED_KEYMASK) {
|
||||
return (0);
|
||||
}
|
||||
switch (wParam) {
|
||||
case VK_CONTROL:
|
||||
if (lParam & EXTENDED_KEYMASK)
|
||||
wParam = VK_RCONTROL;
|
||||
else
|
||||
wParam = VK_LCONTROL;
|
||||
break;
|
||||
case VK_SHIFT:
|
||||
/* EXTENDED trick doesn't work here */
|
||||
{
|
||||
Uint8 *state = SDL_GetKeyState(NULL);
|
||||
if (state[SDLK_LSHIFT] == SDL_RELEASED
|
||||
&& (GetKeyState(VK_LSHIFT) & 0x8000)) {
|
||||
wParam = VK_LSHIFT;
|
||||
} else if (state[SDLK_RSHIFT] == SDL_RELEASED
|
||||
&& (GetKeyState(VK_RSHIFT) & 0x8000)) {
|
||||
wParam = VK_RSHIFT;
|
||||
} else {
|
||||
/* Probably a key repeat */
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VK_MENU:
|
||||
if (lParam & EXTENDED_KEYMASK)
|
||||
wParam = VK_RMENU;
|
||||
else
|
||||
wParam = VK_LMENU;
|
||||
break;
|
||||
}
|
||||
#ifdef NO_GETKEYBOARDSTATE
|
||||
/* this is the workaround for the missing ToAscii() and ToUnicode() in CE (not necessary at KEYUP!) */
|
||||
if (SDL_TranslateUNICODE) {
|
||||
MSG m;
|
||||
|
||||
m.hwnd = hwnd;
|
||||
m.message = msg;
|
||||
m.wParam = wParam;
|
||||
m.lParam = lParam;
|
||||
m.time = 0;
|
||||
if (TranslateMessage(&m)
|
||||
&& PeekMessage(&m, hwnd, 0, WM_USER, PM_NOREMOVE)
|
||||
&& (m.message == WM_CHAR)) {
|
||||
GetMessage(&m, hwnd, 0, WM_USER);
|
||||
wParam = m.wParam;
|
||||
}
|
||||
}
|
||||
#endif /* NO_GETKEYBOARDSTATE */
|
||||
posted = SDL_PrivateKeyboard(SDL_PRESSED,
|
||||
TranslateKey(wParam,
|
||||
HIWORD(lParam),
|
||||
&keysym, 1));
|
||||
}
|
||||
return (0);
|
||||
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
SDL_keysym keysym;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
// Drop GAPI artifacts
|
||||
if (wParam == 0x84 || wParam == 0x5B)
|
||||
return 0;
|
||||
|
||||
// Rotate key if necessary
|
||||
if (this->hidden->orientation != SDL_ORIENTATION_UP)
|
||||
wParam = rotateKey(wParam, this->hidden->orientation);
|
||||
#endif
|
||||
|
||||
switch (wParam) {
|
||||
case VK_CONTROL:
|
||||
if (lParam & EXTENDED_KEYMASK)
|
||||
wParam = VK_RCONTROL;
|
||||
else
|
||||
wParam = VK_LCONTROL;
|
||||
break;
|
||||
case VK_SHIFT:
|
||||
/* EXTENDED trick doesn't work here */
|
||||
{
|
||||
Uint8 *state = SDL_GetKeyState(NULL);
|
||||
if (state[SDLK_LSHIFT] == SDL_PRESSED
|
||||
&& !(GetKeyState(VK_LSHIFT) & 0x8000)) {
|
||||
wParam = VK_LSHIFT;
|
||||
} else if (state[SDLK_RSHIFT] == SDL_PRESSED
|
||||
&& !(GetKeyState(VK_RSHIFT) & 0x8000)) {
|
||||
wParam = VK_RSHIFT;
|
||||
} else {
|
||||
/* Probably a key repeat */
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VK_MENU:
|
||||
if (lParam & EXTENDED_KEYMASK)
|
||||
wParam = VK_RMENU;
|
||||
else
|
||||
wParam = VK_LMENU;
|
||||
break;
|
||||
}
|
||||
/* Windows only reports keyup for print screen */
|
||||
if (wParam == VK_SNAPSHOT
|
||||
&& SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED) {
|
||||
posted = SDL_PrivateKeyboard(SDL_PRESSED,
|
||||
TranslateKey(wParam,
|
||||
HIWORD
|
||||
(lParam),
|
||||
&keysym, 1));
|
||||
}
|
||||
posted = SDL_PrivateKeyboard(SDL_RELEASED,
|
||||
TranslateKey(wParam,
|
||||
HIWORD(lParam),
|
||||
&keysym, 0));
|
||||
}
|
||||
return (0);
|
||||
|
||||
#if defined(SC_SCREENSAVE) && defined(SC_MONITORPOWER)
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
|
||||
(wParam & 0xFFF0) == SC_MONITORPOWER)
|
||||
return (0);
|
||||
}
|
||||
/* Fall through to default processing */
|
||||
#endif /* SC_SCREENSAVE && SC_MONITORPOWER */
|
||||
|
||||
default:
|
||||
{
|
||||
/* Only post the event if we're watching for it */
|
||||
if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
|
||||
SDL_SysWMmsg wmmsg;
|
||||
|
||||
SDL_VERSION(&wmmsg.version);
|
||||
wmmsg.hwnd = hwnd;
|
||||
wmmsg.msg = msg;
|
||||
wmmsg.wParam = wParam;
|
||||
wmmsg.lParam = lParam;
|
||||
posted = SDL_PrivateSysWMEvent(&wmmsg);
|
||||
|
||||
/* DJM: If the user isn't watching for private
|
||||
messages in her SDL event loop, then pass it
|
||||
along to any win32 specific window proc.
|
||||
*/
|
||||
} else if (userWindowProc) {
|
||||
return CallWindowProc(userWindowProc, hwnd, msg, wParam,
|
||||
lParam);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (DefWindowProc(hwnd, msg, wParam, lParam));
|
||||
}
|
||||
|
||||
void
|
||||
DIB_PumpEvents(_THIS)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
||||
if (GetMessage(&msg, NULL, 0, 0) > 0) {
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DIB_InitOSKeymap(_THIS)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Map the VK keysyms */
|
||||
for (i = 0; i < SDL_arraysize(VK_keymap); ++i)
|
||||
VK_keymap[i] = SDLK_UNKNOWN;
|
||||
|
||||
VK_keymap[VK_BACK] = SDLK_BACKSPACE;
|
||||
VK_keymap[VK_TAB] = SDLK_TAB;
|
||||
VK_keymap[VK_CLEAR] = SDLK_CLEAR;
|
||||
VK_keymap[VK_RETURN] = SDLK_RETURN;
|
||||
VK_keymap[VK_PAUSE] = SDLK_PAUSE;
|
||||
VK_keymap[VK_ESCAPE] = SDLK_ESCAPE;
|
||||
VK_keymap[VK_SPACE] = SDLK_SPACE;
|
||||
VK_keymap[VK_APOSTROPHE] = SDLK_QUOTE;
|
||||
VK_keymap[VK_COMMA] = SDLK_COMMA;
|
||||
VK_keymap[VK_MINUS] = SDLK_MINUS;
|
||||
VK_keymap[VK_PERIOD] = SDLK_PERIOD;
|
||||
VK_keymap[VK_SLASH] = SDLK_SLASH;
|
||||
VK_keymap[VK_0] = SDLK_0;
|
||||
VK_keymap[VK_1] = SDLK_1;
|
||||
VK_keymap[VK_2] = SDLK_2;
|
||||
VK_keymap[VK_3] = SDLK_3;
|
||||
VK_keymap[VK_4] = SDLK_4;
|
||||
VK_keymap[VK_5] = SDLK_5;
|
||||
VK_keymap[VK_6] = SDLK_6;
|
||||
VK_keymap[VK_7] = SDLK_7;
|
||||
VK_keymap[VK_8] = SDLK_8;
|
||||
VK_keymap[VK_9] = SDLK_9;
|
||||
VK_keymap[VK_SEMICOLON] = SDLK_SEMICOLON;
|
||||
VK_keymap[VK_EQUALS] = SDLK_EQUALS;
|
||||
VK_keymap[VK_LBRACKET] = SDLK_LEFTBRACKET;
|
||||
VK_keymap[VK_BACKSLASH] = SDLK_BACKSLASH;
|
||||
VK_keymap[VK_OEM_102] = SDLK_LESS;
|
||||
VK_keymap[VK_RBRACKET] = SDLK_RIGHTBRACKET;
|
||||
VK_keymap[VK_GRAVE] = SDLK_BACKQUOTE;
|
||||
VK_keymap[VK_BACKTICK] = SDLK_BACKQUOTE;
|
||||
VK_keymap[VK_A] = SDLK_a;
|
||||
VK_keymap[VK_B] = SDLK_b;
|
||||
VK_keymap[VK_C] = SDLK_c;
|
||||
VK_keymap[VK_D] = SDLK_d;
|
||||
VK_keymap[VK_E] = SDLK_e;
|
||||
VK_keymap[VK_F] = SDLK_f;
|
||||
VK_keymap[VK_G] = SDLK_g;
|
||||
VK_keymap[VK_H] = SDLK_h;
|
||||
VK_keymap[VK_I] = SDLK_i;
|
||||
VK_keymap[VK_J] = SDLK_j;
|
||||
VK_keymap[VK_K] = SDLK_k;
|
||||
VK_keymap[VK_L] = SDLK_l;
|
||||
VK_keymap[VK_M] = SDLK_m;
|
||||
VK_keymap[VK_N] = SDLK_n;
|
||||
VK_keymap[VK_O] = SDLK_o;
|
||||
VK_keymap[VK_P] = SDLK_p;
|
||||
VK_keymap[VK_Q] = SDLK_q;
|
||||
VK_keymap[VK_R] = SDLK_r;
|
||||
VK_keymap[VK_S] = SDLK_s;
|
||||
VK_keymap[VK_T] = SDLK_t;
|
||||
VK_keymap[VK_U] = SDLK_u;
|
||||
VK_keymap[VK_V] = SDLK_v;
|
||||
VK_keymap[VK_W] = SDLK_w;
|
||||
VK_keymap[VK_X] = SDLK_x;
|
||||
VK_keymap[VK_Y] = SDLK_y;
|
||||
VK_keymap[VK_Z] = SDLK_z;
|
||||
VK_keymap[VK_DELETE] = SDLK_DELETE;
|
||||
|
||||
VK_keymap[VK_NUMPAD0] = SDLK_KP0;
|
||||
VK_keymap[VK_NUMPAD1] = SDLK_KP1;
|
||||
VK_keymap[VK_NUMPAD2] = SDLK_KP2;
|
||||
VK_keymap[VK_NUMPAD3] = SDLK_KP3;
|
||||
VK_keymap[VK_NUMPAD4] = SDLK_KP4;
|
||||
VK_keymap[VK_NUMPAD5] = SDLK_KP5;
|
||||
VK_keymap[VK_NUMPAD6] = SDLK_KP6;
|
||||
VK_keymap[VK_NUMPAD7] = SDLK_KP7;
|
||||
VK_keymap[VK_NUMPAD8] = SDLK_KP8;
|
||||
VK_keymap[VK_NUMPAD9] = SDLK_KP9;
|
||||
VK_keymap[VK_DECIMAL] = SDLK_KP_PERIOD;
|
||||
VK_keymap[VK_DIVIDE] = SDLK_KP_DIVIDE;
|
||||
VK_keymap[VK_MULTIPLY] = SDLK_KP_MULTIPLY;
|
||||
VK_keymap[VK_SUBTRACT] = SDLK_KP_MINUS;
|
||||
VK_keymap[VK_ADD] = SDLK_KP_PLUS;
|
||||
|
||||
VK_keymap[VK_UP] = SDLK_UP;
|
||||
VK_keymap[VK_DOWN] = SDLK_DOWN;
|
||||
VK_keymap[VK_RIGHT] = SDLK_RIGHT;
|
||||
VK_keymap[VK_LEFT] = SDLK_LEFT;
|
||||
VK_keymap[VK_INSERT] = SDLK_INSERT;
|
||||
VK_keymap[VK_HOME] = SDLK_HOME;
|
||||
VK_keymap[VK_END] = SDLK_END;
|
||||
VK_keymap[VK_PRIOR] = SDLK_PAGEUP;
|
||||
VK_keymap[VK_NEXT] = SDLK_PAGEDOWN;
|
||||
|
||||
VK_keymap[VK_F1] = SDLK_F1;
|
||||
VK_keymap[VK_F2] = SDLK_F2;
|
||||
VK_keymap[VK_F3] = SDLK_F3;
|
||||
VK_keymap[VK_F4] = SDLK_F4;
|
||||
VK_keymap[VK_F5] = SDLK_F5;
|
||||
VK_keymap[VK_F6] = SDLK_F6;
|
||||
VK_keymap[VK_F7] = SDLK_F7;
|
||||
VK_keymap[VK_F8] = SDLK_F8;
|
||||
VK_keymap[VK_F9] = SDLK_F9;
|
||||
VK_keymap[VK_F10] = SDLK_F10;
|
||||
VK_keymap[VK_F11] = SDLK_F11;
|
||||
VK_keymap[VK_F12] = SDLK_F12;
|
||||
VK_keymap[VK_F13] = SDLK_F13;
|
||||
VK_keymap[VK_F14] = SDLK_F14;
|
||||
VK_keymap[VK_F15] = SDLK_F15;
|
||||
|
||||
VK_keymap[VK_NUMLOCK] = SDLK_NUMLOCK;
|
||||
VK_keymap[VK_CAPITAL] = SDLK_CAPSLOCK;
|
||||
VK_keymap[VK_SCROLL] = SDLK_SCROLLOCK;
|
||||
VK_keymap[VK_RSHIFT] = SDLK_RSHIFT;
|
||||
VK_keymap[VK_LSHIFT] = SDLK_LSHIFT;
|
||||
VK_keymap[VK_RCONTROL] = SDLK_RCTRL;
|
||||
VK_keymap[VK_LCONTROL] = SDLK_LCTRL;
|
||||
VK_keymap[VK_RMENU] = SDLK_RALT;
|
||||
VK_keymap[VK_LMENU] = SDLK_LALT;
|
||||
VK_keymap[VK_RWIN] = SDLK_RSUPER;
|
||||
VK_keymap[VK_LWIN] = SDLK_LSUPER;
|
||||
|
||||
VK_keymap[VK_HELP] = SDLK_HELP;
|
||||
#ifdef VK_PRINT
|
||||
VK_keymap[VK_PRINT] = SDLK_PRINT;
|
||||
#endif
|
||||
VK_keymap[VK_SNAPSHOT] = SDLK_PRINT;
|
||||
VK_keymap[VK_CANCEL] = SDLK_BREAK;
|
||||
VK_keymap[VK_APPS] = SDLK_MENU;
|
||||
}
|
||||
|
||||
static SDL_keysym *
|
||||
TranslateKey(WPARAM vkey, UINT scancode, SDL_keysym * keysym, int pressed)
|
||||
{
|
||||
/* Set the keysym information */
|
||||
keysym->scancode = (unsigned char) scancode;
|
||||
keysym->sym = VK_keymap[vkey];
|
||||
keysym->mod = KMOD_NONE;
|
||||
keysym->unicode = 0;
|
||||
if (pressed && SDL_TranslateUNICODE) {
|
||||
#ifdef NO_GETKEYBOARDSTATE
|
||||
/* Uh oh, better hope the vkey is close enough.. */
|
||||
keysym->unicode = vkey;
|
||||
#else
|
||||
BYTE keystate[256];
|
||||
Uint16 wchars[2];
|
||||
|
||||
GetKeyboardState(keystate);
|
||||
if (SDL_ToUnicode
|
||||
((UINT) vkey, scancode, keystate, wchars,
|
||||
sizeof(wchars) / sizeof(wchars[0]), 0) == 1) {
|
||||
keysym->unicode = wchars[0];
|
||||
}
|
||||
#endif /* NO_GETKEYBOARDSTATE */
|
||||
}
|
||||
return (keysym);
|
||||
}
|
||||
|
||||
int
|
||||
DIB_CreateWindow(_THIS)
|
||||
{
|
||||
char *windowid = SDL_getenv("SDL_WINDOWID");
|
||||
|
||||
SDL_RegisterApp(NULL, 0, 0);
|
||||
|
||||
SDL_windowid = (windowid != NULL);
|
||||
if (SDL_windowid) {
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
|
||||
/* wince 2.1 does not have strtol */
|
||||
wchar_t *windowid_t =
|
||||
SDL_malloc((SDL_strlen(windowid) + 1) * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, windowid, -1,
|
||||
windowid_t, SDL_strlen(windowid) + 1);
|
||||
SDL_Window = (HWND) wcstol(windowid_t, NULL, 0);
|
||||
SDL_free(windowid_t);
|
||||
#else
|
||||
SDL_Window = (HWND) SDL_strtoull(windowid, NULL, 0);
|
||||
#endif
|
||||
if (SDL_Window == NULL) {
|
||||
SDL_SetError("Couldn't get user specified window");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* DJM: we want all event's for the user specified
|
||||
window to be handled by SDL.
|
||||
*/
|
||||
userWindowProc =
|
||||
(WNDPROCTYPE) GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
|
||||
SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR) WinMessage);
|
||||
} else {
|
||||
SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
|
||||
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
|
||||
| WS_MINIMIZEBOX), CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, 0, 0, NULL, NULL,
|
||||
SDL_Instance, NULL);
|
||||
if (SDL_Window == NULL) {
|
||||
SDL_SetError("Couldn't create window");
|
||||
return (-1);
|
||||
}
|
||||
ShowWindow(SDL_Window, SW_HIDE);
|
||||
}
|
||||
|
||||
/* JC 14 Mar 2006
|
||||
Flush the message loop or this can cause big problems later
|
||||
Especially if the user decides to use dialog boxes or assert()!
|
||||
*/
|
||||
WIN_FlushMessageQueue();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
DIB_DestroyWindow(_THIS)
|
||||
{
|
||||
if (SDL_windowid) {
|
||||
SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR) userWindowProc);
|
||||
} else {
|
||||
DestroyWindow(SDL_Window);
|
||||
}
|
||||
SDL_UnregisterApp();
|
||||
|
||||
/* JC 14 Mar 2006
|
||||
Flush the message loop or this can cause big problems later
|
||||
Especially if the user decides to use dialog boxes or assert()!
|
||||
*/
|
||||
WIN_FlushMessageQueue();
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#include "../wincommon/SDL_lowvideo.h"
|
||||
|
||||
/* Variables and functions exported by SDL_dibevents.c to other parts
|
||||
of the native video subsystem (SDL_dibvideo.c)
|
||||
*/
|
||||
extern LONG
|
||||
DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
extern int DIB_CreateWindow(_THIS);
|
||||
extern void DIB_DestroyWindow(_THIS);
|
||||
|
||||
extern void DIB_PumpEvents(_THIS);
|
||||
extern void DIB_InitOSKeymap(_THIS);
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
File diff suppressed because it is too large
Load diff
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_dibvideo_h
|
||||
#define _SDL_dibvideo_h
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
/* for PDA */
|
||||
typedef enum
|
||||
{
|
||||
SDL_ORIENTATION_UP,
|
||||
SDL_ORIENTATION_DOWN,
|
||||
SDL_ORIENTATION_LEFT,
|
||||
SDL_ORIENTATION_RIGHT
|
||||
} SDL_ScreenOrientation;
|
||||
|
||||
/* Private display data */
|
||||
struct SDL_PrivateVideoData
|
||||
{
|
||||
HBITMAP screen_bmp;
|
||||
HPALETTE screen_pal;
|
||||
|
||||
#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
|
||||
int SDL_nummodes[NUM_MODELISTS];
|
||||
SDL_Rect **SDL_modelist[NUM_MODELISTS];
|
||||
|
||||
SDL_ScreenOrientation orientation;
|
||||
#ifdef _WIN32_WCE
|
||||
int invert; /* do to remove, used by GAPI driver! */
|
||||
char hiresFix; /* using hires mode without defining hires resource */
|
||||
int supportRotation; /* for Pocket PC devices */
|
||||
DWORD origRotation; /* for Pocket PC devices */
|
||||
#endif
|
||||
};
|
||||
/* Old variable names */
|
||||
#define screen_bmp (this->hidden->screen_bmp)
|
||||
#define screen_pal (this->hidden->screen_pal)
|
||||
#define SDL_nummodes (this->hidden->SDL_nummodes)
|
||||
#define SDL_modelist (this->hidden->SDL_modelist)
|
||||
|
||||
#endif /* _SDL_dibvideo_h */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
|
||||
#ifndef VK_0
|
||||
#define VK_0 '0'
|
||||
#define VK_1 '1'
|
||||
#define VK_2 '2'
|
||||
#define VK_3 '3'
|
||||
#define VK_4 '4'
|
||||
#define VK_5 '5'
|
||||
#define VK_6 '6'
|
||||
#define VK_7 '7'
|
||||
#define VK_8 '8'
|
||||
#define VK_9 '9'
|
||||
#define VK_A 'A'
|
||||
#define VK_B 'B'
|
||||
#define VK_C 'C'
|
||||
#define VK_D 'D'
|
||||
#define VK_E 'E'
|
||||
#define VK_F 'F'
|
||||
#define VK_G 'G'
|
||||
#define VK_H 'H'
|
||||
#define VK_I 'I'
|
||||
#define VK_J 'J'
|
||||
#define VK_K 'K'
|
||||
#define VK_L 'L'
|
||||
#define VK_M 'M'
|
||||
#define VK_N 'N'
|
||||
#define VK_O 'O'
|
||||
#define VK_P 'P'
|
||||
#define VK_Q 'Q'
|
||||
#define VK_R 'R'
|
||||
#define VK_S 'S'
|
||||
#define VK_T 'T'
|
||||
#define VK_U 'U'
|
||||
#define VK_V 'V'
|
||||
#define VK_W 'W'
|
||||
#define VK_X 'X'
|
||||
#define VK_Y 'Y'
|
||||
#define VK_Z 'Z'
|
||||
#endif /* VK_0 */
|
||||
|
||||
/* These keys haven't been defined, but were experimentally determined */
|
||||
#define VK_SEMICOLON 0xBA
|
||||
#define VK_EQUALS 0xBB
|
||||
#define VK_COMMA 0xBC
|
||||
#define VK_MINUS 0xBD
|
||||
#define VK_PERIOD 0xBE
|
||||
#define VK_SLASH 0xBF
|
||||
#define VK_GRAVE 0xC0
|
||||
#define VK_LBRACKET 0xDB
|
||||
#define VK_BACKSLASH 0xDC
|
||||
#define VK_RBRACKET 0xDD
|
||||
#define VK_APOSTROPHE 0xDE
|
||||
#define VK_BACKTICK 0xDF
|
||||
#define VK_OEM_102 0xE2
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,944 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* CAUTION!!!! If you modify this file, check ../windib/SDL_sysevents.c */
|
||||
|
||||
#include "directx.h"
|
||||
|
||||
#include "SDL_main.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include "../../events/SDL_sysevents.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../wincommon/SDL_lowvideo.h"
|
||||
#include "SDL_dx5video.h"
|
||||
|
||||
#ifndef WM_APP
|
||||
#define WM_APP 0x8000
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
#define NO_GETKEYBOARDSTATE
|
||||
#endif
|
||||
|
||||
/* The keyboard and mouse device input */
|
||||
#define MAX_INPUTS 16 /* Maximum of 16-1 input devices */
|
||||
#define INPUT_QSIZE 512 /* Buffer up to 512 input messages */
|
||||
|
||||
static LPDIRECTINPUT dinput = NULL;
|
||||
static LPDIRECTINPUTDEVICE2 SDL_DIdev[MAX_INPUTS];
|
||||
static HANDLE SDL_DIevt[MAX_INPUTS];
|
||||
static void (*SDL_DIfun[MAX_INPUTS]) (const int, DIDEVICEOBJECTDATA *);
|
||||
static int SDL_DIndev = 0;
|
||||
static int mouse_lost;
|
||||
static int mouse_pressed;
|
||||
static int mouse_buttons_swapped = 0;
|
||||
|
||||
/* The translation table from a DirectInput scancode to an SDL keysym */
|
||||
static SDLKey DIK_keymap[256];
|
||||
static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym * keysym,
|
||||
int pressed);
|
||||
|
||||
/* DJM: If the user setup the window for us, we want to save his window proc,
|
||||
and give him a chance to handle some messages. */
|
||||
#ifdef STRICT
|
||||
#define WNDPROCTYPE WNDPROC
|
||||
#else
|
||||
#define WNDPROCTYPE FARPROC
|
||||
#endif
|
||||
static WNDPROCTYPE userWindowProc = NULL;
|
||||
|
||||
static HWND
|
||||
GetTopLevelParent(HWND hWnd)
|
||||
{
|
||||
HWND hParentWnd;
|
||||
while (1) {
|
||||
hParentWnd = GetParent(hWnd);
|
||||
if (hParentWnd == NULL)
|
||||
break;
|
||||
hWnd = hParentWnd;
|
||||
}
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
/* Convert a DirectInput return code to a text message */
|
||||
static void
|
||||
SetDIerror(char *function, int code)
|
||||
{
|
||||
static char *error;
|
||||
static char errbuf[1024];
|
||||
|
||||
errbuf[0] = 0;
|
||||
switch (code) {
|
||||
case DIERR_GENERIC:
|
||||
error = "Undefined error!";
|
||||
break;
|
||||
case DIERR_OLDDIRECTINPUTVERSION:
|
||||
error = "Your version of DirectInput needs upgrading";
|
||||
break;
|
||||
case DIERR_INVALIDPARAM:
|
||||
error = "Invalid parameters";
|
||||
break;
|
||||
case DIERR_OUTOFMEMORY:
|
||||
error = "Out of memory";
|
||||
break;
|
||||
case DIERR_DEVICENOTREG:
|
||||
error = "Device not registered";
|
||||
break;
|
||||
case DIERR_NOINTERFACE:
|
||||
error = "Interface not supported";
|
||||
break;
|
||||
case DIERR_NOTINITIALIZED:
|
||||
error = "Device not initialized";
|
||||
break;
|
||||
default:
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf),
|
||||
"%s: Unknown DirectInput error: 0x%x", function, code);
|
||||
break;
|
||||
}
|
||||
if (!errbuf[0]) {
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
|
||||
error);
|
||||
}
|
||||
SDL_SetError("%s", errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize DirectInput
|
||||
Note: If NONEXCLUSIVE access is requested for the devices, normal
|
||||
windows input messages will continue to be generated for that
|
||||
input device, in addition to DirectInput messages.
|
||||
*/
|
||||
static void handle_keyboard(const int numevents, DIDEVICEOBJECTDATA * events);
|
||||
static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA * events);
|
||||
struct
|
||||
{
|
||||
char *name;
|
||||
REFGUID guid;
|
||||
LPCDIDATAFORMAT format;
|
||||
DWORD win_level;
|
||||
DWORD raw_level;
|
||||
void (*fun) (const int numevents, DIDEVICEOBJECTDATA * events);
|
||||
} inputs[] = {
|
||||
{
|
||||
"keyboard",
|
||||
&GUID_SysKeyboard, &c_dfDIKeyboard,
|
||||
(DISCL_FOREGROUND | DISCL_NONEXCLUSIVE),
|
||||
(DISCL_FOREGROUND | DISCL_NONEXCLUSIVE), handle_keyboard}, {
|
||||
"mouse",
|
||||
&GUID_SysMouse, &c_dfDIMouse,
|
||||
(DISCL_FOREGROUND | DISCL_NONEXCLUSIVE),
|
||||
(DISCL_FOREGROUND | DISCL_EXCLUSIVE), handle_mouse}, {
|
||||
NULL, NULL, NULL, 0, 0, NULL}
|
||||
};
|
||||
|
||||
static int
|
||||
DX5_DInputInit(_THIS)
|
||||
{
|
||||
int i;
|
||||
LPDIRECTINPUTDEVICE device;
|
||||
HRESULT result;
|
||||
DIPROPDWORD dipdw;
|
||||
HWND topwnd;
|
||||
|
||||
/* Create the DirectInput object */
|
||||
result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION, &dinput, NULL);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInputCreate", result);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Create all of our registered input devices */
|
||||
SDL_DIndev = 0;
|
||||
for (i = 0; inputs[i].name; ++i) {
|
||||
/* Create the DirectInput device */
|
||||
result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
|
||||
&device, NULL);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInput::CreateDevice", result);
|
||||
return (-1);
|
||||
}
|
||||
result = IDirectInputDevice_QueryInterface(device,
|
||||
&IID_IDirectInputDevice2,
|
||||
(LPVOID *) & SDL_DIdev[i]);
|
||||
IDirectInputDevice_Release(device);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInputDevice::QueryInterface", result);
|
||||
return (-1);
|
||||
}
|
||||
topwnd = GetTopLevelParent(SDL_Window);
|
||||
result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
|
||||
topwnd,
|
||||
inputs[i].win_level);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInputDevice::SetCooperativeLevel", result);
|
||||
return (-1);
|
||||
}
|
||||
result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
|
||||
inputs[i].format);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInputDevice::SetDataFormat", result);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Set buffered input -- we aren't polling */
|
||||
SDL_memset(&dipdw, 0, sizeof(dipdw));
|
||||
dipdw.diph.dwSize = sizeof(dipdw);
|
||||
dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
|
||||
dipdw.diph.dwObj = 0;
|
||||
dipdw.diph.dwHow = DIPH_DEVICE;
|
||||
dipdw.dwData = INPUT_QSIZE;
|
||||
result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
|
||||
DIPROP_BUFFERSIZE,
|
||||
&dipdw.diph);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInputDevice::SetProperty", result);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Create an event to be signaled when input is ready */
|
||||
SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (SDL_DIevt[i] == NULL) {
|
||||
SDL_SetError("Couldn't create DirectInput event");
|
||||
return (-1);
|
||||
}
|
||||
result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
|
||||
SDL_DIevt[i]);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInputDevice::SetEventNotification", result);
|
||||
return (-1);
|
||||
}
|
||||
SDL_DIfun[i] = inputs[i].fun;
|
||||
|
||||
/* Acquire the device for input */
|
||||
IDirectInputDevice2_Acquire(SDL_DIdev[i]);
|
||||
|
||||
/* Increment the number of devices we have */
|
||||
++SDL_DIndev;
|
||||
}
|
||||
mouse_pressed = 0;
|
||||
mouse_buttons_swapped = GetSystemMetrics(SM_SWAPBUTTON);
|
||||
|
||||
/* DirectInput is ready! */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Clean up DirectInput */
|
||||
static void
|
||||
DX5_DInputQuit(_THIS)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dinput != NULL) {
|
||||
/* Close and release all DirectInput devices */
|
||||
for (i = 0; i < MAX_INPUTS; ++i) {
|
||||
if (SDL_DIdev[i] != NULL) {
|
||||
IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
|
||||
IDirectInputDevice2_SetEventNotification(SDL_DIdev[i], NULL);
|
||||
if (SDL_DIevt[i] != NULL) {
|
||||
CloseHandle(SDL_DIevt[i]);
|
||||
SDL_DIevt[i] = NULL;
|
||||
}
|
||||
IDirectInputDevice2_Release(SDL_DIdev[i]);
|
||||
SDL_DIdev[i] = NULL;
|
||||
}
|
||||
}
|
||||
/* Release DirectInput */
|
||||
IDirectInput_Release(dinput);
|
||||
dinput = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flag to tell SDL whether or not we queued an event */
|
||||
static int posted = 0;
|
||||
|
||||
/* Input event handler functions */
|
||||
static void
|
||||
handle_keyboard(const int numevents, DIDEVICEOBJECTDATA * keybuf)
|
||||
{
|
||||
int i;
|
||||
SDL_keysym keysym;
|
||||
|
||||
/* Translate keyboard messages */
|
||||
for (i = 0; i < numevents; ++i) {
|
||||
if (keybuf[i].dwData & 0x80) {
|
||||
posted = SDL_PrivateKeyboard(SDL_PRESSED,
|
||||
TranslateKey(keybuf[i].dwOfs,
|
||||
&keysym, 1));
|
||||
} else {
|
||||
posted = SDL_PrivateKeyboard(SDL_RELEASED,
|
||||
TranslateKey(keybuf[i].dwOfs,
|
||||
&keysym, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
static void
|
||||
handle_mouse(const int numevents, DIDEVICEOBJECTDATA * ptrbuf)
|
||||
{
|
||||
int i;
|
||||
Sint16 xrel, yrel;
|
||||
Uint8 state;
|
||||
Uint8 button;
|
||||
DWORD timestamp = 0;
|
||||
|
||||
/* Sanity check. Mailing list reports this being NULL unexpectedly. */
|
||||
if (SDL_PublicSurface == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we are in windowed mode, Windows is taking care of the mouse */
|
||||
if ((SDL_PublicSurface->flags & SDL_INTERNALOPENGL) ||
|
||||
!(SDL_PublicSurface->flags & SDL_FULLSCREEN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the mouse was lost, regain some sense of mouse state */
|
||||
if (mouse_lost) {
|
||||
POINT mouse_pos;
|
||||
Uint8 old_state;
|
||||
Uint8 new_state;
|
||||
|
||||
/* Set ourselves up with the current cursor position */
|
||||
GetCursorPos(&mouse_pos);
|
||||
ScreenToClient(SDL_Window, &mouse_pos);
|
||||
posted = SDL_PrivateMouseMotion(0, 0,
|
||||
(Sint16) mouse_pos.x,
|
||||
(Sint16) mouse_pos.y);
|
||||
|
||||
/* Check for mouse button changes */
|
||||
old_state = SDL_GetMouseState(NULL, NULL);
|
||||
new_state = 0;
|
||||
{ /* Get the new DirectInput button state for the mouse */
|
||||
DIMOUSESTATE distate;
|
||||
HRESULT result;
|
||||
|
||||
result = IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
|
||||
sizeof(distate),
|
||||
&distate);
|
||||
if (result != DI_OK) {
|
||||
/* Try again next time */
|
||||
SetDIerror("IDirectInputDevice2::GetDeviceState", result);
|
||||
return;
|
||||
}
|
||||
for (i = 3; i >= 0; --i) {
|
||||
if ((distate.rgbButtons[i] & 0x80) == 0x80) {
|
||||
new_state |= 0x01;
|
||||
}
|
||||
new_state <<= 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if ((old_state & 0x01) != (new_state & 0x01)) {
|
||||
button = (Uint8) (i + 1);
|
||||
/* Button #2 on two button mice is button 3
|
||||
(the middle button is button 2)
|
||||
*/
|
||||
if (button == 2) {
|
||||
button = 3;
|
||||
} else if (button == 3) {
|
||||
button = 2;
|
||||
}
|
||||
if (new_state & 0x01) {
|
||||
/* Grab mouse so we get mouse-up */
|
||||
if (++mouse_pressed > 0) {
|
||||
SetCapture(SDL_Window);
|
||||
}
|
||||
state = SDL_PRESSED;
|
||||
} else {
|
||||
/* Release mouse after all mouse-ups */
|
||||
if (--mouse_pressed <= 0) {
|
||||
ReleaseCapture();
|
||||
mouse_pressed = 0;
|
||||
}
|
||||
state = SDL_RELEASED;
|
||||
}
|
||||
if (mouse_buttons_swapped) {
|
||||
if (button == 1)
|
||||
button = 3;
|
||||
else if (button == 3)
|
||||
button = 1;
|
||||
}
|
||||
posted = SDL_PrivateMouseButton(state, button, 0, 0);
|
||||
}
|
||||
old_state >>= 1;
|
||||
new_state >>= 1;
|
||||
}
|
||||
mouse_lost = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Translate mouse messages */
|
||||
xrel = 0;
|
||||
yrel = 0;
|
||||
for (i = 0; i < (int) numevents; ++i) {
|
||||
switch (ptrbuf[i].dwOfs) {
|
||||
case DIMOFS_X:
|
||||
if (timestamp != ptrbuf[i].dwTimeStamp) {
|
||||
if (xrel || yrel) {
|
||||
posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
|
||||
xrel = 0;
|
||||
yrel = 0;
|
||||
}
|
||||
timestamp = ptrbuf[i].dwTimeStamp;
|
||||
}
|
||||
xrel += (Sint16) ptrbuf[i].dwData;
|
||||
break;
|
||||
case DIMOFS_Y:
|
||||
if (timestamp != ptrbuf[i].dwTimeStamp) {
|
||||
if (xrel || yrel) {
|
||||
posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
|
||||
xrel = 0;
|
||||
yrel = 0;
|
||||
}
|
||||
timestamp = ptrbuf[i].dwTimeStamp;
|
||||
}
|
||||
yrel += (Sint16) ptrbuf[i].dwData;
|
||||
break;
|
||||
case DIMOFS_Z:
|
||||
if (xrel || yrel) {
|
||||
posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
|
||||
xrel = 0;
|
||||
yrel = 0;
|
||||
}
|
||||
timestamp = 0;
|
||||
if ((int) ptrbuf[i].dwData > 0)
|
||||
button = SDL_BUTTON_WHEELUP;
|
||||
else
|
||||
button = SDL_BUTTON_WHEELDOWN;
|
||||
posted = SDL_PrivateMouseButton(SDL_PRESSED, button, 0, 0);
|
||||
posted |= SDL_PrivateMouseButton(SDL_RELEASED, button, 0, 0);
|
||||
break;
|
||||
case DIMOFS_BUTTON0:
|
||||
case DIMOFS_BUTTON1:
|
||||
case DIMOFS_BUTTON2:
|
||||
case DIMOFS_BUTTON3:
|
||||
if (xrel || yrel) {
|
||||
posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
|
||||
xrel = 0;
|
||||
yrel = 0;
|
||||
}
|
||||
timestamp = 0;
|
||||
button = (Uint8) (ptrbuf[i].dwOfs - DIMOFS_BUTTON0) + 1;
|
||||
/* Button #2 on two button mice is button 3
|
||||
(the middle button is button 2)
|
||||
*/
|
||||
if (button == 2) {
|
||||
button = 3;
|
||||
} else if (button == 3) {
|
||||
button = 2;
|
||||
}
|
||||
if (ptrbuf[i].dwData & 0x80) {
|
||||
/* Grab mouse so we get mouse-up */
|
||||
if (++mouse_pressed > 0) {
|
||||
SetCapture(SDL_Window);
|
||||
}
|
||||
state = SDL_PRESSED;
|
||||
} else {
|
||||
/* Release mouse after all mouse-ups */
|
||||
if (--mouse_pressed <= 0) {
|
||||
ReleaseCapture();
|
||||
mouse_pressed = 0;
|
||||
}
|
||||
state = SDL_RELEASED;
|
||||
}
|
||||
if (mouse_buttons_swapped) {
|
||||
if (button == 1)
|
||||
button = 3;
|
||||
else if (button == 3)
|
||||
button = 1;
|
||||
}
|
||||
posted = SDL_PrivateMouseButton(state, button, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (xrel || yrel) {
|
||||
posted = SDL_PrivateMouseMotion(0, 1, xrel, yrel);
|
||||
}
|
||||
}
|
||||
|
||||
/* The main Win32 event handler */
|
||||
LRESULT
|
||||
DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg) {
|
||||
#ifdef WM_ACTIVATEAPP
|
||||
case WM_ACTIVATEAPP:
|
||||
{
|
||||
int i, active;
|
||||
|
||||
active = (wParam && (GetForegroundWindow() == hwnd));
|
||||
if (active) {
|
||||
for (i = 0; SDL_DIdev[i]; ++i) {
|
||||
IDirectInputDevice2_Acquire(SDL_DIdev[i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; SDL_DIdev[i]; ++i) {
|
||||
IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
|
||||
}
|
||||
mouse_lost = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* WM_ACTIVATEAPP */
|
||||
|
||||
#ifdef WM_DISPLAYCHANGE
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
WPARAM BitsPerPixel;
|
||||
WORD SizeX, SizeY;
|
||||
|
||||
/* Ack! The display changed size and/or depth! */
|
||||
SizeX = LOWORD(lParam);
|
||||
SizeY = HIWORD(lParam);
|
||||
BitsPerPixel = wParam;
|
||||
/* We cause this message when we go fullscreen */
|
||||
}
|
||||
break;
|
||||
#endif /* WM_DISPLAYCHANGE */
|
||||
|
||||
/* The keyboard is handled via DirectInput */
|
||||
case WM_SYSKEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
/* Pass syskey to DefWindwoProc (ALT-F4, etc.) */
|
||||
}
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
/* Ignore windows keyboard messages */ ;
|
||||
}
|
||||
return (0);
|
||||
|
||||
#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER)
|
||||
/* Don't allow screen savers or monitor power downs.
|
||||
This is because they quietly clear DirectX surfaces.
|
||||
It would be better to allow the application to
|
||||
decide whether or not to blow these off, but the
|
||||
semantics of SDL_PrivateSysWMEvent() don't allow
|
||||
the application that choice.
|
||||
*/
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
|
||||
(wParam & 0xFFF0) == SC_MONITORPOWER)
|
||||
return (0);
|
||||
}
|
||||
/* Fall through to default processing */
|
||||
|
||||
#endif /* SC_SCREENSAVE || SC_MONITORPOWER */
|
||||
|
||||
default:
|
||||
{
|
||||
/* Only post the event if we're watching for it */
|
||||
if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
|
||||
SDL_SysWMmsg wmmsg;
|
||||
|
||||
SDL_VERSION(&wmmsg.version);
|
||||
wmmsg.hwnd = hwnd;
|
||||
wmmsg.msg = msg;
|
||||
wmmsg.wParam = wParam;
|
||||
wmmsg.lParam = lParam;
|
||||
posted = SDL_PrivateSysWMEvent(&wmmsg);
|
||||
|
||||
/* DJM: If the user isn't watching for private
|
||||
messages in her SDL event loop, then pass it
|
||||
along to any win32 specific window proc.
|
||||
*/
|
||||
} else if (userWindowProc) {
|
||||
return CallWindowProc(userWindowProc, hwnd, msg, wParam,
|
||||
lParam);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (DefWindowProc(hwnd, msg, wParam, lParam));
|
||||
}
|
||||
|
||||
/* This function checks the windows message queue and DirectInput and returns
|
||||
1 if there was input, 0 if there was no input, or -1 if the application has
|
||||
posted a quit message.
|
||||
*/
|
||||
static int
|
||||
DX5_CheckInput(_THIS, int timeout, BOOL processInput)
|
||||
{
|
||||
MSG msg;
|
||||
int i;
|
||||
HRESULT result;
|
||||
DWORD event;
|
||||
|
||||
/* Check the normal windows queue (highest preference) */
|
||||
posted = 0;
|
||||
while (!posted && PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
||||
if (GetMessage(&msg, NULL, 0, 0) > 0) {
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (posted) {
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Pump the DirectInput flow */
|
||||
if (SDL_GetAppState() & SDL_APPINPUTFOCUS) {
|
||||
for (i = 0; i < SDL_DIndev; ++i) {
|
||||
result = IDirectInputDevice2_Poll(SDL_DIdev[i]);
|
||||
if ((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED)) {
|
||||
if (SDL_strcmp(inputs[i].name, "mouse") == 0) {
|
||||
mouse_lost = 1;
|
||||
}
|
||||
IDirectInputDevice2_Acquire(SDL_DIdev[i]);
|
||||
IDirectInputDevice2_Poll(SDL_DIdev[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for messages and input events */
|
||||
event = MsgWaitForMultipleObjects(SDL_DIndev, SDL_DIevt, FALSE,
|
||||
timeout, QS_ALLEVENTS);
|
||||
if ((event >= WAIT_OBJECT_0) && (event < (WAIT_OBJECT_0 + SDL_DIndev))) {
|
||||
DWORD numevents;
|
||||
static DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
|
||||
|
||||
event -= WAIT_OBJECT_0;
|
||||
numevents = INPUT_QSIZE;
|
||||
result =
|
||||
IDirectInputDevice2_GetDeviceData(SDL_DIdev[event],
|
||||
sizeof(DIDEVICEOBJECTDATA),
|
||||
evtbuf, &numevents, 0);
|
||||
if ((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED)) {
|
||||
if (SDL_strcmp(inputs[event].name, "mouse") == 0) {
|
||||
mouse_lost = 1;
|
||||
}
|
||||
IDirectInputDevice2_Acquire(SDL_DIdev[event]);
|
||||
result =
|
||||
IDirectInputDevice2_GetDeviceData(SDL_DIdev[event],
|
||||
sizeof
|
||||
(DIDEVICEOBJECTDATA),
|
||||
evtbuf, &numevents, 0);
|
||||
}
|
||||
/* Handle the events */
|
||||
if (result == DI_OK && processInput) {
|
||||
/* Note: This can post multiple events to event queue
|
||||
*/
|
||||
(*SDL_DIfun[event]) ((int) numevents, evtbuf);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
if (event != WAIT_TIMEOUT) {
|
||||
/* Maybe there was a windows message? */
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
||||
if (GetMessage(&msg, NULL, 0, 0) > 0) {
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Change cooperative level based on whether or not we are fullscreen */
|
||||
void
|
||||
DX5_DInputReset(_THIS, int fullscreen)
|
||||
{
|
||||
DWORD level;
|
||||
int i;
|
||||
HRESULT result;
|
||||
HWND topwnd;
|
||||
|
||||
for (i = 0; i < MAX_INPUTS; ++i) {
|
||||
if (SDL_DIdev[i] != NULL) {
|
||||
if (fullscreen) {
|
||||
level = inputs[i].raw_level;
|
||||
} else {
|
||||
level = inputs[i].win_level;
|
||||
}
|
||||
IDirectInputDevice2_Unacquire(SDL_DIdev[i]);
|
||||
topwnd = GetTopLevelParent(SDL_Window);
|
||||
result =
|
||||
IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
|
||||
topwnd, level);
|
||||
IDirectInputDevice2_Acquire(SDL_DIdev[i]);
|
||||
if (result != DI_OK) {
|
||||
SetDIerror("DirectInputDevice::SetCooperativeLevel", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
mouse_lost = 1;
|
||||
|
||||
/* Flush pending input */
|
||||
DX5_CheckInput(this, 0, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
DX5_PumpEvents(_THIS)
|
||||
{
|
||||
/* Wait for messages and DirectInput */
|
||||
while (DX5_CheckInput(this, 0, TRUE) > 0) {
|
||||
/* Loop and check again */ ;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DX5_InitOSKeymap(_THIS)
|
||||
{
|
||||
#ifndef DIK_PAUSE
|
||||
#define DIK_PAUSE 0xC5
|
||||
#endif
|
||||
#ifndef DIK_OEM_102
|
||||
#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */
|
||||
#endif
|
||||
int i;
|
||||
|
||||
/* Map the DIK scancodes to SDL keysyms */
|
||||
for (i = 0; i < SDL_arraysize(DIK_keymap); ++i)
|
||||
DIK_keymap[i] = 0;
|
||||
|
||||
/* Defined DIK_* constants */
|
||||
DIK_keymap[DIK_ESCAPE] = SDLK_ESCAPE;
|
||||
DIK_keymap[DIK_1] = SDLK_1;
|
||||
DIK_keymap[DIK_2] = SDLK_2;
|
||||
DIK_keymap[DIK_3] = SDLK_3;
|
||||
DIK_keymap[DIK_4] = SDLK_4;
|
||||
DIK_keymap[DIK_5] = SDLK_5;
|
||||
DIK_keymap[DIK_6] = SDLK_6;
|
||||
DIK_keymap[DIK_7] = SDLK_7;
|
||||
DIK_keymap[DIK_8] = SDLK_8;
|
||||
DIK_keymap[DIK_9] = SDLK_9;
|
||||
DIK_keymap[DIK_0] = SDLK_0;
|
||||
DIK_keymap[DIK_MINUS] = SDLK_MINUS;
|
||||
DIK_keymap[DIK_EQUALS] = SDLK_EQUALS;
|
||||
DIK_keymap[DIK_BACK] = SDLK_BACKSPACE;
|
||||
DIK_keymap[DIK_TAB] = SDLK_TAB;
|
||||
DIK_keymap[DIK_Q] = SDLK_q;
|
||||
DIK_keymap[DIK_W] = SDLK_w;
|
||||
DIK_keymap[DIK_E] = SDLK_e;
|
||||
DIK_keymap[DIK_R] = SDLK_r;
|
||||
DIK_keymap[DIK_T] = SDLK_t;
|
||||
DIK_keymap[DIK_Y] = SDLK_y;
|
||||
DIK_keymap[DIK_U] = SDLK_u;
|
||||
DIK_keymap[DIK_I] = SDLK_i;
|
||||
DIK_keymap[DIK_O] = SDLK_o;
|
||||
DIK_keymap[DIK_P] = SDLK_p;
|
||||
DIK_keymap[DIK_LBRACKET] = SDLK_LEFTBRACKET;
|
||||
DIK_keymap[DIK_RBRACKET] = SDLK_RIGHTBRACKET;
|
||||
DIK_keymap[DIK_RETURN] = SDLK_RETURN;
|
||||
DIK_keymap[DIK_LCONTROL] = SDLK_LCTRL;
|
||||
DIK_keymap[DIK_A] = SDLK_a;
|
||||
DIK_keymap[DIK_S] = SDLK_s;
|
||||
DIK_keymap[DIK_D] = SDLK_d;
|
||||
DIK_keymap[DIK_F] = SDLK_f;
|
||||
DIK_keymap[DIK_G] = SDLK_g;
|
||||
DIK_keymap[DIK_H] = SDLK_h;
|
||||
DIK_keymap[DIK_J] = SDLK_j;
|
||||
DIK_keymap[DIK_K] = SDLK_k;
|
||||
DIK_keymap[DIK_L] = SDLK_l;
|
||||
DIK_keymap[DIK_SEMICOLON] = SDLK_SEMICOLON;
|
||||
DIK_keymap[DIK_APOSTROPHE] = SDLK_QUOTE;
|
||||
DIK_keymap[DIK_GRAVE] = SDLK_BACKQUOTE;
|
||||
DIK_keymap[DIK_LSHIFT] = SDLK_LSHIFT;
|
||||
DIK_keymap[DIK_BACKSLASH] = SDLK_BACKSLASH;
|
||||
DIK_keymap[DIK_OEM_102] = SDLK_BACKSLASH;
|
||||
DIK_keymap[DIK_Z] = SDLK_z;
|
||||
DIK_keymap[DIK_X] = SDLK_x;
|
||||
DIK_keymap[DIK_C] = SDLK_c;
|
||||
DIK_keymap[DIK_V] = SDLK_v;
|
||||
DIK_keymap[DIK_B] = SDLK_b;
|
||||
DIK_keymap[DIK_N] = SDLK_n;
|
||||
DIK_keymap[DIK_M] = SDLK_m;
|
||||
DIK_keymap[DIK_COMMA] = SDLK_COMMA;
|
||||
DIK_keymap[DIK_PERIOD] = SDLK_PERIOD;
|
||||
DIK_keymap[DIK_SLASH] = SDLK_SLASH;
|
||||
DIK_keymap[DIK_RSHIFT] = SDLK_RSHIFT;
|
||||
DIK_keymap[DIK_MULTIPLY] = SDLK_KP_MULTIPLY;
|
||||
DIK_keymap[DIK_LMENU] = SDLK_LALT;
|
||||
DIK_keymap[DIK_SPACE] = SDLK_SPACE;
|
||||
DIK_keymap[DIK_CAPITAL] = SDLK_CAPSLOCK;
|
||||
DIK_keymap[DIK_F1] = SDLK_F1;
|
||||
DIK_keymap[DIK_F2] = SDLK_F2;
|
||||
DIK_keymap[DIK_F3] = SDLK_F3;
|
||||
DIK_keymap[DIK_F4] = SDLK_F4;
|
||||
DIK_keymap[DIK_F5] = SDLK_F5;
|
||||
DIK_keymap[DIK_F6] = SDLK_F6;
|
||||
DIK_keymap[DIK_F7] = SDLK_F7;
|
||||
DIK_keymap[DIK_F8] = SDLK_F8;
|
||||
DIK_keymap[DIK_F9] = SDLK_F9;
|
||||
DIK_keymap[DIK_F10] = SDLK_F10;
|
||||
DIK_keymap[DIK_NUMLOCK] = SDLK_NUMLOCK;
|
||||
DIK_keymap[DIK_SCROLL] = SDLK_SCROLLOCK;
|
||||
DIK_keymap[DIK_NUMPAD7] = SDLK_KP7;
|
||||
DIK_keymap[DIK_NUMPAD8] = SDLK_KP8;
|
||||
DIK_keymap[DIK_NUMPAD9] = SDLK_KP9;
|
||||
DIK_keymap[DIK_SUBTRACT] = SDLK_KP_MINUS;
|
||||
DIK_keymap[DIK_NUMPAD4] = SDLK_KP4;
|
||||
DIK_keymap[DIK_NUMPAD5] = SDLK_KP5;
|
||||
DIK_keymap[DIK_NUMPAD6] = SDLK_KP6;
|
||||
DIK_keymap[DIK_ADD] = SDLK_KP_PLUS;
|
||||
DIK_keymap[DIK_NUMPAD1] = SDLK_KP1;
|
||||
DIK_keymap[DIK_NUMPAD2] = SDLK_KP2;
|
||||
DIK_keymap[DIK_NUMPAD3] = SDLK_KP3;
|
||||
DIK_keymap[DIK_NUMPAD0] = SDLK_KP0;
|
||||
DIK_keymap[DIK_DECIMAL] = SDLK_KP_PERIOD;
|
||||
DIK_keymap[DIK_F11] = SDLK_F11;
|
||||
DIK_keymap[DIK_F12] = SDLK_F12;
|
||||
|
||||
DIK_keymap[DIK_F13] = SDLK_F13;
|
||||
DIK_keymap[DIK_F14] = SDLK_F14;
|
||||
DIK_keymap[DIK_F15] = SDLK_F15;
|
||||
|
||||
DIK_keymap[DIK_NUMPADEQUALS] = SDLK_KP_EQUALS;
|
||||
DIK_keymap[DIK_NUMPADENTER] = SDLK_KP_ENTER;
|
||||
DIK_keymap[DIK_RCONTROL] = SDLK_RCTRL;
|
||||
DIK_keymap[DIK_DIVIDE] = SDLK_KP_DIVIDE;
|
||||
DIK_keymap[DIK_SYSRQ] = SDLK_PRINT;
|
||||
DIK_keymap[DIK_RMENU] = SDLK_RALT;
|
||||
DIK_keymap[DIK_PAUSE] = SDLK_PAUSE;
|
||||
DIK_keymap[DIK_HOME] = SDLK_HOME;
|
||||
DIK_keymap[DIK_UP] = SDLK_UP;
|
||||
DIK_keymap[DIK_PRIOR] = SDLK_PAGEUP;
|
||||
DIK_keymap[DIK_LEFT] = SDLK_LEFT;
|
||||
DIK_keymap[DIK_RIGHT] = SDLK_RIGHT;
|
||||
DIK_keymap[DIK_END] = SDLK_END;
|
||||
DIK_keymap[DIK_DOWN] = SDLK_DOWN;
|
||||
DIK_keymap[DIK_NEXT] = SDLK_PAGEDOWN;
|
||||
DIK_keymap[DIK_INSERT] = SDLK_INSERT;
|
||||
DIK_keymap[DIK_DELETE] = SDLK_DELETE;
|
||||
DIK_keymap[DIK_LWIN] = SDLK_LMETA;
|
||||
DIK_keymap[DIK_RWIN] = SDLK_RMETA;
|
||||
DIK_keymap[DIK_APPS] = SDLK_MENU;
|
||||
}
|
||||
|
||||
static SDL_keysym *
|
||||
TranslateKey(UINT scancode, SDL_keysym * keysym, int pressed)
|
||||
{
|
||||
/* Set the keysym information */
|
||||
keysym->scancode = (unsigned char) scancode;
|
||||
keysym->sym = DIK_keymap[scancode];
|
||||
keysym->mod = KMOD_NONE;
|
||||
keysym->unicode = 0;
|
||||
if (pressed && SDL_TranslateUNICODE) {
|
||||
UINT vkey;
|
||||
#ifndef NO_GETKEYBOARDSTATE
|
||||
BYTE keystate[256];
|
||||
Uint16 wchars[2];
|
||||
#endif
|
||||
|
||||
vkey = MapVirtualKey(scancode, 1);
|
||||
#ifdef NO_GETKEYBOARDSTATE
|
||||
/* Uh oh, better hope the vkey is close enough.. */
|
||||
keysym->unicode = vkey;
|
||||
#else
|
||||
GetKeyboardState(keystate);
|
||||
if (SDL_ToUnicode
|
||||
(vkey, scancode, keystate, wchars,
|
||||
sizeof(wchars) / sizeof(wchars[0]), 0) == 1) {
|
||||
keysym->unicode = wchars[0];
|
||||
}
|
||||
#endif /* NO_GETKEYBOARDSTATE */
|
||||
}
|
||||
return (keysym);
|
||||
}
|
||||
|
||||
int
|
||||
DX5_CreateWindow(_THIS)
|
||||
{
|
||||
char *windowid = SDL_getenv("SDL_WINDOWID");
|
||||
int i;
|
||||
|
||||
/* Clear out DirectInput variables in case we fail */
|
||||
for (i = 0; i < MAX_INPUTS; ++i) {
|
||||
SDL_DIdev[i] = NULL;
|
||||
SDL_DIevt[i] = NULL;
|
||||
SDL_DIfun[i] = NULL;
|
||||
}
|
||||
|
||||
SDL_RegisterApp(NULL, 0, 0);
|
||||
|
||||
SDL_windowid = (windowid != NULL);
|
||||
if (SDL_windowid) {
|
||||
SDL_Window = (HWND) SDL_strtoull(windowid, NULL, 0);
|
||||
if (SDL_Window == NULL) {
|
||||
SDL_SetError("Couldn't get user specified window");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* DJM: we want all event's for the user specified
|
||||
window to be handled by SDL.
|
||||
*/
|
||||
userWindowProc =
|
||||
(WNDPROCTYPE) GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
|
||||
SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR) WinMessage);
|
||||
} else {
|
||||
SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
|
||||
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
|
||||
| WS_MINIMIZEBOX), CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, 0, 0, NULL, NULL,
|
||||
SDL_Instance, NULL);
|
||||
if (SDL_Window == NULL) {
|
||||
SDL_SetError("Couldn't create window");
|
||||
return (-1);
|
||||
}
|
||||
ShowWindow(SDL_Window, SW_HIDE);
|
||||
}
|
||||
|
||||
/* Initialize DirectInput */
|
||||
if (DX5_DInputInit(this) < 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* JC 14 Mar 2006
|
||||
Flush the message loop or this can cause big problems later
|
||||
Especially if the user decides to use dialog boxes or assert()!
|
||||
*/
|
||||
WIN_FlushMessageQueue();
|
||||
|
||||
/* Ready to roll */
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
DX5_DestroyWindow(_THIS)
|
||||
{
|
||||
/* Close down DirectInput */
|
||||
DX5_DInputQuit(this);
|
||||
|
||||
/* Destroy our window */
|
||||
if (SDL_windowid) {
|
||||
SetWindowLongPtr(SDL_Window, GWLP_WNDPROC, (LONG_PTR) userWindowProc);
|
||||
} else {
|
||||
DestroyWindow(SDL_Window);
|
||||
}
|
||||
SDL_UnregisterApp();
|
||||
|
||||
/* JC 14 Mar 2006
|
||||
Flush the message loop or this can cause big problems later
|
||||
Especially if the user decides to use dialog boxes or assert()!
|
||||
*/
|
||||
WIN_FlushMessageQueue();
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#include "../wincommon/SDL_lowvideo.h"
|
||||
|
||||
/* Variables and functions exported by SDL_dx5events.c to other parts
|
||||
of the native video subsystem (SDL_dx5video.c)
|
||||
*/
|
||||
extern LONG
|
||||
DX5_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
extern int DX5_CreateWindow(_THIS);
|
||||
extern void DX5_DestroyWindow(_THIS);
|
||||
|
||||
extern void DX5_PumpEvents(_THIS);
|
||||
extern void DX5_InitOSKeymap(_THIS);
|
||||
extern void DX5_DInputReset(_THIS, int fullscreen);
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
File diff suppressed because it is too large
Load diff
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#ifndef _SDL_dx5video_h
|
||||
#define _SDL_dx5video_h
|
||||
|
||||
#include "directx.h"
|
||||
|
||||
/* Private display data */
|
||||
struct SDL_PrivateVideoData
|
||||
{
|
||||
LPDIRECTDRAW2 ddraw2;
|
||||
LPDIRECTDRAWSURFACE3 SDL_primary;
|
||||
LPDIRECTDRAWCLIPPER SDL_clipper;
|
||||
LPDIRECTDRAWPALETTE SDL_palette;
|
||||
PALETTEENTRY SDL_colors[256];
|
||||
int colorchange_expected;
|
||||
|
||||
#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
|
||||
int SDL_nummodes[NUM_MODELISTS];
|
||||
SDL_Rect **SDL_modelist[NUM_MODELISTS];
|
||||
int SDL_modeindex[NUM_MODELISTS];
|
||||
};
|
||||
/* Old variable names */
|
||||
#define ddraw2 (this->hidden->ddraw2)
|
||||
#define SDL_primary (this->hidden->SDL_primary)
|
||||
#define SDL_clipper (this->hidden->SDL_clipper)
|
||||
#define SDL_palette (this->hidden->SDL_palette)
|
||||
#define SDL_colors (this->hidden->SDL_colors)
|
||||
#define colorchange_expected (this->hidden->colorchange_expected)
|
||||
#define SDL_nummodes (this->hidden->SDL_nummodes)
|
||||
#define SDL_modelist (this->hidden->SDL_modelist)
|
||||
#define SDL_modeindex (this->hidden->SDL_modeindex)
|
||||
|
||||
/* DirectX function pointers for video and events */
|
||||
extern HRESULT(WINAPI * DDrawCreate) (GUID FAR * lpGUID,
|
||||
LPDIRECTDRAW FAR * lplpDD,
|
||||
IUnknown FAR * pUnkOuter);
|
||||
extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
|
||||
LPDIRECTINPUT * ppDI,
|
||||
LPUNKNOWN punkOuter);
|
||||
|
||||
/* DirectDraw error reporting function */
|
||||
extern void SetDDerror(const char *function, int code);
|
||||
|
||||
#endif /* _SDL_dx5video_h */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,309 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* This is the DirectDraw implementation of YUV video overlays */
|
||||
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_dx5yuv_c.h"
|
||||
#include "../SDL_yuvfuncs.h"
|
||||
|
||||
//#define USE_DIRECTX_OVERLAY
|
||||
|
||||
/* The functions used to manipulate software video overlays */
|
||||
static struct private_yuvhwfuncs dx5_yuvfuncs = {
|
||||
DX5_LockYUVOverlay,
|
||||
DX5_UnlockYUVOverlay,
|
||||
DX5_DisplayYUVOverlay,
|
||||
DX5_FreeYUVOverlay
|
||||
};
|
||||
|
||||
struct private_yuvhwdata
|
||||
{
|
||||
LPDIRECTDRAWSURFACE3 surface;
|
||||
|
||||
/* These are just so we don't have to allocate them separately */
|
||||
Uint16 pitches[3];
|
||||
Uint8 *planes[3];
|
||||
};
|
||||
|
||||
|
||||
static LPDIRECTDRAWSURFACE3
|
||||
CreateYUVSurface(_THIS, int width, int height, Uint32 format)
|
||||
{
|
||||
HRESULT result;
|
||||
LPDIRECTDRAWSURFACE dd_surface1;
|
||||
LPDIRECTDRAWSURFACE3 dd_surface3;
|
||||
DDSURFACEDESC ddsd;
|
||||
|
||||
/* Set up the surface description */
|
||||
SDL_memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT);
|
||||
ddsd.dwWidth = width;
|
||||
ddsd.dwHeight = height;
|
||||
#ifdef USE_DIRECTX_OVERLAY
|
||||
ddsd.ddsCaps.dwCaps = (DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY);
|
||||
#else
|
||||
ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY);
|
||||
#endif
|
||||
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
|
||||
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
|
||||
ddsd.ddpfPixelFormat.dwFourCC = format;
|
||||
|
||||
/* Create the DirectDraw video surface */
|
||||
result = IDirectDraw2_CreateSurface(ddraw2, &ddsd, &dd_surface1, NULL);
|
||||
if (result != DD_OK) {
|
||||
SetDDerror("DirectDraw2::CreateSurface", result);
|
||||
return (NULL);
|
||||
}
|
||||
result = IDirectDrawSurface_QueryInterface(dd_surface1,
|
||||
&IID_IDirectDrawSurface3,
|
||||
(LPVOID *) & dd_surface3);
|
||||
IDirectDrawSurface_Release(dd_surface1);
|
||||
if (result != DD_OK) {
|
||||
SetDDerror("DirectDrawSurface::QueryInterface", result);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Make sure the surface format was set properly */
|
||||
SDL_memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
result = IDirectDrawSurface3_Lock(dd_surface3, NULL,
|
||||
&ddsd, DDLOCK_NOSYSLOCK, NULL);
|
||||
if (result != DD_OK) {
|
||||
SetDDerror("DirectDrawSurface3::Lock", result);
|
||||
IDirectDrawSurface_Release(dd_surface3);
|
||||
return (NULL);
|
||||
}
|
||||
IDirectDrawSurface3_Unlock(dd_surface3, NULL);
|
||||
|
||||
if (!(ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC) ||
|
||||
(ddsd.ddpfPixelFormat.dwFourCC != format)) {
|
||||
SDL_SetError("DDraw didn't use requested FourCC format");
|
||||
IDirectDrawSurface_Release(dd_surface3);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* We're ready to go! */
|
||||
return (dd_surface3);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_YUV
|
||||
static char *
|
||||
PrintFOURCC(Uint32 code)
|
||||
{
|
||||
static char buf[5];
|
||||
|
||||
buf[3] = code >> 24;
|
||||
buf[2] = (code >> 16) & 0xFF;
|
||||
buf[1] = (code >> 8) & 0xFF;
|
||||
buf[0] = (code & 0xFF);
|
||||
return (buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Overlay *
|
||||
DX5_CreateYUVOverlay(_THIS, int width, int height, Uint32 format,
|
||||
SDL_Surface * display)
|
||||
{
|
||||
SDL_Overlay *overlay;
|
||||
struct private_yuvhwdata *hwdata;
|
||||
|
||||
#ifdef DEBUG_YUV
|
||||
DWORD numcodes;
|
||||
DWORD *codes;
|
||||
|
||||
printf("FOURCC format requested: 0x%x\n", PrintFOURCC(format));
|
||||
IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, NULL);
|
||||
if (numcodes) {
|
||||
DWORD i;
|
||||
codes = SDL_malloc(numcodes * sizeof(*codes));
|
||||
if (codes) {
|
||||
IDirectDraw2_GetFourCCCodes(ddraw2, &numcodes, codes);
|
||||
for (i = 0; i < numcodes; ++i) {
|
||||
fprintf(stderr, "Code %d: 0x%x\n", i, PrintFOURCC(codes[i]));
|
||||
}
|
||||
SDL_free(codes);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "No FOURCC codes supported\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create the overlay structure */
|
||||
overlay = (SDL_Overlay *) SDL_malloc(sizeof *overlay);
|
||||
if (overlay == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return (NULL);
|
||||
}
|
||||
SDL_memset(overlay, 0, (sizeof *overlay));
|
||||
|
||||
/* Fill in the basic members */
|
||||
overlay->format = format;
|
||||
overlay->w = width;
|
||||
overlay->h = height;
|
||||
|
||||
/* Set up the YUV surface function structure */
|
||||
overlay->hwfuncs = &dx5_yuvfuncs;
|
||||
|
||||
/* Create the pixel data and lookup tables */
|
||||
hwdata = (struct private_yuvhwdata *) SDL_malloc(sizeof *hwdata);
|
||||
overlay->hwdata = hwdata;
|
||||
if (hwdata == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_FreeYUVOverlay(overlay);
|
||||
return (NULL);
|
||||
}
|
||||
hwdata->surface = CreateYUVSurface(this, width, height, format);
|
||||
if (hwdata->surface == NULL) {
|
||||
SDL_FreeYUVOverlay(overlay);
|
||||
return (NULL);
|
||||
}
|
||||
overlay->hw_overlay = 1;
|
||||
|
||||
/* Set up the plane pointers */
|
||||
overlay->pitches = hwdata->pitches;
|
||||
overlay->pixels = hwdata->planes;
|
||||
switch (format) {
|
||||
case SDL_YV12_OVERLAY:
|
||||
case SDL_IYUV_OVERLAY:
|
||||
overlay->planes = 3;
|
||||
break;
|
||||
default:
|
||||
overlay->planes = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We're all done.. */
|
||||
return (overlay);
|
||||
}
|
||||
|
||||
int
|
||||
DX5_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
|
||||
{
|
||||
HRESULT result;
|
||||
LPDIRECTDRAWSURFACE3 surface;
|
||||
DDSURFACEDESC ddsd;
|
||||
|
||||
surface = overlay->hwdata->surface;
|
||||
SDL_memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
result = IDirectDrawSurface3_Lock(surface, NULL,
|
||||
&ddsd, DDLOCK_NOSYSLOCK, NULL);
|
||||
if (result == DDERR_SURFACELOST) {
|
||||
result = IDirectDrawSurface3_Restore(surface);
|
||||
result = IDirectDrawSurface3_Lock(surface, NULL, &ddsd,
|
||||
(DDLOCK_NOSYSLOCK | DDLOCK_WAIT),
|
||||
NULL);
|
||||
}
|
||||
if (result != DD_OK) {
|
||||
SetDDerror("DirectDrawSurface3::Lock", result);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Find the pitch and offset values for the overlay */
|
||||
#if defined(NONAMELESSUNION)
|
||||
overlay->pitches[0] = (Uint16) ddsd.u1.lPitch;
|
||||
#else
|
||||
overlay->pitches[0] = (Uint16) ddsd.lPitch;
|
||||
#endif
|
||||
overlay->pixels[0] = (Uint8 *) ddsd.lpSurface;
|
||||
switch (overlay->format) {
|
||||
case SDL_YV12_OVERLAY:
|
||||
case SDL_IYUV_OVERLAY:
|
||||
/* Add the two extra planes */
|
||||
overlay->pitches[1] = overlay->pitches[0] / 2;
|
||||
overlay->pitches[2] = overlay->pitches[0] / 2;
|
||||
overlay->pixels[1] = overlay->pixels[0] +
|
||||
overlay->pitches[0] * overlay->h;
|
||||
overlay->pixels[2] = overlay->pixels[1] +
|
||||
overlay->pitches[1] * overlay->h / 2;
|
||||
break;
|
||||
default:
|
||||
/* Only one plane, no worries */
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
DX5_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
|
||||
{
|
||||
LPDIRECTDRAWSURFACE3 surface;
|
||||
|
||||
surface = overlay->hwdata->surface;
|
||||
IDirectDrawSurface3_Unlock(surface, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
DX5_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
|
||||
SDL_Rect * dst)
|
||||
{
|
||||
HRESULT result;
|
||||
LPDIRECTDRAWSURFACE3 surface;
|
||||
RECT srcrect, dstrect;
|
||||
|
||||
surface = overlay->hwdata->surface;
|
||||
srcrect.top = src->y;
|
||||
srcrect.bottom = srcrect.top + src->h;
|
||||
srcrect.left = src->x;
|
||||
srcrect.right = srcrect.left + src->w;
|
||||
dstrect.top = SDL_bounds.top + dst->y;
|
||||
dstrect.left = SDL_bounds.left + dst->x;
|
||||
dstrect.bottom = dstrect.top + dst->h;
|
||||
dstrect.right = dstrect.left + dst->w;
|
||||
#ifdef USE_DIRECTX_OVERLAY
|
||||
result = IDirectDrawSurface3_UpdateOverlay(surface, &srcrect,
|
||||
SDL_primary, &dstrect,
|
||||
DDOVER_SHOW, NULL);
|
||||
if (result != DD_OK) {
|
||||
SetDDerror("DirectDrawSurface3::UpdateOverlay", result);
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
result =
|
||||
IDirectDrawSurface3_Blt(SDL_primary, &dstrect, surface, &srcrect,
|
||||
DDBLT_WAIT, NULL);
|
||||
if (result != DD_OK) {
|
||||
SetDDerror("DirectDrawSurface3::Blt", result);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
DX5_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
|
||||
{
|
||||
struct private_yuvhwdata *hwdata;
|
||||
|
||||
hwdata = overlay->hwdata;
|
||||
if (hwdata) {
|
||||
if (hwdata->surface) {
|
||||
IDirectDrawSurface_Release(hwdata->surface);
|
||||
}
|
||||
SDL_free(hwdata);
|
||||
}
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2006 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* This is the DirectDraw implementation of YUV video overlays */
|
||||
|
||||
#include "SDL_video.h"
|
||||
#include "../wincommon/SDL_lowvideo.h"
|
||||
#include "SDL_dx5video.h"
|
||||
|
||||
extern SDL_Overlay *DX5_CreateYUVOverlay(_THIS, int width, int height,
|
||||
Uint32 format,
|
||||
SDL_Surface * display);
|
||||
|
||||
extern int DX5_LockYUVOverlay(_THIS, SDL_Overlay * overlay);
|
||||
|
||||
extern void DX5_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay);
|
||||
|
||||
extern int DX5_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay,
|
||||
SDL_Rect * src, SDL_Rect * dst);
|
||||
|
||||
extern void DX5_FreeYUVOverlay(_THIS, SDL_Overlay * overlay);
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -1,85 +0,0 @@
|
|||
|
||||
#ifndef _directx_h
|
||||
#define _directx_h
|
||||
|
||||
/* Include all of the DirectX 5.0 headers and adds any necessary tweaks */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#ifndef WIN32
|
||||
#define WIN32
|
||||
#endif
|
||||
#undef WINNT
|
||||
|
||||
/* Far pointers don't exist in 32-bit code */
|
||||
#ifndef FAR
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
/* Error codes not yet included in Win32 API header files */
|
||||
#ifndef MAKE_HRESULT
|
||||
#define MAKE_HRESULT(sev,fac,code) \
|
||||
((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
|
||||
#endif
|
||||
|
||||
#ifndef S_OK
|
||||
#define S_OK (HRESULT)0x00000000L
|
||||
#endif
|
||||
|
||||
#ifndef SUCCEEDED
|
||||
#define SUCCEEDED(x) ((HRESULT)(x) >= 0)
|
||||
#endif
|
||||
#ifndef FAILED
|
||||
#define FAILED(x) ((HRESULT)(x)<0)
|
||||
#endif
|
||||
|
||||
#ifndef E_FAIL
|
||||
#define E_FAIL (HRESULT)0x80000008L
|
||||
#endif
|
||||
#ifndef E_NOINTERFACE
|
||||
#define E_NOINTERFACE (HRESULT)0x80004002L
|
||||
#endif
|
||||
#ifndef E_OUTOFMEMORY
|
||||
#define E_OUTOFMEMORY (HRESULT)0x8007000EL
|
||||
#endif
|
||||
#ifndef E_INVALIDARG
|
||||
#define E_INVALIDARG (HRESULT)0x80070057L
|
||||
#endif
|
||||
#ifndef E_NOTIMPL
|
||||
#define E_NOTIMPL (HRESULT)0x80004001L
|
||||
#endif
|
||||
#ifndef REGDB_E_CLASSNOTREG
|
||||
#define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L
|
||||
#endif
|
||||
|
||||
/* Severity codes */
|
||||
#ifndef SEVERITY_ERROR
|
||||
#define SEVERITY_ERROR 1
|
||||
#endif
|
||||
|
||||
/* Error facility codes */
|
||||
#ifndef FACILITY_WIN32
|
||||
#define FACILITY_WIN32 7
|
||||
#endif
|
||||
|
||||
#ifndef FIELD_OFFSET
|
||||
#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
|
||||
#endif
|
||||
|
||||
/* DirectX headers (if it isn't included, I haven't tested it yet)
|
||||
*/
|
||||
/* We need these defines to mark what version of DirectX API we use */
|
||||
#define DIRECTDRAW_VERSION 0x0700
|
||||
#define DIRECTSOUND_VERSION 0x0500
|
||||
#define DIRECTINPUT_VERSION 0x0500
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define NONAMELESSUNION
|
||||
#endif
|
||||
#include <ddraw.h>
|
||||
#include <dsound.h>
|
||||
#include <dinput.h>
|
||||
|
||||
#endif /* _directx_h */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
Loading…
Add table
Add a link
Reference in a new issue