curses 1.3.0 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (256) 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 +25 -0
  5. data/History.md +34 -0
  6. data/README.md +14 -46
  7. data/Rakefile +0 -86
  8. data/curses.gemspec +2 -3
  9. data/ext/curses/curses.c +70 -58
  10. data/ext/curses/extconf.rb +134 -21
  11. data/lib/curses.rb +5 -12
  12. data/sample/addch.rb +16 -0
  13. data/sample/attr_demo.rb +32 -0
  14. data/sample/colors.rb +26 -0
  15. data/sample/menu.rb +3 -3
  16. data/sample/mouse_move.rb +75 -0
  17. data/vendor/PDCurses/.gitignore +47 -0
  18. data/vendor/PDCurses/.travis.yml +49 -0
  19. data/vendor/PDCurses/CMakeLists.txt +68 -0
  20. data/vendor/PDCurses/HISTORY.md +2036 -0
  21. data/vendor/PDCurses/IMPLEMNT.md +327 -0
  22. data/vendor/PDCurses/README.md +77 -0
  23. data/vendor/PDCurses/acs_defs.h +265 -0
  24. data/vendor/PDCurses/appveyor.yml +218 -0
  25. data/vendor/PDCurses/cmake/README.md +71 -0
  26. data/vendor/PDCurses/cmake/build_dependencies.cmake +178 -0
  27. data/vendor/PDCurses/cmake/build_options.cmake +25 -0
  28. data/vendor/PDCurses/cmake/dll_version.cmake +26 -0
  29. data/vendor/PDCurses/cmake/gen_config_header.cmake +43 -0
  30. data/vendor/PDCurses/cmake/get_version.cmake +17 -0
  31. data/vendor/PDCurses/cmake/make_uninstall.cmake +19 -0
  32. data/vendor/PDCurses/cmake/project_common.cmake +121 -0
  33. data/vendor/PDCurses/cmake/resource.in.cmake +52 -0
  34. data/vendor/PDCurses/cmake/sdl2_ttf/CMakeLists.txt +83 -0
  35. data/vendor/PDCurses/cmake/target_arch.cmake +36 -0
  36. data/vendor/PDCurses/cmake/version.in.cmake +73 -0
  37. data/vendor/PDCurses/cmake/watcom_open_dos16_toolchain.cmake +96 -0
  38. data/vendor/PDCurses/cmake/watcom_open_dos32_toolchain.cmake +106 -0
  39. data/vendor/PDCurses/cmake/watcom_open_os2v2_toolchain.cmake +105 -0
  40. data/vendor/PDCurses/curses.h +1846 -0
  41. data/vendor/PDCurses/curspriv.h +134 -0
  42. data/vendor/PDCurses/demos/README.md +25 -0
  43. data/vendor/PDCurses/demos/firework.c +144 -0
  44. data/vendor/PDCurses/demos/newtest.c +581 -0
  45. data/vendor/PDCurses/demos/ozdemo.c +447 -0
  46. data/vendor/PDCurses/demos/ptest.c +283 -0
  47. data/vendor/PDCurses/demos/rain.c +157 -0
  48. data/vendor/PDCurses/demos/testcurs.c +1607 -0
  49. data/vendor/PDCurses/demos/tui.c +1048 -0
  50. data/vendor/PDCurses/demos/tui.h +65 -0
  51. data/vendor/PDCurses/demos/tuidemo.c +233 -0
  52. data/vendor/PDCurses/demos/version.c +61 -0
  53. data/vendor/PDCurses/demos/worm.c +432 -0
  54. data/vendor/PDCurses/demos/xmas.c +955 -0
  55. data/vendor/PDCurses/dos/CMakeLists.txt +47 -0
  56. data/vendor/PDCurses/dos/Makefile.bcc +83 -0
  57. data/vendor/PDCurses/dos/Makefile.dmc +257 -0
  58. data/vendor/PDCurses/dos/Makefile.msc +113 -0
  59. data/vendor/PDCurses/dos/Makefile.wcc +107 -0
  60. data/vendor/PDCurses/dos/README.md +51 -0
  61. data/vendor/PDCurses/dos/bccdos.lrf +9 -0
  62. data/vendor/PDCurses/dos/mscdos.lrf +50 -0
  63. data/vendor/PDCurses/dos/pdcclip.c +132 -0
  64. data/vendor/PDCurses/dos/pdcdisp.c +135 -0
  65. data/vendor/PDCurses/dos/pdcdos.h +194 -0
  66. data/vendor/PDCurses/dos/pdcgetsc.c +98 -0
  67. data/vendor/PDCurses/dos/pdckbd.c +513 -0
  68. data/vendor/PDCurses/dos/pdcscrn.c +785 -0
  69. data/vendor/PDCurses/dos/pdcsetsc.c +101 -0
  70. data/vendor/PDCurses/dos/pdcutil.c +212 -0
  71. data/vendor/PDCurses/libobjs.mif +26 -0
  72. data/vendor/PDCurses/makedist.mif +20 -0
  73. data/vendor/PDCurses/man/README.md +21 -0
  74. data/vendor/PDCurses/man/intro.md +361 -0
  75. data/vendor/PDCurses/man/manext.c +119 -0
  76. data/vendor/PDCurses/man/sdl.md +152 -0
  77. data/vendor/PDCurses/man/sdl2.md +58 -0
  78. data/vendor/PDCurses/man/x11.md +407 -0
  79. data/vendor/PDCurses/ncurses/CMakeLists.txt +66 -0
  80. data/vendor/PDCurses/ncurses/README.md +26 -0
  81. data/vendor/PDCurses/ncurses/makefile +29 -0
  82. data/vendor/PDCurses/os2/CMakeLists.txt +41 -0
  83. data/vendor/PDCurses/os2/Makefile.bcc +90 -0
  84. data/vendor/PDCurses/os2/Makefile.wcc +43 -0
  85. data/vendor/PDCurses/os2/README.md +43 -0
  86. data/vendor/PDCurses/os2/iccos2.lrf +50 -0
  87. data/vendor/PDCurses/os2/iccos2.mak +256 -0
  88. data/vendor/PDCurses/os2/pdcclip.c +188 -0
  89. data/vendor/PDCurses/os2/pdcdisp.c +93 -0
  90. data/vendor/PDCurses/os2/pdcgetsc.c +89 -0
  91. data/vendor/PDCurses/os2/pdckbd.c +521 -0
  92. data/vendor/PDCurses/os2/pdcos2.h +55 -0
  93. data/vendor/PDCurses/os2/pdcscrn.c +449 -0
  94. data/vendor/PDCurses/os2/pdcsetsc.c +112 -0
  95. data/vendor/PDCurses/os2/pdcutil.c +52 -0
  96. data/vendor/PDCurses/panel.h +56 -0
  97. data/vendor/PDCurses/pdcurses/README.md +25 -0
  98. data/vendor/PDCurses/pdcurses/addch.c +693 -0
  99. data/vendor/PDCurses/pdcurses/addchstr.c +245 -0
  100. data/vendor/PDCurses/pdcurses/addstr.c +240 -0
  101. data/vendor/PDCurses/pdcurses/attr.c +359 -0
  102. data/vendor/PDCurses/pdcurses/beep.c +68 -0
  103. data/vendor/PDCurses/pdcurses/bkgd.c +223 -0
  104. data/vendor/PDCurses/pdcurses/border.c +411 -0
  105. data/vendor/PDCurses/pdcurses/clear.c +159 -0
  106. data/vendor/PDCurses/pdcurses/color.c +298 -0
  107. data/vendor/PDCurses/pdcurses/debug.c +109 -0
  108. data/vendor/PDCurses/pdcurses/delch.c +96 -0
  109. data/vendor/PDCurses/pdcurses/deleteln.c +211 -0
  110. data/vendor/PDCurses/pdcurses/deprec.c +27 -0
  111. data/vendor/PDCurses/pdcurses/getch.c +417 -0
  112. data/vendor/PDCurses/pdcurses/getstr.c +474 -0
  113. data/vendor/PDCurses/pdcurses/getyx.c +139 -0
  114. data/vendor/PDCurses/pdcurses/inch.c +127 -0
  115. data/vendor/PDCurses/pdcurses/inchstr.c +214 -0
  116. data/vendor/PDCurses/pdcurses/initscr.c +367 -0
  117. data/vendor/PDCurses/pdcurses/inopts.c +324 -0
  118. data/vendor/PDCurses/pdcurses/insch.c +271 -0
  119. data/vendor/PDCurses/pdcurses/insstr.c +264 -0
  120. data/vendor/PDCurses/pdcurses/instr.c +246 -0
  121. data/vendor/PDCurses/pdcurses/kernel.c +259 -0
  122. data/vendor/PDCurses/pdcurses/keyname.c +157 -0
  123. data/vendor/PDCurses/pdcurses/mouse.c +438 -0
  124. data/vendor/PDCurses/pdcurses/move.c +57 -0
  125. data/vendor/PDCurses/pdcurses/outopts.c +159 -0
  126. data/vendor/PDCurses/pdcurses/overlay.c +214 -0
  127. data/vendor/PDCurses/pdcurses/pad.c +260 -0
  128. data/vendor/PDCurses/pdcurses/panel.c +633 -0
  129. data/vendor/PDCurses/pdcurses/printw.c +126 -0
  130. data/vendor/PDCurses/pdcurses/refresh.c +279 -0
  131. data/vendor/PDCurses/pdcurses/scanw.c +578 -0
  132. data/vendor/PDCurses/pdcurses/scr_dump.c +213 -0
  133. data/vendor/PDCurses/pdcurses/scroll.c +101 -0
  134. data/vendor/PDCurses/pdcurses/slk.c +591 -0
  135. data/vendor/PDCurses/pdcurses/termattr.c +182 -0
  136. data/vendor/PDCurses/pdcurses/terminfo.c +217 -0
  137. data/vendor/PDCurses/pdcurses/touch.c +163 -0
  138. data/vendor/PDCurses/pdcurses/util.c +312 -0
  139. data/vendor/PDCurses/pdcurses/window.c +569 -0
  140. data/vendor/PDCurses/sdl1/Makefile.mng +110 -0
  141. data/vendor/PDCurses/sdl1/README.md +31 -0
  142. data/vendor/PDCurses/sdl1/deffont.h +385 -0
  143. data/vendor/PDCurses/sdl1/deficon.h +23 -0
  144. data/vendor/PDCurses/sdl1/pdcclip.c +131 -0
  145. data/vendor/PDCurses/sdl1/pdcdisp.c +373 -0
  146. data/vendor/PDCurses/sdl1/pdcgetsc.c +30 -0
  147. data/vendor/PDCurses/sdl1/pdckbd.c +405 -0
  148. data/vendor/PDCurses/sdl1/pdcscrn.c +414 -0
  149. data/vendor/PDCurses/sdl1/pdcsdl.h +31 -0
  150. data/vendor/PDCurses/sdl1/pdcsetsc.c +64 -0
  151. data/vendor/PDCurses/sdl1/pdcutil.c +40 -0
  152. data/vendor/PDCurses/sdl1/sdltest.c +79 -0
  153. data/vendor/PDCurses/sdl2/CMakeLists.txt +76 -0
  154. data/vendor/PDCurses/sdl2/Makefile.vc +164 -0
  155. data/vendor/PDCurses/sdl2/README.md +34 -0
  156. data/vendor/PDCurses/sdl2/deffont.h +385 -0
  157. data/vendor/PDCurses/sdl2/deficon.h +23 -0
  158. data/vendor/PDCurses/sdl2/pdcclip.c +93 -0
  159. data/vendor/PDCurses/sdl2/pdcdisp.c +534 -0
  160. data/vendor/PDCurses/sdl2/pdcgetsc.c +30 -0
  161. data/vendor/PDCurses/sdl2/pdckbd.c +480 -0
  162. data/vendor/PDCurses/sdl2/pdcscrn.c +443 -0
  163. data/vendor/PDCurses/sdl2/pdcsdl.h +33 -0
  164. data/vendor/PDCurses/sdl2/pdcsetsc.c +67 -0
  165. data/vendor/PDCurses/sdl2/pdcutil.c +39 -0
  166. data/vendor/PDCurses/sdl2/sdltest.c +81 -0
  167. data/vendor/PDCurses/term.h +48 -0
  168. data/vendor/PDCurses/version.mif +7 -0
  169. data/vendor/PDCurses/vt/CMakeLists.txt +28 -0
  170. data/vendor/PDCurses/vt/Makefile.bcc +111 -0
  171. data/vendor/PDCurses/vt/Makefile.dmc +258 -0
  172. data/vendor/PDCurses/vt/Makefile.vc +144 -0
  173. data/vendor/PDCurses/vt/Makefile.wcc +107 -0
  174. data/vendor/PDCurses/vt/README.md +64 -0
  175. data/vendor/PDCurses/vt/pdcclip.c +20 -0
  176. data/vendor/PDCurses/vt/pdcdisp.c +284 -0
  177. data/vendor/PDCurses/vt/pdcgetsc.c +27 -0
  178. data/vendor/PDCurses/vt/pdckbd.c +394 -0
  179. data/vendor/PDCurses/vt/pdcscrn.c +434 -0
  180. data/vendor/PDCurses/vt/pdcsetsc.c +45 -0
  181. data/vendor/PDCurses/vt/pdcutil.c +43 -0
  182. data/vendor/PDCurses/vt/pdcvt.h +16 -0
  183. data/vendor/PDCurses/watcom.mif +68 -0
  184. data/vendor/PDCurses/wincon/CMakeLists.txt +27 -0
  185. data/vendor/PDCurses/wincon/Makefile.bcc +88 -0
  186. data/vendor/PDCurses/wincon/Makefile.dmc +256 -0
  187. data/vendor/PDCurses/wincon/Makefile.lcc +273 -0
  188. data/vendor/PDCurses/wincon/Makefile.mng +176 -0
  189. data/vendor/PDCurses/wincon/Makefile.vc +144 -0
  190. data/vendor/PDCurses/wincon/Makefile.wcc +51 -0
  191. data/vendor/PDCurses/wincon/README.md +85 -0
  192. data/vendor/PDCurses/wincon/pdcclip.c +174 -0
  193. data/vendor/PDCurses/wincon/pdcdisp.c +143 -0
  194. data/vendor/PDCurses/wincon/pdcgetsc.c +55 -0
  195. data/vendor/PDCurses/wincon/pdckbd.c +786 -0
  196. data/vendor/PDCurses/wincon/pdcscrn.c +717 -0
  197. data/vendor/PDCurses/wincon/pdcsetsc.c +91 -0
  198. data/vendor/PDCurses/wincon/pdcurses.ico +0 -0
  199. data/vendor/PDCurses/wincon/pdcurses.rc +28 -0
  200. data/vendor/PDCurses/wincon/pdcutil.c +41 -0
  201. data/vendor/PDCurses/wincon/pdcwin.h +31 -0
  202. data/vendor/PDCurses/wingui/CMakeLists.txt +27 -0
  203. data/vendor/PDCurses/wingui/Makefile.bcc +85 -0
  204. data/vendor/PDCurses/wingui/Makefile.dmc +259 -0
  205. data/vendor/PDCurses/wingui/Makefile.lcc +273 -0
  206. data/vendor/PDCurses/wingui/Makefile.mng +171 -0
  207. data/vendor/PDCurses/wingui/Makefile.vc +144 -0
  208. data/vendor/PDCurses/wingui/Makefile.wcc +51 -0
  209. data/vendor/PDCurses/wingui/README.md +93 -0
  210. data/vendor/PDCurses/wingui/pdcclip.c +174 -0
  211. data/vendor/PDCurses/wingui/pdcdisp.c +718 -0
  212. data/vendor/PDCurses/wingui/pdcgetsc.c +30 -0
  213. data/vendor/PDCurses/wingui/pdckbd.c +143 -0
  214. data/vendor/PDCurses/wingui/pdcscrn.c +2797 -0
  215. data/vendor/PDCurses/wingui/pdcsetsc.c +89 -0
  216. data/vendor/PDCurses/wingui/pdcurses.ico +0 -0
  217. data/vendor/PDCurses/wingui/pdcurses.rc +28 -0
  218. data/vendor/PDCurses/wingui/pdcutil.c +61 -0
  219. data/vendor/PDCurses/wingui/pdcwin.h +122 -0
  220. data/vendor/PDCurses/x11/Makefile.in +754 -0
  221. data/vendor/PDCurses/x11/PDCurses.spec +82 -0
  222. data/vendor/PDCurses/x11/README.md +62 -0
  223. data/vendor/PDCurses/x11/ScrollBox.c +319 -0
  224. data/vendor/PDCurses/x11/ScrollBox.h +51 -0
  225. data/vendor/PDCurses/x11/ScrollBoxP.h +70 -0
  226. data/vendor/PDCurses/x11/aclocal.m4 +994 -0
  227. data/vendor/PDCurses/x11/big_icon.xbm +46 -0
  228. data/vendor/PDCurses/x11/compose.h +201 -0
  229. data/vendor/PDCurses/x11/config.guess +1500 -0
  230. data/vendor/PDCurses/x11/config.h.in +100 -0
  231. data/vendor/PDCurses/x11/config.sub +1616 -0
  232. data/vendor/PDCurses/x11/configure +6700 -0
  233. data/vendor/PDCurses/x11/configure.ac +295 -0
  234. data/vendor/PDCurses/x11/debian/changelog +6 -0
  235. data/vendor/PDCurses/x11/debian/compat +1 -0
  236. data/vendor/PDCurses/x11/debian/control +11 -0
  237. data/vendor/PDCurses/x11/debian/copyright +27 -0
  238. data/vendor/PDCurses/x11/debian/rules +98 -0
  239. data/vendor/PDCurses/x11/install-sh +253 -0
  240. data/vendor/PDCurses/x11/little_icon.xbm +14 -0
  241. data/vendor/PDCurses/x11/ncurses_cfg.h +45 -0
  242. data/vendor/PDCurses/x11/pdcclip.c +173 -0
  243. data/vendor/PDCurses/x11/pdcdisp.c +85 -0
  244. data/vendor/PDCurses/x11/pdcgetsc.c +28 -0
  245. data/vendor/PDCurses/x11/pdckbd.c +104 -0
  246. data/vendor/PDCurses/x11/pdcscrn.c +258 -0
  247. data/vendor/PDCurses/x11/pdcsetsc.c +95 -0
  248. data/vendor/PDCurses/x11/pdcutil.c +52 -0
  249. data/vendor/PDCurses/x11/pdcx11.c +316 -0
  250. data/vendor/PDCurses/x11/pdcx11.h +191 -0
  251. data/vendor/PDCurses/x11/sb.c +155 -0
  252. data/vendor/PDCurses/x11/x11.c +3686 -0
  253. data/vendor/PDCurses/x11/xcurses-config.in +81 -0
  254. metadata +258 -24
  255. data/.travis.yml +0 -16
  256. data/appveyor.yml +0 -16
@@ -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
+ }