* Rewrote InputServerDevice.h header.

* Renamed _BDeviceAddOn_ to DeviceAddOn, and put it into the BPrivate namespace.
* Moved the DeviceManager functionality into the AddOnManager - this also
  solves a locking issue, as BInputServerDevice::Control() was called in the
  context of the DeviceManager before.
* The AddOnManager now uses the BPathMonitor to monitor the devices that
  BInputServerDevices ask for - this greatly simplifies the code.
* Got rid of TList.h, and use ObjectList.h instead.
* Added PathList class that has a list of paths with reference count, used by
  DeviceAddOn and the AddOnManager.
* DeviceAddOn got an actual implementation that lives in InputServerDevice.cpp.
* Added an experimental BInputServerDevice::AddDevices() that could be used
  instead of recursing over devices manually. It replaces the functionality
  that was found in the DeviceManager before (this was done implicitely for
  all monitored devices).
* Greatly cleaned up and simplified the AddOnManager.
* Also fixed lots of potential errors/leaks when things go wrong.
* Removed the extra locker in AddOnManager - its BLooper lock is now used
  instead.
* Replaced PRINT()/PRINTERR() macros in the AddOnManager with TRACE(), and
  ERROR(), both now use debug_printf().
* Hopefully this fixes the problem that I don't have keyboard under VirtualBox
  from time to time.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28241 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-10-19 15:48:34 +00:00
parent ab42853558
commit 23debb05d0
12 changed files with 912 additions and 973 deletions

View File

@ -1,46 +1,42 @@
/******************************************************************************
/
/ File: InputServerDevice.h
/
/ Description: Add-on class for input_server devices.
/
/ Copyright 1998, Be Incorporated, All Rights Reserved.
/
******************************************************************************/
/*
* Copyright 2008 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _INPUTSERVERDEVICE_H
#define _INPUTSERVERDEVICE_H
#include <BeBuild.h>
#include <Input.h>
#include <SupportDefs.h>
// Register your actual devices using this one - you can subclass
// this to suit your needs
struct input_device_ref {
char *name;
input_device_type type;
void *cookie;
char* name;
input_device_type type; // see Input.h
void* cookie;
};
// BInputServerDevice::Control() codes
enum {
// B_KEYBOARD_DEVICE notifications
B_KEY_MAP_CHANGED = 1,
B_KEY_MAP_CHANGED = 1,
B_KEY_LOCKS_CHANGED,
B_KEY_REPEAT_DELAY_CHANGED,
B_KEY_REPEAT_DELAY_CHANGED,
B_KEY_REPEAT_RATE_CHANGED,
// B_POINTING_DEVICE notifications
B_MOUSE_TYPE_CHANGED,
B_MOUSE_TYPE_CHANGED,
B_MOUSE_MAP_CHANGED,
B_MOUSE_SPEED_CHANGED,
B_CLICK_SPEED_CHANGED,
B_MOUSE_ACCELERATION_CHANGED
B_MOUSE_ACCELERATION_CHANGED,
};
class _BDeviceAddOn_;
namespace BPrivate {
class DeviceAddOn;
}
class BInputServerDevice {
public:
@ -50,30 +46,28 @@ public:
virtual status_t InitCheck();
virtual status_t SystemShuttingDown();
virtual status_t Start(const char *device, void *cookie);
virtual status_t Stop(const char *device, void *cookie);
virtual status_t Control(const char *device,
void *cookie,
uint32 code,
BMessage *message);
virtual status_t Start(const char* device, void* cookie);
virtual status_t Stop(const char* device, void* cookie);
virtual status_t Control(const char* device, void* cookie, uint32 code,
BMessage* message);
status_t RegisterDevices(input_device_ref **devices);
status_t UnregisterDevices(input_device_ref **devices);
status_t RegisterDevices(input_device_ref** devices);
status_t UnregisterDevices(input_device_ref** devices);
status_t EnqueueMessage(BMessage *message);
status_t EnqueueMessage(BMessage* message);
status_t StartMonitoringDevice(const char *device);
status_t StopMonitoringDevice(const char *device);
status_t StartMonitoringDevice(const char* device);
status_t StopMonitoringDevice(const char* device);
status_t AddDevices(const char* path);
private:
_BDeviceAddOn_* fOwner;
virtual void _ReservedInputServerDevice1();
virtual void _ReservedInputServerDevice2();
virtual void _ReservedInputServerDevice3();
virtual void _ReservedInputServerDevice4();
BPrivate::DeviceAddOn* fOwner;
uint32 _reserved[4];
};
#endif
#endif // _INPUTSERVERDEVICE_H

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,14 @@
/*
* Copyright 2004-2005, Haiku, Inc. All rights reserved.
* Copyright 2004-2008, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Marcus Overhagen, Axel Dörfler
* Marcus Overhagen
* Axel Dörfler, axeld@pinc-software.de
* Jérôme Duval
*/
#ifndef _ADD_ON_MANAGER_H
#define _ADD_ON_MANAGER_H
// Manager for input_server add-ons (devices, filters, methods)
#ifndef ADD_ON_MANAGER_H
#define ADD_ON_MANAGER_H
#include <InputServerDevice.h>
@ -18,74 +17,114 @@
#include <Locker.h>
#include <Looper.h>
#include "AddOnMonitor.h"
#include "AddOnMonitorHandler.h"
#include "TList.h"
#include <AddOnMonitor.h>
#include <AddOnMonitorHandler.h>
#include "PathList.h"
using namespace BPrivate;
class AddOnManager : public BLooper {
public:
AddOnManager(bool safeMode);
~AddOnManager();
public:
AddOnManager(bool safeMode);
~AddOnManager();
void LoadState();
void SaveState();
void MessageReceived(BMessage *message);
void LoadState();
void SaveState();
private:
status_t RegisterAddOn(BEntry &entry);
status_t UnregisterAddOn(BEntry &entry);
void RegisterAddOns();
void UnregisterAddOns();
void MessageReceived(BMessage* message);
void RegisterDevice(BInputServerDevice *isd, const entry_ref &ref, image_id addon_image);
void RegisterFilter(BInputServerFilter *isf, const entry_ref &ref, image_id addon_image);
void RegisterMethod(BInputServerMethod *ism, const entry_ref &ref, image_id addon_image);
status_t StartMonitoringDevice(DeviceAddOn* addOn,
const char* device);
status_t StopMonitoringDevice(DeviceAddOn* addOn,
const char* device);
status_t HandleFindDevices(BMessage*, BMessage*);
status_t HandleWatchDevices(BMessage*, BMessage*);
status_t HandleIsDeviceRunning(BMessage*, BMessage*);
status_t HandleStartStopDevices(BMessage*, BMessage*);
status_t HandleControlDevices(BMessage*, BMessage*);
status_t HandleSystemShuttingDown(BMessage*, BMessage*);
status_t HandleMethodReplicant(BMessage*, BMessage*);
status_t HandleNodeMonitor(BMessage*);
private:
void _RegisterAddOns();
void _UnregisterAddOns();
void LoadReplicant();
void UnloadReplicant();
int32 GetReplicantAt(BMessenger target, int32 index) const;
status_t GetReplicantName(BMessenger target, int32 uid, BMessage *reply) const;
status_t GetReplicantView(BMessenger target, int32 uid, BMessage *reply) const;
status_t _RegisterAddOn(BEntry& entry);
status_t _UnregisterAddOn(BEntry& entry);
private:
class InputServerMonitorHandler;
friend class InputServerMonitorHandler;
bool _IsDevice(const char* path) const;
bool _IsFilter(const char* path) const;
bool _IsMethod(const char* path) const;
struct device_info {
entry_ref ref;
image_id addon_image;
BInputServerDevice *device;
};
struct filter_info {
entry_ref ref;
image_id addon_image;
BInputServerFilter *filter;
};
struct method_info {
entry_ref ref;
image_id addon_image;
BInputServerMethod *method;
};
status_t _RegisterDevice(BInputServerDevice* device,
const entry_ref& ref, image_id image);
status_t _RegisterFilter(BInputServerFilter* filter,
const entry_ref& ref, image_id image);
status_t _RegisterMethod(BInputServerMethod* method,
const entry_ref& ref, image_id image);
BLocker fLock;
List<device_info> fDeviceList;
List<filter_info> fFilterList;
List<method_info> fMethodList;
status_t _HandleFindDevices(BMessage* message,
BMessage* reply);
status_t _HandleWatchDevices(BMessage* message,
BMessage* reply);
status_t _HandleIsDeviceRunning(BMessage* message,
BMessage* reply);
status_t _HandleStartStopDevices(BMessage* message,
BMessage* reply);
status_t _HandleControlDevices(BMessage* message,
BMessage* reply);
status_t _HandleSystemShuttingDown(BMessage* message,
BMessage* reply);
status_t _HandleMethodReplicant(BMessage* message,
BMessage* reply);
void _HandleDeviceMonitor(BMessage* message);
AddOnMonitorHandler *fHandler;
AddOnMonitor *fAddOnMonitor;
void _LoadReplicant();
void _UnloadReplicant();
int32 _GetReplicantAt(BMessenger target,
int32 index) const;
status_t _GetReplicantName(BMessenger target,
int32 uid, BMessage* reply) const;
status_t _GetReplicantView(BMessenger target, int32 uid,
BMessage* reply) const;
bool fSafeMode;
status_t _AddDevicePath(DeviceAddOn* addOn,
const char* path, bool& newPath);
status_t _RemoveDevicePath(DeviceAddOn* addOn,
const char* path, bool& lastPath);
private:
class MonitorHandler;
friend class MonitorHandler;
template<typename T> struct add_on_info {
add_on_info()
:
image(-1), add_on(NULL)
{
}
~add_on_info()
{
delete add_on;
if (image >= 0)
unload_add_on(image);
}
entry_ref ref;
image_id image;
T* add_on;
};
typedef struct add_on_info<BInputServerDevice> device_info;
typedef struct add_on_info<BInputServerFilter> filter_info;
typedef struct add_on_info<BInputServerMethod> method_info;
BObjectList<device_info> fDeviceList;
BObjectList<filter_info> fFilterList;
BObjectList<method_info> fMethodList;
BObjectList<DeviceAddOn> fDeviceAddOns;
PathList fDevicePaths;
MonitorHandler* fHandler;
AddOnMonitor* fAddOnMonitor;
bool fSafeMode;
};
#endif // _ADD_ON_MANAGER_H
#endif // ADD_ON_MANAGER_H

View File

@ -1,292 +0,0 @@
/*
* Copyright 2004-2008, the Haiku project. All rights reserved.
* Distributed under the terms of the Haiku License.
*
* Authors:
* Marcus Overhagen, Axel Dörfler
* Jérôme Duval
*/
#include "DeviceManager.h"
#include <stdio.h>
#include <string.h>
#include <Autolock.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <image.h>
#include <Path.h>
#include <String.h>
#include "InputServer.h"
void
DeviceManager::MessageReceived(BMessage *msg)
{
CALLED();
if (msg->what == B_NODE_MONITOR) {
int32 opcode;
if (msg->FindInt32("opcode", &opcode) == B_OK) {
switch (opcode) {
case B_ENTRY_CREATED:
case B_ENTRY_REMOVED:
case B_ENTRY_MOVED:
{
node_ref dir_nref;
if (msg->FindInt32("device", &dir_nref.device) != B_OK
|| msg->FindInt64("directory", &dir_nref.node) != B_OK)
return;
_BDeviceAddOn_ *addon = NULL;
int32 i = 0;
while ((addon = GetAddOn(i++)) !=NULL) {
int32 j=0;
node_ref *dnref = NULL;
while ((dnref = (node_ref *)addon->fMonitoredRefs.ItemAt(j++)) != NULL) {
if (*dnref == dir_nref) {
addon->fDevice->Control(NULL, NULL, msg->what,
msg);
}
}
}
break;
}
case B_STAT_CHANGED:
case B_ATTR_CHANGED:
case B_DEVICE_MOUNTED:
case B_DEVICE_UNMOUNTED:
default:
BLooper::MessageReceived(msg);
break;
}
}
}
}
status_t
DeviceManager::AddDirectory(const node_ref *nref, _BDeviceAddOn_ *addon)
{
CALLED();
BDirectory directory(nref);
status_t status = directory.InitCheck();
if (status != B_OK)
return status;
status = watch_node(nref, B_WATCH_DIRECTORY, this);
if (status != B_OK)
return status;
BEntry entry;
while (directory.GetNextEntry(&entry, true) == B_OK) {
entry_ref ref;
entry.GetRef(&ref);
BMessage msg(B_NODE_MONITOR);
msg.AddInt32("opcode", B_ENTRY_CREATED);
msg.AddInt32("device", nref->device);
msg.AddInt64("directory", nref->node);
msg.AddString("name", ref.name);
addon->fDevice->Control(NULL, NULL, msg.what, &msg);
}
return B_OK;
}
status_t
DeviceManager::RemoveDirectory(const node_ref *nref, _BDeviceAddOn_ *addon)
{
CALLED();
BDirectory directory(nref);
status_t status = directory.InitCheck();
if (status != B_OK)
return status;
status = watch_node(nref, B_STOP_WATCHING, this);
if (status != B_OK)
return status;
BEntry entry;
while (directory.GetNextEntry(&entry, true) == B_OK) {
entry_ref ref;
entry.GetRef(&ref);
BMessage msg(B_NODE_MONITOR);
msg.AddInt32("opcode", B_ENTRY_REMOVED);
msg.AddInt32("device", nref->device);
msg.AddInt64("directory", nref->node);
msg.AddString("name", ref.name);
addon->fDevice->Control(NULL, NULL, msg.what, &msg);
}
return B_OK;
}
DeviceManager::DeviceManager()
:
fLock("device manager")
{
}
DeviceManager::~DeviceManager()
{
_BDeviceAddOn_ *addon = NULL;
while ((addon = (_BDeviceAddOn_ *)fDeviceAddons.RemoveItem((int32)0)) != NULL)
delete addon;
}
void
DeviceManager::LoadState()
{
CALLED();
if (!Lock())
return;
Run();
Unlock();
}
void
DeviceManager::SaveState()
{
}
status_t
DeviceManager::StartMonitoringDevice(_BDeviceAddOn_ *addon, const char *device)
{
CALLED();
status_t err;
node_ref nref;
BDirectory directory;
BPath path("/dev");
if ((err = path.Append(device)) != B_OK) {
PRINTERR(("DeviceManager::StartMonitoringDevice BPath::Append() error %s: %s\n", path.Path(), strerror(err)));
return err;
}
if ((err = directory.SetTo(path.Path())) != B_OK) {
if (err != B_ENTRY_NOT_FOUND) {
PRINTERR(("DeviceManager::StartMonitoringDevice SetTo error %s: %s\n", path.Path(), strerror(err)));
return err;
}
if ((err = create_directory(path.Path(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != B_OK
|| (err = directory.SetTo(path.Path())) != B_OK) {
PRINTERR(("DeviceManager::StartMonitoringDevice CreateDirectory error %s: %s\n", path.Path(), strerror(err)));
return err;
}
}
if ((err = directory.GetNodeRef(&nref)) != B_OK) {
PRINTERR(("DeviceManager::StartMonitoringDevice GetNodeRef error %s: %s\n", path.Path(), strerror(err)));
return err;
}
// test if already monitored
bool alreadyMonitored = false;
_BDeviceAddOn_ *tmpaddon = NULL;
int32 i = 0;
while ((tmpaddon = (_BDeviceAddOn_ *)fDeviceAddons.ItemAt(i++)) !=NULL) {
int32 j=0;
node_ref *dnref = NULL;
while ((dnref = (node_ref *)tmpaddon->fMonitoredRefs.ItemAt(j++)) != NULL) {
if (*dnref == nref) {
PRINT(("StartMonitoringDevice already monitored\n"));
alreadyMonitored = true;
break;
}
}
if (alreadyMonitored)
break;
}
// monitor if needed
if (!alreadyMonitored) {
if ((err = AddDirectory(&nref, addon)) != B_OK)
return err;
}
// add addon in list
if (!fDeviceAddons.HasItem(addon))
fDeviceAddons.AddItem(addon);
// add dir ref in list
int32 j=0;
node_ref *dnref = NULL;
alreadyMonitored = false;
while ((dnref = (node_ref *)addon->fMonitoredRefs.ItemAt(j++)) != NULL) {
if (*dnref == nref) {
alreadyMonitored = true;
break;
}
}
if (!alreadyMonitored)
addon->fMonitoredRefs.AddItem(new node_ref(nref));
return B_OK;
}
status_t
DeviceManager::StopMonitoringDevice(_BDeviceAddOn_ *addon, const char *device)
{
CALLED();
status_t err;
node_ref nref;
BDirectory directory;
BPath path("/dev");
if ((err = path.Append(device)) != B_OK
|| (err = directory.SetTo(path.Path())) != B_OK
|| (err = directory.GetNodeRef(&nref)) != B_OK)
return err;
// test if still monitored
bool stillMonitored = false;
_BDeviceAddOn_ *tmpaddon = NULL;
int32 i = 0;
while ((tmpaddon = (_BDeviceAddOn_ *)fDeviceAddons.ItemAt(i++)) != NULL) {
if (addon == tmpaddon)
continue;
int32 j=0;
node_ref *dnref = NULL;
while ((dnref = (node_ref *)tmpaddon->fMonitoredRefs.ItemAt(j++)) != NULL) {
if (*dnref == nref) {
stillMonitored = true;
break;
}
}
if (stillMonitored)
break;
}
// remove from list
node_ref *dnref = NULL;
int32 j = 0;
while ((dnref = (node_ref *)addon->fMonitoredRefs.ItemAt(j)) != NULL) {
if (*dnref == nref) {
addon->fMonitoredRefs.RemoveItem(j);
delete dnref;
break;
}
j++;
}
if (addon->fMonitoredRefs.IsEmpty())
fDeviceAddons.RemoveItem(addon);
// stop monitoring if needed
if (!stillMonitored) {
if ((err = RemoveDirectory(&nref, addon)) != B_OK)
return err;
}
return B_OK;
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2004-2008, the Haiku project. All rights reserved.
* Distributed under the terms of the Haiku License.
*
* Authors:
* Marcus Overhagen, Axel Dörfler
* Jérôme Duval
*/
#ifndef _DEVICE_MANAGER_H
#define _DEVICE_MANAGER_H
//! Manager for devices monitoring
#include <Handler.h>
#include <Looper.h>
#include <Locker.h>
#include <Node.h>
#include <InputServerDevice.h>
#include <InputServerFilter.h>
#include <InputServerMethod.h>
#include "TList.h"
class DeviceManager : public BLooper {
public:
DeviceManager();
virtual ~DeviceManager();
void LoadState();
void SaveState();
status_t StartMonitoringDevice(_BDeviceAddOn_ *addon,
const char *device);
status_t StopMonitoringDevice(_BDeviceAddOn_ *addon,
const char *device);
_BDeviceAddOn_ *GetAddOn(int32 index)
{ return (_BDeviceAddOn_*)
fDeviceAddons.ItemAt(index); }
virtual void MessageReceived(BMessage *msg);
private:
status_t AddDirectory(const node_ref *nref,
_BDeviceAddOn_ *addon);
status_t RemoveDirectory(const node_ref *nref,
_BDeviceAddOn_ *addon);
BList fDeviceAddons;
BLocker fLock;
};
#endif // _DEVICE_MANAGER_H

View File

@ -58,8 +58,6 @@ BLocker InputServer::gInputFilterListLocker("is_filter_queue_sem");
BList InputServer::gInputMethodList;
BLocker InputServer::gInputMethodListLocker("is_method_queue_sem");
DeviceManager InputServer::gDeviceManager;
KeymapMethod InputServer::gKeymapMethod;
@ -180,8 +178,6 @@ InputServer::InputServer()
fSafeMode = true;
}
gDeviceManager.LoadState();
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
if (has_data(find_thread(NULL))) {
PRINT(("HasData == YES\n"));
@ -218,8 +214,11 @@ InputServer::InputServer()
_InitKeyboardMouseStates();
fAddOnManager = new AddOnManager(SafeMode());
fAddOnManager->LoadState();
fAddOnManager = new(std::nothrow) ::AddOnManager(SafeMode());
if (fAddOnManager != NULL) {
fAddOnManager->Run();
fAddOnManager->LoadState();
}
BMessenger messenger(this);
BRoster().StartWatching(messenger, B_REQUEST_LAUNCHED);
@ -229,8 +228,10 @@ InputServer::InputServer()
InputServer::~InputServer()
{
CALLED();
fAddOnManager->Lock();
fAddOnManager->Quit();
if (fAddOnManager != NULL) {
fAddOnManager->Lock();
fAddOnManager->Quit();
}
_ReleaseInput(NULL);
}
@ -395,7 +396,6 @@ InputServer::QuitRequested()
return false;
} else {
fAddOnManager->SaveState();
gDeviceManager.SaveState();
delete_port(fEventLooperPort);
// the event looper thread will exit after this

View File

@ -1,18 +1,16 @@
/*
* Copyright 2001-2005, Haiku, Inc. All Rights Reserved.
* Copyright 2001-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef INPUT_SERVER_APP_H
#define INPUT_SERVER_APP_H
// #define DEBUG 1
#include "AddOnManager.h"
#include "DeviceManager.h"
#include "KeyboardSettings.h"
#include "MouseSettings.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "shared_cursor_area.h"
//#define DEBUG 1
#include <Application.h>
#include <Debug.h>
@ -28,9 +26,12 @@
#include <Screen.h>
#include <SupportDefs.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <shared_cursor_area.h>
#include "AddOnManager.h"
#include "KeyboardSettings.h"
#include "MouseSettings.h"
#include "PathList.h"
#define INPUTSERVER_SIGNATURE "application/x-vnd.Be-input_server"
@ -65,15 +66,27 @@ class InputDeviceListItem {
bool fRunning;
};
class _BDeviceAddOn_ {
public:
_BDeviceAddOn_(BInputServerDevice *device)
: fDevice(device) {}
namespace BPrivate {
BInputServerDevice* fDevice;
BList fMonitoredRefs;
class DeviceAddOn {
public:
DeviceAddOn(BInputServerDevice* device);
~DeviceAddOn();
bool HasPath(const char* path) const;
status_t AddPath(const char* path);
status_t RemovePath(const char* path);
int32 CountPaths() const;
BInputServerDevice* Device() { return fDevice; }
private:
BInputServerDevice* fDevice;
PathList fMonitoredPaths;
};
} // namespace BPrivate
class _BMethodAddOn_ {
public:
_BMethodAddOn_(BInputServerMethod *method, const char* name,
@ -109,7 +122,7 @@ class InputServer : public BApplication {
virtual bool QuitRequested();
virtual void ReadyToRun();
virtual void MessageReceived(BMessage* message);
virtual void MessageReceived(BMessage* message);
void HandleSetMethod(BMessage* message);
status_t HandleGetSetMouseType(BMessage* message, BMessage* reply);
@ -156,14 +169,14 @@ class InputServer : public BApplication {
bool SafeMode();
::AddOnManager* AddOnManager() { return fAddOnManager; }
static BList gInputFilterList;
static BLocker gInputFilterListLocker;
static BList gInputMethodList;
static BLocker gInputMethodListLocker;
static DeviceManager gDeviceManager;
static KeymapMethod gKeymapMethod;
BRect& ScreenFrame() { return fFrame; }
@ -215,7 +228,7 @@ class InputServer : public BApplication {
port_id fEventLooperPort;
AddOnManager* fAddOnManager;
::AddOnManager* fAddOnManager;
BScreen fScreen;
BRect fFrame;
@ -259,7 +272,7 @@ extern InputServer* gInputServer;
# define PRINT(x) _iprint x
# else
# undef PRINT
# define PRINT(x) SERIAL_PRINT(x)
# define PRINT(x) SERIAL_PRINT(x)
# endif
# define PRINTERR(x) PRINT(x)
# define EXIT() PRINT(("EXIT %s\n", __PRETTY_FUNCTION__))

View File

@ -1,18 +1,68 @@
/*
* Copyright 2002-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2002-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include "InputServer.h"
#include <InputServerDevice.h>
#include <new>
#include <Directory.h>
#include <Path.h>
#include "InputServer.h"
DeviceAddOn::DeviceAddOn(BInputServerDevice *device)
:
fDevice(device)
{
}
DeviceAddOn::~DeviceAddOn()
{
while (const char* path = fMonitoredPaths.PathAt(0)) {
gInputServer->AddOnManager()->StopMonitoringDevice(this, path);
}
}
bool
DeviceAddOn::HasPath(const char* path) const
{
return fMonitoredPaths.HasPath(path);
}
status_t
DeviceAddOn::AddPath(const char* path)
{
return fMonitoredPaths.AddPath(path);
}
status_t
DeviceAddOn::RemovePath(const char* path)
{
return fMonitoredPaths.RemovePath(path);
}
int32
DeviceAddOn::CountPaths() const
{
return fMonitoredPaths.CountPaths();
}
// #pragma mark -
BInputServerDevice::BInputServerDevice()
{
fOwner = new (std::nothrow) _BDeviceAddOn_(this);
fOwner = new(std::nothrow) DeviceAddOn(this);
}
@ -94,15 +144,41 @@ BInputServerDevice::StartMonitoringDevice(const char* device)
CALLED();
PRINT(("StartMonitoringDevice %s\n", device));
return InputServer::gDeviceManager.StartMonitoringDevice(fOwner, device);
return gInputServer->AddOnManager()->StartMonitoringDevice(fOwner, device);
}
status_t
BInputServerDevice::StopMonitoringDevice(const char* device)
{
CALLED();
return InputServer::gDeviceManager.StopMonitoringDevice(fOwner, device);
return gInputServer->AddOnManager()->StopMonitoringDevice(fOwner, device);
}
status_t
BInputServerDevice::AddDevices(const char* path)
{
BDirectory directory;
status_t status = directory.SetTo(path);
if (status != B_OK)
return status;
BEntry entry;
while (directory.GetNextEntry(&entry) == B_OK) {
BPath entryPath(&entry);
if (entry.IsDirectory()) {
AddDevices(entryPath.Path());
} else {
BMessage added(B_NODE_MONITOR);
added.AddInt32("opcode", B_ENTRY_CREATED);
added.AddString("path", entryPath.Path());
Control(NULL, NULL, B_INPUT_DEVICE_ADDED, &added);
}
}
return B_OK;
}
@ -110,4 +186,3 @@ void BInputServerDevice::_ReservedInputServerDevice1() {}
void BInputServerDevice::_ReservedInputServerDevice2() {}
void BInputServerDevice::_ReservedInputServerDevice3() {}
void BInputServerDevice::_ReservedInputServerDevice4() {}

View File

@ -54,7 +54,6 @@ Server input_server :
InputServerMethod.cpp
AddOnManager.cpp
DeviceManager.cpp
MouseSettings.cpp
KeyboardSettings.cpp
@ -63,6 +62,8 @@ Server input_server :
MethodMenuItem.cpp
BottomlineWindow.cpp
PathList.cpp
# storage
AddOnMonitor.cpp
AddOnMonitorHandler.cpp

View File

@ -0,0 +1,110 @@
/*
* Copyright 2008 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#include "PathList.h"
#include <new>
#include <string.h>
struct PathList::path_entry {
path_entry(const char* _path)
{
path = strdup(_path);
}
~path_entry()
{
free((char*)path);
}
const char* path;
int32 ref_count;
};
PathList::PathList()
:
fPaths(10, true)
{
}
PathList::~PathList()
{
}
bool
PathList::HasPath(const char* path, int32* _index) const
{
for (int32 i = fPaths.CountItems(); i-- > 0;) {
if (!strcmp(fPaths.ItemAt(i)->path, path)) {
if (_index != NULL)
*_index = i;
return true;
}
}
return false;
}
status_t
PathList::AddPath(const char* path)
{
if (path == NULL)
return B_BAD_VALUE;
int32 index;
if (HasPath(path, &index)) {
fPaths.ItemAt(index)->ref_count++;
return B_OK;
}
path_entry* entry = new(std::nothrow) path_entry(path);
if (entry == NULL || entry->path == NULL || !fPaths.AddItem(entry)) {
delete entry;
return B_NO_MEMORY;
}
return B_OK;
}
status_t
PathList::RemovePath(const char* path)
{
int32 index;
if (!HasPath(path, &index))
return B_ENTRY_NOT_FOUND;
if (--fPaths.ItemAt(index)->ref_count == 0)
delete fPaths.RemoveItemAt(index);
return B_OK;
}
int32
PathList::CountPaths() const
{
return fPaths.CountItems();
}
const char*
PathList::PathAt(int32 index) const
{
path_entry* entry = fPaths.ItemAt(index);
if (entry == NULL)
return NULL;
return entry->path;
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2008 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef PATH_LIST_H
#define PATH_LIST_H
#include <ObjectList.h>
class PathList {
public:
PathList();
~PathList();
bool HasPath(const char* path,
int32* _index = NULL) const;
status_t AddPath(const char* path);
status_t RemovePath(const char* path);
int32 CountPaths() const;
const char* PathAt(int32 index) const;
private:
struct path_entry;
BObjectList<path_entry> fPaths;
};
#endif // _DEVICE_MANAGER_H

View File

@ -1,129 +0,0 @@
#ifndef _MEDIA_T_LIST_H
#define _MEDIA_T_LIST_H
#include <Debug.h>
template<class value> class List
{
public:
List()
: item_max(INIT_COUNT),
item_count(0),
item_iter(-1),
items((value **)malloc(sizeof(value *) * INIT_COUNT))
{
ASSERT(items);
}
~List()
{
MakeEmpty();
free(items);
}
List(const List<value> &other)
{
*this = other;
}
List<value> &operator=(const List<value> &other)
{
MakeEmpty();
free(items);
item_max = other.item_max;
item_count = other.item_count;
items = (value **)malloc(sizeof(value *) * item_max);
ASSERT(items);
for (int i = 0; i < item_count; i++) {
items[i] = new value;
*items[i] = *other.items[i];
}
return *this;
}
bool Insert(const value &v)
{
if (item_count == item_max) {
item_max *= 2;
items = (value **)realloc(items, sizeof(value *) * item_max);
ASSERT(items);
}
items[item_count] = new value;
*items[item_count] = v;
item_count++;
return true;
}
bool Get(int32 index, value **v)
{
if (index < 0 || index >= item_count)
return false;
*v = items[index];
return true;
}
bool Remove(int32 index)
{
if (index < 0 || index >= item_count)
return false;
delete items[index];
item_count--;
items[index] = items[item_count];
if (index == item_iter)
item_iter--;
return true;
}
int Find(const value &v)
{
for (int i = 0; i < item_count; i++)
if (*items[i] == v)
return i;
return -1;
}
int CountItems()
{
return item_count;
}
bool IsEmpty()
{
return item_count == 0;
}
void MakeEmpty()
{
if (items != 0) {
for (int i = 0; i < item_count; i++) {
delete items[i];
}
item_count = 0;
}
}
void Rewind()
{
item_iter = -1;
}
bool GetNext(value **v)
{
item_iter++;
return Get(item_iter, v);
}
bool RemoveCurrent()
{
return Remove(item_iter);
}
private:
enum { INIT_COUNT=32 };
int item_max;
int item_count;
int item_iter;
value **items;
};
#endif // _MEDIA_T_LIST_H