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