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