00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #include "OSDLKeyboardHandler.h"
00028 
00029 #include "OSDLController.h"      
00030 #include "OSDLEvents.h"          
00031 #include "OSDLBasic.h"           
00032 
00033 
00034 using std::string ;
00035 using std::list ;
00036 using std::map ;
00037 
00038 
00039 using namespace Ceylan::Log ;    
00040 using namespace OSDL::Events ;
00041 
00042 
00043 
00044 #ifdef OSDL_USES_CONFIG_H
00045 #include <OSDLConfig.h>          
00046 #endif // OSDL_USES_CONFIG_H
00047 
00048 
00049 
00050 #if OSDL_VERBOSE_KEYBOARD_HANDLER
00051 
00052 #include <iostream>
00053 #define OSDL_KEYBOARD_HANDLER_LOG( message ) std::cout << "[OSDL Keyboard Handler] " << message << std::endl ;
00054 
00055 #else // OSDL_VERBOSE_KEYBOARD_HANDLER
00056 
00057 #define OSDL_KEYBOARD_HANDLER_LOG( message )
00058 
00059 #endif // OSDL_VERBOSE_KEYBOARD_HANDLER
00060 
00061 
00062 
00063 #if OSDL_USES_SDL
00064 
00065 const Ceylan::System::Millisecond KeyboardHandler::DefaultDelayBeforeKeyRepeat 
00066     = SDL_DEFAULT_REPEAT_DELAY ; 
00067     
00068 const Ceylan::System::Millisecond KeyboardHandler::DefaulKeyRepeatInterval
00069     = SDL_DEFAULT_REPEAT_INTERVAL ;
00070 
00071 #else // OSDL_USES_SDL
00072 
00073 
00074 const Ceylan::System::Millisecond KeyboardHandler::DefaultDelayBeforeKeyRepeat 
00075     = 500 ; 
00076     
00077 const Ceylan::System::Millisecond KeyboardHandler::DefaulKeyRepeatInterval
00078     = 30 ;
00079 
00080 #endif // OSDL_USES_SDL
00081 
00082 
00083 
00084 
00085 
00086 KeyboardMode KeyboardHandler::_CurrentMode = rawInput ;
00087 
00088 
00089 
00090 
00091 KeyboardException::KeyboardException( const string & message ):
00092     EventsException( message )
00093 {
00094 
00095 }
00096 
00097 
00098 
00099 KeyboardException::~KeyboardException() throw()
00100 {
00101 
00102 }
00103 
00104 
00105 
00106 
00107 
00115 void doNothingKeyHandler( const KeyboardEvent & keyboardEvent )
00116 {
00117 
00118     OSDL_KEYBOARD_HANDLER_LOG( EventsModule::DescribeEvent( keyboardEvent ) ) ;
00119         
00120 }
00121 
00122 
00123 
00124 
00136 void smarterKeyHandler( const KeyboardEvent & keyboardEvent )
00137 {
00138 
00139 #if OSDL_USES_SDL
00140 
00141     OSDL_KEYBOARD_HANDLER_LOG( 
00142         EventsModule::DescribeEvent( keyboardEvent ) ) ;        
00143     
00144     
00145     
00146     if ( keyboardEvent.type != EventsModule::KeyPressed )
00147     {
00148         
00149         
00150         return ;
00151     }
00152     
00153     
00154     switch( static_cast<KeyboardHandler::KeyIdentifier>(
00155         keyboardEvent.keysym.sym ) )
00156     {
00157     
00158         case KeyboardHandler::EscapeKey:
00159         case KeyboardHandler::qKey:
00160             LogPlug::debug( "Input keypress requested exit." ) ;
00161             EventsModule::DescribeEvent( keyboardEvent ) ;
00162             OSDL::getExistingCommonModule().getEventsModule().requestQuit() ;
00163             break ;
00164             
00165         case KeyboardHandler::F1Key:
00166             
00167             EventsModule::DescribeEvent( keyboardEvent ) ;
00168             if ( KeyboardHandler::GetMode() == rawInput )
00169                 KeyboardHandler::SetMode( textInput ) ;
00170             else
00171                 KeyboardHandler::SetMode( rawInput ) ;
00172             break ; 
00173             
00174         
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189             
00190         default:
00191             EventsModule::DescribeEvent( keyboardEvent ) ;
00192             break ;
00193     }
00194 
00195 #endif // OSDL_USES_SDL
00196         
00197 }
00198 
00199 
00200 
00201 KeyboardHandler::KeyboardHandler( KeyboardMode initialMode, 
00202         bool useSmarterDefaultKeyHandler ) :
00203     InputDeviceHandler(),
00204     _rawKeyControllerMap(),
00205     _rawKeyHandlerMap(),
00206     _unicodeControllerMap(),
00207     _unicodeHandlerMap(),
00208     _defaultRawKeyController( 0 ),
00209     _focusController( 0 )
00210 {
00211 
00212 #if OSDL_USES_SDL
00213 
00214     send( "Initializing keyboard subsystem." ) ;
00215 
00216     
00217     
00218     
00219     _unicodeInputWasActivated = ( SDL_EnableUNICODE( -1 ) == 1 ) ;
00220     
00221     if ( useSmarterDefaultKeyHandler )
00222     {
00223     
00224         setSmarterDefaultKeyHandlers() ;
00225         
00226     }
00227     else
00228     {
00229     
00230         _defaultRawKeyHandler  = doNothingKeyHandler ;
00231         _defaultUnicodeHandler = doNothingKeyHandler ;
00232         
00233     }
00234     
00235     SetMode( initialMode ) ;    
00236 
00237     send( "Keyboard subsystem initialized." ) ;
00238 
00239     dropIdentifier() ;
00240 
00241 #else // OSDL_USES_SDL
00242 
00243     throw InputDeviceHandlerException( "KeyboardHandler constructor failed: "
00244         "no SDL support available" ) ;
00245 
00246 #endif // OSDL_USES_SDL
00247     
00248 }
00249 
00250 
00251 
00252 KeyboardHandler::~KeyboardHandler() throw()
00253 {
00254 
00255 #if OSDL_USES_SDL
00256 
00257     send( "Stopping keyboard subsystem." ) ;
00258 
00259     if ( _defaultRawKeyController != 0 )
00260         delete _defaultRawKeyController ;
00261         
00262     
00263     if ( _unicodeInputWasActivated ) 
00264         SDL_EnableUNICODE( 1 ) ;
00265     else
00266         SDL_EnableUNICODE( 0 ) ;
00267 
00268     
00269     
00270     send( "Keyboard subsystem stopped." ) ;
00271         
00272 #endif // OSDL_USES_SDL
00273 
00274 }
00275 
00276 
00277 
00278 void KeyboardHandler::linkToController( KeyIdentifier rawKey, 
00279     OSDL::MVC::Controller & controller )
00280 {
00281 
00282     _rawKeyControllerMap[ rawKey ] = & controller ;
00283     
00284 }
00285 
00286     
00287     
00288 void KeyboardHandler::unlinkFromController( KeyIdentifier rawKey, 
00289     OSDL::MVC::Controller & controller )
00290 {
00291 
00292     map<KeyIdentifier, OSDL::MVC::Controller*>::iterator itController
00293         = _rawKeyControllerMap.find( rawKey ) ;
00294             
00295     if ( itController != _rawKeyControllerMap.end() )
00296     {
00297 
00298         if ( (*itController).second != & controller )
00299             throw InputDeviceHandlerException( 
00300                 "KeyboardHandler::unlinkFromController failed: "
00301                 "current controller was not the specified one." ) ;
00302         
00303         _rawKeyControllerMap.erase( itController ) ;
00304         
00305         OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::unlinkFromController: "
00306                 "controller unlinked." ) ;
00307     
00308     }
00309     else
00310     {
00311             
00312         throw InputDeviceHandlerException( 
00313             "KeyboardHandler::unlinkFromController failed: "
00314             "key binding not found." ) ;
00315             
00316     }
00317     
00318 }
00319 
00320     
00321                     
00322 void KeyboardHandler::linkToController( Ceylan::Unicode unicode, 
00323     OSDL::MVC::Controller & controller )
00324 {
00325 
00326     _unicodeControllerMap[ unicode ] = & controller ;
00327     
00328 }
00329     
00330 
00331     
00332 void KeyboardHandler::linkToFocusController(
00333     OSDL::MVC::Controller & controller )
00334 {
00335 
00336     _focusController = & controller ;
00337     
00338 }
00339     
00340     
00341     
00342 void KeyboardHandler::linkToHandler( KeyIdentifier rawKey, 
00343     KeyboardEventHandler handler )
00344 {
00345 
00346     _rawKeyHandlerMap[ rawKey ] = handler ;
00347     
00348 }
00349 
00350     
00351                     
00352 void KeyboardHandler::linkToHandler( Ceylan::Unicode unicode,
00353     KeyboardEventHandler handler )
00354 {
00355 
00356     _unicodeHandlerMap[ unicode ] = handler ;
00357     
00358 }
00359 
00360     
00361 
00362 void KeyboardHandler::setSmarterDefaultKeyHandlers()
00363 {
00364 
00365     _defaultRawKeyHandler  = smarterKeyHandler ;
00366     _defaultUnicodeHandler = smarterKeyHandler ;
00367     
00368 }
00369 
00370 
00371 
00372 
00373 void KeyboardHandler::linkDefaultRawKeyController( 
00374     OSDL::MVC::Controller & newDefaultController )
00375 {
00376 
00377     _defaultRawKeyController = & newDefaultController ;
00378     
00379 }
00380 
00381 
00382 
00383 bool KeyboardHandler::unlinkDefaultRawKeyController()
00384 {
00385 
00386     if ( _defaultRawKeyController != 0 )
00387     {
00388         
00389         _defaultRawKeyController = 0 ;
00390         return true ;
00391         
00392     }
00393     
00394     return false ;  
00395         
00396 }
00397 
00398 
00399 
00400 
00401 void KeyboardHandler::setDefaultRawKeyHandler( 
00402     KeyboardEventHandler newHandler )
00403 {
00404 
00405     _defaultRawKeyHandler = newHandler ;
00406     
00407 }
00408 
00409 
00410 
00411 void KeyboardHandler::setDefaultUnicodeHandler( 
00412     KeyboardEventHandler newHandler )
00413 {
00414 
00415     _defaultUnicodeHandler = newHandler ;
00416     
00417 }
00418 
00419 
00420 
00421 const string KeyboardHandler::toString( Ceylan::VerbosityLevels level ) const
00422 {
00423 
00424     string res = "Keyboard handler in " ;
00425 
00426     switch( _CurrentMode )
00427     {
00428     
00429         case rawInput:
00430             res += "raw input" ;
00431             break ;
00432             
00433         case textInput:
00434             res += "text input" ;
00435             break ;
00436         
00437         default:
00438             res += "unknown (abnormal)" ;
00439             break ; 
00440     }   
00441     
00442     res += " mode" ;
00443 
00444     return res ;
00445         
00446 }
00447 
00448 
00449 
00450 
00451 KeyboardMode KeyboardHandler::GetMode()
00452 {
00453 
00454     return _CurrentMode ;
00455     
00456 }
00457 
00458 
00459 
00460 void KeyboardHandler::SetMode( KeyboardMode newMode )
00461 {
00462 
00463 #if OSDL_USES_SDL
00464     
00465     OSDL_KEYBOARD_HANDLER_LOG( "Setting keyboard mode to " 
00466         << ( ( newMode == rawInput ) ? 
00467             "raw input mode.": "text input mode." ) ) ;
00468         
00469     _CurrentMode = newMode ;
00470     
00471     switch( newMode )
00472     {
00473     
00474         case rawInput:
00475             SDL_EnableUNICODE( 0 ) ;
00476             break ;
00477             
00478         case textInput:
00479             SDL_EnableUNICODE( 1 ) ;
00480             SDL_EnableKeyRepeat( DefaultDelayBeforeKeyRepeat,
00481                 DefaulKeyRepeatInterval ) ;
00482             break ;
00483         
00484         default:
00485             Ceylan::emergencyShutdown( 
00486                 "KeyboardHandler::SetMode: unknown keyboard mode: "
00487                 + Ceylan::toString( newMode ) + "." ) ;
00488             break ; 
00489             
00490     }
00491     
00492 #endif // OSDL_USES_SDL
00493     
00494 }
00495 
00496 
00497 
00498 string KeyboardHandler::DescribeKey( KeyIdentifier key )
00499 {
00500 
00501 #if OSDL_USES_SDL
00502 
00503     
00504     
00505     switch( key )
00506     {
00507     
00508         
00509         case BackspaceKey:
00510             return "backspace" ;
00511             break ;
00512             
00513         case TabKey:
00514             return "tab" ;
00515             break ;
00516             
00517         case ClearKey:
00518             return "clear" ;
00519             break ;
00520             
00521         case EnterKey:
00522             return "enter" ;
00523             break ;
00524             
00525         case PauseKey:
00526             return "pause" ;
00527             break ;
00528             
00529         case EscapeKey:
00530             return "escape" ;
00531             break ;
00532             
00533         case SpaceKey:
00534             return "space" ;
00535             break ;
00536             
00537         case DeleteKey:
00538             return "delete" ;
00539             break ;
00540     
00541         default:
00542             
00543             if ( key < 256 )
00544                 return Ceylan::toString( static_cast<char>( key ) )  ;
00545             else
00546                 return "(unknown key: #" + Ceylan::toString( key ) + ")" ;  
00547             break ;
00548     }
00549     
00550     return "(unexpected key)" ;
00551 
00552 #else // OSDL_USES_SDL
00553 
00554     return "(no SDL support available)" ;
00555 
00556 #endif // OSDL_USES_SDL
00557     
00558 }
00559 
00560 
00561 
00562 string KeyboardHandler::DescribeModifier( KeyModifier modifier )
00563 {
00564 
00565 #if OSDL_USES_SDL
00566 
00567     string res ; 
00568     
00569     if ( modifier & LeftShiftModifier )
00570         res += " left-shift" ;
00571 
00572     if ( modifier & RightShiftModifier )
00573         res += " right-shift" ;
00574 
00575     if ( modifier & LeftControlModifier )
00576         res += " left-control" ;
00577 
00578     if ( modifier & RightControlModifier )
00579         res += " right-control" ;
00580 
00581     if ( modifier & LeftAltModifier )
00582         res += " left-alt" ;
00583 
00584     if ( modifier & RightAltModifier )
00585         res += " right-alt" ;
00586 
00587     if ( modifier & LeftMetaModifier )
00588         res += " left-meta" ;
00589 
00590     if ( modifier & RightMetaModifier )
00591         res += " right-meta" ;
00592 
00593     if ( modifier & NumModifier )
00594         res += " numlock" ;
00595 
00596     if ( modifier & CapsModifier )
00597         res += " capslock" ;
00598 
00599     if ( modifier & ModeModifier )
00600         res += " mode" ;
00601 
00602     if ( modifier & ReservedModifier )
00603         res += " reserved" ;
00604         
00605     if ( res.empty() )
00606         return "(none)" ;
00607     else        
00608         return res ;
00609 
00610 #else // OSDL_USES_SDL
00611 
00612     return "(no SDL support available)" ;
00613 
00614 #endif // OSDL_USES_SDL
00615         
00616 }
00617 
00618 
00619 
00620 string KeyboardHandler::DescribeUnicode( Ceylan::Unicode value )
00621 {
00622                 
00623     if ( ( value & 0xff80 ) == 0 ) 
00624         return "Unicode character '" 
00625             + Ceylan::toString( static_cast<char>( value & 0x7F ) ) + "'" ;
00626     else
00627         return "International Unicode character" ;
00628 
00629 }           
00630 
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 
00639 void KeyboardHandler::focusGained( const FocusEvent & keyboardFocusEvent )  
00640 {
00641 
00642     if ( _focusController != 0 )
00643         _focusController->keyboardFocusGained( keyboardFocusEvent ) ;
00644         
00645 }
00646 
00647 
00648 
00649 void KeyboardHandler::focusLost( const FocusEvent & keyboardFocusEvent ) 
00650 {
00651 
00652     if ( _focusController != 0 )
00653         _focusController->keyboardFocusLost( keyboardFocusEvent ) ;
00654         
00655 }
00656 
00657 
00658 
00659 void KeyboardHandler::keyPressed( const KeyboardEvent & keyboardEvent )
00660 {
00661 
00662 #if OSDL_USES_SDL
00663 
00664     
00665 
00666 
00667 
00668 
00669      
00670     if ( _CurrentMode == rawInput )
00671     {
00672     
00673         map<KeyIdentifier, OSDL::MVC::Controller*>::iterator itController
00674             = _rawKeyControllerMap.find( 
00675                 static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00676             
00677         if ( itController != _rawKeyControllerMap.end() )
00678         {
00679 
00680             OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed: "
00681                 "raw key sent to controller." ) ;
00682 
00683             (*itController).second->rawKeyPressed( keyboardEvent ) ;
00684             
00685         }
00686         else
00687         {
00688 
00689             
00690             
00691             map<KeyIdentifier, KeyboardEventHandler>::iterator itHandler 
00692                 =  _rawKeyHandlerMap.find( 
00693                     static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00694             
00695             if ( itHandler != _rawKeyHandlerMap.end() )
00696             {
00697 
00698                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00699                     "sent to a raw key handler." ) ;
00700 
00701                 (*itHandler).second( keyboardEvent ) ;
00702 
00703             }   
00704             else
00705             {
00706             
00707             
00708                 if ( _defaultRawKeyController != 0 )
00709                 {
00710                 
00711                     OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00712                         "sent to default raw key controller." ) ;
00713                 
00714                     _defaultRawKeyController->rawKeyPressed( keyboardEvent ) ;
00715                     
00716                 }
00717                 else
00718                 {
00719 
00720                     OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00721                         "sent to default raw key handler." ) ;
00722                 
00723                     _defaultRawKeyHandler( keyboardEvent ) ;
00724                 
00725                 }   
00726 
00727             }
00728 
00729         
00730         } 
00731         
00732         
00733         return ;
00734         
00735                     
00736     } 
00737     
00738     
00739     
00740     
00741     if ( _CurrentMode == textInput )
00742     {
00743     
00744         map<Ceylan::Unicode, OSDL::MVC::Controller*>::iterator itController
00745             =  _unicodeControllerMap.find( 
00746                 static_cast<KeyIdentifier>( keyboardEvent.keysym.unicode ) ) ;
00747             
00748         if ( itController != _unicodeControllerMap.end() )
00749         {
00750 
00751             OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed: "
00752                 "Unicode sent to controller." ) ;
00753     
00754             (*itController).second->unicodeSelected( keyboardEvent ) ;
00755             
00756         }
00757         else
00758         {
00759 
00760 
00761             
00762             
00763             map<Ceylan::Unicode, KeyboardEventHandler>::iterator itHandler 
00764                 =  _unicodeHandlerMap.find( 
00765                     static_cast<KeyIdentifier>( 
00766                         keyboardEvent.keysym.unicode ) ) ;
00767             
00768             if ( itHandler != _unicodeHandlerMap.end() )
00769             {
00770 
00771                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00772                     "sent to Unicode handler." ) ;
00773 
00774                 (*itHandler).second( keyboardEvent ) ;
00775 
00776             }   
00777             else
00778             {
00779             
00780                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00781                     "sent to default Unicode handler." ) ;
00782 
00783                 _defaultUnicodeHandler( keyboardEvent ) ;
00784 
00785             }
00786 
00787         
00788         } 
00789 
00790     
00791     } 
00792             
00793 #endif // OSDL_USES_SDL
00794 
00795 }
00796 
00797 
00798 
00799 void KeyboardHandler::keyReleased( const KeyboardEvent & keyboardEvent )
00800 {
00801 
00802 #if OSDL_USES_SDL
00803 
00804     
00805 
00806 
00807 
00808 
00809      
00810      
00811     if ( _CurrentMode == rawInput )
00812     {
00813     
00814         map<KeyIdentifier, OSDL::MVC::Controller*>::iterator itController
00815             = _rawKeyControllerMap.find( 
00816                 static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00817             
00818         if ( itController != _rawKeyControllerMap.end() )
00819         {
00820 
00821             OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyReleased: "
00822                 "raw key sent to controller." ) ;
00823 
00824             (*itController).second->rawKeyReleased( keyboardEvent ) ;
00825             
00826         }
00827         else
00828         {
00829 
00830             
00831             
00832             map<KeyIdentifier, KeyboardEventHandler>::iterator itHandler 
00833                 =  _rawKeyHandlerMap.find( 
00834                     static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00835             
00836             if ( itHandler != _rawKeyHandlerMap.end() )
00837             {
00838 
00839                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyReleased "
00840                     "sent to a raw key handler." ) ;
00841 
00842                 (*itHandler).second( keyboardEvent ) ;
00843 
00844             }   
00845             else
00846             {
00847             
00848                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyReleased "
00849                     "sent to default raw key handler." ) ;
00850                 
00851                 _defaultRawKeyHandler( keyboardEvent ) ;
00852 
00853             }
00854         
00855         }
00856 
00857 
00858         
00859         return ;
00860             
00861     } 
00862     
00863     
00864 
00865 
00866 
00867 
00868 
00869 
00870 #endif // OSDL_USES_SDL
00871      
00872 }
00873