curses 1.2.6 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +19 -0
  3. data/.github/workflows/ubuntu.yml +26 -0
  4. data/.github/workflows/windows.yml +28 -0
  5. data/.gitmodules +1 -1
  6. data/.travis.yml +6 -3
  7. data/History.md +40 -0
  8. data/README.md +4 -1
  9. data/Rakefile +0 -83
  10. data/curses.gemspec +2 -3
  11. data/ext/curses/curses.c +1271 -151
  12. data/ext/curses/extconf.rb +140 -17
  13. data/lib/curses.rb +5 -12
  14. data/sample/form.rb +52 -0
  15. data/sample/menu.rb +1 -1
  16. data/vendor/PDCurses/.gitignore +47 -0
  17. data/vendor/PDCurses/.travis.yml +49 -0
  18. data/vendor/PDCurses/CMakeLists.txt +68 -0
  19. data/vendor/PDCurses/HISTORY.md +2036 -0
  20. data/vendor/PDCurses/IMPLEMNT.md +327 -0
  21. data/vendor/PDCurses/README.md +77 -0
  22. data/vendor/PDCurses/acs_defs.h +265 -0
  23. data/vendor/PDCurses/appveyor.yml +218 -0
  24. data/vendor/PDCurses/cmake/README.md +71 -0
  25. data/vendor/PDCurses/cmake/build_dependencies.cmake +178 -0
  26. data/vendor/PDCurses/cmake/build_options.cmake +25 -0
  27. data/vendor/PDCurses/cmake/dll_version.cmake +26 -0
  28. data/vendor/PDCurses/cmake/gen_config_header.cmake +43 -0
  29. data/vendor/PDCurses/cmake/get_version.cmake +17 -0
  30. data/vendor/PDCurses/cmake/make_uninstall.cmake +19 -0
  31. data/vendor/PDCurses/cmake/project_common.cmake +121 -0
  32. data/vendor/PDCurses/cmake/resource.in.cmake +52 -0
  33. data/vendor/PDCurses/cmake/sdl2_ttf/CMakeLists.txt +83 -0
  34. data/vendor/PDCurses/cmake/target_arch.cmake +36 -0
  35. data/vendor/PDCurses/cmake/version.in.cmake +73 -0
  36. data/vendor/PDCurses/cmake/watcom_open_dos16_toolchain.cmake +96 -0
  37. data/vendor/PDCurses/cmake/watcom_open_dos32_toolchain.cmake +106 -0
  38. data/vendor/PDCurses/cmake/watcom_open_os2v2_toolchain.cmake +105 -0
  39. data/vendor/PDCurses/curses.h +1846 -0
  40. data/vendor/PDCurses/curspriv.h +134 -0
  41. data/vendor/PDCurses/demos/README.md +25 -0
  42. data/vendor/PDCurses/demos/firework.c +144 -0
  43. data/vendor/PDCurses/demos/newtest.c +581 -0
  44. data/vendor/PDCurses/demos/ozdemo.c +447 -0
  45. data/vendor/PDCurses/demos/ptest.c +283 -0
  46. data/vendor/PDCurses/demos/rain.c +157 -0
  47. data/vendor/PDCurses/demos/testcurs.c +1607 -0
  48. data/vendor/PDCurses/demos/tui.c +1048 -0
  49. data/vendor/PDCurses/demos/tui.h +65 -0
  50. data/vendor/PDCurses/demos/tuidemo.c +233 -0
  51. data/vendor/PDCurses/demos/version.c +61 -0
  52. data/vendor/PDCurses/demos/worm.c +432 -0
  53. data/vendor/PDCurses/demos/xmas.c +955 -0
  54. data/vendor/PDCurses/dos/CMakeLists.txt +47 -0
  55. data/vendor/PDCurses/dos/Makefile.bcc +83 -0
  56. data/vendor/PDCurses/dos/Makefile.dmc +257 -0
  57. data/vendor/PDCurses/dos/Makefile.msc +113 -0
  58. data/vendor/PDCurses/dos/Makefile.wcc +107 -0
  59. data/vendor/PDCurses/dos/README.md +51 -0
  60. data/vendor/PDCurses/dos/bccdos.lrf +9 -0
  61. data/vendor/PDCurses/dos/mscdos.lrf +50 -0
  62. data/vendor/PDCurses/dos/pdcclip.c +132 -0
  63. data/vendor/PDCurses/dos/pdcdisp.c +135 -0
  64. data/vendor/PDCurses/dos/pdcdos.h +194 -0
  65. data/vendor/PDCurses/dos/pdcgetsc.c +98 -0
  66. data/vendor/PDCurses/dos/pdckbd.c +513 -0
  67. data/vendor/PDCurses/dos/pdcscrn.c +785 -0
  68. data/vendor/PDCurses/dos/pdcsetsc.c +101 -0
  69. data/vendor/PDCurses/dos/pdcutil.c +212 -0
  70. data/vendor/PDCurses/libobjs.mif +26 -0
  71. data/vendor/PDCurses/makedist.mif +20 -0
  72. data/vendor/PDCurses/man/README.md +21 -0
  73. data/vendor/PDCurses/man/intro.md +361 -0
  74. data/vendor/PDCurses/man/manext.c +119 -0
  75. data/vendor/PDCurses/man/sdl.md +152 -0
  76. data/vendor/PDCurses/man/sdl2.md +58 -0
  77. data/vendor/PDCurses/man/x11.md +407 -0
  78. data/vendor/PDCurses/ncurses/CMakeLists.txt +66 -0
  79. data/vendor/PDCurses/ncurses/README.md +26 -0
  80. data/vendor/PDCurses/ncurses/makefile +29 -0
  81. data/vendor/PDCurses/os2/CMakeLists.txt +41 -0
  82. data/vendor/PDCurses/os2/Makefile.bcc +90 -0
  83. data/vendor/PDCurses/os2/Makefile.wcc +43 -0
  84. data/vendor/PDCurses/os2/README.md +43 -0
  85. data/vendor/PDCurses/os2/iccos2.lrf +50 -0
  86. data/vendor/PDCurses/os2/iccos2.mak +256 -0
  87. data/vendor/PDCurses/os2/pdcclip.c +188 -0
  88. data/vendor/PDCurses/os2/pdcdisp.c +93 -0
  89. data/vendor/PDCurses/os2/pdcgetsc.c +89 -0
  90. data/vendor/PDCurses/os2/pdckbd.c +521 -0
  91. data/vendor/PDCurses/os2/pdcos2.h +55 -0
  92. data/vendor/PDCurses/os2/pdcscrn.c +449 -0
  93. data/vendor/PDCurses/os2/pdcsetsc.c +112 -0
  94. data/vendor/PDCurses/os2/pdcutil.c +52 -0
  95. data/vendor/PDCurses/panel.h +56 -0
  96. data/vendor/PDCurses/pdcurses/README.md +25 -0
  97. data/vendor/PDCurses/pdcurses/addch.c +693 -0
  98. data/vendor/PDCurses/pdcurses/addchstr.c +245 -0
  99. data/vendor/PDCurses/pdcurses/addstr.c +240 -0
  100. data/vendor/PDCurses/pdcurses/attr.c +359 -0
  101. data/vendor/PDCurses/pdcurses/beep.c +68 -0
  102. data/vendor/PDCurses/pdcurses/bkgd.c +223 -0
  103. data/vendor/PDCurses/pdcurses/border.c +411 -0
  104. data/vendor/PDCurses/pdcurses/clear.c +159 -0
  105. data/vendor/PDCurses/pdcurses/color.c +298 -0
  106. data/vendor/PDCurses/pdcurses/debug.c +109 -0
  107. data/vendor/PDCurses/pdcurses/delch.c +96 -0
  108. data/vendor/PDCurses/pdcurses/deleteln.c +211 -0
  109. data/vendor/PDCurses/pdcurses/deprec.c +27 -0
  110. data/vendor/PDCurses/pdcurses/getch.c +417 -0
  111. data/vendor/PDCurses/pdcurses/getstr.c +474 -0
  112. data/vendor/PDCurses/pdcurses/getyx.c +139 -0
  113. data/vendor/PDCurses/pdcurses/inch.c +127 -0
  114. data/vendor/PDCurses/pdcurses/inchstr.c +214 -0
  115. data/vendor/PDCurses/pdcurses/initscr.c +367 -0
  116. data/vendor/PDCurses/pdcurses/inopts.c +324 -0
  117. data/vendor/PDCurses/pdcurses/insch.c +271 -0
  118. data/vendor/PDCurses/pdcurses/insstr.c +264 -0
  119. data/vendor/PDCurses/pdcurses/instr.c +246 -0
  120. data/vendor/PDCurses/pdcurses/kernel.c +259 -0
  121. data/vendor/PDCurses/pdcurses/keyname.c +157 -0
  122. data/vendor/PDCurses/pdcurses/mouse.c +438 -0
  123. data/vendor/PDCurses/pdcurses/move.c +57 -0
  124. data/vendor/PDCurses/pdcurses/outopts.c +159 -0
  125. data/vendor/PDCurses/pdcurses/overlay.c +214 -0
  126. data/vendor/PDCurses/pdcurses/pad.c +260 -0
  127. data/vendor/PDCurses/pdcurses/panel.c +633 -0
  128. data/vendor/PDCurses/pdcurses/printw.c +126 -0
  129. data/vendor/PDCurses/pdcurses/refresh.c +279 -0
  130. data/vendor/PDCurses/pdcurses/scanw.c +578 -0
  131. data/vendor/PDCurses/pdcurses/scr_dump.c +213 -0
  132. data/vendor/PDCurses/pdcurses/scroll.c +101 -0
  133. data/vendor/PDCurses/pdcurses/slk.c +591 -0
  134. data/vendor/PDCurses/pdcurses/termattr.c +182 -0
  135. data/vendor/PDCurses/pdcurses/terminfo.c +217 -0
  136. data/vendor/PDCurses/pdcurses/touch.c +163 -0
  137. data/vendor/PDCurses/pdcurses/util.c +312 -0
  138. data/vendor/PDCurses/pdcurses/window.c +569 -0
  139. data/vendor/PDCurses/sdl1/Makefile.mng +110 -0
  140. data/vendor/PDCurses/sdl1/README.md +31 -0
  141. data/vendor/PDCurses/sdl1/deffont.h +385 -0
  142. data/vendor/PDCurses/sdl1/deficon.h +23 -0
  143. data/vendor/PDCurses/sdl1/pdcclip.c +131 -0
  144. data/vendor/PDCurses/sdl1/pdcdisp.c +373 -0
  145. data/vendor/PDCurses/sdl1/pdcgetsc.c +30 -0
  146. data/vendor/PDCurses/sdl1/pdckbd.c +405 -0
  147. data/vendor/PDCurses/sdl1/pdcscrn.c +414 -0
  148. data/vendor/PDCurses/sdl1/pdcsdl.h +31 -0
  149. data/vendor/PDCurses/sdl1/pdcsetsc.c +64 -0
  150. data/vendor/PDCurses/sdl1/pdcutil.c +40 -0
  151. data/vendor/PDCurses/sdl1/sdltest.c +79 -0
  152. data/vendor/PDCurses/sdl2/CMakeLists.txt +76 -0
  153. data/vendor/PDCurses/sdl2/Makefile.vc +164 -0
  154. data/vendor/PDCurses/sdl2/README.md +34 -0
  155. data/vendor/PDCurses/sdl2/deffont.h +385 -0
  156. data/vendor/PDCurses/sdl2/deficon.h +23 -0
  157. data/vendor/PDCurses/sdl2/pdcclip.c +93 -0
  158. data/vendor/PDCurses/sdl2/pdcdisp.c +534 -0
  159. data/vendor/PDCurses/sdl2/pdcgetsc.c +30 -0
  160. data/vendor/PDCurses/sdl2/pdckbd.c +480 -0
  161. data/vendor/PDCurses/sdl2/pdcscrn.c +443 -0
  162. data/vendor/PDCurses/sdl2/pdcsdl.h +33 -0
  163. data/vendor/PDCurses/sdl2/pdcsetsc.c +67 -0
  164. data/vendor/PDCurses/sdl2/pdcutil.c +39 -0
  165. data/vendor/PDCurses/sdl2/sdltest.c +81 -0
  166. data/vendor/PDCurses/term.h +48 -0
  167. data/vendor/PDCurses/version.mif +7 -0
  168. data/vendor/PDCurses/vt/CMakeLists.txt +28 -0
  169. data/vendor/PDCurses/vt/Makefile.bcc +111 -0
  170. data/vendor/PDCurses/vt/Makefile.dmc +258 -0
  171. data/vendor/PDCurses/vt/Makefile.vc +144 -0
  172. data/vendor/PDCurses/vt/Makefile.wcc +107 -0
  173. data/vendor/PDCurses/vt/README.md +64 -0
  174. data/vendor/PDCurses/vt/pdcclip.c +20 -0
  175. data/vendor/PDCurses/vt/pdcdisp.c +284 -0
  176. data/vendor/PDCurses/vt/pdcgetsc.c +27 -0
  177. data/vendor/PDCurses/vt/pdckbd.c +394 -0
  178. data/vendor/PDCurses/vt/pdcscrn.c +434 -0
  179. data/vendor/PDCurses/vt/pdcsetsc.c +45 -0
  180. data/vendor/PDCurses/vt/pdcutil.c +43 -0
  181. data/vendor/PDCurses/vt/pdcvt.h +16 -0
  182. data/vendor/PDCurses/watcom.mif +68 -0
  183. data/vendor/PDCurses/wincon/CMakeLists.txt +27 -0
  184. data/vendor/PDCurses/wincon/Makefile.bcc +88 -0
  185. data/vendor/PDCurses/wincon/Makefile.dmc +256 -0
  186. data/vendor/PDCurses/wincon/Makefile.lcc +273 -0
  187. data/vendor/PDCurses/wincon/Makefile.mng +176 -0
  188. data/vendor/PDCurses/wincon/Makefile.vc +144 -0
  189. data/vendor/PDCurses/wincon/Makefile.wcc +51 -0
  190. data/vendor/PDCurses/wincon/README.md +85 -0
  191. data/vendor/PDCurses/wincon/pdcclip.c +174 -0
  192. data/vendor/PDCurses/wincon/pdcdisp.c +143 -0
  193. data/vendor/PDCurses/wincon/pdcgetsc.c +55 -0
  194. data/vendor/PDCurses/wincon/pdckbd.c +786 -0
  195. data/vendor/PDCurses/wincon/pdcscrn.c +717 -0
  196. data/vendor/PDCurses/wincon/pdcsetsc.c +91 -0
  197. data/vendor/PDCurses/wincon/pdcurses.ico +0 -0
  198. data/vendor/PDCurses/wincon/pdcurses.rc +28 -0
  199. data/vendor/PDCurses/wincon/pdcutil.c +41 -0
  200. data/vendor/PDCurses/wincon/pdcwin.h +31 -0
  201. data/vendor/PDCurses/wingui/CMakeLists.txt +27 -0
  202. data/vendor/PDCurses/wingui/Makefile.bcc +85 -0
  203. data/vendor/PDCurses/wingui/Makefile.dmc +259 -0
  204. data/vendor/PDCurses/wingui/Makefile.lcc +273 -0
  205. data/vendor/PDCurses/wingui/Makefile.mng +171 -0
  206. data/vendor/PDCurses/wingui/Makefile.vc +144 -0
  207. data/vendor/PDCurses/wingui/Makefile.wcc +51 -0
  208. data/vendor/PDCurses/wingui/README.md +93 -0
  209. data/vendor/PDCurses/wingui/pdcclip.c +174 -0
  210. data/vendor/PDCurses/wingui/pdcdisp.c +718 -0
  211. data/vendor/PDCurses/wingui/pdcgetsc.c +30 -0
  212. data/vendor/PDCurses/wingui/pdckbd.c +143 -0
  213. data/vendor/PDCurses/wingui/pdcscrn.c +2797 -0
  214. data/vendor/PDCurses/wingui/pdcsetsc.c +89 -0
  215. data/vendor/PDCurses/wingui/pdcurses.ico +0 -0
  216. data/vendor/PDCurses/wingui/pdcurses.rc +28 -0
  217. data/vendor/PDCurses/wingui/pdcutil.c +61 -0
  218. data/vendor/PDCurses/wingui/pdcwin.h +122 -0
  219. data/vendor/PDCurses/x11/Makefile.in +754 -0
  220. data/vendor/PDCurses/x11/PDCurses.spec +82 -0
  221. data/vendor/PDCurses/x11/README.md +62 -0
  222. data/vendor/PDCurses/x11/ScrollBox.c +319 -0
  223. data/vendor/PDCurses/x11/ScrollBox.h +51 -0
  224. data/vendor/PDCurses/x11/ScrollBoxP.h +70 -0
  225. data/vendor/PDCurses/x11/aclocal.m4 +994 -0
  226. data/vendor/PDCurses/x11/big_icon.xbm +46 -0
  227. data/vendor/PDCurses/x11/compose.h +201 -0
  228. data/vendor/PDCurses/x11/config.guess +1500 -0
  229. data/vendor/PDCurses/x11/config.h.in +100 -0
  230. data/vendor/PDCurses/x11/config.sub +1616 -0
  231. data/vendor/PDCurses/x11/configure +6700 -0
  232. data/vendor/PDCurses/x11/configure.ac +295 -0
  233. data/vendor/PDCurses/x11/debian/changelog +6 -0
  234. data/vendor/PDCurses/x11/debian/compat +1 -0
  235. data/vendor/PDCurses/x11/debian/control +11 -0
  236. data/vendor/PDCurses/x11/debian/copyright +27 -0
  237. data/vendor/PDCurses/x11/debian/rules +98 -0
  238. data/vendor/PDCurses/x11/install-sh +253 -0
  239. data/vendor/PDCurses/x11/little_icon.xbm +14 -0
  240. data/vendor/PDCurses/x11/ncurses_cfg.h +45 -0
  241. data/vendor/PDCurses/x11/pdcclip.c +173 -0
  242. data/vendor/PDCurses/x11/pdcdisp.c +85 -0
  243. data/vendor/PDCurses/x11/pdcgetsc.c +28 -0
  244. data/vendor/PDCurses/x11/pdckbd.c +104 -0
  245. data/vendor/PDCurses/x11/pdcscrn.c +258 -0
  246. data/vendor/PDCurses/x11/pdcsetsc.c +95 -0
  247. data/vendor/PDCurses/x11/pdcutil.c +52 -0
  248. data/vendor/PDCurses/x11/pdcx11.c +316 -0
  249. data/vendor/PDCurses/x11/pdcx11.h +191 -0
  250. data/vendor/PDCurses/x11/sb.c +155 -0
  251. data/vendor/PDCurses/x11/x11.c +3686 -0
  252. data/vendor/PDCurses/x11/xcurses-config.in +81 -0
  253. metadata +255 -21
@@ -0,0 +1,191 @@
1
+ /* Public Domain Curses */
2
+
3
+ #ifdef HAVE_CONFIG_H
4
+ # include "config.h"
5
+ #endif
6
+
7
+ #include <curspriv.h>
8
+
9
+ #ifdef HAVE_UNISTD_H
10
+ # include <unistd.h>
11
+ #endif
12
+
13
+ #include <signal.h>
14
+ #include <ctype.h>
15
+ #include <pwd.h>
16
+
17
+ #include <sys/types.h>
18
+ #include <sys/socket.h>
19
+ #ifdef HAVE_FCNTL_H
20
+ # include <fcntl.h>
21
+ #endif
22
+ #ifdef HAVE_SYS_SELECT_H
23
+ # include <sys/select.h> /* AIX needs this for FD_ZERO etc macros */
24
+ #endif
25
+ #include <sys/ipc.h>
26
+ #include <sys/shm.h>
27
+
28
+ #ifdef TIME_WITH_SYS_TIME
29
+ # include <sys/time.h>
30
+ # include <time.h>
31
+ #else
32
+ # ifdef HAVE_SYS_TIME_H
33
+ # include <sys/time.h>
34
+ # else
35
+ # include <time.h>
36
+ # endif
37
+ #endif
38
+
39
+ #include <Intrinsic.h>
40
+ #include <StringDefs.h>
41
+ #include <Shell.h>
42
+
43
+ #ifdef USE_XAW3D
44
+ # include <Xaw3d/Box.h>
45
+ # include <Xaw3d/Scrollbar.h>
46
+ #elif defined(USE_NEXTAW)
47
+ # include <neXtaw/Box.h>
48
+ # include <neXtaw/Scrollbar.h>
49
+ #else
50
+ # include <Xaw/Box.h>
51
+ # include <Xaw/Scrollbar.h>
52
+ #endif
53
+ #include "x11/ScrollBox.h"
54
+
55
+ #include "Xmu/StdSel.h"
56
+ #include "Xmu/Atoms.h"
57
+
58
+ #include <keysym.h>
59
+ #include <Xatom.h>
60
+
61
+ #define XCURSCR_Y_SIZE (XCursesLINES * XCursesCOLS * sizeof(chtype))
62
+ #define XCURSCR_FLAG_SIZE (XCursesLINES * sizeof(int))
63
+ #define XCURSCR_START_SIZE (XCursesLINES * sizeof(int))
64
+ #define XCURSCR_LENGTH_SIZE (XCursesLINES * sizeof(int))
65
+ #define XCURSCR_ATRTAB_SIZE (PDC_COLOR_PAIRS * 2 * sizeof(short))
66
+ #define XCURSCR_SIZE (XCURSCR_FLAG_SIZE + XCURSCR_START_SIZE + \
67
+ XCURSCR_LENGTH_SIZE + XCURSCR_Y_SIZE + XCURSCR_ATRTAB_SIZE + \
68
+ sizeof(XColor))
69
+
70
+ #define XCURSCR_Y_OFF(y) ((y) * XCursesCOLS * sizeof(chtype))
71
+ #define XCURSCR_FLAG_OFF (XCURSCR_Y_OFF(0) + XCURSCR_Y_SIZE)
72
+ #define XCURSCR_START_OFF (XCURSCR_FLAG_OFF + XCURSCR_FLAG_SIZE)
73
+ #define XCURSCR_LENGTH_OFF (XCURSCR_START_OFF + XCURSCR_START_SIZE)
74
+ #define XCURSCR_ATRTAB_OFF (XCURSCR_LENGTH_OFF + XCURSCR_LENGTH_SIZE)
75
+ #define XCURSCR_XCOLOR_OFF (XCURSCR_ATRTAB_OFF + XCURSCR_ATRTAB_SIZE)
76
+
77
+ typedef struct
78
+ {
79
+ int lines;
80
+ int cols;
81
+ Pixel cursorColor;
82
+ Pixel colorBlack;
83
+ Pixel colorRed;
84
+ Pixel colorGreen;
85
+ Pixel colorYellow;
86
+ Pixel colorBlue;
87
+ Pixel colorMagenta;
88
+ Pixel colorCyan;
89
+ Pixel colorWhite;
90
+ Pixel colorBoldBlack;
91
+ Pixel colorBoldRed;
92
+ Pixel colorBoldGreen;
93
+ Pixel colorBoldYellow;
94
+ Pixel colorBoldBlue;
95
+ Pixel colorBoldMagenta;
96
+ Pixel colorBoldCyan;
97
+ Pixel colorBoldWhite;
98
+ Pixel pointerForeColor;
99
+ Pixel pointerBackColor;
100
+ XFontStruct *normalFont;
101
+ XFontStruct *italicFont;
102
+ XFontStruct *boldFont;
103
+ char *bitmap;
104
+ #ifdef HAVE_XPM_H
105
+ char *pixmap;
106
+ #endif
107
+ char *composeKey;
108
+ Cursor pointer;
109
+ int shmmin;
110
+ int borderWidth;
111
+ int borderColor;
112
+ int clickPeriod;
113
+ int doubleClickPeriod;
114
+ int scrollbarWidth;
115
+ int cursorBlinkRate;
116
+ char *textCursor;
117
+ } XCursesAppData;
118
+
119
+ extern XCursesAppData xc_app_data;
120
+
121
+ #define XCURSESSHMMIN xc_app_data.shmmin
122
+
123
+ #define XCLOGMSG (XCursesProcess ? " X" : "CURSES")
124
+
125
+ void XC_get_line_lock(int);
126
+ void XC_release_line_lock(int);
127
+
128
+ int PDC_display_cursor(int, int, int, int, int);
129
+
130
+ void XCursesExitCursesProcess(int, char *);
131
+ int XCursesInstruct(int);
132
+ int XCursesInstructAndWait(int);
133
+ int XCursesInitscr(int, char **);
134
+
135
+ int XC_write_socket(int, const void *, int);
136
+ int XC_read_socket(int, void *, int);
137
+ int XC_write_display_socket_int(int);
138
+
139
+ int XCursesSetupX(int argc, char *argv[]);
140
+ RETSIGTYPE XCursesSigwinchHandler(int signo);
141
+
142
+ #ifdef _HPUX_SOURCE
143
+ # define FD_SET_CAST int *
144
+ #else
145
+ # define FD_SET_CAST fd_set *
146
+ #endif
147
+
148
+ extern fd_set xc_readfds;
149
+
150
+ extern unsigned char *Xcurscr;
151
+ extern int XCursesProcess;
152
+ extern int shmidSP;
153
+ extern int shmid_Xcurscr;
154
+ extern int shmkeySP;
155
+ extern int shmkey_Xcurscr;
156
+ extern int xc_otherpid;
157
+ extern int XCursesLINES;
158
+ extern int XCursesCOLS;
159
+ extern int xc_display_sock;
160
+ extern int xc_key_sock;
161
+ extern int xc_display_sockets[2];
162
+ extern int xc_key_sockets[2];
163
+ extern int xc_exit_sock;
164
+
165
+ typedef RETSIGTYPE (*signal_handler)();
166
+
167
+ signal_handler XCursesSetSignal(int, signal_handler);
168
+
169
+ #ifdef PDCDEBUG
170
+ void XC_say(const char *msg);
171
+ # define XC_LOG(x) XC_say x
172
+ #else
173
+ # define XC_LOG(x)
174
+ #endif
175
+
176
+ #ifdef MOUSE_DEBUG
177
+ # define MOUSE_LOG(x) printf x
178
+ #else
179
+ # define MOUSE_LOG(x)
180
+ #endif
181
+
182
+ enum
183
+ {
184
+ CURSES_CLEAR_SELECTION, CURSES_DISPLAY_CURSOR, CURSES_SET_SELECTION,
185
+ CURSES_GET_SELECTION, CURSES_TITLE, CURSES_REFRESH_SCROLLBAR,
186
+ CURSES_RESIZE, CURSES_BELL, CURSES_CONTINUE, CURSES_CURSOR,
187
+ CURSES_CHILD, CURSES_REFRESH, CURSES_GET_COLOR, CURSES_SET_COLOR,
188
+ CURSES_BLINK_ON, CURSES_BLINK_OFF, CURSES_EXIT
189
+ };
190
+
191
+ extern short *xc_atrtab;
@@ -0,0 +1,155 @@
1
+ /* Public Domain Curses */
2
+
3
+ #include "pdcx11.h"
4
+
5
+ /*man-start**************************************************************
6
+
7
+ sb
8
+ --
9
+
10
+ ### Synopsis
11
+
12
+ int sb_init(void)
13
+ int sb_set_horz(int total, int viewport, int cur)
14
+ int sb_set_vert(int total, int viewport, int cur)
15
+ int sb_get_horz(int *total, int *viewport, int *cur)
16
+ int sb_get_vert(int *total, int *viewport, int *cur)
17
+ int sb_refresh(void);
18
+
19
+ ### Description
20
+
21
+ These functions manipulate the scrollbar.
22
+
23
+ ### Return Value
24
+
25
+ All functions return OK on success and ERR on error.
26
+
27
+ ### Portability
28
+ X/Open BSD SYS V
29
+ sb_init - - -
30
+ sb_set_horz - - -
31
+ sb_set_vert - - -
32
+ sb_get_horz - - -
33
+ sb_get_vert - - -
34
+ sb_refresh - - -
35
+
36
+ **man-end****************************************************************/
37
+
38
+ bool sb_started = FALSE;
39
+
40
+ /* sb_init() is the sb initialization routine.
41
+ This must be called before initscr(). */
42
+
43
+ int sb_init(void)
44
+ {
45
+ PDC_LOG(("sb_init() - called\n"));
46
+
47
+ if (SP)
48
+ return ERR;
49
+
50
+ sb_started = TRUE;
51
+
52
+ return OK;
53
+ }
54
+
55
+ /* sb_set_horz() - Used to set horizontal scrollbar.
56
+
57
+ total = total number of columns
58
+ viewport = size of viewport in columns
59
+ cur = current column in total */
60
+
61
+ int sb_set_horz(int total, int viewport, int cur)
62
+ {
63
+ PDC_LOG(("sb_set_horz() - called: total %d viewport %d cur %d\n",
64
+ total, viewport, cur));
65
+
66
+ if (!SP)
67
+ return ERR;
68
+
69
+ SP->sb_total_x = total;
70
+ SP->sb_viewport_x = viewport;
71
+ SP->sb_cur_x = cur;
72
+
73
+ return OK;
74
+ }
75
+
76
+ /* sb_set_vert() - Used to set vertical scrollbar.
77
+
78
+ total = total number of columns on line
79
+ viewport = size of viewport in columns
80
+ cur = current column in total */
81
+
82
+ int sb_set_vert(int total, int viewport, int cur)
83
+ {
84
+ PDC_LOG(("sb_set_vert() - called: total %d viewport %d cur %d\n",
85
+ total, viewport, cur));
86
+
87
+ if (!SP)
88
+ return ERR;
89
+
90
+ SP->sb_total_y = total;
91
+ SP->sb_viewport_y = viewport;
92
+ SP->sb_cur_y = cur;
93
+
94
+ return OK;
95
+ }
96
+
97
+ /* sb_get_horz() - Used to get horizontal scrollbar.
98
+
99
+ total = total number of lines
100
+ viewport = size of viewport in lines
101
+ cur = current line in total */
102
+
103
+ int sb_get_horz(int *total, int *viewport, int *cur)
104
+ {
105
+ PDC_LOG(("sb_get_horz() - called\n"));
106
+
107
+ if (!SP)
108
+ return ERR;
109
+
110
+ if (total)
111
+ *total = SP->sb_total_x;
112
+ if (viewport)
113
+ *viewport = SP->sb_viewport_x;
114
+ if (cur)
115
+ *cur = SP->sb_cur_x;
116
+
117
+ return OK;
118
+ }
119
+
120
+ /* sb_get_vert() - Used to get vertical scrollbar.
121
+
122
+ total = total number of lines
123
+ viewport = size of viewport in lines
124
+ cur = current line in total */
125
+
126
+ int sb_get_vert(int *total, int *viewport, int *cur)
127
+ {
128
+ PDC_LOG(("sb_get_vert() - called\n"));
129
+
130
+ if (!SP)
131
+ return ERR;
132
+
133
+ if (total)
134
+ *total = SP->sb_total_y;
135
+ if (viewport)
136
+ *viewport = SP->sb_viewport_y;
137
+ if (cur)
138
+ *cur = SP->sb_cur_y;
139
+
140
+ return OK;
141
+ }
142
+
143
+ /* sb_refresh() - Used to draw the scrollbars. */
144
+
145
+ int sb_refresh(void)
146
+ {
147
+ PDC_LOG(("sb_refresh() - called\n"));
148
+
149
+ if (!SP)
150
+ return ERR;
151
+
152
+ XCursesInstruct(CURSES_REFRESH_SCROLLBAR);
153
+
154
+ return OK;
155
+ }
@@ -0,0 +1,3686 @@
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
+ }