* 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
This commit is contained in:
Axel Dörfler
2005-11-15 15:35:36 +00:00
parent 44534147b1
commit 9514d2e5e6
5 changed files with 1043 additions and 1336 deletions
+150 -180
View File
@@ -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 <Autolock.h>
@@ -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();
+13 -6
View File
@@ -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 <Locker.h>
#include <Looper.h>
#include <InputServerDevice.h>
@@ -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;
File diff suppressed because it is too large Load Diff
+202 -204
View File
@@ -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 <Application.h>
#include <Debug.h>
#include <InputServerDevice.h>
#include <InputServerFilter.h>
#include <InputServerMethod.h>
#include "AddOnManager.h"
#include "BottomlineWindow.h"
#include "DeviceManager.h"
#include "MouseSettings.h"
#include "KeyboardSettings.h"
#include "MouseSettings.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <Locker.h>
#include <Application.h>
#include <Debug.h>
#include <FindDirectory.h>
#include <InputServerDevice.h>
#include <InputServerFilter.h>
#include <InputServerMethod.h>
#include <InterfaceDefs.h>
#include <Locker.h>
#include <Message.h>
#include <OS.h>
#include <Screen.h>
#include <SupportDefs.h>
#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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#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 */
+62 -245
View File
@@ -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 <Autolock.h>
#include <InputServerDevice.h>
#include "InputServer.h"
/**
* Method: BInputServerDevice::BInputServerDevice()
* Descr:
*/
#include <InputServerDevice.h>
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() {}