* 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:
@@ -1,46 +1,42 @@
|
|||||||
/******************************************************************************
|
/*
|
||||||
/
|
* Copyright 2008 Haiku, Inc. All rights reserved.
|
||||||
/ File: InputServerDevice.h
|
* Distributed under the terms of the MIT License.
|
||||||
/
|
*/
|
||||||
/ Description: Add-on class for input_server devices.
|
|
||||||
/
|
|
||||||
/ Copyright 1998, Be Incorporated, All Rights Reserved.
|
|
||||||
/
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _INPUTSERVERDEVICE_H
|
#ifndef _INPUTSERVERDEVICE_H
|
||||||
#define _INPUTSERVERDEVICE_H
|
#define _INPUTSERVERDEVICE_H
|
||||||
|
|
||||||
#include <BeBuild.h>
|
|
||||||
#include <Input.h>
|
#include <Input.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Register your actual devices using this one - you can subclass
|
||||||
|
// this to suit your needs
|
||||||
struct input_device_ref {
|
struct input_device_ref {
|
||||||
char *name;
|
char* name;
|
||||||
input_device_type type;
|
input_device_type type; // see Input.h
|
||||||
void *cookie;
|
void* cookie;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// BInputServerDevice::Control() codes
|
||||||
enum {
|
enum {
|
||||||
// B_KEYBOARD_DEVICE notifications
|
// B_KEYBOARD_DEVICE notifications
|
||||||
B_KEY_MAP_CHANGED = 1,
|
B_KEY_MAP_CHANGED = 1,
|
||||||
B_KEY_LOCKS_CHANGED,
|
B_KEY_LOCKS_CHANGED,
|
||||||
B_KEY_REPEAT_DELAY_CHANGED,
|
B_KEY_REPEAT_DELAY_CHANGED,
|
||||||
B_KEY_REPEAT_RATE_CHANGED,
|
B_KEY_REPEAT_RATE_CHANGED,
|
||||||
|
|
||||||
// B_POINTING_DEVICE notifications
|
// B_POINTING_DEVICE notifications
|
||||||
B_MOUSE_TYPE_CHANGED,
|
B_MOUSE_TYPE_CHANGED,
|
||||||
B_MOUSE_MAP_CHANGED,
|
B_MOUSE_MAP_CHANGED,
|
||||||
B_MOUSE_SPEED_CHANGED,
|
B_MOUSE_SPEED_CHANGED,
|
||||||
B_CLICK_SPEED_CHANGED,
|
B_CLICK_SPEED_CHANGED,
|
||||||
B_MOUSE_ACCELERATION_CHANGED
|
B_MOUSE_ACCELERATION_CHANGED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
class _BDeviceAddOn_;
|
class DeviceAddOn;
|
||||||
|
}
|
||||||
|
|
||||||
class BInputServerDevice {
|
class BInputServerDevice {
|
||||||
public:
|
public:
|
||||||
@@ -50,30 +46,28 @@ public:
|
|||||||
virtual status_t InitCheck();
|
virtual status_t InitCheck();
|
||||||
virtual status_t SystemShuttingDown();
|
virtual status_t SystemShuttingDown();
|
||||||
|
|
||||||
virtual status_t Start(const char *device, void *cookie);
|
virtual status_t Start(const char* device, void* cookie);
|
||||||
virtual status_t Stop(const char *device, void *cookie);
|
virtual status_t Stop(const char* device, void* cookie);
|
||||||
virtual status_t Control(const char *device,
|
virtual status_t Control(const char* device, void* cookie, uint32 code,
|
||||||
void *cookie,
|
BMessage* message);
|
||||||
uint32 code,
|
|
||||||
BMessage *message);
|
|
||||||
|
|
||||||
status_t RegisterDevices(input_device_ref **devices);
|
status_t RegisterDevices(input_device_ref** devices);
|
||||||
status_t UnregisterDevices(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 StartMonitoringDevice(const char* device);
|
||||||
status_t StopMonitoringDevice(const char *device);
|
status_t StopMonitoringDevice(const char* device);
|
||||||
|
status_t AddDevices(const char* path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
_BDeviceAddOn_* fOwner;
|
|
||||||
|
|
||||||
virtual void _ReservedInputServerDevice1();
|
virtual void _ReservedInputServerDevice1();
|
||||||
virtual void _ReservedInputServerDevice2();
|
virtual void _ReservedInputServerDevice2();
|
||||||
virtual void _ReservedInputServerDevice3();
|
virtual void _ReservedInputServerDevice3();
|
||||||
virtual void _ReservedInputServerDevice4();
|
virtual void _ReservedInputServerDevice4();
|
||||||
|
|
||||||
|
BPrivate::DeviceAddOn* fOwner;
|
||||||
uint32 _reserved[4];
|
uint32 _reserved[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // _INPUTSERVERDEVICE_H
|
||||||
#endif
|
|
||||||
|
|||||||
+509
-360
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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Marcus Overhagen, Axel Dörfler
|
* Marcus Overhagen
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
* Jérôme Duval
|
* Jérôme Duval
|
||||||
*/
|
*/
|
||||||
#ifndef _ADD_ON_MANAGER_H
|
#ifndef ADD_ON_MANAGER_H
|
||||||
#define _ADD_ON_MANAGER_H
|
#define ADD_ON_MANAGER_H
|
||||||
|
|
||||||
// Manager for input_server add-ons (devices, filters, methods)
|
|
||||||
|
|
||||||
|
|
||||||
#include <InputServerDevice.h>
|
#include <InputServerDevice.h>
|
||||||
@@ -18,74 +17,114 @@
|
|||||||
#include <Locker.h>
|
#include <Locker.h>
|
||||||
#include <Looper.h>
|
#include <Looper.h>
|
||||||
|
|
||||||
#include "AddOnMonitor.h"
|
#include <AddOnMonitor.h>
|
||||||
#include "AddOnMonitorHandler.h"
|
#include <AddOnMonitorHandler.h>
|
||||||
#include "TList.h"
|
|
||||||
|
|
||||||
|
#include "PathList.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
class AddOnManager : public BLooper {
|
class AddOnManager : public BLooper {
|
||||||
public:
|
public:
|
||||||
AddOnManager(bool safeMode);
|
AddOnManager(bool safeMode);
|
||||||
~AddOnManager();
|
~AddOnManager();
|
||||||
|
|
||||||
void LoadState();
|
void LoadState();
|
||||||
void SaveState();
|
void SaveState();
|
||||||
void MessageReceived(BMessage *message);
|
|
||||||
|
|
||||||
private:
|
void MessageReceived(BMessage* message);
|
||||||
status_t RegisterAddOn(BEntry &entry);
|
|
||||||
status_t UnregisterAddOn(BEntry &entry);
|
|
||||||
void RegisterAddOns();
|
|
||||||
void UnregisterAddOns();
|
|
||||||
|
|
||||||
void RegisterDevice(BInputServerDevice *isd, const entry_ref &ref, image_id addon_image);
|
status_t StartMonitoringDevice(DeviceAddOn* addOn,
|
||||||
void RegisterFilter(BInputServerFilter *isf, const entry_ref &ref, image_id addon_image);
|
const char* device);
|
||||||
void RegisterMethod(BInputServerMethod *ism, const entry_ref &ref, image_id addon_image);
|
status_t StopMonitoringDevice(DeviceAddOn* addOn,
|
||||||
|
const char* device);
|
||||||
|
|
||||||
status_t HandleFindDevices(BMessage*, BMessage*);
|
private:
|
||||||
status_t HandleWatchDevices(BMessage*, BMessage*);
|
void _RegisterAddOns();
|
||||||
status_t HandleIsDeviceRunning(BMessage*, BMessage*);
|
void _UnregisterAddOns();
|
||||||
status_t HandleStartStopDevices(BMessage*, BMessage*);
|
|
||||||
status_t HandleControlDevices(BMessage*, BMessage*);
|
|
||||||
status_t HandleSystemShuttingDown(BMessage*, BMessage*);
|
|
||||||
status_t HandleMethodReplicant(BMessage*, BMessage*);
|
|
||||||
status_t HandleNodeMonitor(BMessage*);
|
|
||||||
|
|
||||||
void LoadReplicant();
|
status_t _RegisterAddOn(BEntry& entry);
|
||||||
void UnloadReplicant();
|
status_t _UnregisterAddOn(BEntry& entry);
|
||||||
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;
|
|
||||||
|
|
||||||
private:
|
bool _IsDevice(const char* path) const;
|
||||||
class InputServerMonitorHandler;
|
bool _IsFilter(const char* path) const;
|
||||||
friend class InputServerMonitorHandler;
|
bool _IsMethod(const char* path) const;
|
||||||
|
|
||||||
struct device_info {
|
status_t _RegisterDevice(BInputServerDevice* device,
|
||||||
entry_ref ref;
|
const entry_ref& ref, image_id image);
|
||||||
image_id addon_image;
|
status_t _RegisterFilter(BInputServerFilter* filter,
|
||||||
BInputServerDevice *device;
|
const entry_ref& ref, image_id image);
|
||||||
};
|
status_t _RegisterMethod(BInputServerMethod* method,
|
||||||
struct filter_info {
|
const entry_ref& ref, image_id image);
|
||||||
entry_ref ref;
|
|
||||||
image_id addon_image;
|
|
||||||
BInputServerFilter *filter;
|
|
||||||
};
|
|
||||||
struct method_info {
|
|
||||||
entry_ref ref;
|
|
||||||
image_id addon_image;
|
|
||||||
BInputServerMethod *method;
|
|
||||||
};
|
|
||||||
|
|
||||||
BLocker fLock;
|
status_t _HandleFindDevices(BMessage* message,
|
||||||
List<device_info> fDeviceList;
|
BMessage* reply);
|
||||||
List<filter_info> fFilterList;
|
status_t _HandleWatchDevices(BMessage* message,
|
||||||
List<method_info> fMethodList;
|
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;
|
void _LoadReplicant();
|
||||||
AddOnMonitor *fAddOnMonitor;
|
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;
|
BList InputServer::gInputMethodList;
|
||||||
BLocker InputServer::gInputMethodListLocker("is_method_queue_sem");
|
BLocker InputServer::gInputMethodListLocker("is_method_queue_sem");
|
||||||
|
|
||||||
DeviceManager InputServer::gDeviceManager;
|
|
||||||
|
|
||||||
KeymapMethod InputServer::gKeymapMethod;
|
KeymapMethod InputServer::gKeymapMethod;
|
||||||
|
|
||||||
|
|
||||||
@@ -180,8 +178,6 @@ InputServer::InputServer()
|
|||||||
fSafeMode = true;
|
fSafeMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gDeviceManager.LoadState();
|
|
||||||
|
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
if (has_data(find_thread(NULL))) {
|
if (has_data(find_thread(NULL))) {
|
||||||
PRINT(("HasData == YES\n"));
|
PRINT(("HasData == YES\n"));
|
||||||
@@ -218,8 +214,11 @@ InputServer::InputServer()
|
|||||||
|
|
||||||
_InitKeyboardMouseStates();
|
_InitKeyboardMouseStates();
|
||||||
|
|
||||||
fAddOnManager = new AddOnManager(SafeMode());
|
fAddOnManager = new(std::nothrow) ::AddOnManager(SafeMode());
|
||||||
fAddOnManager->LoadState();
|
if (fAddOnManager != NULL) {
|
||||||
|
fAddOnManager->Run();
|
||||||
|
fAddOnManager->LoadState();
|
||||||
|
}
|
||||||
|
|
||||||
BMessenger messenger(this);
|
BMessenger messenger(this);
|
||||||
BRoster().StartWatching(messenger, B_REQUEST_LAUNCHED);
|
BRoster().StartWatching(messenger, B_REQUEST_LAUNCHED);
|
||||||
@@ -229,8 +228,10 @@ InputServer::InputServer()
|
|||||||
InputServer::~InputServer()
|
InputServer::~InputServer()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
fAddOnManager->Lock();
|
if (fAddOnManager != NULL) {
|
||||||
fAddOnManager->Quit();
|
fAddOnManager->Lock();
|
||||||
|
fAddOnManager->Quit();
|
||||||
|
}
|
||||||
|
|
||||||
_ReleaseInput(NULL);
|
_ReleaseInput(NULL);
|
||||||
}
|
}
|
||||||
@@ -395,7 +396,6 @@ InputServer::QuitRequested()
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
fAddOnManager->SaveState();
|
fAddOnManager->SaveState();
|
||||||
gDeviceManager.SaveState();
|
|
||||||
|
|
||||||
delete_port(fEventLooperPort);
|
delete_port(fEventLooperPort);
|
||||||
// the event looper thread will exit after this
|
// 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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef INPUT_SERVER_APP_H
|
#ifndef INPUT_SERVER_APP_H
|
||||||
#define INPUT_SERVER_APP_H
|
#define INPUT_SERVER_APP_H
|
||||||
|
|
||||||
// #define DEBUG 1
|
|
||||||
|
|
||||||
#include "AddOnManager.h"
|
#include <stdlib.h>
|
||||||
#include "DeviceManager.h"
|
#include <string.h>
|
||||||
#include "KeyboardSettings.h"
|
#include <unistd.h>
|
||||||
#include "MouseSettings.h"
|
|
||||||
|
|
||||||
#include "shared_cursor_area.h"
|
//#define DEBUG 1
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
@@ -28,9 +26,12 @@
|
|||||||
#include <Screen.h>
|
#include <Screen.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <shared_cursor_area.h>
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
#include "AddOnManager.h"
|
||||||
|
#include "KeyboardSettings.h"
|
||||||
|
#include "MouseSettings.h"
|
||||||
|
#include "PathList.h"
|
||||||
|
|
||||||
|
|
||||||
#define INPUTSERVER_SIGNATURE "application/x-vnd.Be-input_server"
|
#define INPUTSERVER_SIGNATURE "application/x-vnd.Be-input_server"
|
||||||
@@ -65,15 +66,27 @@ class InputDeviceListItem {
|
|||||||
bool fRunning;
|
bool fRunning;
|
||||||
};
|
};
|
||||||
|
|
||||||
class _BDeviceAddOn_ {
|
namespace BPrivate {
|
||||||
public:
|
|
||||||
_BDeviceAddOn_(BInputServerDevice *device)
|
|
||||||
: fDevice(device) {}
|
|
||||||
|
|
||||||
BInputServerDevice* fDevice;
|
class DeviceAddOn {
|
||||||
BList fMonitoredRefs;
|
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_ {
|
class _BMethodAddOn_ {
|
||||||
public:
|
public:
|
||||||
_BMethodAddOn_(BInputServerMethod *method, const char* name,
|
_BMethodAddOn_(BInputServerMethod *method, const char* name,
|
||||||
@@ -109,7 +122,7 @@ class InputServer : public BApplication {
|
|||||||
|
|
||||||
virtual bool QuitRequested();
|
virtual bool QuitRequested();
|
||||||
virtual void ReadyToRun();
|
virtual void ReadyToRun();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
void HandleSetMethod(BMessage* message);
|
void HandleSetMethod(BMessage* message);
|
||||||
status_t HandleGetSetMouseType(BMessage* message, BMessage* reply);
|
status_t HandleGetSetMouseType(BMessage* message, BMessage* reply);
|
||||||
@@ -156,14 +169,14 @@ class InputServer : public BApplication {
|
|||||||
|
|
||||||
bool SafeMode();
|
bool SafeMode();
|
||||||
|
|
||||||
|
::AddOnManager* AddOnManager() { return fAddOnManager; }
|
||||||
|
|
||||||
static BList gInputFilterList;
|
static BList gInputFilterList;
|
||||||
static BLocker gInputFilterListLocker;
|
static BLocker gInputFilterListLocker;
|
||||||
|
|
||||||
static BList gInputMethodList;
|
static BList gInputMethodList;
|
||||||
static BLocker gInputMethodListLocker;
|
static BLocker gInputMethodListLocker;
|
||||||
|
|
||||||
static DeviceManager gDeviceManager;
|
|
||||||
|
|
||||||
static KeymapMethod gKeymapMethod;
|
static KeymapMethod gKeymapMethod;
|
||||||
|
|
||||||
BRect& ScreenFrame() { return fFrame; }
|
BRect& ScreenFrame() { return fFrame; }
|
||||||
@@ -215,7 +228,7 @@ class InputServer : public BApplication {
|
|||||||
|
|
||||||
port_id fEventLooperPort;
|
port_id fEventLooperPort;
|
||||||
|
|
||||||
AddOnManager* fAddOnManager;
|
::AddOnManager* fAddOnManager;
|
||||||
|
|
||||||
BScreen fScreen;
|
BScreen fScreen;
|
||||||
BRect fFrame;
|
BRect fFrame;
|
||||||
@@ -259,7 +272,7 @@ extern InputServer* gInputServer;
|
|||||||
# define PRINT(x) _iprint x
|
# define PRINT(x) _iprint x
|
||||||
# else
|
# else
|
||||||
# undef PRINT
|
# undef PRINT
|
||||||
# define PRINT(x) SERIAL_PRINT(x)
|
# define PRINT(x) SERIAL_PRINT(x)
|
||||||
# endif
|
# endif
|
||||||
# define PRINTERR(x) PRINT(x)
|
# define PRINTERR(x) PRINT(x)
|
||||||
# define EXIT() PRINT(("EXIT %s\n", __PRETTY_FUNCTION__))
|
# 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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "InputServer.h"
|
|
||||||
|
|
||||||
#include <InputServerDevice.h>
|
#include <InputServerDevice.h>
|
||||||
|
|
||||||
#include <new>
|
#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()
|
BInputServerDevice::BInputServerDevice()
|
||||||
{
|
{
|
||||||
fOwner = new (std::nothrow) _BDeviceAddOn_(this);
|
fOwner = new(std::nothrow) DeviceAddOn(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -94,15 +144,41 @@ BInputServerDevice::StartMonitoringDevice(const char* device)
|
|||||||
CALLED();
|
CALLED();
|
||||||
PRINT(("StartMonitoringDevice %s\n", device));
|
PRINT(("StartMonitoringDevice %s\n", device));
|
||||||
|
|
||||||
return InputServer::gDeviceManager.StartMonitoringDevice(fOwner, device);
|
return gInputServer->AddOnManager()->StartMonitoringDevice(fOwner, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BInputServerDevice::StopMonitoringDevice(const char* device)
|
BInputServerDevice::StopMonitoringDevice(const char* device)
|
||||||
{
|
{
|
||||||
CALLED();
|
return gInputServer->AddOnManager()->StopMonitoringDevice(fOwner, device);
|
||||||
return InputServer::gDeviceManager.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::_ReservedInputServerDevice2() {}
|
||||||
void BInputServerDevice::_ReservedInputServerDevice3() {}
|
void BInputServerDevice::_ReservedInputServerDevice3() {}
|
||||||
void BInputServerDevice::_ReservedInputServerDevice4() {}
|
void BInputServerDevice::_ReservedInputServerDevice4() {}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ Server input_server :
|
|||||||
InputServerMethod.cpp
|
InputServerMethod.cpp
|
||||||
|
|
||||||
AddOnManager.cpp
|
AddOnManager.cpp
|
||||||
DeviceManager.cpp
|
|
||||||
|
|
||||||
MouseSettings.cpp
|
MouseSettings.cpp
|
||||||
KeyboardSettings.cpp
|
KeyboardSettings.cpp
|
||||||
@@ -63,6 +62,8 @@ Server input_server :
|
|||||||
MethodMenuItem.cpp
|
MethodMenuItem.cpp
|
||||||
BottomlineWindow.cpp
|
BottomlineWindow.cpp
|
||||||
|
|
||||||
|
PathList.cpp
|
||||||
|
|
||||||
# storage
|
# storage
|
||||||
AddOnMonitor.cpp
|
AddOnMonitor.cpp
|
||||||
AddOnMonitorHandler.cpp
|
AddOnMonitorHandler.cpp
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
#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
|
|
||||||
Reference in New Issue
Block a user