OSDLKeyboardHandler.cc

Go to the documentation of this file.
00001 #include "OSDLKeyboardHandler.h"
00002 
00003 #include "OSDLController.h"      // for Controller
00004 #include "OSDLEvents.h"          // for KeyPressed, EventsException
00005 #include "OSDLBasic.h"           // for getExistingCommonModule
00006 
00007 #include "SDL.h"                 // for SDL_EnableUNICODE
00008 
00009 
00010 
00011 using std::string ;
00012 using std::list ;
00013 using std::map ;
00014 
00015 
00016 using namespace Ceylan::Log ;    // for LogPlug
00017 using namespace OSDL::Events ;
00018 
00019 
00020 #ifdef OSDL_USES_CONFIG_H
00021 #include <OSDLConfig.h>          // for OSDL_VERBOSE_KEYBOARD_HANDLER and al
00022 #endif // OSDL_USES_CONFIG_H
00023 
00024 
00025 
00026 #if OSDL_VERBOSE_KEYBOARD_HANDLER
00027 
00028 #include <iostream>
00029 #define OSDL_KEYBOARD_HANDLER_LOG( message ) std::cout << "[OSDL Keyboard Handler] " << message << std::endl ;
00030 
00031 #else // OSDL_VERBOSE_KEYBOARD_HANDLER
00032 
00033 #define OSDL_KEYBOARD_HANDLER_LOG( message )
00034 
00035 #endif // OSDL_VERBOSE_KEYBOARD_HANDLER
00036 
00037 
00038 
00039 const Ceylan::System::Millisecond KeyboardHandler::DefaultDelayBeforeKeyRepeat 
00040     = SDL_DEFAULT_REPEAT_DELAY ; 
00041     
00042 const Ceylan::System::Millisecond KeyboardHandler::DefaulKeyRepeatInterval
00043     = SDL_DEFAULT_REPEAT_INTERVAL ;
00044 
00045 
00046 // Starts with raw input mode.
00047 KeyboardMode KeyboardHandler::_CurrentMode = rawInput ;
00048 
00049 
00050 
00051 KeyboardException::KeyboardException( const string & message ) throw() :
00052     EventsException( message )
00053 {
00054 
00055 }
00056 
00057 
00058 KeyboardException::~KeyboardException() throw()
00059 {
00060 
00061 }
00062 
00063 
00064 
00065 
00073 void doNothingKeyHandler( const KeyboardEvent & keyboardEvent )
00074 {
00075 
00076     OSDL_KEYBOARD_HANDLER_LOG( EventsModule::DescribeEvent( keyboardEvent ) ) ;
00077         
00078 }
00079 
00080 
00092 void smarterKeyHandler( const KeyboardEvent & keyboardEvent )
00093 {
00094 
00095     OSDL_KEYBOARD_HANDLER_LOG( 
00096         EventsModule::DescribeEvent( keyboardEvent ) ) ;        
00097     
00098     // Reacts to key presses for both input modes (raw or text) :
00099     
00100     if ( keyboardEvent.type != EventsModule::KeyPressed )
00101     {
00102         
00103         // Only key presses interest us .
00104         return ;
00105     }
00106     
00107     
00108     switch( static_cast<KeyboardHandler::KeyIdentifier>(
00109         keyboardEvent.keysym.sym ) )
00110     {
00111     
00112         case KeyboardHandler::EscapeKey:
00113         case KeyboardHandler::qKey:
00114             LogPlug::debug( "Input keypress requested exit." ) ;
00115             EventsModule::DescribeEvent( keyboardEvent ) ;
00116             OSDL::getExistingCommonModule().getEventsModule().requestQuit() ;
00117             break ;
00118             
00119         case KeyboardHandler::F1Key:
00120             // F1 : toggle text/raw input mode :
00121             EventsModule::DescribeEvent( keyboardEvent ) ;
00122             if ( KeyboardHandler::GetMode() == rawInput )
00123                 KeyboardHandler::SetMode( textInput ) ;
00124             else
00125                 KeyboardHandler::SetMode( rawInput ) ;
00126             break ; 
00127             
00128         /*  
00129         
00130         case KeyboardHandler::F2Key:
00131             // F2 : raw input mode :
00132             EventsModule::DescribeEvent( keyboardEvent ) ;
00133             KeyboardHandler::SetMode( rawInput ) ;
00134             break ; 
00135             
00136         case KeyboardHandler::F3Key:
00137             // F3 : text input mode :
00138             EventsModule::DescribeEvent( keyboardEvent ) ;
00139             KeyboardHandler::SetMode( textInput ) ;
00140             break ; 
00141             
00142         */
00143             
00144         default:
00145             EventsModule::DescribeEvent( keyboardEvent ) ;
00146             break ;
00147     }
00148         
00149 }
00150 
00151 
00152 KeyboardHandler::KeyboardHandler( KeyboardMode initialMode, 
00153     bool useSmarterDefaultKeyHandler )
00154         throw( InputDeviceHandlerException ) :
00155     InputDeviceHandler(),
00156     _rawKeyControllerMap(),
00157     _rawKeyHandlerMap(),
00158     _unicodeControllerMap(),
00159     _unicodeHandlerMap(),
00160     _focusController( 0 )
00161 {
00162 
00163     send( "Initializing keyboard subsystem." ) ;
00164 
00165     // No SDL_InitSubSystem for keyboard.
00166     
00167     // Stores the previous Unicode mode :
00168     _unicodeInputWasActivated = ( SDL_EnableUNICODE( -1 ) == 1 ) ;
00169     
00170     if ( useSmarterDefaultKeyHandler )
00171     {
00172         setSmarterDefaultKeyHandlers() ;
00173     }
00174     else
00175     {
00176         _defaultRawKeyHandler  = doNothingKeyHandler ;
00177         _defaultUnicodeHandler = doNothingKeyHandler ;
00178     }
00179     
00180     SetMode( initialMode ) ;    
00181 
00182     send( "Keyboard subsystem initialized." ) ;
00183 
00184     dropIdentifier() ;
00185     
00186 }
00187 
00188 
00189 KeyboardHandler::~KeyboardHandler() throw()
00190 {
00191 
00192     send( "Stopping keyboard subsystem." ) ;
00193 
00194     // Avoid side-effects :
00195     if ( _unicodeInputWasActivated ) 
00196         SDL_EnableUNICODE( 1 ) ;
00197     else
00198         SDL_EnableUNICODE( 0 ) ;
00199 
00200     // No SDL_QuitSubSystem for keyboard.
00201     
00202     send( "Keyboard subsystem stopped." ) ;
00203         
00204 }
00205 
00206 
00207 void KeyboardHandler::linkToController( KeyIdentifier rawKey, 
00208     OSDL::MVC::Controller & controller ) throw()
00209 {
00210 
00211     _rawKeyControllerMap[ rawKey ] = & controller ;
00212     
00213 }
00214 
00215                     
00216 void KeyboardHandler::linkToController( Ceylan::Unicode unicode, 
00217     OSDL::MVC::Controller & controller ) throw()
00218 {
00219 
00220     _unicodeControllerMap[ unicode ] = & controller ;
00221     
00222 }
00223     
00224 
00225     
00226 void KeyboardHandler::linkToFocusController(
00227     OSDL::MVC::Controller & controller ) throw()
00228 {
00229 
00230     _focusController = & controller ;
00231     
00232 }
00233     
00234     
00235     
00236 void KeyboardHandler::linkToHandler( KeyIdentifier rawKey, 
00237     KeyboardEventHandler handler ) throw()
00238 {
00239 
00240     _rawKeyHandlerMap[ rawKey ] = handler ;
00241     
00242 }
00243 
00244                     
00245 void KeyboardHandler::linkToHandler( Ceylan::Unicode unicode,
00246     KeyboardEventHandler handler ) throw()
00247 {
00248 
00249     _unicodeHandlerMap[ unicode ] = handler ;
00250     
00251 }
00252     
00253 
00254 void KeyboardHandler::setSmarterDefaultKeyHandlers() throw()
00255 {
00256 
00257     _defaultRawKeyHandler  = smarterKeyHandler ;
00258     _defaultUnicodeHandler = smarterKeyHandler ;
00259     
00260 }
00261 
00262 
00263 void KeyboardHandler::setDefaultRawKeyHandler( 
00264     KeyboardEventHandler newHandler ) throw()
00265 {
00266 
00267     _defaultRawKeyHandler = newHandler ;
00268     
00269 }
00270 
00271 
00272 void KeyboardHandler::setDefaultUnicodeHandler( 
00273     KeyboardEventHandler newHandler ) throw()
00274 {
00275 
00276     _defaultUnicodeHandler = newHandler ;
00277     
00278 }
00279 
00280 
00281 const string KeyboardHandler::toString( Ceylan::VerbosityLevels level ) 
00282     const throw()
00283 {
00284 
00285     string res = "Keyboard handler in " ;
00286 
00287     switch( _CurrentMode )
00288     {
00289     
00290         case rawInput:
00291             res += "raw input" ;
00292             break ;
00293             
00294         case textInput:
00295             res += "text input" ;
00296             break ;
00297         
00298         default:
00299             res += "unknown (abnormal)" ;
00300             break ; 
00301     }   
00302     
00303     res += " mode" ;
00304 
00305     return res ;
00306         
00307 }
00308 
00309 
00310 
00311 
00312 KeyboardMode KeyboardHandler::GetMode() throw()
00313 {
00314 
00315     return _CurrentMode ;
00316     
00317 }
00318 
00319 
00320 void KeyboardHandler::SetMode( KeyboardMode newMode ) throw()
00321 {
00322 
00323     
00324     OSDL_KEYBOARD_HANDLER_LOG( "Setting keyboard mode to " 
00325         << ( ( newMode == rawInput ) ? 
00326             "raw input mode." : "text input mode." ) ) ;
00327         
00328     _CurrentMode = newMode ;
00329     
00330     switch( newMode )
00331     {
00332     
00333         case rawInput:
00334             SDL_EnableUNICODE( 0 ) ;
00335             break ;
00336             
00337         case textInput:
00338             SDL_EnableUNICODE( 1 ) ;
00339             SDL_EnableKeyRepeat( DefaultDelayBeforeKeyRepeat,
00340                 DefaulKeyRepeatInterval ) ;
00341             break ;
00342         
00343         default:
00344             Ceylan::emergencyShutdown( 
00345                 "KeyboardHandler::SetMode : unknown keyboard mode : "
00346                 + Ceylan::toString( newMode ) + "." ) ;
00347             break ; 
00348             
00349     }
00350     
00351     
00352 }
00353 
00354 
00355 string KeyboardHandler::DescribeKey( KeyIdentifier key ) throw()
00356 {
00357 
00358     // @fixme add all remaining characters (see SDL_keysym.h)
00359     
00360     switch( key )
00361     {
00362     
00363         // Handle non printable characters specifically :
00364         case BackspaceKey:
00365             return "backspace" ;
00366             break ;
00367             
00368         case TabKey:
00369             return "tab" ;
00370             break ;
00371             
00372         case ClearKey:
00373             return "clear" ;
00374             break ;
00375             
00376         case EnterKey:
00377             return "enter" ;
00378             break ;
00379             
00380         case PauseKey:
00381             return "pause" ;
00382             break ;
00383             
00384         case EscapeKey:
00385             return "escape" ;
00386             break ;
00387             
00388         case SpaceKey:
00389             return "space" ;
00390             break ;
00391             
00392         case DeleteKey:
00393             return "delete" ;
00394             break ;
00395     
00396         default:
00397             // Handles other ASCII characters : 
00398             if ( key < 256 )
00399                 return Ceylan::toString( static_cast<char>( key ) )  ;
00400             else
00401                 return "(unknown key : #" + Ceylan::toString( key ) + ")" ;     
00402             break ;
00403     }
00404     
00405     return "(unexpected key)" ;
00406     
00407 }
00408 
00409 
00410 string KeyboardHandler::DescribeModifier( KeyModifier modifier ) throw()
00411 {
00412 
00413     string res ; 
00414     
00415     if ( modifier & LeftShiftModifier )
00416         res += " left-shift" ;
00417 
00418     if ( modifier & RightShiftModifier )
00419         res += " right-shift" ;
00420 
00421     if ( modifier & LeftControlModifier )
00422         res += " left-control" ;
00423 
00424     if ( modifier & RightControlModifier )
00425         res += " right-control" ;
00426 
00427     if ( modifier & LeftAltModifier )
00428         res += " left-alt" ;
00429 
00430     if ( modifier & RightAltModifier )
00431         res += " right-alt" ;
00432 
00433     if ( modifier & LeftMetaModifier )
00434         res += " left-meta" ;
00435 
00436     if ( modifier & RightMetaModifier )
00437         res += " right-meta" ;
00438 
00439     if ( modifier & NumModifier )
00440         res += " numlock" ;
00441 
00442     if ( modifier & CapsModifier )
00443         res += " capslock" ;
00444 
00445     if ( modifier & ModeModifier )
00446         res += " mode" ;
00447 
00448     if ( modifier & ReservedModifier )
00449         res += " reserved" ;
00450         
00451     if ( res.empty() )
00452         return "(none)" ;
00453     else        
00454         return res ;
00455         
00456 }
00457 
00458 
00459 string KeyboardHandler::DescribeUnicode( Ceylan::Unicode value ) throw()
00460 {
00461                 
00462     if ( ( value & 0xff80 ) == 0 ) 
00463         return "Unicode character '" 
00464             + Ceylan::toString( static_cast<char>( value & 0x7F ) ) + "'" ;
00465     else
00466         return "International Unicode character" ;
00467 
00468 }           
00469 
00470 
00471 
00472 
00473 // Protected section.
00474 
00475 
00476 void KeyboardHandler::focusGained( const FocusEvent & keyboardFocusEvent )
00477     throw()
00478 {
00479 
00480     if ( _focusController != 0 )
00481         _focusController->keyboardFocusGained( keyboardFocusEvent ) ;
00482         
00483 }
00484 
00485 
00486 void KeyboardHandler::focusLost( const FocusEvent & keyboardFocusEvent ) 
00487     throw()
00488 {
00489 
00490     if ( _focusController != 0 )
00491         _focusController->keyboardFocusLost( keyboardFocusEvent ) ;
00492         
00493 }
00494 
00495 
00496 void KeyboardHandler::keyPressed( const KeyboardEvent & keyboardEvent ) throw()
00497 {
00498 
00499 
00500     /*
00501      * In raw or text mode, use a controller if available, otherwise an handler
00502      * will be used, a specified one if any, else the default handler.
00503      *
00504      */
00505      
00506     if ( _CurrentMode == rawInput )
00507     {
00508     
00509         map<KeyIdentifier, OSDL::MVC::Controller *>::iterator itController
00510             = _rawKeyControllerMap.find( 
00511                 static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00512             
00513         if ( itController != _rawKeyControllerMap.end() )
00514         {
00515 
00516             OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed : "
00517                 "raw key sent to controller." ) ;
00518 
00519             (*itController).second->rawKeyPressed( keyboardEvent ) ;
00520             
00521         }
00522         else
00523         {
00524 
00525             // No controller registered, default to handler map :
00526             
00527             map<KeyIdentifier, KeyboardEventHandler>::iterator itHandler 
00528                 =  _rawKeyHandlerMap.find( 
00529                     static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00530             
00531             if ( itHandler != _rawKeyHandlerMap.end() )
00532             {
00533 
00534                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00535                     "sent to a raw key handler." ) ;
00536 
00537                 (*itHandler).second( keyboardEvent ) ;
00538 
00539             }   
00540             else
00541             {
00542             
00543                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00544                     "sent to default raw key handler." ) ;
00545                 
00546                 _defaultRawKeyHandler( keyboardEvent ) ;
00547 
00548             }
00549 
00550         
00551         } 
00552         
00553         // Avoid handling the same key twice (ex : keyboard mode toggle...)     
00554         return ;
00555         
00556                     
00557     } // _CurrentMode == rawInput
00558     
00559     
00560     // Other possibility : in text input mode.
00561     
00562     if ( _CurrentMode == textInput )
00563     {
00564     
00565         map<Ceylan::Unicode, OSDL::MVC::Controller *>::iterator itController
00566             =  _unicodeControllerMap.find( 
00567                 static_cast<KeyIdentifier>( keyboardEvent.keysym.unicode ) ) ;
00568             
00569         if ( itController != _unicodeControllerMap.end() )
00570         {
00571 
00572             OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed : "
00573                 "Unicode sent to controller." ) ;
00574     
00575             (*itController).second->unicodeSelected( keyboardEvent ) ;
00576             
00577         }
00578         else
00579         {
00580 
00581 
00582             // No controller registered, default to handler map :
00583             
00584             map<Ceylan::Unicode, KeyboardEventHandler>::iterator itHandler 
00585                 =  _unicodeHandlerMap.find( 
00586                     static_cast<KeyIdentifier>( 
00587                         keyboardEvent.keysym.unicode ) ) ;
00588             
00589             if ( itHandler != _unicodeHandlerMap.end() )
00590             {
00591 
00592                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00593                     "sent to Unicode handler." ) ;
00594 
00595                 (*itHandler).second( keyboardEvent ) ;
00596 
00597             }   
00598             else
00599             {
00600             
00601                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyPressed "
00602                     "sent to default Unicode handler." ) ;
00603 
00604                 _defaultUnicodeHandler( keyboardEvent ) ;
00605 
00606             }
00607 
00608         
00609         } 
00610 
00611     
00612     } // _CurrentMode == textInput
00613             
00614 
00615 }
00616 
00617 
00618 
00619 void KeyboardHandler::keyReleased( const KeyboardEvent & keyboardEvent ) throw()
00620 {
00621 
00622 
00623     /*
00624      * In raw mode, use a controller if available, otherwise an handler
00625      * will be used, a specified one if any, else the default handler.
00626      *
00627      */
00628      
00629      
00630     if ( _CurrentMode == rawInput )
00631     {
00632     
00633         map<KeyIdentifier, OSDL::MVC::Controller *>::iterator itController
00634             =  _rawKeyControllerMap.find( 
00635                 static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00636             
00637         if ( itController != _rawKeyControllerMap.end() )
00638         {
00639 
00640             OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyReleased : "
00641                 "raw key sent to controller." ) ;
00642 
00643             (*itController).second->rawKeyReleased( keyboardEvent ) ;
00644             
00645         }
00646         else
00647         {
00648 
00649             // No controller registered, default to handler map :
00650             
00651             map<KeyIdentifier, KeyboardEventHandler>::iterator itHandler 
00652                 =  _rawKeyHandlerMap.find( 
00653                     static_cast<KeyIdentifier>( keyboardEvent.keysym.sym ) ) ;
00654             
00655             if ( itHandler != _rawKeyHandlerMap.end() )
00656             {
00657 
00658                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyReleased "
00659                     "sent to a raw key handler." ) ;
00660 
00661                 (*itHandler).second( keyboardEvent ) ;
00662 
00663             }   
00664             else
00665             {
00666             
00667                 OSDL_KEYBOARD_HANDLER_LOG( "KeyboardHandler::keyReleased "
00668                     "sent to default raw key handler." ) ;
00669                 
00670                 _defaultRawKeyHandler( keyboardEvent ) ;
00671 
00672             }
00673         
00674         }
00675 
00676 
00677         // Avoid handling the same key twice (ex : keyboard mode toggle...)     
00678         return ;
00679             
00680     } 
00681     
00682     /*
00683      * Release events do not have unicode information, so do nothing on 
00684      * text input mode.
00685      * They are handled differently, with key repeats.
00686      *
00687      */
00688      
00689 }
00690 

Generated on Fri Mar 30 14:46:59 2007 for OSDL by  doxygen 1.5.1