xref: /haiku/src/tests/servers/input/view_input_device/ViewInputDevice.cpp (revision 24159a0c7d6d6dcba9f2a0c1a7c08d2c8167f21b)
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 
21 extern "C" _EXPORT BInputServerDevice* instantiate_input_device();
22 
23 class ViewInputDevice;
24 
25 class ViewInputDevice : public BInputServerDevice {
26 public:
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 
33 private:
34 	thread_id _Thread;
35 	static int32 _StartWatchPort(void *arg);
36 	void _WatchPort();
37 	port_id _Port;
38 };
39 
40 
41 BInputServerDevice* instantiate_input_device()
42 {
43 	return (new ViewInputDevice());
44 }
45 
46 
47 ViewInputDevice::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 
60 ViewInputDevice::~ViewInputDevice()
61 {
62 }
63 
64 
65 status_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 
78 status_t ViewInputDevice::Stop(const char *device, void *cookie)
79 {
80 	kill_thread(_Thread);
81 	_Port = -1;
82 	return (B_NO_ERROR);
83 }
84 
85 int32 ViewInputDevice::_StartWatchPort(void *arg)
86 {
87 	ViewInputDevice *self = (ViewInputDevice*)arg;
88 	self->_WatchPort();
89 	return (B_NO_ERROR);
90 }
91 
92 void 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