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