Fixed issue with shared OpenGL context not being activated.

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1183 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
ceylo 2009-07-21 16:56:52 +00:00
parent a430319c43
commit e40eb2e64d
6 changed files with 234 additions and 249 deletions

View File

@ -30,8 +30,6 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#define SharedAppController [AppController sharedController]
// Fade operations // Fade operations
enum { enum {
FillScreen, FillScreen,

View File

@ -33,9 +33,6 @@
#import <iostream> #import <iostream>
// AppController singleton object
static AppController *shared = nil;
/* setAppleMenu disappeared from the headers in 10.4 */ /* setAppleMenu disappeared from the headers in 10.4 */
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
@ -83,6 +80,11 @@ static AppController *shared = nil;
// Make the app autorelease pool // Make the app autorelease pool
myMainPool = [[NSAutoreleasePool alloc] init]; myMainPool = [[NSAutoreleasePool alloc] init];
if (!myMainPool) {
[self release];
throw std::bad_alloc();
}
// Don't go on if the user handles the app // Don't go on if the user handles the app
if (![NSApp isRunning]) if (![NSApp isRunning])
{ {
@ -96,7 +98,10 @@ static AppController *shared = nil;
} }
// Make the app // Make the app
[NSApplication sharedApplication]; if (![NSApplication sharedApplication]) {
[self release];
throw std::bad_alloc();
}
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// I want to go back to the desktop mode // I want to go back to the desktop mode
@ -134,7 +139,7 @@ static AppController *shared = nil;
- (void)dealloc - (void)dealloc
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
[myFullscreenWrapper release]; [myMainPool release];
[super dealloc]; [super dealloc];
} }
@ -144,9 +149,8 @@ static AppController *shared = nil;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
+ (AppController *)sharedController + (AppController *)sharedController
{ {
if (nil == shared) // AppController singleton object
shared = [[AppController alloc] init]; static AppController *shared = [[AppController alloc] init];
return shared; return shared;
} }
@ -216,10 +220,6 @@ static AppController *shared = nil;
{ {
if (myFullscreenWrapper) if (myFullscreenWrapper)
[self setFullscreenWindow:nil mode:NULL]; [self setFullscreenWindow:nil mode:NULL];
// FIXME: should I really do this ? what about the user owned windows ?
// And is this really useful as the application is about to exit ?
[NSApp makeWindowsPerform:@selector(close) inOrder:NO];
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -266,10 +266,10 @@ static AppController *shared = nil;
keyEquivalent:@"h"]; keyEquivalent:@"h"];
// + 'Hide other' menu item // + 'Hide other' menu item
menuItem = reinterpret_cast <NSMenuItem *> ([appleMenu addItemWithTitle:@"Hide Others" menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:) action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]); keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; [menuItem setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
// + 'Show all' menu item // + 'Show all' menu item
[appleMenu addItemWithTitle:@"Show All" [appleMenu addItemWithTitle:@"Show All"

View File

@ -34,7 +34,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@interface GLContext : NSOpenGLContext @interface GLContext : NSOpenGLContext
{ {
GLContext *mySharedContext;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -94,27 +94,13 @@
@end @end
////////////////////////////////////////////////////////////
/// Cocoa window implementation to let fullscreen windows
/// catch key events
////////////////////////////////////////////////////////////
@interface GLWindow : NSWindow
////////////////////////////////////////////////////////////
/// Technical note: this class must neither contain new members
/// nor methods. It is used transparently as a NSWindow object
/// by WindowWrapper. Not following this rule could result
/// in a segmentation fault or data corruption.
////////////////////////////////////////////////////////////
@end
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// WindowWrapper class : handles both imported and self-built windows /// WindowWrapper class : handles both imported and self-built windows
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@interface WindowWrapper : NSObject @interface WindowWrapper : NSObject
{ {
GLWindow *myWindow; NSWindow *myWindow;
GLView *myView; GLView *myView;
sf::VideoMode myFullscreenMode; sf::VideoMode myFullscreenMode;
bool myIsFullscreen; bool myIsFullscreen;

View File

@ -29,7 +29,6 @@
#import <SFML/Window/Cocoa/AppController.h> #import <SFML/Window/Cocoa/AppController.h>
#import <SFML/Window/VideoMode.hpp> #import <SFML/Window/VideoMode.hpp>
#import <SFML/Window/WindowStyle.hpp> #import <SFML/Window/WindowStyle.hpp>
#import <SFML/System/Sleep.hpp>
#import <OpenGL/gl.h> #import <OpenGL/gl.h>
#import <iostream> #import <iostream>
@ -39,26 +38,21 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@implementation GLContext @implementation GLContext
static GLContext *sharedCtx = nil;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Return the shared OpenGL context instance (making one if needed) /// Return the shared OpenGL context instance (making one if needed)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
+ (id)sharedContext + (id)sharedContext
{ {
if (sharedCtx == nil) // Make a new context with the default parameters
{ sf::WindowSettings params;
// Make a new context with the default parameters static GLContext *sharedCtx = [[GLContext alloc] initWithAttributes:params sharedContext:nil];
sf::WindowSettings params(0, 0, 0);
sharedCtx = [[GLContext alloc] initWithAttributes:params sharedContext:nil];
}
return sharedCtx; return sharedCtx;
} }
- (void)dealloc - (void)dealloc
{ {
[mySharedContext release]; [[GLContext sharedContext] release];
[super dealloc]; [super dealloc];
} }
@ -66,7 +60,7 @@ static GLContext *sharedCtx = nil;
/// Make a new OpenGL context according to the @attribs settings /// Make a new OpenGL context according to the @attribs settings
/// and the shared context @context /// and the shared context @context
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
- (id)initWithAttributes:(sf::WindowSettings&)attribs sharedContext:(GLContext *)context - (id)initWithAttributes:(sf::WindowSettings&)attribs sharedContext:(GLContext *)sharedContext
{ {
// Note about antialiasing and other context attributes : // Note about antialiasing and other context attributes :
// OpenGL context sharing does not allow the shared contexts to use different attributes. // OpenGL context sharing does not allow the shared contexts to use different attributes.
@ -94,15 +88,15 @@ static GLContext *sharedCtx = nil;
// windowed context (even fullscreen mode uses a window) // windowed context (even fullscreen mode uses a window)
ctxtAttribs[idx++] = NSOpenGLPFAWindow; ctxtAttribs[idx++] = NSOpenGLPFAWindow;
// Color size ; usually 32 bits per pixel // Color buffer bits ; usually 32 bits per pixel
ctxtAttribs[idx++] = NSOpenGLPFAColorSize; ctxtAttribs[idx++] = NSOpenGLPFAColorSize;
ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) sf::VideoMode::GetDesktopMode().BitsPerPixel; ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) sf::VideoMode::GetDesktopMode().BitsPerPixel;
// Z-buffer size // Depth buffer size
ctxtAttribs[idx++] = NSOpenGLPFADepthSize; ctxtAttribs[idx++] = NSOpenGLPFADepthSize;
ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.DepthBits; ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.DepthBits;
// Stencil bits (I don't really know what's that...) // Stencil buffer bits
ctxtAttribs[idx++] = NSOpenGLPFAStencilSize; ctxtAttribs[idx++] = NSOpenGLPFAStencilSize;
ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.StencilBits; ctxtAttribs[idx++] = (NSOpenGLPixelFormatAttribute) attribs.StencilBits;
@ -110,9 +104,7 @@ static GLContext *sharedCtx = nil;
if (myPixelFormat) { if (myPixelFormat) {
self = [super initWithFormat:myPixelFormat self = [super initWithFormat:myPixelFormat
shareContext:context]; shareContext:[sharedContext retain]];
mySharedContext = [context retain];
// Get the effective properties from our OpenGL context // Get the effective properties from our OpenGL context
GLint tmpDepthSize = 0, tmpStencilBits = 0, tmpAntialiasingLevel = 0; GLint tmpDepthSize = 0, tmpStencilBits = 0, tmpAntialiasingLevel = 0;
@ -172,7 +164,13 @@ static GLContext *sharedCtx = nil;
[self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
// make the OpenGL context // make the OpenGL context
myGLContext = [[GLContext alloc] initWithAttributes:settings sharedContext:sharedCtx]; myGLContext = [[GLContext alloc] initWithAttributes:settings
sharedContext:[GLContext sharedContext]];
if (!myGLContext) {
[self release];
return nil;
}
// We need to update the OpenGL view when it's resized // We need to update the OpenGL view when it's resized
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
@ -417,10 +415,10 @@ static GLContext *sharedCtx = nil;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Cocoa window implementation to let fullscreen windows /// Cocoa window category to let fullscreen windows
/// catch key events /// catch key events
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@implementation GLWindow @implementation NSWindow (GLWindow)
- (BOOL)canBecomeKeyWindow - (BOOL)canBecomeKeyWindow
{ {
@ -501,7 +499,7 @@ static GLContext *sharedCtx = nil;
if (self) if (self)
{ {
if (window) { if (window) {
myWindow = (GLWindow *)[window retain]; myWindow = [window retain];
} else { } else {
assert(title != nil); assert(title != nil);
@ -563,7 +561,7 @@ static GLContext *sharedCtx = nil;
// Now we make the window with the values we got // Now we make the window with the values we got
// Note: defer flag set to NO to be able to use OpenGL in our window // Note: defer flag set to NO to be able to use OpenGL in our window
myWindow = [[GLWindow alloc] initWithContentRect:frame myWindow = [[NSWindow alloc] initWithContentRect:frame
styleMask:mask styleMask:mask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]; defer:NO];
@ -646,7 +644,7 @@ static GLContext *sharedCtx = nil;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
- (void)dealloc - (void)dealloc
{ {
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
// Remove the notification observer // Remove the notification observer
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
@ -654,10 +652,13 @@ static GLContext *sharedCtx = nil;
[self show:false]; [self show:false];
// Release the window and view // Release the window and view
[myView removeFromSuperviewWithoutNeedingDisplay];
[myView release]; [myView release];
[myWindow release]; [myWindow release];
[super dealloc]; [super dealloc];
[localPool release];
} }
@ -758,7 +759,7 @@ static GLContext *sharedCtx = nil;
// Wanna open the closed window // Wanna open the closed window
if (myIsFullscreen) { if (myIsFullscreen) {
[SharedAppController setFullscreenWindow:self mode:&myFullscreenMode]; [[AppController sharedController] setFullscreenWindow:self mode:&myFullscreenMode];
} else { } else {
// Show the window // Show the window
[myWindow makeKeyAndOrderFront:nil]; [myWindow makeKeyAndOrderFront:nil];
@ -767,7 +768,7 @@ static GLContext *sharedCtx = nil;
// Wanna close the opened window // Wanna close the opened window
if (myIsFullscreen) { if (myIsFullscreen) {
[SharedAppController setFullscreenWindow:nil mode:NULL]; [[AppController sharedController] setFullscreenWindow:nil mode:NULL];
} else { } else {
// Close the window // Close the window
[myWindow close]; [myWindow close];
@ -849,7 +850,7 @@ static GLContext *sharedCtx = nil;
{ {
NSWindow *sender = [notification object]; NSWindow *sender = [notification object];
if (!([sender styleMask] & NSTitledWindowMask)) if (myIsFullscreen)
[sender center]; [sender center];
} }

View File

@ -33,8 +33,10 @@
#include <string> #include <string>
#ifdef __OBJC__ #ifdef __OBJC__
#import <Cocoa/Cocoa.h>
@class WindowWrapper; @class WindowWrapper;
typedef WindowWrapper* WindowWrapperRef;
#else
typedef void* WindowWrapperRef;
#endif #endif
namespace sf namespace sf
@ -190,13 +192,7 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
WindowWrapperRef myWrapper;
#ifdef __OBJC__
WindowWrapper *myWrapper;
#else
void *myWrapper;
#endif
bool myUseKeyRepeat; bool myUseKeyRepeat;
bool myMouseIn; bool myMouseIn;
float myWheelStatus; float myWheelStatus;

View File

@ -31,9 +31,6 @@
#import <SFML/Window/Cocoa/GLKit.h> #import <SFML/Window/Cocoa/GLKit.h>
#import <SFML/Window/WindowStyle.hpp> #import <SFML/Window/WindowStyle.hpp>
#import <SFML/System.hpp> #import <SFML/System.hpp>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#import <CoreFoundation/CoreFoundation.h>
#import <iostream> #import <iostream>
@ -54,16 +51,16 @@ __done = 1;\
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Private function declarations /// Private function declarations
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static Key::Code KeyForVirtualCode(unsigned short vCode); namespace {
static Key::Code KeyForUnicode(unsigned short uniCode); Key::Code KeyForVirtualCode(unsigned short vCode);
static bool IsTextEvent(NSEvent *event); Key::Code KeyForUnicode(unsigned short uniCode);
} // anonymous namespace
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Default constructor /// Default constructor
/// (creates a dummy window to provide a valid OpenGL context) /// (creates a dummy window to provide a valid OpenGL context)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static WindowImplCocoa *globalWin = NULL;
WindowImplCocoa::WindowImplCocoa() : WindowImplCocoa::WindowImplCocoa() :
myWrapper(nil), myWrapper(nil),
myUseKeyRepeat(false), myUseKeyRepeat(false),
@ -133,7 +130,8 @@ myWheelStatus(0.0f)
{ {
// Create a new window with given size, title and style // Create a new window with given size, title and style
// First we define some objects used for our window // First we define some objects used for our window
NSString *title = [NSString stringWithUTF8String:(Title.c_str()) ? (Title.c_str()) : ""]; NSString *title = [NSString stringWithCString:(Title.c_str()) ? (Title.c_str()) : ""
encoding:NSASCIIStringEncoding];
// We create the window // We create the window
myWrapper = [[WindowWrapper alloc] initWithSettings:params myWrapper = [[WindowWrapper alloc] initWithSettings:params
@ -228,18 +226,20 @@ void WindowImplCocoa::HandleKeyDown(void *eventRef)
// convert the characters // convert the characters
// note: using CFString in order to keep compatibility with Mac OS X 10.4 // note: using CFString in order to keep compatibility with Mac OS X 10.4
// (NSUTF32StringEncoding only defined since Mac OS X 10.5) // (as NSUTF32StringEncoding is only being defined in Mac OS X 10.5 and later)
if (!CFStringGetCString ((CFStringRef)[event characters], if (!CFStringGetCString ((CFStringRef)[event characters],
(char *)utf32Characters, (char *)utf32Characters,
sizeof(utf32Characters), sizeof(utf32Characters),
kCFStringEncodingUTF32)) kCFStringEncodingUTF32))
{ {
const char *utf8Char = NULL; char asciiChar[3] = {0};
if ([[event characters] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) if ([[event characters] lengthOfBytesUsingEncoding:NSASCIIStringEncoding])
utf8Char = [[event characters] UTF8String]; [[event characters] getCString:asciiChar
maxLength:3
encoding:NSASCIIStringEncoding];
std::cerr << "Error while converting character to UTF32 : " std::cerr << "Error while converting character to UTF32 : \""
<< ((utf8Char) ? utf8Char : "(undefined)") << std::endl; << asciiChar << "\"" << std::endl;
} }
else else
{ {
@ -359,7 +359,9 @@ void WindowImplCocoa::HandleMouseDown(void *eventRef)
{ {
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent; Event sfEvent;
NSPoint loc = {0, 0};
// Get mouse position relative to the window
NSPoint loc = [myWrapper mouseLocation];
unsigned mods = [event modifierFlags]; unsigned mods = [event modifierFlags];
switch ([event type]) { switch ([event type]) {
@ -373,9 +375,6 @@ void WindowImplCocoa::HandleMouseDown(void *eventRef)
sfEvent.MouseButton.Button = Mouse::Left; sfEvent.MouseButton.Button = Mouse::Left;
} }
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x; sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y; sfEvent.MouseButton.Y = (int) loc.y;
@ -387,9 +386,6 @@ void WindowImplCocoa::HandleMouseDown(void *eventRef)
sfEvent.Type = Event::MouseButtonPressed; sfEvent.Type = Event::MouseButtonPressed;
sfEvent.MouseButton.Button = Mouse::Right; sfEvent.MouseButton.Button = Mouse::Right;
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x; sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y; sfEvent.MouseButton.Y = (int) loc.y;
@ -410,7 +406,9 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
{ {
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent; Event sfEvent;
NSPoint loc = {0, 0};
// Get mouse position relative to the window
NSPoint loc = [myWrapper mouseLocation];
unsigned mods = [event modifierFlags]; unsigned mods = [event modifierFlags];
switch ([event type]) { switch ([event type]) {
@ -424,9 +422,6 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
sfEvent.MouseButton.Button = Mouse::Left; sfEvent.MouseButton.Button = Mouse::Left;
} }
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x; sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y; sfEvent.MouseButton.Y = (int) loc.y;
@ -438,9 +433,6 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
sfEvent.Type = Event::MouseButtonReleased; sfEvent.Type = Event::MouseButtonReleased;
sfEvent.MouseButton.Button = Mouse::Right; sfEvent.MouseButton.Button = Mouse::Right;
// Get mouse position relative to the window
loc = [myWrapper mouseLocation];
sfEvent.MouseButton.X = (int) loc.x; sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y; sfEvent.MouseButton.Y = (int) loc.y;
@ -460,9 +452,7 @@ void WindowImplCocoa::HandleMouseUp(void *eventRef)
void WindowImplCocoa::HandleMouseMove(void *eventRef) void WindowImplCocoa::HandleMouseMove(void *eventRef)
{ {
Event sfEvent; Event sfEvent;
NSPoint loc = {0, 0}; NSPoint loc = [myWrapper mouseLocation];
loc = [myWrapper mouseLocation];
sfEvent.Type = Event::MouseMoved; sfEvent.Type = Event::MouseMoved;
sfEvent.MouseMove.X = (int) loc.x; sfEvent.MouseMove.X = (int) loc.x;
@ -547,7 +537,7 @@ void WindowImplCocoa::Display()
void WindowImplCocoa::ProcessEvents() void WindowImplCocoa::ProcessEvents()
{ {
// Forward event handling call to the application controller // Forward event handling call to the application controller
[SharedAppController processEvents]; [[AppController sharedController] processEvents];
} }
@ -557,7 +547,18 @@ void WindowImplCocoa::ProcessEvents()
void WindowImplCocoa::SetActive(bool Active) const void WindowImplCocoa::SetActive(bool Active) const
{ {
// Forward the call to the window // Forward the call to the window
[myWrapper setActive:Active]; if (myWrapper)
[myWrapper setActive:Active];
else {
// Or directly activate the shared OpenGL context if we're not using a window
if (Active) {
if ([NSOpenGLContext currentContext] != [GLContext sharedContext])
[[GLContext sharedContext] makeCurrentContext];
} else {
if ([NSOpenGLContext currentContext] == [GLContext sharedContext])
[NSOpenGLContext clearCurrentContext];
}
}
} }
@ -656,164 +657,167 @@ void WindowImplCocoa::SetIcon(unsigned int Width, unsigned int Height, const Uin
} }
//////////////////////////////////////////////////////////// namespace {
/// Return the SFML key corresponding to a key code ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////// /// Return the SFML key corresponding to a key code
static Key::Code KeyForVirtualCode(unsigned short vCode) ////////////////////////////////////////////////////////////
{ Key::Code KeyForVirtualCode(unsigned short vCode)
static struct {
unsigned short code;
Key::Code sfKey;
} virtualTable[] =
{ {
{0x35, Key::Escape}, static struct {
{0x31, Key::Space}, unsigned short code;
{0x24, Key::Return}, // main Return key Key::Code sfKey;
{0x4C, Key::Return}, // pav Return key } virtualTable[] =
{0x33, Key::Back}, {
{0x30, Key::Tab}, {0x35, Key::Escape},
{0x74, Key::PageUp}, {0x31, Key::Space},
{0x79, Key::PageDown}, {0x24, Key::Return}, // main Return key
{0x77, Key::End}, {0x4C, Key::Return}, // pav Return key
{0x73, Key::Home}, {0x33, Key::Back},
{0x72, Key::Insert}, {0x30, Key::Tab},
{0x75, Key::Delete}, {0x74, Key::PageUp},
{0x45, Key::Add}, {0x79, Key::PageDown},
{0x4E, Key::Subtract}, {0x77, Key::End},
{0x43, Key::Multiply}, {0x73, Key::Home},
{0x4B, Key::Divide}, {0x72, Key::Insert},
{0x75, Key::Delete},
{0x45, Key::Add},
{0x4E, Key::Subtract},
{0x43, Key::Multiply},
{0x4B, Key::Divide},
{0x7A, Key::F1}, {0x78, Key::F2}, {0x63, Key::F3},
{0x76, Key::F4}, {0x60, Key::F5}, {0x61, Key::F6},
{0x62, Key::F7}, {0x64, Key::F8}, {0x65, Key::F9},
{0x6D, Key::F10}, {0x67, Key::F11}, {0x6F, Key::F12},
{0x69, Key::F13}, {0x6B, Key::F14}, {0x71, Key::F15},
{0x7B, Key::Left},
{0x7C, Key::Right},
{0x7E, Key::Up},
{0x7D, Key::Down},
{0x52, Key::Numpad0}, {0x53, Key::Numpad1}, {0x54, Key::Numpad2},
{0x55, Key::Numpad3}, {0x56, Key::Numpad4}, {0x57, Key::Numpad5},
{0x58, Key::Numpad6}, {0x59, Key::Numpad7}, {0x5B, Key::Numpad8},
{0x5C, Key::Numpad9},
{0x1D, Key::Num0}, {0x12, Key::Num1}, {0x13, Key::Num2},
{0x14, Key::Num3}, {0x15, Key::Num4}, {0x17, Key::Num5},
{0x16, Key::Num6}, {0x1A, Key::Num7}, {0x1C, Key::Num8},
{0x19, Key::Num9},
{0x3B, Key::LControl}, //< Left Ctrl
{0x3A, Key::LAlt}, //< Left Option/Alt
{0x37, Key::LSystem}, //< Left Command
{0x38, Key::LShift}, //< Left Shift
{0x3E, Key::RControl}, //< Right Ctrl
{0x3D, Key::RAlt}, //< Right Option/Alt
{0x36, Key::RSystem}, //< Right Command
{0x3C, Key::RShift}, //< Right Shift
{0x39, Key::Code(0)} //< Caps Lock (not handled by SFML for now)
};
{0x7A, Key::F1}, {0x78, Key::F2}, {0x63, Key::F3}, Key::Code result = Key::Code(0);
{0x76, Key::F4}, {0x60, Key::F5}, {0x61, Key::F6},
{0x62, Key::F7}, {0x64, Key::F8}, {0x65, Key::F9},
{0x6D, Key::F10}, {0x67, Key::F11}, {0x6F, Key::F12},
{0x69, Key::F13}, {0x6B, Key::F14}, {0x71, Key::F15},
{0x7B, Key::Left}, for (unsigned i = 0;virtualTable[i].code;i++) {
{0x7C, Key::Right}, if (virtualTable[i].code == vCode) {
{0x7E, Key::Up}, result = virtualTable[i].sfKey;
{0x7D, Key::Down}, break;
}
{0x52, Key::Numpad0}, {0x53, Key::Numpad1}, {0x54, Key::Numpad2},
{0x55, Key::Numpad3}, {0x56, Key::Numpad4}, {0x57, Key::Numpad5},
{0x58, Key::Numpad6}, {0x59, Key::Numpad7}, {0x5B, Key::Numpad8},
{0x5C, Key::Numpad9},
{0x1D, Key::Num0}, {0x12, Key::Num1}, {0x13, Key::Num2},
{0x14, Key::Num3}, {0x15, Key::Num4}, {0x17, Key::Num5},
{0x16, Key::Num6}, {0x1A, Key::Num7}, {0x1C, Key::Num8},
{0x19, Key::Num9},
{0x3B, Key::LControl}, //< Left Ctrl
{0x3A, Key::LAlt}, //< Left Option/Alt
{0x37, Key::LSystem}, //< Left Command
{0x38, Key::LShift}, //< Left Shift
{0x3E, Key::RControl}, //< Right Ctrl
{0x3D, Key::RAlt}, //< Right Option/Alt
{0x36, Key::RSystem}, //< Right Command
{0x3C, Key::RShift}, //< Right Shift
{0x39, Key::Code(0)} //< Caps Lock (not handled by SFML for now)
};
Key::Code result = Key::Code(0);
for (unsigned i = 0;virtualTable[i].code;i++) {
if (virtualTable[i].code == vCode) {
result = virtualTable[i].sfKey;
break;
} }
return result;
} }
return result;
} ////////////////////////////////////////////////////////////
/// Return the SFML key corresponding to a unicode code
////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////// Key::Code KeyForUnicode(unsigned short uniCode)
/// Return the SFML key corresponding to a unicode code
////////////////////////////////////////////////////////////
static Key::Code KeyForUnicode(unsigned short uniCode)
{
// TODO: find a better way to get the language independant key
static struct {
unsigned short character;
Key::Code sfKey;
} unicodeTable[] =
{ {
{'!', Key::Code(0)}, //< No Key for this code // TODO: find a better way to get the language independant key
{'"', Key::Code(0)}, //< No Key for this code static struct {
{'#', Key::Code(0)}, //< No Key for this code unsigned short character;
{'$', Key::Code(0)}, //< No Key for this code Key::Code sfKey;
{'%', Key::Code(0)}, //< No Key for this code } unicodeTable[] =
{'&', Key::Code(0)}, //< No Key for this code {
{'\'', Key::Quote}, {'!', Key::Code(0)}, //< No Key for this code
{'(', Key::Code(0)}, //< No Key for this code {'"', Key::Code(0)}, //< No Key for this code
{')', Key::Code(0)}, //< No Key for this code {'#', Key::Code(0)}, //< No Key for this code
{'*', Key::Multiply}, {'$', Key::Code(0)}, //< No Key for this code
{'+', Key::Add}, {'%', Key::Code(0)}, //< No Key for this code
{',', Key::Comma}, {'&', Key::Code(0)}, //< No Key for this code
{'-', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'\'', Key::Quote},
{'.', Key::Period}, {'(', Key::Code(0)}, //< No Key for this code
{'/', Key::Code(0)}, //< Handled by KeyForVirtualCode() {')', Key::Code(0)}, //< No Key for this code
{'0', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'*', Key::Multiply},
{'1', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'+', Key::Add},
{'2', Key::Code(0)}, //< Handled by KeyForVirtualCode() {',', Key::Comma},
{'3', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'-', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'4', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'.', Key::Period},
{'5', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'/', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'6', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'0', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'7', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'1', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'8', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'2', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'9', Key::Code(0)}, //< Handled by KeyForVirtualCode() {'3', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{':', Key::Code(0)}, //< No Key for this code {'4', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{';', Key::SemiColon}, {'5', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'<', Key::Code(0)}, //< No Key for this code {'6', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'=', Key::Equal}, {'7', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'>', Key::Code(0)}, //< No Key for this code {'8', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'?', Key::Code(0)}, //< No Key for this code {'9', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'@', Key::Code(0)}, //< No Key for this code {':', Key::Code(0)}, //< No Key for this code
{'A', Key::A}, {'B', Key::B}, {'C', Key::C}, {';', Key::SemiColon},
{'D', Key::D}, {'E', Key::E}, {'F', Key::F}, {'<', Key::Code(0)}, //< No Key for this code
{'G', Key::G}, {'H', Key::H}, {'I', Key::I}, {'=', Key::Equal},
{'J', Key::J}, {'K', Key::K}, {'L', Key::L}, {'>', Key::Code(0)}, //< No Key for this code
{'M', Key::M}, {'N', Key::N}, {'O', Key::O}, {'?', Key::Code(0)}, //< No Key for this code
{'P', Key::P}, {'Q', Key::Q}, {'R', Key::R}, {'@', Key::Code(0)}, //< No Key for this code
{'S', Key::S}, {'T', Key::T}, {'U', Key::U}, {'A', Key::A}, {'B', Key::B}, {'C', Key::C},
{'V', Key::V}, {'W', Key::W}, {'X', Key::X}, {'D', Key::D}, {'E', Key::E}, {'F', Key::F},
{'Y', Key::Y}, {'Z', Key::Z}, {'G', Key::G}, {'H', Key::H}, {'I', Key::I},
{'[', Key::LBracket}, {'J', Key::J}, {'K', Key::K}, {'L', Key::L},
{'\\', Key::BackSlash}, {'M', Key::M}, {'N', Key::N}, {'O', Key::O},
{']', Key::RBracket}, {'P', Key::P}, {'Q', Key::Q}, {'R', Key::R},
{'^', Key::Code(0)}, //< No Key for this code {'S', Key::S}, {'T', Key::T}, {'U', Key::U},
{'_', Key::Code(0)}, //< No Key for this code {'V', Key::V}, {'W', Key::W}, {'X', Key::X},
{'`', Key::Code(0)}, //< No Key for this code {'Y', Key::Y}, {'Z', Key::Z},
{'a', Key::A}, {'b', Key::B}, {'c', Key::C}, {'[', Key::LBracket},
{'d', Key::D}, {'e', Key::E}, {'f', Key::F}, {'\\', Key::BackSlash},
{'g', Key::G}, {'h', Key::H}, {'i', Key::I}, {']', Key::RBracket},
{'j', Key::J}, {'k', Key::K}, {'l', Key::L}, {'^', Key::Code(0)}, //< No Key for this code
{'m', Key::M}, {'n', Key::N}, {'o', Key::O}, {'_', Key::Code(0)}, //< No Key for this code
{'p', Key::P}, {'q', Key::Q}, {'r', Key::R}, {'`', Key::Code(0)}, //< No Key for this code
{'s', Key::S}, {'t', Key::T}, {'u', Key::U}, {'a', Key::A}, {'b', Key::B}, {'c', Key::C},
{'v', Key::V}, {'w', Key::W}, {'x', Key::X}, {'d', Key::D}, {'e', Key::E}, {'f', Key::F},
{'y', Key::Y}, {'z', Key::Z}, {'g', Key::G}, {'h', Key::H}, {'i', Key::I},
{'{', Key::Code(0)}, //< No Key for this code {'j', Key::J}, {'k', Key::K}, {'l', Key::L},
{'|', Key::Code(0)}, //< No Key for this code {'m', Key::M}, {'n', Key::N}, {'o', Key::O},
{'}', Key::Code(0)}, //< No Key for this code {'p', Key::P}, {'q', Key::Q}, {'r', Key::R},
{'~', Key::Tilde}, {'s', Key::S}, {'t', Key::T}, {'u', Key::U},
{0, Key::Code(0)} {'v', Key::V}, {'w', Key::W}, {'x', Key::X},
}; {'y', Key::Y}, {'z', Key::Z},
{'{', Key::Code(0)}, //< No Key for this code
Key::Code result = Key::Code(0); {'|', Key::Code(0)}, //< No Key for this code
{'}', Key::Code(0)}, //< No Key for this code
for (unsigned i = 0;unicodeTable[i].character;i++) { {'~', Key::Tilde},
if (unicodeTable[i].character == uniCode) { {0, Key::Code(0)}
result = unicodeTable[i].sfKey; };
break;
Key::Code result = Key::Code(0);
for (unsigned i = 0;unicodeTable[i].character;i++) {
if (unicodeTable[i].character == uniCode) {
result = unicodeTable[i].sfKey;
break;
}
} }
return result;
} }
return result; } // anonymous namespace
}
} // namespace priv } // namespace priv