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