de_win.c 10 KB

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