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