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