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