xref: /haiku/src/add-ons/input_server/devices/mouse/MouseInputDevice.cpp (revision 53d77642d6390cbbd784872b12396ea863e990d8)
161d7deeeSJérôme Duval /*****************************************************************************/
261d7deeeSJérôme Duval // Mouse input server device addon
361d7deeeSJérôme Duval // Written by Stefano Ceccherini
461d7deeeSJérôme Duval //
561d7deeeSJérôme Duval // MouseInputDevice.cpp
661d7deeeSJérôme Duval //
761d7deeeSJérôme Duval // Copyright (c) 2004 Haiku Project
861d7deeeSJérôme Duval //
961d7deeeSJérôme Duval // Permission is hereby granted, free of charge, to any person obtaining a
1061d7deeeSJérôme Duval // copy of this software and associated documentation files (the "Software"),
1161d7deeeSJérôme Duval // to deal in the Software without restriction, including without limitation
1261d7deeeSJérôme Duval // the rights to use, copy, modify, merge, publish, distribute, sublicense,
1361d7deeeSJérôme Duval // and/or sell copies of the Software, and to permit persons to whom the
1461d7deeeSJérôme Duval // Software is furnished to do so, subject to the following conditions:
1561d7deeeSJérôme Duval //
1661d7deeeSJérôme Duval // The above copyright notice and this permission notice shall be included
1761d7deeeSJérôme Duval // in all copies or substantial portions of the Software.
1861d7deeeSJérôme Duval //
1961d7deeeSJérôme Duval // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2061d7deeeSJérôme Duval // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2161d7deeeSJérôme Duval // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2261d7deeeSJérôme Duval // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2361d7deeeSJérôme Duval // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2461d7deeeSJérôme Duval // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2561d7deeeSJérôme Duval // DEALINGS IN THE SOFTWARE.
2661d7deeeSJérôme Duval /*****************************************************************************/
2761d7deeeSJérôme Duval #include "MouseInputDevice.h"
2861d7deeeSJérôme Duval 
2961d7deeeSJérôme Duval #include <stdlib.h>
3061d7deeeSJérôme Duval #include <unistd.h>
3161d7deeeSJérôme Duval 
3261d7deeeSJérôme Duval const static uint32 kGetMouseMovements = 10099;
33*53d77642SJérôme Duval const static uint32 kGetMouseAccel = 10101;
34*53d77642SJérôme Duval const static uint32 kSetMouseAccel = 10102;
35*53d77642SJérôme Duval const static uint32 kSetMouseType = 10104;
36*53d77642SJérôme Duval const static uint32 kSetMouseMap = 10106;
37*53d77642SJérôme Duval const static uint32 kSetClickSpeed = 10108;
3861d7deeeSJérôme Duval 
3961d7deeeSJérôme Duval struct mouse_movement {
4061d7deeeSJérôme Duval   int32 ser_fd_index;
4161d7deeeSJérôme Duval   int32 buttons;
4261d7deeeSJérôme Duval   int32 xdelta;
4361d7deeeSJérôme Duval   int32 ydelta;
4461d7deeeSJérôme Duval   int32 click_count;
4561d7deeeSJérôme Duval   int32 mouse_mods;
4661d7deeeSJérôme Duval   int64 mouse_time;
4761d7deeeSJérôme Duval };
4861d7deeeSJérôme Duval 
4961d7deeeSJérôme Duval 
5061d7deeeSJérôme Duval extern "C"
5161d7deeeSJérôme Duval BInputServerDevice *
5261d7deeeSJérôme Duval instantiate_input_device()
5361d7deeeSJérôme Duval {
5461d7deeeSJérôme Duval 	return new MouseInputDevice();
5561d7deeeSJérôme Duval }
5661d7deeeSJérôme Duval 
5761d7deeeSJérôme Duval 
5861d7deeeSJérôme Duval MouseInputDevice::MouseInputDevice()
59*53d77642SJérôme Duval 	: 	fThread(-1),
60*53d77642SJérôme Duval 		fQuit(false)
6161d7deeeSJérôme Duval {
6261d7deeeSJérôme Duval 	fFd = open("dev/input/mouse/ps2/0", O_RDWR);
6361d7deeeSJérôme Duval 	if (fFd >= 0)
6461d7deeeSJérôme Duval 		fThread = spawn_thread(DeviceWatcher, "mouse watcher thread",
6561d7deeeSJérôme Duval 			B_NORMAL_PRIORITY, this);
6661d7deeeSJérôme Duval 
6761d7deeeSJérôme Duval 	fLogFile = fopen("/boot/home/device_log.log", "w");
6861d7deeeSJérôme Duval }
6961d7deeeSJérôme Duval 
7061d7deeeSJérôme Duval 
7161d7deeeSJérôme Duval MouseInputDevice::~MouseInputDevice()
7261d7deeeSJérôme Duval {
7361d7deeeSJérôme Duval 	if (fThread >= 0) {
7461d7deeeSJérôme Duval 		status_t dummy;
7561d7deeeSJérôme Duval 		wait_for_thread(fThread, &dummy);
7661d7deeeSJérôme Duval 	}
7761d7deeeSJérôme Duval 
7861d7deeeSJérôme Duval 	if (fFd >= 0)
7961d7deeeSJérôme Duval 		close(fFd);
8061d7deeeSJérôme Duval 
8161d7deeeSJérôme Duval 	fclose(fLogFile);
8261d7deeeSJérôme Duval }
8361d7deeeSJérôme Duval 
8461d7deeeSJérôme Duval 
8561d7deeeSJérôme Duval status_t
86*53d77642SJérôme Duval MouseInputDevice::InitFromSettings(uint32 opcode)
87*53d77642SJérôme Duval {
88*53d77642SJérôme Duval 	// retrieve current values
89*53d77642SJérôme Duval 
90*53d77642SJérôme Duval 	if (get_mouse_map(&fSettings.map)!=B_OK)
91*53d77642SJérôme Duval 		fprintf(stderr, "error when get_mouse_map\n");
92*53d77642SJérôme Duval 	else
93*53d77642SJérôme Duval 		ioctl(fFd, kSetMouseMap, &fSettings.map);
94*53d77642SJérôme Duval 
95*53d77642SJérôme Duval 	if (get_click_speed(&fSettings.click_speed)!=B_OK)
96*53d77642SJérôme Duval 		fprintf(stderr, "error when get_click_speed\n");
97*53d77642SJérôme Duval 	else
98*53d77642SJérôme Duval 		ioctl(fFd, kSetClickSpeed, &fSettings.click_speed);
99*53d77642SJérôme Duval 
100*53d77642SJérôme Duval 	if (get_mouse_speed(&fSettings.accel.speed)!=B_OK)
101*53d77642SJérôme Duval 		fprintf(stderr, "error when get_mouse_speed\n");
102*53d77642SJérôme Duval 	else {
103*53d77642SJérôme Duval 		if (get_mouse_acceleration(&fSettings.accel.accel_factor)!=B_OK)
104*53d77642SJérôme Duval 			fprintf(stderr, "error when get_mouse_acceleration\n");
105*53d77642SJérôme Duval 		else {
106*53d77642SJérôme Duval 			mouse_accel accel;
107*53d77642SJérôme Duval 			ioctl(fFd, kGetMouseAccel, &accel);
108*53d77642SJérôme Duval 			accel.speed = fSettings.accel.speed;
109*53d77642SJérôme Duval 			accel.accel_factor = fSettings.accel.accel_factor;
110*53d77642SJérôme Duval 			ioctl(fFd, kSetMouseAccel, &fSettings.accel);
111*53d77642SJérôme Duval 		}
112*53d77642SJérôme Duval 	}
113*53d77642SJérôme Duval 
114*53d77642SJérôme Duval 	if (get_mouse_type(&fSettings.type)!=B_OK)
115*53d77642SJérôme Duval 		fprintf(stderr, "error when get_mouse_type\n");
116*53d77642SJérôme Duval 	else
117*53d77642SJérôme Duval 		ioctl(fFd, kSetMouseType, &fSettings.type);
118*53d77642SJérôme Duval 
119*53d77642SJérôme Duval 	return B_OK;
120*53d77642SJérôme Duval }
121*53d77642SJérôme Duval 
122*53d77642SJérôme Duval 
123*53d77642SJérôme Duval status_t
12461d7deeeSJérôme Duval MouseInputDevice::InitCheck()
12561d7deeeSJérôme Duval {
126*53d77642SJérôme Duval 	InitFromSettings();
127*53d77642SJérôme Duval 
12861d7deeeSJérôme Duval 	input_device_ref mouse1 = { "Mouse 1", B_POINTING_DEVICE, (void *)this };
12961d7deeeSJérôme Duval 
13061d7deeeSJérôme Duval 	input_device_ref *devices[2] = { &mouse1, NULL };
13161d7deeeSJérôme Duval 
13261d7deeeSJérôme Duval 	if (fFd >= 0 && fThread >= 0) {
13361d7deeeSJérôme Duval 		RegisterDevices(devices);
13461d7deeeSJérôme Duval 		return BInputServerDevice::InitCheck();
13561d7deeeSJérôme Duval 	}
13661d7deeeSJérôme Duval 	return B_ERROR;
13761d7deeeSJérôme Duval }
13861d7deeeSJérôme Duval 
13961d7deeeSJérôme Duval 
14061d7deeeSJérôme Duval status_t
14161d7deeeSJérôme Duval MouseInputDevice::Start(const char *name, void *cookie)
14261d7deeeSJérôme Duval {
14361d7deeeSJérôme Duval 	fputs("Start(", fLogFile);
14461d7deeeSJérôme Duval 	fputs(name, fLogFile);
14561d7deeeSJérôme Duval 	fputs(")\n", fLogFile);
14661d7deeeSJérôme Duval 	resume_thread(fThread);
14761d7deeeSJérôme Duval 
14861d7deeeSJérôme Duval 	return B_OK;
14961d7deeeSJérôme Duval }
15061d7deeeSJérôme Duval 
15161d7deeeSJérôme Duval 
15261d7deeeSJérôme Duval status_t
15361d7deeeSJérôme Duval MouseInputDevice::Stop(const char *device, void *cookie)
15461d7deeeSJérôme Duval {
15561d7deeeSJérôme Duval 	fputs("Stop()\n", fLogFile);
15661d7deeeSJérôme Duval 
15761d7deeeSJérôme Duval 	suspend_thread(fThread);
15861d7deeeSJérôme Duval 
15961d7deeeSJérôme Duval 	return B_OK;
16061d7deeeSJérôme Duval }
16161d7deeeSJérôme Duval 
16261d7deeeSJérôme Duval 
16361d7deeeSJérôme Duval status_t
16461d7deeeSJérôme Duval MouseInputDevice::Control(const char *name, void *cookie,
16561d7deeeSJérôme Duval 						  uint32 command, BMessage *message)
16661d7deeeSJérôme Duval {
16761d7deeeSJérôme Duval 	fputs("Control()\n", fLogFile);
168*53d77642SJérôme Duval 
169*53d77642SJérôme Duval 	if (command == B_NODE_MONITOR)
170*53d77642SJérôme Duval 		HandleMonitor(message);
171*53d77642SJérôme Duval 	else if (command >= B_MOUSE_TYPE_CHANGED
172*53d77642SJérôme Duval 		&& command <= B_MOUSE_ACCELERATION_CHANGED) {
173*53d77642SJérôme Duval 		InitFromSettings(command);
174*53d77642SJérôme Duval 	}
175*53d77642SJérôme Duval 	return B_OK;
176*53d77642SJérôme Duval }
177*53d77642SJérôme Duval 
178*53d77642SJérôme Duval 
179*53d77642SJérôme Duval status_t
180*53d77642SJérôme Duval MouseInputDevice::HandleMonitor(BMessage *message)
181*53d77642SJérôme Duval {
18261d7deeeSJérôme Duval 	return B_OK;
18361d7deeeSJérôme Duval }
18461d7deeeSJérôme Duval 
18561d7deeeSJérôme Duval 
18661d7deeeSJérôme Duval int32
18761d7deeeSJérôme Duval MouseInputDevice::DeviceWatcher(void *arg)
18861d7deeeSJérôme Duval {
18961d7deeeSJérôme Duval 	MouseInputDevice *dev = (MouseInputDevice *)arg;
19061d7deeeSJérôme Duval 	mouse_movement movements;
19161d7deeeSJérôme Duval 	BMessage *message;
19261d7deeeSJérôme Duval 	char log[128];
19361d7deeeSJérôme Duval 	while (!dev->fQuit) {
19461d7deeeSJérôme Duval 		ioctl(dev->fFd, kGetMouseMovements, &movements);
19561d7deeeSJérôme Duval 
19661d7deeeSJérôme Duval 		// TODO: send B_MOUSE_UP/B_MOUSE_DOWN messages
19761d7deeeSJérôme Duval 
19861d7deeeSJérôme Duval 		message = new BMessage(B_MOUSE_MOVED);
19961d7deeeSJérôme Duval 		if (message) {
20061d7deeeSJérôme Duval 			message->AddInt32("buttons", movements.buttons);
20161d7deeeSJérôme Duval 			message->AddInt32("x", movements.xdelta);
20261d7deeeSJérôme Duval 			message->AddInt32("y", movements.ydelta);
20361d7deeeSJérôme Duval 			snprintf(log, 128, "buttons: %ld, x: %ld, y: %ld\n",
20461d7deeeSJérôme Duval 				movements.buttons, movements.xdelta, movements.ydelta);
20561d7deeeSJérôme Duval 
20661d7deeeSJérôme Duval 			fputs(log, dev->fLogFile);
20761d7deeeSJérôme Duval 
20861d7deeeSJérôme Duval 			dev->EnqueueMessage(message);
20961d7deeeSJérôme Duval 		}
21061d7deeeSJérôme Duval 		snooze(1000);
21161d7deeeSJérôme Duval 	}
21261d7deeeSJérôme Duval 
21361d7deeeSJérôme Duval 	return 0;
21461d7deeeSJérôme Duval }
21561d7deeeSJérôme Duval 
21661d7deeeSJérôme Duval 
217