xref: /haiku/src/servers/input/InputServer.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
1 /*****************************************************************************/
2 // OpenBeOS InputServer
3 //
4 // Version: [0.0.5] [Development Stage]
5 //
6 // [Description]
7 //
8 //
9 // This application and all source files used in its construction, except
10 // where noted, are licensed under the MIT License, and have been written
11 // and are:
12 //
13 // Copyright (c) 2002 OpenBeOS Project
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a
16 // copy of this software and associated documentation files (the "Software"),
17 // to deal in the Software without restriction, including without limitation
18 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
19 // and/or sell copies of the Software, and to permit persons to whom the
20 // Software is furnished to do so, subject to the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be included
23 // in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31 // DEALINGS IN THE SOFTWARE.
32 /*****************************************************************************/
33 
34 
35 #include <stdio.h>
36 
37 #include "InputServer.h"
38 #include "Path.h"
39 #include "Directory.h"
40 #include "FindDirectory.h"
41 #include "Entry.h"
42 #include "Locker.h"
43 #include "Debug.h"
44 
45 #include "InputServerDeviceListEntry.h"
46 #include "InputServerFilterListEntry.h"
47 #include "InputServerMethodListEntry.h"
48 #include "Message.h"
49 
50 // include app_server headers for communication
51 
52 #include "PortLink.h"
53 #include "ServerProtocol.h"
54 
55 #define SERVER_PORT_NAME "OBappserver"
56 #define SERVER_INPUT_PORT "OBinputport"
57 #define X_VALUE "x"
58 #define Y_VALUE "y"
59 
60 
61 extern "C" void RegisterDevices(input_device_ref** devices)
62 {
63 	printf("RegisterDevices\n");
64 };
65 
66 
67 // Static InputServer member variables.
68 //
69 BList   InputServer::gInputDeviceList;
70 BLocker InputServer::gInputDeviceListLocker;
71 
72 BList InputServer::mInputServerDeviceList;
73 BList InputServer::mInputServerFilterList;
74 BList InputServer::mInputServerMethodList;
75 
76 
77 /*
78  *
79  */
80 int main()
81 {
82 	InputServer	*myInputServer;
83 
84 	myInputServer = new InputServer;
85 
86 	myInputServer->Run();
87 
88 	delete myInputServer;
89 }
90 
91 
92 /*
93  *  Method: InputServer::InputServer()
94  *   Descr:
95  */
96 InputServer::InputServer(void) : BApplication("application/x-vnd.OBOS-input_server")
97 {
98 	void *pointer;
99 
100 	EventLoop(pointer);
101 
102 	InitTestDevice();
103 
104 //	InitDevices();
105 	InitFilters();
106 	InitMethods();
107 }
108 
109 /*
110  *  Method: InputServer::InputServer()
111  *   Descr:
112  */
113 InputServer::~InputServer(void)
114 {
115 }
116 
117 
118 /*
119  *  Method: InputServer::ArgvReceived()
120  *   Descr:
121  */
122 void InputServer::ArgvReceived(int32 argc, char** argv)
123 {
124 	if (2 == argc)
125 	{
126 		if (0 == strcmp("-q", argv[1]) )
127 		{
128 			// :TODO: Shutdown and restart the InputServer.
129 			printf("InputServer::ArgvReceived - Restarting . . .\n");
130 			status_t   quit_status;
131 			//BMessenger msgr = BMessenger("application/x-vnd.OpenBeOS-input_server", -1, &quit_status);
132 			BMessenger msgr = BMessenger("application/x-vnd.OBOS-input_server", -1, &quit_status);
133 			if (B_OK == quit_status)
134 			{
135 				BMessage   msg  = BMessage(B_QUIT_REQUESTED);
136 				msgr.SendMessage(&msg);
137 			}
138 			else
139 			{
140 				printf("Unable to send Quit message to running InputServer.");
141 			}
142 		}
143 	}
144 }
145 
146 
147 /*
148  *  Method: InputServer::InitKeyboardMouseStates()
149  *   Descr:
150  */
151 void InputServer::InitKeyboardMouseStates(void)
152 {
153 	// This is where we read in the preferences data for the mouse and keyboard as well as
154 	// determine the screen resolution from the app_server and find the center of the screen
155 	// sMousePos is then set to the center of the screen.
156 
157 	sMousePos.x = 200;
158 	sMousePos.y = 200;
159 
160 }
161 
162 void InputServer::InitTestDevice()
163 {
164 	printf("InputServer::InitTestDevice - Enter\n");
165 	const char* path = "/boot/home/Projects/InputServer/ISD/nervous/nervous";
166 	printf("InputServer::InitTestDevice - Loading add-on . . .\n");
167 	image_id addon_image = load_add_on(path);
168 	if (B_ERROR != addon_image)
169 	{
170 		status_t            isd_status = B_NO_INIT;
171 		BInputServerDevice* (*func)()  = NULL;
172 		printf("InputServer::InitTestDevice - Resolving symbol . . .\n");
173 		if (B_OK == get_image_symbol(addon_image, "instantiate_input_device", B_SYMBOL_TYPE_TEXT, (void**)&func) )
174 		{
175 			printf("Found instantiate_input_device.\n");
176 			if (NULL != func)
177 			{
178 				BInputServerDevice* isd = (*func)();
179 				if (NULL != isd)
180 				{
181 					printf("InputServer::InitTestDevice - Calling InitCheck . . .\n");
182 					isd_status = isd->InitCheck();
183 					mInputServerDeviceList.AddItem(
184 						new InputServerDeviceListEntry(path, isd_status, isd) );
185 					if (B_OK == isd_status)
186 					{
187 						//printf("Starting Nervous . . .\n");
188 						//isd->Start("Nervous Device", NULL);
189 					}
190 					else
191 					{
192 						printf("InitCheck failed.\n");
193 					}
194 				}
195 			}
196 		}
197 		if (B_OK != isd_status)
198 		{
199 			// Free resources associated with ISD's
200 			// that failed to initialize.
201 			//
202 			//unload_add_on(addon_image);
203 		}
204 	}
205 	printf("InputServer::InitTestDevice - Exit\n");
206 }
207 
208 /*
209  *  Method: InputServer::InitDevices()
210  *   Descr:
211  */
212 void InputServer::InitDevices(void)
213 {
214 	BDirectory  dir;
215 	BPath       addon_dir;
216 	BPath       addon_path;
217 	BEntry      entry;
218 	directory_which addon_dirs[] =
219 	            {
220 	                B_BEOS_ADDONS_DIRECTORY,
221 	                B_COMMON_ADDONS_DIRECTORY,
222 	                B_USER_ADDONS_DIRECTORY
223 	            };
224 	const int   addon_dir_count = sizeof(addon_dirs) / sizeof(directory_which);
225 
226 	printf("InputServer::InitDevices - Enter\n");
227 
228 	// Find all Input Server Devices in each of the predefined
229 	// addon directories.
230 	//
231 	for (int i = 0; i < addon_dir_count; i++)
232 	{
233 		if (B_OK == find_directory(addon_dirs[i], &addon_dir) )
234 		{
235 			addon_dir.Append("input_server/devices");
236 			dir.SetTo(addon_dir.Path() );
237 			while (B_NO_ERROR == dir.GetNextEntry(&entry, false) )
238 			{
239 				entry.GetPath(&addon_path);
240 				printf("Adding %s . . .\n", addon_path.Path() );
241 				AddInputServerDevice(addon_path.Path() );
242 			}
243 		}
244 	}
245 	printf("InputServer::InitDevices - Exit\n");
246 }
247 
248 
249 /*
250  *  Method: InputServer::AddInputServerDevice()
251  *   Descr:
252  */
253 status_t InputServer::AddInputServerDevice(const char* path)
254 {
255 	image_id addon_image= load_add_on(path);
256 	if (B_ERROR != addon_image)
257 	{
258 		status_t            isd_status = B_NO_INIT;
259 		BInputServerDevice* (*func)()  = NULL;
260 		if (B_OK == get_image_symbol(addon_image, "instantiate_input_device", B_SYMBOL_TYPE_TEXT, (void**)&func) )
261 		{
262 			if (NULL != func)
263 			{
264 				/*
265 			    // :DANGER: Only reenable this section if this
266 			    //          InputServer can start and manage the
267 			    //          devices, otherwise the system will hang.
268 			    //
269 				BInputServerDevice* isd = (*func)();
270 				if (NULL != isd)
271 				{
272 					isd_status = isd->InitCheck();
273 					mInputServerDeviceList.AddItem(
274 						new InputServerDeviceListEntry(path, isd_status, isd) );
275 				}
276 				*/
277 				mInputServerDeviceList.AddItem(
278 					new InputServerDeviceListEntry(path, B_NO_INIT, NULL) );
279 			}
280 		}
281 		if (B_OK != isd_status)
282 		{
283 			// Free resources associated with ISD's
284 			// that failed to initialize.
285 			//
286 			unload_add_on(addon_image);
287 		}
288 	}
289 	return 0;
290 }
291 
292 
293 /*
294  *  Method: InputServer::InitFilters()
295  *   Descr:
296  */
297 void InputServer::InitFilters(void)
298 {
299 	BDirectory  dir;
300 	BPath       addon_dir;
301 	BPath       addon_path;
302 	BEntry      entry;
303 	directory_which addon_dirs[] =
304 	            {
305 	                B_BEOS_ADDONS_DIRECTORY,
306 	                B_COMMON_ADDONS_DIRECTORY,
307 	                B_USER_ADDONS_DIRECTORY
308 	            };
309 	const int   addon_dir_count = sizeof(addon_dirs) / sizeof(directory_which);
310 
311 	printf("InputServer::InitFilters - Enter\n");
312 
313 	// Find all Input Filters in each of the predefined
314 	// addon directories.
315 	//
316 	for (int i = 0; i < addon_dir_count; i++)
317 	{
318 		if (B_OK == find_directory(addon_dirs[i], &addon_dir) )
319 		{
320 			addon_dir.Append("input_server/filters");
321 			dir.SetTo(addon_dir.Path() );
322 			while (B_NO_ERROR == dir.GetNextEntry(&entry, false) )
323 			{
324 				entry.GetPath(&addon_path);
325 				printf("Adding %s . . .\n", addon_path.Path() );
326 				AddInputServerFilter(addon_path.Path() );
327 			}
328 		}
329 	}
330 	printf("InputServer::InitFilters - Exit\n");
331 }
332 
333 
334 /*
335  *  Method: InputServer::AddInputServerFilter()
336  *   Descr:
337  */
338 status_t InputServer::AddInputServerFilter(const char* path)
339 {
340 	image_id addon_image= load_add_on(path);
341 	if (B_ERROR != addon_image)
342 	{
343 		status_t            isf_status = B_NO_INIT;
344 		BInputServerFilter* (*func)()  = NULL;
345 		if (B_OK == get_image_symbol(addon_image, "instantiate_input_filter", B_SYMBOL_TYPE_TEXT, (void**)&func) )
346 		{
347 			if (NULL != func)
348 			{
349 				/*
350 			    // :DANGER: Only reenable this section if this
351 			    //          InputServer can start and manage the
352 			    //          filters, otherwise the system will hang.
353 			    //
354 				BInputFilter isf = (*func)();
355 				if (NULL != isf)
356 				{
357 					isf_status = isf->InitCheck();
358 					mInputServerFilterList.AddItem(
359 						new InputServerFilterListEntry(path, isf_status, isf );
360 				}
361 				*/
362 				mInputServerFilterList.AddItem(
363 					new InputServerFilterListEntry(path, B_NO_INIT, NULL) );
364 			}
365 		}
366 		if (B_OK != isf_status)
367 		{
368 			// Free resources associated with InputServerFilters
369 			// that failed to initialize.
370 			//
371 			unload_add_on(addon_image);
372 		}
373 	}
374 	return 0;
375 }
376 
377 
378 /*
379  *  Method: InputServer::InitMethods()
380  *   Descr:
381  */
382 void InputServer::InitMethods(void)
383 {
384 	BDirectory  dir;
385 	BPath       addon_dir;
386 	BPath       addon_path;
387 	BEntry      entry;
388 	directory_which addon_dirs[] =
389 	            {
390 	                B_BEOS_ADDONS_DIRECTORY,
391 	                B_COMMON_ADDONS_DIRECTORY,
392 	                B_USER_ADDONS_DIRECTORY
393 	            };
394 	const int   addon_dir_count = sizeof(addon_dirs) / sizeof(directory_which);
395 
396 	printf("InputServer::InitMethods - Enter\n");
397 
398 	// Find all Input Methods in each of the predefined
399 	// addon directories.
400 	//
401 	for (int i = 0; i < addon_dir_count; i++)
402 	{
403 		if (B_OK == find_directory(addon_dirs[i], &addon_dir) )
404 		{
405 			addon_dir.Append("input_server/methods");
406 			dir.SetTo(addon_dir.Path() );
407 			while (B_NO_ERROR == dir.GetNextEntry(&entry, false) )
408 			{
409 				entry.GetPath(&addon_path);
410 				printf("Adding %s . . .\n", addon_path.Path() );
411 				AddInputServerMethod(addon_path.Path() );
412 			}
413 		}
414 	}
415 	printf("InputServer::InitMethods - Exit\n");
416 }
417 
418 
419 /*
420  *  Method: InputServer::AddInputServerMethod()
421  *   Descr:
422  */
423 status_t InputServer::AddInputServerMethod(const char* path)
424 {
425 	image_id addon_image= load_add_on(path);
426 	if (B_ERROR != addon_image)
427 	{
428 		status_t            ism_status = B_NO_INIT;
429 		BInputServerMethod* (*func)()  = NULL;
430 		if (B_OK == get_image_symbol(addon_image, "instantiate_input_method", B_SYMBOL_TYPE_TEXT, (void**)&func) )
431 		{
432 			if (NULL != func)
433 			{
434 				/*
435 			    // :DANGER: Only reenable this section if this
436 			    //          InputServer can start and manage the
437 			    //          methods, otherwise the system will hang.
438 			    //
439 				BInputServerMethod ism = (*func)();
440 				if (NULL != ism)
441 				{
442 					ism_status = ism->InitCheck();
443 					mInputServerMethodList.AddItem(
444 						new InputServerMethodListEntry(path, ism_status, ism) );
445 				}
446 				*/
447 				mInputServerMethodList.AddItem(
448 					new InputServerMethodListEntry(path, B_NO_INIT, NULL) );
449 			}
450 		}
451 		if (B_OK != ism_status)
452 		{
453 			// Free resources associated with InputServerMethods
454 			// that failed to initialize.
455 			//
456 			unload_add_on(addon_image);
457 		}
458 	}
459 	return 0;
460 }
461 
462 
463 /*
464  *  Method: InputServer::QuitRequested()
465  *   Descr:
466  */
467 bool InputServer::QuitRequested(void)
468 {
469 	kill_thread(ISPortThread);
470 	delete_port(EventLooperPort);
471 	EventLooperPort = -1;
472 	return true;
473 }
474 
475 // ---------------------------------------------------------------
476 // InputServer::ReadyToRun(void)
477 //
478 // Verifies to see if the input_server is able to start.
479 //
480 //
481 // Parameters:
482 //		None
483 //
484 // Returns:
485 //		B_OK if the
486 // ---------------------------------------------------------------
487 void InputServer::ReadyToRun(void)
488 {
489 }
490 
491 
492 /*
493  *  Method: InputServer::MessageReceived()
494  *   Descr:
495  */
496 void InputServer::MessageReceived(BMessage *message)
497 {
498 	BMessenger *app_server;
499 	BMessage *reply = NULL;
500 
501 	switch(message->what)
502 	{
503 		case SET_METHOD:
504 		{
505 			//HandleSetMethod();
506 			break;
507 		}
508 		case GET_MOUSE_TYPE:
509 		{
510 			//HandleGetSetMouseType();
511 			break;
512 		}
513 		case SET_MOUSE_TYPE:
514 		{
515 			//HandleGetSetMouseType();
516 			break;
517 		}
518 		case GET_MOUSE_ACCELERATION:
519 		{
520 			//HandleGetSetMouseAcceleration();
521 			break;
522 		}
523 		case SET_MOUSE_ACCELERATION:
524 		{
525 			//HandleGetSetMouseAcceleration();
526 			break;
527 		}
528 		case GET_KEY_REPEAT_DELAY:
529 		{
530 			//HandleGetSetKeyRepeatDelay();
531 			break;
532 		}
533 		case SET_KEY_REPEAT_DELAY:
534 		{
535 			//HandleGetSetKeyRepeatDelay();
536 			break;
537 		}
538 		case GET_KEY_INFO:
539 		{
540 			//HandleGetKeyInfo();
541 			break;
542 		}
543 		case GET_MODIFIERS:
544 		{
545 			//HandleGetModifiers();
546 			break;
547 		}
548 		case SET_MODIFIER_KEY:
549 		{
550 			//HandleSetModifierKey();
551 			break;
552 		}
553 		case SET_KEYBOARD_LOCKS:
554 		{
555 			//HandleSetKeyboardLocks();
556 			break;
557 		}
558 		case GET_MOUSE_SPEED:
559 		{
560 			//HandleGetSetMouseSpeed();
561 			break;
562 		}
563 		case SET_MOUSE_SPEED:
564 		{
565 			//HandleGetSetMouseSpeed();
566 			break;
567 		}
568 		case SET_MOUSE_POSITION:
569 		{
570 			//HandleSetMousePosition();
571 			break;
572 		}
573 		case GET_MOUSE_MAP:
574 		{
575 			//HandleGetSetMouseMap();
576 			break;
577 		}
578 		case SET_MOUSE_MAP:
579 		{
580 			//HandleGetSetMouseMap();
581 			break;
582 		}
583 		case GET_KEYBOARD_ID:
584 		{
585 			//HandleGetKeyboardID();
586 			break;
587 		}
588 		case GET_CLICK_SPEED:
589 		{
590 			HandleGetClickSpeed(message, reply);
591 			break;
592 		}
593 		case SET_CLICK_SPEED:
594 		{
595 			HandleSetClickSpeed(message, reply);
596 			break;
597 		}
598 		case GET_KEY_REPEAT_RATE:
599 		{
600 			//HandleGetSetKeyRepeatRate();
601 			break;
602 		}
603 		case SET_KEY_REPEAT_RATE:
604 		{
605 			//HandleGetSetKeyRepeatRate();
606 			break;
607 		}
608 		case GET_KEY_MAP:
609 		{
610 			//HandleGetSetKeyMap();
611 			break;
612 		}
613 		case SET_KEY_MAP:
614 		{
615 			//HandleGetSetKeyMap();
616 			break;
617 		}
618 		case FOCUS_IM_AWARE_VIEW:
619 		{
620 			//HandleFocusUnfocusIMAwareView();
621 			break;
622 		}
623 		case UNFOCUS_IM_AWARE_VIEW:
624 		{
625 			//HandleFocusUnfocusIMAwareView();
626 			break;
627 		}
628 		case B_QUIT_REQUESTED:
629 		{
630 			QuitRequested();
631 		}
632 
633 		default:
634 		{
635 		printf("Default message . . .\n");
636 		app_server = new BMessenger("application/x-vnd.Be-APPS", -1, NULL);
637 		if (app_server->IsValid())
638 		{
639 			//app_server->SendMessage(message);
640 
641 		}
642 		delete app_server;
643 		break;
644 		}
645 	}
646 }
647 
648 
649 /*
650  *  Method: InputServer::HandleSetMethod()
651  *   Descr:
652  */
653 void InputServer::HandleSetMethod(BMessage *)
654 {
655 }
656 
657 
658 /*
659  *  Method: InputServer::HandleGetMouseType()
660  *   Descr:
661  */
662 void InputServer::HandleGetMouseType(BMessage* message,
663                                      BMessage* reply)
664 {
665 	status_t status = reply->AddInt32("mouse_type", sMouseType);
666 	message->SendReply(status, reply);
667 }
668 
669 
670 /*
671  *  Method: InputServer::HandleSetMouseType()
672  *   Descr:
673  */
674 void InputServer::HandleSetMouseType(BMessage* message,
675                                      BMessage* reply)
676 {
677 	message->FindInt32("mouse_type", &sMouseType);
678 	status_t status = ControlDevices(NULL, B_POINTING_DEVICE, B_MOUSE_TYPE_CHANGED, NULL);
679 	message->SendReply(status, reply);
680 }
681 
682 
683 /*
684  *  Method: InputServer::HandleGetMouseAcceleration()
685  *   Descr:
686  */
687 void InputServer::HandleGetMouseAcceleration(BMessage* message,
688                                              BMessage* reply)
689 {
690 	status_t status = reply->AddInt32("mouse_acceleration", sMouseAcceleration);
691 	message->SendReply(status, reply);
692 }
693 
694 
695 /*
696  *  Method: InputServer::HandleSetMouseAcceleration()
697  *   Descr:
698  */
699 void InputServer::HandleSetMouseAcceleration(BMessage* message,
700                                              BMessage* reply)
701 {
702 	message->FindInt32("mouse_acceleration", &sMouseAcceleration);
703 	status_t status = ControlDevices(NULL, B_POINTING_DEVICE, B_MOUSE_ACCELERATION_CHANGED, NULL);
704 	message->SendReply(status, reply);
705 }
706 
707 
708 /*
709  *  Method: InputServer::HandleGetKeyRepeatDelay()
710  *   Descr:
711  */
712 void InputServer::HandleGetKeyRepeatDelay(BMessage* message,
713                                           BMessage* reply)
714 {
715 	status_t status = reply->AddInt64("key_repeat_delay", sKeyRepeatDelay);
716 	message->SendReply(status, reply);
717 }
718 
719 
720 /*
721  *  Method: InputServer::HandleSetKeyRepeatDelay()
722  *   Descr:
723  */
724 void InputServer::HandleSetKeyRepeatDelay(BMessage* message,
725                                           BMessage* reply)
726 {
727 	message->FindInt64("key_repeat_delay", &sKeyRepeatDelay);
728 	status_t status = ControlDevices(NULL, B_KEYBOARD_DEVICE, B_KEY_REPEAT_DELAY_CHANGED, NULL);
729 	message->SendReply(status, reply);
730 }
731 
732 
733 /*
734  *  Method: InputServer::HandleGetKeyInfo()
735  *   Descr:
736  */
737 void InputServer::HandleGetKeyInfo(BMessage *,
738                               BMessage *)
739 {
740 }
741 
742 
743 /*
744  *  Method: InputServer::HandleGetModifiers()
745  *   Descr:
746  */
747 void InputServer::HandleGetModifiers(BMessage *,
748                                 BMessage *)
749 {
750 }
751 
752 
753 /*
754  *  Method: InputServer::HandleSetModifierKey()
755  *   Descr:
756  */
757 void InputServer::HandleSetModifierKey(BMessage *,
758                                   BMessage *)
759 {
760 }
761 
762 
763 /*
764  *  Method: InputServer::HandleSetKeyboardLocks()
765  *   Descr:
766  */
767 void InputServer::HandleSetKeyboardLocks(BMessage *,
768                                     BMessage *)
769 {
770 }
771 
772 
773 /*
774  *  Method: InputServer::HandleGetMouseSpeed()
775  *   Descr:
776  */
777 void InputServer::HandleGetMouseSpeed(BMessage* message,
778                                       BMessage* reply)
779 {
780 	status_t status = reply->AddInt32("mouse_speed", sMouseSpeed);
781 	message->SendReply(status, reply);
782 }
783 
784 
785 /*
786  *  Method: InputServer::HandleSetMouseSpeed()
787  *   Descr:
788  */
789 void InputServer::HandleSetMouseSpeed(BMessage* message,
790                                       BMessage* reply)
791 {
792 	message->FindInt32("mouse_speed", &sMouseSpeed);
793 	status_t status = ControlDevices(NULL, B_POINTING_DEVICE, B_MOUSE_SPEED_CHANGED, NULL);
794 	message->SendReply(status, reply);
795 }
796 
797 
798 /*
799  *  Method: InputServer::HandleSetMousePosition()
800  *   Descr:
801  */
802 void InputServer::HandleSetMousePosition(BMessage *message, BMessage *outbound)
803 {
804 
805 	// this assumes that both supplied pointers are identical
806 
807 	ASSERT(outbound == message);
808 
809 	sMousePos.x = 200;
810 	sMousePos.y = 200;
811 
812 	int32 xValue,
813 		  yValue;
814 
815     message->FindInt32("x",xValue);
816     printf("[HandleSetMousePosition] x = %lu:\n",xValue);
817 
818    	switch(message->what){
819    		case B_MOUSE_MOVED:{
820     		// get point and button from msg
821     		if((outbound->FindInt32(X_VALUE,&xValue) == B_OK) && (outbound->FindInt32(Y_VALUE,&yValue) == B_OK)){
822 				sMousePos.x += xValue;
823 				sMousePos.y += yValue;
824 				outbound->ReplaceInt32(X_VALUE,sMousePos.x);
825 				outbound->ReplaceInt32(Y_VALUE,sMousePos.y);
826 	   			}
827     		break;
828     		}
829    				// Should be some Mouse Down and Up code here ..
830    				// Along with some Key Down and up codes ..
831    		default:
832       		break;
833 
834 		}
835 }
836 
837 
838 /*
839  *  Method: InputServer::HandleGetMouseMap()
840  *   Descr:
841  */
842 void InputServer::HandleGetMouseMap(BMessage* message,
843                                     BMessage* reply)
844 {
845 	status_t status = reply->AddData("mouse_map", B_RAW_TYPE, &sMouseMap, sizeof(sMouseMap) );
846 	message->SendReply(status, reply);
847 }
848 
849 
850 /*
851  *  Method: InputServer::HandleSetMouseMap()
852  *   Descr:
853  */
854 void InputServer::HandleSetMouseMap(BMessage* message,
855                                     BMessage* reply)
856 {
857 	mouse_map* map;
858 	ssize_t    size;
859 	message->FindData("mouse_map", B_RAW_TYPE, (const void**)&map, &size);
860 	memcpy(&sMouseMap, map, sizeof(sMouseMap) );
861 	status_t status = ControlDevices(NULL, B_POINTING_DEVICE, B_MOUSE_MAP_CHANGED, NULL);
862 	message->SendReply(status, reply);
863 }
864 
865 
866 /*
867  *  Method: InputServer::HandleGetKeyboardID()
868  *   Descr:
869  */
870 void InputServer::HandleGetKeyboardID(BMessage *,
871                                       BMessage *)
872 {
873 }
874 
875 
876 /*
877  *  Method: InputServer::HandleGetClickSpeed()
878  *   Descr:
879  */
880 void InputServer::HandleGetClickSpeed(BMessage* message,
881                                       BMessage* reply)
882 {
883 	status_t status = reply->AddInt64("mouse_click_speed", sMouseClickSpeed);
884 	message->SendReply(status, reply);
885 }
886 
887 /*
888  *  Method: InputServer::HandleSetClickSpeed()
889  *   Descr:
890  */
891 void InputServer::HandleSetClickSpeed(BMessage* message,
892                                       BMessage* reply)
893 {
894 	message->FindInt64("mouse_click_speed", &sMouseClickSpeed);
895 	status_t status = ControlDevices(NULL, B_POINTING_DEVICE, B_CLICK_SPEED_CHANGED, NULL);
896 	message->SendReply(status, reply);
897 }
898 
899 
900 /*
901  *  Method: InputServer::HandleGetKeyRepeatRate()
902  *   Descr:
903  */
904 void InputServer::HandleGetKeyRepeatRate(BMessage* message,
905                                          BMessage* reply)
906 {
907 	status_t status = reply->AddInt32("key_repeat_rate", sKeyRepeatRate);
908 	message->SendReply(status, reply);
909 }
910 
911 
912 /*
913  *  Method: InputServer::HandleSetKeyRepeatRate()
914  *   Descr:
915  */
916 void InputServer::HandleSetKeyRepeatRate(BMessage* message,
917                                          BMessage* reply)
918 {
919 	message->FindInt32("key_repeat_rate", &sKeyRepeatRate);
920 	status_t status = ControlDevices(NULL, B_KEYBOARD_DEVICE, B_KEY_REPEAT_RATE_CHANGED, NULL);
921 	message->SendReply(status, reply);
922 }
923 
924 
925 /*
926  *  Method: InputServer::HandleGetSetKeyMap()
927  *   Descr:
928  */
929 void InputServer::HandleGetSetKeyMap(BMessage *,
930                                      BMessage *)
931 {
932 }
933 
934 
935 /*
936  *  Method: InputServer::HandleFocusUnfocusIMAwareView()
937  *   Descr:
938  */
939 void InputServer::HandleFocusUnfocusIMAwareView(BMessage *,
940                                            BMessage *)
941 {
942 }
943 
944 
945 /*
946  *  Method: InputServer::EnqueueDeviceMessage()
947  *   Descr:
948  */
949 status_t InputServer::EnqueueDeviceMessage(BMessage *message)
950 {
951 	//return (write_port(fEventPort, (int32)message, NULL, 0));
952 	return (write_port(EventLooperPort, (int32)message, NULL, 0));
953 }
954 
955 
956 /*
957  *  Method: InputServer::EnqueueMethodMessage()
958  *   Descr:
959  */
960 status_t InputServer::EnqueueMethodMessage(BMessage *)
961 {
962 	return 0;
963 }
964 
965 
966 /*
967  *  Method: InputServer::UnlockMethodQueue()
968  *   Descr:
969  */
970 status_t InputServer::UnlockMethodQueue(void)
971 {
972 	return 0;
973 }
974 
975 
976 /*
977  *  Method: InputServer::LockMethodQueue()
978  *   Descr:
979  */
980 status_t InputServer::LockMethodQueue(void)
981 {
982 	return 0;
983 }
984 
985 
986 /*
987  *  Method: InputServer::SetNextMethod()
988  *   Descr:
989  */
990 status_t InputServer::SetNextMethod(bool)
991 {
992 	return 0;
993 }
994 
995 
996 /*
997  *  Method: InputServer::SetActiveMethod()
998  *   Descr:
999  */
1000 /*
1001 InputServer::SetActiveMethod(_BMethodAddOn_ *)
1002 {
1003 	return 0;
1004 }
1005 */
1006 
1007 
1008 /*
1009  *  Method: InputServer::MethodReplicant()
1010  *   Descr:
1011  */
1012 const BMessenger* InputServer::MethodReplicant(void)
1013 {
1014 	return NULL;
1015 }
1016 
1017 
1018 /*
1019  *  Method: InputServer::EventLoop()
1020  *   Descr:
1021  */
1022 status_t InputServer::EventLoop(void *)
1023 {
1024 	printf("Starting event loop . . .\n");
1025 	EventLooperPort = create_port(100, "obos_is_event_port");
1026 	if(EventLooperPort < 0) {
1027 		_sPrintf("OBOS InputServer: create_port error: (0x%x) %s\n",EventLooperPort,strerror(EventLooperPort));
1028 	}
1029 	ISPortThread = spawn_thread(ISPortWatcher, "_input_server_event_loop_", B_REAL_TIME_DISPLAY_PRIORITY+3, this);
1030 	resume_thread(ISPortThread);
1031 
1032 	return 0;
1033 }
1034 
1035 
1036 /*
1037  *  Method: InputServer::EventLoopRunning()
1038  *   Descr:
1039  */
1040 bool InputServer::EventLoopRunning(void)
1041 {
1042 	return true;
1043 }
1044 
1045 
1046 /*
1047  *  Method: InputServer::DispatchEvents()
1048  *   Descr:
1049  */
1050 bool InputServer::DispatchEvents(BList *eventList)
1051 {
1052 BMessage *event;
1053 
1054 for ( int32 i = 0; NULL != (event = (BMessage *)eventList->ItemAt(i)); i++ )
1055 	{
1056 	// now we must send each event to the app_server
1057 	DispatchEvent(event);
1058 	}
1059 	return true;
1060 }// end DispatchEvents()
1061 
1062 int InputServer::DispatchEvent(BMessage *message)
1063 {
1064 	// variables
1065 	int32 xValue,
1066 		  yValue;
1067     uint32 buttons = 0;
1068 
1069     message->FindInt32("x",xValue);
1070     printf("[DispatchEvent] x = %lu:\n",xValue);
1071 
1072 	port_id pid = find_port(SERVER_INPUT_PORT);
1073    	PortLink *appsvrlink = new PortLink(pid);
1074    	switch(message->what){
1075    		case B_MOUSE_MOVED:{
1076     		// get point and button from msg
1077     		if((message->FindInt32(X_VALUE,&xValue) == B_OK) && (message->FindInt32(Y_VALUE,&yValue) == B_OK)){
1078     			int64 time=(int64)real_time_clock();
1079     			appsvrlink->SetOpCode(B_MOUSE_MOVED);
1080     			appsvrlink->Attach(&time,sizeof(int64));
1081     			appsvrlink->Attach((float)xValue);
1082     			appsvrlink->Attach((float)yValue);
1083     			message->FindInt32("buttons",buttons);
1084     			appsvrlink->Attach(&buttons,sizeof(int32));
1085     			appsvrlink->Flush();
1086     			printf("B_MOUSE_MOVED: x = %lu: y = %lu: time = %llu: buttons = %lu\n",xValue,yValue,time,buttons);
1087     			}
1088     		break;
1089     		}
1090    				// Should be some Mouse Down and Up code here ..
1091    				// Along with some Key Down and up codes ..
1092    		default:
1093       		break;
1094 
1095 		}
1096 	delete appsvrlink;
1097     return true;
1098 }
1099 
1100 /*
1101  *  Method: InputServer::CacheEvents()
1102  *   Descr:
1103  */
1104 bool InputServer::CacheEvents(BList *)
1105 {
1106 	return true;
1107 }
1108 
1109 
1110 /*
1111  *  Method: InputServer::GetNextEvents()
1112  *   Descr:
1113  */
1114 const BList* InputServer::GetNextEvents(BList *)
1115 {
1116 	return NULL;
1117 }
1118 
1119 
1120 /*
1121  *  Method: InputServer::FilterEvents()
1122  *  Descr:  This method applies all defined filters to each event in the
1123  *          supplied list.  The supplied list is modified to reflect the
1124  *          output of the filters.
1125  *          The method returns true if the filters were applied to all
1126  *          events without error and false otherwise.
1127  */
1128 bool InputServer::FilterEvents(BList *eventsToFilter)
1129 {
1130 	if (NULL != eventsToFilter)
1131 	{
1132 		BInputServerFilter* current_filter;
1133 		BMessage*           current_event;
1134 		int32               filter_index  = 0;
1135 		int32               event_index   = 0;
1136 
1137 		while (NULL != (current_filter = (BInputServerFilter*)mInputServerFilterList.ItemAt(filter_index) ) )
1138 		{
1139 			// Apply the current filter to all available event messages.
1140 			//
1141 			while (NULL != (current_event = (BMessage*)eventsToFilter->ItemAt(event_index) ) )
1142 			{
1143 				// Storage for new event messages generated by the filter.
1144 				//
1145 				BList out_list;
1146 
1147 				// Apply the current filter to the current event message.
1148 				//
1149 				filter_result result = current_filter->Filter(current_event, &out_list);
1150 				if (B_DISPATCH_MESSAGE == result)
1151 				{
1152 					// Use the result in current_message; ignore out_list.
1153 					//
1154 					event_index++;
1155 
1156 					// Free resources associated with items in out_list.
1157 					//
1158 					void* out_item;
1159 					for (int32 i = 0; NULL != (out_item = out_list.ItemAt(i) ); i++)
1160 					{
1161 						delete out_item;
1162 					}
1163 				}
1164 				else if (B_SKIP_MESSAGE == result)
1165 				{
1166 					// Use the result in out_list (if any); ignore current message.
1167 					//
1168 					eventsToFilter->RemoveItem(event_index);
1169 					eventsToFilter->AddList(&out_list, event_index);
1170 					event_index += out_list.CountItems();
1171 
1172 					// NOTE: eventsToFilter now owns out_list's items.
1173 				}
1174 				else
1175 				{
1176 					// Error - Free resources associated with items in out_list and return.
1177 					//
1178 					void* out_item;
1179 					for (int32 i = 0; NULL != (out_item = out_list.ItemAt(i) ); i++)
1180 					{
1181 						delete out_item;
1182 					}
1183 					return false;
1184 				}
1185 
1186 				// NOTE: The BList destructor frees out_lists's resources here.
1187 				//       It does NOT free the resources associated with out_list's
1188 				//       member items - those should either already be deleted or
1189 				//       should be owned by eventsToFilter.
1190 			}
1191 
1192 		} // while()
1193 
1194 		filter_index++;
1195 
1196 	} // while()
1197 
1198 	return true;
1199 }
1200 
1201 
1202 /*
1203  *  Method: InputServer::SanitizeEvents()
1204  *   Descr:
1205  */
1206 bool InputServer::SanitizeEvents(BList *)
1207 {
1208 	return true;
1209 }
1210 
1211 
1212 /*
1213  *  Method: InputServer::MethodizeEvents()
1214  *   Descr:
1215  */
1216 bool InputServer::MethodizeEvents(BList *,
1217                              bool)
1218 {
1219 	return true;
1220 }
1221 
1222 
1223 /*
1224  *  Method: InputServer::StartStopDevices()
1225  *   Descr:
1226  */
1227 status_t InputServer::StartStopDevices(const char*       deviceName,
1228                                        input_device_type deviceType,
1229                                        bool              doStart)
1230 {
1231 	printf("StartStopDevice: Enter\n");
1232 	for (int i = gInputDeviceList.CountItems() - 1; i >= 0; i--)
1233 	{
1234 		printf("Device #%d\n", i);
1235 		InputDeviceListItem* item = (InputDeviceListItem*)gInputDeviceList.ItemAt(i);
1236 		if (NULL != item)
1237 		{
1238 			BInputServerDevice* isd = item->mIsd;
1239 			input_device_ref*   dev = item->mDev;
1240 			printf("Hey\n");
1241 			if ( (NULL != isd) && (NULL != dev) )
1242 			{
1243 				printf("  Starting/stopping: %s\n", dev->name);
1244 				if (deviceType == dev->type)
1245 				{
1246 					if (doStart) isd->Start(dev->name, dev->cookie);
1247 					else          isd->Stop(dev->name, dev->cookie);
1248 				}
1249 			}
1250 		}
1251 	}
1252 	printf("StartStopDevice: Exit\n");
1253 
1254 	return B_OK;
1255 }
1256 
1257 
1258 /*
1259  *  Method: InputServer::ControlDevices()
1260  *   Descr:
1261  */
1262 status_t InputServer::ControlDevices(const char* deviceName,
1263                             input_device_type    deviceType,
1264                             unsigned long        command,
1265                             BMessage*            message)
1266 {
1267 	status_t status = B_OK;
1268 
1269 	for (int i = gInputDeviceList.CountItems() - 1; i >= 0; i--)
1270 	{
1271 		printf("ControlDevice #%d\n", i);
1272 		InputDeviceListItem* item = (InputDeviceListItem*)gInputDeviceList.ItemAt(i);
1273 		if (NULL != item)
1274 		{
1275 			BInputServerDevice* isd = item->mIsd;
1276 			input_device_ref*   dev = item->mDev;
1277 			if ( (NULL != isd) && (NULL != dev) )
1278 			{
1279 				printf("  Controlling: %s\n", dev->name);
1280 				if (deviceType == dev->type)
1281 				{
1282 					// :TODO: Descriminate based on Device Name also.
1283 
1284 					// :TODO: Pass non-NULL Device Name and Cookie.
1285 
1286 					status = isd->Control(NULL /*Name*/, NULL /*Cookie*/, command, message);
1287 				}
1288 			}
1289 		}
1290 	}
1291 
1292 	return status;
1293 }
1294 
1295 
1296 /*
1297  *  Method: InputServer::DoMouseAcceleration()
1298  *   Descr:
1299  */
1300 bool InputServer::DoMouseAcceleration(long *,
1301                                  long *)
1302 {
1303 	return true;
1304 }
1305 
1306 
1307 /*
1308  *  Method: InputServer::SetMousePos()
1309  *   Descr:
1310  */
1311 bool InputServer::SetMousePos(long *,
1312                          long *,
1313                          long,
1314                          long)
1315 {
1316 	return true;
1317 }
1318 
1319 
1320 /*
1321  *  Method: InputServer::SetMousePos()
1322  *   Descr:
1323  */
1324 bool InputServer::SetMousePos(long *,
1325                          long *,
1326                          BPoint)
1327 {
1328 	return true;
1329 }
1330 
1331 
1332 /*
1333  *  Method: InputServer::SetMousePos()
1334  *   Descr:
1335  */
1336 bool InputServer::SetMousePos(long *,
1337                          long *,
1338                          float,
1339                          float)
1340 {
1341 	return true;
1342 }
1343 
1344 
1345 /*
1346  *  Method: InputServer::SafeMode()
1347  *   Descr:
1348  */
1349 bool InputServer::SafeMode(void)
1350 {
1351 	return true;
1352 }
1353 
1354 int32 InputServer::ISPortWatcher(void *arg)
1355 {
1356 	InputServer *self = (InputServer*)arg;
1357 	self->WatchPort();
1358 	return (B_NO_ERROR);
1359 }
1360 
1361 void InputServer::WatchPort()
1362 {
1363 	int32     	code;
1364 	ssize_t    	length;
1365 	char		*buffer;
1366 	status_t  	err;
1367 
1368 	while (true) {
1369 		// Block until we find the size of the next message
1370 		length = port_buffer_size(EventLooperPort);
1371 		buffer = (char*)malloc(length);
1372 		printf("[Event Looper] BMessage Size = %lu\n", length);
1373 		//event = NULL;
1374 		BMessage *event = new BMessage();
1375 		err = read_port(EventLooperPort, &code, buffer, length);
1376 		if(err != length) {
1377 			if(err >= 0) {
1378 				printf("InputServer: failed to read full packet (read %lu of %lu)\n",err,length);
1379 			} else {
1380 				printf("InputServer: read_port error: (0x%lx) %s\n",err,strerror(err));
1381 			}
1382 		}else{
1383 
1384 			if ((err = event->Unflatten(buffer)) < 0) {
1385 				printf("[InputServer] Unflatten() error: (0x%lx) %s\n",err,strerror(err));
1386 			} else {
1387 			// This is where the message should be processed.
1388 			event->PrintToStream();
1389 
1390 			HandleSetMousePosition(event, event);
1391 
1392 			DispatchEvent(event);
1393 
1394 			//printf("Event writen to port\n");
1395 			delete(event);
1396 			}
1397 
1398 		}
1399 		free(buffer);
1400 		if(event!=NULL) {
1401 			//delete(event);
1402 			event = NULL;
1403 		}
1404 	}
1405 
1406 }
1407 
1408