1//-------------------------------------------------------------------------
2// Handy InputDevice that queue all events from app_server's ViewHWInterface.
3//-------------------------------------------------------------------------
4/*
5	Copyright 1999, Be Incorporated.   All Rights Reserved.
6	This file may be used under the terms of the Be Sample Code License.
7*/
8
9#include <stdlib.h>
10#include <string.h>
11#include <unistd.h>
12
13#include <Debug.h>
14#include <FindDirectory.h>
15#include <InterfaceDefs.h>
16#include <Message.h>
17#include <OS.h>
18#include <add-ons/input_server/InputServerDevice.h>
19#include <SupportDefs.h>
20
21extern "C" _EXPORT BInputServerDevice* instantiate_input_device();
22
23class ViewInputDevice;
24
25class ViewInputDevice : public BInputServerDevice {
26public:
27	ViewInputDevice();
28	virtual ~ViewInputDevice();
29
30	virtual status_t Start(const char *device, void *cookie);
31	virtual	status_t Stop(const char *device, void *cookie);
32
33private:
34	thread_id _Thread;
35	static int32 _StartWatchPort(void *arg);
36	void _WatchPort();
37	port_id _Port;
38};
39
40
41BInputServerDevice* instantiate_input_device()
42{
43	return (new ViewInputDevice());
44}
45
46
47ViewInputDevice::ViewInputDevice()
48	: BInputServerDevice()
49{
50	input_device_ref *device[2];
51	input_device_ref mover = {"ViewInputDevice", B_POINTING_DEVICE, NULL};
52	device[0] = &mover;
53	device[1] = NULL;
54	_Port = -1;
55
56	RegisterDevices(device);
57}
58
59
60ViewInputDevice::~ViewInputDevice()
61{
62}
63
64
65status_t ViewInputDevice::Start(const char *device, void *cookie)
66{
67	_Port = find_port("ViewInputDevice");
68	if(_Port < 0) {
69		_sPrintf("ViewInputDevice: find_port error: (0x%x) %s\n",_Port,strerror(_Port));
70		return(_Port);
71	}
72	_Thread = spawn_thread(_StartWatchPort, device, B_REAL_TIME_DISPLAY_PRIORITY+4, this);
73	resume_thread(_Thread);
74	return (B_NO_ERROR);
75}
76
77
78status_t ViewInputDevice::Stop(const char *device, void *cookie)
79{
80	kill_thread(_Thread);
81	_Port = -1;
82	return (B_NO_ERROR);
83}
84
85int32 ViewInputDevice::_StartWatchPort(void *arg)
86{
87	ViewInputDevice *self = (ViewInputDevice*)arg;
88	self->_WatchPort();
89	return (B_NO_ERROR);
90}
91
92void ViewInputDevice::_WatchPort()
93{
94	int32 code;
95	ssize_t length;
96	char *buffer;
97	BMessage *event;
98	status_t err;
99
100	while (true) {
101		// Block until we find the size of the next message
102		length = port_buffer_size(_Port);
103		buffer = (char*)malloc(length);
104		event = NULL;
105		event = new BMessage();
106		err = read_port(_Port, &code, buffer, length);
107		if(err != length) {
108			if(err >= 0) {
109				_sPrintf("ViewInputDevice: failed to read full packet (read %u of %u)\n",err,length);
110			} else {
111				_sPrintf("ViewInputDevice: read_port error: (0x%x) %s\n",err,strerror(err));
112			}
113		} else if ((err = event->Unflatten(buffer)) < 0) {
114			_sPrintf("ViewInputDevice: (0x%x) %s\n",err,strerror(err));
115		} else {
116			EnqueueMessage(event);
117			event = NULL;
118		}
119		free( buffer);
120		if(event!=NULL) {
121			delete(event);
122			event = NULL;
123		}
124	}
125}
126
127