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