1 /* 2 * Copyright 2019-2020, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Preetpal Kaur <preetpalok123@gmail.com> 7 * Adrien Destugues <pulkomandy@gmail.com> 8 */ 9 10 11 #include <CardLayout.h> 12 #include <CardView.h> 13 #include <Catalog.h> 14 #include <Control.h> 15 #include <ControlLook.h> 16 #include <LayoutBuilder.h> 17 #include <ScrollView.h> 18 19 #include <private/input/InputServerTypes.h> 20 21 #include "InputConstants.h" 22 #include "InputDeviceView.h" 23 #include "InputKeyboard.h" 24 #include "InputMouse.h" 25 #include "InputTouchpadPref.h" 26 #include "InputTouchpadPrefView.h" 27 #include "InputWindow.h" 28 #include "MouseSettings.h" 29 #include "SettingsView.h" 30 31 #undef B_TRANSLATION_CONTEXT 32 #define B_TRANSLATION_CONTEXT "InputWindow" 33 34 35 InputWindow::InputWindow(BRect rect) 36 : 37 BWindow(rect, B_TRANSLATE_SYSTEM_NAME("Input"), B_TITLED_WINDOW, 38 B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS 39 | B_AUTO_UPDATE_SIZE_LIMITS | B_QUIT_ON_WINDOW_CLOSE) 40 { 41 fDeviceListView = new BListView(B_TRANSLATE("Device List")); 42 fDeviceListView->SetSelectionMessage(new BMessage(ITEM_SELECTED)); 43 fDeviceListView->SetExplicitMinSize( 44 BSize(be_control_look->ComposeIconSize(32).Width() 45 + fDeviceListView->StringWidth("Extended PS/2 Mouse 1"), 46 B_SIZE_UNSET)); 47 48 BScrollView* scrollView = new BScrollView( 49 "scrollView", fDeviceListView, 0, false, B_FANCY_BORDER); 50 fCardView = new BCardView(); 51 52 BLayoutBuilder::Group<>(this, B_HORIZONTAL, 10) 53 .SetInsets(B_USE_WINDOW_SPACING) 54 .Add(scrollView, 1) 55 .Add(fCardView, 3); 56 57 FindDevice(); 58 } 59 60 61 void 62 InputWindow::MessageReceived(BMessage* message) 63 { 64 switch (message->what) { 65 case ITEM_SELECTED: 66 { 67 int32 index = message->GetInt32("index", 0); 68 if (index >= 0) 69 fCardView->CardLayout()->SetVisibleItem(index); 70 break; 71 } 72 case kMsgMouseType: 73 case kMsgMouseMap: 74 case kMsgMouseFocusMode: 75 case kMsgFollowsMouseMode: 76 case kMsgAcceptFirstClick: 77 case kMsgDoubleClickSpeed: 78 case kMsgMouseSpeed: 79 case kMsgAccelerationFactor: 80 case kMsgDefaults: 81 case kMsgRevert: 82 { 83 PostMessage( 84 message, fCardView->CardLayout()->VisibleItem()->View()); 85 break; 86 } 87 case SCROLL_AREA_CHANGED: 88 case SCROLL_CONTROL_CHANGED: 89 case TAP_CONTROL_CHANGED: 90 case DEFAULT_SETTINGS: 91 case REVERT_SETTINGS: 92 { 93 PostMessage( 94 message, fCardView->CardLayout()->VisibleItem()->View()); 95 break; 96 } 97 case kMsgSliderrepeatrate: 98 case kMsgSliderdelayrate: 99 { 100 PostMessage( 101 message, fCardView->CardLayout()->VisibleItem()->View()); 102 break; 103 } 104 105 case B_INPUT_DEVICES_CHANGED: 106 { 107 int32 operation = message->FindInt32("be:opcode"); 108 BString name = message->FindString("be:device_name"); 109 110 if (operation == B_INPUT_DEVICE_ADDED) { 111 BInputDevice* device = find_input_device(name); 112 if (device) 113 AddDevice(device); 114 } else if (operation == B_INPUT_DEVICE_REMOVED) { 115 for (int i = 0; i < fDeviceListView->CountItems(); i++) { 116 DeviceListItemView* item 117 = dynamic_cast<DeviceListItemView*>( 118 fDeviceListView->ItemAt(i)); 119 if (item != NULL && item->Label() == name) { 120 fDeviceListView->RemoveItem(i); 121 BView* settings = fCardView->ChildAt(i); 122 fCardView->RemoveChild(settings); 123 delete settings; 124 break; 125 } 126 } 127 } 128 129 break; 130 } 131 132 default: 133 BWindow::MessageReceived(message); 134 break; 135 } 136 } 137 138 139 void 140 InputWindow::Show() 141 { 142 CenterOnScreen(); 143 BWindow::Show(); 144 watch_input_devices(this, true); 145 } 146 147 148 void 149 InputWindow::Hide() 150 { 151 BWindow::Hide(); 152 watch_input_devices(this, false); 153 } 154 155 156 status_t 157 InputWindow::FindDevice() 158 { 159 BList devList; 160 status_t status = get_input_devices(&devList); 161 if (status != B_OK) 162 return status; 163 164 int32 i = 0; 165 166 while (true) { 167 BInputDevice* dev = (BInputDevice*)devList.ItemAt(i); 168 if (dev == NULL) 169 break; 170 i++; 171 172 AddDevice(dev); 173 } 174 175 return B_OK; 176 } 177 178 179 void 180 InputWindow::AddDevice(BInputDevice* dev) 181 { 182 BString name = dev->Name(); 183 184 if (dev->Type() == B_POINTING_DEVICE && name.FindFirst("Touchpad") >= 0) { 185 TouchpadPrefView* view = new TouchpadPrefView(dev); 186 fCardView->AddChild(view); 187 188 DeviceListItemView* touchpad 189 = new DeviceListItemView(name, TOUCHPAD_TYPE); 190 fDeviceListView->AddItem(touchpad); 191 } else if (dev->Type() == B_POINTING_DEVICE) { 192 MouseSettings* settings; 193 settings = fMultipleMouseSettings.AddMouseSettings(name); 194 195 InputMouse* view = new InputMouse(dev, settings); 196 fCardView->AddChild(view); 197 198 DeviceListItemView* mouse = new DeviceListItemView(name, MOUSE_TYPE); 199 fDeviceListView->AddItem(mouse); 200 } else if (dev->Type() == B_KEYBOARD_DEVICE) { 201 InputKeyboard* view = new InputKeyboard(dev); 202 fCardView->AddChild(view); 203 204 DeviceListItemView* keyboard 205 = new DeviceListItemView(name, KEYBOARD_TYPE); 206 fDeviceListView->AddItem(keyboard); 207 } else 208 delete dev; 209 } 210