1e853104403f9c02c8aa3b7302dc84e3fc20aeb2
[reactos.git] / dll / win32 / serialui / serialui.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS SerialUI DLL
4 * FILE: serialui.c
5 * PUROPSE: A dialog box to configure COM port.
6 * Functions to set (and get too) default configuration.
7 * PROGRAMMERS: Saveliy Tretiakov (saveliyt@mail.ru)
8 * REVISIONS:
9 * ST (05/04/2005) Created. Implemented drvCommConfigDialog.
10 */
11
12 #include "serialui.h"
13
14 static HINSTANCE hDllInstance;
15
16 /************************************
17 *
18 * DATA
19 *
20 ************************************/
21
22 const DWORD Bauds[] = {
23 CBR_110,
24 CBR_300,
25 CBR_600,
26 CBR_1200,
27 CBR_2400,
28 CBR_4800,
29 CBR_9600,
30 CBR_14400,
31 CBR_19200,
32 CBR_38400,
33 CBR_56000,
34 CBR_57600,
35 CBR_115200,
36 CBR_128000,
37 CBR_256000,
38 0
39 };
40
41 const BYTE ByteSizes[] = {
42 5,
43 6,
44 7,
45 8,
46 0
47 };
48
49
50 const PARITY_INFO Parities[] = {
51 { EVENPARITY, IDS_EVENPARITY },
52 { MARKPARITY, IDS_MARKPARITY },
53 { NOPARITY, IDS_NOPARITY },
54 { ODDPARITY, IDS_ODDPARITY },
55 { SPACEPARITY, IDS_SPACEPARITY },
56 { 0, 0 }
57 };
58
59 const STOPBIT_INFO StopBits[] = {
60 { ONESTOPBIT, IDS_ONESTOPBIT },
61 { ONE5STOPBITS, IDS_ONE5STOPBITS },
62 { TWOSTOPBITS, IDS_TWOSTOPBITS },
63 { 0, 0 }
64 };
65
66
67 /************************************
68 *
69 * DLLMAIN
70 *
71 ************************************/
72
73 BOOL
74 WINAPI
75 DllMain(HINSTANCE hInstance,
76 DWORD dwReason,
77 LPVOID reserved)
78 {
79 if(dwReason==DLL_PROCESS_ATTACH)
80 {
81 hDllInstance = hInstance;
82 }
83 else if(dwReason==DLL_THREAD_ATTACH)
84 {
85 DisableThreadLibraryCalls(hInstance);
86 }
87
88 return TRUE;
89 }
90
91
92 /************************************
93 *
94 * EXPORTS
95 *
96 ************************************/
97
98 /*
99 * @implemented
100 */
101 DWORD WINAPI drvCommConfigDialogW(LPCWSTR lpszDevice,
102 HWND hWnd,
103 LPCOMMCONFIG lpCommConfig)
104 {
105 DIALOG_INFO DialogInfo;
106
107 if(!lpszDevice || !lpCommConfig)
108 {
109 return ERROR_INVALID_PARAMETER;
110 }
111
112 DialogInfo.lpszDevice = lpszDevice;
113 DialogInfo.lpCC = lpCommConfig;
114
115 return DialogBoxParamW(hDllInstance, MAKEINTRESOURCEW(IDD_COMMDLG),
116 hWnd, CommDlgProc, (LPARAM)&DialogInfo);
117 }
118
119 /*
120 * @implemented
121 */
122 DWORD WINAPI drvCommConfigDialogA(LPCSTR lpszDevice,
123 HWND hWnd,
124 LPCOMMCONFIG lpCommConfig)
125 {
126 BOOL result;
127 UINT len;
128 WCHAR *wstr;
129
130 len = MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, NULL, 0);
131 if((wstr = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR))))
132 {
133 MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, wstr, len);
134 result = drvCommConfigDialogW(wstr, hWnd, lpCommConfig);
135 HeapFree(GetProcessHeap(), 0, wstr);
136 return result;
137 }
138 else
139 return ERROR_NOT_ENOUGH_MEMORY;
140 }
141
142 /*
143 * @unimplemented
144 */
145 DWORD WINAPI drvSetDefaultCommConfigW(LPCWSTR lpszDevice,
146 LPCOMMCONFIG lpCommConfig,
147 DWORD dwSize)
148 {
149 UNIMPLEMENTED
150 }
151
152 /*
153 * @unimplemented
154 */
155 DWORD WINAPI drvSetDefaultCommConfigA(LPCSTR lpszDevice,
156 LPCOMMCONFIG lpCommConfig,
157 DWORD dwSize)
158 {
159 UNIMPLEMENTED
160 }
161
162 /*
163 * @unimplemented
164 */
165 DWORD WINAPI drvGetDefaultCommConfigW(LPCWSTR lpszDevice,
166 LPCOMMCONFIG lpCommConfig,
167 LPDWORD lpdwSize)
168 {
169 UNIMPLEMENTED
170 }
171
172 /*
173 * @unimplemented
174 */
175 DWORD WINAPI drvGetDefaultCommConfigA(LPCSTR lpszDevice,
176 LPCOMMCONFIG lpCommConfig,
177 LPDWORD lpdwSize)
178 {
179 UNIMPLEMENTED
180 }
181
182
183 /************************************
184 *
185 * INTERNALS
186 *
187 ************************************/
188
189 INT_PTR
190 CALLBACK
191 CommDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
192 {
193 LPDIALOG_INFO lpDlgInfo = NULL;
194 HWND hBox;
195
196 switch (Msg)
197 {
198
199 case WM_INITDIALOG:
200 {
201 WCHAR wstr[255];
202 RECT rc, rcDlg, rcOwner;
203 HWND hOwner;
204 INT i;
205
206 lpDlgInfo = (LPDIALOG_INFO)lParam;
207 SetWindowLongPtrW(hDlg, DWL_USER, (LONG_PTR)lpDlgInfo);
208
209 /* Set title */
210 if(LoadStringW(hDllInstance, IDS_TITLE, wstr, sizeof(wstr) / sizeof(wstr[0])))
211 {
212 SetWindowTextW(hDlg, wstr);
213 }
214
215 /* FIXME - this won't work correctly systems with multiple monitors! */
216 if(!(hOwner = GetParent(hDlg)))
217 hOwner = GetDesktopWindow();
218
219 /* Position dialog in the center of owner window */
220 GetWindowRect(hOwner, &rcOwner);
221 GetWindowRect(hDlg, &rcDlg);
222 CopyRect(&rc, &rcOwner);
223 OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
224 OffsetRect(&rc, -rc.left, -rc.top);
225 OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
226 SetWindowPos(hDlg, HWND_TOP,
227 rcOwner.left + (rc.right / 2),
228 rcOwner.top + (rc.bottom / 2),
229 0, 0, SWP_NOSIZE);
230
231 /* Initialize baud rate combo */
232 if(!(hBox = GetDlgItem(hDlg, IDC_BAUDRATE)))
233 EndDialog(hDlg, ERROR_CANCELLED);
234
235 for(i = 0; Bauds[i]; i++)
236 {
237 wsprintf(wstr, L"%d", Bauds[i]);
238 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
239 if(Bauds[i] == lpDlgInfo->lpCC->dcb.BaudRate)
240 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
241 }
242
243 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR)
244 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BAUD_INDEX, 0);
245
246 /* Initialize byte size combo */
247 if(!(hBox = GetDlgItem(hDlg, IDC_BYTESIZE)))
248 EndDialog(hDlg, ERROR_CANCELLED);
249
250 for(i = 0; ByteSizes[i]; i++)
251 {
252 wsprintf(wstr, L"%d", Bauds[i]);
253 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
254 if(ByteSizes[i] == lpDlgInfo->lpCC->dcb.ByteSize)
255 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
256 }
257
258 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR)
259 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BYTESIZE_INDEX, 0);
260
261 /* Initialize parity combo */
262 if(!(hBox = GetDlgItem(hDlg, IDC_PARITY)))
263 EndDialog(hDlg, ERROR_CANCELLED);
264
265 for(i = 0; Parities[i].StrId; i++)
266 {
267 if(LoadStringW(hDllInstance, Parities[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0])))
268 {
269 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
270 if(Parities[i].Parity == lpDlgInfo->lpCC->dcb.Parity)
271 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
272 }
273 }
274
275 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR)
276 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_PARITY_INDEX, 0);
277
278 /* Initialize stop bits combo */
279 if(!(hBox = GetDlgItem(hDlg, IDC_STOPBITS)))
280 EndDialog(hDlg, ERROR_CANCELLED);
281
282 for(i = 0; StopBits[i].StrId; i++)
283 {
284 if(LoadStringW(hDllInstance, StopBits[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0])))
285 {
286 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
287 if(StopBits[i].StopBit == lpDlgInfo->lpCC->dcb.StopBits)
288 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
289 }
290 }
291
292 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR)
293 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_STOPBITS_INDEX, 0);
294
295 /* Initialize flow control combo */
296 if(!(hBox = GetDlgItem(hDlg, IDC_FLOW)))
297 EndDialog(hDlg, ERROR_CANCELLED);
298
299 if(LoadStringW(hDllInstance, IDS_FC_NO, wstr, sizeof(wstr) / sizeof(wstr[0])))
300 {
301 SendMessageW(hBox, CB_INSERTSTRING, 0, (LPARAM)wstr);
302 SendMessageW(hBox, CB_SETCURSEL, 0, 0);
303 lpDlgInfo->InitialFlowIndex = 0;
304 }
305
306
307 if(LoadStringW(hDllInstance, IDS_FC_CTSRTS, wstr, sizeof(wstr) / sizeof(wstr[0])))
308 {
309 SendMessageW(hBox, CB_INSERTSTRING, 1, (LPARAM)wstr);
310 if(lpDlgInfo->lpCC->dcb.fRtsControl == RTS_CONTROL_HANDSHAKE
311 || lpDlgInfo->lpCC->dcb.fOutxCtsFlow != FALSE)
312 {
313 SendMessageW(hBox, CB_SETCURSEL, 1, 0);
314 lpDlgInfo->InitialFlowIndex = 1;
315 }
316 }
317
318 if(LoadStringW(hDllInstance, IDS_FC_XONXOFF, wstr, sizeof(wstr) / sizeof(wstr[0])))
319 {
320 SendMessageW(hBox, CB_INSERTSTRING, 2, (LPARAM)wstr);
321 if(lpDlgInfo->lpCC->dcb.fOutX || lpDlgInfo->lpCC->dcb.fInX)
322 {
323 SendMessageW(hBox, CB_SETCURSEL, 2, 0);
324 lpDlgInfo->InitialFlowIndex = 2;
325 }
326 }
327
328 /* Set focus */
329 SetFocus(GetDlgItem(hDlg, IDC_OKBTN));
330
331 return FALSE;
332 } /* WM_INITDIALOG */
333
334 case WM_COMMAND:
335 {
336 switch(wParam)
337 {
338 case IDC_CANCELBTN:
339 EndDialog(hDlg, ERROR_CANCELLED);
340 break;
341 case IDC_OKBTN:
342 OkButton(hDlg);
343 EndDialog(hDlg, ERROR_SUCCESS);
344 break;
345 }
346 return TRUE;
347 } /* WM_COMMAND */
348
349 case WM_CLOSE:
350 {
351 EndDialog(hDlg, ERROR_CANCELLED);
352 return TRUE;
353 } /* WM_CLOSE */
354
355 default:
356 return FALSE;
357 }
358
359 }
360
361
362 VOID OkButton(HWND hDlg)
363 {
364 LPDIALOG_INFO lpDlgInfo;
365 UINT Index;
366
367 lpDlgInfo = (LPDIALOG_INFO) GetWindowLongPtrW(hDlg, DWL_USER);
368
369 /* Baud rate */
370 Index = SendMessageW(GetDlgItem(hDlg, IDC_BAUDRATE), CB_GETCURSEL, 0, 0);
371 lpDlgInfo->lpCC->dcb.BaudRate = Bauds[Index];
372
373 /* Byte size */
374 Index = SendMessageW(GetDlgItem(hDlg, IDC_BYTESIZE), CB_GETCURSEL, 0, 0);
375 lpDlgInfo->lpCC->dcb.ByteSize = ByteSizes[Index];
376
377 /* Parity */
378 Index = SendMessageW(GetDlgItem(hDlg, IDC_PARITY), CB_GETCURSEL, 0, 0);
379 lpDlgInfo->lpCC->dcb.Parity = Parities[Index].Parity;
380
381 /* Stop bits */
382 Index = SendMessageW(GetDlgItem(hDlg, IDC_STOPBITS), CB_GETCURSEL, 0, 0);
383 lpDlgInfo->lpCC->dcb.StopBits = StopBits[Index].StopBit;
384
385 /* Flow Control */
386 Index = SendMessageW(GetDlgItem(hDlg, IDC_FLOW), CB_GETCURSEL, 0, 0);
387 if(lpDlgInfo->InitialFlowIndex != Index)
388 {
389 switch(Index)
390 {
391 case 0: /* NO */
392 lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
393 lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE;
394 lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE;
395 lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
396 lpDlgInfo->lpCC->dcb.fOutX = FALSE;
397 lpDlgInfo->lpCC->dcb.fInX = FALSE;
398 break;
399 case 1: /* CTS/RTS */
400 lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
401 lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
402 lpDlgInfo->lpCC->dcb.fOutxCtsFlow = TRUE;
403 lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
404 lpDlgInfo->lpCC->dcb.fOutX = FALSE;
405 lpDlgInfo->lpCC->dcb.fInX = FALSE;
406 break;
407 case 2: /* XON/XOFF */
408 lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
409 lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE;
410 lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE;
411 lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
412 lpDlgInfo->lpCC->dcb.fOutX = TRUE;
413 lpDlgInfo->lpCC->dcb.fInX = TRUE;
414 break;
415 }
416 }
417 }