diff --git a/src/servers/input/AddOnManager.cpp b/src/servers/input/AddOnManager.cpp index 1d3d411100..58717195fc 100644 --- a/src/servers/input/AddOnManager.cpp +++ b/src/servers/input/AddOnManager.cpp @@ -83,20 +83,20 @@ AddOnManager::RegisterAddOn(BEntry &entry) if (get_image_symbol(addon_image, "instantiate_input_device", B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) { - PRINT(("AddOnManager::RegisterAddOn(): can't find instantiate_input_device in \"%s\"\n", + PRINTERR(("AddOnManager::RegisterAddOn(): can't find instantiate_input_device in \"%s\"\n", path.Path())); goto exit_error; } BInputServerDevice *isd = (*instantiate_func)(); if (isd == NULL) { - PRINT(("AddOnManager::RegisterAddOn(): instantiate_input_device in \"%s\" returned NULL\n", + PRINTERR(("AddOnManager::RegisterAddOn(): instantiate_input_device in \"%s\" returned NULL\n", path.Path())); goto exit_error; } status_t status = isd->InitCheck(); if (status != B_OK) { - PRINT(("AddOnManager::RegisterAddOn(): BInputServerDevice.InitCheck in \"%s\" returned %s\n", + PRINTERR(("AddOnManager::RegisterAddOn(): BInputServerDevice.InitCheck in \"%s\" returned %s\n", path.Path(), strerror(status))); delete isd; goto exit_error; @@ -110,20 +110,20 @@ AddOnManager::RegisterAddOn(BEntry &entry) if (get_image_symbol(addon_image, "instantiate_input_filter", B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) { - PRINT(("AddOnManager::RegisterAddOn(): can't find instantiate_input_filter in \"%s\"\n", + PRINTERR(("AddOnManager::RegisterAddOn(): can't find instantiate_input_filter in \"%s\"\n", path.Path())); goto exit_error; } BInputServerFilter *isf = (*instantiate_func)(); if (isf == NULL) { - PRINT(("AddOnManager::RegisterAddOn(): instantiate_input_filter in \"%s\" returned NULL\n", + PRINTERR(("AddOnManager::RegisterAddOn(): instantiate_input_filter in \"%s\" returned NULL\n", path.Path())); goto exit_error; } status_t status = isf->InitCheck(); if (status != B_OK) { - PRINT(("AddOnManager::RegisterAddOn(): BInputServerFilter.InitCheck in \"%s\" returned %s\n", + PRINTERR(("AddOnManager::RegisterAddOn(): BInputServerFilter.InitCheck in \"%s\" returned %s\n", path.Path(), strerror(status))); delete isf; goto exit_error; @@ -136,21 +136,21 @@ AddOnManager::RegisterAddOn(BEntry &entry) if (get_image_symbol(addon_image, "instantiate_input_method", B_SYMBOL_TYPE_TEXT, (void **)&instantiate_func) < B_OK) { - PRINT(("AddOnManager::RegisterAddOn(): can't find instantiate_input_method in \"%s\"\n", + PRINTERR(("AddOnManager::RegisterAddOn(): can't find instantiate_input_method in \"%s\"\n", path.Path())); goto exit_error; } BInputServerMethod *ism = (*instantiate_func)(); if (ism == NULL) { - PRINT(("AddOnManager::RegisterAddOn(): instantiate_input_method in \"%s\" returned NULL\n", + PRINTERR(("AddOnManager::RegisterAddOn(): instantiate_input_method in \"%s\" returned NULL\n", path.Path())); goto exit_error; } status_t status = ism->InitCheck(); if (status != B_OK) { - printf("AddOnManager::RegisterAddOn(): BInputServerMethod.InitCheck in \"%s\" returned %s\n", - path.Path(), strerror(status)); + PRINTERR(("AddOnManager::RegisterAddOn(): BInputServerMethod.InitCheck in \"%s\" returned %s\n", + path.Path(), strerror(status))); delete ism; goto exit_error; } @@ -225,6 +225,11 @@ AddOnManager::UnregisterAddOn(BEntry &entry) // we remove the method replicant BDeskbar().RemoveItem(REPLICANT_CTL_NAME); ((InputServer*)be_app)->SetMethodReplicant(NULL); + } else { + BMessage msg(IS_REMOVE_METHOD); + msg.AddInt32("cookie", (uint32)pinfo->ism); + if (((InputServer*)be_app)->MethodReplicant()) + ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); } } @@ -463,6 +468,16 @@ AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref, i } } } + + if (((InputServer*)be_app)->MethodReplicant()) { + _BMethodAddOn_ *addon = InputServer::gKeymapMethod.fOwner; + addon->AddMethod(); + } + } + + if (((InputServer*)be_app)->MethodReplicant()) { + _BMethodAddOn_ *addon = method->fOwner; + addon->AddMethod(); } } diff --git a/src/servers/input/InputServer.cpp b/src/servers/input/InputServer.cpp index a0e389a0fa..759079846b 100644 --- a/src/servers/input/InputServer.cpp +++ b/src/servers/input/InputServer.cpp @@ -76,6 +76,8 @@ BLocker InputServer::gInputMethodListLocker("is_method_queue_sem"); DeviceManager InputServer::gDeviceManager; +KeymapMethod InputServer::gKeymapMethod; + #if DEBUG == 2 FILE *InputServer::sLogFile = NULL; #endif @@ -168,8 +170,6 @@ InputServer::InputServer(void) : BApplication(INPUTSERVER_SIGNATURE), fAddOnManager = new AddOnManager(SafeMode()); fAddOnManager->LoadState(); - //BDeskbar().AddItem(new ::MethodReplicant); - BMessenger messenger(this); BRoster().StartWatching(messenger, B_REQUEST_LAUNCHED); } @@ -237,6 +237,8 @@ InputServer::InitKeyboardMouseStates(void) BMessage *msg = new BMessage(B_MOUSE_MOVED); HandleSetMousePosition(msg, msg); + + fActiveMethod = &gKeymapMethod; } @@ -506,10 +508,12 @@ InputServer::MessageReceived(BMessage *message) void InputServer::HandleSetMethod(BMessage *message) { - int32 cookie; - if (message->FindInt32("cookie", &cookie) == B_OK) { - _BMethodAddOn_ *addon = (_BMethodAddOn_*)cookie; - SetActiveMethod(addon); + CALLED(); + uint32 cookie; + if (message->FindInt32("cookie", (int32*)&cookie) == B_OK) { + BInputServerMethod *method = (BInputServerMethod*)cookie; + PRINT(("%s cookie %p\n", __PRETTY_FUNCTION__, method)); + SetActiveMethod(method); } } @@ -928,13 +932,13 @@ InputServer::EnqueueMethodMessage(BMessage *message) { CALLED(); - status_t err; - - ssize_t length = message->FlattenedSize(); - char buffer[length]; - if ((err = message->Flatten(buffer,length)) < B_OK) - return err; - return write_port(fEventLooperPort, 0, buffer, length); + LockMethodQueue(); + + fMethodQueue.AddItem(message); + + UnlockMethodQueue(); + + return B_OK; } @@ -981,14 +985,16 @@ InputServer::SetNextMethod(bool) * Descr: */ void -InputServer::SetActiveMethod(_BMethodAddOn_ *addon) +InputServer::SetActiveMethod(BInputServerMethod *method) { + CALLED(); if (fActiveMethod) - fActiveMethod->MethodActivated(false); - fActiveMethod = addon; + fActiveMethod->fOwner->MethodActivated(false); + fActiveMethod = method; - if (fActiveMethod) - fActiveMethod->MethodActivated(true); + if (fActiveMethod) { + fActiveMethod->fOwner->MethodActivated(true); + } } @@ -1292,6 +1298,8 @@ bool InputServer::CacheEvents(BList *eventsToCache) { CALLED(); + + MethodizeEvents(eventsToCache, true); FilterEvents(eventsToCache); @@ -1403,11 +1411,37 @@ InputServer::SanitizeEvents(BList *) * Descr: */ bool -InputServer::MethodizeEvents(BList *, +InputServer::MethodizeEvents(BList *events, bool) { CALLED(); + if (fActiveMethod) { + + BList newList; + for (int32 i=0; iCountItems(); i++) { + BMessage *item = (BMessage *)events->ItemAt(i); + BList filterList; + filter_result res = fActiveMethod->Filter(item, &filterList); + switch (res) { + case B_SKIP_MESSAGE: + delete item; + case B_DISPATCH_MESSAGE: + if (filterList.CountItems()>0) { + newList.AddList(&filterList); + delete item; + } else + newList.AddItem(item); + } + + newList.AddList(&fMethodQueue); + fMethodQueue.MakeEmpty(); + } + + events->MakeEmpty(); + events->AddList(&newList); + } + return true; } diff --git a/src/servers/input/InputServer.h b/src/servers/input/InputServer.h index 1647ba62d6..02525dd45e 100644 --- a/src/servers/input/InputServer.h +++ b/src/servers/input/InputServer.h @@ -87,6 +87,7 @@ class _BMethodAddOn_ status_t SetIcon(const uchar *icon); status_t SetMenu(const BMenu *menu, const BMessenger &messenger); status_t MethodActivated(bool activate); + status_t AddMethod(); private: BInputServerMethod *fMethod; char *fName; @@ -95,6 +96,15 @@ class _BMethodAddOn_ BMessenger fMessenger; }; + +class KeymapMethod : public BInputServerMethod +{ +public: + KeymapMethod(); + ~KeymapMethod(); +}; + + /*****************************************************************************/ // InputServer // @@ -114,7 +124,6 @@ public: virtual bool QuitRequested(void); virtual void ReadyToRun(void); - //thread_id Run(void); virtual void MessageReceived(BMessage*); void HandleSetMethod(BMessage*); @@ -139,7 +148,7 @@ public: status_t UnlockMethodQueue(void); status_t LockMethodQueue(void); status_t SetNextMethod(bool); - void SetActiveMethod(_BMethodAddOn_*); + void SetActiveMethod(BInputServerMethod*); const BMessenger* MethodReplicant(void); void SetMethodReplicant(const BMessenger *); status_t EventLoop(); @@ -175,6 +184,8 @@ public: static DeviceManager gDeviceManager; + static KeymapMethod gKeymapMethod; + BRect& ScreenFrame() { return fFrame;}; private: status_t LoadKeymap(); @@ -210,7 +221,8 @@ private: BScreen fScreen; BRect fFrame; - _BMethodAddOn_ *fActiveMethod; + BInputServerMethod *fActiveMethod; + BList fMethodQueue; const BMessenger *fReplicantMessenger; #ifndef COMPILE_FOR_R5 diff --git a/src/servers/input/InputServerMethod.cpp b/src/servers/input/InputServerMethod.cpp index e15ceeb634..a91f5ed70e 100644 --- a/src/servers/input/InputServerMethod.cpp +++ b/src/servers/input/InputServerMethod.cpp @@ -33,7 +33,7 @@ #include #include "InputServer.h" #include "InputServerTypes.h" - +#include "remote_icon.h" /** * Method: BInputServerMethod::BInputServerMethod() * Descr: @@ -173,52 +173,100 @@ _BMethodAddOn_::~_BMethodAddOn_() status_t _BMethodAddOn_::SetName(const char* name) { + CALLED(); if (fName) free(fName); if (name) fName = strdup(name); BMessage msg(IS_UPDATE_NAME); - msg.AddInt32("cookie", (uint32)this); + msg.AddInt32("cookie", (uint32)fMethod); msg.AddString("name", name); - return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + if (((InputServer*)be_app)->MethodReplicant()) + return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + else + return B_ERROR; } status_t _BMethodAddOn_::SetIcon(const uchar* icon) -{ +{ + CALLED(); memcpy(fIcon, icon, 16*16*1); BMessage msg(IS_UPDATE_ICON); - msg.AddInt32("cookie", (uint32)this); + msg.AddInt32("cookie", (uint32)fMethod); msg.AddData("icon", B_RAW_TYPE, icon, 16*16*1); - return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + if (((InputServer*)be_app)->MethodReplicant()) + return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + else + return B_ERROR; } status_t _BMethodAddOn_::SetMenu(const BMenu *menu, const BMessenger &messenger) { - if (fMenu) - delete fMenu; + CALLED(); fMenu = menu; fMessenger = messenger; - + BMessage msg(IS_UPDATE_MENU); - msg.AddInt32("cookie", (uint32)this); + msg.AddInt32("cookie", (uint32)fMethod); BMessage menuMsg; - menu->Archive(&menuMsg); + if (menu) + menu->Archive(&menuMsg); msg.AddMessage("menu", &menuMsg); msg.AddMessenger("target", messenger); - return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + if (((InputServer*)be_app)->MethodReplicant()) + return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + else + return B_ERROR; } status_t _BMethodAddOn_::MethodActivated(bool activate) { - if (fMethod) + CALLED(); + if (fMethod) { + PRINT(("%s cookie %p\n", __PRETTY_FUNCTION__, fMethod)); + if (activate && ((InputServer*)be_app)->MethodReplicant()) { + BMessage msg(IS_UPDATE_METHOD); + msg.AddInt32("cookie", (uint32)fMethod); + ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + } return fMethod->MethodActivated(activate); + } return B_ERROR; } + + +status_t +_BMethodAddOn_::AddMethod() +{ + PRINT(("%s cookie %p\n", __PRETTY_FUNCTION__, fMethod)); + BMessage msg(IS_ADD_METHOD); + msg.AddInt32("cookie", (uint32)fMethod); + msg.AddString("name", fName); + msg.AddData("icon", B_RAW_TYPE, fIcon, 16*16*1); + if (((InputServer*)be_app)->MethodReplicant()) + return ((InputServer*)be_app)->MethodReplicant()->SendMessage(&msg); + else + return B_ERROR; +} + + +KeymapMethod::KeymapMethod() + : BInputServerMethod("Roman", kRemoteBits) +{ + +} + + +KeymapMethod::~KeymapMethod() +{ + +} + diff --git a/src/servers/input/MethodReplicant.cpp b/src/servers/input/MethodReplicant.cpp index 0e41dfe232..53a1a006ad 100644 --- a/src/servers/input/MethodReplicant.cpp +++ b/src/servers/input/MethodReplicant.cpp @@ -148,6 +148,12 @@ MethodReplicant::MessageReceived(BMessage *message) case IS_UPDATE_METHOD: UpdateMethod(message); break; + case IS_ADD_METHOD: + AddMethod(message); + break; + case IS_REMOVE_METHOD: + RemoveMethod(message); + break; default: BView::MessageReceived(message); @@ -176,14 +182,6 @@ MethodReplicant::MouseDown(BPoint point) where = ConvertToScreen(point); - BMenuItem *tmpItem; - fMenu.AddItem(tmpItem = new MethodMenuItem(0, "Roman", kRemoteBits)); - BMenu *otherMenu = new BMenu("Help"); - otherMenu->AddItem(new BMenuItem("Help", NULL)); - BMessenger messenger; - fMenu.AddItem(new MethodMenuItem(0x80029138, "Roman Roman", kRemoteBits, otherMenu, messenger)); - tmpItem->SetMarked(true); - fMenu.SetTargetForItems(this); MethodMenuItem *item = (MethodMenuItem*)fMenu.Go(where, true, true, BRect(where - BPoint(4, 4), where + BPoint(4, 4))); @@ -219,6 +217,9 @@ MethodReplicant::UpdateMethod(BMessage *message) return; } item->SetMarked(true); + + fSegments->SetBits(item->Icon(), kRemoteWidth*kRemoteHeight, 0, kRemoteColorSpace); + Invalidate(); } @@ -227,23 +228,23 @@ MethodReplicant::UpdateMethodIcon(BMessage *message) { CALLED(); int32 cookie; - if (message->FindInt32("cookie", &cookie)!=B_OK) { - fprintf(stderr, "can't find cookie in message\n"); - return; - } + if (message->FindInt32("cookie", &cookie)!=B_OK) { + fprintf(stderr, "can't find cookie in message\n"); + return; + } const uchar *data; ssize_t numBytes; if (message->FindData("icon", B_ANY_TYPE, (const void**)&data, &numBytes)!=B_OK) { fprintf(stderr, "can't find icon in message\n"); - return; - } + return; + } MethodMenuItem *item = FindItemByCookie(cookie); - if (item == NULL) { - fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie); - return; - } + if (item == NULL) { + fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie); + return; + } item->SetIcon(data); } @@ -274,10 +275,9 @@ MethodReplicant::UpdateMethodMenu(BMessage *message) BMenu *menu = (BMenu *)BMenu::Instantiate(&msg); if (menu == NULL) { - fprintf(stderr, "can't instantiate menu\n"); - return; - } - menu->SetTargetForItems(messenger); + PRINT(("can't instantiate menu\n")); + } else + menu->SetTargetForItems(messenger); MethodMenuItem *item = FindItemByCookie(cookie); if (item == NULL) { @@ -286,10 +286,16 @@ MethodReplicant::UpdateMethodMenu(BMessage *message) } int32 index = fMenu.IndexOf(item); - MethodMenuItem *item2 = new MethodMenuItem(cookie, item->Label(), item->Icon(), - menu, messenger); - fMenu.RemoveItem(index); + MethodMenuItem *item2 = NULL; + if (menu) + item2 = new MethodMenuItem(cookie, item->Label(), item->Icon(), + menu, messenger); + else + item2 = new MethodMenuItem(cookie, item->Label(), item->Icon()); + item = (MethodMenuItem*)fMenu.RemoveItem(index); fMenu.AddItem(item2, index); + item2->SetMarked(item->IsMarked()); + delete item; } @@ -298,22 +304,22 @@ MethodReplicant::UpdateMethodName(BMessage *message) { CALLED(); int32 cookie; - if (message->FindInt32("cookie", &cookie)!=B_OK) { - fprintf(stderr, "can't find cookie in message\n"); - return; - } + if (message->FindInt32("cookie", &cookie)!=B_OK) { + fprintf(stderr, "can't find cookie in message\n"); + return; + } const char *name; if (message->FindString("name", &name)!=B_OK) { - fprintf(stderr, "can't find name in message\n"); - return; - } + fprintf(stderr, "can't find name in message\n"); + return; + } MethodMenuItem *item = FindItemByCookie(cookie); - if (item == NULL) { - fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie); - return; - } + if (item == NULL) { + fprintf(stderr, "can't find item with cookie 0x%lx\n", cookie); + return; + } item->SetName(name); } @@ -332,3 +338,60 @@ MethodReplicant::FindItemByCookie(int32 cookie) return NULL; } + +void +MethodReplicant::AddMethod(BMessage *message) +{ + CALLED(); + int32 cookie; + if (message->FindInt32("cookie", &cookie)!=B_OK) { + fprintf(stderr, "can't find cookie in message\n"); + return; + } + + const char *name; + if (message->FindString("name", &name)!=B_OK) { + fprintf(stderr, "can't find name in message\n"); + return; + } + + const uchar *icon; + ssize_t numBytes; + if (message->FindData("icon", B_ANY_TYPE, (const void**)&icon, &numBytes)!=B_OK) { + fprintf(stderr, "can't find icon in message\n"); + return; + } + + MethodMenuItem *item = FindItemByCookie(cookie); + if (item != NULL) { + fprintf(stderr, "item with cookie %lx already exists\n", cookie); + return; + } + + item = new MethodMenuItem(cookie, name, icon); + fMenu.AddItem(item); + item->SetTarget(this); + + if (fMenu.CountItems() == 1) + item->SetMarked(true); +} + + +void +MethodReplicant::RemoveMethod(BMessage *message) +{ + CALLED(); + int32 cookie; + if (message->FindInt32("cookie", &cookie)!=B_OK) { + fprintf(stderr, "can't find cookie in message\n"); + return; + } + + MethodMenuItem *item = FindItemByCookie(cookie); + if (item == NULL) { + fprintf(stderr, "can't find item with cookie %lx\n", cookie); + return; + } + fMenu.RemoveItem(item); + delete item; +} diff --git a/src/servers/input/MethodReplicant.h b/src/servers/input/MethodReplicant.h index 8e7f90d47c..a74b1fd0cf 100644 --- a/src/servers/input/MethodReplicant.h +++ b/src/servers/input/MethodReplicant.h @@ -55,6 +55,8 @@ private: void UpdateMethodIcon(BMessage *); void UpdateMethodMenu(BMessage *); void UpdateMethodName(BMessage *); + void AddMethod(BMessage *message); + void RemoveMethod(BMessage *message); MethodMenuItem *FindItemByCookie(int32 cookie); };