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