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