PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/bdwgc/cord/tests/de_win.c

https://gitlab.com/lexicall/ecl
C | 369 lines | 285 code | 52 blank | 32 comment | 33 complexity | 9a359b26a8a182ed55cbfbac0eb1ca83 MD5 | raw file
  1. /*
  2. * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
  3. *
  4. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5. * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
  6. *
  7. * Permission is hereby granted to use or copy this program
  8. * for any purpose, provided the above notices are retained on all copies.
  9. * Permission to modify the code and to distribute modified code is granted,
  10. * provided the above notices are retained, and a notice that the code was
  11. * modified is included with the above copyright notice.
  12. */
  13. /*
  14. * The MS Windows specific part of de.
  15. * This started as the generic Windows application template
  16. * but significant parts didn't survive to the final version.
  17. *
  18. * This was written by a nonexpert windows programmer.
  19. */
  20. #include "windows.h"
  21. #include "gc.h"
  22. #include "cord.h"
  23. #include "de_cmds.h"
  24. #include "de_win.h"
  25. int LINES = 0;
  26. int COLS = 0;
  27. #define szAppName TEXT("DE")
  28. HWND hwnd;
  29. void de_error(char *s)
  30. {
  31. (void)MessageBoxA(hwnd, s, "Demonstration Editor",
  32. MB_ICONINFORMATION | MB_OK);
  33. InvalidateRect(hwnd, NULL, TRUE);
  34. }
  35. int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  36. LPSTR command_line, int nCmdShow)
  37. {
  38. MSG msg;
  39. WNDCLASS wndclass;
  40. HANDLE hAccel;
  41. # ifdef THREAD_LOCAL_ALLOC
  42. GC_INIT(); /* Required if GC is built with THREAD_LOCAL_ALLOC */
  43. /* Always safe, but this is used as a GC test. */
  44. # endif
  45. if (!hPrevInstance)
  46. {
  47. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  48. wndclass.lpfnWndProc = WndProc;
  49. wndclass.cbClsExtra = 0;
  50. wndclass.cbWndExtra = DLGWINDOWEXTRA;
  51. wndclass.hInstance = hInstance;
  52. wndclass.hIcon = LoadIcon (hInstance, szAppName);
  53. wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
  54. wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  55. wndclass.lpszMenuName = TEXT("DE");
  56. wndclass.lpszClassName = szAppName;
  57. if (RegisterClass (&wndclass) == 0) {
  58. char buf[50];
  59. sprintf(buf, "RegisterClass: error code: 0x%X",
  60. (unsigned)GetLastError());
  61. de_error(buf);
  62. return(0);
  63. }
  64. }
  65. /* Empirically, the command line does not include the command name ...
  66. if (command_line != 0) {
  67. while (isspace(*command_line)) command_line++;
  68. while (*command_line != 0 && !isspace(*command_line)) command_line++;
  69. while (isspace(*command_line)) command_line++;
  70. } */
  71. if (command_line == 0 || *command_line == 0) {
  72. de_error("File name argument required");
  73. return( 0 );
  74. } else {
  75. char *p = command_line;
  76. while (*p != 0 && !isspace(*(unsigned char *)p))
  77. p++;
  78. arg_file_name = CORD_to_char_star(
  79. CORD_substr(command_line, 0, p - command_line));
  80. }
  81. hwnd = CreateWindow (szAppName,
  82. TEXT("Demonstration Editor"),
  83. WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
  84. CW_USEDEFAULT, 0, /* default pos. */
  85. CW_USEDEFAULT, 0, /* default width, height */
  86. NULL, /* No parent */
  87. NULL, /* Window class menu */
  88. hInstance, NULL);
  89. if (hwnd == NULL) {
  90. char buf[50];
  91. sprintf(buf, "CreateWindow: error code: 0x%X",
  92. (unsigned)GetLastError());
  93. de_error(buf);
  94. return(0);
  95. }
  96. ShowWindow (hwnd, nCmdShow);
  97. hAccel = LoadAccelerators( hInstance, szAppName );
  98. while (GetMessage (&msg, NULL, 0, 0))
  99. {
  100. if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
  101. {
  102. TranslateMessage (&msg);
  103. DispatchMessage (&msg);
  104. }
  105. }
  106. return msg.wParam;
  107. }
  108. /* Return the argument with all control characters replaced by blanks. */
  109. char * plain_chars(char * text, size_t len)
  110. {
  111. char * result = GC_MALLOC_ATOMIC(len + 1);
  112. register size_t i;
  113. for (i = 0; i < len; i++) {
  114. if (iscntrl(((unsigned char *)text)[i])) {
  115. result[i] = ' ';
  116. } else {
  117. result[i] = text[i];
  118. }
  119. }
  120. result[len] = '\0';
  121. return(result);
  122. }
  123. /* Return the argument with all non-control-characters replaced by */
  124. /* blank, and all control characters c replaced by c + 32. */
  125. char * control_chars(char * text, size_t len)
  126. {
  127. char * result = GC_MALLOC_ATOMIC(len + 1);
  128. register size_t i;
  129. for (i = 0; i < len; i++) {
  130. if (iscntrl(((unsigned char *)text)[i])) {
  131. result[i] = text[i] + 0x40;
  132. } else {
  133. result[i] = ' ';
  134. }
  135. }
  136. result[len] = '\0';
  137. return(result);
  138. }
  139. int char_width;
  140. int char_height;
  141. void get_line_rect(int line, int win_width, RECT * rectp)
  142. {
  143. rectp -> top = line * char_height;
  144. rectp -> bottom = rectp->top + char_height;
  145. rectp -> left = 0;
  146. rectp -> right = win_width;
  147. }
  148. int caret_visible = 0; /* Caret is currently visible. */
  149. int screen_was_painted = 0;/* Screen has been painted at least once. */
  150. void update_cursor(void);
  151. INT_PTR CALLBACK AboutBoxCallback( HWND hDlg, UINT message,
  152. WPARAM wParam, LPARAM lParam )
  153. {
  154. (void)lParam;
  155. switch( message )
  156. {
  157. case WM_INITDIALOG:
  158. SetFocus( GetDlgItem( hDlg, IDOK ) );
  159. break;
  160. case WM_COMMAND:
  161. switch( wParam )
  162. {
  163. case IDOK:
  164. EndDialog( hDlg, TRUE );
  165. break;
  166. }
  167. break;
  168. case WM_CLOSE:
  169. EndDialog( hDlg, TRUE );
  170. return TRUE;
  171. }
  172. return FALSE;
  173. }
  174. LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
  175. WPARAM wParam, LPARAM lParam)
  176. {
  177. static HANDLE hInstance;
  178. HDC dc;
  179. PAINTSTRUCT ps;
  180. RECT client_area;
  181. RECT this_line;
  182. RECT dummy;
  183. TEXTMETRIC tm;
  184. register int i;
  185. int id;
  186. switch (message)
  187. {
  188. case WM_CREATE:
  189. hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
  190. dc = GetDC(hwnd);
  191. SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
  192. GetTextMetrics(dc, &tm);
  193. ReleaseDC(hwnd, dc);
  194. char_width = tm.tmAveCharWidth;
  195. char_height = tm.tmHeight + tm.tmExternalLeading;
  196. GetClientRect(hwnd, &client_area);
  197. COLS = (client_area.right - client_area.left)/char_width;
  198. LINES = (client_area.bottom - client_area.top)/char_height;
  199. generic_init();
  200. return(0);
  201. case WM_CHAR:
  202. if (wParam == QUIT) {
  203. SendMessage( hwnd, WM_CLOSE, 0, 0L );
  204. } else {
  205. do_command((int)wParam);
  206. }
  207. return(0);
  208. case WM_SETFOCUS:
  209. CreateCaret(hwnd, NULL, char_width, char_height);
  210. ShowCaret(hwnd);
  211. caret_visible = 1;
  212. update_cursor();
  213. return(0);
  214. case WM_KILLFOCUS:
  215. HideCaret(hwnd);
  216. DestroyCaret();
  217. caret_visible = 0;
  218. return(0);
  219. case WM_LBUTTONUP:
  220. {
  221. unsigned xpos = LOWORD(lParam); /* From left */
  222. unsigned ypos = HIWORD(lParam); /* from top */
  223. set_position(xpos / (unsigned)char_width,
  224. ypos / (unsigned)char_height);
  225. return(0);
  226. }
  227. case WM_COMMAND:
  228. id = LOWORD(wParam);
  229. if (id & EDIT_CMD_FLAG) {
  230. if (id & REPEAT_FLAG) do_command(REPEAT);
  231. do_command(CHAR_CMD(id));
  232. return( 0 );
  233. } else {
  234. switch(id) {
  235. case IDM_FILEEXIT:
  236. SendMessage( hwnd, WM_CLOSE, 0, 0L );
  237. return( 0 );
  238. case IDM_HELPABOUT:
  239. if( DialogBox( hInstance, TEXT("ABOUTBOX"),
  240. hwnd, AboutBoxCallback ) )
  241. InvalidateRect( hwnd, NULL, TRUE );
  242. return( 0 );
  243. case IDM_HELPCONTENTS:
  244. de_error(
  245. "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"
  246. "Undo: ^U Write: ^W Quit:^D Repeat count: ^R[n]\n"
  247. "Top: ^T Locate (search, find): ^L text ^L\n");
  248. return( 0 );
  249. }
  250. }
  251. break;
  252. case WM_CLOSE:
  253. DestroyWindow( hwnd );
  254. return 0;
  255. case WM_DESTROY:
  256. PostQuitMessage (0);
  257. GC_win32_free_heap();
  258. return 0;
  259. case WM_PAINT:
  260. dc = BeginPaint(hwnd, &ps);
  261. GetClientRect(hwnd, &client_area);
  262. COLS = (client_area.right - client_area.left)/char_width;
  263. LINES = (client_area.bottom - client_area.top)/char_height;
  264. SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
  265. for (i = 0; i < LINES; i++) {
  266. get_line_rect(i, client_area.right, &this_line);
  267. if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) {
  268. CORD raw_line = retrieve_screen_line(i);
  269. size_t len = CORD_len(raw_line);
  270. char * text = CORD_to_char_star(raw_line);
  271. /* May contain embedded NULLs */
  272. char * plain = plain_chars(text, len);
  273. char * blanks = CORD_to_char_star(CORD_chars(' ',
  274. COLS - len));
  275. char * control = control_chars(text, len);
  276. # define RED RGB(255,0,0)
  277. SetBkMode(dc, OPAQUE);
  278. SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
  279. TextOutA(dc, this_line.left, this_line.top,
  280. plain, (int)len);
  281. TextOutA(dc, this_line.left + (int)len * char_width,
  282. this_line.top,
  283. blanks, (int)(COLS - len));
  284. SetBkMode(dc, TRANSPARENT);
  285. SetTextColor(dc, RED);
  286. TextOutA(dc, this_line.left, this_line.top,
  287. control, (int)strlen(control));
  288. }
  289. }
  290. EndPaint(hwnd, &ps);
  291. screen_was_painted = 1;
  292. return 0;
  293. }
  294. return DefWindowProc (hwnd, message, wParam, lParam);
  295. }
  296. int last_col;
  297. int last_line;
  298. void move_cursor(int c, int l)
  299. {
  300. last_col = c;
  301. last_line = l;
  302. if (caret_visible) update_cursor();
  303. }
  304. void update_cursor(void)
  305. {
  306. SetCaretPos(last_col * char_width, last_line * char_height);
  307. ShowCaret(hwnd);
  308. }
  309. void invalidate_line(int i)
  310. {
  311. RECT line;
  312. if (!screen_was_painted) return;
  313. /* Invalidating a rectangle before painting seems result in a */
  314. /* major performance problem. */
  315. get_line_rect(i, COLS*char_width, &line);
  316. InvalidateRect(hwnd, &line, FALSE);
  317. }