]> git.zerfleddert.de Git - proxmark3-svn/blob - winsrc/gui.cpp
Fixed a typo in command.cpp, moved Changelog to CHANGES.TXT for better coherence.
[proxmark3-svn] / winsrc / gui.cpp
1 //-----------------------------------------------------------------------------
2 // Routines for the user interface when doing interactive things with prox
3 // cards; this is basically a command line thing, in one window, and then
4 // another window to do the graphs.
5 // Jonathan Westhues, Sept 2005
6 //-----------------------------------------------------------------------------
7 #include <windows.h>
8 #include <limits.h>
9 #include <commctrl.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <math.h>
13
14 #include "prox.h"
15
16 #define oops() do { \
17 char line[100]; \
18 sprintf(line, "Internal error at line %d file '%s'", __LINE__, \
19 __FILE__); \
20 MessageBox(NULL, line, "Error", MB_ICONERROR); \
21 exit(-1); \
22 } while(0)
23
24 void dbp(char *str, ...)
25 {
26 va_list f;
27 char buf[1024];
28 va_start(f, str);
29 vsprintf(buf, str, f);
30 OutputDebugString(buf);
31 OutputDebugString("\n");
32 }
33
34 int GraphBuffer[MAX_GRAPH_TRACE_LEN];
35 int GraphTraceLen;
36
37 HPEN GreyPen, GreenPen, WhitePen, YellowPen;
38 HBRUSH GreenBrush, YellowBrush;
39
40 static int GraphStart = 0;
41 static double GraphPixelsPerPoint = 1;
42
43 static int CursorAPos;
44 static int CursorBPos;
45 double CursorScaleFactor = 1.0;
46 static HPEN CursorAPen;
47 static HPEN CursorBPen;
48
49 static HWND CommandWindow;
50 static HWND GraphWindow;
51 static HWND ScrollbackEdit;
52 static HWND CommandEdit;
53
54 #define COMMAND_HISTORY_MAX 16
55 static char CommandHistory[COMMAND_HISTORY_MAX][256];
56 static int CommandHistoryPos = -1;
57 static int CommandHistoryNext;
58
59 static HFONT MyFixedFont;
60 #define FixedFont(x) SendMessage((x), WM_SETFONT, (WPARAM)MyFixedFont, TRUE)
61
62 void ExecCmd(char *cmd)
63 {
64
65 }
66 int CommandFinished;
67
68 static void ResizeCommandWindow(void)
69 {
70 int w, h;
71 RECT r;
72 GetClientRect(CommandWindow, &r);
73 w = r.right - r.left;
74 h = r.bottom - r.top;
75 MoveWindow(ScrollbackEdit, 10, 10, w - 20, h - 50, TRUE);
76 MoveWindow(CommandEdit, 10, h - 29, w - 20, 22, TRUE);
77 }
78
79 void RepaintGraphWindow(void)
80 {
81 InvalidateRect(GraphWindow, NULL, TRUE);
82 }
83
84 static LRESULT CALLBACK
85 CommandWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
86 {
87 switch (msg) {
88 case WM_DESTROY:
89 case WM_QUIT:
90 exit(0);
91 return 0;
92
93 case WM_SIZE:
94 ResizeCommandWindow();
95 return 0;
96
97 case WM_SETFOCUS:
98 SetFocus(CommandEdit);
99 break;
100
101 default:
102 return DefWindowProc(hwnd, msg, wParam, lParam);
103 }
104
105 return 1;
106 }
107
108 static void PaintGraph(HDC hdc)
109 {
110 HBRUSH brush;
111 HPEN pen;
112
113 brush = GreenBrush;
114 pen = GreenPen;
115
116 if(GraphStart < 0) {
117 GraphStart = 0;
118 }
119
120 RECT r;
121 GetClientRect(GraphWindow, &r);
122
123 SelectObject(hdc, WhitePen);
124
125 MoveToEx(hdc, r.left + 40, r.top, NULL);
126 LineTo(hdc, r.left + 40, r.bottom);
127
128 int zeroHeight = r.top + (r.bottom - r.top) / 2;
129 SelectObject(hdc, GreyPen);
130 MoveToEx(hdc, r.left, zeroHeight, NULL);
131 LineTo(hdc, r.right, zeroHeight);
132
133 int startMax =
134 (GraphTraceLen - (int)((r.right - r.left - 40) / GraphPixelsPerPoint));
135 if(startMax < 0) {
136 startMax = 0;
137 }
138 if(GraphStart > startMax) {
139 GraphStart = startMax;
140 }
141
142 int absYMax = 1;
143
144 SelectObject(hdc, pen);
145
146 int i;
147 for(i = GraphStart; ; i++) {
148 if(i >= GraphTraceLen) {
149 break;
150 }
151 if(fabs((double)GraphBuffer[i]) > absYMax) {
152 absYMax = (int)fabs((double)GraphBuffer[i]);
153 }
154 int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
155 if(x > r.right) {
156 break;
157 }
158 }
159
160 absYMax = (int)(absYMax*1.2 + 1);
161 SelectObject(hdc, MyFixedFont);
162 SetTextColor(hdc, RGB(255, 255, 255));
163 SetBkColor(hdc, RGB(0, 0, 0));
164
165 // number of points that will be plotted
166 int span = (int)((r.right - r.left) / GraphPixelsPerPoint);
167 // one label every 100 pixels, let us say
168 int labels = (r.right - r.left - 40) / 100;
169 if(labels <= 0) labels = 1;
170 int pointsPerLabel = span / labels;
171 if(pointsPerLabel <= 0) pointsPerLabel = 1;
172
173 int yMin = INT_MAX;
174 int yMax = INT_MIN;
175 int yMean = 0;
176 int n = 0;
177
178 for(i = GraphStart; ; i++) {
179 if(i >= GraphTraceLen) {
180 break;
181 }
182 int x = 40 + (int)((i - GraphStart)*GraphPixelsPerPoint);
183 if(x > r.right + GraphPixelsPerPoint) {
184 break;
185 }
186
187 int y = GraphBuffer[i];
188 if(y < yMin) {
189 yMin = y;
190 }
191 if(y > yMax) {
192 yMax = y;
193 }
194 yMean += y;
195 n++;
196
197 y = (y * (r.top - r.bottom) / (2*absYMax)) + zeroHeight;
198 if(i == GraphStart) {
199 MoveToEx(hdc, x, y, NULL);
200 } else {
201 LineTo(hdc, x, y);
202 }
203
204 if(GraphPixelsPerPoint > 10) {
205 RECT f;
206 f.left = x - 3;
207 f.top = y - 3;
208 f.right = x + 3;
209 f.bottom = y + 3;
210 FillRect(hdc, &f, brush);
211 }
212
213 if(((i - GraphStart) % pointsPerLabel == 0) && i != GraphStart) {
214 SelectObject(hdc, WhitePen);
215 MoveToEx(hdc, x, zeroHeight - 3, NULL);
216 LineTo(hdc, x, zeroHeight + 3);
217
218 char str[100];
219 sprintf(str, "+%d", (i - GraphStart));
220 SIZE size;
221 GetTextExtentPoint32(hdc, str, strlen(str), &size);
222 TextOut(hdc, x - size.cx, zeroHeight + 8, str, strlen(str));
223
224 SelectObject(hdc, pen);
225 MoveToEx(hdc, x, y, NULL);
226 }
227
228 if(i == CursorAPos || i == CursorBPos) {
229 if(i == CursorAPos) {
230 SelectObject(hdc, CursorAPen);
231 } else {
232 SelectObject(hdc, CursorBPen);
233 }
234 MoveToEx(hdc, x, r.top, NULL);
235 LineTo(hdc, x, r.bottom);
236
237 SelectObject(hdc, pen);
238 MoveToEx(hdc, x, y, NULL);
239 }
240 }
241
242 if(n != 0) {
243 yMean /= n;
244 }
245
246 char str[100];
247 sprintf(str, "@%d max=%d min=%d mean=%d n=%d/%d dt=%d [%.3f]",
248 GraphStart, yMax, yMin, yMean, n, GraphTraceLen,
249 CursorBPos - CursorAPos, (CursorBPos - CursorAPos)/CursorScaleFactor);
250 TextOut(hdc, 50, r.bottom - 20, str, strlen(str));
251 }
252
253 static LRESULT CALLBACK
254 GraphWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
255 {
256 switch (msg) {
257 case WM_DESTROY:
258 case WM_QUIT:
259 GraphWindow = NULL;
260 return DefWindowProc(hwnd, msg, wParam, lParam);
261
262 case WM_SIZE:
263 RepaintGraphWindow();
264 return 0;
265
266 case WM_PAINT: {
267 PAINTSTRUCT ps;
268 HDC hdc = BeginPaint(hwnd, &ps);
269 if(GraphStart < 0) {
270 GraphStart = 0;
271 }
272 // This draws the trace.
273 PaintGraph(hdc);
274 EndPaint(hwnd, &ps);
275 break;
276 }
277 case WM_KEYDOWN:
278 switch(wParam) {
279 case VK_DOWN:
280 if(GraphPixelsPerPoint <= 50) {
281 GraphPixelsPerPoint *= 2;
282 }
283 break;
284
285 case VK_UP:
286 if(GraphPixelsPerPoint >= 0.02) {
287 GraphPixelsPerPoint /= 2;
288 }
289 break;
290
291 case VK_RIGHT:
292 if(GraphPixelsPerPoint < 20) {
293 GraphStart += (int)(20 / GraphPixelsPerPoint);
294 } else {
295 GraphStart++;
296 }
297 break;
298
299 case VK_LEFT:
300 if(GraphPixelsPerPoint < 20) {
301 GraphStart -= (int)(20 / GraphPixelsPerPoint);
302 } else {
303 GraphStart--;
304 }
305 break;
306
307 default:
308 goto nopaint;
309 }
310 RepaintGraphWindow();
311 nopaint:
312 break;
313
314 case WM_LBUTTONDOWN:
315 case WM_RBUTTONDOWN: {
316 int x = LOWORD(lParam);
317 x -= 40;
318 x = (int)(x / GraphPixelsPerPoint);
319 x += GraphStart;
320 if(msg == WM_LBUTTONDOWN) {
321 CursorAPos = x;
322 } else {
323 CursorBPos = x;
324 }
325 RepaintGraphWindow();
326 break;
327 }
328 default:
329 return DefWindowProc(hwnd, msg, wParam, lParam);
330 }
331
332 return 1;
333 }
334
335 void PrintToScrollback(char *fmt, ...)
336 {
337 va_list f;
338 char str[1024];
339 strcpy(str, "\r\n");
340 va_start(f, fmt);
341 vsprintf(str+2, fmt, f);
342
343 static char TextBuf[1024*32];
344 SendMessage(ScrollbackEdit, WM_GETTEXT, (WPARAM)sizeof(TextBuf),
345 (LPARAM)TextBuf);
346
347 if(strlen(TextBuf) + strlen(str) + 1 <= sizeof(TextBuf)) {
348 strcat(TextBuf, str);
349 } else {
350 lstrcpyn(TextBuf, str, sizeof(TextBuf));
351 }
352
353 SendMessage(ScrollbackEdit, WM_SETTEXT, 0, (LPARAM)TextBuf);
354 SendMessage(ScrollbackEdit, EM_LINESCROLL, 0, (LPARAM)INT_MAX);
355 }
356
357 void ShowGraphWindow(void)
358 {
359 if(GraphWindow) return;
360
361 GraphWindow = CreateWindowEx(0, "Graph", "graphed",
362 WS_OVERLAPPED | WS_BORDER | WS_MINIMIZEBOX | WS_SYSMENU |
363 WS_SIZEBOX | WS_VISIBLE, 200, 150, 600, 500, NULL, NULL, NULL,
364 NULL);
365 if(!GraphWindow) oops();
366 }
367
368 void HideGraphWindow(void)
369 {
370 if(GraphWindow) {
371 DestroyWindow(GraphWindow);
372 GraphWindow = NULL;
373 }
374 }
375
376 static void SetCommandEditTo(char *str)
377 {
378 SendMessage(CommandEdit, WM_SETTEXT, 0, (LPARAM)str);
379 SendMessage(CommandEdit, EM_SETSEL, strlen(str), strlen(str));
380 }
381
382 void ShowGui(void)
383 {
384 WNDCLASSEX wc;
385 memset(&wc, 0, sizeof(wc));
386 wc.cbSize = sizeof(wc);
387
388 wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC;
389 wc.lpfnWndProc = (WNDPROC)CommandWindowProc;
390 wc.hInstance = NULL;
391 wc.hbrBackground = (HBRUSH)(COLOR_BTNSHADOW);
392 wc.lpszClassName = "Command";
393 wc.lpszMenuName = NULL;
394 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
395
396 if(!RegisterClassEx(&wc)) oops();
397
398 wc.lpszClassName = "Graph";
399 wc.lpfnWndProc = (WNDPROC)GraphWindowProc;
400 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
401
402 if(!RegisterClassEx(&wc)) oops();
403
404 CommandWindow = CreateWindowEx(0, "Command", "prox",
405 WS_OVERLAPPED | WS_BORDER | WS_MINIMIZEBOX | WS_SYSMENU |
406 WS_SIZEBOX | WS_VISIBLE, 20, 20, 500, 400, NULL, NULL, NULL,
407 NULL);
408 if(!CommandWindow) oops();
409
410 ScrollbackEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "",
411 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_MULTILINE |
412 ES_AUTOVSCROLL | WS_VSCROLL, 0, 0, 0, 0, CommandWindow, NULL,
413 NULL, NULL);
414
415 CommandEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "",
416 WS_CHILD | WS_CLIPSIBLINGS | WS_TABSTOP | WS_VISIBLE |
417 ES_AUTOHSCROLL, 0, 0, 0, 0, CommandWindow, NULL, NULL, NULL);
418
419 MyFixedFont = CreateFont(14, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
420 ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
421 FF_DONTCARE, "Lucida Console");
422 if(!MyFixedFont)
423 MyFixedFont = (HFONT)GetStockObject(SYSTEM_FONT);
424
425 FixedFont(ScrollbackEdit);
426 FixedFont(CommandEdit);
427
428 ResizeCommandWindow();
429 SetFocus(CommandEdit);
430
431 PrintToScrollback(">> Started prox, built " __DATE__ " " __TIME__);
432 PrintToScrollback(">> Connected to device");
433
434 GreyPen = CreatePen(PS_SOLID, 1, RGB(100, 100, 100));
435 GreenPen = CreatePen(PS_SOLID, 1, RGB(100, 255, 100));
436 YellowPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
437 GreenBrush = CreateSolidBrush(RGB(100, 255, 100));
438 YellowBrush = CreateSolidBrush(RGB(255, 255, 0));
439 WhitePen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
440
441 CursorAPen = CreatePen(PS_DASH, 1, RGB(255, 255, 0));
442 CursorBPen = CreatePen(PS_DASH, 1, RGB(255, 0, 255));
443
444 MSG msg;
445 for(;;) {
446 if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
447 if(msg.message == WM_KEYDOWN && msg.wParam == VK_RETURN) {
448 char got[1024];
449 SendMessage(CommandEdit, WM_GETTEXT, (WPARAM)sizeof(got),
450 (LPARAM)got);
451
452 if(strcmp(got, "cls")==0) {
453 SendMessage(ScrollbackEdit, WM_SETTEXT, 0, (LPARAM)"");
454 } else {
455 CommandReceived(got);
456 }
457 SendMessage(CommandEdit, WM_SETTEXT, 0, (LPARAM)"");
458
459 // Insert it into the command history, unless it is
460 // identical to the previous command in the history.
461 int prev = CommandHistoryNext - 1;
462 if(prev < 0) prev += COMMAND_HISTORY_MAX;
463 if(strcmp(CommandHistory[prev], got) != 0) {
464 strcpy(CommandHistory[CommandHistoryNext], got);
465 CommandHistoryNext++;
466 if(CommandHistoryNext == COMMAND_HISTORY_MAX) {
467 CommandHistoryNext = 0;
468 }
469 }
470 CommandHistoryPos = -1;
471 } else if(msg.message == WM_KEYDOWN && msg.wParam == VK_UP &&
472 msg.hwnd == CommandEdit)
473 {
474 if(CommandHistoryPos == -1) {
475 CommandHistoryPos = CommandHistoryNext;
476 }
477 CommandHistoryPos--;
478 if(CommandHistoryPos < 0) {
479 CommandHistoryPos = COMMAND_HISTORY_MAX-1;
480 }
481 SetCommandEditTo(CommandHistory[CommandHistoryPos]);
482 } else if(msg.message == WM_KEYDOWN && msg.wParam == VK_DOWN &&
483 msg.hwnd == CommandEdit)
484 {
485 CommandHistoryPos++;
486 if(CommandHistoryPos >= COMMAND_HISTORY_MAX) {
487 CommandHistoryPos = 0;
488 }
489 SetCommandEditTo(CommandHistory[CommandHistoryPos]);
490 } else if(msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE &&
491 msg.hwnd == CommandEdit)
492 {
493 SendMessage(CommandEdit, WM_SETTEXT, 0, (LPARAM)"");
494 } else {
495 if(msg.message == WM_KEYDOWN) {
496 CommandHistoryPos = -1;
497 }
498 TranslateMessage(&msg);
499 DispatchMessage(&msg);
500 }
501 }
502
503 UsbCommand c;
504 if(ReceiveCommandPoll(&c)) {
505 UsbCommandReceived(&c);
506 }
507
508 Sleep(10);
509 }
510 }
Impressum, Datenschutz