]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/wingui.c
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 //-----------------------------------------------------------------------------
21 sprintf(line, "Internal error at line %d file '%s'", __LINE__, \
23 MessageBox(NULL, line, "Error", MB_ICONERROR); \
27 void dbp(char *str
, ...)
32 vsprintf(buf
, str
, f
);
33 OutputDebugString(buf
);
34 OutputDebugString("\n");
37 int GraphBuffer
[MAX_GRAPH_TRACE_LEN
];
39 int PlotGridX
, PlotGridY
;
41 HPEN GreyPenLite
, GreyPen
, GreenPen
, WhitePen
, YellowPen
;
42 HBRUSH GreenBrush
, YellowBrush
;
44 static int GraphStart
= 0;
45 static double GraphPixelsPerPoint
= 1;
47 static int CursorAPos
;
48 static int CursorBPos
;
49 double CursorScaleFactor
= 1.0;
50 static HPEN CursorAPen
;
51 static HPEN CursorBPen
;
53 static HWND CommandWindow
;
54 static HWND GraphWindow
;
55 static HWND ScrollbackEdit
;
56 static HWND CommandEdit
;
58 #define COMMAND_HISTORY_MAX 16
59 static char CommandHistory
[COMMAND_HISTORY_MAX
][256];
60 static int CommandHistoryPos
= -1;
61 static int CommandHistoryNext
;
63 static HFONT MyFixedFont
;
64 #define FixedFont(x) SendMessage((x), WM_SETFONT, (WPARAM)MyFixedFont, TRUE)
66 void ExecCmd(char *cmd
)
73 static void ResizeCommandWindow(void)
77 GetClientRect(CommandWindow
, &r
);
80 MoveWindow(ScrollbackEdit
, 10, 10, w
- 20, h
- 50, TRUE
);
81 MoveWindow(CommandEdit
, 10, h
- 29, w
- 20, 22, TRUE
);
84 void RepaintGraphWindow(void)
86 InvalidateRect(GraphWindow
, NULL
, TRUE
);
89 static LRESULT CALLBACK
90 CommandWindowProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
99 ResizeCommandWindow();
103 SetFocus(CommandEdit
);
107 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
113 static void PaintGraph(HDC hdc
)
129 GetClientRect(GraphWindow
, &r
);
130 int zeroHeight
= (r
.top
+ r
.bottom
) >> 1;
132 // plot X and Y grid lines
133 if ((PlotGridX
> 0) && ((PlotGridX
* GraphPixelsPerPoint
) > 1)) {
134 for(i
= offset
; i
< r
.right
; i
+= (int)(PlotGridX
* GraphPixelsPerPoint
)) {
135 SelectObject(hdc
, GreyPenLite
);
136 MoveToEx(hdc
, r
.left
+ i
, r
.top
, NULL
);
137 LineTo(hdc
, r
.left
+ i
, r
.bottom
);
141 if ((PlotGridY
> 0) && ((PlotGridY
* GraphPixelsPerPoint
) > 1)){
142 for(i
= 0; i
< ((r
.top
+ r
.bottom
)>>1); i
+= (int)(PlotGridY
* GraphPixelsPerPoint
)) {
143 SelectObject(hdc
, GreyPenLite
);
144 MoveToEx(hdc
, r
.left
, zeroHeight
+ i
, NULL
);
145 LineTo(hdc
, r
.right
, zeroHeight
+ i
);
146 MoveToEx(hdc
, r
.left
, zeroHeight
- i
, NULL
);
147 LineTo(hdc
, r
.right
, zeroHeight
- i
);
151 // print vertical separator white line on the left of the window
152 SelectObject(hdc
, WhitePen
);
153 MoveToEx(hdc
, r
.left
+ offset
, r
.top
, NULL
);
154 LineTo(hdc
, r
.left
+ offset
, r
.bottom
);
156 // print horizontal grey zero axis line
157 SelectObject(hdc
, GreyPen
);
158 MoveToEx(hdc
, r
.left
, zeroHeight
, NULL
);
159 LineTo(hdc
, r
.right
, zeroHeight
);
161 startMax
= (GraphTraceLen
- (int)((r
.right
- r
.left
- offset
) / GraphPixelsPerPoint
));
163 if(startMax
< 0) startMax
= 0;
164 if(GraphStart
> startMax
) GraphStart
= startMax
;
165 if(GraphStart
< 0) GraphStart
= 0;
168 SelectObject(hdc
, pen
);
170 // go over the portion of the graph to be displayed and find the largest
171 // absolute value which will be used to auto scale the graph when displayed
172 for(i
= GraphStart
; ; i
++) {
173 if(i
>= GraphTraceLen
) {
176 if(fabs((double)GraphBuffer
[i
]) > absYMax
) {
177 absYMax
= (int)fabs((double)GraphBuffer
[i
]);
179 int x
= offset
+ (int)((i
- GraphStart
)*GraphPixelsPerPoint
);
185 absYMax
= (int)(absYMax
*1.2 + 1);
186 SelectObject(hdc
, MyFixedFont
);
187 SetTextColor(hdc
, RGB(255, 255, 255));
188 SetBkColor(hdc
, RGB(0, 0, 0));
190 // number of points that will be plotted
191 double span
= (int)((r
.right
- r
.left
) / GraphPixelsPerPoint
);
193 // one label every offset pixels, let us say
194 int labels
= (r
.right
- r
.left
- offset
) / offset
;
195 if(labels
<= 0) labels
= 1;
196 // round to nearest power of 2
197 int pointsPerLabel
= (int)(log(span
/ labels
)/log(2.0));
198 if(pointsPerLabel
<= 0) pointsPerLabel
= 1;
199 pointsPerLabel
= (int)pow(2.0,pointsPerLabel
);
201 // go over the graph and plot samples and labels
202 for(i
= GraphStart
; ; i
++) {
203 if(i
>= GraphTraceLen
) {
206 int x
= offset
+ (int)((i
- GraphStart
)*GraphPixelsPerPoint
);
207 if(x
> r
.right
+ GraphPixelsPerPoint
) {
211 int y
= GraphBuffer
[i
];
212 if(y
< yMin
) yMin
= y
;
213 if(y
> yMax
) yMax
= y
;
217 y
= (y
* (r
.top
- r
.bottom
) / (2*absYMax
)) + zeroHeight
;
218 if(i
== GraphStart
) {
219 MoveToEx(hdc
, x
, y
, NULL
);
224 if(GraphPixelsPerPoint
> 10) {
230 FillRect(hdc
, &f
, brush
);
234 if(((i
- GraphStart
) % pointsPerLabel
== 0) && i
!= GraphStart
) {
235 SelectObject(hdc
, WhitePen
);
236 MoveToEx(hdc
, x
, zeroHeight
- 8, NULL
);
237 LineTo(hdc
, x
, zeroHeight
+ 8);
239 sprintf(str
, "+%d", i
);
241 GetTextExtentPoint32(hdc
, str
, strlen(str
), &size
);
242 TextOut(hdc
, x
- size
.cx
, zeroHeight
+ 8, str
, strlen(str
));
244 SelectObject(hdc
, pen
);
245 MoveToEx(hdc
, x
, y
, NULL
);
248 // plot measurement cursors
249 if(i
== CursorAPos
|| i
== CursorBPos
) {
250 if(i
== CursorAPos
) {
251 SelectObject(hdc
, CursorAPen
);
253 SelectObject(hdc
, CursorBPen
);
255 MoveToEx(hdc
, x
, r
.top
, NULL
);
256 LineTo(hdc
, x
, r
.bottom
);
258 SelectObject(hdc
, pen
);
259 MoveToEx(hdc
, x
, y
, NULL
);
267 // print misc information at bottom of graph window
268 sprintf(str
, "@%d max=%d min=%d mean=%d n=%d/%d dt=%d [%.3f] zoom=%.3f CursorA=%d [%d] CursorB=%d [%d]",
269 GraphStart
, yMax
, yMin
, yMean
, n
, GraphTraceLen
,
270 CursorBPos
- CursorAPos
, (CursorBPos
- CursorAPos
)/CursorScaleFactor
, GraphPixelsPerPoint
,
271 CursorAPos
, GraphBuffer
[CursorAPos
], CursorBPos
, GraphBuffer
[CursorBPos
]);
272 TextOut(hdc
, 50, r
.bottom
- 20, str
, strlen(str
));
275 static LRESULT CALLBACK
276 GraphWindowProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
282 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
285 RepaintGraphWindow();
290 HDC hdc
= BeginPaint(hwnd
, &ps
);
294 // This draws the trace.
302 if(GraphPixelsPerPoint
<= 8) {
303 GraphPixelsPerPoint
*= 2;
308 if(GraphPixelsPerPoint
>= 0.01) {
309 GraphPixelsPerPoint
/= 2;
314 if(GraphPixelsPerPoint
< 16) {
315 GraphStart
+= (int)(16 / GraphPixelsPerPoint
);
322 if(GraphPixelsPerPoint
< 16) {
323 GraphStart
-= (int)(16 / GraphPixelsPerPoint
);
332 RepaintGraphWindow();
337 case WM_RBUTTONDOWN
: {
338 int x
= LOWORD(lParam
);
340 x
= (int)(x
/ GraphPixelsPerPoint
);
343 if(msg
== WM_LBUTTONDOWN
) {
348 RepaintGraphWindow();
352 return DefWindowProc(hwnd
, msg
, wParam
, lParam
);
358 void PrintAndLog(char *fmt
, ...)
364 vsprintf(str
+2, fmt
, f
);
366 static char TextBuf
[1024*32];
367 SendMessage(ScrollbackEdit
, WM_GETTEXT
, (WPARAM
)sizeof(TextBuf
),
370 if(strlen(TextBuf
) + strlen(str
) + 1 <= sizeof(TextBuf
)) {
371 strcat(TextBuf
, str
);
373 lstrcpyn(TextBuf
, str
, sizeof(TextBuf
));
376 SendMessage(ScrollbackEdit
, WM_SETTEXT
, 0, (LPARAM
)TextBuf
);
377 SendMessage(ScrollbackEdit
, EM_LINESCROLL
, 0, (LPARAM
)INT_MAX
);
380 void ShowGraphWindow(void)
382 if(GraphWindow
) return;
384 GraphWindow
= CreateWindowEx(0, "Graph", "graphed",
385 WS_OVERLAPPED
| WS_BORDER
| WS_MINIMIZEBOX
| WS_SYSMENU
|
386 WS_SIZEBOX
| WS_VISIBLE
, 200, 150, 600, 500, NULL
, NULL
, NULL
,
388 if(!GraphWindow
) oops();
391 void HideGraphWindow(void)
394 DestroyWindow(GraphWindow
);
399 static void SetCommandEditTo(char *str
)
401 SendMessage(CommandEdit
, WM_SETTEXT
, 0, (LPARAM
)str
);
402 SendMessage(CommandEdit
, EM_SETSEL
, strlen(str
), strlen(str
));
408 memset(&wc
, 0, sizeof(wc
));
409 wc
.cbSize
= sizeof(wc
);
411 wc
.style
= CS_BYTEALIGNCLIENT
| CS_BYTEALIGNWINDOW
| CS_OWNDC
;
412 wc
.lpfnWndProc
= (WNDPROC
)CommandWindowProc
;
414 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNSHADOW
);
415 wc
.lpszClassName
= "Command";
416 wc
.lpszMenuName
= NULL
;
417 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
419 if(!RegisterClassEx(&wc
)) oops();
421 wc
.lpszClassName
= "Graph";
422 wc
.lpfnWndProc
= (WNDPROC
)GraphWindowProc
;
423 wc
.hbrBackground
= (HBRUSH
)GetStockObject(BLACK_BRUSH
);
425 if(!RegisterClassEx(&wc
)) oops();
427 CommandWindow
= CreateWindowEx(0, "Command", "prox",
428 WS_OVERLAPPED
| WS_BORDER
| WS_MINIMIZEBOX
| WS_SYSMENU
|
429 WS_SIZEBOX
| WS_VISIBLE
, 20, 20, 500, 400, NULL
, NULL
, NULL
,
431 if(!CommandWindow
) oops();
433 ScrollbackEdit
= CreateWindowEx(WS_EX_CLIENTEDGE
, "edit", "",
434 WS_CHILD
| WS_CLIPSIBLINGS
| WS_VISIBLE
| ES_MULTILINE
|
435 ES_AUTOVSCROLL
| WS_VSCROLL
, 0, 0, 0, 0, CommandWindow
, NULL
,
438 CommandEdit
= CreateWindowEx(WS_EX_CLIENTEDGE
, "edit", "",
439 WS_CHILD
| WS_CLIPSIBLINGS
| WS_TABSTOP
| WS_VISIBLE
|
440 ES_AUTOHSCROLL
, 0, 0, 0, 0, CommandWindow
, NULL
, NULL
, NULL
);
442 MyFixedFont
= CreateFont(14, 0, 0, 0, FW_REGULAR
, FALSE
, FALSE
, FALSE
,
443 ANSI_CHARSET
, OUT_DEFAULT_PRECIS
, CLIP_DEFAULT_PRECIS
, DEFAULT_QUALITY
,
444 FF_DONTCARE
, "Lucida Console");
446 MyFixedFont
= (HFONT
)GetStockObject(SYSTEM_FONT
);
448 FixedFont(ScrollbackEdit
);
449 FixedFont(CommandEdit
);
451 ResizeCommandWindow();
452 SetFocus(CommandEdit
);
454 PrintAndLog(">> Started prox, built " __DATE__
" " __TIME__
);
455 PrintAndLog(">> Connected to device");
457 GreyPenLite
= CreatePen(PS_SOLID
, 1, RGB(50, 50, 50));
458 GreyPen
= CreatePen(PS_SOLID
, 1, RGB(100, 100, 100));
459 GreenPen
= CreatePen(PS_SOLID
, 1, RGB(100, 255, 100));
460 YellowPen
= CreatePen(PS_SOLID
, 1, RGB(255, 255, 0));
461 GreenBrush
= CreateSolidBrush(RGB(100, 255, 100));
462 YellowBrush
= CreateSolidBrush(RGB(255, 255, 0));
463 WhitePen
= CreatePen(PS_SOLID
, 1, RGB(255, 255, 255));
465 CursorAPen
= CreatePen(PS_DASH
, 1, RGB(255, 255, 0));
466 CursorBPen
= CreatePen(PS_DASH
, 1, RGB(255, 0, 255));
470 if(PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
471 if(msg
.message
== WM_KEYDOWN
&& msg
.wParam
== VK_RETURN
) {
473 SendMessage(CommandEdit
, WM_GETTEXT
, (WPARAM
)sizeof(got
),
476 if(strcmp(got
, "cls")==0) {
477 SendMessage(ScrollbackEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
479 CommandReceived(got
);
481 SendMessage(CommandEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
483 // Insert it into the command history, unless it is
484 // identical to the previous command in the history.
485 int prev
= CommandHistoryNext
- 1;
486 if(prev
< 0) prev
+= COMMAND_HISTORY_MAX
;
487 if(strcmp(CommandHistory
[prev
], got
) != 0) {
488 strcpy(CommandHistory
[CommandHistoryNext
], got
);
489 CommandHistoryNext
++;
490 if(CommandHistoryNext
== COMMAND_HISTORY_MAX
) {
491 CommandHistoryNext
= 0;
494 CommandHistoryPos
= -1;
495 } else if(msg
.message
== WM_KEYDOWN
&& msg
.wParam
== VK_UP
&&
496 msg
.hwnd
== CommandEdit
)
498 if(CommandHistoryPos
== -1) {
499 CommandHistoryPos
= CommandHistoryNext
;
502 if(CommandHistoryPos
< 0) {
503 CommandHistoryPos
= COMMAND_HISTORY_MAX
-1;
505 SetCommandEditTo(CommandHistory
[CommandHistoryPos
]);
506 } else if(msg
.message
== WM_KEYDOWN
&& msg
.wParam
== VK_DOWN
&&
507 msg
.hwnd
== CommandEdit
)
510 if(CommandHistoryPos
>= COMMAND_HISTORY_MAX
) {
511 CommandHistoryPos
= 0;
513 SetCommandEditTo(CommandHistory
[CommandHistoryPos
]);
514 } else if(msg
.message
== WM_KEYDOWN
&& msg
.wParam
== VK_ESCAPE
&&
515 msg
.hwnd
== CommandEdit
)
517 SendMessage(CommandEdit
, WM_SETTEXT
, 0, (LPARAM
)"");
519 if(msg
.message
== WM_KEYDOWN
) {
520 CommandHistoryPos
= -1;
522 TranslateMessage(&msg
);
523 DispatchMessage(&msg
);
530 if(ReceiveCommandPoll(&c
))
531 UsbCommandReceived(&c
);