curses 1.4.4 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (258) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +6 -0
  3. data/.github/workflows/macos.yml +1 -1
  4. data/.github/workflows/push_gem.yml +48 -0
  5. data/.github/workflows/ubuntu.yml +2 -2
  6. data/.github/workflows/windows.yml +2 -2
  7. data/History.md +23 -0
  8. data/README.md +7 -0
  9. data/curses.gemspec +1 -1
  10. data/ext/curses/curses.c +7 -7
  11. data/sample/colors.rb +6 -1
  12. data/sample/form.rb +1 -1
  13. data/sample/menu.rb +2 -0
  14. metadata +9 -251
  15. data/vendor/PDCurses/.gitignore +0 -47
  16. data/vendor/PDCurses/.travis.yml +0 -49
  17. data/vendor/PDCurses/CMakeLists.txt +0 -68
  18. data/vendor/PDCurses/HISTORY.md +0 -2036
  19. data/vendor/PDCurses/IMPLEMNT.md +0 -327
  20. data/vendor/PDCurses/Makefile +0 -27
  21. data/vendor/PDCurses/README.md +0 -77
  22. data/vendor/PDCurses/acs_defs.h +0 -265
  23. data/vendor/PDCurses/appveyor.yml +0 -218
  24. data/vendor/PDCurses/cmake/README.md +0 -71
  25. data/vendor/PDCurses/cmake/build_dependencies.cmake +0 -178
  26. data/vendor/PDCurses/cmake/build_options.cmake +0 -25
  27. data/vendor/PDCurses/cmake/dll_version.cmake +0 -26
  28. data/vendor/PDCurses/cmake/gen_config_header.cmake +0 -43
  29. data/vendor/PDCurses/cmake/get_version.cmake +0 -17
  30. data/vendor/PDCurses/cmake/make_uninstall.cmake +0 -19
  31. data/vendor/PDCurses/cmake/project_common.cmake +0 -121
  32. data/vendor/PDCurses/cmake/resource.in.cmake +0 -52
  33. data/vendor/PDCurses/cmake/sdl2_ttf/CMakeLists.txt +0 -83
  34. data/vendor/PDCurses/cmake/target_arch.cmake +0 -36
  35. data/vendor/PDCurses/cmake/version.in.cmake +0 -73
  36. data/vendor/PDCurses/cmake/watcom_open_dos16_toolchain.cmake +0 -96
  37. data/vendor/PDCurses/cmake/watcom_open_dos32_toolchain.cmake +0 -106
  38. data/vendor/PDCurses/cmake/watcom_open_os2v2_toolchain.cmake +0 -105
  39. data/vendor/PDCurses/curses.h +0 -1846
  40. data/vendor/PDCurses/curspriv.h +0 -134
  41. data/vendor/PDCurses/demos/README.md +0 -25
  42. data/vendor/PDCurses/demos/firework.c +0 -144
  43. data/vendor/PDCurses/demos/newtest.c +0 -581
  44. data/vendor/PDCurses/demos/ozdemo.c +0 -447
  45. data/vendor/PDCurses/demos/ptest.c +0 -283
  46. data/vendor/PDCurses/demos/rain.c +0 -157
  47. data/vendor/PDCurses/demos/testcurs.c +0 -1607
  48. data/vendor/PDCurses/demos/tui.c +0 -1048
  49. data/vendor/PDCurses/demos/tui.h +0 -65
  50. data/vendor/PDCurses/demos/tuidemo.c +0 -233
  51. data/vendor/PDCurses/demos/version.c +0 -61
  52. data/vendor/PDCurses/demos/worm.c +0 -432
  53. data/vendor/PDCurses/demos/xmas.c +0 -955
  54. data/vendor/PDCurses/dos/CMakeLists.txt +0 -47
  55. data/vendor/PDCurses/dos/Makefile +0 -105
  56. data/vendor/PDCurses/dos/Makefile.bcc +0 -83
  57. data/vendor/PDCurses/dos/Makefile.dmc +0 -257
  58. data/vendor/PDCurses/dos/Makefile.msc +0 -113
  59. data/vendor/PDCurses/dos/Makefile.wcc +0 -107
  60. data/vendor/PDCurses/dos/README.md +0 -51
  61. data/vendor/PDCurses/dos/bccdos.lrf +0 -9
  62. data/vendor/PDCurses/dos/mscdos.lrf +0 -50
  63. data/vendor/PDCurses/dos/pdcclip.c +0 -132
  64. data/vendor/PDCurses/dos/pdcdisp.c +0 -135
  65. data/vendor/PDCurses/dos/pdcdos.h +0 -194
  66. data/vendor/PDCurses/dos/pdcgetsc.c +0 -98
  67. data/vendor/PDCurses/dos/pdckbd.c +0 -513
  68. data/vendor/PDCurses/dos/pdcscrn.c +0 -785
  69. data/vendor/PDCurses/dos/pdcsetsc.c +0 -101
  70. data/vendor/PDCurses/dos/pdcutil.c +0 -212
  71. data/vendor/PDCurses/libobjs.mif +0 -26
  72. data/vendor/PDCurses/makedist.mif +0 -20
  73. data/vendor/PDCurses/man/Makefile +0 -37
  74. data/vendor/PDCurses/man/README.md +0 -21
  75. data/vendor/PDCurses/man/intro.md +0 -361
  76. data/vendor/PDCurses/man/manext.c +0 -119
  77. data/vendor/PDCurses/man/sdl.md +0 -152
  78. data/vendor/PDCurses/man/sdl2.md +0 -58
  79. data/vendor/PDCurses/man/x11.md +0 -407
  80. data/vendor/PDCurses/ncurses/CMakeLists.txt +0 -66
  81. data/vendor/PDCurses/ncurses/README.md +0 -26
  82. data/vendor/PDCurses/ncurses/makefile +0 -29
  83. data/vendor/PDCurses/os2/CMakeLists.txt +0 -41
  84. data/vendor/PDCurses/os2/Makefile +0 -132
  85. data/vendor/PDCurses/os2/Makefile.bcc +0 -90
  86. data/vendor/PDCurses/os2/Makefile.wcc +0 -43
  87. data/vendor/PDCurses/os2/README.md +0 -43
  88. data/vendor/PDCurses/os2/iccos2.lrf +0 -50
  89. data/vendor/PDCurses/os2/iccos2.mak +0 -256
  90. data/vendor/PDCurses/os2/pdcclip.c +0 -188
  91. data/vendor/PDCurses/os2/pdcdisp.c +0 -93
  92. data/vendor/PDCurses/os2/pdcgetsc.c +0 -89
  93. data/vendor/PDCurses/os2/pdckbd.c +0 -521
  94. data/vendor/PDCurses/os2/pdcos2.h +0 -55
  95. data/vendor/PDCurses/os2/pdcscrn.c +0 -449
  96. data/vendor/PDCurses/os2/pdcsetsc.c +0 -112
  97. data/vendor/PDCurses/os2/pdcutil.c +0 -52
  98. data/vendor/PDCurses/panel.h +0 -56
  99. data/vendor/PDCurses/pdcurses/README.md +0 -25
  100. data/vendor/PDCurses/pdcurses/addch.c +0 -693
  101. data/vendor/PDCurses/pdcurses/addchstr.c +0 -245
  102. data/vendor/PDCurses/pdcurses/addstr.c +0 -240
  103. data/vendor/PDCurses/pdcurses/attr.c +0 -359
  104. data/vendor/PDCurses/pdcurses/beep.c +0 -68
  105. data/vendor/PDCurses/pdcurses/bkgd.c +0 -223
  106. data/vendor/PDCurses/pdcurses/border.c +0 -411
  107. data/vendor/PDCurses/pdcurses/clear.c +0 -159
  108. data/vendor/PDCurses/pdcurses/color.c +0 -298
  109. data/vendor/PDCurses/pdcurses/debug.c +0 -109
  110. data/vendor/PDCurses/pdcurses/delch.c +0 -96
  111. data/vendor/PDCurses/pdcurses/deleteln.c +0 -211
  112. data/vendor/PDCurses/pdcurses/deprec.c +0 -27
  113. data/vendor/PDCurses/pdcurses/getch.c +0 -417
  114. data/vendor/PDCurses/pdcurses/getstr.c +0 -474
  115. data/vendor/PDCurses/pdcurses/getyx.c +0 -139
  116. data/vendor/PDCurses/pdcurses/inch.c +0 -127
  117. data/vendor/PDCurses/pdcurses/inchstr.c +0 -214
  118. data/vendor/PDCurses/pdcurses/initscr.c +0 -367
  119. data/vendor/PDCurses/pdcurses/inopts.c +0 -324
  120. data/vendor/PDCurses/pdcurses/insch.c +0 -271
  121. data/vendor/PDCurses/pdcurses/insstr.c +0 -264
  122. data/vendor/PDCurses/pdcurses/instr.c +0 -246
  123. data/vendor/PDCurses/pdcurses/kernel.c +0 -259
  124. data/vendor/PDCurses/pdcurses/keyname.c +0 -157
  125. data/vendor/PDCurses/pdcurses/mouse.c +0 -438
  126. data/vendor/PDCurses/pdcurses/move.c +0 -57
  127. data/vendor/PDCurses/pdcurses/outopts.c +0 -159
  128. data/vendor/PDCurses/pdcurses/overlay.c +0 -214
  129. data/vendor/PDCurses/pdcurses/pad.c +0 -260
  130. data/vendor/PDCurses/pdcurses/panel.c +0 -633
  131. data/vendor/PDCurses/pdcurses/printw.c +0 -126
  132. data/vendor/PDCurses/pdcurses/refresh.c +0 -279
  133. data/vendor/PDCurses/pdcurses/scanw.c +0 -578
  134. data/vendor/PDCurses/pdcurses/scr_dump.c +0 -213
  135. data/vendor/PDCurses/pdcurses/scroll.c +0 -101
  136. data/vendor/PDCurses/pdcurses/slk.c +0 -591
  137. data/vendor/PDCurses/pdcurses/termattr.c +0 -182
  138. data/vendor/PDCurses/pdcurses/terminfo.c +0 -217
  139. data/vendor/PDCurses/pdcurses/touch.c +0 -163
  140. data/vendor/PDCurses/pdcurses/util.c +0 -312
  141. data/vendor/PDCurses/pdcurses/window.c +0 -569
  142. data/vendor/PDCurses/sdl1/Makefile +0 -129
  143. data/vendor/PDCurses/sdl1/Makefile.mng +0 -110
  144. data/vendor/PDCurses/sdl1/README.md +0 -31
  145. data/vendor/PDCurses/sdl1/deffont.h +0 -385
  146. data/vendor/PDCurses/sdl1/deficon.h +0 -23
  147. data/vendor/PDCurses/sdl1/pdcclip.c +0 -131
  148. data/vendor/PDCurses/sdl1/pdcdisp.c +0 -373
  149. data/vendor/PDCurses/sdl1/pdcgetsc.c +0 -30
  150. data/vendor/PDCurses/sdl1/pdckbd.c +0 -405
  151. data/vendor/PDCurses/sdl1/pdcscrn.c +0 -414
  152. data/vendor/PDCurses/sdl1/pdcsdl.h +0 -31
  153. data/vendor/PDCurses/sdl1/pdcsetsc.c +0 -64
  154. data/vendor/PDCurses/sdl1/pdcutil.c +0 -40
  155. data/vendor/PDCurses/sdl1/sdltest.c +0 -79
  156. data/vendor/PDCurses/sdl2/CMakeLists.txt +0 -76
  157. data/vendor/PDCurses/sdl2/Makefile +0 -135
  158. data/vendor/PDCurses/sdl2/Makefile.vc +0 -164
  159. data/vendor/PDCurses/sdl2/README.md +0 -34
  160. data/vendor/PDCurses/sdl2/deffont.h +0 -385
  161. data/vendor/PDCurses/sdl2/deficon.h +0 -23
  162. data/vendor/PDCurses/sdl2/pdcclip.c +0 -93
  163. data/vendor/PDCurses/sdl2/pdcdisp.c +0 -534
  164. data/vendor/PDCurses/sdl2/pdcgetsc.c +0 -30
  165. data/vendor/PDCurses/sdl2/pdckbd.c +0 -480
  166. data/vendor/PDCurses/sdl2/pdcscrn.c +0 -443
  167. data/vendor/PDCurses/sdl2/pdcsdl.h +0 -33
  168. data/vendor/PDCurses/sdl2/pdcsetsc.c +0 -67
  169. data/vendor/PDCurses/sdl2/pdcutil.c +0 -39
  170. data/vendor/PDCurses/sdl2/sdltest.c +0 -81
  171. data/vendor/PDCurses/term.h +0 -48
  172. data/vendor/PDCurses/version.mif +0 -7
  173. data/vendor/PDCurses/vt/CMakeLists.txt +0 -28
  174. data/vendor/PDCurses/vt/Makefile +0 -135
  175. data/vendor/PDCurses/vt/Makefile.bcc +0 -111
  176. data/vendor/PDCurses/vt/Makefile.dmc +0 -258
  177. data/vendor/PDCurses/vt/Makefile.vc +0 -144
  178. data/vendor/PDCurses/vt/Makefile.wcc +0 -107
  179. data/vendor/PDCurses/vt/README.md +0 -64
  180. data/vendor/PDCurses/vt/pdcclip.c +0 -20
  181. data/vendor/PDCurses/vt/pdcdisp.c +0 -284
  182. data/vendor/PDCurses/vt/pdcgetsc.c +0 -27
  183. data/vendor/PDCurses/vt/pdckbd.c +0 -394
  184. data/vendor/PDCurses/vt/pdcscrn.c +0 -434
  185. data/vendor/PDCurses/vt/pdcsetsc.c +0 -45
  186. data/vendor/PDCurses/vt/pdcutil.c +0 -43
  187. data/vendor/PDCurses/vt/pdcvt.h +0 -16
  188. data/vendor/PDCurses/watcom.mif +0 -68
  189. data/vendor/PDCurses/wincon/CMakeLists.txt +0 -27
  190. data/vendor/PDCurses/wincon/Makefile.bcc +0 -88
  191. data/vendor/PDCurses/wincon/Makefile.dmc +0 -256
  192. data/vendor/PDCurses/wincon/Makefile.lcc +0 -273
  193. data/vendor/PDCurses/wincon/Makefile.mng +0 -176
  194. data/vendor/PDCurses/wincon/Makefile.vc +0 -144
  195. data/vendor/PDCurses/wincon/Makefile.wcc +0 -51
  196. data/vendor/PDCurses/wincon/README.md +0 -85
  197. data/vendor/PDCurses/wincon/pdcclip.c +0 -174
  198. data/vendor/PDCurses/wincon/pdcdisp.c +0 -143
  199. data/vendor/PDCurses/wincon/pdcgetsc.c +0 -55
  200. data/vendor/PDCurses/wincon/pdckbd.c +0 -786
  201. data/vendor/PDCurses/wincon/pdcscrn.c +0 -717
  202. data/vendor/PDCurses/wincon/pdcsetsc.c +0 -91
  203. data/vendor/PDCurses/wincon/pdcurses.ico +0 -0
  204. data/vendor/PDCurses/wincon/pdcurses.rc +0 -28
  205. data/vendor/PDCurses/wincon/pdcutil.c +0 -41
  206. data/vendor/PDCurses/wincon/pdcwin.h +0 -31
  207. data/vendor/PDCurses/wingui/CMakeLists.txt +0 -27
  208. data/vendor/PDCurses/wingui/Makefile.bcc +0 -85
  209. data/vendor/PDCurses/wingui/Makefile.dmc +0 -259
  210. data/vendor/PDCurses/wingui/Makefile.lcc +0 -273
  211. data/vendor/PDCurses/wingui/Makefile.mng +0 -171
  212. data/vendor/PDCurses/wingui/Makefile.vc +0 -144
  213. data/vendor/PDCurses/wingui/Makefile.wcc +0 -51
  214. data/vendor/PDCurses/wingui/README.md +0 -93
  215. data/vendor/PDCurses/wingui/pdcclip.c +0 -174
  216. data/vendor/PDCurses/wingui/pdcdisp.c +0 -718
  217. data/vendor/PDCurses/wingui/pdcgetsc.c +0 -30
  218. data/vendor/PDCurses/wingui/pdckbd.c +0 -143
  219. data/vendor/PDCurses/wingui/pdcscrn.c +0 -2797
  220. data/vendor/PDCurses/wingui/pdcsetsc.c +0 -89
  221. data/vendor/PDCurses/wingui/pdcurses.ico +0 -0
  222. data/vendor/PDCurses/wingui/pdcurses.rc +0 -28
  223. data/vendor/PDCurses/wingui/pdcutil.c +0 -61
  224. data/vendor/PDCurses/wingui/pdcwin.h +0 -122
  225. data/vendor/PDCurses/x11/Makefile.in +0 -754
  226. data/vendor/PDCurses/x11/PDCurses.spec +0 -82
  227. data/vendor/PDCurses/x11/README.md +0 -62
  228. data/vendor/PDCurses/x11/ScrollBox.c +0 -319
  229. data/vendor/PDCurses/x11/ScrollBox.h +0 -51
  230. data/vendor/PDCurses/x11/ScrollBoxP.h +0 -70
  231. data/vendor/PDCurses/x11/aclocal.m4 +0 -994
  232. data/vendor/PDCurses/x11/big_icon.xbm +0 -46
  233. data/vendor/PDCurses/x11/compose.h +0 -201
  234. data/vendor/PDCurses/x11/config.guess +0 -1500
  235. data/vendor/PDCurses/x11/config.h.in +0 -100
  236. data/vendor/PDCurses/x11/config.sub +0 -1616
  237. data/vendor/PDCurses/x11/configure +0 -6700
  238. data/vendor/PDCurses/x11/configure.ac +0 -295
  239. data/vendor/PDCurses/x11/debian/changelog +0 -6
  240. data/vendor/PDCurses/x11/debian/compat +0 -1
  241. data/vendor/PDCurses/x11/debian/control +0 -11
  242. data/vendor/PDCurses/x11/debian/copyright +0 -27
  243. data/vendor/PDCurses/x11/debian/rules +0 -98
  244. data/vendor/PDCurses/x11/install-sh +0 -253
  245. data/vendor/PDCurses/x11/little_icon.xbm +0 -14
  246. data/vendor/PDCurses/x11/ncurses_cfg.h +0 -45
  247. data/vendor/PDCurses/x11/pdcclip.c +0 -173
  248. data/vendor/PDCurses/x11/pdcdisp.c +0 -85
  249. data/vendor/PDCurses/x11/pdcgetsc.c +0 -28
  250. data/vendor/PDCurses/x11/pdckbd.c +0 -104
  251. data/vendor/PDCurses/x11/pdcscrn.c +0 -258
  252. data/vendor/PDCurses/x11/pdcsetsc.c +0 -95
  253. data/vendor/PDCurses/x11/pdcutil.c +0 -52
  254. data/vendor/PDCurses/x11/pdcx11.c +0 -316
  255. data/vendor/PDCurses/x11/pdcx11.h +0 -191
  256. data/vendor/PDCurses/x11/sb.c +0 -155
  257. data/vendor/PDCurses/x11/x11.c +0 -3686
  258. data/vendor/PDCurses/x11/xcurses-config.in +0 -81
@@ -1,3686 +0,0 @@
1
- /* Public Domain Curses */
2
-
3
- #include "pdcx11.h"
4
-
5
- #ifdef HAVE_DECKEYSYM_H
6
- # include <DECkeysym.h>
7
- #endif
8
-
9
- #ifdef HAVE_SUNKEYSYM_H
10
- # include <Sunkeysym.h>
11
- #endif
12
-
13
- #ifdef HAVE_XPM_H
14
- # include <xpm.h>
15
- #endif
16
-
17
- #if defined PDC_XIM
18
- # include <Xlocale.h>
19
- #endif
20
-
21
- #ifdef HAVE_XF86KEYSYM_H
22
- # include <XF86keysym.h>
23
- #endif
24
-
25
- #include <stdlib.h>
26
- #include <string.h>
27
-
28
- #ifndef XPOINTER_TYPEDEFED
29
- typedef char * XPointer;
30
- #endif
31
-
32
- #ifndef MAX_PATH
33
- # define MAX_PATH 256
34
- #endif
35
-
36
- XCursesAppData xc_app_data;
37
-
38
- #if NeedWidePrototypes
39
- # define PDC_SCROLLBAR_TYPE double
40
- #else
41
- # define PDC_SCROLLBAR_TYPE float
42
- #endif
43
-
44
- #define MAX_COLORS 256 /* maximum of "normal" colors */
45
- #define COLOR_CURSOR MAX_COLORS /* color of cursor */
46
- #define COLOR_BORDER MAX_COLORS + 1 /* color of border */
47
-
48
- #define XCURSESDISPLAY (XtDisplay(drawing))
49
- #define XCURSESWIN (XtWindow(drawing))
50
-
51
- /* Default icons for XCurses applications. */
52
-
53
- #include "big_icon.xbm"
54
- #include "little_icon.xbm"
55
-
56
- #define CURSOR_BLINK_RATE 500
57
- /* Used to be set in xc_app_data.cursorBlinkRate */
58
-
59
- static void _selection_off(void);
60
- static void _display_cursor(int, int, int, int);
61
- static void _redraw_cursor(void);
62
- static void _exit_process(int, int, char *);
63
- static void _send_key_to_curses(unsigned long, MOUSE_STATUS *, bool);
64
-
65
- static void XCursesButton(Widget, XEvent *, String *, Cardinal *);
66
- static void XCursesHandleString(Widget, XEvent *, String *, Cardinal *);
67
- static void XCursesKeyPress(Widget, XEvent *, String *, Cardinal *);
68
- static void XCursesPasteSelection(Widget, XButtonEvent *);
69
-
70
- static struct
71
- {
72
- KeySym keycode;
73
- bool numkeypad;
74
- unsigned short normal;
75
- unsigned short shifted;
76
- unsigned short control;
77
- unsigned short alt;
78
- } key_table[] =
79
- {
80
- /* keycode keypad normal shifted control alt*/
81
- {';', FALSE, ';', ':', CTL_SEMICOLON, ALT_SEMICOLON },
82
- {'=', FALSE, '=', '+', CTL_EQUAL, ALT_EQUAL },
83
- {',', FALSE, ',', '<', CTL_COMMA, ALT_COMMA },
84
- {'-', FALSE, '-', '_', CTL_MINUS, ALT_MINUS },
85
- {'.', FALSE, '.', '>', CTL_STOP, ALT_STOP },
86
- {'/', FALSE, '/', '?', CTL_FSLASH, ALT_FSLASH },
87
- {'`', FALSE, '`', '~', CTL_BQUOTE, ALT_BQUOTE },
88
-
89
- /* keycode keypad normal shifted control alt*/
90
- {XK_Left, FALSE, KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT},
91
- {XK_Right, FALSE, KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT},
92
- {XK_Up, FALSE, KEY_UP, KEY_SUP, CTL_UP, ALT_UP},
93
- {XK_Down, FALSE, KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN},
94
- {XK_Home, FALSE, KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME},
95
- /* Sun Type 4 keyboard */
96
- {XK_R7, FALSE, KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME},
97
- {XK_End, FALSE, KEY_END, KEY_SEND, CTL_END, ALT_END},
98
- /* Sun Type 4 keyboard */
99
- {XK_R13, FALSE, KEY_END, KEY_SEND, CTL_END, ALT_END},
100
- {XK_Prior, FALSE, KEY_PPAGE, KEY_SPREVIOUS,CTL_PGUP, ALT_PGUP},
101
- /* Sun Type 4 keyboard */
102
- {XK_R9, FALSE, KEY_PPAGE, KEY_SPREVIOUS,CTL_PGUP, ALT_PGUP},
103
- {XK_Next, FALSE, KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN},
104
- /* Sun Type 4 keyboard */
105
- {XK_R15, FALSE, KEY_NPAGE, KEY_SNEXT, CTL_PGDN, ALT_PGDN},
106
- {XK_Insert, FALSE, KEY_IC, KEY_SIC, CTL_INS, ALT_INS},
107
- {XK_Delete, FALSE, KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL},
108
- {XK_F1, FALSE, KEY_F(1), KEY_F(13), KEY_F(25), KEY_F(37)},
109
- {XK_F2, FALSE, KEY_F(2), KEY_F(14), KEY_F(26), KEY_F(38)},
110
- {XK_F3, FALSE, KEY_F(3), KEY_F(15), KEY_F(27), KEY_F(39)},
111
- {XK_F4, FALSE, KEY_F(4), KEY_F(16), KEY_F(28), KEY_F(40)},
112
- {XK_F5, FALSE, KEY_F(5), KEY_F(17), KEY_F(29), KEY_F(41)},
113
- {XK_F6, FALSE, KEY_F(6), KEY_F(18), KEY_F(30), KEY_F(42)},
114
- {XK_F7, FALSE, KEY_F(7), KEY_F(19), KEY_F(31), KEY_F(43)},
115
- {XK_F8, FALSE, KEY_F(8), KEY_F(20), KEY_F(32), KEY_F(44)},
116
- {XK_F9, FALSE, KEY_F(9), KEY_F(21), KEY_F(33), KEY_F(45)},
117
- {XK_F10, FALSE, KEY_F(10), KEY_F(22), KEY_F(34), KEY_F(46)},
118
- {XK_F11, FALSE, KEY_F(11), KEY_F(23), KEY_F(35), KEY_F(47)},
119
- {XK_F12, FALSE, KEY_F(12), KEY_F(24), KEY_F(36), KEY_F(48)},
120
- {XK_F13, FALSE, KEY_F(13), KEY_F(25), KEY_F(37), KEY_F(49)},
121
- {XK_F14, FALSE, KEY_F(14), KEY_F(26), KEY_F(38), KEY_F(50)},
122
- {XK_F15, FALSE, KEY_F(15), KEY_F(27), KEY_F(39), KEY_F(51)},
123
- {XK_F16, FALSE, KEY_F(16), KEY_F(28), KEY_F(40), KEY_F(52)},
124
- {XK_F17, FALSE, KEY_F(17), KEY_F(29), KEY_F(41), KEY_F(53)},
125
- {XK_F18, FALSE, KEY_F(18), KEY_F(30), KEY_F(42), KEY_F(54)},
126
- {XK_F19, FALSE, KEY_F(19), KEY_F(31), KEY_F(43), KEY_F(55)},
127
- {XK_F20, FALSE, KEY_F(20), KEY_F(32), KEY_F(44), KEY_F(56)},
128
- {XK_BackSpace, FALSE, 0x08, 0x08, CTL_BKSP, ALT_BKSP},
129
- {XK_Tab, FALSE, 0x09, KEY_BTAB, CTL_TAB, ALT_TAB},
130
- #if defined(XK_ISO_Left_Tab)
131
- {XK_ISO_Left_Tab, FALSE, 0x09, KEY_BTAB, CTL_TAB, ALT_TAB},
132
- #endif
133
- {XK_Select, FALSE, KEY_SELECT, KEY_SELECT, KEY_SELECT, KEY_SELECT},
134
- {XK_Print, FALSE, KEY_PRINT, KEY_SPRINT, KEY_PRINT, KEY_PRINT},
135
- {XK_Find, FALSE, KEY_FIND, KEY_SFIND, KEY_FIND, KEY_FIND},
136
- {XK_Pause, FALSE, KEY_SUSPEND, KEY_SSUSPEND, KEY_SUSPEND, KEY_SUSPEND},
137
- {XK_Clear, FALSE, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR, KEY_CLEAR},
138
- {XK_Cancel, FALSE, KEY_CANCEL, KEY_SCANCEL, KEY_CANCEL, KEY_CANCEL},
139
- {XK_Break, FALSE, KEY_BREAK, KEY_BREAK, KEY_BREAK, KEY_BREAK},
140
- {XK_Help, FALSE, KEY_HELP, KEY_SHELP, KEY_LHELP, KEY_HELP},
141
- {XK_L4, FALSE, KEY_UNDO, KEY_SUNDO, KEY_UNDO, KEY_UNDO},
142
- {XK_L6, FALSE, KEY_COPY, KEY_SCOPY, KEY_COPY, KEY_COPY},
143
- {XK_L9, FALSE, KEY_FIND, KEY_SFIND, KEY_FIND, KEY_FIND},
144
- {XK_Menu, FALSE, KEY_OPTIONS, KEY_SOPTIONS, KEY_OPTIONS, KEY_OPTIONS},
145
- {XK_Super_R, FALSE, KEY_COMMAND, KEY_SCOMMAND, KEY_COMMAND, KEY_COMMAND},
146
- {XK_Super_L, FALSE, KEY_COMMAND, KEY_SCOMMAND, KEY_COMMAND, KEY_COMMAND},
147
- #ifdef HAVE_SUNKEYSYM_H
148
- {SunXK_F36, FALSE, KEY_F(41), KEY_F(43), KEY_F(45), KEY_F(47)},
149
- {SunXK_F37, FALSE, KEY_F(42), KEY_F(44), KEY_F(46), KEY_F(48)},
150
- #endif
151
- #ifdef HAVE_DECKEYSYM_H
152
- {DXK_Remove, FALSE, KEY_DC, KEY_SDC, CTL_DEL, ALT_DEL},
153
- #endif
154
- {XK_Escape, FALSE, 0x1B, 0x1B, 0x1B, ALT_ESC},
155
- {XK_KP_Enter, TRUE, PADENTER, PADENTER, CTL_PADENTER,ALT_PADENTER},
156
- {XK_KP_Add, TRUE, PADPLUS, '+', CTL_PADPLUS, ALT_PADPLUS},
157
- {XK_KP_Subtract,TRUE, PADMINUS, '-', CTL_PADMINUS,ALT_PADMINUS},
158
- {XK_KP_Multiply,TRUE, PADSTAR, '*', CTL_PADSTAR, ALT_PADSTAR},
159
- /* Sun Type 4 keyboard */
160
- {XK_R6, TRUE, PADSTAR, '*', CTL_PADSTAR, ALT_PADSTAR},
161
- {XK_KP_Divide, TRUE, PADSLASH, '/', CTL_PADSLASH,ALT_PADSLASH},
162
- /* Sun Type 4 keyboard */
163
- {XK_R5, TRUE, PADSLASH, '/', CTL_PADSLASH,ALT_PADSLASH},
164
- {XK_KP_Decimal,TRUE, PADSTOP, '.', CTL_PADSTOP, ALT_PADSTOP},
165
- {XK_KP_0, TRUE, PAD0, '0', CTL_PAD0, ALT_PAD0},
166
- {XK_KP_1, TRUE, KEY_C1, '1', CTL_PAD1, ALT_PAD1},
167
- {XK_KP_2, TRUE, KEY_C2, '2', CTL_PAD2, ALT_PAD2},
168
- {XK_KP_3, TRUE, KEY_C3, '3', CTL_PAD3, ALT_PAD3},
169
- {XK_KP_4, TRUE, KEY_B1, '4', CTL_PAD4, ALT_PAD4},
170
- {XK_KP_5, TRUE, KEY_B2, '5', CTL_PAD5, ALT_PAD5},
171
- /* Sun Type 4 keyboard */
172
- {XK_R11, TRUE, KEY_B2, '5', CTL_PAD5, ALT_PAD5},
173
- {XK_KP_6, TRUE, KEY_B3, '6', CTL_PAD6, ALT_PAD6},
174
- {XK_KP_7, TRUE, KEY_A1, '7', CTL_PAD7, ALT_PAD7},
175
- {XK_KP_8, TRUE, KEY_A2, '8', CTL_PAD8, ALT_PAD8},
176
- {XK_KP_9, TRUE, KEY_A3, '9', CTL_PAD9, ALT_PAD9},
177
- /* the following added to support Sun Type 5 keyboards */
178
- {XK_F21, FALSE, KEY_SUSPEND, KEY_SSUSPEND, KEY_SUSPEND, KEY_SUSPEND},
179
- {XK_F22, FALSE, KEY_PRINT, KEY_SPRINT, KEY_PRINT, KEY_PRINT},
180
- {XK_F24, TRUE, PADMINUS, '-', CTL_PADMINUS,ALT_PADMINUS},
181
- /* Sun Type 4 keyboard */
182
- {XK_F25, TRUE, PADSLASH, '/', CTL_PADSLASH,ALT_PADSLASH},
183
- /* Sun Type 4 keyboard */
184
- {XK_F26, TRUE, PADSTAR, '*', CTL_PADSTAR, ALT_PADSTAR},
185
- {XK_F27, TRUE, KEY_A1, '7', CTL_PAD7, ALT_PAD7},
186
- {XK_F29, TRUE, KEY_A3, '9', CTL_PAD9, ALT_PAD9},
187
- {XK_F31, TRUE, KEY_B2, '5', CTL_PAD5, ALT_PAD5},
188
- {XK_F35, TRUE, KEY_C3, '3', CTL_PAD3, ALT_PAD3},
189
- #ifdef HAVE_XK_KP_DELETE
190
- {XK_KP_Delete, TRUE, PADSTOP, '.', CTL_PADSTOP, ALT_PADSTOP},
191
- #endif
192
- #ifdef HAVE_XK_KP_INSERT
193
- {XK_KP_Insert, TRUE, PAD0, '0', CTL_PAD0, ALT_PAD0},
194
- #endif
195
- #ifdef HAVE_XK_KP_END
196
- {XK_KP_End, TRUE, KEY_C1, '1', CTL_PAD1, ALT_PAD1},
197
- #endif
198
- #ifdef HAVE_XK_KP_DOWN
199
- {XK_KP_Down, TRUE, KEY_C2, '2', CTL_PAD2, ALT_PAD2},
200
- #endif
201
- #ifdef HAVE_XK_KP_NEXT
202
- {XK_KP_Next, TRUE, KEY_C3, '3', CTL_PAD3, ALT_PAD3},
203
- #endif
204
- #ifdef HAVE_XK_KP_LEFT
205
- {XK_KP_Left, TRUE, KEY_B1, '4', CTL_PAD4, ALT_PAD4},
206
- #endif
207
- #ifdef HAVE_XK_KP_BEGIN
208
- {XK_KP_Begin, TRUE, KEY_B2, '5', CTL_PAD5, ALT_PAD5},
209
- #endif
210
- #ifdef HAVE_XK_KP_RIGHT
211
- {XK_KP_Right, TRUE, KEY_B3, '6', CTL_PAD6, ALT_PAD6},
212
- #endif
213
- #ifdef HAVE_XK_KP_HOME
214
- {XK_KP_Home, TRUE, KEY_A1, '7', CTL_PAD7, ALT_PAD7},
215
- #endif
216
- #ifdef HAVE_XK_KP_UP
217
- {XK_KP_Up, TRUE, KEY_A2, '8', CTL_PAD8, ALT_PAD8},
218
- #endif
219
- #ifdef HAVE_XK_KP_PRIOR
220
- {XK_KP_Prior, TRUE, KEY_A3, '9', CTL_PAD9, ALT_PAD9},
221
- #endif
222
-
223
- #ifdef XF86XK_Back
224
- {XF86XK_Back, FALSE, KEY_BROWSER_BACK, KEY_SBROWSER_BACK,
225
- KEY_CBROWSER_BACK, KEY_ABROWSER_BACK },
226
- #endif
227
-
228
- #ifdef XF86XK_Forward
229
- {XF86XK_Forward, FALSE, KEY_BROWSER_FWD, KEY_SBROWSER_FWD,
230
- KEY_CBROWSER_FWD, KEY_ABROWSER_FWD },
231
- #endif
232
-
233
- #ifdef XF86XK_Reload
234
- {XF86XK_Reload, FALSE, KEY_BROWSER_REF, KEY_SBROWSER_REF,
235
- KEY_CBROWSER_REF, KEY_ABROWSER_REF },
236
- #endif
237
-
238
- #ifdef XF86XK_Search
239
- {XF86XK_Search, FALSE, KEY_SEARCH, KEY_SSEARCH,
240
- KEY_CSEARCH, KEY_ASEARCH },
241
- #endif
242
-
243
- #ifdef XF86XK_Favorites
244
- {XF86XK_Favorites, FALSE, KEY_FAVORITES, KEY_SFAVORITES,
245
- KEY_CFAVORITES, KEY_AFAVORITES },
246
- #endif
247
-
248
- #ifdef XF86XK_AudioPlay
249
- {XF86XK_AudioPlay, FALSE, KEY_PLAY_PAUSE, KEY_SPLAY_PAUSE,
250
- KEY_CPLAY_PAUSE, KEY_APLAY_PAUSE },
251
- #endif
252
-
253
- #ifdef XF86XK_AudioStop
254
- {XF86XK_AudioStop, FALSE, KEY_MEDIA_STOP, KEY_SMEDIA_STOP,
255
- KEY_CMEDIA_STOP, KEY_AMEDIA_STOP },
256
- #endif
257
-
258
- #ifdef XF86XK_AudioPrev
259
- {XF86XK_AudioPrev, FALSE, KEY_PREV_TRACK, KEY_SPREV_TRACK,
260
- KEY_CPREV_TRACK, KEY_APREV_TRACK },
261
- #endif
262
-
263
- #ifdef XF86XK_AudioNext
264
- {XF86XK_AudioNext, FALSE, KEY_NEXT_TRACK, KEY_SNEXT_TRACK,
265
- KEY_CNEXT_TRACK, KEY_ANEXT_TRACK },
266
- #endif
267
-
268
- #ifdef XF86XK_Tools
269
- {XF86XK_Tools, FALSE, KEY_MEDIA_SELECT, KEY_SMEDIA_SELECT,
270
- KEY_CMEDIA_SELECT, KEY_AMEDIA_SELECT },
271
- #endif
272
-
273
- {0, 0, 0, 0, 0, 0}
274
- };
275
-
276
- #ifndef PDC_XIM
277
- # include "compose.h"
278
- #endif
279
-
280
- #define BITMAPDEPTH 1
281
-
282
- unsigned long pdc_key_modifiers = 0L;
283
-
284
- static GC normal_gc, bold_gc, block_cursor_gc, rect_cursor_gc, italic_gc, border_gc;
285
- static int font_height, font_width, font_ascent, font_descent,
286
- window_width, window_height;
287
- static int resize_window_width = 0, resize_window_height = 0;
288
- static char *bitmap_file = NULL;
289
- #ifdef HAVE_XPM_H
290
- static char *pixmap_file = NULL;
291
- #endif
292
- static KeySym keysym = 0;
293
- static int PDC_blink_state = 1;
294
- static int PDC_really_blinking = FALSE; /* see 'pdcsetsc.c' */
295
-
296
- #ifndef PDC_XIM
297
- static int state_mask[8] =
298
- {
299
- ShiftMask,
300
- LockMask,
301
- ControlMask,
302
- Mod1Mask,
303
- Mod2Mask,
304
- Mod3Mask,
305
- Mod4Mask,
306
- Mod5Mask
307
- };
308
- #endif
309
-
310
- static Atom wm_atom[2];
311
- static String class_name = "XCurses";
312
- static XtAppContext app_context;
313
- static Widget topLevel, drawing, scrollBox, scrollVert, scrollHoriz;
314
- static int received_map_notify = 0;
315
- static bool mouse_selection = FALSE;
316
- static chtype *tmpsel = NULL;
317
- static unsigned long tmpsel_length = 0;
318
- static int selection_start_x = 0, selection_start_y = 0,
319
- selection_end_x = 0, selection_end_y = 0;
320
- static Pixmap icon_bitmap;
321
- #ifdef HAVE_XPM_H
322
- static Pixmap icon_pixmap;
323
- static Pixmap icon_pixmap_mask;
324
- #endif
325
- static bool window_entered = TRUE;
326
- static char *program_name;
327
-
328
- /* Macros just for app_resources */
329
-
330
- #ifdef PDC_WIDE
331
- # define DEFFONT "-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso10646-1"
332
- # define DEFBOLDFONT "-misc-fixed-bold-r-normal--13-120-75-75-c-70-iso10646-1"
333
- # define DEFITALICFONT "-misc-fixed-medium-o-normal--13-120-75-75-c-70-iso10646-1"
334
- #else
335
- # define DEFFONT "-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1"
336
- # define DEFBOLDFONT "-misc-fixed-bold-r-normal--13-120-75-75-c-70-iso8859-1"
337
- # define DEFITALICFONT "-misc-fixed-medium-o-normal--13-120-75-75-c-70-iso8859-1"
338
- #endif
339
-
340
- #define APPDATAOFF(n) XtOffsetOf(XCursesAppData, n)
341
-
342
- #define RINT(name1, name2, value) { \
343
- #name1, #name2, XtRInt, \
344
- sizeof(int), APPDATAOFF(name1), XtRImmediate, \
345
- (XtPointer)value \
346
- }
347
-
348
- #define RPIXEL(name1, name2, value) { \
349
- #name1, #name2, XtRPixel, \
350
- sizeof(Pixel), APPDATAOFF(name1), XtRString, \
351
- (XtPointer)#value \
352
- }
353
-
354
- #define RCOLOR(name, value) RPIXEL(color##name, Color##name, value)
355
-
356
-
357
- #define RSTRINGP(name1, name2, param) { \
358
- #name1, #name2, XtRString, \
359
- MAX_PATH, APPDATAOFF(name1), XtRString, (XtPointer)param \
360
- }
361
-
362
- #define RSTRING(name1, name2) RSTRINGP(name1, name2, "")
363
-
364
- #define RFONT(name1, name2, value) { \
365
- #name1, #name2, XtRFontStruct, \
366
- sizeof(XFontStruct), APPDATAOFF(name1), XtRString, \
367
- (XtPointer)value \
368
- }
369
-
370
- #define RCURSOR(name1, name2, value) { \
371
- #name1, #name2, XtRCursor, \
372
- sizeof(Cursor), APPDATAOFF(name1), XtRString, \
373
- (XtPointer)#value \
374
- }
375
-
376
- static XtResource app_resources[] =
377
- {
378
- RINT(lines, Lines, 24),
379
- RINT(cols, Cols, 80),
380
-
381
- RPIXEL(cursorColor, CursorColor, Red),
382
-
383
- RCOLOR(Black, Black),
384
- RCOLOR(Red, red3),
385
- RCOLOR(Green, green3),
386
- RCOLOR(Yellow, yellow3),
387
- RCOLOR(Blue, blue3),
388
- RCOLOR(Magenta, magenta3),
389
- RCOLOR(Cyan, cyan3),
390
- RCOLOR(White, Grey),
391
-
392
- RCOLOR(BoldBlack, grey40),
393
- RCOLOR(BoldRed, red1),
394
- RCOLOR(BoldGreen, green1),
395
- RCOLOR(BoldYellow, yellow1),
396
- RCOLOR(BoldBlue, blue1),
397
- RCOLOR(BoldMagenta, magenta1),
398
- RCOLOR(BoldCyan, cyan1),
399
- RCOLOR(BoldWhite, White),
400
-
401
- RFONT(normalFont, NormalFont, DEFFONT),
402
- RFONT(italicFont, ItalicFont, DEFITALICFONT),
403
- RFONT(boldFont, BoldFont, DEFBOLDFONT),
404
-
405
- RSTRING(bitmap, Bitmap),
406
- #ifdef HAVE_XPM_H
407
- RSTRING(pixmap, Pixmap),
408
- #endif
409
- RSTRINGP(composeKey, ComposeKey, "Multi_key"),
410
-
411
- RCURSOR(pointer, Pointer, xterm),
412
-
413
- RPIXEL(pointerForeColor, PointerForeColor, Black),
414
- RPIXEL(pointerBackColor, PointerBackColor, White),
415
-
416
- RINT(shmmin, Shmmin, 0),
417
- RINT(borderWidth, BorderWidth, 0),
418
-
419
- RPIXEL(borderColor, BorderColor, Black),
420
-
421
- RINT(doubleClickPeriod, DoubleClickPeriod, (PDC_CLICK_PERIOD * 2)),
422
- RINT(clickPeriod, ClickPeriod, PDC_CLICK_PERIOD),
423
- RINT(scrollbarWidth, ScrollbarWidth, 15),
424
- RINT(cursorBlinkRate, CursorBlinkRate, 0),
425
-
426
- RSTRING(textCursor, TextCursor)
427
- };
428
-
429
-
430
- #undef RCURSOR
431
- #undef RFONT
432
- #undef RSTRING
433
- #undef RCOLOR
434
- #undef RPIXEL
435
- /* #undef RINT */
436
- /* #undef APPDATAOFF */
437
- #undef DEFFONT
438
- #undef DEFBOLDFONT
439
- #undef DEFITALICFONT
440
-
441
- /* Macros for options */
442
-
443
- #define COPT(name) {"-" #name, "*" #name, XrmoptionSepArg, NULL}
444
- #define CCOLOR(name) COPT(color##name)
445
-
446
- static XrmOptionDescRec options[] =
447
- {
448
- COPT(lines), COPT(cols), COPT(normalFont), COPT(italicFont),
449
- COPT(bitmap), COPT(boldFont),
450
- #ifdef HAVE_XPM_H
451
- COPT(pixmap),
452
- #endif
453
- COPT(pointer), COPT(shmmin), COPT(composeKey), COPT(clickPeriod),
454
- COPT(doubleClickPeriod), COPT(scrollbarWidth),
455
- COPT(pointerForeColor), COPT(pointerBackColor),
456
- COPT(cursorBlinkRate), COPT(cursorColor), COPT(textCursor),
457
-
458
- CCOLOR(Black), CCOLOR(Red), CCOLOR(Green), CCOLOR(Yellow),
459
- CCOLOR(Blue), CCOLOR(Magenta), CCOLOR(Cyan), CCOLOR(White),
460
-
461
- CCOLOR(BoldBlack), CCOLOR(BoldRed), CCOLOR(BoldGreen),
462
- CCOLOR(BoldYellow), CCOLOR(BoldBlue), CCOLOR(BoldMagenta),
463
- CCOLOR(BoldCyan), CCOLOR(BoldWhite)
464
- };
465
-
466
- #undef CCOLOR
467
- #undef COPT
468
-
469
- static XtActionsRec action_table[] =
470
- {
471
- {"XCursesButton", (XtActionProc)XCursesButton},
472
- {"XCursesKeyPress", (XtActionProc)XCursesKeyPress},
473
- {"XCursesPasteSelection", (XtActionProc)XCursesPasteSelection},
474
- {"string", (XtActionProc)XCursesHandleString}
475
- };
476
-
477
- static bool after_first_curses_request = FALSE;
478
- static Pixel colors[MAX_COLORS + 2];
479
-
480
- #ifdef PDC_XIM
481
- static XIM Xim = NULL;
482
- static XIC Xic = NULL;
483
- #endif
484
-
485
- static const char *default_translations =
486
- {
487
- "<Key>: XCursesKeyPress() \n" \
488
- "<KeyUp>: XCursesKeyPress() \n" \
489
- "<BtnDown>: XCursesButton() \n" \
490
- "<BtnUp>: XCursesButton() \n" \
491
- "<BtnMotion>: XCursesButton()"
492
- };
493
-
494
- static int _to_utf8(char *outcode, chtype code)
495
- {
496
- #ifdef PDC_WIDE
497
- if (code & A_ALTCHARSET && !(code & 0xff80))
498
- code = acs_map[code & 0x7f];
499
- #endif
500
- code &= A_CHARTEXT;
501
-
502
- if (code < 0x80)
503
- {
504
- outcode[0] = code;
505
- return 1;
506
- }
507
- else
508
- if (code < 0x800)
509
- {
510
- outcode[0] = ((code & 0x07c0) >> 6) | 0xc0;
511
- outcode[1] = (code & 0x003f) | 0x80;
512
- return 2;
513
- }
514
- else if( code < 0x10000)
515
- {
516
- outcode[0] = ((code & 0xf000) >> 12) | 0xe0;
517
- outcode[1] = ((code & 0x0fc0) >> 6) | 0x80;
518
- outcode[2] = (code & 0x003f) | 0x80;
519
- return 3;
520
- }
521
- else /* SMP: Unicode past 64K */
522
- {
523
- outcode[0] = (code >> 18) | 0xf0;
524
- outcode[1] = ((code >> 12) & 0x3f) | 0x80;
525
- outcode[2] = ((code >> 6) & 0x3f) | 0x80;
526
- outcode[3] = ( code & 0x3f) | 0x80;
527
- return 4;
528
- }
529
- }
530
-
531
- static int _from_utf8(wchar_t *pwc, const char *s, size_t n)
532
- {
533
- wchar_t key;
534
- int i = -1;
535
- const unsigned char *string;
536
-
537
- if (!s || (n < 1))
538
- return -1;
539
-
540
- if (!*s)
541
- return 0;
542
-
543
- string = (const unsigned char *)s;
544
-
545
- key = string[0];
546
-
547
- /* Simplistic UTF-8 decoder -- minimal validation */
548
-
549
- if (key & 0x80)
550
- {
551
- if ((key & 0xe0) == 0xc0)
552
- {
553
- if (1 < n)
554
- {
555
- key = ((key & 0x1f) << 6) | (string[1] & 0x3f);
556
- i = 2;
557
- }
558
- }
559
- else if ((key & 0xf0) == 0xe0) /* Unicode from 0x800 to 0xffff */
560
- {
561
- if (2 < n)
562
- {
563
- key = ((key & 0x0f) << 12) |
564
- ((string[1] & 0x3f) << 6) | (string[2] & 0x3f);
565
- i = 3;
566
- }
567
- }
568
- else if ((key & 0xf8) == 0xf0) /* SMP: Unicode past 64K */
569
- {
570
- if (3 < n)
571
- {
572
- key = ((key & 0x07) << 18) | ((string[1] & 0x3f) << 12) |
573
- ((string[2] & 0x3f) << 6) | (string[3] & 0x3f);
574
- i = 4;
575
- }
576
- }
577
- else
578
- fprintf(stderr, "Invalid UTF8\n");
579
- }
580
- else
581
- i = 1;
582
-
583
- if (i)
584
- *pwc = key;
585
-
586
- return i;
587
- }
588
-
589
- #ifndef X_HAVE_UTF8_STRING
590
- static Atom XA_UTF8_STRING(Display *dpy)
591
- {
592
- static AtomPtr p = NULL;
593
-
594
- if (!p)
595
- p = XmuMakeAtom("UTF8_STRING");
596
-
597
- return XmuInternAtom(dpy, p);
598
- }
599
- #endif
600
-
601
- signal_handler XCursesSetSignal(int signo, signal_handler action)
602
- {
603
- #if defined(SA_INTERRUPT) || defined(SA_RESTART)
604
- struct sigaction sigact, osigact;
605
-
606
- sigact.sa_handler = action;
607
-
608
- sigact.sa_flags =
609
- # ifdef SA_INTERRUPT
610
- # ifdef SA_RESTART
611
- SA_INTERRUPT | SA_RESTART;
612
- # else
613
- SA_INTERRUPT;
614
- # endif
615
- # else /* must be SA_RESTART */
616
- SA_RESTART;
617
- # endif
618
- sigemptyset(&sigact.sa_mask);
619
-
620
- if (sigaction(signo, &sigact, &osigact))
621
- return SIG_ERR;
622
-
623
- return osigact.sa_handler;
624
-
625
- #else /* not SA_INTERRUPT or SA_RESTART, use plain signal */
626
- return signal(signo, action);
627
- #endif
628
- }
629
-
630
- RETSIGTYPE XCursesSigwinchHandler(int signo)
631
- {
632
- PDC_LOG(("%s:XCursesSigwinchHandler() - called: SIGNO: %d\n",
633
- XCLOGMSG, signo));
634
-
635
- /* Patch by: Georg Fuchs, georg.fuchs@rz.uni-regensburg.de
636
- 02-Feb-1999 */
637
-
638
- SP->resized += 1;
639
-
640
- /* Always trap SIGWINCH if the C library supports SIGWINCH */
641
-
642
- #ifdef SIGWINCH
643
- XCursesSetSignal(SIGWINCH, XCursesSigwinchHandler);
644
- #endif
645
- }
646
-
647
- /* Convert character positions x and y to pixel positions, stored in
648
- xpos and ypos */
649
-
650
- static void _make_xy(int x, int y, int *xpos, int *ypos)
651
- {
652
- *xpos = (x * font_width) + xc_app_data.borderWidth;
653
- *ypos = xc_app_data.normalFont->ascent + (y * font_height) +
654
- xc_app_data.borderWidth;
655
- }
656
-
657
- /* This function 'intensifies' a color by shifting it toward white. */
658
- /* It used to average the input color with white. Then it did a */
659
- /* weighted average: 2/3 of the input color, 1/3 white, for a */
660
- /* lower "intensification" level. */
661
- /* Then Mark Hessling suggested that the output level should */
662
- /* remap zero to 85 (= 255 / 3, so one-third intensity), and input */
663
- /* of 192 or greater should be remapped to 255 (full intensity). */
664
- /* Assuming we want a linear response between zero and 192, that */
665
- /* leads to output = 85 + input * (255-85)/192. */
666
- /* This should lead to proper handling of bold text in legacy */
667
- /* apps, where "bold" means "high intensity". */
668
- /* NOTE that this is basically a clone of code in wingui/pdcdisp.c. */
669
- /* The same basic logic should eventually be used in SDL, I think. */
670
-
671
- static Pixel intensified_color( Pixel ival)
672
- {
673
- int rgb, i;
674
- Pixel oval = 0;
675
-
676
- for( i = 0; i < 3; i++, ival >>= 8)
677
- {
678
- rgb = (int)( ival & 0xff);
679
- if( rgb >= 192)
680
- rgb = 255;
681
- else
682
- rgb = 85 + rgb * (255 - 85) / 192;
683
- oval |= ((Pixel)rgb << (i * 8));
684
- }
685
- return( oval);
686
- }
687
-
688
- /* For use in adjusting colors for A_DIMmed characters. Just */
689
- /* knocks down the intensity of R, G, and B by 1/3. */
690
-
691
- static Pixel dimmed_color( Pixel ival)
692
- {
693
- unsigned i;
694
- Pixel oval = 0;
695
-
696
- for( i = 0; i < 3; i++, ival >>= 8)
697
- {
698
- unsigned rgb = (unsigned)( ival & 0xff);
699
-
700
- rgb -= (rgb / 3);
701
- oval |= ((Pixel)rgb << (i * 8));
702
- }
703
- return( oval);
704
- }
705
-
706
- /* see 'addch.c' for an explanation of how combining chars are handled. */
707
- /* Though note that right now, it doesn't work at all; we'll have to */
708
- /* arrange shared memory or communication between the X process and the */
709
- /* "host" process... to be done later. */
710
-
711
- #if defined( CHTYPE_LONG) && CHTYPE_LONG >= 2
712
- #ifdef PDC_WIDE
713
- #define USING_COMBINING_CHARACTER_SCHEME
714
- int PDC_expand_combined_characters( const cchar_t c, cchar_t *added); /* addch.c */
715
- #endif
716
-
717
- /* PDC_get_rgb_values(), extract_packed_rgb(), intensified_component(), */
718
- /* intensified_color(), and dimmed_color() each exist in x11/x11.c, */
719
- /* wingui/pdcdisp.c, and sdl2/pdcdisp.c in forms slightly modified for */
720
- /* each platform. But they all look pretty much alike. */
721
-
722
- /* PDCurses stores RGBs in fifteen bits, five bits each */
723
- /* for red, green, blue. A Pixel uses eight bits per */
724
- /* channel. Hence the following. */
725
- static Pixel extract_packed_rgb( const chtype color)
726
- {
727
- const int red = (int)( (color << 3) & 0xf8);
728
- const int green = (int)( (color >> 2) & 0xf8);
729
- const int blue = (int)( (color >> 7) & 0xf8);
730
-
731
- return( ((Pixel)red << 16) | ((Pixel)green << 8) | (Pixel)blue);
732
- }
733
- #endif
734
-
735
-
736
- void PDC_get_rgb_values( const chtype srcp,
737
- Pixel *foreground_rgb, Pixel *background_rgb)
738
- {
739
- bool reverse_colors = ((srcp & A_REVERSE) ? TRUE : FALSE);
740
- bool intensify_backgnd = FALSE;
741
-
742
- #if defined( CHTYPE_LONG) && CHTYPE_LONG >= 2
743
- if( srcp & A_RGB_COLOR)
744
- {
745
- /* Extract RGB from 30 bits of the color field */
746
- *background_rgb = extract_packed_rgb( srcp >> PDC_COLOR_SHIFT);
747
- *foreground_rgb = extract_packed_rgb( srcp >> (PDC_COLOR_SHIFT + 15));
748
- }
749
- else
750
- #endif
751
- {
752
- short foreground_index, background_index;
753
-
754
- PDC_pair_content( PAIR_NUMBER( srcp), &foreground_index, &background_index);
755
- *foreground_rgb = colors[foreground_index];
756
- *background_rgb = colors[background_index];
757
- }
758
-
759
- if( srcp & A_BLINK)
760
- {
761
- if( !PDC_really_blinking) /* convert 'blinking' to 'bold' */
762
- intensify_backgnd = TRUE;
763
- else if( PDC_blink_state)
764
- reverse_colors = !reverse_colors;
765
- }
766
- if( reverse_colors)
767
- {
768
- const Pixel temp = *foreground_rgb;
769
-
770
- *foreground_rgb = *background_rgb;
771
- *background_rgb = temp;
772
- }
773
-
774
- if( srcp & A_BOLD)
775
- *foreground_rgb = intensified_color( *foreground_rgb);
776
- if( intensify_backgnd)
777
- *background_rgb = intensified_color( *background_rgb);
778
- if( srcp & A_DIM)
779
- *foreground_rgb = dimmed_color( *foreground_rgb);
780
- if( srcp & A_DIM)
781
- *background_rgb = dimmed_color( *background_rgb);
782
- }
783
-
784
- /* Output a block of characters with common attributes */
785
-
786
- static int _new_packet( const chtype attr, const bool rev, const int len,
787
- const int col, const int row,
788
- #ifdef PDC_WIDE
789
- XChar2b *text)
790
- #else
791
- char *text)
792
- #endif
793
- {
794
- XRectangle bounds;
795
- GC gc;
796
- int xpos, ypos;
797
- Pixel foreground_rgb, background_rgb;
798
-
799
- #ifdef PDC_WIDE
800
- text[len].byte1 = text[len].byte2 = 0;
801
- #else
802
- text[len] = '\0';
803
- #endif
804
-
805
- /* Determine which GC to use - normal or italic */
806
- if ( attr & A_ITALIC )
807
- {
808
- gc = italic_gc;
809
- }
810
- else if ( attr & A_BOLD )
811
- {
812
- gc = bold_gc;
813
- }
814
- else
815
- {
816
- gc = normal_gc;
817
- }
818
-
819
- /* Draw it */
820
-
821
- PDC_get_rgb_values( attr, &foreground_rgb, &background_rgb);
822
- if( rev)
823
- {
824
- const Pixel swap_val = foreground_rgb;
825
-
826
- foreground_rgb = background_rgb;
827
- background_rgb = swap_val;
828
- }
829
- XSetForeground(XCURSESDISPLAY, gc, foreground_rgb);
830
- XSetBackground(XCURSESDISPLAY, gc, background_rgb);
831
-
832
- _make_xy(col, row, &xpos, &ypos);
833
-
834
- bounds.x = xpos;
835
- bounds.y = ypos - font_ascent;
836
- bounds.width = font_width * len;
837
- bounds.height = font_height;
838
-
839
- XSetClipRectangles(XCURSESDISPLAY, gc, 0, 0, &bounds, 1, Unsorted);
840
-
841
- #ifdef PDC_WIDE
842
- XDrawImageString16(
843
- #else
844
- XDrawImageString(
845
- #endif
846
- XCURSESDISPLAY, XCURSESWIN, gc, xpos, ypos, text, len);
847
-
848
- /* Underline, etc. */
849
-
850
- if (attr & (A_LEFTLINE|A_RIGHTLINE|A_UNDERLINE|A_OVERLINE|A_STRIKEOUT))
851
- {
852
- int k;
853
-
854
- if (SP->line_color != -1)
855
- XSetForeground(XCURSESDISPLAY, gc, colors[SP->line_color]);
856
-
857
- if (attr & A_UNDERLINE) /* UNDER */
858
- XDrawLine(XCURSESDISPLAY, XCURSESWIN, gc,
859
- xpos, ypos + xc_app_data.normalFont->descent-1, xpos + font_width * len, ypos + xc_app_data.normalFont->descent-1);
860
- /* xpos, ypos + 1, xpos + font_width * len, ypos + 1);*/
861
-
862
- if (attr & A_OVERLINE)
863
- XDrawLine(XCURSESDISPLAY, XCURSESWIN, gc,
864
- xpos, ypos - font_ascent, xpos + font_width * len, ypos - font_ascent);
865
-
866
- if (attr & A_STRIKEOUT)
867
- XDrawLine(XCURSESDISPLAY, XCURSESWIN, gc,
868
- xpos, ypos + (font_descent - font_ascent) / 2,
869
- xpos + font_width * len, ypos + (font_descent - font_ascent) / 2);
870
-
871
- if (attr & A_LEFTLINE) /* LEFT */
872
- for (k = 0; k < len; k++)
873
- {
874
- int x = xpos + font_width * k;
875
- XDrawLine(XCURSESDISPLAY, XCURSESWIN, gc,
876
- x, ypos - font_ascent, x, ypos + font_descent);
877
- }
878
-
879
- if (attr & A_RIGHTLINE) /* RIGHT */
880
- for (k = 0; k < len; k++)
881
- {
882
- int x = xpos + font_width * (k + 1) - 1;
883
- XDrawLine(XCURSESDISPLAY, XCURSESWIN, gc,
884
- x, ypos - font_ascent, x, ypos + font_descent);
885
- }
886
- }
887
-
888
- PDC_LOG(("%s:_new_packet() - row: %d col: %d "
889
- "num_cols: %d fore: %d back: %d text:<%s>\n",
890
- XCLOGMSG, row, col, len, foreground_rgb, background_rgb, text));
891
-
892
- return OK;
893
- }
894
-
895
- /* The core display routine -- update one line of text */
896
-
897
- static int _display_text(const chtype *ch, int row, int col,
898
- int num_cols, bool highlight)
899
- {
900
- #ifdef PDC_WIDE
901
- XChar2b text[513];
902
- #else
903
- char text[513];
904
- #endif
905
- chtype old_attr, attr;
906
- int i, j;
907
-
908
- PDC_LOG(("%s:_display_text() - called: row: %d col: %d "
909
- "num_cols: %d\n", XCLOGMSG, row, col, num_cols));
910
-
911
- if (!num_cols)
912
- return OK;
913
-
914
- old_attr = *ch & A_ATTRIBUTES;
915
-
916
- for (i = 0, j = 0; j < num_cols; j++)
917
- {
918
- chtype curr = ch[j];
919
-
920
- attr = curr & A_ATTRIBUTES;
921
-
922
- #ifdef CHTYPE_LONG
923
- if (attr & A_ALTCHARSET && !(curr & 0xff80))
924
- {
925
- attr ^= A_ALTCHARSET;
926
- curr = acs_map[curr & 0x7f];
927
- }
928
- #endif
929
-
930
- #ifndef PDC_WIDE
931
- /* Special handling for ACS_BLOCK */
932
-
933
- if (!(curr & A_CHARTEXT))
934
- {
935
- curr |= ' ';
936
- attr ^= A_REVERSE;
937
- }
938
- #endif
939
- if (attr != old_attr || i > 100)
940
- {
941
- if (_new_packet(old_attr, highlight, i, col, row, text) == ERR)
942
- return ERR;
943
-
944
- old_attr = attr;
945
- col += i;
946
- i = 0;
947
- }
948
-
949
- #ifdef PDC_WIDE
950
- curr &= A_CHARTEXT;
951
- if( curr <= 0xffff) /* BMP Unicode */
952
- {
953
- if( !curr)
954
- curr = ' ';
955
- text[i].byte1 = (curr & 0xff00) >> 8;
956
- text[i++].byte2 = curr & 0x00ff;
957
- }
958
- else /* SMP & combining chars */
959
- {
960
- const chtype MAX_UNICODE = 0x110000;
961
-
962
- if( curr < MAX_UNICODE) /* Supplemental Multilingual Plane */
963
- { /* (SMP); store w/surrogates */
964
- const unsigned short part1 = (unsigned short)
965
- (0xd800 | ((curr - 0x10000) >> 10));
966
- const unsigned short part2 = (unsigned short)
967
- (0xdc00 | (curr & 0x3ff));
968
-
969
- text[i].byte1 = part1 >> 8;
970
- text[i++].byte2 = part1 & 0xff;
971
- text[i].byte1 = part2 >> 8;
972
- text[i++].byte2 = part2 & 0xff;
973
- }
974
- #ifdef USING_COMBINING_CHARACTER_SCHEME
975
- else if( curr > MAX_UNICODE)
976
- {
977
- #ifdef GOT_COMBINING_CHARS_IN_X
978
- cchar_t added[10];
979
- int n_combined = 0;
980
-
981
- while( (curr = PDC_expand_combined_characters( curr,
982
- &added[n_combined])) > MAX_UNICODE)
983
- n_combined++;
984
- while( n_combined >= 0)
985
- {
986
- text[i].byte1 = added[n_combined] >> 8;
987
- text[i++].byte2 = added[n_combined] & 0xff;
988
- n_combined--;
989
- }
990
- #else
991
- text[i].byte1 = 0;
992
- text[i++].byte2 = '?';
993
- #endif
994
- }
995
- #endif
996
- }
997
- #else /* non-wide case */
998
- text[i++] = curr & 0xff;
999
- #endif
1000
- }
1001
-
1002
- return _new_packet(old_attr, highlight, i, col, row, text);
1003
- }
1004
-
1005
- static void _get_gc(GC *gc, XFontStruct *font_info, int fore, int back)
1006
- {
1007
- XGCValues values;
1008
-
1009
- /* Create default Graphics Context */
1010
-
1011
- *gc = XCreateGC(XCURSESDISPLAY, XCURSESWIN, 0L, &values);
1012
-
1013
- /* specify font */
1014
-
1015
- XSetFont(XCURSESDISPLAY, *gc, font_info->fid);
1016
-
1017
- #ifdef WHY_IS_THIS_HERE
1018
- XSetForeground(XCURSESDISPLAY, *gc, colors[fore]);
1019
- XSetBackground(XCURSESDISPLAY, *gc, colors[back]);
1020
- #endif
1021
- }
1022
-
1023
- #define RGB( R, G, B) (((unsigned long)(R)) << 16 \
1024
- | ((unsigned long)(G) << 8) | (unsigned long)(B))
1025
-
1026
- static void _initialize_colors(void)
1027
- {
1028
- int i, r, g, b;
1029
-
1030
- colors[COLOR_BLACK] = xc_app_data.colorBlack;
1031
- colors[COLOR_RED] = xc_app_data.colorRed;
1032
- colors[COLOR_GREEN] = xc_app_data.colorGreen;
1033
- colors[COLOR_YELLOW] = xc_app_data.colorYellow;
1034
- colors[COLOR_BLUE] = xc_app_data.colorBlue;
1035
- colors[COLOR_MAGENTA] = xc_app_data.colorMagenta;
1036
- colors[COLOR_CYAN] = xc_app_data.colorCyan;
1037
- colors[COLOR_WHITE] = xc_app_data.colorWhite;
1038
-
1039
- colors[COLOR_BLACK + 8] = xc_app_data.colorBoldBlack;
1040
- colors[COLOR_RED + 8] = xc_app_data.colorBoldRed;
1041
- colors[COLOR_GREEN + 8] = xc_app_data.colorBoldGreen;
1042
- colors[COLOR_YELLOW + 8] = xc_app_data.colorBoldYellow;
1043
- colors[COLOR_BLUE + 8] = xc_app_data.colorBoldBlue;
1044
- colors[COLOR_MAGENTA + 8] = xc_app_data.colorBoldMagenta;
1045
- colors[COLOR_CYAN + 8] = xc_app_data.colorBoldCyan;
1046
- colors[COLOR_WHITE + 8] = xc_app_data.colorBoldWhite;
1047
- i = 16;
1048
- /* 256-color xterm extended palette: 216 colors in a
1049
- 6x6x6 color cube, plus 24 (not 50) shades of gray */
1050
- for( r = 0; r < 6; r++)
1051
- for( g = 0; g < 6; g++)
1052
- for( b = 0; b < 6; b++)
1053
- colors[i++] = RGB( r ? r * 40 + 55 : 0,
1054
- g ? g * 40 + 55 : 0,
1055
- b ? b * 40 + 55 : 0);
1056
- for( i = 0; i < 24; i++)
1057
- colors[i + 232] = RGB( i * 10 + 8, i * 10 + 8, i * 10 + 8);
1058
-
1059
- colors[COLOR_CURSOR] = xc_app_data.cursorColor;
1060
- colors[COLOR_BORDER] = xc_app_data.borderColor;
1061
- }
1062
-
1063
- static void _refresh_scrollbar(void)
1064
- {
1065
- XC_LOG(("_refresh_scrollbar() - called\n"));
1066
-
1067
- if (SP->sb_on)
1068
- {
1069
- PDC_SCROLLBAR_TYPE total_y = SP->sb_total_y;
1070
- PDC_SCROLLBAR_TYPE total_x = SP->sb_total_x;
1071
-
1072
- if (total_y)
1073
- XawScrollbarSetThumb(scrollVert,
1074
- (PDC_SCROLLBAR_TYPE)(SP->sb_cur_y) / total_y,
1075
- (PDC_SCROLLBAR_TYPE)(SP->sb_viewport_y) / total_y);
1076
-
1077
- if (total_x)
1078
- XawScrollbarSetThumb(scrollHoriz,
1079
- (PDC_SCROLLBAR_TYPE)(SP->sb_cur_x) / total_x,
1080
- (PDC_SCROLLBAR_TYPE)(SP->sb_viewport_x) / total_x);
1081
- }
1082
- }
1083
-
1084
- static void _set_cursor_color(chtype *ch, short *fore, short *back)
1085
- {
1086
- int attr;
1087
- short f, b;
1088
-
1089
- attr = PAIR_NUMBER(*ch);
1090
-
1091
- if (attr)
1092
- {
1093
- PDC_pair_content(attr, &f, &b);
1094
- *fore = 7 - (f % 8);
1095
- *back = 7 - (b % 8);
1096
- }
1097
- else
1098
- {
1099
- if (*ch & A_REVERSE)
1100
- {
1101
- *back = COLOR_BLACK;
1102
- *fore = COLOR_WHITE;
1103
- }
1104
- else
1105
- {
1106
- *back = COLOR_WHITE;
1107
- *fore = COLOR_BLACK;
1108
- }
1109
- }
1110
- }
1111
-
1112
- static void _get_icon(void)
1113
- {
1114
- XIconSize *icon_size;
1115
- int size_count = 0;
1116
- Status rc;
1117
- unsigned char *bitmap_bits = NULL;
1118
- unsigned icon_bitmap_width = 0, icon_bitmap_height = 0,
1119
- file_bitmap_width = 0, file_bitmap_height = 0;
1120
-
1121
- XC_LOG(("_get_icon() - called\n"));
1122
-
1123
- icon_size = XAllocIconSize();
1124
-
1125
- rc = XGetIconSizes(XtDisplay(topLevel),
1126
- RootWindowOfScreen(XtScreen(topLevel)),
1127
- &icon_size, &size_count);
1128
-
1129
- /* if the WM can advise on icon sizes... */
1130
-
1131
- if (rc && size_count)
1132
- {
1133
- int i, max_height = 0, max_width = 0;
1134
-
1135
- PDC_LOG(("%s:size_count: %d rc: %d\n", XCLOGMSG, size_count, rc));
1136
-
1137
- for (i = 0; i < size_count; i++)
1138
- {
1139
- if (icon_size[i].max_width > max_width)
1140
- max_width = icon_size[i].max_width;
1141
- if (icon_size[i].max_height > max_height)
1142
- max_height = icon_size[i].max_height;
1143
-
1144
- PDC_LOG(("%s:min: %d %d\n", XCLOGMSG,
1145
- icon_size[i].min_width, icon_size[i].min_height));
1146
-
1147
- PDC_LOG(("%s:max: %d %d\n", XCLOGMSG,
1148
- icon_size[i].max_width, icon_size[i].max_height));
1149
-
1150
- PDC_LOG(("%s:inc: %d %d\n", XCLOGMSG,
1151
- icon_size[i].width_inc, icon_size[i].height_inc));
1152
- }
1153
-
1154
- if (max_width >= big_icon_width && max_height >= big_icon_height)
1155
- {
1156
- icon_bitmap_width = big_icon_width;
1157
- icon_bitmap_height = big_icon_height;
1158
- bitmap_bits = (unsigned char *)big_icon_bits;
1159
- }
1160
- else
1161
- {
1162
- icon_bitmap_width = little_icon_width;
1163
- icon_bitmap_height = little_icon_height;
1164
- bitmap_bits = (unsigned char *)little_icon_bits;
1165
- }
1166
-
1167
- }
1168
- else /* use small icon */
1169
- {
1170
- icon_bitmap_width = little_icon_width;
1171
- icon_bitmap_height = little_icon_height;
1172
- bitmap_bits = (unsigned char *)little_icon_bits;
1173
- }
1174
-
1175
- XFree(icon_size);
1176
-
1177
- #ifdef HAVE_XPM_H
1178
- if (xc_app_data.pixmap && xc_app_data.pixmap[0]) /* supplied pixmap */
1179
- {
1180
- XpmReadFileToPixmap(XtDisplay(topLevel),
1181
- RootWindowOfScreen(XtScreen(topLevel)),
1182
- (char *)xc_app_data.pixmap,
1183
- &icon_pixmap, &icon_pixmap_mask, NULL);
1184
- return;
1185
- }
1186
- #endif
1187
-
1188
- if (xc_app_data.bitmap && xc_app_data.bitmap[0]) /* supplied bitmap */
1189
- {
1190
- int x_hot = 0, y_hot = 0;
1191
-
1192
- rc = XReadBitmapFile(XtDisplay(topLevel),
1193
- RootWindowOfScreen(XtScreen(topLevel)),
1194
- (char *)xc_app_data.bitmap,
1195
- &file_bitmap_width, &file_bitmap_height,
1196
- &icon_bitmap, &x_hot, &y_hot);
1197
-
1198
- switch(rc)
1199
- {
1200
- case BitmapOpenFailed:
1201
- fprintf(stderr, "bitmap file %s: not found\n",
1202
- xc_app_data.bitmap);
1203
- break;
1204
- case BitmapFileInvalid:
1205
- fprintf(stderr, "bitmap file %s: contents invalid\n",
1206
- xc_app_data.bitmap);
1207
- break;
1208
- default:
1209
- return;
1210
- }
1211
- }
1212
-
1213
- icon_bitmap = XCreateBitmapFromData(XtDisplay(topLevel),
1214
- RootWindowOfScreen(XtScreen(topLevel)),
1215
- (char *)bitmap_bits, icon_bitmap_width, icon_bitmap_height);
1216
- }
1217
-
1218
- static void _draw_border(void)
1219
- {
1220
- /* Draw the border if required */
1221
-
1222
- if (xc_app_data.borderWidth)
1223
- XDrawRectangle(XCURSESDISPLAY, XCURSESWIN, border_gc,
1224
- xc_app_data.borderWidth / 2,
1225
- xc_app_data.borderWidth / 2,
1226
- window_width - xc_app_data.borderWidth,
1227
- window_height - xc_app_data.borderWidth);
1228
- }
1229
-
1230
- /* Redraw the entire screen */
1231
-
1232
- static void _display_screen(void)
1233
- {
1234
- int row;
1235
-
1236
- XC_LOG(("_display_screen() - called\n"));
1237
-
1238
- for (row = 0; row < XCursesLINES; row++)
1239
- {
1240
- XC_get_line_lock(row);
1241
-
1242
- _display_text((const chtype *)(Xcurscr + XCURSCR_Y_OFF(row)),
1243
- row, 0, COLS, FALSE);
1244
-
1245
- XC_release_line_lock(row);
1246
- if( row == SP->cursrow && SP->visibility)
1247
- _redraw_cursor();
1248
- }
1249
-
1250
- _draw_border();
1251
- }
1252
-
1253
- /* Draw changed portions of the screen */
1254
-
1255
- static void _refresh_screen(void)
1256
- {
1257
- int row, start_col, num_cols;
1258
-
1259
- XC_LOG(("_refresh_screen() - called\n"));
1260
-
1261
- for (row = 0; row < XCursesLINES; row++)
1262
- {
1263
- num_cols = (int)*(Xcurscr + XCURSCR_LENGTH_OFF + row);
1264
-
1265
- if (num_cols)
1266
- {
1267
- XC_get_line_lock(row);
1268
-
1269
- start_col = (int)*(Xcurscr + XCURSCR_START_OFF + row);
1270
-
1271
- _display_text((const chtype *)(Xcurscr + XCURSCR_Y_OFF(row) +
1272
- (start_col * sizeof(chtype))), row, start_col,
1273
- num_cols, FALSE);
1274
-
1275
- *(Xcurscr + XCURSCR_LENGTH_OFF + row) = 0;
1276
-
1277
- XC_release_line_lock(row);
1278
- if( row == SP->cursrow && SP->visibility)
1279
- _redraw_cursor();
1280
- }
1281
- }
1282
-
1283
- _selection_off();
1284
- }
1285
-
1286
- static void _handle_expose(Widget w, XtPointer client_data, XEvent *event,
1287
- Boolean *unused)
1288
- {
1289
- XC_LOG(("_handle_expose() - called\n"));
1290
-
1291
- /* ignore all Exposes except last */
1292
-
1293
- if (event->xexpose.count)
1294
- return;
1295
-
1296
- if (after_first_curses_request && received_map_notify)
1297
- _display_screen();
1298
- }
1299
-
1300
- static void _handle_nonmaskable(Widget w, XtPointer client_data, XEvent *event,
1301
- Boolean *unused)
1302
- {
1303
- XClientMessageEvent *client_event = (XClientMessageEvent *)event;
1304
-
1305
- PDC_LOG(("%s:_handle_nonmaskable called: xc_otherpid %d event %d\n",
1306
- XCLOGMSG, xc_otherpid, event->type));
1307
-
1308
- if (event->type == ClientMessage)
1309
- {
1310
- XC_LOG(("ClientMessage received\n"));
1311
-
1312
- /* This code used to include handling of WM_SAVE_YOURSELF, but
1313
- it resulted in continual failure of THE on my Toshiba laptop.
1314
- Removed on 3-3-2001. Now only exits on WM_DELETE_WINDOW. */
1315
-
1316
- if ((Atom)client_event->data.s[0] == wm_atom[0])
1317
- {
1318
- /* if we specified an exit key return it, otherwise exit the process */
1319
- if ( SP->exit_key )
1320
- _send_key_to_curses(SP->exit_key, NULL, TRUE);
1321
- else
1322
- _exit_process(0, SIGKILL, "");
1323
- }
1324
- }
1325
- }
1326
-
1327
- static int override_cursor = -1;
1328
-
1329
- #define CURSOR_UNBLINKING_RECTANGLE 0x303
1330
-
1331
- static void XCursesKeyPress(Widget w, XEvent *event, String *params,
1332
- Cardinal *nparams)
1333
- {
1334
- enum { STATE_NORMAL, STATE_COMPOSE, STATE_CHAR };
1335
-
1336
- #ifdef PDC_XIM
1337
- Status status;
1338
- wchar_t buffer[120];
1339
- #else
1340
- unsigned char buffer[120];
1341
- XComposeStatus compose;
1342
- static int compose_state = STATE_NORMAL;
1343
- static int compose_index = 0;
1344
- int char_idx = 0;
1345
- #endif
1346
- unsigned long key = 0;
1347
- int buflen = 40;
1348
- int i, count;
1349
- unsigned long modifier = 0;
1350
- bool key_code = FALSE;
1351
- static XEvent prev_event;
1352
- static int repeat_count = 0;
1353
-
1354
- XC_LOG(("XCursesKeyPress() - called\n"));
1355
-
1356
- /* Handle modifier keys first; ignore other KeyReleases */
1357
- if( event->type == KeyPress && prev_event.type == KeyRelease
1358
- && event->xkey.time == prev_event.xkey.time
1359
- && event->xkey.keycode == prev_event.xkey.keycode)
1360
- {
1361
- repeat_count++;
1362
- }
1363
- else if( event->type == KeyPress)
1364
- repeat_count = 0;
1365
- prev_event = *event;
1366
-
1367
- if (event->type == KeyRelease)
1368
- {
1369
- /* The keysym value was set by a previous call to this function
1370
- with a KeyPress event (or reset by the mouse event handler) */
1371
-
1372
- if (SP->return_key_modifiers &&
1373
- #ifndef PDC_XIM
1374
- keysym != compose_key &&
1375
- #endif
1376
- IsModifierKey(keysym))
1377
- {
1378
- switch (keysym) {
1379
- case XK_Shift_L:
1380
- key = KEY_SHIFT_L;
1381
- break;
1382
- case XK_Shift_R:
1383
- key = KEY_SHIFT_R;
1384
- break;
1385
- case XK_Control_L:
1386
- key = KEY_CONTROL_L;
1387
- break;
1388
- case XK_Control_R:
1389
- key = KEY_CONTROL_R;
1390
- break;
1391
- case XK_Alt_L:
1392
- key = KEY_ALT_L;
1393
- break;
1394
- case XK_Alt_R:
1395
- key = KEY_ALT_R;
1396
- }
1397
-
1398
- if (key)
1399
- _send_key_to_curses(key, NULL, TRUE);
1400
- }
1401
-
1402
- return;
1403
- }
1404
-
1405
- buffer[0] = '\0';
1406
-
1407
- #ifdef PDC_XIM
1408
- count = XwcLookupString(Xic, &(event->xkey), buffer, buflen,
1409
- &keysym, &status);
1410
- #else
1411
- count = XLookupString(&(event->xkey), (char *)buffer, buflen,
1412
- &keysym, &compose);
1413
- #endif
1414
-
1415
- /* translate keysym into curses key code */
1416
-
1417
- PDC_LOG(("%s:Key mask: %x\n", XCLOGMSG, event->xkey.state));
1418
-
1419
- #ifdef PDCDEBUG
1420
- for (i = 0; i < 4; i++)
1421
- PDC_debug("%s:Keysym %x %d\n", XCLOGMSG,
1422
- XKeycodeToKeysym(XCURSESDISPLAY, event->xkey.keycode, i), i);
1423
- #endif
1424
-
1425
- #ifndef PDC_XIM
1426
-
1427
- /* Check if the key just pressed is the user-specified compose
1428
- key; if it is, set the compose state and exit. */
1429
-
1430
- if (keysym == compose_key)
1431
- {
1432
- /* Change the shape of the cursor to an outline rectangle to
1433
- indicate we are in "compose" status */
1434
-
1435
- override_cursor = CURSOR_UNBLINKING_RECTANGLE;
1436
- compose_state = STATE_COMPOSE;
1437
- return;
1438
- }
1439
-
1440
- switch (compose_state)
1441
- {
1442
- case STATE_COMPOSE:
1443
- if (IsModifierKey(keysym))
1444
- return;
1445
-
1446
- if (event->xkey.state & compose_mask)
1447
- {
1448
- compose_state = STATE_NORMAL;
1449
- override_cursor = -1;
1450
- break;
1451
- }
1452
-
1453
- if (buffer[0] && count == 1)
1454
- key = buffer[0];
1455
-
1456
- compose_index = -1;
1457
-
1458
- for (i = 0; i < (int)strlen(compose_chars); i++)
1459
- if (compose_chars[i] == key)
1460
- {
1461
- compose_index = i;
1462
- break;
1463
- }
1464
-
1465
- if (compose_index == -1)
1466
- {
1467
- compose_state = STATE_NORMAL;
1468
- compose_index = 0;
1469
- override_cursor = -1;
1470
- break;
1471
- }
1472
-
1473
- compose_state = STATE_CHAR;
1474
- return;
1475
-
1476
- case STATE_CHAR:
1477
- if (IsModifierKey(keysym))
1478
- return;
1479
-
1480
- if (event->xkey.state & compose_mask)
1481
- {
1482
- compose_state = STATE_NORMAL;
1483
- override_cursor = -1;
1484
- break;
1485
- }
1486
-
1487
- if (buffer[0] && count == 1)
1488
- key = buffer[0];
1489
-
1490
- char_idx = -1;
1491
-
1492
- for (i = 0; i < MAX_COMPOSE_CHARS; i++)
1493
- if (compose_lookups[compose_index][i] == key)
1494
- {
1495
- char_idx = i;
1496
- break;
1497
- }
1498
-
1499
- if (char_idx == -1)
1500
- {
1501
- compose_state = STATE_NORMAL;
1502
- compose_index = 0;
1503
- override_cursor = -1;
1504
- break;
1505
- }
1506
-
1507
- _send_key_to_curses(compose_keys[compose_index][char_idx],
1508
- NULL, FALSE);
1509
-
1510
- compose_state = STATE_NORMAL;
1511
- compose_index = 0;
1512
- override_cursor = -1;
1513
-
1514
- return;
1515
- }
1516
-
1517
- #endif /* PDC_XIM */
1518
-
1519
- /* To get here we are procesing "normal" keys */
1520
-
1521
- PDC_LOG(("%s:Keysym %x %d\n", XCLOGMSG,
1522
- XKeycodeToKeysym(XCURSESDISPLAY, event->xkey.keycode, key), key));
1523
-
1524
- /* 0x10: usually, numlock modifier */
1525
-
1526
- if (event->xkey.state & Mod2Mask)
1527
- modifier |= PDC_KEY_MODIFIER_NUMLOCK;
1528
-
1529
- /* 0x01: shift modifier */
1530
-
1531
- if (event->xkey.state & ShiftMask)
1532
- modifier |= PDC_KEY_MODIFIER_SHIFT;
1533
-
1534
- /* 0x04: control modifier */
1535
-
1536
- if (event->xkey.state & ControlMask)
1537
- modifier |= PDC_KEY_MODIFIER_CONTROL;
1538
-
1539
- /* 0x08: usually, alt modifier */
1540
-
1541
- if (event->xkey.state & Mod1Mask)
1542
- modifier |= PDC_KEY_MODIFIER_ALT;
1543
-
1544
- if( repeat_count)
1545
- modifier |= PDC_KEY_MODIFIER_REPEAT;
1546
-
1547
- for (i = 0; key_table[i].keycode; i++)
1548
- {
1549
- if (key_table[i].keycode == keysym)
1550
- {
1551
- PDC_LOG(("%s:State %x\n", XCLOGMSG, event->xkey.state));
1552
-
1553
- /* ControlMask: 0x04: control modifier
1554
- Mod1Mask: 0x08: usually, alt modifier
1555
- Mod2Mask: 0x10: usually, numlock modifier
1556
- ShiftMask: 0x01: shift modifier */
1557
-
1558
- if ((event->xkey.state & ShiftMask) ||
1559
- (key_table[i].numkeypad &&
1560
- (event->xkey.state & Mod2Mask)))
1561
- {
1562
- key = key_table[i].shifted;
1563
- }
1564
- else if (event->xkey.state & ControlMask)
1565
- {
1566
- key = key_table[i].control;
1567
- }
1568
- else if (event->xkey.state & Mod1Mask)
1569
- {
1570
- key = key_table[i].alt;
1571
- }
1572
-
1573
- /* To get here, we ignore all other modifiers */
1574
-
1575
- else
1576
- key = key_table[i].normal;
1577
-
1578
- key_code = (key > 0x100);
1579
- break;
1580
- }
1581
- }
1582
-
1583
- if (!key && buffer[0] && count == 1)
1584
- key = buffer[0];
1585
-
1586
- PDC_LOG(("%s:Key: %s (%lx) pressed - %lx Mod: %x\n", XCLOGMSG,
1587
- XKeysymToString(keysym), keysym, key, event->xkey.state));
1588
-
1589
- /* Handle ALT letters and numbers */
1590
-
1591
- /* enable Alt key without numlock on */
1592
- if (event->xkey.state & Mod1Mask)
1593
- {
1594
- if (key >= 'A' && key <= 'Z')
1595
- {
1596
- key += ALT_A - 'A';
1597
- key_code = TRUE;
1598
- }
1599
-
1600
- if (key >= 'a' && key <= 'z')
1601
- {
1602
- key += ALT_A - 'a';
1603
- key_code = TRUE;
1604
- }
1605
-
1606
- if (key >= '0' && key <= '9')
1607
- {
1608
- key += ALT_0 - '0';
1609
- key_code = TRUE;
1610
- }
1611
- }
1612
-
1613
- /* After all that, send the key back to the application if is
1614
- NOT zero. */
1615
-
1616
- if (key)
1617
- {
1618
- static long unicode_value = -1L;
1619
-
1620
- if( key == 21 && modifier == /* Ctrl-Shift-U hit: Unicode entry */
1621
- (PDC_KEY_MODIFIER_SHIFT | PDC_KEY_MODIFIER_CONTROL))
1622
- unicode_value = 0L;
1623
- if( unicode_value >= 0L)
1624
- {
1625
- int offset = 0;
1626
-
1627
- override_cursor = CURSOR_UNBLINKING_RECTANGLE;
1628
- if( key >= '0' && key <= '9')
1629
- offset = '0';
1630
- if( key >= 'a' && key <= 'f')
1631
- offset = 'a' - 10;
1632
- if( key >= 'A' && key <= 'F')
1633
- offset = 'A' - 10;
1634
- if( offset)
1635
- {
1636
- unicode_value <<= 4;
1637
- unicode_value |= (long)( key - offset);
1638
- }
1639
- if( key == 13 || key == PADENTER)
1640
- {
1641
- key = unicode_value;
1642
- unicode_value = -1L;
1643
- modifier = 0;
1644
- key_code = FALSE;
1645
- override_cursor = -1;
1646
- }
1647
- else /* still in unicode entry mode */
1648
- return;
1649
- }
1650
-
1651
- if (SP->save_key_modifiers)
1652
- key |= (modifier << 24);
1653
-
1654
- _send_key_to_curses(key, NULL, key_code);
1655
- }
1656
- }
1657
-
1658
- static void XCursesHandleString(Widget w, XEvent *event, String *params,
1659
- Cardinal *nparams)
1660
- {
1661
- unsigned char *ptr;
1662
-
1663
- if (*nparams != 1)
1664
- return;
1665
-
1666
- ptr = (unsigned char *)*params;
1667
-
1668
- if (ptr[0] == '0' && ptr[1] == 'x' && ptr[2] != '\0')
1669
- {
1670
- unsigned char c;
1671
- unsigned long total = 0;
1672
-
1673
- for (ptr += 2; (c = tolower(*ptr)); ptr++)
1674
- {
1675
- total <<= 4;
1676
-
1677
- if (c >= '0' && c <= '9')
1678
- total += c - '0';
1679
- else
1680
- if (c >= 'a' && c <= 'f')
1681
- total += c - ('a' - 10);
1682
- else
1683
- break;
1684
- }
1685
-
1686
- if (c == '\0')
1687
- _send_key_to_curses(total, NULL, FALSE);
1688
- }
1689
- else
1690
- for (; *ptr; ptr++)
1691
- _send_key_to_curses((unsigned long)*ptr, NULL, FALSE);
1692
- }
1693
-
1694
- static void _paste_string(Widget w, XtPointer data, Atom *selection, Atom *type,
1695
- XtPointer value, unsigned long *length, int *format)
1696
- {
1697
- unsigned long i, key;
1698
- unsigned char *string = value;
1699
-
1700
- XC_LOG(("_paste_string() - called\n"));
1701
-
1702
- if (!*type || !*length || !string)
1703
- return;
1704
-
1705
- for (i = 0; string[i] && (i < (*length)); i++)
1706
- {
1707
- key = string[i];
1708
-
1709
- if (key == 10) /* new line - convert to ^M */
1710
- key = 13;
1711
-
1712
- _send_key_to_curses(key, NULL, FALSE);
1713
- }
1714
-
1715
- XtFree(value);
1716
- }
1717
-
1718
- static void _paste_utf8(Widget w, XtPointer event, Atom *selection, Atom *type,
1719
- XtPointer value, unsigned long *length, int *format)
1720
- {
1721
- wchar_t key;
1722
- size_t i = 0, len;
1723
- char *string = value;
1724
-
1725
- XC_LOG(("_paste_utf8() - called\n"));
1726
-
1727
- if (!*type || !*length)
1728
- {
1729
- XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, _paste_string,
1730
- event, ((XButtonEvent *)event)->time);
1731
- return;
1732
- }
1733
-
1734
- len = *length;
1735
-
1736
- if (!string)
1737
- return;
1738
-
1739
- while (string[i] && (i < len))
1740
- {
1741
- int retval = _from_utf8(&key, string + i, len - i);
1742
-
1743
- if (retval < 1)
1744
- return;
1745
-
1746
- if (key == 10) /* new line - convert to ^M */
1747
- key = 13;
1748
-
1749
- _send_key_to_curses(key, NULL, FALSE);
1750
-
1751
- i += retval;
1752
- }
1753
-
1754
- XtFree(value);
1755
- }
1756
-
1757
- static void XCursesPasteSelection(Widget w, XButtonEvent *button_event)
1758
- {
1759
- XC_LOG(("XCursesPasteSelection() - called\n"));
1760
-
1761
- XtGetSelectionValue(w, XA_PRIMARY, XA_UTF8_STRING(XtDisplay(w)),
1762
- _paste_utf8, (XtPointer)button_event,
1763
- button_event->time);
1764
- }
1765
-
1766
- static Boolean _convert_proc(Widget w, Atom *selection, Atom *target,
1767
- Atom *type_return, XtPointer *value_return,
1768
- unsigned long *length_return, int *format_return)
1769
- {
1770
- XC_LOG(("_convert_proc() - called\n"));
1771
-
1772
- if (*target == XA_TARGETS(XtDisplay(topLevel)))
1773
- {
1774
- XSelectionRequestEvent *req = XtGetSelectionRequest(w,
1775
- *selection, (XtRequestId)NULL);
1776
-
1777
- Atom *targetP;
1778
- XPointer std_targets;
1779
- unsigned long std_length;
1780
-
1781
- XmuConvertStandardSelection(topLevel, req->time, selection,
1782
- target, type_return, &std_targets,
1783
- &std_length, format_return);
1784
-
1785
- *length_return = std_length + 2;
1786
- *value_return = XtMalloc(sizeof(Atom) * (*length_return));
1787
-
1788
- targetP = *(Atom**)value_return;
1789
- *targetP++ = XA_STRING;
1790
- *targetP++ = XA_UTF8_STRING(XtDisplay(topLevel));
1791
-
1792
- memmove((void *)targetP, (const void *)std_targets,
1793
- sizeof(Atom) * std_length);
1794
-
1795
- XtFree((char *)std_targets);
1796
- *type_return = XA_ATOM;
1797
- *format_return = sizeof(Atom) * 8;
1798
-
1799
- return True;
1800
- }
1801
- else if (*target == XA_UTF8_STRING(XtDisplay(topLevel)) ||
1802
- *target == XA_STRING)
1803
- {
1804
- bool utf8 = !(*target == XA_STRING);
1805
- char *data = XtMalloc(tmpsel_length * 3 + 1);
1806
- chtype *tmp = tmpsel;
1807
- int ret_length = 0;
1808
-
1809
- if (utf8)
1810
- {
1811
- while (*tmp)
1812
- ret_length += _to_utf8(data + ret_length, *tmp++);
1813
- }
1814
- else
1815
- while (*tmp)
1816
- data[ret_length++] = *tmp++ & 0xff;
1817
-
1818
- data[ret_length++] = '\0';
1819
-
1820
- *value_return = data;
1821
- *length_return = ret_length;
1822
- *format_return = 8;
1823
- *type_return = *target;
1824
-
1825
- return True;
1826
- }
1827
- else
1828
- {
1829
- return XmuConvertStandardSelection(topLevel, CurrentTime,
1830
- selection, target, type_return, (XPointer*)value_return,
1831
- length_return, format_return);
1832
- }
1833
- }
1834
-
1835
- static void _lose_ownership(Widget w, Atom *type)
1836
- {
1837
- XC_LOG(("_lose_ownership() - called\n"));
1838
-
1839
- if (tmpsel)
1840
- free(tmpsel);
1841
-
1842
- tmpsel = NULL;
1843
- tmpsel_length = 0;
1844
- _selection_off();
1845
- }
1846
-
1847
- static void _show_selection(int start_x, int start_y, int end_x, int end_y,
1848
- bool highlight)
1849
- {
1850
- int i, num_cols, start_col, row;
1851
-
1852
- PDC_LOG(("%s:_show_selection() - called StartX: %d StartY: %d "
1853
- "EndX: %d EndY: %d Highlight: %d\n", XCLOGMSG,
1854
- start_x, start_y, end_x, end_y, highlight));
1855
-
1856
- for (i = 0; i < end_y - start_y + 1; i++)
1857
- {
1858
- if (start_y == end_y) /* only one line */
1859
- {
1860
- start_col = start_x;
1861
- num_cols = end_x - start_x + 1;
1862
- row = start_y;
1863
- }
1864
- else if (!i) /* first line */
1865
- {
1866
- start_col = start_x;
1867
- num_cols = COLS - start_x;
1868
- row = start_y;
1869
- }
1870
- else if (start_y + i == end_y) /* last line */
1871
- {
1872
- start_col = 0;
1873
- num_cols = end_x + 1;
1874
- row = end_y;
1875
- }
1876
- else /* full line */
1877
- {
1878
- start_col = 0;
1879
- num_cols = COLS;
1880
- row = start_y + i;
1881
- }
1882
-
1883
- XC_get_line_lock(row);
1884
-
1885
- _display_text((const chtype *)(Xcurscr + XCURSCR_Y_OFF(row) +
1886
- (start_col * sizeof(chtype))), row, start_col,
1887
- num_cols, highlight);
1888
-
1889
- XC_release_line_lock(row);
1890
- }
1891
- }
1892
-
1893
- static void _selection_off(void)
1894
- {
1895
- XC_LOG(("_selection_off() - called\n"));
1896
-
1897
- if( mouse_selection)
1898
- {
1899
- _display_screen();
1900
-
1901
- selection_start_x = selection_start_y = selection_end_x =
1902
- selection_end_y = 0;
1903
-
1904
- mouse_selection = FALSE;
1905
- }
1906
- }
1907
-
1908
- static void _selection_on(int x, int y)
1909
- {
1910
- XC_LOG(("_selection_on() - called\n"));
1911
-
1912
- selection_start_x = selection_end_x = x;
1913
- selection_start_y = selection_end_y = y;
1914
- }
1915
-
1916
- static void _selection_extend(int x, int y)
1917
- {
1918
- int temp, current_start, current_end, current_start_x,
1919
- current_end_x, current_start_y, current_end_y, new_start,
1920
- new_end, new_start_x, new_end_x, new_start_y, new_end_y;
1921
-
1922
- XC_LOG(("_selection_extend() - called\n"));
1923
-
1924
- mouse_selection = TRUE;
1925
-
1926
- /* convert x/y coordinates into start/stop */
1927
-
1928
- current_start = (selection_start_y * COLS) + selection_start_x;
1929
- current_end = (selection_end_y * COLS) + selection_end_x;
1930
-
1931
- if (current_start > current_end)
1932
- {
1933
- current_start_x = selection_end_x;
1934
- current_start_y = selection_end_y;
1935
- current_end_x = selection_start_x;
1936
- current_end_y = selection_start_y;
1937
- temp = current_start;
1938
- current_start = current_end;
1939
- current_end = temp;
1940
- }
1941
- else
1942
- {
1943
- current_end_x = selection_end_x;
1944
- current_end_y = selection_end_y;
1945
- current_start_x = selection_start_x;
1946
- current_start_y = selection_start_y;
1947
- }
1948
-
1949
- /* Now we have the current selection as a linear expression.
1950
- Convert the new position to a linear expression. */
1951
-
1952
- selection_end_x = x;
1953
- selection_end_y = y;
1954
-
1955
- /* convert x/y coordinates into start/stop */
1956
-
1957
- new_start = (selection_start_y * COLS) + selection_start_x;
1958
- new_end = (selection_end_y * COLS) + selection_end_x;
1959
-
1960
- if (new_start > new_end)
1961
- {
1962
- new_start_x = selection_end_x;
1963
- new_start_y = selection_end_y;
1964
- new_end_x = selection_start_x;
1965
- new_end_y = selection_start_y;
1966
- temp = new_start;
1967
- new_start = new_end;
1968
- new_end = temp;
1969
- }
1970
- else
1971
- {
1972
- new_end_x = selection_end_x;
1973
- new_end_y = selection_end_y;
1974
- new_start_x = selection_start_x;
1975
- new_start_y = selection_start_y;
1976
- }
1977
-
1978
- if (new_end > current_end)
1979
- _show_selection(current_end_x, current_end_y, new_end_x,
1980
- new_end_y, TRUE);
1981
- else if (new_end < current_end)
1982
- _show_selection(new_end_x, new_end_y, current_end_x,
1983
- current_end_y, FALSE);
1984
- else if (new_start < current_start)
1985
- _show_selection(new_start_x, new_start_y, current_start_x,
1986
- current_start_y, TRUE);
1987
- else if (new_start > current_start)
1988
- _show_selection(current_start_x, current_start_y,
1989
- new_start_x, new_start_y, FALSE);
1990
- else
1991
- _show_selection(current_start_x, current_start_y,
1992
- new_start_x, new_start_y, TRUE);
1993
- }
1994
-
1995
- static void _selection_set(void)
1996
- {
1997
- int i, j, start, end, start_x, end_x, start_y, end_y, num_cols,
1998
- start_col, row, num_chars, ch, last_nonblank, length, newlen;
1999
- chtype *ptr = NULL;
2000
-
2001
- XC_LOG(("_selection_set() - called\n"));
2002
-
2003
- /* convert x/y coordinates into start/stop */
2004
-
2005
- start = (selection_start_y * COLS) + selection_start_x;
2006
- end = (selection_end_y * COLS) + selection_end_x;
2007
-
2008
- if (start == end)
2009
- {
2010
- if (tmpsel)
2011
- free(tmpsel);
2012
-
2013
- tmpsel = NULL;
2014
- tmpsel_length = 0;
2015
-
2016
- return;
2017
- }
2018
-
2019
- if (start > end)
2020
- {
2021
- start_x = selection_end_x;
2022
- start_y = selection_end_y;
2023
- end_x = selection_start_x;
2024
- end_y = selection_start_y;
2025
- length = start - end + 1;
2026
- }
2027
- else
2028
- {
2029
- end_x = selection_end_x;
2030
- end_y = selection_end_y;
2031
- start_x = selection_start_x;
2032
- start_y = selection_start_y;
2033
- length = end - start + 1;
2034
- }
2035
-
2036
- newlen = length + end_y - start_y + 2;
2037
-
2038
- if (length > (int)tmpsel_length)
2039
- {
2040
- if (!tmpsel_length)
2041
- tmpsel = malloc(newlen * sizeof(chtype));
2042
- else
2043
- tmpsel = realloc(tmpsel, newlen * sizeof(chtype));
2044
- }
2045
-
2046
- if (!tmpsel)
2047
- {
2048
- tmpsel_length = 0;
2049
- return;
2050
- }
2051
-
2052
- tmpsel_length = length;
2053
- num_chars = 0;
2054
-
2055
- for (i = 0; i < end_y - start_y + 1; i++)
2056
- {
2057
-
2058
- if (start_y == end_y) /* only one line */
2059
- {
2060
- start_col = start_x;
2061
- num_cols = end_x - start_x + 1;
2062
- row = start_y;
2063
- }
2064
- else if (!i) /* first line */
2065
- {
2066
- start_col = start_x;
2067
- num_cols = COLS - start_x;
2068
- row = start_y;
2069
- }
2070
- else if (start_y + i == end_y) /* last line */
2071
- {
2072
- start_col = 0;
2073
- num_cols = end_x + 1;
2074
- row = end_y;
2075
- }
2076
- else /* full line */
2077
- {
2078
- start_col = 0;
2079
- num_cols = COLS;
2080
- row = start_y + i;
2081
- }
2082
-
2083
- XC_get_line_lock(row);
2084
-
2085
- ptr = (chtype *)(Xcurscr + XCURSCR_Y_OFF(row) +
2086
- start_col * sizeof(chtype));
2087
-
2088
- if (i < end_y - start_y)
2089
- {
2090
- last_nonblank = 0;
2091
-
2092
- for (j = 0; j < num_cols; j++)
2093
- {
2094
- ch = (int)(ptr[j] & A_CHARTEXT);
2095
- if (ch != (int)' ')
2096
- last_nonblank = j;
2097
- }
2098
- }
2099
- else
2100
- last_nonblank = num_cols - 1;
2101
-
2102
- for (j = 0; j <= last_nonblank; j++)
2103
- tmpsel[num_chars++] = ptr[j];
2104
-
2105
- XC_release_line_lock(row);
2106
-
2107
- if (i < end_y - start_y)
2108
- tmpsel[num_chars++] = '\n';
2109
- }
2110
-
2111
- tmpsel[num_chars] = '\0';
2112
- tmpsel_length = num_chars;
2113
- }
2114
-
2115
- #define CURSOR_INVISIBLE 0
2116
- #define CURSOR_NORMAL 1
2117
- #define CURSOR_BLOCK 2
2118
- #define CURSOR_RECTANGLE 3
2119
- #define CURSOR_VLINE 4
2120
- #define CURSOR_HALF_BLOCK 5
2121
-
2122
- static void _display_cursor(int old_row, int old_x, int new_row, int new_x)
2123
- {
2124
- int xpos, ypos, i, cursor_to_show;
2125
- chtype *ch;
2126
- short fore = 0, back = 0;
2127
-
2128
- PDC_LOG(("%s:_display_cursor() - draw char at row: %d col %d\n",
2129
- XCLOGMSG, old_row, old_x));
2130
-
2131
- /* if the cursor position is outside the boundary of the screen,
2132
- ignore the request */
2133
-
2134
- if (old_row >= XCursesLINES || old_x >= COLS ||
2135
- new_row >= XCursesLINES || new_x >= COLS)
2136
- return;
2137
-
2138
- /* display the character at the current cursor position */
2139
- PDC_LOG(("%s:_display_cursor() - draw char at row: %d col %d\n",
2140
- XCLOGMSG, old_row, old_x));
2141
-
2142
- _display_text((const chtype *)(Xcurscr + (XCURSCR_Y_OFF(old_row) +
2143
- (old_x * sizeof(chtype)))), old_row, old_x, 1, FALSE);
2144
-
2145
- /* display the cursor at the new cursor position */
2146
-
2147
- /* use lower 8 bits for 1/2 cycle (or if not in window) */
2148
- if( PDC_blink_state || !window_entered)
2149
- cursor_to_show = (SP->visibility & 0xff);
2150
- else /* ...& upper 8 bits on other 1/2 cycle */
2151
- cursor_to_show = (SP->visibility >> 8);
2152
- if( override_cursor >= 0)
2153
- cursor_to_show = (PDC_blink_state ? override_cursor & 0xff
2154
- : override_cursor >> 8);
2155
- if( !cursor_to_show)
2156
- return; /* cursor not displayed, no more to do */
2157
-
2158
- _make_xy(new_x, new_row, &xpos, &ypos);
2159
-
2160
- ch = (chtype *)(Xcurscr + XCURSCR_Y_OFF(new_row) + new_x * sizeof(chtype));
2161
-
2162
- _set_cursor_color(ch, &fore, &back);
2163
- XSetForeground(XCURSESDISPLAY, rect_cursor_gc, colors[back]);
2164
-
2165
- switch( cursor_to_show)
2166
- {
2167
- case CURSOR_VLINE:
2168
- for (i = 1; i <= 2; i++)
2169
- XDrawLine(XCURSESDISPLAY, XCURSESWIN, rect_cursor_gc,
2170
- xpos + i, ypos - xc_app_data.normalFont->ascent,
2171
- xpos + i, ypos - xc_app_data.normalFont->ascent +
2172
- font_height - 1);
2173
- break;
2174
- case CURSOR_NORMAL:
2175
- case CURSOR_HALF_BLOCK:
2176
- {
2177
- int n_lines = xc_app_data.normalFont->descent;
2178
-
2179
- ypos += n_lines - 1;
2180
- if( cursor_to_show == CURSOR_HALF_BLOCK)
2181
- n_lines += xc_app_data.normalFont->ascent / 2;
2182
- else
2183
- n_lines += 2;
2184
- for( i = 0; i < n_lines; i++, ypos--)
2185
- XDrawLine(XCURSESDISPLAY, XCURSESWIN, rect_cursor_gc,
2186
- xpos, ypos, xpos + font_width, ypos);
2187
- break;
2188
- }
2189
- case CURSOR_RECTANGLE:
2190
- XDrawRectangle(XCURSESDISPLAY, XCURSESWIN, rect_cursor_gc,
2191
- xpos + 1, ypos - font_height +
2192
- xc_app_data.normalFont->descent + 1,
2193
- font_width - 2, font_height - 2);
2194
- break;
2195
- case CURSOR_BLOCK:
2196
- default:
2197
- {
2198
- /* cursor visibility high */
2199
- #ifdef PDC_WIDE
2200
- XChar2b buf[2];
2201
-
2202
- buf[0].byte1 = (*ch & 0xff00) >> 8;
2203
- buf[0].byte2 = *ch & 0x00ff;
2204
-
2205
- buf[1].byte1 = buf[1].byte2 = 0;
2206
- #else
2207
- char buf[2];
2208
-
2209
- buf[0] = *ch & 0xff;
2210
- buf[1] = '\0';
2211
- #endif
2212
- XSetForeground(XCURSESDISPLAY, block_cursor_gc, colors[fore]);
2213
- XSetBackground(XCURSESDISPLAY, block_cursor_gc, colors[back]);
2214
- #ifdef PDC_WIDE
2215
- XDrawImageString16(
2216
- #else
2217
- XDrawImageString(
2218
- #endif
2219
- XCURSESDISPLAY, XCURSESWIN, block_cursor_gc,
2220
- xpos, ypos, buf, 1);
2221
- }
2222
- break;
2223
- }
2224
-
2225
- PDC_LOG(("%s:_display_cursor() - draw cursor at row %d col %d\n",
2226
- XCLOGMSG, new_row, new_x));
2227
- }
2228
-
2229
- static void _redraw_cursor(void)
2230
- {
2231
- _display_cursor(SP->cursrow, SP->curscol, SP->cursrow, SP->curscol);
2232
- }
2233
-
2234
- static void _handle_enter_leave(Widget w, XtPointer client_data,
2235
- XEvent *event, Boolean *unused)
2236
- {
2237
- XC_LOG(("_handle_enter_leave called\n"));
2238
-
2239
- switch(event->type)
2240
- {
2241
- case EnterNotify:
2242
- XC_LOG(("EnterNotify received\n"));
2243
-
2244
- window_entered = TRUE;
2245
- break;
2246
-
2247
- case LeaveNotify:
2248
- XC_LOG(("LeaveNotify received\n"));
2249
-
2250
- window_entered = FALSE;
2251
-
2252
- /* Display the cursor so it stays on while the window is
2253
- not current */
2254
-
2255
- // _redraw_cursor();
2256
- break;
2257
-
2258
- default:
2259
- PDC_LOG(("%s:_handle_enter_leave - unknown event %d\n",
2260
- XCLOGMSG, event->type));
2261
- }
2262
- }
2263
-
2264
- static void _send_key_to_curses(unsigned long key, MOUSE_STATUS *ms,
2265
- bool key_code)
2266
- {
2267
- PDC_LOG(("%s:_send_key_to_curses() - called: sending %d\n",
2268
- XCLOGMSG, key));
2269
-
2270
- SP->key_code = key_code;
2271
-
2272
- if (XC_write_socket(xc_key_sock, &key, sizeof(unsigned long)) < 0)
2273
- _exit_process(1, SIGKILL, "exiting from _send_key_to_curses");
2274
-
2275
- if (ms)
2276
- {
2277
- MOUSE_LOG(("%s:writing mouse stuff\n", XCLOGMSG));
2278
-
2279
- if (XC_write_socket(xc_key_sock, ms, sizeof(MOUSE_STATUS)) < 0)
2280
- _exit_process(1, SIGKILL, "exiting from _send_key_to_curses");
2281
- }
2282
- }
2283
-
2284
- #ifdef A_OVERLINE
2285
- #define A_ALL_LINES (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE | A_OVERLINE | A_STRIKEOUT)
2286
- #else
2287
- #define A_ALL_LINES (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE)
2288
- #endif
2289
-
2290
- /* Note that the logic used to avoid unnecessary drawing is heavily
2291
- borrowed from the HandleTimer function in wingui/pdcscrn.c. The
2292
- comments there may be helpful. */
2293
-
2294
- static void _blink_cursor(XtPointer unused, XtIntervalId *id)
2295
- {
2296
- XC_LOG(("_blink_cursor() - called:\n"));
2297
-
2298
- int i;
2299
- static int previously_really_blinking = 0;
2300
- static int prev_line_color = -1;
2301
- chtype attr_to_seek = 0;
2302
-
2303
- if( prev_line_color != SP->line_color)
2304
- attr_to_seek = A_ALL_LINES;
2305
- if( PDC_really_blinking || previously_really_blinking)
2306
- attr_to_seek |= A_BLINK;
2307
- prev_line_color = SP->line_color;
2308
- previously_really_blinking = PDC_really_blinking;
2309
- PDC_blink_state ^= 1;
2310
- if( attr_to_seek)
2311
- for( i = 0; i < SP->lines; i++)
2312
- {
2313
- const chtype *line;
2314
- int j = 0, n_chars;
2315
-
2316
- XC_get_line_lock( i);
2317
- line = (const chtype *)(Xcurscr + XCURSCR_Y_OFF( i));
2318
-
2319
- /* skip over starting text that isn't blinking: */
2320
- while( j < SP->cols && !(*line & attr_to_seek))
2321
- {
2322
- j++;
2323
- line++;
2324
- }
2325
- n_chars = SP->cols - j;
2326
- /* then skip over text at the end that's not blinking: */
2327
- while( n_chars && !(line[n_chars - 1] & attr_to_seek))
2328
- n_chars--;
2329
- if( n_chars)
2330
- _display_text( line, i, j, n_chars, 0);
2331
- XC_release_line_lock( i);
2332
- }
2333
-
2334
- _redraw_cursor();
2335
-
2336
- XtAppAddTimeOut(app_context, CURSOR_BLINK_RATE,
2337
- _blink_cursor, NULL);
2338
- }
2339
-
2340
- static void XCursesButton(Widget w, XEvent *event, String *params,
2341
- Cardinal *nparams)
2342
- {
2343
- int button_no;
2344
- static int last_button_no = 0;
2345
- static Time last_button_press_time = 0;
2346
- MOUSE_STATUS save_mouse_status;
2347
- bool send_key = TRUE;
2348
- static bool remove_release;
2349
- static bool handle_real_release;
2350
-
2351
- XC_LOG(("XCursesButton() - called\n"));
2352
-
2353
- keysym = 0; /* suppress any modifier key return */
2354
-
2355
- save_mouse_status = Mouse_status;
2356
- button_no = event->xbutton.button;
2357
-
2358
- /* It appears that under X11R6 (at least on Linux), that an
2359
- event_type of ButtonMotion does not include the mouse button in
2360
- the event. The following code is designed to cater for this
2361
- situation. */
2362
-
2363
- if (!button_no)
2364
- button_no = last_button_no;
2365
-
2366
- last_button_no = button_no;
2367
-
2368
- Mouse_status.changes = 0;
2369
-
2370
- switch(event->type)
2371
- {
2372
- case ButtonPress:
2373
- /* Handle button 4 and 5, which are normally mapped to the wheel
2374
- mouse scroll up and down, and button 6 and 7, which are
2375
- normally mapped to the wheel mouse scroll left and right */
2376
-
2377
- if (button_no >= 4 && button_no <= 7)
2378
- {
2379
- /* Send the KEY_MOUSE to curses program */
2380
-
2381
- memset(&Mouse_status, 0, sizeof(Mouse_status));
2382
-
2383
- switch(button_no)
2384
- {
2385
- case 4:
2386
- Mouse_status.changes = PDC_MOUSE_WHEEL_UP;
2387
- break;
2388
- case 5:
2389
- Mouse_status.changes = PDC_MOUSE_WHEEL_DOWN;
2390
- break;
2391
- case 6:
2392
- Mouse_status.changes = PDC_MOUSE_WHEEL_LEFT;
2393
- break;
2394
- case 7:
2395
- Mouse_status.changes = PDC_MOUSE_WHEEL_RIGHT;
2396
- }
2397
-
2398
- MOUSE_X_POS = MOUSE_Y_POS = -1;
2399
- _send_key_to_curses(KEY_MOUSE, &Mouse_status, TRUE);
2400
- remove_release = TRUE;
2401
-
2402
- return;
2403
- }
2404
-
2405
- if (button_no == 2 &&
2406
- (!SP->_trap_mbe || (event->xbutton.state & ShiftMask)))
2407
- {
2408
- XCursesPasteSelection(drawing, (XButtonEvent *)event);
2409
- remove_release = TRUE;
2410
-
2411
- return;
2412
- }
2413
-
2414
- remove_release = False;
2415
- handle_real_release = False;
2416
-
2417
- MOUSE_LOG(("\nButtonPress\n"));
2418
-
2419
- if ((event->xbutton.time - last_button_press_time) <
2420
- xc_app_data.doubleClickPeriod)
2421
- {
2422
- const short curr_status = BUTTON_STATUS( button_no);
2423
-
2424
- MOUSE_X_POS = save_mouse_status.x;
2425
- MOUSE_Y_POS = save_mouse_status.y;
2426
- if( curr_status == BUTTON_DOUBLE_CLICKED
2427
- || curr_status == BUTTON_TRIPLE_CLICKED)
2428
- BUTTON_STATUS(button_no) = BUTTON_TRIPLE_CLICKED;
2429
- else
2430
- BUTTON_STATUS(button_no) = BUTTON_DOUBLE_CLICKED;
2431
-
2432
- _selection_off();
2433
- remove_release = True;
2434
- }
2435
- else
2436
- {
2437
- napms(SP->mouse_wait);
2438
- event->type = ButtonRelease;
2439
- XSendEvent(event->xbutton.display, event->xbutton.window,
2440
- True, 0, event);
2441
- last_button_press_time = event->xbutton.time;
2442
-
2443
- return;
2444
- }
2445
-
2446
- last_button_press_time = event->xbutton.time;
2447
- break;
2448
-
2449
- case MotionNotify:
2450
- MOUSE_LOG(("\nMotionNotify: y: %d x: %d Width: %d "
2451
- "Height: %d\n", event->xbutton.y, event->xbutton.x,
2452
- font_width, font_height));
2453
-
2454
- MOUSE_X_POS = (event->xbutton.x - xc_app_data.borderWidth) /
2455
- font_width;
2456
- MOUSE_Y_POS = (event->xbutton.y - xc_app_data.borderWidth) /
2457
- font_height;
2458
-
2459
- if (button_no == 1 &&
2460
- (!SP->_trap_mbe || (event->xbutton.state & ShiftMask)))
2461
- {
2462
- _selection_extend(MOUSE_X_POS, MOUSE_Y_POS);
2463
- send_key = FALSE;
2464
- }
2465
- else
2466
- _selection_off();
2467
-
2468
- /* Throw away mouse movements if they are in the same character
2469
- position as the last mouse event, or if we are currently in
2470
- the middle of a double click event. */
2471
-
2472
- if ((MOUSE_X_POS == save_mouse_status.x &&
2473
- MOUSE_Y_POS == save_mouse_status.y) ||
2474
- save_mouse_status.button[button_no - 1] == BUTTON_DOUBLE_CLICKED)
2475
- {
2476
- send_key = FALSE;
2477
- break;
2478
- }
2479
-
2480
- Mouse_status.changes |= PDC_MOUSE_MOVED;
2481
- break;
2482
-
2483
- case ButtonRelease:
2484
- if (remove_release)
2485
- {
2486
- MOUSE_LOG(("Release at: %ld - removed\n", event->xbutton.time));
2487
- return;
2488
- }
2489
- else
2490
- {
2491
- MOUSE_X_POS = (event->xbutton.x - xc_app_data.borderWidth) /
2492
- font_width;
2493
- MOUSE_Y_POS = (event->xbutton.y - xc_app_data.borderWidth) /
2494
- font_height;
2495
-
2496
- if (!handle_real_release)
2497
- {
2498
- if ((event->xbutton.time - last_button_press_time) <
2499
- SP->mouse_wait &&
2500
- (event->xbutton.time != last_button_press_time))
2501
- {
2502
- /* The "real" release was shorter than usleep() time;
2503
- therefore generate a click event */
2504
-
2505
- MOUSE_LOG(("Release at: %ld - click\n",
2506
- event->xbutton.time));
2507
-
2508
- BUTTON_STATUS(button_no) = BUTTON_CLICKED;
2509
-
2510
- if (button_no == 1 && mouse_selection &&
2511
- (!SP->_trap_mbe || (event->xbutton.state & ShiftMask)))
2512
- {
2513
- send_key = FALSE;
2514
-
2515
- if (XtOwnSelection(topLevel, XA_PRIMARY,
2516
- event->xbutton.time, _convert_proc,
2517
- _lose_ownership, NULL) == False)
2518
- _selection_off();
2519
- }
2520
- else
2521
- _selection_off();
2522
-
2523
- /* Ensure the "pseudo" release event is ignored */
2524
-
2525
- remove_release = True;
2526
- handle_real_release = False;
2527
- break;
2528
- }
2529
- else
2530
- {
2531
- /* Button release longer than usleep() time;
2532
- therefore generate a press and wait for the real
2533
- release to occur later. */
2534
-
2535
- MOUSE_LOG(("Generated Release at: %ld - "
2536
- "press & release\n", event->xbutton.time));
2537
-
2538
- BUTTON_STATUS(button_no) = BUTTON_PRESSED;
2539
-
2540
- if (button_no == 1 &&
2541
- (!SP->_trap_mbe || (event->xbutton.state & ShiftMask)))
2542
- {
2543
- _selection_off();
2544
- _selection_on(MOUSE_X_POS, MOUSE_Y_POS);
2545
- }
2546
-
2547
- handle_real_release = True;
2548
- break;
2549
- }
2550
- }
2551
- else
2552
- {
2553
- MOUSE_LOG(("Release at: %ld - released\n",
2554
- event->xbutton.time));
2555
- }
2556
- }
2557
-
2558
- MOUSE_LOG(("\nButtonRelease\n"));
2559
-
2560
- BUTTON_STATUS(button_no) = BUTTON_RELEASED;
2561
-
2562
- if (button_no == 1 && mouse_selection &&
2563
- (!SP->_trap_mbe || (event->xbutton.state & ShiftMask)))
2564
- {
2565
- send_key = FALSE;
2566
-
2567
- if (XtOwnSelection(topLevel, XA_PRIMARY,
2568
- event->xbutton.time, _convert_proc,
2569
- _lose_ownership, NULL) == False)
2570
- _selection_off();
2571
-
2572
- _selection_set();
2573
- }
2574
- else
2575
- _selection_off();
2576
-
2577
- break;
2578
- }
2579
-
2580
- /* Set up the mouse status fields in preparation for sending */
2581
-
2582
- Mouse_status.changes |= 1 << (button_no - 1);
2583
-
2584
- if (Mouse_status.changes & PDC_MOUSE_MOVED &&
2585
- BUTTON_STATUS(button_no) == BUTTON_PRESSED)
2586
- BUTTON_STATUS(button_no) = BUTTON_MOVED;
2587
-
2588
- if (event->xbutton.state & ShiftMask)
2589
- BUTTON_STATUS(button_no) |= BUTTON_SHIFT;
2590
- if (event->xbutton.state & ControlMask)
2591
- BUTTON_STATUS(button_no) |= BUTTON_CONTROL;
2592
- if (event->xbutton.state & Mod1Mask)
2593
- BUTTON_STATUS(button_no) |= BUTTON_ALT;
2594
-
2595
- /* If we are ignoring the event, or the mouse position is outside
2596
- the bounds of the screen (because of the border), return here */
2597
-
2598
- MOUSE_LOG(("Button: %d x: %d y: %d Button status: %x "
2599
- "Mouse status: %x\n", button_no, MOUSE_X_POS, MOUSE_Y_POS,
2600
- BUTTON_STATUS(button_no), Mouse_status.changes));
2601
-
2602
- MOUSE_LOG(("Send: %d Button1: %x Button2: %x Button3: %x %d %d\n",
2603
- send_key, BUTTON_STATUS(1), BUTTON_STATUS(2),
2604
- BUTTON_STATUS(3), XCursesLINES, XCursesCOLS));
2605
-
2606
- if (!send_key || MOUSE_X_POS < 0 || MOUSE_X_POS >= XCursesCOLS ||
2607
- MOUSE_Y_POS < 0 || MOUSE_Y_POS >= XCursesLINES)
2608
- return;
2609
-
2610
- /* Send the KEY_MOUSE to curses program */
2611
-
2612
- _send_key_to_curses(KEY_MOUSE, &Mouse_status, TRUE);
2613
- }
2614
-
2615
- static void _scroll_up_down(Widget w, XtPointer client_data,
2616
- XtPointer call_data)
2617
- {
2618
- int pixels = (long) call_data;
2619
- int total_y = SP->sb_total_y * font_height;
2620
- int viewport_y = SP->sb_viewport_y * font_height;
2621
- int cur_y = SP->sb_cur_y * font_height;
2622
-
2623
- /* When pixels is negative, right button pressed, move data down,
2624
- thumb moves up. Otherwise, left button pressed, pixels positive,
2625
- move data up, thumb down. */
2626
-
2627
- cur_y += pixels;
2628
-
2629
- /* limit panning to size of overall */
2630
-
2631
- if (cur_y < 0)
2632
- cur_y = 0;
2633
- else
2634
- if (cur_y > (total_y - viewport_y))
2635
- cur_y = total_y - viewport_y;
2636
-
2637
- SP->sb_cur_y = cur_y / font_height;
2638
-
2639
- XawScrollbarSetThumb(w, (double)((double)cur_y / (double)total_y),
2640
- (double)((double)viewport_y / (double)total_y));
2641
-
2642
- /* Send a key: if pixels negative, send KEY_SCROLL_DOWN */
2643
-
2644
- _send_key_to_curses(KEY_SF, NULL, TRUE);
2645
- }
2646
-
2647
- static void _scroll_left_right(Widget w, XtPointer client_data,
2648
- XtPointer call_data)
2649
- {
2650
- int pixels = (long) call_data;
2651
- int total_x = SP->sb_total_x * font_width;
2652
- int viewport_x = SP->sb_viewport_x * font_width;
2653
- int cur_x = SP->sb_cur_x * font_width;
2654
-
2655
- cur_x += pixels;
2656
-
2657
- /* limit panning to size of overall */
2658
-
2659
- if (cur_x < 0)
2660
- cur_x = 0;
2661
- else
2662
- if (cur_x > (total_x - viewport_x))
2663
- cur_x = total_x - viewport_x;
2664
-
2665
- SP->sb_cur_x = cur_x / font_width;
2666
-
2667
- XawScrollbarSetThumb(w, (double)((double)cur_x / (double)total_x),
2668
- (double)((double)viewport_x / (double)total_x));
2669
-
2670
- _send_key_to_curses(KEY_SR, NULL, TRUE);
2671
- }
2672
-
2673
- static void _thumb_up_down(Widget w, XtPointer client_data,
2674
- XtPointer call_data)
2675
- {
2676
- double percent = *(double *) call_data;
2677
- double total_y = (double)SP->sb_total_y;
2678
- double viewport_y = (double)SP->sb_viewport_y;
2679
- int cur_y = SP->sb_cur_y;
2680
-
2681
- /* If the size of the viewport is > overall area simply return,
2682
- as no scrolling is permitted. */
2683
-
2684
- if (SP->sb_viewport_y >= SP->sb_total_y)
2685
- return;
2686
-
2687
- if ((SP->sb_cur_y = (int)((double)total_y * percent)) >=
2688
- (total_y - viewport_y))
2689
- SP->sb_cur_y = total_y - viewport_y;
2690
-
2691
- XawScrollbarSetThumb(w, (double)(cur_y / total_y),
2692
- (double)(viewport_y / total_y));
2693
-
2694
- _send_key_to_curses(KEY_SF, NULL, TRUE);
2695
- }
2696
-
2697
- static void _thumb_left_right(Widget w, XtPointer client_data,
2698
- XtPointer call_data)
2699
- {
2700
- double percent = *(double *) call_data;
2701
- double total_x = (double)SP->sb_total_x;
2702
- double viewport_x = (double)SP->sb_viewport_x;
2703
- int cur_x = SP->sb_cur_x;
2704
-
2705
- if (SP->sb_viewport_x >= SP->sb_total_x)
2706
- return;
2707
-
2708
- if ((SP->sb_cur_x = (int)((float)total_x * percent)) >=
2709
- (total_x - viewport_x))
2710
- SP->sb_cur_x = total_x - viewport_x;
2711
-
2712
- XawScrollbarSetThumb(w, (double)(cur_x / total_x),
2713
- (double)(viewport_x / total_x));
2714
-
2715
- _send_key_to_curses(KEY_SR, NULL, TRUE);
2716
- }
2717
-
2718
- static void _exit_process(int rc, int sig, char *msg)
2719
- {
2720
- if (rc || sig)
2721
- fprintf(stderr, "%s:_exit_process() - called: rc:%d sig:%d <%s>\n",
2722
- XCLOGMSG, rc, sig, msg);
2723
-
2724
- shmdt((char *)SP);
2725
- shmdt((char *)Xcurscr);
2726
- shmctl(shmidSP, IPC_RMID, 0);
2727
- shmctl(shmid_Xcurscr, IPC_RMID, 0);
2728
-
2729
- if (bitmap_file)
2730
- {
2731
- XFreePixmap(XCURSESDISPLAY, icon_bitmap);
2732
- free(bitmap_file);
2733
- }
2734
-
2735
- #ifdef HAVE_XPM_H
2736
- if (pixmap_file)
2737
- {
2738
- XFreePixmap(XCURSESDISPLAY, icon_pixmap);
2739
- XFreePixmap(XCURSESDISPLAY, icon_pixmap_mask);
2740
- free(pixmap_file);
2741
- }
2742
- #endif
2743
- XFreeGC(XCURSESDISPLAY, normal_gc);
2744
- XFreeGC(XCURSESDISPLAY, italic_gc);
2745
- XFreeGC(XCURSESDISPLAY, bold_gc);
2746
- XFreeGC(XCURSESDISPLAY, block_cursor_gc);
2747
- XFreeGC(XCURSESDISPLAY, rect_cursor_gc);
2748
- XFreeGC(XCURSESDISPLAY, border_gc);
2749
- #ifdef PDC_XIM
2750
- XDestroyIC(Xic);
2751
- #endif
2752
-
2753
- shutdown(xc_display_sock, 2);
2754
- close(xc_display_sock);
2755
-
2756
- shutdown(xc_exit_sock, 2);
2757
- close(xc_exit_sock);
2758
-
2759
- shutdown(xc_key_sock, 2);
2760
- close(xc_key_sock);
2761
-
2762
- if (sig)
2763
- kill(xc_otherpid, sig); /* to kill parent process */
2764
-
2765
- _exit(rc);
2766
- }
2767
-
2768
- static void _resize(void)
2769
- {
2770
- short save_atrtab[PDC_COLOR_PAIRS * 2];
2771
-
2772
- after_first_curses_request = FALSE;
2773
-
2774
- SP->lines = XCursesLINES = ((resize_window_height -
2775
- (2 * xc_app_data.borderWidth)) / font_height);
2776
-
2777
- LINES = XCursesLINES - SP->linesrippedoff - SP->slklines;
2778
-
2779
- SP->cols = COLS = XCursesCOLS = ((resize_window_width -
2780
- (2 * xc_app_data.borderWidth)) / font_width);
2781
-
2782
- window_width = resize_window_width;
2783
- window_height = resize_window_height;
2784
-
2785
- _draw_border();
2786
-
2787
- /* Detach and drop the current shared memory segment and create and
2788
- attach to a new segment */
2789
-
2790
- memcpy(save_atrtab, xc_atrtab, sizeof(save_atrtab));
2791
-
2792
- SP->XcurscrSize = XCURSCR_SIZE;
2793
- shmdt((char *)Xcurscr);
2794
- shmctl(shmid_Xcurscr, IPC_RMID, 0);
2795
-
2796
- if ((shmid_Xcurscr = shmget(shmkey_Xcurscr,
2797
- SP->XcurscrSize + XCURSESSHMMIN, 0700 | IPC_CREAT)) < 0)
2798
- {
2799
- perror("Cannot allocate shared memory for curscr");
2800
-
2801
- _exit_process(4, SIGKILL, "exiting from _process_curses_requests");
2802
- }
2803
-
2804
- Xcurscr = (unsigned char*)shmat(shmid_Xcurscr, 0, 0);
2805
- memset(Xcurscr, 0, SP->XcurscrSize);
2806
- xc_atrtab = (short *)(Xcurscr + XCURSCR_ATRTAB_OFF);
2807
- memcpy(xc_atrtab, save_atrtab, sizeof(save_atrtab));
2808
- }
2809
-
2810
- /* For PDC_set_title() */
2811
-
2812
- static void _set_title(void)
2813
- {
2814
- char title[1024]; /* big enough for window title */
2815
- int pos;
2816
-
2817
- if ((XC_read_socket(xc_display_sock, &pos, sizeof(int)) < 0) ||
2818
- (XC_read_socket(xc_display_sock, title, pos) < 0))
2819
- {
2820
- _exit_process(5, SIGKILL, "exiting from _set_title");
2821
- }
2822
-
2823
- XtVaSetValues(topLevel, XtNtitle, title, NULL);
2824
- }
2825
-
2826
- /* For color_content() */
2827
-
2828
- static void _get_color(void)
2829
- {
2830
- XColor *tmp = (XColor *)(Xcurscr + XCURSCR_XCOLOR_OFF);
2831
- int index = tmp->pixel;
2832
- Colormap cmap = DefaultColormap(XCURSESDISPLAY,
2833
- DefaultScreen(XCURSESDISPLAY));
2834
-
2835
- if (index < 0 || index >= MAX_COLORS)
2836
- _exit_process(4, SIGKILL, "exiting from _get_color");
2837
-
2838
- tmp->pixel = colors[index];
2839
- XQueryColor(XCURSESDISPLAY, cmap, tmp);
2840
- }
2841
-
2842
- /* For init_color() */
2843
-
2844
- static void _set_color(void)
2845
- {
2846
- XColor *tmp = (XColor *)(Xcurscr + XCURSCR_XCOLOR_OFF);
2847
- int index = tmp->pixel;
2848
- Colormap cmap = DefaultColormap(XCURSESDISPLAY,
2849
- DefaultScreen(XCURSESDISPLAY));
2850
-
2851
- if (index < 0 || index >= MAX_COLORS)
2852
- _exit_process(4, SIGKILL, "exiting from _set_color");
2853
-
2854
- if (XAllocColor(XCURSESDISPLAY, cmap, tmp))
2855
- {
2856
- colors[index] = tmp->pixel;
2857
-
2858
- _display_screen();
2859
- }
2860
- }
2861
-
2862
- /* For PDC_getclipboard() */
2863
-
2864
- static void _get_selection(Widget w, XtPointer data, Atom *selection,
2865
- Atom *type, XtPointer value,
2866
- unsigned long *length, int *format)
2867
- {
2868
- unsigned char *src = value;
2869
- int pos, len = *length;
2870
-
2871
- XC_LOG(("_get_selection() - called\n"));
2872
-
2873
- if (!value && !len)
2874
- {
2875
- if (XC_write_display_socket_int(PDC_CLIP_EMPTY) < 0)
2876
- _exit_process(4, SIGKILL, "exiting from _get_selection");
2877
- }
2878
- else
2879
- {
2880
- /* Here all is OK, send PDC_CLIP_SUCCESS, then length, then
2881
- contents */
2882
-
2883
- if (XC_write_display_socket_int(PDC_CLIP_SUCCESS) < 0)
2884
- _exit_process(4, SIGKILL, "exiting from _get_selection");
2885
-
2886
- if (XC_write_display_socket_int(len) < 0)
2887
- _exit_process(4, SIGKILL, "exiting from _get_selection");
2888
-
2889
- for (pos = 0; pos < len; pos++)
2890
- {
2891
- #ifdef PDC_WIDE
2892
- wchar_t c;
2893
- #else
2894
- unsigned char c;
2895
- #endif
2896
- c = *src++;
2897
-
2898
- if (XC_write_socket(xc_display_sock, &c, sizeof(c)) < 0)
2899
- _exit_process(4, SIGKILL, "exiting from _get_selection");
2900
- }
2901
- }
2902
- }
2903
-
2904
- #ifdef PDC_WIDE
2905
- static void _get_selection_utf8(Widget w, XtPointer data, Atom *selection,
2906
- Atom *type, XtPointer value,
2907
- unsigned long *length, int *format)
2908
- {
2909
- int len = *length;
2910
-
2911
- XC_LOG(("_get_selection_utf8() - called\n"));
2912
-
2913
- if (!*type || !*length)
2914
- {
2915
- XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, _get_selection,
2916
- (XtPointer)NULL, 0);
2917
- return;
2918
- }
2919
-
2920
- if (!value && !len)
2921
- {
2922
- if (XC_write_display_socket_int(PDC_CLIP_EMPTY) >= 0)
2923
- return;
2924
- }
2925
- else
2926
- {
2927
- wchar_t *wcontents = malloc((len + 1) * sizeof(wchar_t));
2928
- char *src = value;
2929
- int i = 0;
2930
-
2931
- while (*src && i < (*length))
2932
- {
2933
- int retval = _from_utf8(wcontents + i, src, len);
2934
-
2935
- src += retval;
2936
- len -= retval;
2937
- i++;
2938
- }
2939
-
2940
- wcontents[i] = 0;
2941
- len = i;
2942
-
2943
- /* Here all is OK, send PDC_CLIP_SUCCESS, then length, then
2944
- contents */
2945
-
2946
- if (XC_write_display_socket_int(PDC_CLIP_SUCCESS) >= 0)
2947
- if (XC_write_display_socket_int(len) >= 0)
2948
- if (XC_write_socket(xc_display_sock,
2949
- wcontents, len * sizeof(wchar_t)) >= 0)
2950
- {
2951
- free(wcontents);
2952
- return;
2953
- }
2954
- }
2955
-
2956
- _exit_process(4, SIGKILL, "exiting from _get_selection_utf8");
2957
- }
2958
- #endif
2959
-
2960
- /* For PDC_setclipboard() */
2961
-
2962
- static void _set_selection(void)
2963
- {
2964
- long length, pos;
2965
- int status;
2966
-
2967
- if (XC_read_socket(xc_display_sock, &length, sizeof(long)) < 0)
2968
- _exit_process(5, SIGKILL, "exiting from _set_selection");
2969
-
2970
- if (length > (long)tmpsel_length)
2971
- {
2972
- if (!tmpsel_length)
2973
- tmpsel = malloc((length + 1) * sizeof(chtype));
2974
- else
2975
- tmpsel = realloc(tmpsel, (length + 1) * sizeof(chtype));
2976
- }
2977
-
2978
- if (!tmpsel)
2979
- if (XC_write_display_socket_int(PDC_CLIP_MEMORY_ERROR) < 0)
2980
- _exit_process(4, SIGKILL, "exiting from _set_selection");
2981
-
2982
- for (pos = 0; pos < length; pos++)
2983
- {
2984
- #ifdef PDC_WIDE
2985
- wchar_t c;
2986
- #else
2987
- unsigned char c;
2988
- #endif
2989
- if (XC_read_socket(xc_display_sock, &c, sizeof(c)) < 0)
2990
- _exit_process(5, SIGKILL, "exiting from _set_selection");
2991
-
2992
- tmpsel[pos] = c;
2993
- }
2994
-
2995
- tmpsel_length = length;
2996
- tmpsel[length] = 0;
2997
-
2998
- if (XtOwnSelection(topLevel, XA_PRIMARY, CurrentTime,
2999
- _convert_proc, _lose_ownership, NULL) == False)
3000
- {
3001
- status = PDC_CLIP_ACCESS_ERROR;
3002
- free(tmpsel);
3003
- tmpsel = NULL;
3004
- tmpsel_length = 0;
3005
- }
3006
- else
3007
- status = PDC_CLIP_SUCCESS;
3008
-
3009
- _selection_off();
3010
-
3011
- if (XC_write_display_socket_int(status) < 0)
3012
- _exit_process(4, SIGKILL, "exiting from _set_selection");
3013
- }
3014
-
3015
- /* The curses process is waiting; tell it to continue */
3016
-
3017
- static void _resume_curses(void)
3018
- {
3019
- if (XC_write_display_socket_int(CURSES_CONTINUE) < 0)
3020
- _exit_process(4, SIGKILL, "exiting from _process_curses_requests");
3021
- }
3022
-
3023
- /* The curses process sent us a message */
3024
-
3025
- static void _process_curses_requests(XtPointer client_data, int *fid,
3026
- XtInputId *id)
3027
- {
3028
- struct timeval socket_timeout = {0};
3029
- int s;
3030
- int old_row, new_row;
3031
- int old_x, new_x;
3032
- int pos, num_cols;
3033
-
3034
- char buf[12]; /* big enough for 2 integers */
3035
-
3036
- XC_LOG(("_process_curses_requests() - called\n"));
3037
-
3038
- if (!received_map_notify)
3039
- return;
3040
-
3041
- FD_ZERO(&xc_readfds);
3042
- FD_SET(xc_display_sock, &xc_readfds);
3043
-
3044
- if ((s = select(FD_SETSIZE, (FD_SET_CAST)&xc_readfds, NULL,
3045
- NULL, &socket_timeout)) < 0)
3046
- _exit_process(2, SIGKILL, "exiting from _process_curses_requests"
3047
- " - select failed");
3048
-
3049
- if (!s) /* no requests pending - should never happen! */
3050
- return;
3051
-
3052
- if (FD_ISSET(xc_display_sock, &xc_readfds))
3053
- {
3054
- /* read first integer to determine total message has been
3055
- received */
3056
-
3057
- XC_LOG(("_process_curses_requests() - before XC_read_socket()\n"));
3058
-
3059
- if (XC_read_socket(xc_display_sock, &num_cols, sizeof(int)) < 0)
3060
- _exit_process(3, SIGKILL, "exiting from _process_curses_requests"
3061
- " - first read");
3062
-
3063
- XC_LOG(("_process_curses_requests() - after XC_read_socket()\n"));
3064
-
3065
- after_first_curses_request = TRUE;
3066
-
3067
- switch(num_cols)
3068
- {
3069
- case CURSES_EXIT: /* request from curses to stop */
3070
- XC_LOG(("CURSES_EXIT received from child\n"));
3071
- _exit_process(0, 0, "XCursesProcess requested to exit by child");
3072
- break;
3073
-
3074
- case CURSES_BELL:
3075
- XC_LOG(("CURSES_BELL received from child\n"));
3076
- XBell(XCURSESDISPLAY, 50);
3077
- break;
3078
-
3079
- /* request from curses to confirm completion of display */
3080
-
3081
- case CURSES_REFRESH:
3082
- XC_LOG(("CURSES_REFRESH received from child\n"));
3083
- _refresh_screen();
3084
- _resume_curses();
3085
- break;
3086
-
3087
- case CURSES_REFRESH_SCROLLBAR:
3088
- _refresh_scrollbar();
3089
- break;
3090
-
3091
- case CURSES_BLINK_ON:
3092
- PDC_really_blinking = TRUE;
3093
- break;
3094
-
3095
- case CURSES_BLINK_OFF:
3096
- PDC_really_blinking = FALSE;
3097
- break;
3098
-
3099
- case CURSES_CURSOR:
3100
- XC_LOG(("CURSES_CURSOR received from child\n"));
3101
-
3102
- if (XC_read_socket(xc_display_sock, buf, sizeof(int) * 2) < 0)
3103
- _exit_process(5, SIGKILL, "exiting from CURSES_CURSOR "
3104
- "_process_curses_requests");
3105
-
3106
- memcpy(&pos, buf, sizeof(int));
3107
- old_row = pos & 0xFF;
3108
- old_x = pos >> 8;
3109
-
3110
- memcpy(&pos, buf + sizeof(int), sizeof(int));
3111
- new_row = pos & 0xFF;
3112
- new_x = pos >> 8;
3113
-
3114
- /* Only redraw the cursor if it's actually moved. */
3115
- /* Otherwise, it'll get refreshed at the next cycle. */
3116
- if( old_row != new_row || old_x != new_x)
3117
- _display_cursor(old_row, old_x, new_row, new_x);
3118
- break;
3119
-
3120
- case CURSES_DISPLAY_CURSOR:
3121
- if(PDC_blink_state)
3122
- {
3123
- XC_LOG(("CURSES_DISPLAY_CURSOR received from child. Vis. now: 1\n"));
3124
- }
3125
- else
3126
- {
3127
- XC_LOG(("CURSES_DISPLAY_CURSOR received from child. Vis. now: 0\n"));
3128
- }
3129
- break;
3130
-
3131
- case CURSES_TITLE:
3132
- XC_LOG(("CURSES_TITLE received from child\n"));
3133
- _set_title();
3134
- break;
3135
-
3136
- case CURSES_RESIZE:
3137
- XC_LOG(("CURSES_RESIZE received from child\n"));
3138
- _resize();
3139
- _resume_curses();
3140
- break;
3141
-
3142
- case CURSES_GET_SELECTION:
3143
- XC_LOG(("CURSES_GET_SELECTION received from child\n"));
3144
-
3145
- _resume_curses();
3146
-
3147
- XtGetSelectionValue(topLevel, XA_PRIMARY,
3148
- #ifdef PDC_WIDE
3149
- XA_UTF8_STRING(XtDisplay(topLevel)),
3150
- _get_selection_utf8,
3151
- #else
3152
- XA_STRING, _get_selection,
3153
- #endif
3154
- (XtPointer)NULL, 0);
3155
-
3156
- break;
3157
-
3158
- case CURSES_SET_SELECTION:
3159
- XC_LOG(("CURSES_SET_SELECTION received from child\n"));
3160
- _set_selection();
3161
- break;
3162
-
3163
- case CURSES_CLEAR_SELECTION:
3164
- XC_LOG(("CURSES_CLEAR_SELECTION received from child\n"));
3165
- _resume_curses();
3166
- _selection_off();
3167
- break;
3168
-
3169
- case CURSES_GET_COLOR:
3170
- XC_LOG(("CURSES_GET_COLOR recieved from child\n"));
3171
- _get_color();
3172
- _resume_curses();
3173
- break;
3174
-
3175
- case CURSES_SET_COLOR:
3176
- XC_LOG(("CURSES_SET_COLOR recieved from child\n"));
3177
- _set_color();
3178
- _resume_curses();
3179
- break;
3180
-
3181
- default:
3182
- PDC_LOG(("%s:Unknown request %d\n", XCLOGMSG, num_cols));
3183
- }
3184
- }
3185
- }
3186
-
3187
- static void _handle_structure_notify(Widget w, XtPointer client_data,
3188
- XEvent *event, Boolean *unused)
3189
- {
3190
- XC_LOG(("_handle_structure_notify() - called\n"));
3191
-
3192
- switch(event->type)
3193
- {
3194
- case ConfigureNotify:
3195
- XC_LOG(("ConfigureNotify received\n"));
3196
-
3197
- /* Window has been resized, change width and height to send to
3198
- place_text and place_graphics in next Expose. Also will need
3199
- to kill (SIGWINCH) curses process if screen size changes. */
3200
-
3201
- resize_window_width = event->xconfigure.width;
3202
- resize_window_height = event->xconfigure.height;
3203
-
3204
- after_first_curses_request = FALSE;
3205
-
3206
- #ifdef SIGWINCH
3207
- SP->resized = 1;
3208
-
3209
- kill(xc_otherpid, SIGWINCH);
3210
- #endif
3211
- _send_key_to_curses(KEY_RESIZE, NULL, TRUE);
3212
- break;
3213
-
3214
- case MapNotify:
3215
- XC_LOG(("MapNotify received\n"));
3216
-
3217
- received_map_notify = 1;
3218
-
3219
- _draw_border();
3220
- break;
3221
-
3222
- default:
3223
- PDC_LOG(("%s:_handle_structure_notify - unknown event %d\n",
3224
- XCLOGMSG, event->type));
3225
- }
3226
- }
3227
-
3228
- static RETSIGTYPE _handle_signals(int signo)
3229
- {
3230
- int flag = CURSES_EXIT;
3231
-
3232
- PDC_LOG(("%s:_handle_signals() - called: %d\n", XCLOGMSG, signo));
3233
-
3234
- /* Patch by: Georg Fuchs */
3235
-
3236
- XCursesSetSignal(signo, _handle_signals);
3237
-
3238
- #ifdef SIGTSTP
3239
- if (signo == SIGTSTP)
3240
- {
3241
- pause();
3242
- return;
3243
- }
3244
- #endif
3245
- #ifdef SIGCONT
3246
- if (signo == SIGCONT)
3247
- return;
3248
- #endif
3249
- #ifdef SIGCLD
3250
- if (signo == SIGCLD)
3251
- return;
3252
- #endif
3253
- #ifdef SIGTTIN
3254
- if (signo == SIGTTIN)
3255
- return;
3256
- #endif
3257
- #ifdef SIGWINCH
3258
- if (signo == SIGWINCH)
3259
- return;
3260
- #endif
3261
-
3262
- /* End of patch by: Georg Fuchs */
3263
-
3264
- XCursesSetSignal(signo, SIG_IGN);
3265
-
3266
- /* Send a CURSES_EXIT to myself */
3267
-
3268
- if (XC_write_socket(xc_exit_sock, &flag, sizeof(int)) < 0)
3269
- _exit_process(7, signo, "exiting from _handle_signals");
3270
- }
3271
-
3272
- #ifdef PDC_XIM
3273
- static void _dummy_handler(Widget w, XtPointer client_data,
3274
- XEvent *event, Boolean *unused)
3275
- {
3276
- }
3277
- #endif
3278
-
3279
- int XCursesSetupX(int argc, char *argv[])
3280
- {
3281
- char *myargv[] = {"PDCurses", NULL};
3282
- char override_text[2][10];
3283
- char **new_argv = NULL;
3284
- extern bool sb_started;
3285
-
3286
- int italic_font_valid, bold_font_valid;
3287
- int italic_font_width, italic_font_height;
3288
- int bold_font_width, bold_font_height;
3289
- XColor pointerforecolor, pointerbackcolor;
3290
- XrmValue rmfrom, rmto;
3291
- int i;
3292
- int minwidth, minheight;
3293
-
3294
- XC_LOG(("XCursesSetupX called\n"));
3295
-
3296
- if (!argv)
3297
- {
3298
- argv = myargv;
3299
- argc = 1;
3300
- }
3301
-
3302
- program_name = argv[0];
3303
- if( XCursesLINES != 24 || XCursesCOLS != 80)
3304
- { /* a call to resize() was made before initscr() */
3305
- int pass;
3306
-
3307
- new_argv = (char **)calloc( argc + 5, sizeof( char *));
3308
- for( i = 0; i < argc; i++)
3309
- new_argv[i] = argv[i];
3310
- argv = new_argv;
3311
- for( pass = 0; pass < 2; pass++)
3312
- {
3313
- const char *override = (pass ? "-cols" : "-lines");
3314
-
3315
- i = 0;
3316
- while( i < argc && strcmp( argv[i], override))
3317
- i++;
3318
- argv[i] = (char *)override;
3319
- argv[i + 1] = override_text[pass];
3320
- sprintf( override_text[pass], "%d",
3321
- (pass ? XCursesCOLS : XCursesLINES));
3322
- if( i == argc) /* this is new (usual case) */
3323
- argc += 2;
3324
- }
3325
- }
3326
-
3327
- /* Keep open the 'write' end of the socket so the XCurses process
3328
- can send a CURSES_EXIT to itself from within the signal handler */
3329
-
3330
- xc_exit_sock = xc_display_sockets[0];
3331
- xc_display_sock = xc_display_sockets[1];
3332
-
3333
- close(xc_key_sockets[0]);
3334
- xc_key_sock = xc_key_sockets[1];
3335
-
3336
- /* Trap all signals when XCurses is the child process, but only if
3337
- they haven't already been ignored by the application. */
3338
-
3339
- for (i = 0; i < PDC_MAX_SIGNALS; i++)
3340
- if (XCursesSetSignal(i, _handle_signals) == SIG_IGN)
3341
- XCursesSetSignal(i, SIG_IGN);
3342
-
3343
- /* Start defining X Toolkit things */
3344
-
3345
- #if XtSpecificationRelease > 4
3346
- XtSetLanguageProc(NULL, (XtLanguageProc)NULL, NULL);
3347
- #endif
3348
-
3349
- /* Exit if no DISPLAY variable set */
3350
-
3351
- if (!getenv("DISPLAY"))
3352
- {
3353
- fprintf(stderr, "Error: no DISPLAY variable set\n");
3354
- kill(xc_otherpid, SIGKILL);
3355
- return ERR;
3356
- }
3357
-
3358
- /* Initialise the top level widget */
3359
-
3360
- topLevel = XtVaAppInitialize(&app_context, class_name, options,
3361
- XtNumber(options), &argc, argv, NULL, NULL);
3362
- if( new_argv)
3363
- free( new_argv);
3364
-
3365
- XtVaGetApplicationResources(topLevel, &xc_app_data, app_resources,
3366
- XtNumber(app_resources), NULL);
3367
-
3368
- /* Check application resource values here */
3369
-
3370
- font_width = xc_app_data.normalFont->max_bounds.rbearing -
3371
- xc_app_data.normalFont->min_bounds.lbearing;
3372
-
3373
- font_height = xc_app_data.normalFont->max_bounds.ascent +
3374
- xc_app_data.normalFont->max_bounds.descent;
3375
-
3376
- font_ascent = xc_app_data.normalFont->max_bounds.ascent;
3377
- font_descent = xc_app_data.normalFont->max_bounds.descent;
3378
-
3379
- /* Check that the italic font and normal fonts are the same size */
3380
- /* italic fonts can have negative lbearings! */
3381
- if ( xc_app_data.italicFont->min_bounds.lbearing < 0 )
3382
- italic_font_width = xc_app_data.italicFont->max_bounds.rbearing + xc_app_data.italicFont->min_bounds.lbearing;
3383
- else
3384
- italic_font_width = xc_app_data.italicFont->max_bounds.rbearing - xc_app_data.italicFont->min_bounds.lbearing;
3385
- italic_font_height = xc_app_data.italicFont->max_bounds.ascent + xc_app_data.italicFont->max_bounds.descent;
3386
- italic_font_valid = (font_width == italic_font_width) && (font_height == italic_font_height);
3387
-
3388
- /* Check that the bold font and normal fonts are the same size */
3389
- if ( xc_app_data.boldFont->min_bounds.lbearing < 0 )
3390
- bold_font_width = xc_app_data.boldFont->max_bounds.rbearing + xc_app_data.boldFont->min_bounds.lbearing;
3391
- else
3392
- bold_font_width = xc_app_data.boldFont->max_bounds.rbearing - xc_app_data.boldFont->min_bounds.lbearing;
3393
- bold_font_height = xc_app_data.boldFont->max_bounds.ascent + xc_app_data.boldFont->max_bounds.descent;
3394
- bold_font_valid = (font_width == bold_font_width) && (font_height == bold_font_height);
3395
-
3396
- /* Calculate size of display window */
3397
-
3398
- XCursesCOLS = xc_app_data.cols;
3399
- XCursesLINES = xc_app_data.lines;
3400
-
3401
- window_width = font_width * XCursesCOLS +
3402
- 2 * xc_app_data.borderWidth;
3403
-
3404
- window_height = font_height * XCursesLINES +
3405
- 2 * xc_app_data.borderWidth;
3406
-
3407
- minwidth = font_width * 2 + xc_app_data.borderWidth * 2;
3408
- minheight = font_height * 2 + xc_app_data.borderWidth * 2;
3409
-
3410
- /* Set up the icon for the application; the default is an internal
3411
- one for PDCurses. Then set various application level resources. */
3412
-
3413
- _get_icon();
3414
-
3415
- #ifdef HAVE_XPM_H
3416
- if (xc_app_data.pixmap && xc_app_data.pixmap[0])
3417
- XtVaSetValues(topLevel, XtNminWidth, minwidth, XtNminHeight,
3418
- minheight, XtNbaseWidth, xc_app_data.borderWidth * 2,
3419
- XtNbaseHeight, xc_app_data.borderWidth * 2,
3420
- XtNiconPixmap, icon_pixmap,
3421
- XtNiconMask, icon_pixmap_mask, NULL);
3422
- else
3423
- #endif
3424
- XtVaSetValues(topLevel, XtNminWidth, minwidth, XtNminHeight,
3425
- minheight, XtNbaseWidth, xc_app_data.borderWidth * 2,
3426
- XtNbaseHeight, xc_app_data.borderWidth * 2,
3427
- XtNiconPixmap, icon_bitmap, NULL);
3428
-
3429
- /* Create a BOX widget in which to draw */
3430
-
3431
- if (xc_app_data.scrollbarWidth && sb_started)
3432
- {
3433
- scrollBox = XtVaCreateManagedWidget(program_name,
3434
- scrollBoxWidgetClass, topLevel, XtNwidth,
3435
- window_width + xc_app_data.scrollbarWidth,
3436
- XtNheight, window_height + xc_app_data.scrollbarWidth,
3437
- XtNwidthInc, font_width, XtNheightInc, font_height, NULL);
3438
-
3439
- drawing = XtVaCreateManagedWidget(program_name,
3440
- boxWidgetClass, scrollBox, XtNwidth,
3441
- window_width, XtNheight, window_height, XtNwidthInc,
3442
- font_width, XtNheightInc, font_height, NULL);
3443
-
3444
- scrollVert = XtVaCreateManagedWidget("scrollVert",
3445
- scrollbarWidgetClass, scrollBox, XtNorientation,
3446
- XtorientVertical, XtNheight, window_height, XtNwidth,
3447
- xc_app_data.scrollbarWidth, NULL);
3448
-
3449
- XtAddCallback(scrollVert, XtNscrollProc, _scroll_up_down, drawing);
3450
- XtAddCallback(scrollVert, XtNjumpProc, _thumb_up_down, drawing);
3451
-
3452
- scrollHoriz = XtVaCreateManagedWidget("scrollHoriz",
3453
- scrollbarWidgetClass, scrollBox, XtNorientation,
3454
- XtorientHorizontal, XtNwidth, window_width, XtNheight,
3455
- xc_app_data.scrollbarWidth, NULL);
3456
-
3457
- XtAddCallback(scrollHoriz, XtNscrollProc, _scroll_left_right, drawing);
3458
- XtAddCallback(scrollHoriz, XtNjumpProc, _thumb_left_right, drawing);
3459
- }
3460
- else
3461
- {
3462
- drawing = XtVaCreateManagedWidget(program_name, boxWidgetClass,
3463
- topLevel, XtNwidth, window_width, XtNheight, window_height,
3464
- XtNwidthInc, font_width, XtNheightInc, font_height, NULL);
3465
-
3466
- XtVaSetValues(topLevel, XtNwidthInc, font_width, XtNheightInc,
3467
- font_height, NULL);
3468
- }
3469
-
3470
- /* Process any default translations */
3471
-
3472
- XtAugmentTranslations(drawing,
3473
- XtParseTranslationTable(default_translations));
3474
- XtAppAddActions(app_context, action_table, XtNumber(action_table));
3475
-
3476
- /* Process the supplied colors */
3477
-
3478
- _initialize_colors();
3479
-
3480
- /* Now have LINES and COLS. Set these in the shared SP so the curses
3481
- program can find them. */
3482
-
3483
- LINES = XCursesLINES;
3484
- COLS = XCursesCOLS;
3485
-
3486
- if ((shmidSP = shmget(shmkeySP, sizeof(SCREEN) + XCURSESSHMMIN,
3487
- 0700 | IPC_CREAT)) < 0)
3488
- {
3489
- perror("Cannot allocate shared memory for SCREEN");
3490
- kill(xc_otherpid, SIGKILL);
3491
- return ERR;
3492
- }
3493
-
3494
- SP = (SCREEN*)shmat(shmidSP, 0, 0);
3495
- memset(SP, 0, sizeof(SCREEN));
3496
- SP->XcurscrSize = XCURSCR_SIZE;
3497
- SP->lines = XCursesLINES;
3498
- SP->cols = XCursesCOLS;
3499
-
3500
- SP->mouse_wait = xc_app_data.clickPeriod;
3501
- SP->audible = TRUE;
3502
-
3503
- PDC_LOG(("%s:SHM size for curscr %d\n", XCLOGMSG, SP->XcurscrSize));
3504
-
3505
- if ((shmid_Xcurscr = shmget(shmkey_Xcurscr, SP->XcurscrSize +
3506
- XCURSESSHMMIN, 0700 | IPC_CREAT)) < 0)
3507
- {
3508
- perror("Cannot allocate shared memory for curscr");
3509
- kill(xc_otherpid, SIGKILL);
3510
- shmdt((char *)SP);
3511
- shmctl(shmidSP, IPC_RMID, 0);
3512
- return ERR;
3513
- }
3514
-
3515
- Xcurscr = (unsigned char *)shmat(shmid_Xcurscr, 0, 0);
3516
- memset(Xcurscr, 0, SP->XcurscrSize);
3517
- xc_atrtab = (short *)(Xcurscr + XCURSCR_ATRTAB_OFF);
3518
-
3519
- PDC_LOG(("%s:shmid_Xcurscr %d shmkey_Xcurscr %d LINES %d COLS %d\n",
3520
- XCLOGMSG, shmid_Xcurscr, shmkey_Xcurscr, LINES, COLS));
3521
-
3522
- /* Add Event handlers to the drawing widget */
3523
-
3524
- XtAddEventHandler(drawing, ExposureMask, False, _handle_expose, NULL);
3525
- XtAddEventHandler(drawing, StructureNotifyMask, False,
3526
- _handle_structure_notify, NULL);
3527
- XtAddEventHandler(drawing, EnterWindowMask | LeaveWindowMask, False,
3528
- _handle_enter_leave, NULL);
3529
- XtAddEventHandler(topLevel, 0, True, _handle_nonmaskable, NULL);
3530
-
3531
- /* Add input handler from xc_display_sock (requests from curses
3532
- program) */
3533
-
3534
- XtAppAddInput(app_context, xc_display_sock, (XtPointer)XtInputReadMask,
3535
- _process_curses_requests, NULL);
3536
-
3537
- /* start the Timeout event for blinking the cursor (and blinking text) */
3538
-
3539
- XtAppAddTimeOut(app_context, CURSOR_BLINK_RATE,
3540
- _blink_cursor, NULL);
3541
-
3542
- /* Leave telling the curses process that it can start to here so
3543
- that when the curses process makes a request, the Xcurses
3544
- process can service the request. */
3545
-
3546
- XC_write_display_socket_int(CURSES_CHILD);
3547
-
3548
- XtRealizeWidget(topLevel);
3549
-
3550
- /* Handle trapping of the WM_DELETE_WINDOW property */
3551
-
3552
- wm_atom[0] = XInternAtom(XtDisplay(topLevel), "WM_DELETE_WINDOW", False);
3553
-
3554
- XSetWMProtocols(XtDisplay(topLevel), XtWindow(topLevel), wm_atom, 1);
3555
-
3556
- /* Create the Graphics Context for drawing. This MUST be done AFTER
3557
- the associated widget has been realized. */
3558
-
3559
- XC_LOG(("before _get_gc\n"));
3560
-
3561
- _get_gc(&normal_gc, xc_app_data.normalFont, COLOR_WHITE, COLOR_BLACK);
3562
-
3563
- _get_gc(&italic_gc, italic_font_valid ? xc_app_data.italicFont :
3564
- xc_app_data.normalFont, COLOR_WHITE, COLOR_BLACK);
3565
-
3566
- _get_gc(&bold_gc, bold_font_valid ? xc_app_data.boldFont :
3567
- xc_app_data.normalFont, COLOR_WHITE, COLOR_BLACK);
3568
-
3569
- _get_gc(&block_cursor_gc, xc_app_data.normalFont,
3570
- COLOR_BLACK, COLOR_CURSOR);
3571
-
3572
- _get_gc(&rect_cursor_gc, xc_app_data.normalFont,
3573
- COLOR_CURSOR, COLOR_BLACK);
3574
-
3575
- _get_gc(&border_gc, xc_app_data.normalFont, COLOR_BORDER, COLOR_BLACK);
3576
-
3577
- XSetLineAttributes(XCURSESDISPLAY, rect_cursor_gc, 2,
3578
- LineSolid, CapButt, JoinMiter);
3579
-
3580
- XSetLineAttributes(XCURSESDISPLAY, border_gc, xc_app_data.borderWidth,
3581
- LineSolid, CapButt, JoinMiter);
3582
-
3583
- /* Set the cursor for the application */
3584
-
3585
- XDefineCursor(XCURSESDISPLAY, XCURSESWIN, xc_app_data.pointer);
3586
- rmfrom.size = sizeof(Pixel);
3587
- rmto.size = sizeof(XColor);
3588
-
3589
- rmto.addr = (XPointer)&pointerforecolor;
3590
- rmfrom.addr = (XPointer)&(xc_app_data.pointerForeColor);
3591
- XtConvertAndStore(drawing, XtRPixel, &rmfrom, XtRColor, &rmto);
3592
-
3593
- rmfrom.size = sizeof(Pixel);
3594
- rmto.size = sizeof(XColor);
3595
-
3596
- rmfrom.addr = (XPointer)&(xc_app_data.pointerBackColor);
3597
- rmto.addr = (XPointer)&pointerbackcolor;
3598
- XtConvertAndStore(drawing, XtRPixel, &rmfrom, XtRColor, &rmto);
3599
-
3600
- XRecolorCursor(XCURSESDISPLAY, xc_app_data.pointer,
3601
- &pointerforecolor, &pointerbackcolor);
3602
-
3603
- #ifndef PDC_XIM
3604
-
3605
- /* Convert the supplied compose key to a Keysym */
3606
-
3607
- compose_key = XStringToKeysym(xc_app_data.composeKey);
3608
-
3609
- if (compose_key && IsModifierKey(compose_key))
3610
- {
3611
- int i, j;
3612
- KeyCode *kcp;
3613
- XModifierKeymap *map;
3614
- KeyCode compose_keycode = XKeysymToKeycode(XCURSESDISPLAY, compose_key);
3615
-
3616
- map = XGetModifierMapping(XCURSESDISPLAY);
3617
- kcp = map->modifiermap;
3618
-
3619
- for (i = 0; i < 8; i++)
3620
- {
3621
- for (j = 0; j < map->max_keypermod; j++, kcp++)
3622
- {
3623
- if (!*kcp)
3624
- continue;
3625
-
3626
- if (compose_keycode == *kcp)
3627
- {
3628
- compose_mask = state_mask[i];
3629
- break;
3630
- }
3631
- }
3632
-
3633
- if (compose_mask)
3634
- break;
3635
- }
3636
-
3637
- XFreeModifiermap(map);
3638
- }
3639
-
3640
- #else
3641
- Xim = XOpenIM(XCURSESDISPLAY, NULL, NULL, NULL);
3642
-
3643
- if (Xim)
3644
- {
3645
- Xic = XCreateIC(Xim, XNInputStyle,
3646
- XIMPreeditNothing | XIMStatusNothing,
3647
- XNClientWindow, XCURSESWIN, NULL);
3648
- }
3649
-
3650
- if (Xic)
3651
- {
3652
- long im_event_mask;
3653
-
3654
- XGetICValues(Xic, XNFilterEvents, &im_event_mask, NULL);
3655
- if (im_event_mask)
3656
- XtAddEventHandler(drawing, im_event_mask, False,
3657
- _dummy_handler, NULL);
3658
-
3659
- XSetICFocus(Xic);
3660
- }
3661
- else
3662
- {
3663
- perror("ERROR: Cannot create input context");
3664
- kill(xc_otherpid, SIGKILL);
3665
- shmdt((char *)SP);
3666
- shmdt((char *)Xcurscr);
3667
- shmctl(shmidSP, IPC_RMID, 0);
3668
- shmctl(shmid_Xcurscr, IPC_RMID, 0);
3669
- return ERR;
3670
- }
3671
-
3672
- #endif
3673
-
3674
- /* Wait for events */
3675
- {
3676
- XEvent event;
3677
-
3678
- for (;;) /* forever */
3679
- {
3680
- XtAppNextEvent(app_context, &event);
3681
- XtDispatchEvent(&event);
3682
- }
3683
- }
3684
-
3685
- return OK; /* won't get here */
3686
- }