xref: /haiku/src/preferences/input/InputWindow.cpp (revision 15fb7d88e971c4d6c787c6a3a5c159afb1ebf77b)
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 <SplitView.h>
22 #include <Screen.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 	FindDevice();
45 
46 	BLayoutBuilder::Group<>(this, B_HORIZONTAL, 10)
47 		.SetInsets(B_USE_WINDOW_SPACING)
48 		.Add(fDeviceListView)
49 		.AddGroup(B_VERTICAL, 0)
50 			.Add(fCardView)
51 		.End();
52 }
53 
54 void
55 InputWindow::MessageReceived(BMessage* message)
56 {
57 	switch (message->what) {
58 		case ITEM_SELECTED:
59 		{
60 			int32 name = message->GetInt32("index", 0);
61 			fCardView->CardLayout()->SetVisibleItem(name);
62 		}
63 		case kMsgMouseType:
64 		case kMsgMouseMap:
65 		case kMsgMouseFocusMode:
66 		case kMsgFollowsMouseMode:
67 		case kMsgAcceptFirstClick:
68 		case kMsgDoubleClickSpeed:
69 		case kMsgMouseSpeed:
70 		case kMsgAccelerationFactor:
71 		case kMsgDefaults:
72 		case kMsgRevert:
73 		{
74 			PostMessage(message,
75 				fCardView->CardLayout()->VisibleItem()->View());
76 			break;
77 		}
78 		case SCROLL_AREA_CHANGED:
79 		case SCROLL_CONTROL_CHANGED:
80 		case TAP_CONTROL_CHANGED:
81 		case DEFAULT_SETTINGS:
82 		case REVERT_SETTINGS:
83 		{
84 			PostMessage(message,
85 				fCardView->CardLayout()->VisibleItem()->View());
86 			break;
87 		}
88 		case kMsgSliderrepeatrate:
89 		case kMsgSliderdelayrate:
90 		{
91 			PostMessage(message,
92 				fCardView->CardLayout()->VisibleItem()->View());
93 			break;
94 		}
95 
96 		case IS_NOTIFY_DEVICE:
97 		{
98 			bool added = message->FindBool("added");
99 			BString name = message->FindString("name");
100 
101 			if (added) {
102 				BInputDevice* device = find_input_device(name);
103 				if (device)
104 					AddDevice(device);
105 			} else {
106 				for (int i = 0; i < fDeviceListView->fDeviceList->CountItems();
107 					i++) {
108 					BStringItem* item = dynamic_cast<BStringItem*>(
109 						fDeviceListView->fDeviceList->ItemAt(i));
110 					if (item->Text() == name) {
111 						fDeviceListView->fDeviceList->RemoveItem(i);
112 						BView* settings = fCardView->ChildAt(i);
113 						fCardView->RemoveChild(settings);
114 						delete settings;
115 						break;
116 					}
117 				}
118 			}
119 
120 			break;
121 		}
122 
123 		default:
124 			BWindow::MessageReceived(message);
125 			break;
126 	}
127 }
128 
129 
130 void
131 InputWindow::Show()
132 {
133 	CenterOnScreen();
134 	BWindow::Show();
135 	status_t x = watch_input_devices(this, true);
136 	puts(strerror(x));
137 }
138 
139 
140 void
141 InputWindow::Hide()
142 {
143 	BWindow::Hide();
144 	watch_input_devices(this, false);
145 }
146 
147 
148 status_t
149 InputWindow::FindDevice()
150 {
151 	BList devList;
152 	status_t status = get_input_devices(&devList);
153 	if (status != B_OK)
154 		return status;
155 
156 	int32 i = 0;
157 
158 	fDeviceListView = new DeviceListView(B_TRANSLATE("Device List"));
159 	fCardView = new BCardView();
160 
161 	while (true) {
162 		BInputDevice* dev = (BInputDevice*)devList.ItemAt(i);
163 		if (dev == NULL) {
164 			break;
165 		}
166 		i++;
167 
168 		AddDevice(dev);
169 	}
170 
171 	return B_OK;
172 }
173 
174 
175 void
176 InputWindow::AddDevice(BInputDevice* dev)
177 {
178 	BString name = dev->Name();
179 
180 	if (dev->Type() == B_POINTING_DEVICE
181 		&& name.FindFirst("Touchpad") >= 0) {
182 
183 		TouchpadPrefView* view = new TouchpadPrefView(dev);
184 		fCardView->AddChild(view);
185 		fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
186 	} else if (dev->Type() == B_POINTING_DEVICE) {
187 		InputMouse* view = new InputMouse(dev);
188 		fCardView->AddChild(view);
189 		fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
190 	} else if (dev->Type() == B_KEYBOARD_DEVICE) {
191 		InputKeyboard* view = new InputKeyboard(dev);
192 		fCardView->AddChild(view);
193 		fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
194 	} else {
195 		delete dev;
196 	}
197 }
198