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