From 9514d2e5e6d5f285d06e3628b0062ea945ee6d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 15 Nov 2005 15:35:36 +0000 Subject: [PATCH] * introduced a global gInputServer object, so that you don't need to cast the be_app object anymore. * fixed some missing locks for the input device list. * moved the input device list into the InputServer object - didn't make a lot of sense the way it was done before. Also moved registering/unregistering into the InputerServer class. * Made the InputDeviceListItem class a bit more useful and encapsulated. * cleanup, removed empty function documentation stubs. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14946 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/input/AddOnManager.cpp | 330 +++--- src/servers/input/AddOnManager.h | 19 +- src/servers/input/InputServer.cpp | 1317 +++++++++++------------ src/servers/input/InputServer.h | 406 ++++--- src/servers/input/InputServerDevice.cpp | 307 ++---- 5 files changed, 1043 insertions(+), 1336 deletions(-) diff --git a/src/servers/input/AddOnManager.cpp b/src/servers/input/AddOnManager.cpp index 35d06d141c..6a8b39c68d 100644 --- a/src/servers/input/AddOnManager.cpp +++ b/src/servers/input/AddOnManager.cpp @@ -1,10 +1,11 @@ /* -** Copyright 2004, the Haiku project. All rights reserved. -** Distributed under the terms of the Haiku License. -** -** Author : Jérôme Duval -** Original authors: Marcus Overhagen, Axel Dörfler -*/ + * Copyright 2004-2005, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marcus Overhagen, Axel Dörfler + * Jérôme Duval + */ #include @@ -25,6 +26,54 @@ #include "InputServerTypes.h" #include "MethodReplicant.h" + +class AddOnManager::InputServerMonitorHandler : public AddOnMonitorHandler { + public: + InputServerMonitorHandler(AddOnManager* manager) + { + fManager = manager; + } + + virtual void + AddOnCreated(const add_on_entry_info * entry_info) + { + } + + virtual void + AddOnEnabled(const add_on_entry_info * entry_info) + { + CALLED(); + entry_ref ref; + make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node, + entry_info->name, &ref); + BEntry entry(&ref, false); + fManager->RegisterAddOn(entry); + } + + virtual void + AddOnDisabled(const add_on_entry_info * entry_info) + { + CALLED(); + entry_ref ref; + make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node, + entry_info->name, &ref); + BEntry entry(&ref, false); + fManager->UnregisterAddOn(entry); + } + + virtual void + AddOnRemoved(const add_on_entry_info * entry_info) + { + } + + private: + AddOnManager* fManager; +}; + + +// #pragma mark - + + AddOnManager::AddOnManager(bool safeMode) : BLooper("addon_manager"), fLock("add-on manager"), @@ -100,8 +149,6 @@ AddOnManager::RegisterAddOn(BEntry &entry) } RegisterDevice(isd, ref, addon_image); - - } else if (pathString.FindFirst("input_server/filters")>0) { BInputServerFilter *(*instantiate_func)(); @@ -127,7 +174,6 @@ AddOnManager::RegisterAddOn(BEntry &entry) } RegisterFilter(isf, ref, addon_image); - } else if (pathString.FindFirst("input_server/methods")>0) { BInputServerMethod *(*instantiate_func)(); @@ -153,16 +199,15 @@ AddOnManager::RegisterAddOn(BEntry &entry) } RegisterMethod(ism, ref, addon_image); - } else { PRINTERR(("AddOnManager::RegisterAddOn(): addon type not found for \"%s\" \n", path.Path())); goto exit_error; } return B_OK; + exit_error: unload_add_on(addon_image); - return status; } @@ -183,14 +228,14 @@ AddOnManager::UnregisterAddOn(BEntry &entry) entry.GetParent(&parent); BPath parentPath(&parent); BString pathString = parentPath.Path(); - + BAutolock locker(fLock); - + if (pathString.FindFirst("input_server/devices")>0) { device_info *pinfo; for (fDeviceList.Rewind(); fDeviceList.GetNext(&pinfo);) { if (!strcmp(pinfo->ref.name, ref.name)) { - InputServer::StartStopDevices(pinfo->isd, false); + gInputServer->StartStopDevices(*pinfo->isd, false); delete pinfo->isd; if (pinfo->addon_image >= B_OK) unload_add_on(pinfo->addon_image); @@ -224,63 +269,35 @@ AddOnManager::UnregisterAddOn(BEntry &entry) if (fMethodList.CountItems()<=0) { // we remove the method replicant BDeskbar().RemoveItem(REPLICANT_CTL_NAME); - ((InputServer*)be_app)->SetMethodReplicant(NULL); + gInputServer->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); + if (gInputServer->MethodReplicant()) + gInputServer->MethodReplicant()->SendMessage(&msg); } } return B_OK; } + void AddOnManager::RegisterAddOns() { CALLED(); status_t err; - class IAHandler : public AddOnMonitorHandler { - private: - AddOnManager * fManager; - public: - IAHandler(AddOnManager * manager) { - fManager = manager; - } - virtual void AddOnCreated(const add_on_entry_info * entry_info) { - } - virtual void AddOnEnabled(const add_on_entry_info * entry_info) { - CALLED(); - entry_ref ref; - make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node, - entry_info->name, &ref); - BEntry entry(&ref, false); - fManager->RegisterAddOn(entry); - } - virtual void AddOnDisabled(const add_on_entry_info * entry_info) { - CALLED(); - entry_ref ref; - make_entry_ref(entry_info->dir_nref.device, entry_info->dir_nref.node, - entry_info->name, &ref); - BEntry entry(&ref, false); - fManager->UnregisterAddOn(entry); - } - virtual void AddOnRemoved(const add_on_entry_info * entry_info) { - } - }; - - fHandler = new IAHandler(this); + fHandler = new InputServerMonitorHandler(this); fAddOnMonitor = new AddOnMonitor(fHandler); #ifndef APPSERVER_TEST_MODE err = fAddOnMonitor->InitCheck(); - if (err != B_OK) { - PRINTERR(("AddOnManager::RegisterAddOns(): fAddOnMonitor->InitCheck() returned %s\n", - strerror(err))); - return; - } + if (err != B_OK) { + PRINTERR(("AddOnManager::RegisterAddOns(): fAddOnMonitor->InitCheck() returned %s\n", + strerror(err))); + return; + } const directory_which directories[] = { B_USER_ADDONS_DIRECTORY, @@ -310,7 +327,6 @@ AddOnManager::RegisterAddOns() BEntry entry("/boot/home/svnhaiku/trunk/tests/servers/input/view_input_device/input_server/devices/ViewInputDevice"); RegisterAddOn(entry); #endif - } @@ -330,7 +346,7 @@ AddOnManager::UnregisterAddOns() { device_info *pinfo; for (fDeviceList.Rewind(); fDeviceList.GetNext(&pinfo);) { - InputServer::StartStopDevices(pinfo->isd, false); + gInputServer->StartStopDevices(*pinfo->isd, false); delete pinfo->isd; if (pinfo->addon_image >= B_OK) unload_add_on(pinfo->addon_image); @@ -361,7 +377,8 @@ AddOnManager::UnregisterAddOns() void -AddOnManager::RegisterDevice(BInputServerDevice *device, const entry_ref &ref, image_id addon_image) +AddOnManager::RegisterDevice(BInputServerDevice* device, const entry_ref& ref, + image_id addonImage) { BAutolock locker(fLock); @@ -377,15 +394,16 @@ AddOnManager::RegisterDevice(BInputServerDevice *device, const entry_ref &ref, i device_info info; info.ref = ref; - info.addon_image = addon_image; + info.addon_image = addonImage; info.isd = device; - + fDeviceList.Insert(info); } void -AddOnManager::RegisterFilter(BInputServerFilter *filter, const entry_ref &ref, image_id addon_image) +AddOnManager::RegisterFilter(BInputServerFilter* filter, const entry_ref& ref, + image_id addonImage) { BAutolock locker(fLock); @@ -401,7 +419,7 @@ AddOnManager::RegisterFilter(BInputServerFilter *filter, const entry_ref &ref, i filter_info info; info.ref = ref; - info.addon_image = addon_image; + info.addon_image = addonImage; info.isf = filter; fFilterList.Insert(info); @@ -413,7 +431,8 @@ AddOnManager::RegisterFilter(BInputServerFilter *filter, const entry_ref &ref, i void -AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref, image_id addon_image) +AddOnManager::RegisterMethod(BInputServerMethod* method, const entry_ref& ref, + image_id addonImage) { BAutolock locker(fLock); @@ -429,25 +448,24 @@ AddOnManager::RegisterMethod(BInputServerMethod *method, const entry_ref &ref, i method_info info; info.ref = ref; - info.addon_image = addon_image; + info.addon_image = addonImage; info.ism = method; - + fMethodList.Insert(info); - + BAutolock lock2(InputServer::gInputMethodListLocker); - InputServer::gInputMethodList.AddItem(method); - - if (((InputServer*)be_app)->MethodReplicant() == NULL) { + + if (gInputServer->MethodReplicant() == NULL) { LoadReplicant(); - if (((InputServer*)be_app)->MethodReplicant()) { + if (gInputServer->MethodReplicant()) { _BMethodAddOn_ *addon = InputServer::gKeymapMethod.fOwner; addon->AddMethod(); } } - if (((InputServer*)be_app)->MethodReplicant()) { + if (gInputServer->MethodReplicant()) { _BMethodAddOn_ *addon = method->fOwner; addon->AddMethod(); } @@ -459,12 +477,12 @@ AddOnManager::LoadReplicant() { CALLED(); app_info info; - be_app->GetAppInfo(&info); + be_app->GetAppInfo(&info); - status_t err = BDeskbar().AddItem(&info.ref); - if (err!=B_OK) { - PRINTERR(("Deskbar refuses to add method replicant: %s\n", strerror(err))); - } + status_t err = BDeskbar().AddItem(&info.ref); + if (err != B_OK) { + PRINTERR(("Deskbar refuses to add method replicant: %s\n", strerror(err))); + } BMessage request(B_GET_PROPERTY); BMessenger to; BMessenger status; @@ -481,7 +499,6 @@ AddOnManager::LoadReplicant() if ((to.SendMessage(&request, &reply) == B_OK) && (reply.FindMessenger("result", &status) == B_OK)) { - // enum replicant in Status view int32 index = 0; int32 uid; @@ -497,7 +514,7 @@ AddOnManager::LoadReplicant() if (GetReplicantView(status, uid, &rep_view)==0) { BMessenger result; if (rep_view.FindMessenger("result", &result) == B_OK) { - ((InputServer*)be_app)->SetMethodReplicant(new BMessenger(result)); + gInputServer->SetMethodReplicant(new BMessenger(result)); } } } @@ -506,7 +523,6 @@ AddOnManager::LoadReplicant() } -// int32 AddOnManager::GetReplicantAt(BMessenger target, int32 index) const { @@ -514,7 +530,7 @@ AddOnManager::GetReplicantAt(BMessenger target, int32 index) const So here we want to get the Unique ID of the replicant at the given index in the target Shelf. */ - + BMessage request(B_GET_PROPERTY);// We're getting the ID property BMessage reply; status_t err; @@ -533,7 +549,6 @@ AddOnManager::GetReplicantAt(BMessenger target, int32 index) const } -// status_t AddOnManager::GetReplicantName(BMessenger target, int32 uid, BMessage *reply) const { @@ -541,7 +556,7 @@ AddOnManager::GetReplicantName(BMessenger target, int32 uid, BMessage *reply) co We send a message to the target shelf, asking it for the Name of the replicant with the given unique id. */ - + BMessage request(B_GET_PROPERTY); BMessage uid_specifier(B_ID_SPECIFIER);// specifying via ID status_t err; @@ -563,21 +578,23 @@ AddOnManager::GetReplicantName(BMessenger target, int32 uid, BMessage *reply) co return B_OK; } -// -status_t -AddOnManager::GetReplicantView(BMessenger target, int32 uid, BMessage *reply) const + +status_t +AddOnManager::GetReplicantView(BMessenger target, int32 uid, + BMessage* reply) const { /* We send a message to the target shelf, asking it for the Name of the replicant with the given unique id. */ - + BMessage request(B_GET_PROPERTY); BMessage uid_specifier(B_ID_SPECIFIER);// specifying via ID status_t err; status_t e; - request.AddSpecifier("View");// ask for the Name of the replicant + request.AddSpecifier("View"); + // ask for the Name of the replicant // IDs are specified using code like the following 3 lines: uid_specifier.AddInt32("id", uid); @@ -594,22 +611,18 @@ AddOnManager::GetReplicantView(BMessenger target, int32 uid, BMessage *reply) co } -/* - * Method: AddOnManager::MessageReceived() - * Descr: - */ void AddOnManager::MessageReceived(BMessage *message) { CALLED(); BMessage reply; - status_t status = B_OK; + status_t status; - PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what>>24, message->what>>16, message->what>>8, message->what)); - - switch(message->what) - { + PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what >> 24, + message->what >> 16, message->what >> 8, message->what)); + + switch (message->what) { case IS_FIND_DEVICES: status = HandleFindDevices(message, &reply); break; @@ -634,155 +647,112 @@ AddOnManager::MessageReceived(BMessage *message) case IS_METHOD_REGISTER: status = HandleMethodReplicant(message, &reply); break; + default: - { - return; - } + return; } - + reply.AddInt32("status", status); message->SendReply(&reply); } -/* - * Method: AddOnManager::HandleStartStopDevices() - * Descr: - */ status_t -AddOnManager::HandleStartStopDevices(BMessage *message, - BMessage *reply) +AddOnManager::HandleStartStopDevices(BMessage* message, + BMessage* reply) { const char *name = NULL; int32 type = 0; - if (! ((message->FindInt32("type", &type)!=B_OK) ^ (message->FindString("device", &name)!=B_OK))) + if (!((message->FindInt32("type", &type) != B_OK) + ^ (message->FindString("device", &name) != B_OK))) return B_ERROR; - - return InputServer::StartStopDevices(name, (input_device_type)type, message->what == IS_START_DEVICE); + + return gInputServer->StartStopDevices(name, (input_device_type)type, + message->what == IS_START_DEVICE); } -/* - * Method: AddOnManager::HandleFindDevices() - * Descr: - */ status_t -AddOnManager::HandleFindDevices(BMessage *message, - BMessage *reply) +AddOnManager::HandleFindDevices(BMessage* message, BMessage* reply) { CALLED(); const char *name = NULL; - message->FindString("device", &name); - - for (int i = InputServer::gInputDeviceList.CountItems() - 1; i >= 0; i--) { - InputDeviceListItem* item = (InputDeviceListItem*)InputServer::gInputDeviceList.ItemAt(i); - if (!item) - continue; - - if (!name || strcmp(name, item->mDev.name) == 0) { - reply->AddString("device", item->mDev.name); - reply->AddInt32("type", item->mDev.type); - if (name) - return B_OK; - } - } + input_device_type type; + if (message->FindString("device", &name) != B_OK + || gInputServer->GetDeviceInfo(name, &type) != B_OK) + return B_NAME_NOT_FOUND; + + reply->AddString("device", name); + reply->AddInt32("type", type); return B_OK; } -/* - * Method: AddOnManager::HandleWatchDevices() - * Descr: - */ status_t -AddOnManager::HandleWatchDevices(BMessage *message, - BMessage *reply) +AddOnManager::HandleWatchDevices(BMessage* message, BMessage* reply) { // TODO return B_OK; } -/* - * Method: AddOnManager::HandleIsDeviceRunning() - * Descr: - */ status_t -AddOnManager::HandleIsDeviceRunning(BMessage *message, - BMessage *reply) +AddOnManager::HandleIsDeviceRunning(BMessage* message, BMessage* reply) { - const char *name = NULL; - if (message->FindString("device", &name)!=B_OK) - return B_ERROR; - - for (int i = InputServer::gInputDeviceList.CountItems() - 1; i >= 0; i--) { - InputDeviceListItem* item = (InputDeviceListItem*)InputServer::gInputDeviceList.ItemAt(i); - if (!item) - continue; - - if (strcmp(name, item->mDev.name) == 0) - return (item->mStarted) ? B_OK : B_ERROR; - } + const char *name; + bool running; + if (message->FindString("device", &name) != B_OK + || gInputServer->GetDeviceInfo(name, NULL, &running) != B_OK) + return B_NAME_NOT_FOUND; - return B_ERROR; + return running ? B_OK : B_ERROR; } -/* - * Method: AddOnManager::HandleControlDevices() - * Descr: - */ status_t -AddOnManager::HandleControlDevices(BMessage *message, - BMessage *reply) +AddOnManager::HandleControlDevices(BMessage* message, BMessage* reply) { CALLED(); const char *name = NULL; int32 type = 0; - if (! ((message->FindInt32("type", &type)!=B_OK) ^ (message->FindString("device", &name)!=B_OK))) + if (!((message->FindInt32("type", &type) != B_OK) + ^ (message->FindString("device", &name) != B_OK))) return B_ERROR; - + uint32 code = 0; - BMessage msg; - bool isMessage = true; - if (message->FindInt32("code", (int32*)&code)!=B_OK) + BMessage controlMessage; + bool hasMessage = true; + if (message->FindInt32("code", (int32*)&code) != B_OK) return B_ERROR; - if (message->FindMessage("message", &msg)!=B_OK) - isMessage = false; - - return InputServer::ControlDevices(name, (input_device_type)type, code, isMessage ? &msg : NULL); + if (message->FindMessage("message", &controlMessage) != B_OK) + hasMessage = false; + + return gInputServer->ControlDevices(name, (input_device_type)type, + code, hasMessage ? &controlMessage : NULL); } -/* - * Method: AddOnManager::HandleSystemShuttingDown() - * Descr: - */ status_t -AddOnManager::HandleSystemShuttingDown(BMessage *message, - BMessage *reply) +AddOnManager::HandleSystemShuttingDown(BMessage* message, + BMessage* reply) { CALLED(); - + // TODO return B_OK; } -/* - * Method: AddOnManager::HandleMethodReplicant() - * Descr: - */ + status_t -AddOnManager::HandleMethodReplicant(BMessage *message, - BMessage *reply) +AddOnManager::HandleMethodReplicant(BMessage* message, BMessage* reply) { CALLED(); LoadReplicant(); BAutolock lock(InputServer::gInputMethodListLocker); - if (((InputServer*)be_app)->MethodReplicant()) { + if (gInputServer->MethodReplicant()) { _BMethodAddOn_ *addon = InputServer::gKeymapMethod.fOwner; addon->AddMethod(); diff --git a/src/servers/input/AddOnManager.h b/src/servers/input/AddOnManager.h index 8a3e2f381a..ca6f3f098c 100644 --- a/src/servers/input/AddOnManager.h +++ b/src/servers/input/AddOnManager.h @@ -1,15 +1,17 @@ /* -** Copyright 2004, the Haiku project. All rights reserved. -** Distributed under the terms of the Haiku License. -** -** Author : Jérôme Duval -** Original authors: Marcus Overhagen, Axel Dörfler -*/ + * Copyright 2004-2005, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marcus Overhagen, Axel Dörfler + * Jérôme Duval + */ #ifndef _ADD_ON_MANAGER_H #define _ADD_ON_MANAGER_H // Manager for input_server add-ons (devices, filters, methods) + #include #include #include @@ -19,6 +21,7 @@ #include "AddOnMonitorHandler.h" #include "TList.h" + class AddOnManager : public BLooper { public: AddOnManager(bool safeMode); @@ -27,6 +30,7 @@ class AddOnManager : public BLooper { void LoadState(); void SaveState(); void MessageReceived(BMessage *message); + private: status_t RegisterAddOn(BEntry &entry); status_t UnregisterAddOn(BEntry &entry); @@ -52,6 +56,9 @@ class AddOnManager : public BLooper { status_t GetReplicantView(BMessenger target, int32 uid, BMessage *reply) const; private: + class InputServerMonitorHandler; + friend class InputServerMonitorHandler; + struct device_info { entry_ref ref; image_id addon_image; diff --git a/src/servers/input/InputServer.cpp b/src/servers/input/InputServer.cpp index d339db73f5..cace468b39 100644 --- a/src/servers/input/InputServer.cpp +++ b/src/servers/input/InputServer.cpp @@ -1,83 +1,58 @@ -/*****************************************************************************/ -// Haiku InputServer -// -// [Description] -// -// -// This application and all source files used in its construction, except -// where noted, are licensed under the MIT License, and have been written -// and are: -// -// Copyright (c) 2002-2005 Haiku Project -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2002-2005, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - #include "InputServer.h" #include "InputServerTypes.h" #include "kb_mouse_driver.h" #include "MethodReplicant.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "SystemKeymap.cpp" + // this is an automatically generated file + #ifndef USE_R5_STYLE_COMM #include #endif -#define FAST_MOUSE_MOVED '_FMM' // received from app_server when screen res changed, but could be sent to too. +#define FAST_MOUSE_MOVED '_FMM' + // received from app_server when screen res changed, but could be sent to too. -extern "C" void RegisterDevices(input_device_ref** devices) -{ - CALLED(); -}; - #ifdef COMPILE_FOR_R5 -extern "C" status_t _kget_safemode_option_(const char *parameter, char *buffer, size_t *_bufferSize); +extern "C" status_t _kget_safemode_option_(const char *parameter, + char *buffer, size_t *_bufferSize); #else -extern "C" status_t _kern_get_safemode_option(const char *parameter, char *buffer, size_t *_bufferSize); +extern "C" status_t _kern_get_safemode_option(const char *parameter, + char *buffer, size_t *_bufferSize); #endif -// Static InputServer member variables. -// -BList InputServer::gInputDeviceList; -BLocker InputServer::gInputDeviceListLocker("is_device_queue_sem"); +// Global InputServer member variables. -BList InputServer::gInputFilterList; +InputServer* gInputServer; + +BList InputServer::gInputFilterList; BLocker InputServer::gInputFilterListLocker("is_filter_queue_sem"); -BList InputServer::gInputMethodList; +BList InputServer::gInputMethodList; BLocker InputServer::gInputMethodListLocker("is_method_queue_sem"); DeviceManager InputServer::gDeviceManager; @@ -91,32 +66,76 @@ FILE *InputServer::sLogFile = NULL; extern "C" _EXPORT BView* instantiate_deskbar_item(); -BView * -instantiate_deskbar_item() + +InputDeviceListItem::InputDeviceListItem(BInputServerDevice& serverDevice, + input_device_ref& device) + : + fServerDevice(&serverDevice), + fDevice(device), + fRunning(false) { - return new MethodReplicant(INPUTSERVER_SIGNATURE); } -/* - * - */ -int main() +void +InputDeviceListItem::Start() { - InputServer *myInputServer = new InputServer; - - myInputServer->Run(); - - delete myInputServer; + PRINT((" Starting: %s\n", fDevice.name)); + fServerDevice->Start(fDevice.name, fDevice.cookie); + fRunning = true; } -/* - * Method: InputServer::InputServer() - * Descr: - */ -InputServer::InputServer(void) : BApplication(INPUTSERVER_SIGNATURE), - sSafeMode(false), +void +InputDeviceListItem::Stop() +{ + PRINT((" Stopping: %s\n", fDevice.name)); + fServerDevice->Stop(fDevice.name, fDevice.cookie); + fRunning = false; +} + + +void +InputDeviceListItem::Control(uint32 code, BMessage* message) +{ + fServerDevice->Control(fDevice.name, fDevice.cookie, code, message); +} + + +bool +InputDeviceListItem::HasName(const char* name) const +{ + if (name == NULL) + return false; + + return !strcmp(name, fDevice.name); +} + + +bool +InputDeviceListItem::HasType(input_device_type type) const +{ + return type == fDevice.type; +} + + +bool +InputDeviceListItem::Matches(const char* name, input_device_type type) const +{ + if (name != NULL) + return HasName(name); + + return HasType(type); +} + + +// #pragma mark - + + +InputServer::InputServer() + : BApplication(INPUTSERVER_SIGNATURE), + fSafeMode(false), + fInputDeviceListLocker("input server device list"), fChars(NULL), fScreen(B_MAIN_SCREEN_ID), fBLWindow(NULL), @@ -128,6 +147,7 @@ InputServer::InputServer(void) : BApplication(INPUTSERVER_SIGNATURE), #endif CALLED(); + gInputServer = this; EventLoop(); @@ -143,7 +163,7 @@ InputServer::InputServer(void) : BApplication(INPUTSERVER_SIGNATURE), if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) - sSafeMode = true; + fSafeMode = true; } gDeviceManager.LoadState(); @@ -186,7 +206,7 @@ InputServer::InputServer(void) : BApplication(INPUTSERVER_SIGNATURE), PRINTERR(("input_server couldn't find app_server's input port\n")); #endif - InitKeyboardMouseStates(); + _InitKeyboardMouseStates(); fAddOnManager = new AddOnManager(SafeMode()); fAddOnManager->LoadState(); @@ -195,11 +215,8 @@ InputServer::InputServer(void) : BApplication(INPUTSERVER_SIGNATURE), BRoster().StartWatching(messenger, B_REQUEST_LAUNCHED); } -/* - * Method: InputServer::InputServer() - * Descr: - */ -InputServer::~InputServer(void) + +InputServer::~InputServer() { CALLED(); fAddOnManager->Lock(); @@ -218,10 +235,6 @@ InputServer::~InputServer(void) } -/* - * Method: InputServer::ArgvReceived() - * Descr: - */ void InputServer::ArgvReceived(int32 argc, char** argv) { @@ -239,25 +252,21 @@ InputServer::ArgvReceived(int32 argc, char** argv) } -/* - * Method: InputServer::InitKeyboardMouseStates() - * Descr: - */ void -InputServer::InitKeyboardMouseStates(void) +InputServer::_InitKeyboardMouseStates() { CALLED(); // This is where we determine the screen resolution from the app_server and find the center of the screen // fMousePos is then set to the center of the screen. fFrame = fScreen.Frame(); - if (fFrame == BRect(0,0,0,0)) - fFrame = BRect(0,0,800,600); - fMousePos = BPoint(fFrame.right/2, fFrame.bottom/2); - - if (LoadKeymap()!=B_OK) + if (fFrame == BRect(0, 0, 0, 0)) + fFrame = BRect(0, 0, 800, 600); + fMousePos = BPoint(fFrame.right / 2, fFrame.bottom / 2); + + if (LoadKeymap() != B_OK) LoadSystemKeymap(); - + BMessage *msg = new BMessage(B_MOUSE_MOVED); HandleSetMousePosition(msg, msg); @@ -265,8 +274,6 @@ InputServer::InitKeyboardMouseStates(void) } -#include "SystemKeymap.cpp" - status_t InputServer::LoadKeymap() { @@ -314,107 +321,87 @@ InputServer::LoadSystemKeymap() fCharsSize = sSystemKeyCharsSize; fChars = new char[fCharsSize]; memcpy(fChars, sSystemKeyChars, fCharsSize); - + // we save this keymap to file BPath path; - if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK) + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) return B_BAD_VALUE; - + path.Append("Key_map"); entry_ref ref; get_ref_for_path(path.Path(), &ref); - - status_t err; - - BFile file(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE ); - if ((err = file.InitCheck()) != B_OK) { + + BFile file; + status_t err = file.SetTo(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + if (err != B_OK) { PRINTERR(("error %s\n", strerror(err))); return err; } - - for (uint32 i=0; iSaveState(); gDeviceManager.SaveState(); - + kill_thread(fISPortThread); delete_port(fEventLooperPort); fEventLooperPort = -1; return true; } -// --------------------------------------------------------------- -// InputServer::ReadyToRun(void) -// -// Verifies to see if the input_server is able to start. -// -// -// Parameters: -// None -// -// Returns: -// B_OK if the -// --------------------------------------------------------------- -void InputServer::ReadyToRun(void) + +void +InputServer::ReadyToRun() { CALLED(); } -/* - * Method: InputServer::MessageReceived() - * Descr: - */ void -InputServer::MessageReceived(BMessage *message) +InputServer::MessageReceived(BMessage* message) { CALLED(); - + BMessage reply; status_t status = B_OK; - PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what>>24, message->what>>16, message->what>>8, message->what)); - - switch(message->what) - { + PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what >> 24, + message->what >> 16, message->what >> 8, message->what)); + + switch (message->what) { case IS_SET_METHOD: HandleSetMethod(message); break; @@ -502,35 +489,30 @@ InputServer::MessageReceived(BMessage *message) case IS_METHOD_REGISTER: fAddOnManager->PostMessage(message); return; - case B_SOME_APP_LAUNCHED: { + case B_SOME_APP_LAUNCHED: + { const char *signature; + // TODO: what's this for? if (message->FindString("be:signature", &signature)==B_OK) { PRINT(("input_server : %s\n", signature)); if (strcmp(signature, "application/x-vnd.Be-TSKB")==0) { - + } } return; + } - } - break; default: - { return; - } } - + reply.AddInt32("status", status); message->SendReply(&reply); } -/* - * Method: InputServer::HandleSetMethod() - * Descr: - */ void -InputServer::HandleSetMethod(BMessage *message) +InputServer::HandleSetMethod(BMessage* message) { CALLED(); uint32 cookie; @@ -542,113 +524,78 @@ InputServer::HandleSetMethod(BMessage *message) } -/* - * Method: InputServer::HandleGetSetMouseType() - * Descr: - */ status_t -InputServer::HandleGetSetMouseType(BMessage* message, - BMessage* reply) +InputServer::HandleGetSetMouseType(BMessage* message, BMessage* reply) { - status_t status; - int32 type; - if (message->FindInt32("mouse_type", &type)==B_OK) { + int32 type; + if (message->FindInt32("mouse_type", &type) == B_OK) { fMouseSettings.SetMouseType(type); - + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_POINTING_DEVICE); msg.AddInt32("code", B_MOUSE_TYPE_CHANGED); - status = fAddOnManager->PostMessage(&msg); - - } else - status = reply->AddInt32("mouse_type", fMouseSettings.MouseType()); - return status; + return fAddOnManager->PostMessage(&msg); + } + + return reply->AddInt32("mouse_type", fMouseSettings.MouseType()); } -/* - * Method: InputServer::HandleGetSetMouseAcceleration() - * Descr: - */ status_t InputServer::HandleGetSetMouseAcceleration(BMessage* message, - BMessage* reply) + BMessage* reply) { - status_t status; int32 factor; if (message->FindInt32("speed", &factor) == B_OK) { fMouseSettings.SetAccelerationFactor(factor); - + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_POINTING_DEVICE); msg.AddInt32("code", B_MOUSE_ACCELERATION_CHANGED); - status = fAddOnManager->PostMessage(&msg); - } else - status = reply->AddInt32("speed", fMouseSettings.AccelerationFactor()); - return status; + return fAddOnManager->PostMessage(&msg); + } + + return reply->AddInt32("speed", fMouseSettings.AccelerationFactor()); } -/* - * Method: InputServer::HandleGetSetKeyRepeatDelay() - * Descr: - */ status_t -InputServer::HandleGetSetKeyRepeatDelay(BMessage* message, - BMessage* reply) +InputServer::HandleGetSetKeyRepeatDelay(BMessage* message, BMessage* reply) { - status_t status; bigtime_t delay; if (message->FindInt64("delay", &delay) == B_OK) { fKeyboardSettings.SetKeyboardRepeatDelay(delay); - + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_KEYBOARD_DEVICE); msg.AddInt32("code", B_KEY_REPEAT_DELAY_CHANGED); - status = fAddOnManager->PostMessage(&msg); - } else - status = reply->AddInt64("delay", fKeyboardSettings.KeyboardRepeatDelay()); - return status; + return fAddOnManager->PostMessage(&msg); + } + + return reply->AddInt64("delay", fKeyboardSettings.KeyboardRepeatDelay()); } -/* - * Method: InputServer::HandleGetKeyInfo() - * Descr: - */ status_t -InputServer::HandleGetKeyInfo(BMessage *message, - BMessage *reply) +InputServer::HandleGetKeyInfo(BMessage* message, BMessage* reply) { - return reply->AddData("key_info", B_ANY_TYPE, &fKey_info, sizeof(fKey_info)); + return reply->AddData("key_info", B_ANY_TYPE, &fKeyInfo, sizeof(fKeyInfo)); } -/* - * Method: InputServer::HandleGetModifiers() - * Descr: - */ status_t -InputServer::HandleGetModifiers(BMessage *message, - BMessage *reply) +InputServer::HandleGetModifiers(BMessage* message, BMessage* reply) { - return reply->AddInt32("modifiers", fKey_info.modifiers); + return reply->AddInt32("modifiers", fKeyInfo.modifiers); } -/* - * Method: InputServer::HandleSetModifierKey() - * Descr: - */ status_t -InputServer::HandleSetModifierKey(BMessage *message, - BMessage *reply) +InputServer::HandleSetModifierKey(BMessage* message, BMessage* reply) { - status_t status = B_ERROR; int32 modifier, key; if (message->FindInt32("modifier", &modifier) == B_OK && message->FindInt32("key", &key) == B_OK) { - switch (modifier) { case B_CAPS_LOCK: fKeys.caps_key = key; @@ -689,77 +636,62 @@ InputServer::HandleSetModifierKey(BMessage *message, default: return B_ERROR; } - - //TODO : unmap the key ? - + + // TODO: unmap the key ? + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_KEYBOARD_DEVICE); msg.AddInt32("code", B_KEY_MAP_CHANGED); - status = fAddOnManager->PostMessage(&msg); + return fAddOnManager->PostMessage(&msg); } - return status; + + return B_ERROR; } -/* - * Method: InputServer::HandleSetKeyboardLocks() - * Descr: - */ status_t -InputServer::HandleSetKeyboardLocks(BMessage *message, - BMessage *reply) +InputServer::HandleSetKeyboardLocks(BMessage* message, BMessage* reply) { - status_t status = B_ERROR; if (message->FindInt32("locks", (int32*)&fKeys.lock_settings) == B_OK) { BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_KEYBOARD_DEVICE); msg.AddInt32("code", B_KEY_LOCKS_CHANGED); - status = fAddOnManager->PostMessage(&msg); + return fAddOnManager->PostMessage(&msg); } - - return status; + + return B_ERROR; } -/* - * Method: InputServer::HandleGetSetMouseSpeed() - * Descr: - */ status_t -InputServer::HandleGetSetMouseSpeed(BMessage* message, - BMessage* reply) +InputServer::HandleGetSetMouseSpeed(BMessage* message, BMessage* reply) { - status_t status; int32 speed; if (message->FindInt32("speed", &speed) == B_OK) { fMouseSettings.SetMouseSpeed(speed); - + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_POINTING_DEVICE); msg.AddInt32("code", B_MOUSE_SPEED_CHANGED); - status = fAddOnManager->PostMessage(&msg); - } else - status = reply->AddInt32("speed", fMouseSettings.MouseSpeed()); - return status; + return fAddOnManager->PostMessage(&msg); + } + + return reply->AddInt32("speed", fMouseSettings.MouseSpeed()); } -/* - * Method: InputServer::HandleSetMousePosition() - * Descr: - */ status_t InputServer::HandleSetMousePosition(BMessage *message, BMessage *outbound) { CALLED(); - + // this assumes that both supplied pointers are identical - + ASSERT(outbound == message); - + int32 xValue, yValue; - - switch(message->what){ + + switch (message->what) { case B_MOUSE_MOVED: case B_MOUSE_DOWN: case B_MOUSE_UP: @@ -773,20 +705,18 @@ InputServer::HandleSetMousePosition(BMessage *message, BMessage *outbound) outbound->RemoveName("x"); outbound->RemoveName("y"); outbound->AddPoint("where", fMousePos); - outbound->AddInt32("modifiers", fKey_info.modifiers); + outbound->AddInt32("modifiers", fKeyInfo.modifiers); PRINT(("new position : %f, %f, %ld, %ld\n", fMousePos.x, fMousePos.y, xValue, yValue)); - } - else if (outbound->FindPoint("where", &fMousePos) == B_OK) { - outbound->RemoveName("where"); - fMousePos.ConstrainTo(fFrame); - outbound->AddPoint("where", fMousePos); - outbound->AddInt32("modifiers", fKey_info.modifiers); - PRINT(("new position : %f, %f\n", fMousePos.x, fMousePos.y)); - } + } else if (outbound->FindPoint("where", &fMousePos) == B_OK) { + outbound->RemoveName("where"); + fMousePos.ConstrainTo(fFrame); + outbound->AddPoint("where", fMousePos); + outbound->AddInt32("modifiers", fKeyInfo.modifiers); + PRINT(("new position : %f, %f\n", fMousePos.x, fMousePos.y)); + } #ifdef R5_CURSOR_COMM - if (fAppBuffer) { - fAppBuffer[0] = - (0x3 << 30) + if (fAppBuffer) { + fAppBuffer[0] = (0x3 << 30L) | ((uint32)fMousePos.x & 0x7fff) << 15 | ((uint32)fMousePos.y & 0x7fff); @@ -794,25 +724,28 @@ InputServer::HandleSetMousePosition(BMessage *message, BMessage *outbound) release_sem(fCursorSem); } #endif - break; + break; // some Key Down and up codes .. case B_KEY_DOWN: case B_KEY_UP: case B_UNMAPPED_KEY_DOWN: case B_UNMAPPED_KEY_UP: - case B_MODIFIERS_CHANGED: { + case B_MODIFIERS_CHANGED: + { ssize_t size = 0; uint8 *data = NULL; - outbound->FindInt32("modifiers", (int32*)&fKey_info.modifiers); - if ((outbound->FindData("states", B_UINT8_TYPE, (const void**)&data, &size) == B_OK) - && (size == (ssize_t)sizeof(fKey_info.key_states))) { + outbound->FindInt32("modifiers", (int32*)&fKeyInfo.modifiers); + if (outbound->FindData("states", B_UINT8_TYPE, + (const void**)&data, &size) == B_OK + && size == (ssize_t)sizeof(fKeyInfo.key_states)) { PRINT(("updated keyinfo\n")); - memcpy(fKey_info.key_states, data, size); + memcpy(fKeyInfo.key_states, data, size); } - PRINT(("keyinfo %ld %ld\n", size, (ssize_t)sizeof(fKey_info.key_states))); - + PRINT(("keyinfo %ld %ld\n", size, (ssize_t)sizeof(fKeyInfo.key_states))); + break; } + default: break; } @@ -821,134 +754,98 @@ InputServer::HandleSetMousePosition(BMessage *message, BMessage *outbound) } -/* - * Method: InputServer::HandleGetMouseMap() - * Descr: - */ status_t -InputServer::HandleGetSetMouseMap(BMessage* message, - BMessage* reply) +InputServer::HandleGetSetMouseMap(BMessage* message, BMessage* reply) { - status_t status; mouse_map *map; - ssize_t size; - + ssize_t size; if (message->FindData("mousemap", B_RAW_TYPE, (const void**)&map, &size) == B_OK) { fMouseSettings.SetMapping(*map); - + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_POINTING_DEVICE); msg.AddInt32("code", B_MOUSE_MAP_CHANGED); - status = fAddOnManager->PostMessage(&msg); - + return fAddOnManager->PostMessage(&msg); } else { - mouse_map map; + mouse_map map; fMouseSettings.Mapping(map); - status = reply->AddData("mousemap", B_RAW_TYPE, &map, sizeof(mouse_map) ); - } - return status; + return reply->AddData("mousemap", B_RAW_TYPE, &map, sizeof(mouse_map)); + } } -/* - * Method: InputServer::HandleGetKeyboardID() - * Descr: - */ status_t -InputServer::HandleGetKeyboardID(BMessage *message, - BMessage *reply) +InputServer::HandleGetKeyboardID(BMessage* message, BMessage* reply) { - return reply->AddInt16("id", sKeyboardID); + return reply->AddInt16("id", fKeyboardID); } -/* - * Method: InputServer::HandleGetSetClickSpeed() - * Descr: - */ status_t -InputServer::HandleGetSetClickSpeed(BMessage *message, - BMessage *reply) +InputServer::HandleGetSetClickSpeed(BMessage* message, BMessage* reply) { - status_t status = B_ERROR; - bigtime_t click_speed; - if (message->FindInt64("speed", &click_speed) == B_OK) { - fMouseSettings.SetClickSpeed(click_speed); - + bigtime_t clickSpeed; + if (message->FindInt64("speed", &clickSpeed) == B_OK) { + fMouseSettings.SetClickSpeed(clickSpeed); + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_POINTING_DEVICE); msg.AddInt32("code", B_CLICK_SPEED_CHANGED); - status = fAddOnManager->PostMessage(&msg); - - } else - status = reply->AddInt64("speed", fMouseSettings.ClickSpeed()); - return status; + return fAddOnManager->PostMessage(&msg); + } + + return reply->AddInt64("speed", fMouseSettings.ClickSpeed()); } -/* - * Method: InputServer::HandleGetSetKeyRepeatRate() - * Descr: - */ status_t -InputServer::HandleGetSetKeyRepeatRate(BMessage* message, - BMessage* reply) +InputServer::HandleGetSetKeyRepeatRate(BMessage* message, BMessage* reply) { - status_t status; - int32 key_repeat_rate; - if (message->FindInt32("rate", &key_repeat_rate) == B_OK) { - fKeyboardSettings.SetKeyboardRepeatRate(key_repeat_rate); - + int32 keyRepeatRate; + if (message->FindInt32("rate", &keyRepeatRate) == B_OK) { + fKeyboardSettings.SetKeyboardRepeatRate(keyRepeatRate); + BMessage msg(IS_CONTROL_DEVICES); msg.AddInt32("type", B_KEYBOARD_DEVICE); msg.AddInt32("code", B_KEY_REPEAT_RATE_CHANGED); - status = fAddOnManager->PostMessage(&msg); - } else - status = reply->AddInt32("rate", fKeyboardSettings.KeyboardRepeatRate()); - return status; + return fAddOnManager->PostMessage(&msg); + } + + return reply->AddInt32("rate", fKeyboardSettings.KeyboardRepeatRate()); } -/* - * Method: InputServer::HandleGetSetKeyMap() - * Descr: - */ status_t -InputServer::HandleGetSetKeyMap(BMessage *message, - BMessage *reply) -{ +InputServer::HandleGetSetKeyMap(BMessage* message, BMessage* reply) +{ CALLED(); - status_t status; + if (message->what == IS_GET_KEY_MAP) { - status = reply->AddData("keymap", B_ANY_TYPE, &fKeys, sizeof(fKeys)); + status_t status = reply->AddData("keymap", B_ANY_TYPE, &fKeys, sizeof(fKeys)); if (status == B_OK) status = reply->AddData("key_buffer", B_ANY_TYPE, fChars, fCharsSize); - } else { - if (LoadKeymap()!=B_OK) - LoadSystemKeymap(); - - BMessage msg(IS_CONTROL_DEVICES); - msg.AddInt32("type", B_KEYBOARD_DEVICE); - msg.AddInt32("code", B_KEY_MAP_CHANGED); - status = fAddOnManager->PostMessage(&msg); + + return status; } - return status; + + if (LoadKeymap() != B_OK) + LoadSystemKeymap(); + + BMessage msg(IS_CONTROL_DEVICES); + msg.AddInt32("type", B_KEYBOARD_DEVICE); + msg.AddInt32("code", B_KEY_MAP_CHANGED); + return fAddOnManager->PostMessage(&msg); } -/* - * Method: InputServer::HandleFocusUnfocusIMAwareView() - * Descr: - */ status_t -InputServer::HandleFocusUnfocusIMAwareView(BMessage *message, - BMessage *reply) +InputServer::HandleFocusUnfocusIMAwareView(BMessage* message, + BMessage* reply) { CALLED(); BMessenger messenger; status_t status = message->FindMessenger("view", &messenger); - if (status != B_OK) return status; @@ -962,38 +859,32 @@ InputServer::HandleFocusUnfocusIMAwareView(BMessage *message, fIMAware = false; } - return status; + return B_OK; } -/* - * Method: InputServer::EnqueueDeviceMessage() - * Descr: - */ -status_t -InputServer::EnqueueDeviceMessage(BMessage *message) +status_t +InputServer::EnqueueDeviceMessage(BMessage* message) { CALLED(); - - status_t err; - + ssize_t length = message->FlattenedSize(); char buffer[length]; + status_t err; if ((err = message->Flatten(buffer,length)) < B_OK) return err; + return write_port(fEventLooperPort, 0, buffer, length); } -/* - * Method: InputServer::EnqueueMethodMessage() - * Descr: - */ status_t -InputServer::EnqueueMethodMessage(BMessage *message) +InputServer::EnqueueMethodMessage(BMessage* message) { CALLED(); - PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what>>24, message->what>>16, message->what>>8, message->what)); + PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what >> 24, + message->what >> 16, message->what >> 8, message->what)); + #ifdef DEBUG if (message->what == 'IMEV') { int32 code; @@ -1001,23 +892,17 @@ InputServer::EnqueueMethodMessage(BMessage *message) PRINT(("%s be:opcode %li\n", __PRETTY_FUNCTION__, code)); } #endif + LockMethodQueue(); - fMethodQueue.AddItem(message); - - write_port_etc(fEventLooperPort, 0, NULL, 0, B_RELATIVE_TIMEOUT, 0); - UnlockMethodQueue(); + write_port_etc(fEventLooperPort, 0, NULL, 0, B_RELATIVE_TIMEOUT, 0); return B_OK; } -/* - * Method: InputServer::UnlockMethodQueue() - * Descr: - */ -status_t +status_t InputServer::UnlockMethodQueue() { gInputMethodListLocker.Unlock(); @@ -1025,11 +910,7 @@ InputServer::UnlockMethodQueue() } -/* - * Method: InputServer::LockMethodQueue() - * Descr: - */ -status_t +status_t InputServer::LockMethodQueue() { gInputMethodListLocker.Lock(); @@ -1037,18 +918,14 @@ InputServer::LockMethodQueue() } -/* - * Method: InputServer::SetNextMethod() - * Descr: - */ status_t InputServer::SetNextMethod(bool direction) { LockMethodQueue(); - + int32 index = gInputMethodList.IndexOf(fActiveMethod); index += (direction ? 1 : -1); - + if (index < -1) index = gInputMethodList.CountItems() - 1; if (index >= gInputMethodList.CountItems()) @@ -1058,7 +935,7 @@ InputServer::SetNextMethod(bool direction) if (index != -1) method = (BInputServerMethod *)gInputMethodList.ItemAt(index); - + SetActiveMethod(method); UnlockMethodQueue(); @@ -1066,28 +943,20 @@ InputServer::SetNextMethod(bool direction) } -/* - * Method: InputServer::SetActiveMethod() - * Descr: - */ void -InputServer::SetActiveMethod(BInputServerMethod *method) +InputServer::SetActiveMethod(BInputServerMethod* method) { CALLED(); if (fActiveMethod) fActiveMethod->fOwner->MethodActivated(false); + fActiveMethod = method; - - if (fActiveMethod) { - fActiveMethod->fOwner->MethodActivated(true); - } + + if (fActiveMethod) + fActiveMethod->fOwner->MethodActivated(true); } -/* - * Method: InputServer::MethodReplicant() - * Descr: - */ const BMessenger* InputServer::MethodReplicant() { @@ -1096,71 +965,59 @@ InputServer::MethodReplicant() void -InputServer::SetMethodReplicant(const BMessenger *messenger) +InputServer::SetMethodReplicant(const BMessenger* messenger) { fReplicantMessenger = messenger; } -/* - * Method: InputServer::EventLoop() - * Descr: - */ status_t InputServer::EventLoop() { CALLED(); fEventLooperPort = create_port(100, "haiku_is_event_port"); - if(fEventLooperPort < 0) { - PRINTERR(("InputServer: create_port error: (0x%x) %s\n", fEventLooperPort, strerror(fEventLooperPort))); + if (fEventLooperPort < 0) { + PRINTERR(("InputServer: create_port error: (0x%x) %s\n", + fEventLooperPort, strerror(fEventLooperPort))); } - fISPortThread = spawn_thread(ISPortWatcher, "_input_server_event_loop_", B_REAL_TIME_DISPLAY_PRIORITY+3, this); - resume_thread(fISPortThread); + fISPortThread = spawn_thread(ISPortWatcher, "_input_server_event_loop_", + B_REAL_TIME_DISPLAY_PRIORITY + 3, this); + resume_thread(fISPortThread); return 0; } -/* - * Method: InputServer::EventLoopRunning() - * Descr: - */ bool -InputServer::EventLoopRunning(void) +InputServer::EventLoopRunning() { return fEventLooperPort > -1; } -/* - * Method: InputServer::DispatchEvents() - * Descr: - */ bool -InputServer::DispatchEvents(BList *eventList) +InputServer::DispatchEvents(BList* eventList) { CALLED(); - + CacheEvents(eventList); - if (fEventsCache.CountItems()>0) { + if (fEventsCache.CountItems() > 0) { + BMessage* event; - BMessage *event; - - for ( int32 i = 0; NULL != (event = (BMessage *)fEventsCache.ItemAt(i)); i++ ) { + for (int32 i = 0; NULL != (event = (BMessage *)fEventsCache.ItemAt(i)); i++) { // now we must send each event to the app_server if (event->what == B_INPUT_METHOD_EVENT && !fIMAware) { SERIAL_PRINT(("IME received\n")); int32 opcode = -1; event->FindInt32("be:opcode", &opcode); BList events; - if (!fBLWindow && opcode == B_INPUT_METHOD_STARTED) { + if (!fBLWindow && opcode == B_INPUT_METHOD_STARTED) fBLWindow = new BottomlineWindow(be_plain_font); - } - + if (fBLWindow) { fBLWindow->HandleInputMethodEvent(event, &events); - + if (!events.IsEmpty()) { fBLWindow->PostMessage(B_QUIT_REQUESTED); fBLWindow = NULL; @@ -1168,21 +1025,21 @@ InputServer::DispatchEvents(BList *eventList) fEventsCache.AddList(&events); } } - } else { + } else DispatchEvent(event); - } delete event; } - + fEventsCache.MakeEmpty(); } + return true; } -int -InputServer::DispatchEvent(BMessage *message) +status_t +InputServer::DispatchEvent(BMessage* message) { CALLED(); @@ -1195,40 +1052,33 @@ InputServer::DispatchEvent(BMessage *message) ssize_t size; uint8 *data; if (message->FindData("states", B_UINT8_TYPE, (const void**)&data, &size) != B_OK) - message->AddData("states", B_UINT8_TYPE, fKey_info.key_states, 16); - if (message->FindInt32("modifiers", (int32*)&modifiers)!=B_OK) - message->AddInt32("modifiers", fKey_info.modifiers); - + message->AddData("states", B_UINT8_TYPE, fKeyInfo.key_states, 16); + if (message->FindInt32("modifiers", (int32*)&modifiers) != B_OK) + message->AddInt32("modifiers", fKeyInfo.modifiers); break; } } - - status_t err; - + ssize_t length = message->FlattenedSize(); char buffer[length]; + status_t err; if ((err = message->Flatten(buffer,length)) < B_OK) return err; - - if (fAsPort>0) + + if (fAsPort > 0) write_port(fAsPort, 0, buffer, length); - return true; + return B_OK; } -/* - * Method: InputServer::CacheEvents() - * Descr: - */ -bool -InputServer::CacheEvents(BList *eventsToCache) + +bool +InputServer::CacheEvents(BList* eventsToCache) { CALLED(); SanitizeEvents(eventsToCache); - MethodizeEvents(eventsToCache, true); - FilterEvents(eventsToCache); fEventsCache.AddList(eventsToCache); @@ -1238,103 +1088,81 @@ InputServer::CacheEvents(BList *eventsToCache) } -/* - * Method: InputServer::GetNextEvents() - * Descr: - */ -const BList* +const BList* InputServer::GetNextEvents(BList *) { return NULL; } -/* - * Method: InputServer::FilterEvents() - * Descr: This method applies all defined filters to each event in the - * supplied list. The supplied list is modified to reflect the - * output of the filters. - * The method returns true if the filters were applied to all - * events without error and false otherwise. +/** This method applies all defined filters to each event in the + * supplied list. The supplied list is modified to reflect the + * output of the filters. + * The method returns true if the filters were applied to all + * events without error and false otherwise. */ + bool -InputServer::FilterEvents(BList *eventsToFilter) +InputServer::FilterEvents(BList* eventsToFilter) { CALLED(); - + if (NULL == eventsToFilter) return false; - - BInputServerFilter *current_filter; - int32 filter_index = 0; - while (NULL != (current_filter = (BInputServerFilter*)gInputFilterList.ItemAt(filter_index) ) ) { + BInputServerFilter* currentFilter; + int32 filterIndex = 0; + + while ((currentFilter = (BInputServerFilter*)gInputFilterList.ItemAt(filterIndex)) != NULL) { // Apply the current filter to all available event messages. - // - int32 event_index = 0; - BMessage *current_event; - while (NULL != (current_event = (BMessage*)eventsToFilter->ItemAt(event_index) ) ) { + int32 eventIndex = 0; + BMessage *currentEvent; + while ((currentEvent = (BMessage*)eventsToFilter->ItemAt(eventIndex)) != NULL) { // Storage for new event messages generated by the filter. - // - BList out_list; - - // Apply the current filter to the current event message. - // - PRINT(("InputServer::FilterEvents Filter called\n")); - filter_result result = current_filter->Filter(current_event, &out_list); - if (B_DISPATCH_MESSAGE == result) { - // Use the result in current_message; ignore out_list. - // - event_index++; + BList outList; - // Free resources associated with items in out_list. - // - void *out_item; - for (int32 i = 0; NULL != (out_item = out_list.ItemAt(i) ); i++) - delete (BMessage*)out_item; - } else if (B_SKIP_MESSAGE == result) { + // Apply the current filter to the current event message. + PRINT(("InputServer::FilterEvents Filter called\n")); + filter_result result = currentFilter->Filter(currentEvent, &outList); + + if (result == B_SKIP_MESSAGE) { // Use the result in out_list (if any); ignore current message. - // - eventsToFilter->RemoveItem(event_index); - eventsToFilter->AddList(&out_list, event_index); - event_index += out_list.CountItems(); - - // NOTE: eventsToFilter now owns out_list's items. + eventsToFilter->RemoveItem(eventIndex); + eventsToFilter->AddList(&outList, eventIndex); + eventIndex += outList.CountItems(); + + // NOTE: eventsToFilter now owns outList's items. } else { - // Error - Free resources associated with items in out_list and return. - // - void* out_item; - for (int32 i = 0; NULL != (out_item = out_list.ItemAt(i) ); i++) - delete (BMessage*)out_item; + // Free resources associated with items in outList. + void* outItem; + for (int32 i = 0; (outItem = outList.ItemAt(i)) != NULL; i++) { + delete (BMessage*)outItem; + } + } + if (result == B_DISPATCH_MESSAGE) { + // Use the result in current_message; ignore outList. + eventIndex++; + } else { + // Error return false; } - - // NOTE: The BList destructor frees out_lists's resources here. - // It does NOT free the resources associated with out_list's - // member items - those should either already be deleted or - // should be owned by eventsToFilter. - } // while() - - filter_index++; - - } // while() - + } + + filterIndex++; + } + return true; } -/* - * Method: InputServer::SanitizeEvents() - * Descr: - */ -bool -InputServer::SanitizeEvents(BList *events) +bool +InputServer::SanitizeEvents(BList* events) { CALLED(); int32 index = 0; BMessage *event; PRINT(("SanitizeEvents: %ld \n", events->CountItems())); - while (NULL != (event = (BMessage*)events->ItemAt(index) ) ) { + while ((event = (BMessage*)events->ItemAt(index)) != NULL) { PRINT(("SanitizeEvents: what:%lx\n", event->what)); switch (event->what) { case B_KEY_DOWN: @@ -1342,12 +1170,14 @@ InputServer::SanitizeEvents(BList *events) // we scan for Alt+Space key down events which means we change to next input method // Note : Shift+Alt+Space key allows to change to the previous input method - PRINT(("SanitizeEvents: %lx, %lx\n",fKey_info.modifiers, fKey_info.key_states[KEY_Spacebar >> 3] )); - - if ((fKey_info.modifiers & B_COMMAND_KEY) - && (fKey_info.key_states[KEY_Spacebar >> 3] & (1 << (7 - (KEY_Spacebar % 8))))) { - SetNextMethod(!fKey_info.modifiers & B_SHIFT_KEY); - + PRINT(("SanitizeEvents: %lx, %lx\n", fKeyInfo.modifiers, + fKeyInfo.key_states[KEY_Spacebar >> 3])); + + if ((fKeyInfo.modifiers & B_COMMAND_KEY) != 0 + && (fKeyInfo.key_states[KEY_Spacebar >> 3] + & (1 << (7 - (KEY_Spacebar % 8))))) { + SetNextMethod(!fKeyInfo.modifiers & B_SHIFT_KEY); + // this event isn't sent to the user events->RemoveItem(index); delete event; @@ -1363,31 +1193,25 @@ InputServer::SanitizeEvents(BList *events) } -/* - * Method: InputServer::MethodizeEvents() - * Descr: - */ bool -InputServer::MethodizeEvents(BList *events, - bool) +InputServer::MethodizeEvents(BList* events, bool) { CALLED(); - - if (fActiveMethod) { + if (fActiveMethod) { BList newList; newList.AddList(&fMethodQueue); fMethodQueue.MakeEmpty(); - + for (int32 i=0; iCountItems(); i++) { BMessage *item = (BMessage *)events->ItemAt(i); BList filterList; - filter_result res = fActiveMethod->Filter(item, &filterList); - switch (res) { + filter_result result = fActiveMethod->Filter(item, &filterList); + switch (result) { case B_SKIP_MESSAGE: delete item; case B_DISPATCH_MESSAGE: - if (filterList.CountItems()>0) { + if (filterList.CountItems() > 0) { newList.AddList(&filterList); delete item; } else @@ -1406,103 +1230,147 @@ InputServer::MethodizeEvents(BList *events, } -/* - * Method: InputServer::StartStopDevices() - * Descr: - */ -status_t -InputServer::StartStopDevices(const char *name, input_device_type type, bool doStart) -{ - CALLED(); +/** The fInputDeviceListLocker must be locked when calling this function */ - for (int i = gInputDeviceList.CountItems() - 1; i >= 0; i--) { - InputDeviceListItem* item = (InputDeviceListItem*)gInputDeviceList.ItemAt(i); - if (!item) - continue; - - if ((name && strcmp(name, item->mDev.name) == 0) || (!name && item->mDev.type == type)) { - if (!item->mIsd) - return B_ERROR; - - input_device_ref dev = item->mDev; - - if (doStart) { - PRINT((" Starting: %s\n", dev.name)); - item->mIsd->Start(dev.name, dev.cookie); - item->mStarted = true; - } else { - PRINT((" Stopping: %s\n", dev.name)); - item->mIsd->Stop(dev.name, dev.cookie); - item->mStarted = false; - } - if (name) - return B_OK; - } +InputDeviceListItem* +InputServer::_FindInputDeviceListItem(BInputServerDevice& device) +{ + for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { + InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); + + if (item->ServerDevice() == &device) + return item; } - if (name) - return B_ERROR; - else - return B_OK; + return NULL; } - -/* - * Method: InputServer::StartStopDevices() - * Descr: - */ -status_t -InputServer::StartStopDevices(BInputServerDevice *isd, - bool doStart) +status_t +InputServer::GetDeviceInfo(const char* name, input_device_type *_type, + bool *_isRunning) { - CALLED(); - for (int i = gInputDeviceList.CountItems() - 1; i >= 0; i--) - { - PRINT(("%s Device #%d\n", __PRETTY_FUNCTION__, i)); - InputDeviceListItem* item = (InputDeviceListItem*)gInputDeviceList.ItemAt(i); - if (NULL != item && isd == item->mIsd) - { - input_device_ref dev = item->mDev; - - if (doStart) { - PRINT((" Starting: %s\n", dev.name)); - isd->Start(dev.name, dev.cookie); - item->mStarted = true; - } else { - PRINT((" Stopping: %s\n", dev.name)); - isd->Stop(dev.name, dev.cookie); - item->mStarted = false; + BAutolock lock(fInputDeviceListLocker); + + for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { + InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); + + if (item->HasName(name)) { + if (_type) + *_type = item->Type(); + if (_isRunning) + *_isRunning = item->Running(); + + return B_OK; + } + } + + return B_NAME_NOT_FOUND; +} + + +status_t +InputServer::UnregisterDevices(BInputServerDevice& serverDevice, + input_device_ref **devices) +{ + CALLED(); + BAutolock lock(fInputDeviceListLocker); + + if (devices != NULL) { + // remove the devices as specified only + input_device_ref *device = NULL; + for (int32 i = 0; NULL != (device = devices[i]); i++) { + for (int32 j = fInputDeviceList.CountItems() - 1; j >= 0; j--) { + InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(j); + + if (item->ServerDevice() == &serverDevice && item->HasName(device->name)) { + item->Stop(); + fInputDeviceList.RemoveItem(j); + delete item; + break; + } + } + } + } else { + // remove all devices from this BInputServerObject + for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { + InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); + + if (item->ServerDevice() == &serverDevice) { + item->Stop(); + fInputDeviceList.RemoveItem(i); + delete item; } } } - EXIT(); - + + return B_OK; +} + + +status_t +InputServer::RegisterDevices(BInputServerDevice& serverDevice, + input_device_ref** devices) +{ + if (devices == NULL) + return B_BAD_VALUE; + + BAutolock lock(fInputDeviceListLocker); + + input_device_ref *device = NULL; + for (int32 i = 0; (device = devices[i]) != NULL; i++) { + if (device->type != B_POINTING_DEVICE + && device->type != B_KEYBOARD_DEVICE + && device->type != B_UNDEFINED_DEVICE) + continue; + + // find existing input server device + + bool found = false; + for (int32 j = fInputDeviceList.CountItems() - 1; j >= 0; j--) { + InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(j); + + if (item->HasName(device->name)) { + PRINT(("RegisterDevices found %s\n", device->name)); + found = true; + break; + } + } + + if (!found) { + PRINT(("RegisterDevices not found %s\n", device->name)); + InputDeviceListItem* item = new (nothrow) InputDeviceListItem(serverDevice, + *device); + if (item != NULL && fInputDeviceList.AddItem(item)) { + item->Start(); + } else { + delete item; + return B_NO_MEMORY; + } + } + } + return B_OK; } -/* - * Method: InputServer::ControlDevices() - * Descr: - */ -status_t -InputServer::ControlDevices(const char* name, input_device_type type, uint32 code, BMessage* msg) -{ +status_t +InputServer::StartStopDevices(const char* name, input_device_type type, bool doStart) +{ CALLED(); - for (int i = gInputDeviceList.CountItems() - 1; i >= 0; i--) { - InputDeviceListItem* item = (InputDeviceListItem*)gInputDeviceList.ItemAt(i); + BAutolock lock(fInputDeviceListLocker); + + for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { + InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); if (!item) continue; - - if ((name && strcmp(name, item->mDev.name) == 0) || item->mDev.type == type) { - if (!item->mIsd) - return B_ERROR; - - input_device_ref dev = item->mDev; - - item->mIsd->Control(dev.name, dev.cookie, code, msg); - + + if (item->Matches(name, type)) { + if (doStart) + item->Start(); + else + item->Stop(); + if (name) return B_OK; } @@ -1510,18 +1378,60 @@ InputServer::ControlDevices(const char* name, input_device_type type, uint32 cod if (name) return B_ERROR; - else - return B_OK; + + return B_OK; +} + + + +status_t +InputServer::StartStopDevices(BInputServerDevice& serverDevice, bool doStart) +{ + CALLED(); + BAutolock lock(fInputDeviceListLocker); + + InputDeviceListItem* item = _FindInputDeviceListItem(serverDevice); + if (item != NULL) { + if (doStart) + item->Start(); + else + item->Stop(); + } + EXIT(); + + return B_OK; +} + + +status_t +InputServer::ControlDevices(const char* name, input_device_type type, + uint32 code, BMessage* message) +{ + CALLED(); + BAutolock lock(fInputDeviceListLocker); + + for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { + InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); + if (!item) + continue; + + if (item->Matches(name, type)) { + item->Control(code, message); + + if (name) + return B_OK; + } + } + + if (name) + return B_ERROR; + + return B_OK; } -/* - * Method: InputServer::DoMouseAcceleration() - * Descr: - */ bool -InputServer::DoMouseAcceleration(int32 *x, - int32 *y) +InputServer::DoMouseAcceleration(int32* _x, int32* _y) { CALLED(); int32 speed = fMouseSettings.MouseSpeed() >> 15; @@ -1534,85 +1444,60 @@ InputServer::DoMouseAcceleration(int32 *x, } -/* - * Method: InputServer::SetMousePos() - * Descr: - */ -bool -InputServer::SetMousePos(long *, - long *, - long, - long) -{ - CALLED(); - return true; -} - - -/* - * Method: InputServer::SetMousePos() - * Descr: - */ -bool -InputServer::SetMousePos(long *, - long *, - BPoint) -{ - CALLED(); - return true; -} - - -/* - * Method: InputServer::SetMousePos() - * Descr: - */ -bool -InputServer::SetMousePos(long *, - long *, - float, - float) -{ - CALLED(); - return true; -} - - -/* - * Method: InputServer::SafeMode() - * Descr: - */ bool -InputServer::SafeMode(void) +InputServer::SetMousePos(long *, long *, long, long) { - return sSafeMode; + CALLED(); + return true; +} + + +bool +InputServer::SetMousePos(long *, long *, BPoint) +{ + CALLED(); + return true; +} + + +bool +InputServer::SetMousePos(long *, long *, float, float) +{ + CALLED(); + return true; +} + + +bool +InputServer::SafeMode() +{ + return fSafeMode; } int32 -InputServer::ISPortWatcher(void *arg) +InputServer::ISPortWatcher(void* arg) { - InputServer *self = (InputServer*)arg; + InputServer* self = (InputServer*)arg; self->WatchPort(); - return B_NO_ERROR; + + return B_OK; } void InputServer::WatchPort() { - while (true) { // Block until we find the size of the next message - ssize_t length = port_buffer_size(fEventLooperPort); + ssize_t length = port_buffer_size(fEventLooperPort); PRINT(("[Event Looper] BMessage Size = %lu\n", length)); - - int32 code; + char buffer[length]; - + int32 code; status_t err = read_port(fEventLooperPort, &code, buffer, length); - if(err != length) { - if(err >= 0) { + if (err != length) { + if (err >= 0) { PRINTERR(("InputServer: failed to read full packet (read %lu of %lu)\n", err, length)); } else { PRINTERR(("InputServer: read_port error: (0x%lx) %s\n", err, strerror(err))); @@ -1625,9 +1510,9 @@ InputServer::WatchPort() DispatchEvents(&list); continue; } - - BMessage *event = new BMessage; - + + BMessage* event = new BMessage; + if ((err = event->Unflatten(buffer)) < 0) { PRINTERR(("[InputServer] Unflatten() error: (0x%lx) %s\n", err, strerror(err))); delete event; @@ -1656,3 +1541,33 @@ InputServer::WatchPort() } } + +// #pragma mark - + + +extern "C" void +RegisterDevices(input_device_ref** devices) +{ + CALLED(); +}; + + +BView * +instantiate_deskbar_item() +{ + return new MethodReplicant(INPUTSERVER_SIGNATURE); +} + + +int +main() +{ + InputServer *inputServer = new InputServer; + + inputServer->Run(); + delete inputServer; + + return 0; +} + + diff --git a/src/servers/input/InputServer.h b/src/servers/input/InputServer.h index cba3e0b932..7d71e00391 100644 --- a/src/servers/input/InputServer.h +++ b/src/servers/input/InputServer.h @@ -1,270 +1,268 @@ -/*****************************************************************************/ -// Haiku input_server -// -// This is the primary application class for the Haiku input_server. -// -// -// Copyright (c) 2001-2005 Haiku Project -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2001-2005, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef INPUT_SERVER_APP_H +#define INPUT_SERVER_APP_H -#ifndef INPUTSERVERAPP_H -#define INPUTSERVERAPP_H - -// BeAPI Headers -#include -#include -#include -#include -#include #include "AddOnManager.h" #include "BottomlineWindow.h" #include "DeviceManager.h" -#include "MouseSettings.h" #include "KeyboardSettings.h" +#include "MouseSettings.h" -#include -#include -#include -#include - +#include +#include #include +#include +#include +#include #include +#include #include #include #include #include -#define HAIKU_APPSERVER_COMM -#define R5_CURSOR_COMM // define this when R5 cursor communication should be used -//#define APPSERVER_R5_COMM // define this when R5 app_server communication should be used +#include +#include +#include -#define INPUTSERVER_SIGNATURE "application/x-vnd.Be-input_server" // use this when target should replace R5 input_server + +#define HAIKU_APPSERVER_COMM +#define R5_CURSOR_COMM + // define this when R5 cursor communication should be used +//#define APPSERVER_R5_COMM + // define this when R5 app_server communication should be used + +#define INPUTSERVER_SIGNATURE "application/x-vnd.Be-input_server" + // use this when target should replace R5 input_server #ifdef APPSERVER_R5_COMM #define R5_CURSOR_COMM #undef HAIKU_APPSERVER_COMM #endif -class InputDeviceListItem -{ +class InputDeviceListItem { public: - BInputServerDevice* mIsd; - input_device_ref mDev; - bool mStarted; + InputDeviceListItem(BInputServerDevice& serverDevice, input_device_ref& device); - InputDeviceListItem(BInputServerDevice* isd, input_device_ref dev): - mIsd(isd), mDev(dev), mStarted(false) {}; + void Start(); + void Stop(); + void Control(uint32 code, BMessage* message); + + const char* Name() const { return fDevice.name; } + input_device_type Type() const { return fDevice.type; } + bool Running() const { return fRunning; } + + bool HasName(const char* name) const; + bool HasType(input_device_type type) const; + bool Matches(const char* name, input_device_type type) const; + + BInputServerDevice* ServerDevice() { return fServerDevice; } + + private: + BInputServerDevice* fServerDevice; + input_device_ref fDevice; + bool fRunning; }; -class _BDeviceAddOn_ -{ +class _BDeviceAddOn_ { public: _BDeviceAddOn_(BInputServerDevice *device) - : fDevice(device) {}; - - BInputServerDevice *fDevice; + : fDevice(device) {} + + BInputServerDevice* fDevice; BList fMonitoredRefs; }; -class _BMethodAddOn_ -{ +class _BMethodAddOn_ { public: - _BMethodAddOn_(BInputServerMethod *method, const char* name, const uchar *icon); + _BMethodAddOn_(BInputServerMethod *method, const char* name, const uchar* icon); ~_BMethodAddOn_(); - status_t SetName(const char *name); - status_t SetIcon(const uchar *icon); - status_t SetMenu(const BMenu *menu, const BMessenger &messenger); + status_t SetName(const char* name); + 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; + + private: + BInputServerMethod* fMethod; + char* fName; uchar fIcon[16*16*1]; - const BMenu *fMenu; + const BMenu* fMenu; BMessenger fMessenger; }; -class KeymapMethod : public BInputServerMethod -{ -public: - KeymapMethod(); - ~KeymapMethod(); +class KeymapMethod : public BInputServerMethod { + public: + KeymapMethod(); + ~KeymapMethod(); }; -/*****************************************************************************/ -// InputServer -// -// Application class for input_server. -/*****************************************************************************/ +class InputServer : public BApplication { + public: + InputServer(); + virtual ~InputServer(); -class InputServer : public BApplication -{ - typedef BApplication Inherited; -public: - InputServer(void); - virtual ~InputServer(void); + virtual void ArgvReceived(int32 argc, char** argv); - virtual void ArgvReceived(long, char**); + virtual bool QuitRequested(); + virtual void ReadyToRun(); + virtual void MessageReceived(BMessage* message); - void InitKeyboardMouseStates(void); + void HandleSetMethod(BMessage* message); + status_t HandleGetSetMouseType(BMessage* message, BMessage* reply); + status_t HandleGetSetMouseAcceleration(BMessage* message, BMessage* reply); + status_t HandleGetSetKeyRepeatDelay(BMessage* message, BMessage* reply); + status_t HandleGetKeyInfo(BMessage* message, BMessage* reply); + status_t HandleGetModifiers(BMessage* message, BMessage* reply); + status_t HandleSetModifierKey(BMessage* message, BMessage* reply); + status_t HandleSetKeyboardLocks(BMessage* message, BMessage* reply); + status_t HandleGetSetMouseSpeed(BMessage* message, BMessage* reply); + status_t HandleSetMousePosition(BMessage* message, BMessage* reply); + status_t HandleGetSetMouseMap(BMessage* message, BMessage* reply); + status_t HandleGetKeyboardID(BMessage* message, BMessage* reply); + status_t HandleGetSetClickSpeed(BMessage* message, BMessage* reply); + status_t HandleGetSetKeyRepeatRate(BMessage* message, BMessage* reply); + status_t HandleGetSetKeyMap(BMessage* message, BMessage* reply); + status_t HandleFocusUnfocusIMAwareView(BMessage* message, BMessage* reply); - virtual bool QuitRequested(void); - virtual void ReadyToRun(void); - virtual void MessageReceived(BMessage*); + status_t EnqueueDeviceMessage(BMessage* message); + status_t EnqueueMethodMessage(BMessage* message); + status_t UnlockMethodQueue(); + status_t LockMethodQueue(); + status_t SetNextMethod(bool direction); + void SetActiveMethod(BInputServerMethod* method); + const BMessenger* MethodReplicant(); + void SetMethodReplicant(const BMessenger *replicant); + status_t EventLoop(); + bool EventLoopRunning(); - void HandleSetMethod(BMessage*); - status_t HandleGetSetMouseType(BMessage*, BMessage*); - status_t HandleGetSetMouseAcceleration(BMessage*, BMessage*); - status_t HandleGetSetKeyRepeatDelay(BMessage*, BMessage*); - status_t HandleGetKeyInfo(BMessage*, BMessage*); - status_t HandleGetModifiers(BMessage*, BMessage*); - status_t HandleSetModifierKey(BMessage*, BMessage*); - status_t HandleSetKeyboardLocks(BMessage*, BMessage*); - status_t HandleGetSetMouseSpeed(BMessage*, BMessage*); - status_t HandleSetMousePosition(BMessage*, BMessage*); - status_t HandleGetSetMouseMap(BMessage*, BMessage*); - status_t HandleGetKeyboardID(BMessage*, BMessage*); - status_t HandleGetSetClickSpeed(BMessage*, BMessage*); - status_t HandleGetSetKeyRepeatRate(BMessage*, BMessage*); - status_t HandleGetSetKeyMap(BMessage*, BMessage*); - status_t HandleFocusUnfocusIMAwareView(BMessage*, BMessage*); + bool DispatchEvents(BList* eventList); + status_t DispatchEvent(BMessage* event); + bool CacheEvents(BList* eventList); + const BList* GetNextEvents(BList*); + bool FilterEvents(BList* eventList); + bool SanitizeEvents(BList* eventList); + bool MethodizeEvents(BList* eventList, bool); - status_t EnqueueDeviceMessage(BMessage*); - status_t EnqueueMethodMessage(BMessage*); - status_t UnlockMethodQueue(void); - status_t LockMethodQueue(void); - status_t SetNextMethod(bool); - void SetActiveMethod(BInputServerMethod*); - const BMessenger* MethodReplicant(void); - void SetMethodReplicant(const BMessenger *); - status_t EventLoop(); - bool EventLoopRunning(void); + status_t GetDeviceInfo(const char* name, input_device_type *_type, + bool *_isRunning = NULL); + status_t UnregisterDevices(BInputServerDevice& serverDevice, + input_device_ref** devices = NULL); + status_t RegisterDevices(BInputServerDevice& serverDevice, + input_device_ref** devices); + status_t StartStopDevices(const char* name, input_device_type type, + bool doStart); + status_t StartStopDevices(BInputServerDevice& serverDevice, bool start); + status_t ControlDevices(const char *name, input_device_type type, + uint32 code, BMessage* message); - bool DispatchEvents(BList*); - int DispatchEvent(BMessage*); - bool CacheEvents(BList*); - const BList* GetNextEvents(BList*); - bool FilterEvents(BList*); - bool SanitizeEvents(BList*); - bool MethodizeEvents(BList*, bool); + bool DoMouseAcceleration(int32*, int32*); + bool SetMousePos(long*, long*, long, long); + bool SetMousePos(long*, long*, BPoint); + bool SetMousePos(long*, long*, float, float); - static status_t StartStopDevices(const char *name, input_device_type type, bool doStart); - static status_t StartStopDevices(BInputServerDevice *isd, bool); - static status_t ControlDevices(const char *, input_device_type, unsigned long, BMessage*); + bool SafeMode(); - bool DoMouseAcceleration(int32*, int32*); - bool SetMousePos(long*, long*, long, long); - bool SetMousePos(long*, long*, BPoint); - bool SetMousePos(long*, long*, float, float); + static BList gInputFilterList; + static BLocker gInputFilterListLocker; - bool SafeMode(void); + static BList gInputMethodList; + static BLocker gInputMethodListLocker; - static BList gInputDeviceList; - static BLocker gInputDeviceListLocker; + static DeviceManager gDeviceManager; + + static KeymapMethod gKeymapMethod; + + BRect& ScreenFrame() { return fFrame; } + + private: + typedef BApplication _inherited; + + status_t LoadKeymap(); + status_t LoadSystemKeymap(); + void _InitKeyboardMouseStates(); + + void WatchPort(); + + static int32 ISPortWatcher(void *arg); +// static bool doStartStopDevice(void*, void*); + InputDeviceListItem* _FindInputDeviceListItem(BInputServerDevice& device); + + private: + bool fEventLoopRunning; + bool fSafeMode; + port_id fEventPort; + + uint16 fKeyboardID; + + BList fInputDeviceList; + BLocker fInputDeviceListLocker; + + + KeyboardSettings fKeyboardSettings; + MouseSettings fMouseSettings; + + BPoint fMousePos; // current mouse position + key_info fKeyInfo; // current key info + key_map fKeys; // current key_map + char* fChars; // current keymap chars + uint32 fCharsSize; // current keymap char count + + port_id fEventLooperPort; + thread_id fISPortThread; + + AddOnManager* fAddOnManager; + + BList fEventsCache; + + BScreen fScreen; + BRect fFrame; + + BInputServerMethod* fActiveMethod; + BList fMethodQueue; + const BMessenger* fReplicantMessenger; + BottomlineWindow* fBLWindow; + bool fIMAware; - static BList gInputFilterList; - static BLocker gInputFilterListLocker; - - static BList gInputMethodList; - static BLocker gInputMethodListLocker; - - static DeviceManager gDeviceManager; - - static KeymapMethod gKeymapMethod; - - BRect& ScreenFrame() { return fFrame;}; -private: - status_t LoadKeymap(); - status_t LoadSystemKeymap(); - - bool sEventLoopRunning; - bool sSafeMode; - port_id sEventPort; - - uint16 sKeyboardID; - - KeyboardSettings fKeyboardSettings; - MouseSettings fMouseSettings; - - BPoint fMousePos; // current mouse position - key_info fKey_info; // current key info - key_map fKeys; // current key_map - char *fChars; // current keymap chars - uint32 fCharsSize; // current keymap char count - - port_id fEventLooperPort; - thread_id fISPortThread; - - static int32 ISPortWatcher(void *arg); - void WatchPort(); - - static bool doStartStopDevice(void*, void*); - - AddOnManager *fAddOnManager; - - BList fEventsCache; - - BScreen fScreen; - BRect fFrame; - - BInputServerMethod *fActiveMethod; - BList fMethodQueue; - const BMessenger *fReplicantMessenger; - BottomlineWindow *fBLWindow; - bool fIMAware; - #ifdef R5_CURSOR_COMM - sem_id fCursorSem; - port_id fAsPort; - area_id fCloneArea; - uint32 *fAppBuffer; + sem_id fCursorSem; + port_id fAsPort; + area_id fCloneArea; + uint32* fAppBuffer; #endif - + #if DEBUG == 2 -public: - static FILE *sLogFile; + public: + static FILE *sLogFile; #endif }; -#if DEBUG>=1 -#if DEBUG == 2 - #undef PRINT +extern InputServer* gInputServer; + +#if DEBUG >= 1 +# if DEBUG == 2 +# undef PRINT inline void _iprint(const char *fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); \ fputs(buf, InputServer::sLogFile); fflush(InputServer::sLogFile); } - #define PRINT(x) _iprint x +# define PRINT(x) _iprint x +# else +# undef PRINT +# define PRINT(x) SERIAL_PRINT(x) +# endif +# define PRINTERR(x) PRINT(x) +# define EXIT() PRINT(("EXIT %s\n", __PRETTY_FUNCTION__)) +# define CALLED() PRINT(("CALLED %s\n", __PRETTY_FUNCTION__)) #else - #undef PRINT - #define PRINT(x) SERIAL_PRINT(x) -#endif - #define PRINTERR(x) PRINT(x) - #define EXIT() PRINT(("EXIT %s\n", __PRETTY_FUNCTION__)) - #define CALLED() PRINT(("CALLED %s\n", __PRETTY_FUNCTION__)) -#else - #define EXIT() ((void)0) - #define CALLED() ((void)0) - #define PRINTERR(x) SERIAL_PRINT(x) +# define EXIT() ((void)0) +# define CALLED() ((void)0) +# define PRINTERR(x) SERIAL_PRINT(x) #endif -#endif +#endif /* INPUT_SERVER_APP_H */ diff --git a/src/servers/input/InputServerDevice.cpp b/src/servers/input/InputServerDevice.cpp index bda11d7cd0..1871ef668b 100644 --- a/src/servers/input/InputServerDevice.cpp +++ b/src/servers/input/InputServerDevice.cpp @@ -1,293 +1,110 @@ -/*****************************************************************************/ -// Haiku InputServer -// -// This is the InputServerDevice implementation -// -// This application and all source files used in its construction, except -// where noted, are licensed under the MIT License, and have been written -// and are: -// -// Copyright (c) 2002-2004 Haiku Project -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2002-2005, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + -#include -#include #include "InputServer.h" -/** - * Method: BInputServerDevice::BInputServerDevice() - * Descr: - */ +#include + + BInputServerDevice::BInputServerDevice() { fOwner = new _BDeviceAddOn_(this); } -/** - * Method: BInputServerDevice::~BInputServerDevice() - * Descr: - */ BInputServerDevice::~BInputServerDevice() { CALLED(); - // Lock this section of code so that access to the device list - // is serialized. Be sure to release the lock before exitting. - // - InputServer::gInputDeviceListLocker.Lock(); - - for (int i = InputServer::gInputDeviceList.CountItems() - 1; - i >= 0 && i < InputServer::gInputDeviceList.CountItems(); i--) { - - PRINT(("%s Device #%d\n", __PRETTY_FUNCTION__, i)); - InputDeviceListItem* item = (InputDeviceListItem*) InputServer::gInputDeviceList.ItemAt(i); - if (NULL != item && this == item->mIsd) { - if (item->mStarted) { - input_device_ref dev = item->mDev; - PRINT((" Stopping: %s\n", dev.name)); - Stop(dev.name, dev.cookie); - } - InputServer::gInputDeviceList.RemoveItem(i++); - delete item; - } - } - - InputServer::gInputDeviceListLocker.Unlock(); - + + gInputServer->UnregisterDevices(*this); delete fOwner; } -/** - * Method: BInputServerDevice::InitCheck() - * Descr: - */ status_t BInputServerDevice::InitCheck() { - return B_OK; -} - - -/** - * Method: BInputServerDevice::SystemShuttingDown() - * Descr: - */ -status_t -BInputServerDevice::SystemShuttingDown() -{ - return B_OK; -} - - -/** - * Method: BInputServerDevice::Start() - * Descr: - */ -status_t -BInputServerDevice::Start(const char *device, - void *cookie) -{ - return B_OK; -} - - -/** - * Method: BInputServerDevice::Stop() - * Descr: - */ -status_t -BInputServerDevice::Stop(const char *device, - void *cookie) -{ - return B_OK; -} - - -/** - * Method: BInputServerDevice::Control() - * Descr: - */ -status_t -BInputServerDevice::Control(const char *device, - void *cookie, - uint32 code, - BMessage *message) -{ - return B_OK; -} - - -/** - * Method: BInputServerDevice::RegisterDevices() - * Descr: - */ -status_t -BInputServerDevice::RegisterDevices(input_device_ref **devices) -{ - CALLED(); - - BAutolock lock(InputServer::gInputDeviceListLocker); - - input_device_ref *device = NULL; - for (int i = 0; NULL != (device = devices[i]); i++) { - if (device->type != B_POINTING_DEVICE - && device->type != B_KEYBOARD_DEVICE - && device->type != B_UNDEFINED_DEVICE) - continue; - - bool found = false; - for (int j = InputServer::gInputDeviceList.CountItems() - 1; j >= 0; j--) { - InputDeviceListItem* item = (InputDeviceListItem*)InputServer::gInputDeviceList.ItemAt(j); - if (!item) - continue; - - if (strcmp(device->name, item->mDev.name) == 0) { - found = true; - break; - } - } - - if (!found) { - PRINT(("RegisterDevices not found %s\n", device->name)); - InputServer::gInputDeviceList.AddItem(new InputDeviceListItem(this, *device) ); - InputServer::StartStopDevices(this, true); - } else { - PRINT(("RegisterDevices found %s\n", device->name)); - } - } - return B_OK; } -/** - * Method: BInputServerDevice::UnregisterDevices() - * Descr: - */ status_t -BInputServerDevice::UnregisterDevices(input_device_ref **devices) +BInputServerDevice::SystemShuttingDown() +{ + return B_OK; +} + + +status_t +BInputServerDevice::Start(const char* device, void* cookie) +{ + return B_OK; +} + + +status_t +BInputServerDevice::Stop(const char* device, void* cookie) +{ + return B_OK; +} + + +status_t +BInputServerDevice::Control(const char* device, void* cookie, + uint32 code, BMessage* message) +{ + return B_OK; +} + + +status_t +BInputServerDevice::RegisterDevices(input_device_ref** devices) +{ + CALLED(); + return gInputServer->RegisterDevices(*this, devices); +} + + +status_t +BInputServerDevice::UnregisterDevices(input_device_ref** devices) { CALLED(); - - BAutolock lock(InputServer::gInputDeviceListLocker); - - input_device_ref *device = NULL; - for (int i = 0; NULL != (device = devices[i]); i++) { - - for (int j = InputServer::gInputDeviceList.CountItems() - 1; j >= 0; j--) { - InputDeviceListItem* item = (InputDeviceListItem*)InputServer::gInputDeviceList.ItemAt(j); - if (!item) - continue; - - if (strcmp(device->name, item->mDev.name) == 0) { - Stop(item->mDev.name, item->mDev.cookie); - InputServer::gInputDeviceList.RemoveItem(j); - break; - } - } - } - - return B_OK; + // TODO: is this function supposed to remove devices that do not belong to this object? + // (at least that's what the previous implementation allowed for) + return gInputServer->UnregisterDevices(*this, devices); } -/** - * Method: BInputServerDevice::EnqueueMessage() - * Descr: - */ status_t -BInputServerDevice::EnqueueMessage(BMessage *message) +BInputServerDevice::EnqueueMessage(BMessage* message) { - return ((InputServer*)be_app)->EnqueueDeviceMessage(message); + return gInputServer->EnqueueDeviceMessage(message); } -/** - * Method: BInputServerDevice::StartMonitoringDevice() - * Descr: - */ status_t -BInputServerDevice::StartMonitoringDevice(const char *device) +BInputServerDevice::StartMonitoringDevice(const char* device) { CALLED(); PRINT(("StartMonitoringDevice %s\n", device)); - return InputServer::gDeviceManager.StartMonitoringDevice(fOwner, device); + return InputServer::gDeviceManager.StartMonitoringDevice(fOwner, device); } -/** - * Method: BInputServerDevice::StopMonitoringDevice() - * Descr: - */ status_t -BInputServerDevice::StopMonitoringDevice(const char *device) -{ - CALLED(); - return InputServer::gDeviceManager.StopMonitoringDevice(fOwner, device); -} - -/** -///////////////////////// Below this line is reserved functions ///////////////////////////// -*/ - - -/** - * Method: BInputServerDevice::_ReservedInputServerDevice1() - * Descr: - */ -void -BInputServerDevice::_ReservedInputServerDevice1() +BInputServerDevice::StopMonitoringDevice(const char* device) { + CALLED(); + return InputServer::gDeviceManager.StopMonitoringDevice(fOwner, device); } -/** - * Method: BInputServerDevice::_ReservedInputServerDevice2() - * Descr: - */ -void -BInputServerDevice::_ReservedInputServerDevice2() -{ -} - - -/** - * Method: BInputServerDevice::_ReservedInputServerDevice3() - * Descr: - */ -void -BInputServerDevice::_ReservedInputServerDevice3() -{ -} - - -/** - * Method: BInputServerDevice::_ReservedInputServerDevice4() - * Descr: - */ -void -BInputServerDevice::_ReservedInputServerDevice4() -{ -} - +void BInputServerDevice::_ReservedInputServerDevice1() {} +void BInputServerDevice::_ReservedInputServerDevice2() {} +void BInputServerDevice::_ReservedInputServerDevice3() {} +void BInputServerDevice::_ReservedInputServerDevice4() {}