1 /* 2 * Copyright 2002-2005, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "InputServer.h" 8 #include "InputServerTypes.h" 9 #include "BottomlineWindow.h" 10 #include "kb_mouse_driver.h" 11 #include "MethodReplicant.h" 12 13 #include <AppServerLink.h> 14 #include <MessagePrivate.h> 15 16 #include <Autolock.h> 17 #include <Deskbar.h> 18 #include <Directory.h> 19 #include <Entry.h> 20 #include <File.h> 21 #include <FindDirectory.h> 22 #include <Locker.h> 23 #include <Message.h> 24 #include <OS.h> 25 #include <Path.h> 26 #include <Roster.h> 27 #include <String.h> 28 #include <driver_settings.h> 29 30 #include <stdio.h> 31 32 #include "SystemKeymap.cpp" 33 // this is an automatically generated file 34 35 #include <ServerProtocol.h> 36 37 using std::nothrow; 38 39 40 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 41 extern "C" status_t _kern_get_safemode_option(const char *parameter, 42 char *buffer, size_t *_bufferSize); 43 #else 44 extern "C" status_t _kget_safemode_option_(const char *parameter, 45 char *buffer, size_t *_bufferSize); 46 #endif 47 48 49 // Global InputServer member variables. 50 51 InputServer* gInputServer; 52 53 BList InputServer::gInputFilterList; 54 BLocker InputServer::gInputFilterListLocker("is_filter_queue_sem"); 55 56 BList InputServer::gInputMethodList; 57 BLocker InputServer::gInputMethodListLocker("is_method_queue_sem"); 58 59 DeviceManager InputServer::gDeviceManager; 60 61 KeymapMethod InputServer::gKeymapMethod; 62 63 #if DEBUG == 2 64 FILE *InputServer::sLogFile = NULL; 65 #endif 66 67 68 extern "C" _EXPORT BView* instantiate_deskbar_item(); 69 70 71 InputDeviceListItem::InputDeviceListItem(BInputServerDevice& serverDevice, 72 input_device_ref& device) 73 : 74 fServerDevice(&serverDevice), 75 fDevice(device), 76 fRunning(false) 77 { 78 } 79 80 81 void 82 InputDeviceListItem::Start() 83 { 84 PRINT((" Starting: %s\n", fDevice.name)); 85 fServerDevice->Start(fDevice.name, fDevice.cookie); 86 fRunning = true; 87 } 88 89 90 void 91 InputDeviceListItem::Stop() 92 { 93 PRINT((" Stopping: %s\n", fDevice.name)); 94 fServerDevice->Stop(fDevice.name, fDevice.cookie); 95 fRunning = false; 96 } 97 98 99 void 100 InputDeviceListItem::Control(uint32 code, BMessage* message) 101 { 102 fServerDevice->Control(fDevice.name, fDevice.cookie, code, message); 103 } 104 105 106 bool 107 InputDeviceListItem::HasName(const char* name) const 108 { 109 if (name == NULL) 110 return false; 111 112 return !strcmp(name, fDevice.name); 113 } 114 115 116 bool 117 InputDeviceListItem::HasType(input_device_type type) const 118 { 119 return type == fDevice.type; 120 } 121 122 123 bool 124 InputDeviceListItem::Matches(const char* name, input_device_type type) const 125 { 126 if (name != NULL) 127 return HasName(name); 128 129 return HasType(type); 130 } 131 132 133 // #pragma mark - 134 135 136 InputServer::InputServer() 137 : BApplication(INPUTSERVER_SIGNATURE), 138 fSafeMode(false), 139 fInputDeviceListLocker("input server device list"), 140 fChars(NULL), 141 fScreen(B_MAIN_SCREEN_ID), 142 fInputMethodWindow(NULL), 143 fInputMethodAware(false), 144 fCursorSem(-1), 145 fAppServerPort(-1), 146 fCursorArea(-1) 147 { 148 #if DEBUG == 2 149 if (sLogFile == NULL) 150 sLogFile = fopen("/var/log/input_server.log", "a"); 151 #endif 152 153 CALLED(); 154 gInputServer = this; 155 156 _StartEventLoop(); 157 158 char parameter[32]; 159 size_t parameterLength = sizeof(parameter); 160 161 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 162 if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, parameter, ¶meterLength) == B_OK) 163 #else 164 if (_kget_safemode_option_(B_SAFEMODE_SAFE_MODE, parameter, ¶meterLength) == B_OK) 165 #endif 166 { 167 if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") 168 || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") 169 || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) 170 fSafeMode = true; 171 } 172 173 gDeviceManager.LoadState(); 174 175 #ifndef HAIKU_TARGET_PLATFORM_HAIKU 176 if (has_data(find_thread(NULL))) { 177 PRINT(("HasData == YES\n")); 178 int32 buffer[2]; 179 thread_id appThreadId; 180 memset(buffer, 0, sizeof(buffer)); 181 int32 code = receive_data(&appThreadId, buffer, sizeof(buffer)); 182 (void)code; // suppresses warning in non-debug build 183 PRINT(("tid : %ld, code :%ld\n", appThreadId, code)); 184 for (int32 i = 0; i < 2; i++) { 185 PRINT(("data : %lx\n", buffer[i])); 186 } 187 fCursorSem = buffer[0]; 188 area_id appArea = buffer[1]; 189 190 fCursorArea = clone_area("isClone", (void**)&fCursorBuffer, 191 B_ANY_ADDRESS, B_READ_AREA|B_WRITE_AREA, appArea); 192 if (fCursorArea < B_OK) { 193 PRINTERR(("clone_area error : %s\n", strerror(fCloneArea))); 194 } 195 196 fAppServerPort = create_port(100, "is_as"); 197 198 PRINT(("is_as port :%ld\n", fAppServerPort)); 199 200 buffer[1] = fEventLooperPort; 201 buffer[0] = fAppServerPort; 202 203 status_t err; 204 if ((err = send_data(appThreadId, 0, buffer, sizeof(buffer)))!=B_OK) 205 PRINTERR(("error when send_data %s\n", strerror(err))); 206 } 207 #endif 208 209 _InitKeyboardMouseStates(); 210 211 fAddOnManager = new AddOnManager(SafeMode()); 212 fAddOnManager->LoadState(); 213 214 BMessenger messenger(this); 215 BRoster().StartWatching(messenger, B_REQUEST_LAUNCHED); 216 } 217 218 219 InputServer::~InputServer() 220 { 221 CALLED(); 222 fAddOnManager->Lock(); 223 fAddOnManager->Quit(); 224 225 _ReleaseInput(NULL); 226 227 #if DEBUG == 2 228 fclose(sLogFile); 229 #endif 230 } 231 232 233 void 234 InputServer::ArgvReceived(int32 argc, char** argv) 235 { 236 CALLED(); 237 if (2 == argc && (0 == strcmp("-q", argv[1]))) { 238 PRINT(("InputServer::ArgvReceived - Restarting ...\n")); 239 status_t quit_status = B_OK; 240 BMessenger msgr = BMessenger(INPUTSERVER_SIGNATURE, -1, &quit_status); 241 if (B_OK == quit_status) { 242 msgr.SendMessage(B_QUIT_REQUESTED); 243 } else { 244 PRINTERR(("Unable to send Quit message to running InputServer.\n")); 245 } 246 } 247 } 248 249 250 void 251 InputServer::_InitKeyboardMouseStates() 252 { 253 CALLED(); 254 // This is where we determine the screen resolution from the app_server and find the center of the screen 255 // fMousePos is then set to the center of the screen. 256 257 fFrame = fScreen.Frame(); 258 if (fFrame == BRect(0, 0, 0, 0)) 259 fFrame = BRect(0, 0, 800, 600); 260 fMousePos = BPoint(fFrame.right / 2, fFrame.bottom / 2); 261 262 if (_LoadKeymap() != B_OK) 263 _LoadSystemKeymap(); 264 265 BMessage *msg = new BMessage(B_MOUSE_MOVED); 266 HandleSetMousePosition(msg, msg); 267 268 fActiveMethod = &gKeymapMethod; 269 } 270 271 272 status_t 273 InputServer::_LoadKeymap() 274 { 275 BPath path; 276 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK) 277 return B_BAD_VALUE; 278 279 path.Append("Key_map"); 280 281 entry_ref ref; 282 get_ref_for_path(path.Path(), &ref); 283 284 status_t err; 285 286 BFile file(&ref, B_READ_ONLY); 287 if ((err = file.InitCheck()) != B_OK) 288 return err; 289 290 if (file.Read(&fKeys, sizeof(fKeys)) < (ssize_t)sizeof(fKeys)) 291 return B_BAD_VALUE; 292 293 for (uint32 i = 0; i < sizeof(fKeys)/4; i++) 294 ((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]); 295 296 if (file.Read(&fCharsSize, sizeof(uint32)) < (ssize_t)sizeof(uint32)) 297 return B_BAD_VALUE; 298 299 fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize); 300 301 delete[] fChars; 302 fChars = new (nothrow) char[fCharsSize]; 303 if (fChars == NULL) 304 return B_NO_MEMORY; 305 306 if (file.Read(fChars, fCharsSize) != (signed)fCharsSize) 307 return B_BAD_VALUE; 308 309 return B_OK; 310 } 311 312 313 status_t 314 InputServer::_LoadSystemKeymap() 315 { 316 delete[] fChars; 317 fKeys = sSystemKeymap; 318 fCharsSize = sSystemKeyCharsSize; 319 fChars = new (nothrow) char[fCharsSize]; 320 if (fChars == NULL) 321 return B_NO_MEMORY; 322 323 memcpy(fChars, sSystemKeyChars, fCharsSize); 324 325 // we save this keymap to file 326 BPath path; 327 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 328 return B_BAD_VALUE; 329 330 path.Append("Key_map"); 331 332 entry_ref ref; 333 get_ref_for_path(path.Path(), &ref); 334 335 BFile file; 336 status_t err = file.SetTo(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 337 if (err != B_OK) { 338 PRINTERR(("error %s\n", strerror(err))); 339 return err; 340 } 341 342 for (uint32 i = 0; i < sizeof(fKeys) / 4; i++) { 343 ((uint32*)&fKeys)[i] = B_HOST_TO_BENDIAN_INT32(((uint32*)&fKeys)[i]); 344 } 345 346 if ((err = file.Write(&fKeys, sizeof(fKeys))) < (ssize_t)sizeof(fKeys)) 347 return err; 348 349 for (uint32 i = 0; i < sizeof(fKeys) / 4; i++) { 350 ((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]); 351 } 352 353 fCharsSize = B_HOST_TO_BENDIAN_INT32(fCharsSize); 354 355 if ((err = file.Write(&fCharsSize, sizeof(uint32))) < (ssize_t)sizeof(uint32)) 356 return B_BAD_VALUE; 357 358 fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize); 359 360 if ((err = file.Write(fChars, fCharsSize)) < (ssize_t)fCharsSize) 361 return err; 362 363 return B_OK; 364 } 365 366 367 bool 368 InputServer::QuitRequested() 369 { 370 CALLED(); 371 if (!BApplication::QuitRequested()) 372 return false; 373 374 PostMessage(SYSTEM_SHUTTING_DOWN); 375 376 fAddOnManager->SaveState(); 377 gDeviceManager.SaveState(); 378 379 delete_port(fEventLooperPort); 380 // the event looper thread will exit after this 381 fEventLooperPort = -1; 382 return true; 383 } 384 385 386 void 387 InputServer::ReadyToRun() 388 { 389 CALLED(); 390 391 // say hello to the app_server 392 393 BPrivate::AppServerLink link; 394 link.StartMessage(AS_REGISTER_INPUT_SERVER); 395 link.Flush(); 396 } 397 398 399 status_t 400 InputServer::_AcquireInput(BMessage& message, BMessage& reply) 401 { 402 // TODO: it currently just gets everything we have 403 area_id area; 404 if (message.FindInt32("cursor area", &area) == B_OK) { 405 // try to clone the area 406 fCursorBuffer = NULL; 407 408 fCursorSem = create_sem(0, "cursor semaphore"); 409 if (fCursorSem >= B_OK) { 410 fCursorArea = clone_area("input server cursor", (void**)&fCursorBuffer, 411 B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area); 412 } 413 } 414 415 fAppServerPort = create_port(200, "input server target"); 416 if (fAppServerPort < B_OK) { 417 _ReleaseInput(&message); 418 return fAppServerPort; 419 } 420 421 reply.AddBool("has keyboard", true); 422 reply.AddBool("has mouse", true); 423 reply.AddInt32("event port", fAppServerPort); 424 425 if (fCursorBuffer != NULL) { 426 // cursor shared buffer is supported 427 reply.AddInt32("cursor semaphore", fCursorSem); 428 } 429 430 return B_OK; 431 } 432 433 434 void 435 InputServer::_ReleaseInput(BMessage* /*message*/) 436 { 437 if (fCursorBuffer != NULL) { 438 fCursorBuffer = NULL; 439 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 440 delete_sem(fCursorSem); 441 #endif 442 delete_area(fCursorArea); 443 444 fCursorSem = -1; 445 fCursorArea = -1; 446 } 447 448 delete_port(fAppServerPort); 449 } 450 451 452 void 453 InputServer::MessageReceived(BMessage* message) 454 { 455 CALLED(); 456 457 BMessage reply; 458 status_t status = B_OK; 459 460 PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what >> 24, 461 message->what >> 16, message->what >> 8, message->what)); 462 463 switch (message->what) { 464 case IS_SET_METHOD: 465 HandleSetMethod(message); 466 break; 467 case IS_GET_MOUSE_TYPE: 468 status = HandleGetSetMouseType(message, &reply); 469 break; 470 case IS_SET_MOUSE_TYPE: 471 status = HandleGetSetMouseType(message, &reply); 472 break; 473 case IS_GET_MOUSE_ACCELERATION: 474 status = HandleGetSetMouseAcceleration(message, &reply); 475 break; 476 case IS_SET_MOUSE_ACCELERATION: 477 status = HandleGetSetMouseAcceleration(message, &reply); 478 break; 479 case IS_GET_KEY_REPEAT_DELAY: 480 status = HandleGetSetKeyRepeatDelay(message, &reply); 481 break; 482 case IS_SET_KEY_REPEAT_DELAY: 483 status = HandleGetSetKeyRepeatDelay(message, &reply); 484 break; 485 case IS_GET_KEY_INFO: 486 status = HandleGetKeyInfo(message, &reply); 487 break; 488 case IS_GET_MODIFIERS: 489 status = HandleGetModifiers(message, &reply); 490 break; 491 case IS_SET_MODIFIER_KEY: 492 status = HandleSetModifierKey(message, &reply); 493 break; 494 case IS_SET_KEYBOARD_LOCKS: 495 status = HandleSetKeyboardLocks(message, &reply); 496 break; 497 case IS_GET_MOUSE_SPEED: 498 status = HandleGetSetMouseSpeed(message, &reply); 499 break; 500 case IS_SET_MOUSE_SPEED: 501 status = HandleGetSetMouseSpeed(message, &reply); 502 break; 503 case IS_SET_MOUSE_POSITION: 504 status = HandleSetMousePosition(message, &reply); 505 break; 506 case IS_GET_MOUSE_MAP: 507 status = HandleGetSetMouseMap(message, &reply); 508 break; 509 case IS_SET_MOUSE_MAP: 510 status = HandleGetSetMouseMap(message, &reply); 511 break; 512 case IS_GET_KEYBOARD_ID: 513 status = HandleGetKeyboardID(message, &reply); 514 break; 515 case IS_GET_CLICK_SPEED: 516 status = HandleGetSetClickSpeed(message, &reply); 517 break; 518 case IS_SET_CLICK_SPEED: 519 status = HandleGetSetClickSpeed(message, &reply); 520 break; 521 case IS_GET_KEY_REPEAT_RATE: 522 status = HandleGetSetKeyRepeatRate(message, &reply); 523 break; 524 case IS_SET_KEY_REPEAT_RATE: 525 status = HandleGetSetKeyRepeatRate(message, &reply); 526 break; 527 case IS_GET_KEY_MAP: 528 status = HandleGetSetKeyMap(message, &reply); 529 break; 530 case IS_RESTORE_KEY_MAP: 531 status = HandleGetSetKeyMap(message, &reply); 532 break; 533 case IS_FOCUS_IM_AWARE_VIEW: 534 status = HandleFocusUnfocusIMAwareView(message, &reply); 535 break; 536 case IS_UNFOCUS_IM_AWARE_VIEW: 537 status = HandleFocusUnfocusIMAwareView(message, &reply); 538 break; 539 540 // app_server communication 541 case IS_ACQUIRE_INPUT: 542 status = _AcquireInput(*message, reply); 543 break; 544 case IS_RELEASE_INPUT: 545 _ReleaseInput(message); 546 return; 547 case IS_SCREEN_BOUNDS_UPDATED: 548 { 549 // This is what the R5 app_server sends us when the screen 550 // configuration changes 551 BRect frame; 552 if (message->FindRect("screen_bounds", &frame) != B_OK) 553 frame = fScreen.Frame(); 554 555 if (frame == fFrame) 556 break; 557 558 BPoint pos(fMousePos.x * frame.Width() / fFrame.Width(), 559 fMousePos.y * frame.Height() / fFrame.Height()); 560 fFrame = frame; 561 562 BMessage set; 563 set.AddPoint("where", pos); 564 HandleSetMousePosition(&set, NULL); 565 break; 566 } 567 568 // device looper related 569 case IS_FIND_DEVICES: 570 case IS_WATCH_DEVICES: 571 case IS_IS_DEVICE_RUNNING: 572 case IS_START_DEVICE: 573 case IS_STOP_DEVICE: 574 case IS_CONTROL_DEVICES: 575 case SYSTEM_SHUTTING_DOWN: 576 case IS_METHOD_REGISTER: 577 fAddOnManager->PostMessage(message); 578 return; 579 580 case B_SOME_APP_LAUNCHED: 581 { 582 const char *signature; 583 // TODO: what's this for? 584 if (message->FindString("be:signature", &signature)==B_OK) { 585 PRINT(("input_server : %s\n", signature)); 586 if (strcmp(signature, "application/x-vnd.Be-TSKB")==0) { 587 588 } 589 } 590 return; 591 } 592 593 default: 594 return; 595 } 596 597 reply.AddInt32("status", status); 598 message->SendReply(&reply); 599 } 600 601 602 void 603 InputServer::HandleSetMethod(BMessage* message) 604 { 605 CALLED(); 606 uint32 cookie; 607 if (message->FindInt32("cookie", (int32*)&cookie) == B_OK) { 608 BInputServerMethod *method = (BInputServerMethod*)cookie; 609 PRINT(("%s cookie %p\n", __PRETTY_FUNCTION__, method)); 610 SetActiveMethod(method); 611 } 612 } 613 614 615 status_t 616 InputServer::HandleGetSetMouseType(BMessage* message, BMessage* reply) 617 { 618 int32 type; 619 if (message->FindInt32("mouse_type", &type) == B_OK) { 620 fMouseSettings.SetMouseType(type); 621 622 BMessage msg(IS_CONTROL_DEVICES); 623 msg.AddInt32("type", B_POINTING_DEVICE); 624 msg.AddInt32("code", B_MOUSE_TYPE_CHANGED); 625 return fAddOnManager->PostMessage(&msg); 626 } 627 628 return reply->AddInt32("mouse_type", fMouseSettings.MouseType()); 629 } 630 631 632 status_t 633 InputServer::HandleGetSetMouseAcceleration(BMessage* message, 634 BMessage* reply) 635 { 636 int32 factor; 637 if (message->FindInt32("speed", &factor) == B_OK) { 638 fMouseSettings.SetAccelerationFactor(factor); 639 640 BMessage msg(IS_CONTROL_DEVICES); 641 msg.AddInt32("type", B_POINTING_DEVICE); 642 msg.AddInt32("code", B_MOUSE_ACCELERATION_CHANGED); 643 return fAddOnManager->PostMessage(&msg); 644 } 645 646 return reply->AddInt32("speed", fMouseSettings.AccelerationFactor()); 647 } 648 649 650 status_t 651 InputServer::HandleGetSetKeyRepeatDelay(BMessage* message, BMessage* reply) 652 { 653 bigtime_t delay; 654 if (message->FindInt64("delay", &delay) == B_OK) { 655 fKeyboardSettings.SetKeyboardRepeatDelay(delay); 656 657 BMessage msg(IS_CONTROL_DEVICES); 658 msg.AddInt32("type", B_KEYBOARD_DEVICE); 659 msg.AddInt32("code", B_KEY_REPEAT_DELAY_CHANGED); 660 return fAddOnManager->PostMessage(&msg); 661 } 662 663 return reply->AddInt64("delay", fKeyboardSettings.KeyboardRepeatDelay()); 664 } 665 666 667 status_t 668 InputServer::HandleGetKeyInfo(BMessage* message, BMessage* reply) 669 { 670 return reply->AddData("key_info", B_ANY_TYPE, &fKeyInfo, sizeof(fKeyInfo)); 671 } 672 673 674 status_t 675 InputServer::HandleGetModifiers(BMessage* message, BMessage* reply) 676 { 677 return reply->AddInt32("modifiers", fKeyInfo.modifiers); 678 } 679 680 681 status_t 682 InputServer::HandleSetModifierKey(BMessage* message, BMessage* reply) 683 { 684 int32 modifier, key; 685 if (message->FindInt32("modifier", &modifier) == B_OK 686 && message->FindInt32("key", &key) == B_OK) { 687 switch (modifier) { 688 case B_CAPS_LOCK: 689 fKeys.caps_key = key; 690 break; 691 case B_NUM_LOCK: 692 fKeys.num_key = key; 693 break; 694 case B_SCROLL_LOCK: 695 fKeys.num_key = key; 696 break; 697 case B_LEFT_SHIFT_KEY: 698 fKeys.left_shift_key = key; 699 break; 700 case B_RIGHT_SHIFT_KEY: 701 fKeys.right_shift_key = key; 702 break; 703 case B_LEFT_COMMAND_KEY: 704 fKeys.left_command_key = key; 705 break; 706 case B_RIGHT_COMMAND_KEY: 707 fKeys.right_command_key = key; 708 break; 709 case B_LEFT_CONTROL_KEY: 710 fKeys.left_control_key = key; 711 break; 712 case B_RIGHT_CONTROL_KEY: 713 fKeys.right_control_key = key; 714 break; 715 case B_LEFT_OPTION_KEY: 716 fKeys.left_option_key = key; 717 break; 718 case B_RIGHT_OPTION_KEY: 719 fKeys.right_option_key = key; 720 break; 721 case B_MENU_KEY: 722 fKeys.menu_key = key; 723 break; 724 default: 725 return B_ERROR; 726 } 727 728 // TODO: unmap the key ? 729 730 BMessage msg(IS_CONTROL_DEVICES); 731 msg.AddInt32("type", B_KEYBOARD_DEVICE); 732 msg.AddInt32("code", B_KEY_MAP_CHANGED); 733 return fAddOnManager->PostMessage(&msg); 734 } 735 736 return B_ERROR; 737 } 738 739 740 status_t 741 InputServer::HandleSetKeyboardLocks(BMessage* message, BMessage* reply) 742 { 743 if (message->FindInt32("locks", (int32*)&fKeys.lock_settings) == B_OK) { 744 BMessage msg(IS_CONTROL_DEVICES); 745 msg.AddInt32("type", B_KEYBOARD_DEVICE); 746 msg.AddInt32("code", B_KEY_LOCKS_CHANGED); 747 return fAddOnManager->PostMessage(&msg); 748 } 749 750 return B_ERROR; 751 } 752 753 754 status_t 755 InputServer::HandleGetSetMouseSpeed(BMessage* message, BMessage* reply) 756 { 757 int32 speed; 758 if (message->FindInt32("speed", &speed) == B_OK) { 759 fMouseSettings.SetMouseSpeed(speed); 760 761 BMessage msg(IS_CONTROL_DEVICES); 762 msg.AddInt32("type", B_POINTING_DEVICE); 763 msg.AddInt32("code", B_MOUSE_SPEED_CHANGED); 764 return fAddOnManager->PostMessage(&msg); 765 } 766 767 return reply->AddInt32("speed", fMouseSettings.MouseSpeed()); 768 } 769 770 771 status_t 772 InputServer::HandleSetMousePosition(BMessage* message, BMessage* reply) 773 { 774 CALLED(); 775 776 BPoint where; 777 if (message->FindPoint("where", &where) != B_OK) 778 return B_BAD_VALUE; 779 780 // create a new event for this and enqueue it to the event list just like any other 781 782 BMessage* event = new BMessage(B_MOUSE_MOVED); 783 if (event == NULL) 784 return B_NO_MEMORY; 785 786 event->AddPoint("where", where); 787 event->AddBool("be:set_mouse", true); 788 if (EnqueueDeviceMessage(event) != B_OK) { 789 delete event; 790 return B_NO_MEMORY; 791 } 792 793 return B_OK; 794 } 795 796 797 status_t 798 InputServer::HandleGetSetMouseMap(BMessage* message, BMessage* reply) 799 { 800 mouse_map *map; 801 ssize_t size; 802 if (message->FindData("mousemap", B_RAW_TYPE, (const void**)&map, &size) == B_OK) { 803 fMouseSettings.SetMapping(*map); 804 805 BMessage msg(IS_CONTROL_DEVICES); 806 msg.AddInt32("type", B_POINTING_DEVICE); 807 msg.AddInt32("code", B_MOUSE_MAP_CHANGED); 808 return fAddOnManager->PostMessage(&msg); 809 } else { 810 mouse_map map; 811 fMouseSettings.Mapping(map); 812 return reply->AddData("mousemap", B_RAW_TYPE, &map, sizeof(mouse_map)); 813 } 814 } 815 816 817 status_t 818 InputServer::HandleGetKeyboardID(BMessage* message, BMessage* reply) 819 { 820 return reply->AddInt16("id", fKeyboardID); 821 } 822 823 824 status_t 825 InputServer::HandleGetSetClickSpeed(BMessage* message, BMessage* reply) 826 { 827 bigtime_t clickSpeed; 828 if (message->FindInt64("speed", &clickSpeed) == B_OK) { 829 fMouseSettings.SetClickSpeed(clickSpeed); 830 831 BMessage msg(IS_CONTROL_DEVICES); 832 msg.AddInt32("type", B_POINTING_DEVICE); 833 msg.AddInt32("code", B_CLICK_SPEED_CHANGED); 834 return fAddOnManager->PostMessage(&msg); 835 } 836 837 return reply->AddInt64("speed", fMouseSettings.ClickSpeed()); 838 } 839 840 841 status_t 842 InputServer::HandleGetSetKeyRepeatRate(BMessage* message, BMessage* reply) 843 { 844 int32 keyRepeatRate; 845 if (message->FindInt32("rate", &keyRepeatRate) == B_OK) { 846 fKeyboardSettings.SetKeyboardRepeatRate(keyRepeatRate); 847 848 BMessage msg(IS_CONTROL_DEVICES); 849 msg.AddInt32("type", B_KEYBOARD_DEVICE); 850 msg.AddInt32("code", B_KEY_REPEAT_RATE_CHANGED); 851 return fAddOnManager->PostMessage(&msg); 852 } 853 854 return reply->AddInt32("rate", fKeyboardSettings.KeyboardRepeatRate()); 855 } 856 857 858 status_t 859 InputServer::HandleGetSetKeyMap(BMessage* message, BMessage* reply) 860 { 861 CALLED(); 862 863 if (message->what == IS_GET_KEY_MAP) { 864 status_t status = reply->AddData("keymap", B_ANY_TYPE, &fKeys, sizeof(fKeys)); 865 if (status == B_OK) 866 status = reply->AddData("key_buffer", B_ANY_TYPE, fChars, fCharsSize); 867 868 return status; 869 } 870 871 if (_LoadKeymap() != B_OK) 872 _LoadSystemKeymap(); 873 874 BMessage msg(IS_CONTROL_DEVICES); 875 msg.AddInt32("type", B_KEYBOARD_DEVICE); 876 msg.AddInt32("code", B_KEY_MAP_CHANGED); 877 return fAddOnManager->PostMessage(&msg); 878 } 879 880 881 status_t 882 InputServer::HandleFocusUnfocusIMAwareView(BMessage* message, 883 BMessage* reply) 884 { 885 CALLED(); 886 887 BMessenger messenger; 888 status_t status = message->FindMessenger("view", &messenger); 889 if (status != B_OK) 890 return status; 891 892 // check if current view is ours 893 894 if (message->what == IS_FOCUS_IM_AWARE_VIEW) { 895 PRINT(("HandleFocusUnfocusIMAwareView : entering\n")); 896 fInputMethodAware = true; 897 } else { 898 PRINT(("HandleFocusUnfocusIMAwareView : leaving\n")); 899 fInputMethodAware = false; 900 } 901 902 return B_OK; 903 } 904 905 906 /** Enqueues the message into the event queue. 907 * The message must only be deleted in case this method returns an error. 908 */ 909 910 status_t 911 InputServer::EnqueueDeviceMessage(BMessage* message) 912 { 913 CALLED(); 914 915 BAutolock _(fEventQueueLock); 916 if (!fEventQueue.AddItem(message)) 917 return B_NO_MEMORY; 918 919 if (fEventQueue.CountItems() == 1) { 920 // notify event loop only if we haven't already done so 921 write_port_etc(fEventLooperPort, 1, NULL, 0, B_RELATIVE_TIMEOUT, 0); 922 } 923 return B_OK; 924 } 925 926 927 /** Enqueues the message into the method queue. 928 * The message must only be deleted in case this method returns an error. 929 */ 930 931 status_t 932 InputServer::EnqueueMethodMessage(BMessage* message) 933 { 934 CALLED(); 935 PRINT(("%s what:%c%c%c%c\n", __PRETTY_FUNCTION__, message->what >> 24, 936 message->what >> 16, message->what >> 8, message->what)); 937 938 #ifdef DEBUG 939 if (message->what == 'IMEV') { 940 int32 code; 941 message->FindInt32("be:opcode", &code); 942 PRINT(("%s be:opcode %li\n", __PRETTY_FUNCTION__, code)); 943 } 944 #endif 945 946 BAutolock _(fEventQueueLock); 947 if (!fMethodQueue.AddItem(message)) 948 return B_NO_MEMORY; 949 950 if (fMethodQueue.CountItems() == 1) { 951 // notify event loop only if we haven't already done so 952 write_port_etc(fEventLooperPort, 0, NULL, 0, B_RELATIVE_TIMEOUT, 0); 953 } 954 return B_OK; 955 } 956 957 958 status_t 959 InputServer::SetNextMethod(bool direction) 960 { 961 gInputMethodListLocker.Lock(); 962 963 int32 index = gInputMethodList.IndexOf(fActiveMethod); 964 index += (direction ? 1 : -1); 965 966 if (index < -1) 967 index = gInputMethodList.CountItems() - 1; 968 if (index >= gInputMethodList.CountItems()) 969 index = -1; 970 971 BInputServerMethod *method = &gKeymapMethod; 972 973 if (index != -1) 974 method = (BInputServerMethod *)gInputMethodList.ItemAt(index); 975 976 SetActiveMethod(method); 977 978 gInputMethodListLocker.Unlock(); 979 return B_OK; 980 } 981 982 983 void 984 InputServer::SetActiveMethod(BInputServerMethod* method) 985 { 986 CALLED(); 987 if (fActiveMethod) 988 fActiveMethod->fOwner->MethodActivated(false); 989 990 fActiveMethod = method; 991 992 if (fActiveMethod) 993 fActiveMethod->fOwner->MethodActivated(true); 994 } 995 996 997 const BMessenger* 998 InputServer::MethodReplicant() 999 { 1000 return fReplicantMessenger; 1001 } 1002 1003 1004 void 1005 InputServer::SetMethodReplicant(const BMessenger* messenger) 1006 { 1007 fReplicantMessenger = messenger; 1008 } 1009 1010 1011 bool 1012 InputServer::EventLoopRunning() 1013 { 1014 return fEventLooperPort >= B_OK; 1015 } 1016 1017 1018 /** The fInputDeviceListLocker must be locked when calling this function */ 1019 1020 InputDeviceListItem* 1021 InputServer::_FindInputDeviceListItem(BInputServerDevice& device) 1022 { 1023 for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { 1024 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); 1025 1026 if (item->ServerDevice() == &device) 1027 return item; 1028 } 1029 1030 return NULL; 1031 } 1032 1033 1034 status_t 1035 InputServer::GetDeviceInfo(const char* name, input_device_type *_type, 1036 bool *_isRunning) 1037 { 1038 BAutolock lock(fInputDeviceListLocker); 1039 1040 for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { 1041 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); 1042 1043 if (item->HasName(name)) { 1044 if (_type) 1045 *_type = item->Type(); 1046 if (_isRunning) 1047 *_isRunning = item->Running(); 1048 1049 return B_OK; 1050 } 1051 } 1052 1053 return B_NAME_NOT_FOUND; 1054 } 1055 1056 1057 status_t 1058 InputServer::GetDeviceInfos(BMessage *msg) 1059 { 1060 CALLED(); 1061 BAutolock lock(fInputDeviceListLocker); 1062 1063 for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { 1064 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); 1065 msg->AddString("device", item->Name()); 1066 msg->AddInt32("type", item->Type()); 1067 } 1068 return B_OK; 1069 } 1070 1071 1072 status_t 1073 InputServer::UnregisterDevices(BInputServerDevice& serverDevice, 1074 input_device_ref **devices) 1075 { 1076 CALLED(); 1077 BAutolock lock(fInputDeviceListLocker); 1078 1079 if (devices != NULL) { 1080 // remove the devices as specified only 1081 input_device_ref *device = NULL; 1082 for (int32 i = 0; NULL != (device = devices[i]); i++) { 1083 for (int32 j = fInputDeviceList.CountItems() - 1; j >= 0; j--) { 1084 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(j); 1085 1086 if (item->ServerDevice() == &serverDevice && item->HasName(device->name)) { 1087 item->Stop(); 1088 fInputDeviceList.RemoveItem(j); 1089 delete item; 1090 break; 1091 } 1092 } 1093 } 1094 } else { 1095 // remove all devices from this BInputServerObject 1096 for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { 1097 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); 1098 1099 if (item->ServerDevice() == &serverDevice) { 1100 item->Stop(); 1101 fInputDeviceList.RemoveItem(i); 1102 delete item; 1103 } 1104 } 1105 } 1106 1107 return B_OK; 1108 } 1109 1110 1111 status_t 1112 InputServer::RegisterDevices(BInputServerDevice& serverDevice, 1113 input_device_ref** devices) 1114 { 1115 if (devices == NULL) 1116 return B_BAD_VALUE; 1117 1118 BAutolock lock(fInputDeviceListLocker); 1119 1120 input_device_ref *device = NULL; 1121 for (int32 i = 0; (device = devices[i]) != NULL; i++) { 1122 if (device->type != B_POINTING_DEVICE 1123 && device->type != B_KEYBOARD_DEVICE 1124 && device->type != B_UNDEFINED_DEVICE) 1125 continue; 1126 1127 // find existing input server device 1128 1129 bool found = false; 1130 for (int32 j = fInputDeviceList.CountItems() - 1; j >= 0; j--) { 1131 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(j); 1132 1133 if (item->HasName(device->name)) { 1134 PRINT(("RegisterDevices found %s\n", device->name)); 1135 found = true; 1136 break; 1137 } 1138 } 1139 1140 if (!found) { 1141 PRINT(("RegisterDevices not found %s\n", device->name)); 1142 InputDeviceListItem* item = new (nothrow) InputDeviceListItem(serverDevice, 1143 *device); 1144 if (item != NULL && fInputDeviceList.AddItem(item)) { 1145 item->Start(); 1146 } else { 1147 delete item; 1148 return B_NO_MEMORY; 1149 } 1150 } 1151 } 1152 1153 return B_OK; 1154 } 1155 1156 1157 status_t 1158 InputServer::StartStopDevices(const char* name, input_device_type type, bool doStart) 1159 { 1160 CALLED(); 1161 BAutolock lock(fInputDeviceListLocker); 1162 1163 for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { 1164 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); 1165 if (!item) 1166 continue; 1167 1168 if (item->Matches(name, type)) { 1169 if (!doStart ^ item->Running()) 1170 return B_ERROR; 1171 1172 if (doStart) 1173 item->Start(); 1174 else 1175 item->Stop(); 1176 1177 if (name) 1178 return B_OK; 1179 } 1180 } 1181 1182 if (name) 1183 return B_ERROR; 1184 1185 return B_OK; 1186 } 1187 1188 1189 1190 status_t 1191 InputServer::StartStopDevices(BInputServerDevice& serverDevice, bool doStart) 1192 { 1193 CALLED(); 1194 BAutolock lock(fInputDeviceListLocker); 1195 1196 InputDeviceListItem* item = _FindInputDeviceListItem(serverDevice); 1197 if (item != NULL) { 1198 if (!doStart ^ item->Running()) 1199 return B_ERROR; 1200 1201 if (doStart) 1202 item->Start(); 1203 else 1204 item->Stop(); 1205 } 1206 EXIT(); 1207 1208 return B_OK; 1209 } 1210 1211 1212 status_t 1213 InputServer::ControlDevices(const char* name, input_device_type type, 1214 uint32 code, BMessage* message) 1215 { 1216 CALLED(); 1217 BAutolock lock(fInputDeviceListLocker); 1218 1219 for (int32 i = fInputDeviceList.CountItems() - 1; i >= 0; i--) { 1220 InputDeviceListItem* item = (InputDeviceListItem*)fInputDeviceList.ItemAt(i); 1221 if (!item) 1222 continue; 1223 1224 if (item->Matches(name, type)) { 1225 item->Control(code, message); 1226 1227 if (name) 1228 return B_OK; 1229 } 1230 } 1231 1232 if (name) 1233 return B_ERROR; 1234 1235 return B_OK; 1236 } 1237 1238 1239 bool 1240 InputServer::DoMouseAcceleration(int32* _x, int32* _y) 1241 { 1242 CALLED(); 1243 int32 speed = fMouseSettings.MouseSpeed() >> 15; 1244 1245 // ToDo: implement mouse acceleration 1246 (void)speed; 1247 //*y = *x * speed; 1248 PRINT(("DoMouse : %ld %ld %ld %ld\n", *x, *y, speed, fMouseSettings.MouseSpeed())); 1249 return true; 1250 } 1251 1252 1253 bool 1254 InputServer::SetMousePos(long *, long *, long, long) 1255 { 1256 CALLED(); 1257 return true; 1258 } 1259 1260 1261 bool 1262 InputServer::SetMousePos(long *, long *, BPoint) 1263 { 1264 CALLED(); 1265 return true; 1266 } 1267 1268 1269 bool 1270 InputServer::SetMousePos(long *, long *, float, float) 1271 { 1272 CALLED(); 1273 return true; 1274 } 1275 1276 1277 bool 1278 InputServer::SafeMode() 1279 { 1280 return fSafeMode; 1281 } 1282 1283 1284 status_t 1285 InputServer::_StartEventLoop() 1286 { 1287 CALLED(); 1288 fEventLooperPort = create_port(100, "input server events"); 1289 if (fEventLooperPort < 0) { 1290 PRINTERR(("InputServer: create_port error: (0x%x) %s\n", 1291 fEventLooperPort, strerror(fEventLooperPort))); 1292 return fEventLooperPort; 1293 } 1294 1295 thread_id thread = spawn_thread(_EventLooper, "_input_server_event_loop_", 1296 B_REAL_TIME_DISPLAY_PRIORITY + 3, this); 1297 if (thread < B_OK || resume_thread(thread) < B_OK) { 1298 if (thread >= B_OK) 1299 kill_thread(thread); 1300 delete_port(fEventLooperPort); 1301 fEventLooperPort = -1; 1302 return thread < B_OK ? thread : B_ERROR; 1303 } 1304 1305 return B_OK; 1306 } 1307 1308 1309 status_t 1310 InputServer::_EventLooper(void* arg) 1311 { 1312 InputServer* self = (InputServer*)arg; 1313 self->_EventLoop(); 1314 1315 return B_OK; 1316 } 1317 1318 1319 void 1320 InputServer::_EventLoop() 1321 { 1322 while (true) { 1323 // Block until we find the size of the next message 1324 ssize_t length = port_buffer_size(fEventLooperPort); 1325 if (length < B_OK) { 1326 PRINT("[Event Looper] port gone, exiting.\n"); 1327 return; 1328 } 1329 1330 PRINT(("[Event Looper] BMessage Size = %lu\n", length)); 1331 1332 char buffer[length]; 1333 int32 code; 1334 status_t err = read_port(fEventLooperPort, &code, buffer, length); 1335 if (err != length) { 1336 if (err >= 0) { 1337 PRINTERR(("InputServer: failed to read full packet (read %lu of %lu)\n", err, length)); 1338 } else { 1339 PRINTERR(("InputServer: read_port error: (0x%lx) %s\n", err, strerror(err))); 1340 } 1341 continue; 1342 } 1343 1344 EventList events; 1345 if (fEventQueueLock.Lock()) { 1346 // move the items to our own list to block the event queue as short as possible 1347 events.AddList(&fEventQueue); 1348 fEventQueue.MakeEmpty(); 1349 fEventQueueLock.Unlock(); 1350 } 1351 1352 if (length > 0) { 1353 BMessage* event = new BMessage; 1354 1355 if ((err = event->Unflatten(buffer)) < 0) { 1356 PRINTERR(("[InputServer] Unflatten() error: (0x%lx) %s\n", err, strerror(err))); 1357 delete event; 1358 } 1359 1360 events.AddItem(event); 1361 } 1362 1363 // This is where the message should be processed. 1364 1365 if (_SanitizeEvents(events) 1366 && _MethodizeEvents(events) 1367 && _FilterEvents(events)) 1368 _DispatchEvents(events); 1369 } 1370 } 1371 1372 1373 /** Frees events from unwanted fields, adds missing fields, and removes 1374 * unwanted events altogether. 1375 * As a side effect, it will also update the internal mouse states. 1376 */ 1377 1378 bool 1379 InputServer::_SanitizeEvents(EventList& events) 1380 { 1381 CALLED(); 1382 int32 index = 0; 1383 BMessage *event; 1384 1385 while ((event = (BMessage*)events.ItemAt(index)) != NULL) { 1386 switch (event->what) { 1387 #ifndef HAIKU_TARGET_PLATFORM_HAIKU 1388 case IS_SCREEN_BOUNDS_UPDATED: 1389 { 1390 // This is what the R5 app_server sends us when the screen 1391 // configuration changes 1392 BRect frame; 1393 if (event->FindRect("screen_bounds", &frame) != B_OK) 1394 frame = fScreen.Frame(); 1395 1396 if (frame != fFrame) { 1397 fMousePos.x = fMousePos.x * frame.Width() / fFrame.Width(); 1398 fMousePos.y = fMousePos.y * frame.Height() / fFrame.Height(); 1399 fFrame = frame; 1400 } else { 1401 // TODO: discard event 1402 } 1403 1404 event->what = B_MOUSE_MOVED; 1405 event->AddPoint("where", fMousePos); 1406 // supposed to fall through 1407 } 1408 #endif 1409 case B_MOUSE_MOVED: 1410 case B_MOUSE_DOWN: 1411 { 1412 int32 buttons; 1413 if (event->FindInt32("buttons", &buttons) != B_OK) 1414 event->AddInt32("buttons", 0); 1415 1416 // supposed to fall through 1417 } 1418 case B_MOUSE_UP: 1419 { 1420 BPoint where; 1421 int32 x, y; 1422 1423 if (event->FindInt32("x", &x) == B_OK 1424 && event->FindInt32("y", &y) == B_OK) { 1425 fMousePos.x += x; 1426 fMousePos.y -= y; 1427 fMousePos.ConstrainTo(fFrame); 1428 1429 event->RemoveName("x"); 1430 event->RemoveName("y"); 1431 event->AddPoint("where", fMousePos); 1432 1433 PRINT(("new position: %f, %f, %ld, %ld\n", 1434 fMousePos.x, fMousePos.y, xValue, yValue)); 1435 } else if (event->FindPoint("where", &where) == B_OK) { 1436 fMousePos = where; 1437 fMousePos.ConstrainTo(fFrame); 1438 1439 event->ReplacePoint("where", fMousePos); 1440 PRINT(("new position : %f, %f\n", fMousePos.x, fMousePos.y)); 1441 } 1442 1443 event->AddInt32("modifiers", fKeyInfo.modifiers); 1444 break; 1445 } 1446 case B_KEY_DOWN: 1447 case B_UNMAPPED_KEY_DOWN: 1448 if (fActiveMethod == NULL) 1449 break; 1450 1451 // we scan for Alt+Space key down events which means we change 1452 // to next input method 1453 // (pressing "shift" will let us switch to the previous method) 1454 1455 PRINT(("SanitizeEvents: %lx, %lx\n", fKeyInfo.modifiers, 1456 fKeyInfo.key_states[KEY_Spacebar >> 3])); 1457 1458 if ((fKeyInfo.modifiers & B_COMMAND_KEY) != 0 1459 && (fKeyInfo.key_states[KEY_Spacebar >> 3] 1460 & (1 << (7 - (KEY_Spacebar % 8))))) { 1461 SetNextMethod(!fKeyInfo.modifiers & B_SHIFT_KEY); 1462 1463 // this event isn't sent to the user 1464 events.RemoveItemAt(index); 1465 delete event; 1466 continue; 1467 } 1468 break; 1469 } 1470 1471 index++; 1472 } 1473 1474 return true; 1475 } 1476 1477 1478 /** Applies the filters of the active input method to the 1479 * incoming events. It will also move the events in the method 1480 * queue to the event list. 1481 */ 1482 1483 bool 1484 InputServer::_MethodizeEvents(EventList& events) 1485 { 1486 CALLED(); 1487 1488 if (fActiveMethod == NULL) 1489 return true; 1490 1491 int32 count = events.CountItems(); 1492 for (int32 i = 0; i < count;) { 1493 _FilterEvent(fActiveMethod, events, i, count); 1494 } 1495 1496 if (!fInputMethodAware) { 1497 // special handling for non-input-method-aware views 1498 for (int32 i = 0; i < count; i++) { 1499 BMessage* event = events.ItemAt(i); 1500 1501 if (event->what != B_INPUT_METHOD_EVENT) 1502 continue; 1503 1504 SERIAL_PRINT(("IME received\n")); 1505 1506 int32 opcode; 1507 if (fInputMethodWindow == NULL 1508 && event->FindInt32("be:opcode", &opcode) == B_OK 1509 && opcode == B_INPUT_METHOD_STARTED) 1510 fInputMethodWindow = new (nothrow) BottomlineWindow(); 1511 1512 if (fInputMethodWindow != NULL) { 1513 EventList newEvents; 1514 fInputMethodWindow->HandleInputMethodEvent(event, newEvents); 1515 1516 if (!newEvents.IsEmpty()) { 1517 fInputMethodWindow->PostMessage(B_QUIT_REQUESTED); 1518 fInputMethodWindow = NULL; 1519 1520 // replace event with new events (but don't scan them again 1521 // for input method messages) 1522 events.RemoveItemAt(i); 1523 delete event; 1524 1525 events.AddList(&newEvents, i); 1526 i += newEvents.CountItems() - 1; 1527 count = events.CountItems(); 1528 } 1529 } 1530 } 1531 } 1532 1533 // move the method events into the event queue - they are not 1534 // "methodized" either 1535 BAutolock _(fEventQueueLock); 1536 events.AddList(&fMethodQueue); 1537 fMethodQueue.MakeEmpty(); 1538 1539 return events.CountItems() > 0; 1540 } 1541 1542 1543 /** This method applies all defined filters to each event in the 1544 * supplied list. The supplied list is modified to reflect the 1545 * output of the filters. 1546 * The method returns true if the filters were applied to all 1547 * events without error and false otherwise. 1548 */ 1549 1550 bool 1551 InputServer::_FilterEvents(EventList& events) 1552 { 1553 CALLED(); 1554 BAutolock _(gInputFilterListLocker); 1555 1556 int32 count = gInputFilterList.CountItems(); 1557 int32 eventCount = events.CountItems(); 1558 1559 for (int32 i = 0; i < count; i++) { 1560 BInputServerFilter* filter = (BInputServerFilter*)gInputFilterList.ItemAt(i); 1561 1562 // Apply the current filter to all available event messages. 1563 1564 for (int32 eventIndex = 0; eventIndex < eventCount;) { 1565 _FilterEvent(filter, events, eventIndex, eventCount); 1566 } 1567 } 1568 1569 return eventCount != 0; 1570 } 1571 1572 1573 void 1574 InputServer::_DispatchEvents(EventList& events) 1575 { 1576 CALLED(); 1577 1578 int32 count = events.CountItems(); 1579 1580 for (int32 i = 0; i < count; i++) { 1581 BMessage* event = events.ItemAt(i); 1582 1583 // now we must send each event to the app_server 1584 _DispatchEvent(event); 1585 delete event; 1586 } 1587 1588 events.MakeEmpty(); 1589 } 1590 1591 1592 /** Applies the given filter to the event list. 1593 * For your convenience, it also alters the \a index and \a count arguments 1594 * ready for the next call to this method. 1595 */ 1596 1597 void 1598 InputServer::_FilterEvent(BInputServerFilter* filter, EventList& events, 1599 int32& index, int32& count) 1600 { 1601 BMessage* event = events.ItemAt(index); 1602 1603 BList newEvents; 1604 filter_result result = filter->Filter(event, &newEvents); 1605 1606 if (result == B_SKIP_MESSAGE || newEvents.CountItems() > 0) { 1607 // we no longer need the current event 1608 events.RemoveItemAt(index); 1609 delete event; 1610 1611 if (result == B_DISPATCH_MESSAGE) { 1612 // add the new events - but don't methodize them again 1613 events.AsBList()->AddList(&newEvents, index); 1614 index += newEvents.CountItems(); 1615 count = events.CountItems(); 1616 } else 1617 count--; 1618 } else 1619 index++; 1620 } 1621 1622 1623 status_t 1624 InputServer::_DispatchEvent(BMessage* event) 1625 { 1626 CALLED(); 1627 1628 switch (event->what) { 1629 case B_MOUSE_MOVED: 1630 case B_MOUSE_DOWN: 1631 case B_MOUSE_UP: 1632 if (fCursorBuffer) { 1633 #ifndef HAIKU_TARGET_PLATFORM_HAIKU 1634 fCursorBuffer[0] = (0x3 << 30L) 1635 | ((uint32)fMousePos.x & 0x7fff) << 15 1636 | ((uint32)fMousePos.y & 0x7fff); 1637 1638 PRINT(("released cursorSem with value : %08lx\n", fCursorBuffer[0])); 1639 release_sem(fCursorSem); 1640 #else 1641 atomic_set((int32*)&fCursorBuffer->pos, (uint32)fMousePos.x << 16UL 1642 | ((uint32)fMousePos.y & 0xffff)); 1643 if (atomic_or(&fCursorBuffer->read, 1) == 0) 1644 release_sem(fCursorSem); 1645 #endif 1646 } 1647 break; 1648 1649 case B_KEY_DOWN: 1650 case B_KEY_UP: 1651 case B_UNMAPPED_KEY_DOWN: 1652 case B_UNMAPPED_KEY_UP: 1653 case B_MODIFIERS_CHANGED: 1654 { 1655 // update or add modifiers 1656 uint32 modifiers; 1657 if (event->FindInt32("modifiers", (int32*)&modifiers) == B_OK) 1658 fKeyInfo.modifiers = modifiers; 1659 else 1660 event->AddInt32("modifiers", fKeyInfo.modifiers); 1661 1662 // update or add key states 1663 const uint8 *data; 1664 ssize_t size; 1665 if (event->FindData("states", B_UINT8_TYPE, 1666 (const void**)&data, &size) == B_OK) { 1667 PRINT(("updated keyinfo\n")); 1668 if (size == sizeof(fKeyInfo.key_states)) 1669 memcpy(fKeyInfo.key_states, data, size); 1670 } else { 1671 event->AddData("states", B_UINT8_TYPE, fKeyInfo.key_states, 1672 sizeof(fKeyInfo.key_states)); 1673 } 1674 1675 PRINT(("keyinfo %ld %ld\n", size, (ssize_t)sizeof(fKeyInfo.key_states))); 1676 break; 1677 } 1678 1679 default: 1680 break; 1681 } 1682 1683 #if defined(HAIKU_TARGET_PLATFORM_HAIKU) && defined(USING_MESSAGE4) 1684 BMessenger reply; 1685 BMessage::Private messagePrivate(event); 1686 return messagePrivate.SendMessage(fAppServerPort, 0, true, 0, reply); 1687 #else 1688 ssize_t length = event->FlattenedSize(); 1689 char buffer[length]; 1690 status_t err; 1691 if ((err = event->Flatten(buffer,length)) < B_OK) 1692 return err; 1693 1694 return write_port(fAppServerPort, 0, buffer, length); 1695 #endif 1696 } 1697 1698 1699 // #pragma mark - 1700 1701 1702 extern "C" void 1703 RegisterDevices(input_device_ref** devices) 1704 { 1705 CALLED(); 1706 }; 1707 1708 1709 BView * 1710 instantiate_deskbar_item() 1711 { 1712 return new MethodReplicant(INPUTSERVER_SIGNATURE); 1713 } 1714 1715 1716 int 1717 main() 1718 { 1719 InputServer *inputServer = new InputServer; 1720 1721 inputServer->Run(); 1722 delete inputServer; 1723 1724 return 0; 1725 } 1726 1727 1728