diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 7bb2302c38..5dd58f5e46 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,98 @@ #endif +class KeyboardFilter : public BMessageFilter { + public: + KeyboardFilter(Desktop* desktop); + + virtual filter_result Filter(BMessage* message, BHandler** _target); + + private: + Desktop* fDesktop; +}; + + +KeyboardFilter::KeyboardFilter(Desktop* desktop) + : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE), + fDesktop(desktop) +{ +} + + +filter_result +KeyboardFilter::Filter(BMessage* message, BHandler** /*_target*/) +{ + int32 key; + int32 modifiers; + + if (message->what != B_KEY_DOWN + || message->FindInt32("key", &key) != B_OK + || message->FindInt32("modifiers", &modifiers) != B_OK) + return B_DISPATCH_MESSAGE; + + // Check for safe video mode (F12 + l-cmd + l-ctrl + l-shift) + if (key == 0x0d + && (modifiers & (B_LEFT_COMMAND_KEY + | B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY)) != 0) + { + // TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN. + STRACE(("Safe Video Mode invoked - code unimplemented\n")); + return B_SKIP_MESSAGE; + } + + if (key > 0x01 && key < 0x0e) { + // workspace change, F1-F12 + +#if !TEST_MODE + if (modifiers & B_COMMAND_KEY) +#else + if (modifiers & B_CONTROL_KEY) +#endif + { + STRACE(("Set Workspace %ld\n", key - 1)); + RootLayer* root = fDesktop->RootLayer(); + + root->Lock(); + root->SetActiveWorkspace(key - 2); + +#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER + // to draw the current Workspace index on screen. + BRegion region(VisibleRegion()); + fDesktop->GetDrawingEngine()->ConstrainClippingRegion(®ion); + root->Draw(region.Frame()); + fDesktop->GetDrawingEngine()->ConstrainClippingRegion(NULL); +#endif + root->Unlock(); + return B_SKIP_MESSAGE; + } + } + + // TODO: this should be moved client side! + // (that's how it is done in BeOS, clients could need this key for + // different purposes - also, it's preferrable to let the client + // write the dump within his own environment) + if (key == 0xe) { + // screen dump, PrintScreen + char filename[128]; + BEntry entry; + + int32 index = 1; + do { + sprintf(filename, "/boot/home/screen%ld.png", index++); + entry.SetTo(filename); + } while(entry.Exists()); + + fDesktop->GetDrawingEngine()->DumpToFile(filename); + return B_SKIP_MESSAGE; + } + + return B_DISPATCH_MESSAGE; +} + + +// #pragma mark - + + Desktop::Desktop(uid_t userID) : MessageLooper("desktop"), fUserID(userID), @@ -94,7 +187,7 @@ Desktop::Init() // TODO: add user identity to the name char name[32]; sprintf(name, "RootLayer %d", 1); - fRootLayer = new RootLayer(name, 4, this, GetDrawingEngine()); + fRootLayer = new ::RootLayer(name, 4, this, GetDrawingEngine()); #if TEST_MODE gInputManager->AddStream(new InputServerStream); @@ -105,7 +198,7 @@ Desktop::Init() // temporary hack to get things started class MouseFilter : public BMessageFilter { public: - MouseFilter(RootLayer* layer) + MouseFilter(::RootLayer* layer) : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE), fRootLayer(layer) { @@ -121,9 +214,10 @@ Desktop::Init() } private: - RootLayer* fRootLayer; + ::RootLayer* fRootLayer; }; fEventDispatcher.SetMouseFilter(new MouseFilter(fRootLayer)); + fEventDispatcher.SetKeyboardFilter(new KeyboardFilter(this)); // take care of setting the default cursor ServerCursor *cursor = fCursorManager.GetCursor(B_CURSOR_DEFAULT); @@ -394,20 +488,17 @@ Desktop::AddWinBorder(WinBorder *winBorder) if (!winBorder) return; - // R2: how to determine the RootLayer to which this window should be added??? - // for now, use ActiveRootLayer() because we only have one instance. - int32 feel = winBorder->Feel(); // we are ServerApp thread, we need to lock RootLayer here. - ActiveRootLayer()->Lock(); + RootLayer()->Lock(); // we're playing with window list. lock first. Lock(); if (fWinBorderList.HasItem(winBorder)) { Unlock(); - ActiveRootLayer()->Unlock(); + RootLayer()->Unlock(); debugger("AddWinBorder: WinBorder already in Desktop list\n"); return; } @@ -443,12 +534,12 @@ Desktop::AddWinBorder(WinBorder *winBorder) } // send WinBorder to be added to workspaces - ActiveRootLayer()->AddWinBorder(winBorder); + RootLayer()->AddWinBorder(winBorder); // hey, unlock! Unlock(); - ActiveRootLayer()->Unlock(); + RootLayer()->Unlock(); } @@ -459,7 +550,7 @@ Desktop::RemoveWinBorder(WinBorder *winBorder) return; // we are ServerApp thread, we need to lock RootLayer here. - ActiveRootLayer()->Lock(); + RootLayer()->Lock(); // we're playing with window list. lock first. Lock(); @@ -494,16 +585,16 @@ Desktop::RemoveWinBorder(WinBorder *winBorder) } } else { Unlock(); - ActiveRootLayer()->Unlock(); + RootLayer()->Unlock(); debugger("RemoveWinBorder: WinBorder not found in Desktop list\n"); return; } // Tell to winBorder's RootLayer about this. - ActiveRootLayer()->RemoveWinBorder(winBorder); + RootLayer()->RemoveWinBorder(winBorder); Unlock(); - ActiveRootLayer()->Unlock(); + RootLayer()->Unlock(); } @@ -538,7 +629,7 @@ Desktop::AddWinBorderToSubset(WinBorder *winBorder, WinBorder *toWinBorder) } // send WinBorder to be added to workspaces, if not already in there. - ActiveRootLayer()->AddSubsetWinBorder(winBorder, toWinBorder); + RootLayer()->AddSubsetWinBorder(winBorder, toWinBorder); Unlock(); } @@ -562,7 +653,7 @@ Desktop::RemoveWinBorderFromSubset(WinBorder *winBorder, WinBorder *fromWinBorde } // remove WinBorder from workspace, if needed - some other windows may still have it in their subset - ActiveRootLayer()->RemoveSubsetWinBorder(winBorder, fromWinBorder); + RootLayer()->RemoveSubsetWinBorder(winBorder, fromWinBorder); if (fromWinBorder->Feel() == B_NORMAL_WINDOW_FEEL) { //remove from this normal_window's subset. diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index f3f04cd197..d192a69db4 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -60,7 +60,7 @@ class Desktop : public MessageLooper, public ScreenOwner { { return fActiveScreen; } inline Screen* ActiveScreen() const { return fActiveScreen; } - inline RootLayer* ActiveRootLayer() const { return fRootLayer; } + inline ::RootLayer* RootLayer() const { return fRootLayer; } inline CursorManager& GetCursorManager() { return fCursorManager; } virtual void ScreenRemoved(Screen* screen) {} @@ -116,7 +116,7 @@ class Desktop : public MessageLooper, public ScreenOwner { BObjectList fWinBorderList; - RootLayer* fRootLayer; + ::RootLayer* fRootLayer; Screen* fActiveScreen; CursorManager fCursorManager; diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 83f31ff980..7cf48e3003 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -61,7 +61,7 @@ EventDispatcher::EventDispatcher() fTransit(false), fSuspendFocus(false), fMouseFilter(NULL), - fKeyFilter(NULL), + fKeyboardFilter(NULL), fListeners(10, true), // the list owns its items fCursorLock("cursor loop lock"), @@ -322,15 +322,15 @@ EventDispatcher::SetMouseFilter(BMessageFilter* filter) void -EventDispatcher::SetKeyFilter(BMessageFilter* filter) +EventDispatcher::SetKeyboardFilter(BMessageFilter* filter) { BAutolock _(this); - if (fKeyFilter == filter) + if (fKeyboardFilter == filter) return; - delete fKeyFilter; - fKeyFilter = filter; + delete fKeyboardFilter; + fKeyboardFilter = filter; } @@ -501,8 +501,8 @@ EventDispatcher::_EventLoop() case B_UNMAPPED_KEY_DOWN: case B_UNMAPPED_KEY_UP: case B_MODIFIERS_CHANGED: - if (fKeyFilter != NULL - && fKeyFilter->Filter(event, NULL) == B_SKIP_MESSAGE) + if (fKeyboardFilter != NULL + && fKeyboardFilter->Filter(event, NULL) == B_SKIP_MESSAGE) break; keyboardEvent = true; diff --git a/src/servers/app/EventDispatcher.h b/src/servers/app/EventDispatcher.h index 7b6677008d..d5a1b070b6 100644 --- a/src/servers/app/EventDispatcher.h +++ b/src/servers/app/EventDispatcher.h @@ -36,7 +36,7 @@ class EventDispatcher : public BLocker { void RemoveListener(BMessenger& messenger, int32 token); void SetMouseFilter(BMessageFilter* filter); - void SetKeyFilter(BMessageFilter* filter); + void SetKeyboardFilter(BMessageFilter* filter); bool HasCursorThread(); void SetHWInterface(HWInterface* interface); @@ -81,7 +81,7 @@ class EventDispatcher : public BLocker { bool fSuspendFocus; BMessageFilter* fMouseFilter; - BMessageFilter* fKeyFilter; + BMessageFilter* fKeyboardFilter; BObjectList fListeners; diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 26282b82ac..510b252e9d 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -806,45 +806,6 @@ Layer::MouseWheelChanged(const BMessage *msg) } } -void -Layer::KeyDown(const BMessage *msg) -{ - if (Window() && !IsTopLayer()) { - Window()->SendMessageToClient(msg, B_NULL_TOKEN, true); - } -} - -void -Layer::KeyUp(const BMessage *msg) -{ - if (Window() && !IsTopLayer()) { - Window()->SendMessageToClient(msg, B_NULL_TOKEN, true); - } -} - -void -Layer::UnmappedKeyDown(const BMessage *msg) -{ - if (Window() && !IsTopLayer()) { - Window()->SendMessageToClient(msg, B_NULL_TOKEN, true); - } -} - -void -Layer::UnmappedKeyUp(const BMessage *msg) -{ - if (Window() && !IsTopLayer()) { - Window()->SendMessageToClient(msg, B_NULL_TOKEN, true); - } -} - -void -Layer::ModifiersChanged(const BMessage *msg) -{ - if (Window() && !IsTopLayer()) { - Window()->SendMessageToClient(msg, B_NULL_TOKEN, true); - } -} void Layer::WorkspaceActivated(int32 index, bool active) diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index a193136343..5c975f2648 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -146,12 +146,6 @@ class Layer { virtual void MouseMoved(const BMessage *msg); virtual void MouseWheelChanged(const BMessage *msg); - virtual void KeyDown(const BMessage *msg); - virtual void KeyUp(const BMessage *msg); - virtual void UnmappedKeyDown(const BMessage *msg); - virtual void UnmappedKeyUp(const BMessage *msg); - virtual void ModifiersChanged(const BMessage *msg); - virtual void WorkspaceActivated(int32 index, bool active); virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces); virtual void Activated(bool active); diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index ae1ab30e14..d3e703d820 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +//#include #include #include @@ -1056,134 +1056,6 @@ RootLayer::MouseEventHandler(BMessage *msg) } -void -RootLayer::KeyboardEventHandler(BMessage *msg) -{ - switch (msg->what) { - case B_KEY_DOWN: - { - int32 scancode = 0; - int32 modifiers = 0; - - msg->FindInt32("key", &scancode); - msg->FindInt32("modifiers", &modifiers); - - // F1-F12 - if (scancode > 0x01 && scancode < 0x0e) { - // Check for workspace change or safe video mode - if (scancode == 0x0d && (modifiers & (B_LEFT_COMMAND_KEY - | B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY)) != 0) - { - // TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN. (DrawingEngine API change) - STRACE(("Safe Video Mode invoked - code unimplemented\n")); - break; - } - -#if !TEST_MODE - if (modifiers & B_COMMAND_KEY) -#else - if (modifiers & B_CONTROL_KEY) -#endif - { - STRACE(("Set Workspace %ld\n",scancode-1)); - SetActiveWorkspace(scancode - 2); - #ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER - // to draw the current Workspace index on screen. - BRegion reg(VisibleRegion()); - fDriver->ConstrainClippingRegion(®); - Draw(reg.Frame()); - fDriver->ConstrainClippingRegion(NULL); - #endif - break; - } - } - - // Tab key - if (scancode == 0x26 && (modifiers & B_CONTROL_KEY)) { - STRACE(("Twitcher\n")); - //ServerApp *deskbar = app_server->FindApp("application/x-vnd.Be-TSKB"); - //if(deskbar) - //{ - // TODO: implement; - printf("Send Twitcher message key to Deskbar - unimplmemented\n"); - break; - //} - } - - // PrintScreen - if (scancode == 0xe) { - if (GetDrawingEngine()) { - char filename[128]; - BEntry entry; - - int32 index = 1; - do { - sprintf(filename, "/boot/home/screen%ld.png", index++); - entry.SetTo(filename); - } while(entry.Exists()); - - GetDrawingEngine()->DumpToFile(filename); - - break; - } - } - - // We got this far, so apparently it's safe to pass to the active - // window. - - if (Focus()) - Focus()->KeyDown(msg); - - break; - } - - case B_KEY_UP: - { - int32 scancode = 0; - int32 modifiers = 0; - - msg->FindInt32("key", &scancode); - msg->FindInt32("modifiers", &modifiers); - - // Tab key - if (scancode == 0x26 && (modifiers & B_CONTROL_KEY)) { - //ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB"); - //if(deskbar) - //{ - printf("Send Twitcher message key to Deskbar - unimplmemented\n"); - break; - //} - } - - // We got this far, so apparently it's safe to pass to the active - // window. - - if (Focus()) - Focus()->KeyUp(msg); - break; - } - - case B_UNMAPPED_KEY_DOWN: - if (Focus()) - Focus()->UnmappedKeyDown(msg); - break; - - case B_UNMAPPED_KEY_UP: - if (Focus()) - Focus()->UnmappedKeyUp(msg); - break; - - case B_MODIFIERS_CHANGED: - if (Focus()) - Focus()->ModifiersChanged(msg); - break; - - default: - break; - } -} - - bool RootLayer::AddToInputNotificationLists(Layer *lay, uint32 mask, uint32 options) { diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index ad391a73c8..d9e07a34c3 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -123,10 +123,6 @@ public: thread_id LockingThread() { return fAllRegionsLock.LockingThread(); } -// BRegion fRedrawReg; -// BList fCopyRegList; -// BList fCopyList; - private: friend class Desktop; @@ -143,8 +139,6 @@ friend class Desktop; // Input related methods void MouseEventHandler(BMessage *msg); - void KeyboardEventHandler(BMessage *msg); - void _ProcessMouseMovedEvent(BMessage *msg); Desktop* fDesktop; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index c8b7517366..6607be6c86 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -847,7 +847,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: get current workspace\n", Signature())); // TODO: Locking this way is not nice - RootLayer *root = fDesktop->ActiveRootLayer(); + RootLayer *root = fDesktop->RootLayer(); root->Lock(); fLink.StartMessage(SERVER_TRUE); @@ -865,7 +865,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) // TODO: See above int32 index; link.Read(&index); - RootLayer *root = fDesktop->ActiveRootLayer(); + RootLayer *root = fDesktop->RootLayer(); root->Lock(); root->SetActiveWorkspace(index); root->Unlock(); @@ -2098,9 +2098,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) bool makedefault = false; link.Read(&makedefault); -// TODO: lock RootLayer, set mode and tell it to update it's frame and all clipping -// optionally put this into a message and let the root layer thread handle it. - RootLayer* rootLayer = fDesktop->ActiveRootLayer(); + RootLayer* rootLayer = fDesktop->RootLayer(); rootLayer->Lock(); status_t status = fDesktop->ScreenAt(0)->SetMode(mode); if (status == B_OK) { @@ -2189,7 +2187,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) // ToDo: locking is probably wrong - why the hell is there no (safe) // way to get to the workspace object directly? - RootLayer *root = fDesktop->ActiveRootLayer(); + RootLayer *root = fDesktop->RootLayer(); root->Lock(); Workspace *workspace; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 97210df8bc..f05c440681 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1587,7 +1587,7 @@ if (myRootLayer) // 2) int32 button state fLink.Attach(fDesktop->HWInterface()->GetCursorPosition()); - fLink.Attach(fDesktop->ActiveRootLayer()->Buttons()); + fLink.Attach(fDesktop->RootLayer()->Buttons()); fLink.Flush(); break;