* 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:
parent
ab42853558
commit
23debb05d0
@ -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
@ -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
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
||||
|
@ -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__))
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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
|
||||
|
110
src/servers/input/PathList.cpp
Normal file
110
src/servers/input/PathList.cpp
Normal 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;
|
||||
}
|
33
src/servers/input/PathList.h
Normal file
33
src/servers/input/PathList.h
Normal 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
|
@ -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
|
Loading…
Reference in New Issue
Block a user