diff --git a/src/servers/app/server/AppServer.cpp b/src/servers/app/server/AppServer.cpp index 9aa6e6281a..1cf4c1837a 100644 --- a/src/servers/app/server/AppServer.cpp +++ b/src/servers/app/server/AppServer.cpp @@ -558,11 +558,195 @@ void AppServer::Broadcast(int32 code) /*! \brief Handles all incoming key messages \param code ID code of the key message - \param buffer Attachment buffer of the keyboard message + \param buffer Attachment buffer of the keyboard message. Always non-NULL. + + This function handles 5 message codes: B_KEY_UP, B_KEY_DOWN, + B_UNMAPPED_KEY_UP, B_UNMAPPED_KEY_DOWN, and B_MODIFIERS_CHANGED. It filters + out any combinations which are app_server specific: + # Left Ctrl+Alt+Shift+F12 - set to 640x480x256@60Hz + # Alt + Function Key - Change workspace + # Control+Tab - Send to Deskbar for the Twitcher */ void AppServer::HandleKeyMessage(int32 code, int8 *buffer) { - // TODO: Implement + int8 *index=buffer; + + switch(code) + { + case B_KEY_DOWN: + { + // Attached Data: + // 1) int64 bigtime_t object of when the message was sent + // 2) int32 raw key code (scancode) + // 3) int32 modifier-independent ASCII code for the character + // 4) int32 repeat count + // 5) int32 modifiers + // 6) int8[3] UTF-8 data generated + // 7) int8 number of bytes to follow containing the + // generated string + // 8) Character string generated by the keystroke + // 9) int32 number of elements in the key state array to follow + // 10) int8 state of all keys + + // Obtain only what data which we'll need + index+=sizeof(int64); + int32 scancode=*((int32*)index); index+=sizeof(int32) * 3; + int32 modifiers=*((int32*)index); index+=sizeof(int8) * 3; + int8 stringlength=*index; index+=stringlength + sizeof(int8); + int32 keyindices=*index; + + + // Check for workspace change or safe video mode + if(scancode>0x01 && scancode<0x0e) + { + // F12 + if(scancode==0x0d) + { + if(modifiers & B_LEFT_COMMAND_KEY & + B_LEFT_CONTROL_KEY & B_LEFT_SHIFT_KEY) + { + // TODO: Set to Safe Mode here. (DisplayDriver API change) + } + } + + if(modifiers & B_COMMAND_KEY) + SetWorkspace(scancode-2); + + // Tab key + if(scancode==0x26 && (modifiers & B_CONTROL_KEY)) + { + ServerApp *deskbar=FindApp("application/x-vnd.Be-TSKB"); + if(deskbar) + { + // I hope this calculation's right ;) + size_t msgsize=sizeof(int64) + ( sizeof(int32) * 5) + + ( sizeof(int8) * (4+ stringlength + keyindices)); + deskbar->PostMessage(code, msgsize, buffer); + break; + } + } + } + + // We got this far, so apparently it's safe to pass to the active + // window. + + // TODO: Call ServerWindow::HandleKeyEvent when we have ServerWindow.h + + break; + } + case B_KEY_UP: + { + // Attached Data: + // 1) int64 bigtime_t object of when the message was sent + // 2) int32 raw key code (scancode) + // 3) int32 modifier-independent ASCII code for the character + // 4) int32 modifiers + // 5) int8[3] UTF-8 data generated + // 6) int8 number of bytes to follow containing the + // generated string + // 7) Character string generated by the keystroke + // 8) int32 number of elements in the key state array to follow + // 9) int8 state of all keys + + // Obtain only what data which we'll need + index+=sizeof(int64); + int32 scancode=*((int32*)index); index+=sizeof(int32) * 3; + int32 modifiers=*((int32*)index); index+=sizeof(int8) * 3; + int8 stringlength=*index; index+=stringlength + sizeof(int8); + int32 keyindices=*index; + + // Send the key_up msg to the Deskbar for the twitcher + + // Tab key + if(scancode==0x26 && (modifiers & B_CONTROL_KEY)) + { + ServerApp *deskbar=FindApp("application/x-vnd.Be-TSKB"); + if(deskbar) + { + // I hope this calculation's right ;) + size_t msgsize=sizeof(int64) + ( sizeof(int32) * 4) + + ( sizeof(int8) * (4+ stringlength + keyindices)); + deskbar->PostMessage(code, msgsize, buffer); + break; + } + } + + // We got this far, so apparently it's safe to pass to the active + // window. + + // fall through to the next case + } + case B_UNMAPPED_KEY_DOWN: + { + // Attached Data: + // 1) int64 bigtime_t object of when the message was sent + // 2) int32 raw key code (scancode) + // 3) int32 modifiers + // 4) int32 number of elements in the key state array to follow + // 5) int8 state of all keys + + // fall through to the next case + } + case B_UNMAPPED_KEY_UP: + { + // Attached Data: + // 1) int64 bigtime_t object of when the message was sent + // 2) int32 raw key code (scancode) + // 3) int32 modifiers + // 4) int32 number of elements in the key state array to follow + // 5) int8 state of all keys + + // fall through to the next case + } + case B_MODIFIERS_CHANGED: + { + // Attached Data: + // 1) int64 bigtime_t object of when the message was sent + // 2) int32 modifiers + // 3) int32 old modifiers + // 4) int32 number of elements in the key state array to follow + // 5) int8 state of all keys + + // TODO: Call ServerWindow::HandleKeyEvent when we have ServerWindow.h + + break; + } + default: + break; + } +} + +/*! + \brief Finds the application with the given signature + \param sig MIME signature of the application to find + \return the corresponding ServerApp or NULL if not found + + This call should be made only when necessary because it locks the app list + while it does its searching. +*/ +ServerApp *AppServer::FindApp(const char *sig) +{ + if(!sig) + return NULL; + + ServerApp *foundapp=NULL; + + acquire_sem(_applist_lock); + + for(int32 i=0; i<_applist->CountItems();i++) + { + foundapp=(ServerApp*)_applist->ItemAt(i); + if(foundapp && foundapp->_signature==sig) + { + release_sem(_applist_lock); + return foundapp; + } + } + + release_sem(_applist_lock); + + // couldn't find a match + return NULL; } /*! diff --git a/src/servers/app/server/AppServer.h b/src/servers/app/server/AppServer.h index 04bca0835a..6f02770413 100644 --- a/src/servers/app/server/AppServer.h +++ b/src/servers/app/server/AppServer.h @@ -33,7 +33,8 @@ public: void DispatchMessage(int32 code, int8 *buffer); void Broadcast(int32 code); void HandleKeyMessage(int32 code, int8 *buffer); - + ServerApp *FindApp(const char *sig); + create_decorator *make_decorator; // global function pointer private: friend Decorator *instantiate_decorator(Layer *lay, const char *title, uint32 dflags, uint32 wlook); diff --git a/src/servers/app/server/ServerApp.cpp b/src/servers/app/server/ServerApp.cpp index 0b4faba3de..7f4e33c745 100644 --- a/src/servers/app/server/ServerApp.cpp +++ b/src/servers/app/server/ServerApp.cpp @@ -176,9 +176,9 @@ bool ServerApp::PingTarget(void) \brief Send a message to the ServerApp with no attachments \param code ID code of the message to post */ -void ServerApp::PostMessage(int32 code) +void ServerApp::PostMessage(int32 code, size_t size, int8 *buffer) { - write_port(_receiver,code, NULL, 0); + write_port(_receiver,code, buffer, size); } /*! diff --git a/src/servers/app/server/ServerApp.h b/src/servers/app/server/ServerApp.h index 346c677f18..bf47533377 100644 --- a/src/servers/app/server/ServerApp.h +++ b/src/servers/app/server/ServerApp.h @@ -67,7 +67,7 @@ public: void Activate(bool value) { _isactive=value; } bool PingTarget(void); - void PostMessage(int32 code); + void PostMessage(int32 code, size_t size=0, int8 *buffer=NULL); protected: friend AppServer; void DispatchMessage(int32 code, int8 *buffer);