keyxdef.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /* {{{ Copyright */
  2. /*
  3. Additional keyboard support routines.
  4. Copyright (C) 1998-2024
  5. Free Software Foundation, Inc.
  6. Written by:
  7. Gyorgy Tamasi, 1998
  8. This file is part of the Midnight Commander.
  9. The Midnight Commander is free software: you can redistribute it
  10. and/or modify it under the terms of the GNU General Public License as
  11. published by the Free Software Foundation, either version 3 of the License,
  12. or (at your option) any later version.
  13. The Midnight Commander is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /* }}} */
  21. /** \file keyxdef.c
  22. * \brief Source: additional keyboard support routines
  23. *
  24. * PURPOSE:
  25. * We would like to support the direct ALT-?/META-? and some other 'extra'
  26. * keyboard functionality provided by some terminals under some OSes (and
  27. * not supported by the 'learn keys...' facility of 'mc'.
  28. * (First target platform: QNX.)
  29. *
  30. * REMARK:
  31. *
  32. * Implementation strategy: we don't want to rely on a specific terminal
  33. * information database management API (termcap,terminfo,SLang,...), so we
  34. * try to define a superset of the possible key identifiers here.
  35. *
  36. */
  37. #include <config.h>
  38. #include "lib/global.h"
  39. #include "tty.h"
  40. #include "mouse.h" /* required before key.h */
  41. #include "key.h"
  42. #if defined(__QNX__) && !defined(__QNXNTO__)
  43. #define HAVE_QNX_KEYS
  44. #endif
  45. #ifdef HAVE_QNX_KEYS
  46. /* select implementation: use QNX/term interface */
  47. #define __USE_QNX_TI
  48. /* implementation specific _TE() definition */
  49. #ifdef __USE_QNX_TI
  50. /* include QNX/term.h (not NCURSES/term.h!) */
  51. #if __WATCOMC__ > 1000
  52. #include <sys/term.h>
  53. #else
  54. #include <term.h>
  55. #endif
  56. #include <stdlib.h> /* getenv() */
  57. /* fieldname -> index conversion */
  58. #define __QTISX(_qtisn) (((int) (&((struct _strs *) 0)->_qtisn)) / sizeof (charoffset))
  59. /* define the OS/implementation-specific __TK() format */
  60. #define __TK(_tis, _tcs, _tisx, _qtisn) __QTISX (_qtisn)
  61. #endif /* __USE_QNX_TI */
  62. #endif /* HAVE_QNX_KEYS */
  63. /* {{{ */
  64. /* general key definitions:
  65. *
  66. * format:
  67. *
  68. * terminfo name,
  69. * termcap name,
  70. * index in the terminfo string table (ncurses),
  71. * field name in the QNX terminfo strings struct
  72. */
  73. /*** global variables ****************************************************************************/
  74. /*** file scope macro definitions ****************************************************************/
  75. #define Key_backspace __TK ("kbs", "kb", 55, _ky_backspace)
  76. #define Key_catab __TK ("ktbc", "ka", 56, _ky_catab)
  77. #define Key_clear __TK ("kclr", "kC", 57, _ky_clear)
  78. #define Key_ctab __TK ("kctab", "kt", 58, _ky_ctab)
  79. #define Key_dc __TK ("kdch1", "kD", 59, _ky_dc)
  80. #define Key_dl __TK ("kdl1", "kL", 60, _ky_dl)
  81. #define Key_down __TK ("kcud1", "kd", 61, _ky_down)
  82. #define Key_eic __TK ("krmir", "kM", 62, _ky_eic)
  83. #define Key_eol __TK ("kel", "kE", 63, _ky_eol)
  84. #define Key_eos __TK ("ked", "kS", 64, _ky_eos)
  85. #define Key_f0 __TK ("kf0", "k0", 65, _ky_f0)
  86. #define Key_f1 __TK ("kf1", "k1", 66, _ky_f1)
  87. #define Key_f10 __TK ("kf10", "k;", 67, _ky_f10)
  88. #define Key_f2 __TK ("kf2", "k2", 68, _ky_f2)
  89. #define Key_f3 __TK ("kf3", "k3", 69, _ky_f3)
  90. #define Key_f4 __TK ("kf4", "k4", 70, _ky_f4)
  91. #define Key_f5 __TK ("kf5", "k5", 71, _ky_f5)
  92. #define Key_f6 __TK ("kf6", "k6", 72, _ky_f6)
  93. #define Key_f7 __TK ("kf7", "k7", 73, _ky_f7)
  94. #define Key_f8 __TK ("kf8", "k8", 74, _ky_f8)
  95. #define Key_f9 __TK ("kf9", "k9", 75, _ky_f9)
  96. #define Key_home __TK ("khome", "kh", 76, _ky_home)
  97. #define Key_ic __TK ("kich1", "kI", 77, _ky_ic)
  98. #define Key_il __TK ("kil1", "kA", 78, _ky_il)
  99. #define Key_left __TK ("kcub1", "kl", 79, _ky_left)
  100. #define Key_ll __TK ("kll", "kH", 80, _ky_ll)
  101. #define Key_npage __TK ("knp", "kN", 81, _ky_npage)
  102. #define Key_ppage __TK ("kpp", "kP", 82, _ky_ppage)
  103. #define Key_right __TK ("kcuf1", "kr", 83, _ky_right)
  104. #define Key_sf __TK ("kind", "kF", 84, _ky_sf)
  105. #define Key_sr __TK ("kri", "kR", 85, _ky_sr)
  106. #define Key_stab __TK ("khts", "kT", 86, _ky_stab)
  107. #define Key_up __TK ("kcuu1", "ku", 87, _ky_up)
  108. #define Key_a1 __TK ("ka1", "K1", 139, _ky_a1)
  109. #define Key_a3 __TK ("ka3", "K3", 140, _ky_a3)
  110. #define Key_b2 __TK ("kb2", "K2", 141, _ky_b2)
  111. #define Key_c1 __TK ("kc1", "K4", 142, _ky_c1)
  112. #define Key_c3 __TK ("kc3", "K5", 143, _ky_c3)
  113. #define Key_btab __TK ("kcbt", "kB", 148, _ky_btab)
  114. #define Key_beg __TK ("kbeg", "@1", 158, _ky_beg)
  115. #define Key_cancel __TK ("kcan", "@2", 159, _ky_cancel)
  116. #define Key_close __TK ("kclo", "@3", 160, _ky_close)
  117. #define Key_command __TK ("kcmd", "@4", 161, _ky_command)
  118. #define Key_copy __TK ("kcpy", "@5", 162, _ky_copy)
  119. #define Key_create __TK ("kcrt", "@6", 163, _ky_create)
  120. #define Key_end __TK ("kend", "@7", 164, _ky_end)
  121. #define Key_enter __TK ("kent", "@8", 165, _ky_enter)
  122. #define Key_exit __TK ("kext", "@9", 166, _ky_exit)
  123. #define Key_find __TK ("kfnd", "@0", 167, _ky_find)
  124. #define Key_help __TK ("khlp", "%1", 168, _ky_help)
  125. #define Key_mark __TK ("kmrk", "%2", 169, _ky_mark)
  126. #define Key_message __TK ("kmsg", "%3", 170, _ky_message)
  127. #define Key_move __TK ("kmov", "%4", 171, _ky_move)
  128. #define Key_next __TK ("knxt", "%5", 172, _ky_next)
  129. #define Key_open __TK ("kopn", "%6", 173, _ky_open)
  130. #define Key_options __TK ("kopt", "%7", 174, _ky_options)
  131. #define Key_previous __TK ("kprv", "%8", 175, _ky_previous)
  132. #define Key_print __TK ("kprt", "%9", 176, _ky_print)
  133. #define Key_redo __TK ("krdo", "%0", 177, _ky_redo)
  134. #define Key_reference __TK ("kref", "&1", 178, _ky_reference)
  135. #define Key_refresh __TK ("krfr", "&2", 179, _ky_refresh)
  136. #define Key_replace __TK ("krpl", "&3", 180, _ky_replace)
  137. #define Key_restart __TK ("krst", "&4", 181, _ky_restart)
  138. #define Key_resume __TK ("kres", "&5", 182, _ky_resume)
  139. #define Key_save __TK ("ksav", "&6", 183, _ky_save)
  140. #define Key_suspend __TK ("kspd", "&7", 184, _ky_suspend)
  141. #define Key_undo __TK ("kund", "&8", 185, _ky_undo)
  142. #define Key_sbeg __TK ("kBEG", "&9", 186, _ky_sbeg)
  143. #define Key_scancel __TK ("kCAN", "&0", 187, _ky_scancel)
  144. #define Key_scommand __TK ("kCMD", "*1", 188, _ky_scommand)
  145. #define Key_scopy __TK ("kCPY", "*2", 189, _ky_scopy)
  146. #define Key_screate __TK ("kCRT", "*3", 190, _ky_screate)
  147. #define Key_sdc __TK ("kDC", "*4", 191, _ky_sdc)
  148. #define Key_sdl __TK ("kDL", "*5", 192, _ky_sdl)
  149. #define Key_select __TK ("kslt", "*6", 193, _ky_select)
  150. #define Key_send __TK ("kEND", "*7", 194, _ky_send)
  151. #define Key_seol __TK ("kEOL", "*8", 195, _ky_seol)
  152. #define Key_sexit __TK ("kEXT", "*9", 196, _ky_sexit)
  153. #define Key_sfind __TK ("kFND", "*0", 197, _ky_sfind)
  154. #define Key_shelp __TK ("kHLP", "#1", 198, _ky_shelp)
  155. #define Key_shome __TK ("kHOM", "#2", 199, _ky_shome)
  156. #define Key_sic __TK ("kIC", "#3", 200, _ky_sic)
  157. #define Key_sleft __TK ("kLFT", "#4", 201, _ky_sleft)
  158. #define Key_smessage __TK ("kMSG", "%a", 202, _ky_smessage)
  159. #define Key_smove __TK ("kMOV", "%b", 203, _ky_smove)
  160. #define Key_snext __TK ("kNXT", "%c", 204, _ky_snext)
  161. #define Key_soptions __TK ("kOPT", "%d", 205, _ky_soptions)
  162. #define Key_sprevious __TK ("kPRV", "%e", 206, _ky_sprevious)
  163. #define Key_sprint __TK ("kPRT", "%f", 207, _ky_sprint)
  164. #define Key_sredo __TK ("kRDO", "%g", 208, _ky_sredo)
  165. #define Key_sreplace __TK ("kRPL", "%h", 209, _ky_sreplace)
  166. #define Key_sright __TK ("kRIT", "%i", 210, _ky_sright)
  167. #define Key_srsume __TK ("kRES", "%j", 211, _ky_srsume)
  168. #define Key_ssave __TK ("kSAV", "!1", 212, _ky_ssave)
  169. #define Key_ssuspend __TK ("kSPD", "!2", 213, _ky_ssuspend)
  170. #define Key_sundo __TK ("kUND", "!3", 214, _ky_sundo)
  171. #define Key_f11 __TK ("kf11", "F1", 216, _ky_f11)
  172. #define Key_f12 __TK ("kf12", "F2", 217, _ky_f12)
  173. #define Key_f13 __TK ("kf13", "F3", 218, _ky_f13)
  174. #define Key_f14 __TK ("kf14", "F4", 219, _ky_f14)
  175. #define Key_f15 __TK ("kf15", "F5", 220, _ky_f15)
  176. #define Key_f16 __TK ("kf16", "F6", 221, _ky_f16)
  177. #define Key_f17 __TK ("kf17", "F7", 222, _ky_f17)
  178. #define Key_f18 __TK ("kf18", "F8", 223, _ky_f18)
  179. #define Key_f19 __TK ("kf19", "F9", 224, _ky_f19)
  180. #define Key_f20 __TK ("kf20", "FA", 225, _ky_f20)
  181. #define Key_f21 __TK ("kf21", "FB", 226, _ky_f21)
  182. #define Key_f22 __TK ("kf22", "FC", 227, _ky_f22)
  183. #define Key_f23 __TK ("kf23", "FD", 228, _ky_f23)
  184. #define Key_f24 __TK ("kf24", "FE", 229, _ky_f24)
  185. #define Key_f25 __TK ("kf25", "FF", 230, _ky_f25)
  186. #define Key_f26 __TK ("kf26", "FG", 231, _ky_f26)
  187. #define Key_f27 __TK ("kf27", "FH", 232, _ky_f27)
  188. #define Key_f28 __TK ("kf28", "FI", 233, _ky_f28)
  189. #define Key_f29 __TK ("kf29", "FJ", 234, _ky_f29)
  190. #define Key_f30 __TK ("kf30", "FK", 235, _ky_f30)
  191. #define Key_f31 __TK ("kf31", "FL", 236, _ky_f31)
  192. #define Key_f32 __TK ("kf32", "FM", 237, _ky_f32)
  193. #define Key_f33 __TK ("kf33", "FN", 238, _ky_f33)
  194. #define Key_f34 __TK ("kf34", "FO", 239, _ky_f34)
  195. #define Key_f35 __TK ("kf35", "FP", 240, _ky_f35)
  196. #define Key_f36 __TK ("kf36", "FQ", 241, _ky_f36)
  197. #define Key_f37 __TK ("kf37", "FR", 242, _ky_f37)
  198. #define Key_f38 __TK ("kf38", "FS", 243, _ky_f38)
  199. #define Key_f39 __TK ("kf39", "FT", 244, _ky_f39)
  200. #define Key_f40 __TK ("kf40", "FU", 245, _ky_f40)
  201. #define Key_f41 __TK ("kf41", "FV", 246, _ky_f41)
  202. #define Key_f42 __TK ("kf42", "FW", 247, _ky_f42)
  203. #define Key_f43 __TK ("kf43", "FX", 248, _ky_f43)
  204. #define Key_f44 __TK ("kf44", "FY", 249, _ky_f44)
  205. #define Key_f45 __TK ("kf45", "FZ", 250, _ky_f45)
  206. #define Key_f46 __TK ("kf46", "Fa", 251, _ky_f46)
  207. #define Key_f47 __TK ("kf47", "Fb", 252, _ky_f47)
  208. #define Key_f48 __TK ("kf48", "Fc", 253, _ky_f48)
  209. #define Key_f49 __TK ("kf49", "Fd", 254, _ky_f49)
  210. #define Key_f50 __TK ("kf50", "Fe", 255, _ky_f50)
  211. #define Key_f51 __TK ("kf51", "Ff", 256, _ky_f51)
  212. #define Key_f52 __TK ("kf52", "Fg", 257, _ky_f52)
  213. #define Key_f53 __TK ("kf53", "Fh", 258, _ky_f53)
  214. #define Key_f54 __TK ("kf54", "Fi", 259, _ky_f54)
  215. #define Key_f55 __TK ("kf55", "Fj", 260, _ky_f55)
  216. #define Key_f56 __TK ("kf56", "Fk", 261, _ky_f56)
  217. #define Key_f57 __TK ("kf57", "Fl", 262, _ky_f57)
  218. #define Key_f58 __TK ("kf58", "Fm", 263, _ky_f58)
  219. #define Key_f59 __TK ("kf59", "Fn", 264, _ky_f59)
  220. #define Key_f60 __TK ("kf60", "Fo", 265, _ky_f60)
  221. #define Key_f61 __TK ("kf61", "Fp", 266, _ky_f61)
  222. #define Key_f62 __TK ("kf62", "Fq", 267, _ky_f62)
  223. #define Key_f63 __TK ("kf63", "Fr", 268, _ky_f63)
  224. /* }}} */
  225. #ifdef HAVE_QNX_KEYS
  226. /* don't force pre-defining of base keys under QNX */
  227. #define FORCE_BASE_KEY_DEFS 0
  228. /* OS specific key aliases */
  229. #define Key_alt_a Key_clear
  230. #define Key_alt_b Key_stab
  231. #define Key_alt_c Key_close
  232. #define Key_alt_d Key_catab
  233. #define Key_alt_e Key_message
  234. #define Key_alt_f Key_find
  235. #define Key_alt_g Key_refresh
  236. #define Key_alt_h Key_help
  237. #define Key_alt_i Key_move
  238. #define Key_alt_j Key_restart
  239. #define Key_alt_k Key_options
  240. #define Key_alt_l Key_reference
  241. #define Key_alt_m Key_mark
  242. #define Key_alt_n Key_sbeg
  243. #define Key_alt_o Key_open
  244. #define Key_alt_p Key_resume
  245. #define Key_alt_q Key_save
  246. #define Key_alt_r Key_replace
  247. #define Key_alt_s Key_scopy
  248. #define Key_alt_t Key_screate
  249. #define Key_alt_u Key_undo
  250. #define Key_alt_v Key_sdl
  251. #define Key_alt_w Key_sexit
  252. #define Key_alt_x Key_sfind
  253. #define Key_alt_y Key_shelp
  254. #define Key_alt_z Key_soptions
  255. #define Key_ctl_enter Key_enter
  256. #define Key_ctl_tab Key_ctab
  257. #define Key_alt_tab Key_ctl_tab /* map ALT-TAB to CTRL-TAB */
  258. #define Key_alt_enter Key_ctl_enter /* map ALT-ENTER to CTRL-ENTER */
  259. #ifdef __USE_QNX_TI
  260. /* define current xtra_key_define_t (enable OS/implementation) */
  261. #define xtra_key_define_t qnx_key_define_t
  262. #endif /* __USE_QNX_TI */
  263. #endif /* HAVE_QNX_KEYS */
  264. #ifdef xtra_key_define_t
  265. #ifndef FORCE_BASE_KEY_DEFS
  266. #define FORCE_BASE_KEY_DEFS 0
  267. #endif
  268. #endif /* xtra_key_define_t */
  269. #ifdef HAVE_QNX_KEYS
  270. #ifdef __USE_QNX_TI
  271. #define __CT (__cur_term)
  272. #define __QTISOFFS(_qtisx) (((charoffset *) (&__CT->_strs))[_qtisx])
  273. #define __QTISSTR(_qtisx) (&__CT->_strtab[0] + __QTISOFFS (_qtisx))
  274. #endif /* __USE_QNX_TI */
  275. #endif /* HAVE_QNX_KEYS */
  276. /*** file scope type declarations ****************************************************************/
  277. #ifdef HAVE_QNX_KEYS
  278. #ifdef __USE_QNX_TI
  279. /* OS/implementation specific key-define struct */
  280. typedef const struct qnx_key_define_s
  281. {
  282. int mc_code;
  283. int str_idx;
  284. } qnx_key_define_t;
  285. #endif /* __USE_QNX_TI */
  286. #endif /* HAVE_QNX_KEYS */
  287. /*** file scope variables ************************************************************************/
  288. #ifdef xtra_key_define_t
  289. /* general key define table */
  290. xtra_key_define_t xtra_key_defines[] = {
  291. #if FORCE_BASE_KEY_DEFS
  292. { KEY_BACKSPACE, Key_backspace },
  293. { KEY_LEFT, Key_left },
  294. { KEY_RIGHT, Key_right },
  295. { KEY_UP, Key_up },
  296. { KEY_DOWN, Key_down },
  297. { KEY_NPAGE, Key_npage },
  298. { KEY_PPAGE, Key_ppage },
  299. { KEY_HOME, Key_home },
  300. { KEY_END, Key_end },
  301. { KEY_DC, Key_dc },
  302. { KEY_IC, Key_ic },
  303. { KEY_F (1), Key_f1 },
  304. { KEY_F (2), Key_f2 },
  305. { KEY_F (3), Key_f3 },
  306. { KEY_F (4), Key_f4 },
  307. { KEY_F (5), Key_f5 },
  308. { KEY_F (6), Key_f6 },
  309. { KEY_F (7), Key_f7 },
  310. { KEY_F (8), Key_f8 },
  311. { KEY_F (9), Key_f9 },
  312. { KEY_F (10), Key_f10 },
  313. { KEY_F (11), Key_f11 },
  314. { KEY_F (12), Key_f12 },
  315. { KEY_F (13), Key_f13 },
  316. { KEY_F (14), Key_f14 },
  317. { KEY_F (15), Key_f15 },
  318. { KEY_F (16), Key_f16 },
  319. { KEY_F (17), Key_f17 },
  320. { KEY_F (18), Key_f18 },
  321. { KEY_F (19), Key_f19 },
  322. { KEY_F (20), Key_f20 },
  323. #endif
  324. { ALT ('a'), Key_alt_a },
  325. { ALT ('b'), Key_alt_b },
  326. { ALT ('c'), Key_alt_c },
  327. { ALT ('d'), Key_alt_d },
  328. { ALT ('e'), Key_alt_e },
  329. { ALT ('f'), Key_alt_f },
  330. { ALT ('g'), Key_alt_g },
  331. { ALT ('h'), Key_alt_h },
  332. { ALT ('i'), Key_alt_i },
  333. { ALT ('j'), Key_alt_j },
  334. { ALT ('k'), Key_alt_k },
  335. { ALT ('l'), Key_alt_l },
  336. { ALT ('m'), Key_alt_m },
  337. { ALT ('n'), Key_alt_n },
  338. { ALT ('o'), Key_alt_o },
  339. { ALT ('p'), Key_alt_p },
  340. { ALT ('q'), Key_alt_q },
  341. { ALT ('r'), Key_alt_r },
  342. { ALT ('s'), Key_alt_s },
  343. { ALT ('t'), Key_alt_t },
  344. { ALT ('u'), Key_alt_u },
  345. { ALT ('v'), Key_alt_v },
  346. { ALT ('w'), Key_alt_w },
  347. { ALT ('x'), Key_alt_x },
  348. { ALT ('y'), Key_alt_y },
  349. { ALT ('z'), Key_alt_z },
  350. { ALT ('\n'), Key_alt_enter },
  351. { ALT ('\t'), Key_alt_tab }
  352. };
  353. #endif /* xtra_key_define_t */
  354. /*** file scope functions ************************************************************************/
  355. /* --------------------------------------------------------------------------------------------- */
  356. /* --------------------------------------------------------------------------------------------- */
  357. /*** public functions ****************************************************************************/
  358. /* --------------------------------------------------------------------------------------------- */
  359. #ifdef HAVE_QNX_KEYS
  360. #ifdef __USE_QNX_TI
  361. void
  362. load_qnx_key_defines (void)
  363. {
  364. static int _qnx_keys_defined = 0;
  365. if (!_qnx_keys_defined)
  366. {
  367. int idx;
  368. int term_setup_ok;
  369. __setupterm (NULL, fileno (stdout), &term_setup_ok);
  370. if (term_setup_ok != 1)
  371. return;
  372. for (idx = 0; idx < sizeof (xtra_key_defines) / sizeof (xtra_key_defines[0]); idx++)
  373. {
  374. int str_idx = xtra_key_defines[idx].str_idx;
  375. if (__QTISOFFS (str_idx))
  376. {
  377. if (*__QTISSTR (str_idx))
  378. {
  379. define_sequence (xtra_key_defines[idx].mc_code, __QTISSTR (str_idx),
  380. MCKEY_NOACTION);
  381. }
  382. }
  383. }
  384. _qnx_keys_defined = 1;
  385. }
  386. }
  387. #endif /* __USE_QNX_TI */
  388. #endif /* HAVE_QNX_KEYS */
  389. /* --------------------------------------------------------------------------------------------- */
  390. /* called from key.c/init_key() */
  391. void
  392. load_xtra_key_defines (void)
  393. {
  394. #ifdef HAVE_QNX_KEYS
  395. load_qnx_key_defines ();
  396. #endif
  397. }
  398. /* --------------------------------------------------------------------------------------------- */