00001 00002 // 00003 // SFML - Simple and Fast Multimedia Library 00004 // Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com) 00005 // 00006 // This software is provided 'as-is', without any express or implied warranty. 00007 // In no event will the authors be held liable for any damages arising from the use of this software. 00008 // 00009 // Permission is granted to anyone to use this software for any purpose, 00010 // including commercial applications, and to alter it and redistribute it freely, 00011 // subject to the following restrictions: 00012 // 00013 // 1. The origin of this software must not be misrepresented; 00014 // you must not claim that you wrote the original software. 00015 // If you use this software in a product, an acknowledgment 00016 // in the product documentation would be appreciated but is not required. 00017 // 00018 // 2. Altered source versions must be plainly marked as such, 00019 // and must not be misrepresented as being the original software. 00020 // 00021 // 3. This notice may not be removed or altered from any source distribution. 00022 // 00024 00025 00027 // Headers 00029 #import <SFML/Window/Cocoa/WindowImplCocoa.hpp> 00030 #import <SFML/Window/Cocoa/AppController.h> 00031 #import <SFML/Window/Cocoa/GLKit.h> 00032 #import <SFML/Window/WindowStyle.hpp> 00033 #import <SFML/System.hpp> 00034 #import <OpenGL/OpenGL.h> 00035 #import <OpenGL/gl.h> 00036 #import <CoreFoundation/CoreFoundation.h> 00037 #import <iostream> 00038 00039 00040 namespace sf 00041 { 00042 namespace priv 00043 { 00044 00045 // Do something only once (useful in loops) 00046 #define ONCE(make) \ 00047 { static int __done = 0;\ 00048 if (!__done) {\ 00049 make;\ 00050 __done = 1;\ 00051 } } 00052 00053 00057 static Key::Code KeyForVirtualCode(unsigned short vCode); 00058 static Key::Code KeyForUnicode(unsigned short uniCode); 00059 static bool IsTextEvent(NSEvent *event); 00060 00061 00066 static WindowImplCocoa *globalWin = NULL; 00067 WindowImplCocoa::WindowImplCocoa() : 00068 myWrapper(nil), 00069 myUseKeyRepeat(false), 00070 myMouseIn(false), 00071 myWheelStatus(0.0f) 00072 { 00073 [AppController sharedController]; 00074 00075 // Create the shared OpenGL context 00076 if ([GLContext sharedContext]) { 00077 // Then we make it the current active OpenGL context 00078 SetActive(); 00079 } else { 00080 std::cerr << "Unable to make the main shared OpenGL context" << std::endl; 00081 } 00082 } 00083 00084 00088 WindowImplCocoa::WindowImplCocoa(WindowHandle Handle, WindowSettings& params) : 00089 myWrapper(NULL), 00090 myUseKeyRepeat(false), 00091 myMouseIn(false), 00092 myWheelStatus(0.0f) 00093 { 00094 if (Handle) 00095 { 00096 if (![(NSWindow *)Handle isKindOfClass:[NSWindow class]]) 00097 std::cerr << "Cannot import this Window Handle because it is not a <NSWindow *> object" 00098 << "(or one of its subclasses). You gave a <" 00099 << [[(NSWindow *)Handle className] UTF8String] 00100 << "> object." << std::endl; 00101 else 00102 { 00103 00104 // We create the window according to the given handle 00105 myWrapper = [[WindowWrapper alloc] initWithWindow:(NSWindow *)Handle 00106 settings:params 00107 delegate:this]; 00108 00109 if (myWrapper) 00110 { 00111 // initial mouse state 00112 myMouseIn = [myWrapper mouseInside]; 00113 00114 // We set the myWidth and myHeight members to the correct values 00115 myWidth = (int) [[myWrapper glView] frame].size.width; 00116 myHeight = (int) [[myWrapper glView] frame].size.height; 00117 } else { 00118 std::cerr << "Failed to make the public window" << std::endl; 00119 } 00120 } 00121 } 00122 } 00123 00124 00128 WindowImplCocoa::WindowImplCocoa(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& params) : 00129 myWrapper(NULL), 00130 myUseKeyRepeat(false), 00131 myMouseIn(false), 00132 myWheelStatus(0.0f) 00133 { 00134 // Create a new window with given size, title and style 00135 // First we define some objects used for our window 00136 NSString *title = [NSString stringWithUTF8String:(Title.c_str()) ? (Title.c_str()) : ""]; 00137 00138 // We create the window 00139 myWrapper = [[WindowWrapper alloc] initWithSettings:params 00140 videoMode:Mode 00141 style:WindowStyle 00142 title:title 00143 delegate:this]; 00144 00145 if (myWrapper) 00146 { 00147 // initial mouse state 00148 myMouseIn = [myWrapper mouseInside]; 00149 00150 // We set the myWidth and myHeight members to the correct values 00151 myWidth = Mode.Width; 00152 myHeight = Mode.Height; 00153 } else { 00154 std::cerr << "Failed to make the public window" << std::endl; 00155 } 00156 } 00157 00158 00162 WindowImplCocoa::~WindowImplCocoa() 00163 { 00164 // Release the window wrapper 00165 [myWrapper release]; 00166 } 00167 00168 00172 bool WindowImplCocoa::IsContextActive() 00173 { 00174 return ([NSOpenGLContext currentContext] != NULL); 00175 } 00176 00177 00181 void WindowImplCocoa::HandleNotifiedEvent(Event& event) 00182 { 00183 // Set myWidth and myHeight to correct value if 00184 // window size changed 00185 switch (event.Type) { 00186 case Event::Resized: 00187 myWidth = event.Size.Width; 00188 myHeight = event.Size.Height; 00189 break; 00190 00191 default: 00192 break; 00193 } 00194 00195 // And send the event 00196 SendEvent(event); 00197 } 00198 00199 00203 void WindowImplCocoa::HandleKeyDown(void *eventRef) 00204 { 00205 NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); 00206 00207 Event sfEvent; 00208 unichar chr = 0, rawchr = 0; 00209 unsigned long length = [[event characters] length]; 00210 unsigned mods = [event modifierFlags]; 00211 00212 if (length) { 00213 chr = [[event characters] characterAtIndex:0]; 00214 00215 // Note : I got a crash (out of bounds exception) while typing so now I test... 00216 if ([[event charactersIgnoringModifiers] length]) 00217 rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0]; 00218 00219 00220 // Don't handle repeated events if we chose not to send them 00221 if (!myUseKeyRepeat && [event isARepeat]) 00222 return; 00223 00224 // Is it also a text event ? 00225 if (IsTextEvent(event)) { 00226 // buffer for the UTF-32 characters 00227 Uint32 utf32Characters[2] = {0}; 00228 00229 // convert the characters 00230 // note: using CFString in order to keep compatibility with Mac OS X 10.4 00231 // (NSUTF32StringEncoding only defined since Mac OS X 10.5) 00232 if (!CFStringGetCString ((CFStringRef)[event characters], 00233 (char *)utf32Characters, 00234 sizeof(utf32Characters), 00235 kCFStringEncodingUTF32)) 00236 { 00237 const char *utf8Char = NULL; 00238 if ([[event characters] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) 00239 utf8Char = [[event characters] UTF8String]; 00240 00241 std::cerr << "Error while converting character to UTF32 : " 00242 << ((utf8Char) ? utf8Char : "(undefined)") << std::endl; 00243 } 00244 else 00245 { 00246 sfEvent.Type = Event::TextEntered; 00247 sfEvent.Text.Unicode = utf32Characters[0]; 00248 00249 SendEvent(sfEvent); 00250 } 00251 } 00252 00253 // Anyway it's also a KeyPressed event 00254 sfEvent.Type = Event::KeyPressed; 00255 00256 // Get the keys 00257 if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) { 00258 sfEvent.Key.Code = KeyForVirtualCode([event keyCode]); 00259 } 00260 00261 // Get the modifiers 00262 sfEvent.Key.Alt = mods & NSAlternateKeyMask; 00263 sfEvent.Key.Control = mods & NSControlKeyMask; 00264 sfEvent.Key.Shift = mods & NSShiftKeyMask; 00265 00266 // Send the event 00267 SendEvent(sfEvent); 00268 } 00269 } 00270 00271 00275 void WindowImplCocoa::HandleKeyUp(void *eventRef) 00276 { 00277 NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); 00278 00279 Event sfEvent; 00280 unsigned mods = [event modifierFlags]; 00281 unichar chr = 0, rawchr = 0; 00282 00283 if ([[event characters] length]) { 00284 chr = [[event characters] characterAtIndex:0]; 00285 00286 if ([[event charactersIgnoringModifiers] length]) 00287 rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0]; 00288 00289 sfEvent.Type = Event::KeyReleased; 00290 00291 // Get the code 00292 if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) { 00293 sfEvent.Key.Code = KeyForVirtualCode([event keyCode]); 00294 } 00295 00296 // Get the modifiers 00297 sfEvent.Key.Alt = mods & NSAlternateKeyMask; 00298 sfEvent.Key.Control = mods & NSControlKeyMask; 00299 sfEvent.Key.Shift = mods & NSShiftKeyMask; 00300 00301 // Send the event 00302 SendEvent(sfEvent); 00303 } 00304 } 00305 00306 00310 void WindowImplCocoa::HandleModifierKey(void *eventRef) 00311 { 00312 NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); 00313 Event sfEvent; 00314 unsigned mods = [event modifierFlags]; 00315 00316 sfEvent.Type = Event::KeyPressed; 00317 00318 // Get the code 00319 sfEvent.Key.Code = KeyForVirtualCode([event keyCode]); 00320 00321 // Get the modifiers 00322 sfEvent.Key.Alt = mods & NSAlternateKeyMask; 00323 sfEvent.Key.Control = mods & NSControlKeyMask; 00324 sfEvent.Key.Shift = mods & NSShiftKeyMask; 00325 00326 // Guess whether it's a pressed or released event 00327 // Note: this does not work fine is both left and right modifiers are pressed 00328 // I did not find any way to fix this. 00329 // TODO: fix handling of modifier flags for use of left and right key at the same time 00330 if (!(mods & NSAlternateKeyMask) && 00331 (sfEvent.Key.Code == Key::LAlt || sfEvent.Key.Code == Key::RAlt)) { 00332 sfEvent.Type = Event::KeyReleased; 00333 } 00334 00335 if (!(mods & NSControlKeyMask) && 00336 (sfEvent.Key.Code == Key::LControl || sfEvent.Key.Code == Key::RControl)) { 00337 sfEvent.Type = Event::KeyReleased; 00338 } 00339 00340 if (!(mods & NSShiftKeyMask) && 00341 (sfEvent.Key.Code == Key::LShift || sfEvent.Key.Code == Key::RShift)) { 00342 sfEvent.Type = Event::KeyReleased; 00343 } 00344 00345 if (!(mods & NSCommandKeyMask) && 00346 (sfEvent.Key.Code == Key::LSystem || sfEvent.Key.Code == Key::RSystem)) { 00347 sfEvent.Type = Event::KeyReleased; 00348 } 00349 00350 // Send the event 00351 SendEvent(sfEvent); 00352 } 00353 00354 00358 void WindowImplCocoa::HandleMouseDown(void *eventRef) 00359 { 00360 NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); 00361 Event sfEvent; 00362 NSPoint loc = {0, 0}; 00363 unsigned mods = [event modifierFlags]; 00364 00365 switch ([event type]) { 00366 case NSLeftMouseDown: 00367 sfEvent.Type = Event::MouseButtonPressed; 00368 00369 // Guess whether it's a mouse left or mouse right event 00370 if (mods & NSControlKeyMask) { 00371 sfEvent.MouseButton.Button = Mouse::Right; 00372 } else { 00373 sfEvent.MouseButton.Button = Mouse::Left; 00374 } 00375 00376 // Get mouse position relative to the window 00377 loc = [myWrapper mouseLocation]; 00378 00379 sfEvent.MouseButton.X = (int) loc.x; 00380 sfEvent.MouseButton.Y = (int) loc.y; 00381 00382 // Send the event 00383 SendEvent(sfEvent); 00384 break; 00385 00386 case NSRightMouseDown: 00387 sfEvent.Type = Event::MouseButtonPressed; 00388 sfEvent.MouseButton.Button = Mouse::Right; 00389 00390 // Get mouse position relative to the window 00391 loc = [myWrapper mouseLocation]; 00392 00393 sfEvent.MouseButton.X = (int) loc.x; 00394 sfEvent.MouseButton.Y = (int) loc.y; 00395 00396 // Send the event 00397 SendEvent(sfEvent); 00398 break; 00399 00400 default: 00401 break; 00402 } 00403 } 00404 00405 00409 void WindowImplCocoa::HandleMouseUp(void *eventRef) 00410 { 00411 NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); 00412 Event sfEvent; 00413 NSPoint loc = {0, 0}; 00414 unsigned mods = [event modifierFlags]; 00415 00416 switch ([event type]) { 00417 case NSLeftMouseUp: 00418 sfEvent.Type = Event::MouseButtonReleased; 00419 00420 // Guess whether it's a mouse left or mouse right event 00421 if (mods & NSControlKeyMask) { 00422 sfEvent.MouseButton.Button = Mouse::Right; 00423 } else { 00424 sfEvent.MouseButton.Button = Mouse::Left; 00425 } 00426 00427 // Get mouse position relative to the window 00428 loc = [myWrapper mouseLocation]; 00429 00430 sfEvent.MouseButton.X = (int) loc.x; 00431 sfEvent.MouseButton.Y = (int) loc.y; 00432 00433 // Send the event 00434 SendEvent(sfEvent); 00435 break; 00436 00437 case NSRightMouseUp: 00438 sfEvent.Type = Event::MouseButtonReleased; 00439 sfEvent.MouseButton.Button = Mouse::Right; 00440 00441 // Get mouse position relative to the window 00442 loc = [myWrapper mouseLocation]; 00443 00444 sfEvent.MouseButton.X = (int) loc.x; 00445 sfEvent.MouseButton.Y = (int) loc.y; 00446 00447 // Send the event 00448 SendEvent(sfEvent); 00449 break; 00450 00451 default: 00452 break; 00453 } 00454 } 00455 00456 00460 void WindowImplCocoa::HandleMouseMove(void *eventRef) 00461 { 00462 Event sfEvent; 00463 NSPoint loc = {0, 0}; 00464 00465 loc = [myWrapper mouseLocation]; 00466 sfEvent.Type = Event::MouseMoved; 00467 00468 sfEvent.MouseMove.X = (int) loc.x; 00469 sfEvent.MouseMove.Y = (int) loc.y; 00470 00471 SendEvent(sfEvent); 00472 00473 if ([myWrapper mouseInside] && !myMouseIn) { 00474 // If mouse IS inside but WAS not inside last time 00475 sfEvent.Type = Event::MouseEntered; 00476 myMouseIn = true; 00477 00478 SendEvent(sfEvent); 00479 } else if (![myWrapper mouseInside] && myMouseIn) { 00480 // Is mouse WAS not inside but IS now inside 00481 sfEvent.Type = Event::MouseLeft; 00482 myMouseIn = false; 00483 00484 SendEvent(sfEvent); 00485 } 00486 } 00487 00488 00492 void WindowImplCocoa::HandleMouseWheel(void *eventRef) 00493 { 00494 NSEvent *event = reinterpret_cast <NSEvent *> (eventRef); 00495 00496 // SFML uses integer values for delta but Cocoa uses float and it is mostly fewer than 1.0 00497 // Therefore I chose to add the float value to a 'wheel status' and 00498 // send a sf event only when it's greater than 1.0 00499 myWheelStatus += [event deltaY]; 00500 00501 if (fabs(myWheelStatus) > 1.0f) { 00502 // Make the event and send it 00503 Event sfEvent; 00504 sfEvent.Type = Event::MouseWheelMoved; 00505 sfEvent.MouseWheel.Delta = (int) myWheelStatus; 00506 SendEvent(sfEvent); 00507 00508 // Remove as much integer units as the one that have been put in the event 00509 // (was a mistake to set this to 0) 00510 myWheelStatus -= (int) myWheelStatus; 00511 } 00512 } 00513 00514 00518 void WindowImplCocoa::Display() 00519 { 00520 // Forward flush call to the window 00521 [myWrapper flushBuffer]; 00522 } 00523 00524 00528 void WindowImplCocoa::ProcessEvents() 00529 { 00530 // Forward event handling call to the application controller 00531 [SharedAppController processEvents]; 00532 } 00533 00534 00538 void WindowImplCocoa::SetActive(bool Active) const 00539 { 00540 // Forward the call to the window 00541 [myWrapper setActive:Active]; 00542 } 00543 00544 00548 void WindowImplCocoa::UseVerticalSync(bool Enabled) 00549 { 00550 // Forward the call to the window 00551 [myWrapper enableVerticalSync:Enabled]; 00552 } 00553 00554 00558 void WindowImplCocoa::ShowMouseCursor(bool flag) 00559 { 00560 if (flag) { 00561 [NSCursor unhide]; 00562 } else { 00563 [NSCursor hide]; 00564 } 00565 } 00566 00567 00571 void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top) 00572 { 00573 NSPoint pos = NSMakePoint ((float) Left, (float) Top); 00574 00575 if (myWrapper) { 00576 // Flip for SFML window coordinate system 00577 pos.y = [[myWrapper window] frame].size.height - pos.y; 00578 00579 // Adjust for view reference instead of window 00580 pos.y -= [[myWrapper window] frame].size.height - [[myWrapper glView] frame].size.height; 00581 00582 // Convert to screen coordinates 00583 NSPoint absolute = [[myWrapper window] convertBaseToScreen:pos]; 00584 00585 // Flip screen coodinates 00586 absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y; 00587 00588 // Move cursor 00589 CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, CGPointMake(absolute.x, absolute.y)); 00590 } 00591 } 00592 00593 00597 void WindowImplCocoa::SetPosition(int Left, int Top) 00598 { 00599 [myWrapper setPosition:NSMakePoint(Left, Top)]; 00600 } 00601 00602 00607 void WindowImplCocoa::SetSize(unsigned int Width, unsigned int Height) 00608 { 00609 [myWrapper setSize:NSMakeSize(Width, Height)]; 00610 } 00611 00612 00616 void WindowImplCocoa::Show(bool State) 00617 { 00618 [myWrapper show:State]; 00619 } 00620 00621 00625 void WindowImplCocoa::EnableKeyRepeat(bool Enabled) 00626 { 00627 myUseKeyRepeat = Enabled; 00628 } 00629 00630 00634 void WindowImplCocoa::SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels) 00635 { 00636 // Nothing to do 00637 } 00638 00639 00643 static Key::Code KeyForVirtualCode(unsigned short vCode) 00644 { 00645 static struct { 00646 unsigned short code; 00647 Key::Code sfKey; 00648 } virtualTable[] = 00649 { 00650 {0x35, Key::Escape}, 00651 {0x31, Key::Space}, 00652 {0x24, Key::Return}, // main Return key 00653 {0x4C, Key::Return}, // pav Return key 00654 {0x33, Key::Back}, 00655 {0x30, Key::Tab}, 00656 {0x74, Key::PageUp}, 00657 {0x79, Key::PageDown}, 00658 {0x77, Key::End}, 00659 {0x73, Key::Home}, 00660 {0x72, Key::Insert}, 00661 {0x75, Key::Delete}, 00662 {0x45, Key::Add}, 00663 {0x4E, Key::Subtract}, 00664 {0x43, Key::Multiply}, 00665 {0x4B, Key::Divide}, 00666 00667 {0x7A, Key::F1}, {0x78, Key::F2}, {0x63, Key::F3}, 00668 {0x76, Key::F4}, {0x60, Key::F5}, {0x61, Key::F6}, 00669 {0x62, Key::F7}, {0x64, Key::F8}, {0x65, Key::F9}, 00670 {0x6D, Key::F10}, {0x67, Key::F11}, {0x6F, Key::F12}, 00671 {0x69, Key::F13}, {0x6B, Key::F14}, {0x71, Key::F15}, 00672 00673 {0x7B, Key::Left}, 00674 {0x7C, Key::Right}, 00675 {0x7E, Key::Up}, 00676 {0x7D, Key::Down}, 00677 00678 {0x52, Key::Numpad0}, {0x53, Key::Numpad1}, {0x54, Key::Numpad2}, 00679 {0x55, Key::Numpad3}, {0x56, Key::Numpad4}, {0x57, Key::Numpad5}, 00680 {0x58, Key::Numpad6}, {0x59, Key::Numpad7}, {0x5B, Key::Numpad8}, 00681 {0x5C, Key::Numpad9}, 00682 00683 {0x1D, Key::Num0}, {0x12, Key::Num1}, {0x13, Key::Num2}, 00684 {0x14, Key::Num3}, {0x15, Key::Num4}, {0x17, Key::Num5}, 00685 {0x16, Key::Num6}, {0x1A, Key::Num7}, {0x1C, Key::Num8}, 00686 {0x19, Key::Num9}, 00687 00688 {0x3B, Key::LControl}, //< Left Ctrl 00689 {0x3A, Key::LAlt}, //< Left Option/Alt 00690 {0x37, Key::LSystem}, //< Left Command 00691 {0x38, Key::LShift}, //< Left Shift 00692 {0x3E, Key::RControl}, //< Right Ctrl 00693 {0x3D, Key::RAlt}, //< Right Option/Alt 00694 {0x36, Key::RSystem}, //< Right Command 00695 {0x3C, Key::RShift}, //< Right Shift 00696 00697 {0x39, Key::Code(0)} //< Caps Lock (not handled by SFML for now) 00698 }; 00699 00700 Key::Code result = Key::Code(0); 00701 00702 for (unsigned i = 0;virtualTable[i].code;i++) { 00703 if (virtualTable[i].code == vCode) { 00704 result = virtualTable[i].sfKey; 00705 break; 00706 } 00707 } 00708 00709 return result; 00710 } 00711 00712 00716 static Key::Code KeyForUnicode(unsigned short uniCode) 00717 { 00718 // TODO: find a better way to get the language independant key 00719 static struct { 00720 unsigned short character; 00721 Key::Code sfKey; 00722 } unicodeTable[] = 00723 { 00724 {'!', Key::Code(0)}, //< No Key for this code 00725 {'"', Key::Code(0)}, //< No Key for this code 00726 {'#', Key::Code(0)}, //< No Key for this code 00727 {'$', Key::Code(0)}, //< No Key for this code 00728 {'%', Key::Code(0)}, //< No Key for this code 00729 {'&', Key::Code(0)}, //< No Key for this code 00730 {'\'', Key::Quote}, 00731 {'(', Key::Code(0)}, //< No Key for this code 00732 {')', Key::Code(0)}, //< No Key for this code 00733 {'*', Key::Multiply}, 00734 {'+', Key::Add}, 00735 {',', Key::Comma}, 00736 {'-', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00737 {'.', Key::Period}, 00738 {'/', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00739 {'0', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00740 {'1', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00741 {'2', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00742 {'3', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00743 {'4', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00744 {'5', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00745 {'6', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00746 {'7', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00747 {'8', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00748 {'9', Key::Code(0)}, //< Handled by KeyForVirtualCode() 00749 {':', Key::Code(0)}, //< No Key for this code 00750 {';', Key::SemiColon}, 00751 {'<', Key::Code(0)}, //< No Key for this code 00752 {'=', Key::Equal}, 00753 {'>', Key::Code(0)}, //< No Key for this code 00754 {'?', Key::Code(0)}, //< No Key for this code 00755 {'@', Key::Code(0)}, //< No Key for this code 00756 {'A', Key::A}, {'B', Key::B}, {'C', Key::C}, 00757 {'D', Key::D}, {'E', Key::E}, {'F', Key::F}, 00758 {'G', Key::G}, {'H', Key::H}, {'I', Key::I}, 00759 {'J', Key::J}, {'K', Key::K}, {'L', Key::L}, 00760 {'M', Key::M}, {'N', Key::N}, {'O', Key::O}, 00761 {'P', Key::P}, {'Q', Key::Q}, {'R', Key::R}, 00762 {'S', Key::S}, {'T', Key::T}, {'U', Key::U}, 00763 {'V', Key::V}, {'W', Key::W}, {'X', Key::X}, 00764 {'Y', Key::Y}, {'Z', Key::Z}, 00765 {'[', Key::LBracket}, 00766 {'\\', Key::BackSlash}, 00767 {']', Key::RBracket}, 00768 {'^', Key::Code(0)}, //< No Key for this code 00769 {'_', Key::Code(0)}, //< No Key for this code 00770 {'`', Key::Code(0)}, //< No Key for this code 00771 {'a', Key::A}, {'b', Key::B}, {'c', Key::C}, 00772 {'d', Key::D}, {'e', Key::E}, {'f', Key::F}, 00773 {'g', Key::G}, {'h', Key::H}, {'i', Key::I}, 00774 {'j', Key::J}, {'k', Key::K}, {'l', Key::L}, 00775 {'m', Key::M}, {'n', Key::N}, {'o', Key::O}, 00776 {'p', Key::P}, {'q', Key::Q}, {'r', Key::R}, 00777 {'s', Key::S}, {'t', Key::T}, {'u', Key::U}, 00778 {'v', Key::V}, {'w', Key::W}, {'x', Key::X}, 00779 {'y', Key::Y}, {'z', Key::Z}, 00780 {'{', Key::Code(0)}, //< No Key for this code 00781 {'|', Key::Code(0)}, //< No Key for this code 00782 {'}', Key::Code(0)}, //< No Key for this code 00783 {'~', Key::Tilde}, 00784 {0, Key::Code(0)} 00785 }; 00786 00787 Key::Code result = Key::Code(0); 00788 00789 for (unsigned i = 0;unicodeTable[i].character;i++) { 00790 if (unicodeTable[i].character == uniCode) { 00791 result = unicodeTable[i].sfKey; 00792 break; 00793 } 00794 } 00795 00796 return result; 00797 } 00798 00799 00803 static bool IsTextEvent(NSEvent *event) 00804 { 00805 bool res = false; 00806 00807 if (event && [event type] == NSKeyDown && [[event characters] length]) { 00808 unichar code = [[event characters] characterAtIndex:0]; 00809 00810 // Codes from 0xF700 to 0xF8FF are non text keys (see NSEvent.h) 00811 if (code < 0xF700 || code > 0xF8FF) 00812 res = true; 00813 } 00814 00815 return res; 00816 } 00817 00818 00819 } // namespace priv 00820 00821 } // namespace sf 00822
:: Copyright © 2007-2008 Laurent Gomila, all rights reserved :: Documentation generated by doxygen 1.5.2 ::