slvideo.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326
  1. /* -*- mode: C; mode: fold -*- */
  2. /* Copyright (c) 1992, 1997, 2001, 2002 John E. Davis
  3. * This file is part of the S-Lang library.
  4. *
  5. * You may distribute under the terms of either the GNU General Public
  6. * License or the Perl Artistic License.
  7. */
  8. /* This file is best edited with a folding editor */
  9. #include "slinclud.h"
  10. #if !defined(__WIN32__) && !defined(__IBMC__)
  11. # include <dos.h>
  12. #endif
  13. #include "slang.h"
  14. #include "_slang.h"
  15. int SLtt_Term_Cannot_Insert;
  16. int SLtt_Term_Cannot_Scroll;
  17. int SLtt_Ignore_Beep = 3;
  18. int SLtt_Use_Ansi_Colors;
  19. int SLtt_Has_Status_Line = 0;
  20. int SLtt_Screen_Rows = 25;
  21. int SLtt_Screen_Cols = 80;
  22. int SLtt_Msdos_Cheap_Video = 0;
  23. void (*_SLtt_color_changed_hook)(void);
  24. /* This definition will need changing when SLsmg_Char_Type changes. */
  25. #define SLSMG_CHAR_TO_USHORT(x) ((unsigned short)(x))
  26. /*{{{ ------------- static local variables ---------- */
  27. static int Attribute_Byte;
  28. static int Scroll_r1 = 0, Scroll_r2 = 25;
  29. static int Cursor_Row = 1, Cursor_Col = 1;
  30. static int Current_Color;
  31. static int IsColor = 1;
  32. static int Blink_Killed = 1; /* high intensity background enabled */
  33. #define JMAX_COLORS 256
  34. #define JNORMAL_COLOR 0
  35. #define JNO_COLOR -1
  36. static unsigned char Color_Map [JMAX_COLORS] =
  37. {
  38. 0x7, 0x70, 0x70, 0x70, 0x70, 0x7, 0x7, 0x7,
  39. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  40. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  41. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  42. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  43. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  44. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  45. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  46. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  47. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  48. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  49. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  50. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  51. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  52. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  53. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  54. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  55. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  56. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  57. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  58. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  59. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  60. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  61. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  62. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  63. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  64. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  65. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  66. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  67. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  68. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
  69. 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7
  70. };
  71. #define JMAX_COLOR_NAMES 16
  72. static const char * const Color_Names [JMAX_COLOR_NAMES] =
  73. {
  74. "black", "blue", "green", "cyan",
  75. "red", "magenta", "brown", "lightgray",
  76. "gray", "brightblue", "brightgreen", "brightcyan",
  77. "brightred", "brightmagenta", "yellow", "white"
  78. };
  79. static void fixup_colors (void);
  80. /*}}}*/
  81. static void goto_rc_abs (int r, int c)
  82. {
  83. SLtt_goto_rc (r - Scroll_r1, c);
  84. }
  85. #if defined(__BORLANDC__) && defined(__MSDOS__)
  86. # define IBMPC_ASM_VIDEO 1
  87. #endif
  88. #if defined(__WATCOMC__) && !defined(__NT__) && !defined(__os2__)
  89. # define WATCOM_VIDEO 1
  90. #endif
  91. #if defined (__GO32__)
  92. # define GO32_VIDEO 1
  93. #endif
  94. #if defined (__EMX__) /* EMX video does both DOS & OS/2 */
  95. # define EMX_VIDEO 1
  96. #else
  97. # if defined(__os2__)
  98. # define OS2_VIDEO 1
  99. # endif
  100. #endif
  101. #if defined (__WIN32__)
  102. # define WIN32_VIDEO 1
  103. #endif
  104. /* The functions in these folds contain somewhat video system specific code
  105. * that if merged together into single functions will become a confusing
  106. * mess.
  107. */
  108. #ifdef IBMPC_ASM_VIDEO /*{{{*/
  109. # include <conio.h>
  110. # include <bios.h>
  111. # include <mem.h>
  112. /* buffer to hold a line of character/attribute pairs */
  113. #define MAXCOLS 256
  114. static unsigned char Line_Buffer [MAXCOLS*2];
  115. #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
  116. static unsigned char *Video_Base;
  117. # define MK_SCREEN_POINTER(row,col) ((unsigned short *)\
  118. (Video_Base +\
  119. 2 * (SLtt_Screen_Cols * (row)\
  120. + (col))))
  121. static int Video_Status_Port;
  122. # define MONO_STATUS 0x3BA
  123. # define CGA_STATUS 0x3DA
  124. # define CGA_SETMODE 0x3D8
  125. # define SNOW_CHECK \
  126. if (SLtt_Msdos_Cheap_Video)\
  127. { while ((inp (CGA_STATUS) & 0x08)); while (!(inp (CGA_STATUS) & 0x08)); }
  128. void SLtt_write_string (char *str)
  129. {
  130. /* FIXME: Priority=medium
  131. * This should not go to stdout. */
  132. fputs (str, stdout);
  133. }
  134. /* row is with respect to the scrolling region. */
  135. void SLtt_goto_rc (int r, int c)
  136. {
  137. union REGS regs;
  138. r += Scroll_r1;
  139. if (r > SLtt_Screen_Rows - 1) r = SLtt_Screen_Rows - 1;
  140. if (c > SLtt_Screen_Cols - 1) c = SLtt_Screen_Cols - 1;
  141. Cursor_Row = r;
  142. Cursor_Col = c;
  143. regs.h.dh = r;
  144. regs.h.dl = c;
  145. regs.h.bh = 0;
  146. regs.h.ah = 2;
  147. int86 (0x10, &regs, &regs);
  148. }
  149. static void asm_video_getxy (void)
  150. {
  151. asm mov ah, 3
  152. asm mov bh, 0
  153. asm int 10h
  154. asm xor ax, ax
  155. asm mov al, dh
  156. asm mov Cursor_Row, ax
  157. asm xor ax, ax
  158. asm mov al, dl
  159. asm mov Cursor_Col, ax
  160. }
  161. void SLtt_begin_insert (void)
  162. {
  163. unsigned short *p;
  164. int n;
  165. asm_video_getxy ();
  166. n = SLtt_Screen_Cols - Cursor_Col;
  167. p = MK_SCREEN_POINTER (Cursor_Row, SLtt_Screen_Cols - 1);
  168. SNOW_CHECK;
  169. asm mov ax, ds
  170. asm mov bx, di
  171. asm mov dx, si
  172. asm mov cx, n
  173. asm les di, p
  174. asm lds si, p
  175. asm sub si, 2
  176. asm std
  177. asm rep movsw
  178. asm mov ds, ax
  179. asm mov di, bx
  180. asm mov si, dx
  181. }
  182. void SLtt_end_insert (void)
  183. {
  184. }
  185. void SLtt_delete_char (void)
  186. {
  187. unsigned short *p;
  188. int n;
  189. asm_video_getxy ();
  190. n = SLtt_Screen_Cols - Cursor_Col - 1;
  191. p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
  192. SNOW_CHECK;
  193. asm mov ax, ds
  194. asm mov bx, si
  195. asm mov dx, di
  196. asm mov cx, n
  197. asm les di, p
  198. asm lds si, p
  199. asm add si, 2
  200. asm cld
  201. asm rep movsw
  202. asm mov ds, ax
  203. asm mov si, bx
  204. asm mov di, dx
  205. }
  206. void SLtt_erase_line (void)
  207. {
  208. unsigned short w, *p;
  209. p = MK_SCREEN_POINTER (Cursor_Row, 0);
  210. Attribute_Byte = 0x07;
  211. w = MK_SPACE_CHAR ();
  212. SNOW_CHECK;
  213. asm mov dx, di
  214. asm mov ax, w
  215. asm mov cx, SLtt_Screen_Cols
  216. asm les di, p
  217. asm cld
  218. asm rep stosw
  219. asm mov di, dx
  220. Current_Color = JNO_COLOR; /* since we messed with attribute byte */
  221. }
  222. void SLtt_delete_nlines (int nlines)
  223. {
  224. SLtt_normal_video ();
  225. /* This has the effect of pulling all lines below it up */
  226. asm mov ax, nlines
  227. asm mov ah, 6 /* int 6h */
  228. asm xor cx, cx
  229. asm mov ch, byte ptr Scroll_r1
  230. asm mov dx, SLtt_Screen_Cols
  231. asm dec dx
  232. asm mov dh, byte ptr Scroll_r2
  233. asm mov bh, byte ptr Attribute_Byte
  234. asm int 10h
  235. }
  236. void SLtt_reverse_index (int nlines)
  237. {
  238. SLtt_normal_video ();
  239. asm xor cx, cx
  240. asm mov ch, byte ptr Scroll_r1
  241. asm mov dx, SLtt_Screen_Cols
  242. asm dec dx
  243. asm mov dh, byte ptr Scroll_r2
  244. asm mov bh, byte ptr Attribute_Byte
  245. asm mov ah, 7
  246. asm mov al, byte ptr nlines
  247. asm int 10h
  248. }
  249. static void asm_video_invert_region (int top_row, int bot_row)
  250. {
  251. register unsigned short ch, sh;
  252. register unsigned short *pmin = MK_SCREEN_POINTER (top_row, 0);
  253. register unsigned short *pmax = MK_SCREEN_POINTER (bot_row, 0);
  254. while (pmin < pmax)
  255. {
  256. sh = *pmin;
  257. ch = sh;
  258. ch = ch ^ 0xFF00;
  259. *pmin = (ch & 0xFF00) | (sh & 0x00FF);
  260. pmin++;
  261. }
  262. }
  263. void SLtt_del_eol (void)
  264. {
  265. unsigned short *p;
  266. unsigned short w;
  267. int n;
  268. n = SLtt_Screen_Cols - Cursor_Col;
  269. p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
  270. if (Current_Color != JNO_COLOR) SLtt_normal_video ();
  271. w = MK_SPACE_CHAR ();
  272. SNOW_CHECK;
  273. asm mov dx, di
  274. asm les di, p
  275. asm mov ax, w
  276. asm mov cx, n
  277. asm cld
  278. asm rep stosw
  279. asm mov di, dx
  280. }
  281. static unsigned short *asm_video_write (register unsigned char *pp,
  282. register unsigned char *p,
  283. register unsigned short *pos)
  284. {
  285. int n = (int) (p - pp); /* num of characters of PP to write */
  286. asm push si
  287. asm push ds
  288. asm push di
  289. /* set up register for BOTH fast and slow */
  290. asm mov bx, SLtt_Msdos_Cheap_Video
  291. /* These are the registers needed for both fast AND slow */
  292. asm mov ah, byte ptr Attribute_Byte
  293. asm mov cx, n
  294. asm lds si, dword ptr pp
  295. asm les di, dword ptr pos
  296. asm cld
  297. asm cmp bx, 0 /* cheap video test */
  298. asm je L_fast
  299. asm mov bx, ax
  300. asm mov dx, CGA_STATUS
  301. asm jg L_slow_blank
  302. /* slow video */
  303. asm cli
  304. /* wait for retrace */
  305. L_slow:
  306. asm in al, dx
  307. asm test al, 1
  308. asm jnz L_slow
  309. L_slow1:
  310. asm in al, dx
  311. asm test al, 1
  312. asm jz L_slow1
  313. /* move a character out */
  314. asm mov ah, bh
  315. asm lodsb
  316. asm stosw
  317. asm loop L_slow
  318. asm sti
  319. asm jmp done
  320. /* -------------- slow video, vertical retace and pump --------------*/
  321. L_slow_blank:
  322. L_slow_blank_loop:
  323. asm in al, dx
  324. asm test al, 8
  325. asm jnz L_slow_blank_loop
  326. L_slow_blank1:
  327. asm in al, dx
  328. asm test al, 8
  329. asm jz L_slow_blank1
  330. /* write line */
  331. asm mov ah, bh
  332. L_slow_blank2:
  333. asm lodsb
  334. asm stosw
  335. asm loop L_slow_blank2
  336. asm jmp done
  337. /*-------------- Fast video --------------*/
  338. L_fast:
  339. asm lodsb
  340. asm stosw
  341. asm loop L_fast
  342. done:
  343. asm pop di
  344. asm pop ds
  345. asm pop si
  346. return (pos + n);
  347. }
  348. static void write_attributes (SLsmg_Char_Type *src, unsigned int count)
  349. {
  350. register unsigned char *p;
  351. register unsigned short pair;
  352. unsigned char ch, color;
  353. register unsigned short *pos;
  354. p = Line_Buffer;
  355. pos = MK_SCREEN_POINTER (Cursor_Row, 0);
  356. while (count--)
  357. {
  358. pair = SLSMG_CHAR_TO_USHORT(*src); /* character/color pair */
  359. src++;
  360. ch = pair & 0xff; /* character value */
  361. color = pair >> 8; /* color value */
  362. if (color != Current_Color) /* need a new color */
  363. {
  364. if (p != Line_Buffer)
  365. {
  366. pos = asm_video_write (Line_Buffer, p, pos);
  367. p = Line_Buffer;
  368. }
  369. SLtt_reverse_video (color); /* change color */
  370. }
  371. *(p++) = ch;
  372. }
  373. pos = asm_video_write (Line_Buffer, p, pos);
  374. }
  375. void SLtt_cls (void)
  376. {
  377. SLtt_normal_video ();
  378. asm mov dx, SLtt_Screen_Cols
  379. asm dec dx
  380. asm mov ax, SLtt_Screen_Rows
  381. asm dec ax
  382. asm mov dh, al
  383. asm xor cx, cx
  384. asm xor ax, ax
  385. asm mov ah, 7
  386. asm mov bh, byte ptr Attribute_Byte
  387. asm int 10h
  388. }
  389. void SLtt_putchar (char ch)
  390. {
  391. unsigned short p, *pp;
  392. if (Current_Color) SLtt_normal_video ();
  393. asm_video_getxy (); /* get current position */
  394. switch (ch)
  395. {
  396. case 7: /* ^G - break */
  397. SLtt_beep (); break;
  398. case 8: /* ^H - backspace */
  399. goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
  400. case 13: /* ^M - carriage return */
  401. goto_rc_abs (Cursor_Row, 0); break;
  402. default:
  403. /* write character to screen */
  404. pp = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
  405. p = (Attribute_Byte << 8) | (unsigned char) ch;
  406. SNOW_CHECK;
  407. *pp = p;
  408. goto_rc_abs (Cursor_Row, Cursor_Col + 1);
  409. }
  410. }
  411. void SLtt_get_screen_size (void)
  412. {
  413. int w, h;
  414. h = 0;
  415. /* Get BIOS's screenwidth, this works on ALL displays. */
  416. w = *((int *)MK_FP(0x40, 0x4a));
  417. /* Use Ralf Brown test for EGA or greater */
  418. asm mov ah, 12h
  419. asm mov bl, 10h
  420. asm mov bh, 0xFF /* EGA or greater will change this */
  421. asm int 10h
  422. asm cmp bh, 0xFF
  423. asm je L1
  424. /* if EGA or compatible: Get BIOS's number of rows. */
  425. h = *(char *)MK_FP(0x40, 0x84) + 1;
  426. /* scan_lines = *(int *) 0x485; */
  427. L1:
  428. if (h <= 0) h = 25;
  429. SLtt_Screen_Rows = h;
  430. SLtt_Screen_Cols = w;
  431. }
  432. void SLtt_get_terminfo (void)
  433. {
  434. SLtt_get_screen_size ();
  435. }
  436. /*----------------------------------------------------------------------*\
  437. * Function: int SLtt_init_video (void);
  438. \*----------------------------------------------------------------------*/
  439. int SLtt_init_video (void)
  440. {
  441. unsigned char *p;
  442. #ifdef HAS_SAVE_SCREEN
  443. save_screen ();
  444. #endif
  445. Cursor_Row = Cursor_Col = 0;
  446. p = (unsigned char far *) 0x00400049L;
  447. if (*p == 7)
  448. {
  449. Video_Status_Port = MONO_STATUS;
  450. Video_Base = (unsigned char *) MK_FP (0xb000,0000);
  451. IsColor = 0;
  452. }
  453. else
  454. {
  455. Video_Status_Port = CGA_STATUS;
  456. Video_Base = (unsigned char *) MK_FP (0xb800,0000);
  457. IsColor = 1;
  458. }
  459. /* test for video adapter type. Of primary interest is whether there is
  460. * snow or not. Assume snow if the card is color and not EGA or greater.
  461. */
  462. /* Use Ralf Brown test for EGA or greater */
  463. asm mov ah, 0x12
  464. asm mov bl, 0x10
  465. asm mov bh, 0xFF
  466. asm int 10h
  467. asm cmp bh, 0xFF
  468. asm je L1
  469. /* (V)EGA */
  470. asm xor bx, bx
  471. asm mov SLtt_Msdos_Cheap_Video, bx
  472. asm mov ax, Attribute_Byte
  473. asm cmp ax, bx
  474. asm jne L2
  475. asm mov ax, 0x17
  476. asm mov Attribute_Byte, ax
  477. asm jmp L2
  478. L1:
  479. /* Not (V)EGA */
  480. asm mov ah, 0x0F
  481. asm int 10h
  482. asm cmp al, 7
  483. asm je L3
  484. asm mov ax, 1
  485. asm mov SLtt_Msdos_Cheap_Video, ax
  486. L3:
  487. asm mov ax, Attribute_Byte
  488. asm cmp ax, 0
  489. asm jne L2
  490. asm mov ax, 0x07
  491. asm mov Attribute_Byte, ax
  492. L2:
  493. /* toggle the blink bit so we can use hi intensity background */
  494. if (IsColor && !SLtt_Msdos_Cheap_Video)
  495. {
  496. asm mov ax, 0x1003
  497. asm mov bx, 0
  498. asm int 0x10
  499. Blink_Killed = 1;
  500. }
  501. SLtt_Use_Ansi_Colors = IsColor;
  502. SLtt_get_screen_size ();
  503. SLtt_reset_scroll_region ();
  504. fixup_colors ();
  505. return 0;
  506. }
  507. void SLtt_beep (void)
  508. {
  509. int audible; /* audible bell */
  510. int special = 0; /* first row to invert */
  511. int visual = 0; /* final row to invert */
  512. if (!SLtt_Ignore_Beep) return;
  513. audible = (SLtt_Ignore_Beep & 1);
  514. if ( (SLtt_Ignore_Beep & 4) )
  515. {
  516. special = SLtt_Screen_Rows - 1;
  517. visual = special--; /* only invert bottom status line */
  518. }
  519. else if ( (SLtt_Ignore_Beep & 2) )
  520. {
  521. visual = SLtt_Screen_Rows;
  522. }
  523. if (visual) asm_video_invert_region (special, visual);
  524. if (audible) sound (1500); delay (100); if (audible) nosound ();
  525. if (visual) asm_video_invert_region (special, visual);
  526. }
  527. #endif /* IBMPC_ASM_VIDEO */
  528. /*}}}*/
  529. #ifdef GO32_VIDEO /*{{{*/
  530. # include <pc.h>
  531. # define HAS_SAVE_SCREEN 1
  532. # ifdef HAS_SAVE_SCREEN
  533. static void *Saved_Screen_Buffer;
  534. static int Saved_Cursor_Row;
  535. static void save_screen (void)
  536. {
  537. int row, col;
  538. SLfree ((char *) Saved_Screen_Buffer);
  539. Saved_Screen_Buffer = NULL;
  540. Saved_Screen_Buffer = (short *) SLmalloc (sizeof (short) *
  541. ScreenCols () * ScreenRows ());
  542. if (Saved_Screen_Buffer == NULL)
  543. return;
  544. ScreenRetrieve (Saved_Screen_Buffer);
  545. ScreenGetCursor (&row, &col);
  546. Saved_Cursor_Row = row;
  547. }
  548. static void restore_screen (void)
  549. {
  550. if (Saved_Screen_Buffer == NULL) return;
  551. ScreenUpdate (Saved_Screen_Buffer);
  552. goto_rc_abs (Saved_Cursor_Row, 0);
  553. }
  554. #endif /* HAS_SAVE_SCREEN */
  555. void SLtt_write_string (char *str)
  556. {
  557. while (Cursor_Col < SLtt_Screen_Cols)
  558. {
  559. char ch = *str++;
  560. if (ch == 0)
  561. break;
  562. ScreenPutChar (ch, Attribute_Byte, Cursor_Col, Cursor_Row);
  563. Cursor_Col++;
  564. }
  565. goto_rc_abs (Cursor_Row, Cursor_Col);
  566. }
  567. void SLtt_goto_rc (int row, int col)
  568. {
  569. row += Scroll_r1;
  570. if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
  571. if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
  572. ScreenSetCursor (row, col);
  573. Cursor_Row = row;
  574. Cursor_Col = col;
  575. }
  576. static void go32_video_getxy (void)
  577. {
  578. ScreenGetCursor (&Cursor_Row, &Cursor_Col);
  579. }
  580. static void go32_video_deleol (int x)
  581. {
  582. while (x < SLtt_Screen_Cols)
  583. ScreenPutChar (32, Attribute_Byte, x++, Cursor_Row);
  584. }
  585. void SLtt_begin_insert (void)
  586. {
  587. }
  588. void SLtt_end_insert (void)
  589. {
  590. }
  591. void SLtt_delete_char (void)
  592. {
  593. }
  594. void SLtt_erase_line (void)
  595. {
  596. Attribute_Byte = 0x07;
  597. go32_video_deleol (0);
  598. Current_Color = JNO_COLOR; /* since we messed with attribute byte */
  599. }
  600. void SLtt_delete_nlines (int nlines)
  601. {
  602. union REGS r;
  603. SLtt_normal_video ();
  604. r.x.ax = nlines;
  605. r.x.cx = 0;
  606. r.h.ah = 6;
  607. r.h.ch = Scroll_r1;
  608. r.h.dl = SLtt_Screen_Cols - 1;
  609. r.h.dh = Scroll_r2;
  610. r.h.bh = Attribute_Byte;
  611. int86 (0x10, &r, &r);
  612. }
  613. void SLtt_reverse_index (int nlines)
  614. {
  615. union REGS r;
  616. SLtt_normal_video ();
  617. r.h.al = nlines;
  618. r.x.cx = 0;
  619. r.h.ah = 7;
  620. r.h.ch = Scroll_r1;
  621. r.h.dl = SLtt_Screen_Cols - 1;
  622. r.h.dh = Scroll_r2;
  623. r.h.bh = Attribute_Byte;
  624. int86 (0x10, &r, &r);
  625. }
  626. static void go32_video_invert_region (int top_row, int bot_row)
  627. {
  628. unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */
  629. unsigned char *b, *bmax;
  630. b = buf + 1 + 2 * SLtt_Screen_Cols * top_row;
  631. bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row;
  632. ScreenRetrieve (buf);
  633. while (b < bmax)
  634. {
  635. *b ^= 0xFF;
  636. b += 2;
  637. }
  638. ScreenUpdate (buf);
  639. }
  640. void SLtt_beep (void)
  641. {
  642. int audible; /* audible bell */
  643. int special = 0; /* first row to invert */
  644. int visual = 0; /* final row to invert */
  645. if (!SLtt_Ignore_Beep) return;
  646. audible = (SLtt_Ignore_Beep & 1);
  647. if ( (SLtt_Ignore_Beep & 4) )
  648. {
  649. special = SLtt_Screen_Rows - 1;
  650. visual = special--; /* only invert bottom status line */
  651. }
  652. else if ( (SLtt_Ignore_Beep & 2) )
  653. {
  654. visual = SLtt_Screen_Rows;
  655. }
  656. if (visual) go32_video_invert_region (special, visual);
  657. if (audible) sound (1500); delay (100); if (audible) nosound ();
  658. if (visual) go32_video_invert_region (special, visual);
  659. }
  660. void SLtt_del_eol (void)
  661. {
  662. if (Current_Color != JNO_COLOR) SLtt_normal_video ();
  663. go32_video_deleol (Cursor_Col);
  664. }
  665. static void
  666. write_attributes (SLsmg_Char_Type *src, unsigned int count)
  667. {
  668. register unsigned short pair;
  669. unsigned int n;
  670. /* write into a character/attribute pair */
  671. n = Cursor_Col;
  672. while (count)
  673. {
  674. pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
  675. src++;
  676. SLtt_reverse_video (pair >> 8); /* color change */
  677. ScreenPutChar ((int)pair & 0xFF, Attribute_Byte, n, Cursor_Row);
  678. n++;
  679. count--;
  680. }
  681. }
  682. /*----------------------------------------------------------------------*\
  683. * Function: void SLtt_cls (void);
  684. \*----------------------------------------------------------------------*/
  685. void SLtt_cls (void)
  686. {
  687. SLtt_normal_video ();
  688. SLtt_reset_scroll_region ();
  689. SLtt_goto_rc (0, 0);
  690. SLtt_delete_nlines (SLtt_Screen_Rows);
  691. }
  692. void SLtt_putchar (char ch)
  693. {
  694. if (Current_Color) SLtt_normal_video ();
  695. go32_video_getxy (); /* get current position */
  696. switch (ch)
  697. {
  698. case 7: /* ^G - break */
  699. SLtt_beep (); break;
  700. case 8: /* ^H - backspace */
  701. goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
  702. case 13: /* ^M - carriage return */
  703. goto_rc_abs (Cursor_Row, 0); break;
  704. default: /* write character to screen */
  705. ScreenPutChar ((int) ch, Attribute_Byte, Cursor_Col, Cursor_Row);
  706. goto_rc_abs (Cursor_Row, Cursor_Col + 1);
  707. }
  708. }
  709. void SLtt_get_screen_size (void)
  710. {
  711. SLtt_Screen_Rows = ScreenRows ();
  712. SLtt_Screen_Cols = ScreenCols ();
  713. }
  714. void SLtt_get_terminfo (void)
  715. {
  716. SLtt_get_screen_size ();
  717. }
  718. int SLtt_init_video (void)
  719. {
  720. #ifdef HAS_SAVE_SCREEN
  721. save_screen ();
  722. #endif
  723. if (!Attribute_Byte) Attribute_Byte = 0x17;
  724. IsColor = 1; /* is it really? */
  725. if (IsColor)
  726. {
  727. union REGS r;
  728. r.x.ax = 0x1003; r.x.bx = 0;
  729. int86 (0x10, &r, &r);
  730. Blink_Killed = 1;
  731. }
  732. Cursor_Row = Cursor_Col = 0;
  733. SLtt_Term_Cannot_Insert = 1;
  734. SLtt_reset_scroll_region ();
  735. SLtt_Use_Ansi_Colors = IsColor;
  736. fixup_colors ();
  737. return 0;
  738. }
  739. #endif /* GO32_VIDEO */
  740. /*}}}*/
  741. #ifdef EMX_VIDEO /*{{{*/
  742. # define INCL_VIO
  743. # define INCL_DOSPROCESS
  744. # include <os2.h>
  745. # include <os2emx.h>
  746. # include <sys/video.h>
  747. static VIOMODEINFO vioModeInfo;
  748. /* buffer to hold a line of character/attribute pairs */
  749. #define MAXCOLS 256
  750. static unsigned char Line_Buffer [MAXCOLS*2];
  751. /* this is how to make a space character */
  752. #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
  753. void SLtt_write_string (char *str)
  754. {
  755. /* FIXME: Priority=medium
  756. * This should not go to stdout. */
  757. fputs (str, stdout);
  758. }
  759. void SLtt_goto_rc (int row, int col)
  760. {
  761. row += Scroll_r1;
  762. if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
  763. if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
  764. v_gotoxy (col, row);
  765. Cursor_Row = row;
  766. Cursor_Col = col;
  767. }
  768. static void emx_video_getxy (void)
  769. {
  770. v_getxy (&Cursor_Col, &Cursor_Row);
  771. }
  772. static void emx_video_deleol (int x)
  773. {
  774. unsigned char *p, *pmax;
  775. int count = SLtt_Screen_Cols - x;
  776. int w = MK_SPACE_CHAR ();
  777. p = Line_Buffer;
  778. pmax = p + 2 * count;
  779. while (p < pmax)
  780. {
  781. *p++ = (unsigned char) w;
  782. *p++ = (unsigned char) (w >> 8);
  783. }
  784. v_putline (Line_Buffer, x, Cursor_Row, count);
  785. }
  786. void SLtt_begin_insert (void)
  787. {
  788. int n;
  789. emx_video_getxy ();
  790. n = SLtt_Screen_Cols - Cursor_Col;
  791. v_getline (Line_Buffer, Cursor_Col, Cursor_Row, n);
  792. v_putline (Line_Buffer, Cursor_Col+1, Cursor_Row, n - 1);
  793. }
  794. void SLtt_end_insert (void)
  795. {
  796. }
  797. void SLtt_delete_char (void)
  798. {
  799. int n;
  800. emx_video_getxy ();
  801. n = SLtt_Screen_Cols - Cursor_Col - 1;
  802. v_getline (Line_Buffer, Cursor_Col+1, Cursor_Row, n);
  803. v_putline (Line_Buffer, Cursor_Col, Cursor_Row, n);
  804. }
  805. void SLtt_erase_line (void)
  806. {
  807. Attribute_Byte = 0x07;
  808. emx_video_deleol (0);
  809. Current_Color = JNO_COLOR; /* since we messed with attribute byte */
  810. }
  811. void SLtt_delete_nlines (int nlines)
  812. {
  813. SLtt_normal_video ();
  814. v_attrib (Attribute_Byte);
  815. v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines, V_SCROLL_UP);
  816. }
  817. void SLtt_reverse_index (int nlines)
  818. {
  819. SLtt_normal_video ();
  820. v_attrib (Attribute_Byte);
  821. v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines,
  822. V_SCROLL_DOWN);
  823. }
  824. static void emx_video_invert_region (int top_row, int bot_row)
  825. {
  826. int row, col;
  827. for (row = top_row; row < bot_row; row++)
  828. {
  829. v_getline (Line_Buffer, 0, row, SLtt_Screen_Cols);
  830. for (col = 1; col < SLtt_Screen_Cols * 2; col += 2)
  831. Line_Buffer [col] ^= 0xff;
  832. v_putline (Line_Buffer, 0, row, SLtt_Screen_Cols);
  833. }
  834. }
  835. void SLtt_beep (void)
  836. {
  837. int audible; /* audible bell */
  838. int special = 0; /* first row to invert */
  839. int visual = 0; /* final row to invert */
  840. if (!SLtt_Ignore_Beep) return;
  841. audible = (SLtt_Ignore_Beep & 1);
  842. if ( (SLtt_Ignore_Beep & 4) )
  843. {
  844. special = SLtt_Screen_Rows - 1;
  845. visual = special--; /* only invert bottom status line */
  846. }
  847. else if ( (SLtt_Ignore_Beep & 2) )
  848. {
  849. visual = SLtt_Screen_Rows;
  850. }
  851. if (visual) emx_video_invert_region (special, visual);
  852. if (audible) /*sound (1500)*/; _sleep2 (100); if (audible) /* nosound () */;
  853. if (visual) emx_video_invert_region (special, visual);
  854. }
  855. void SLtt_del_eol (void)
  856. {
  857. if (Current_Color != JNO_COLOR) SLtt_normal_video ();
  858. emx_video_deleol (Cursor_Col);
  859. }
  860. static void
  861. write_attributes (SLsmg_Char_Type *src, unsigned int count)
  862. {
  863. register unsigned char *p = Line_Buffer;
  864. register unsigned short pair;
  865. int n = count;
  866. /* write into a character/attribute pair */
  867. while (n-- > 0)
  868. {
  869. pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
  870. src++;
  871. SLtt_reverse_video (pair >> 8); /* color change */
  872. *(p++) = pair & 0xff; /* character byte */
  873. *(p++) = Attribute_Byte; /* attribute byte */
  874. }
  875. v_putline (Line_Buffer, Cursor_Col, Cursor_Row, count);
  876. }
  877. void SLtt_cls (void)
  878. {
  879. SLtt_normal_video ();
  880. SLtt_reset_scroll_region ();
  881. SLtt_goto_rc (0, 0);
  882. SLtt_delete_nlines (SLtt_Screen_Rows);
  883. }
  884. void SLtt_putchar (char ch)
  885. {
  886. if (Current_Color) SLtt_normal_video ();
  887. emx_video_getxy (); /* get current position */
  888. switch (ch)
  889. {
  890. case 7: /* ^G - break */
  891. SLtt_beep (); break;
  892. case 8: /* ^H - backspace */
  893. goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
  894. case 13: /* ^M - carriage return */
  895. goto_rc_abs (Cursor_Row, 0); break;
  896. default: /* write character to screen */
  897. v_putn (ch, 1);
  898. goto_rc_abs (Cursor_Row, Cursor_Col + 1);
  899. }
  900. }
  901. void SLtt_get_terminfo (void)
  902. {
  903. SLtt_get_screen_size ();
  904. }
  905. void SLtt_get_screen_size (void)
  906. {
  907. vioModeInfo.cb = sizeof(vioModeInfo);
  908. VioGetMode (&vioModeInfo, 0);
  909. SLtt_Screen_Cols = vioModeInfo.col;
  910. SLtt_Screen_Rows = vioModeInfo.row;
  911. }
  912. int SLtt_init_video (void)
  913. {
  914. int OldCol, OldRow;
  915. PTIB ptib;
  916. PPIB ppib;
  917. USHORT args[3] = { 6, 2, 1 };
  918. #ifdef HAS_SAVE_SCREEN
  919. save_screen ();
  920. #endif
  921. Cursor_Row = Cursor_Col = 0;
  922. v_init ();
  923. if ( v_hardware () != V_MONOCHROME ) IsColor = 1; else IsColor = 0;
  924. v_getxy(&OldCol,&OldRow);
  925. v_gotoxy (0, 0);
  926. if (IsColor)
  927. {
  928. if (_osmode == OS2_MODE)
  929. {
  930. # if 0
  931. /* Enable high-intensity background colors */
  932. VIOINTENSITY RequestBlock;
  933. RequestBlock.cb = sizeof (RequestBlock);
  934. RequestBlock.type = 2; RequestBlock.fs = 1;
  935. VioSetState (&RequestBlock, 0); /* nop if !fullscreen */
  936. # endif
  937. }
  938. }
  939. DosGetInfoBlocks (&ptib, &ppib);
  940. if ((ppib->pib_ultype) == 2) /* VIO */
  941. Blink_Killed = 1;
  942. else
  943. { /* Fullscreen */
  944. if (VioSetState (args, 0) == 0)
  945. Blink_Killed = 1;
  946. else
  947. Blink_Killed = 0;
  948. }
  949. if (!Attribute_Byte)
  950. {
  951. /* find the attribute currently under the cursor */
  952. v_getline (Line_Buffer, OldCol, OldRow, 1);
  953. Attribute_Byte = Line_Buffer[1];
  954. SLtt_set_color (JNORMAL_COLOR, NULL,
  955. Color_Names[(Attribute_Byte) & 0xf],
  956. Color_Names[(Attribute_Byte) >> 4]);
  957. }
  958. v_attrib (Attribute_Byte);
  959. fixup_colors ();
  960. SLtt_get_screen_size ();
  961. SLtt_Use_Ansi_Colors = IsColor;
  962. SLtt_reset_scroll_region ();
  963. return 0;
  964. }
  965. #endif /* EMX_VIDEO */
  966. /*}}}*/
  967. #ifdef WIN32_VIDEO /*{{{*/
  968. #include <windows.h>
  969. static HANDLE hStdout = INVALID_HANDLE_VALUE;
  970. #define MAXCOLS 256
  971. static CHAR_INFO Line_Buffer [MAXCOLS];
  972. void SLtt_write_string (char *str)
  973. {
  974. DWORD bytes;
  975. int n, c;
  976. if (str == NULL) return;
  977. n = (int) strlen (str);
  978. c = n + Cursor_Col;
  979. if (c >= SLtt_Screen_Cols)
  980. n = SLtt_Screen_Cols - Cursor_Col;
  981. if (n < 0) n = 0;
  982. (void) WriteConsole (hStdout, str, (unsigned int) n, &bytes, NULL);
  983. goto_rc_abs (Cursor_Row, Cursor_Col + n);
  984. }
  985. void SLtt_goto_rc (int row, int col)
  986. {
  987. COORD newPosition;
  988. row += Scroll_r1;
  989. if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
  990. if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
  991. newPosition.X = col;
  992. newPosition.Y = row;
  993. (void) SetConsoleCursorPosition(hStdout, newPosition);
  994. Cursor_Row = row;
  995. Cursor_Col = col;
  996. }
  997. static void win32_video_getxy (void)
  998. {
  999. CONSOLE_SCREEN_BUFFER_INFO screenInfo;
  1000. if (TRUE == GetConsoleScreenBufferInfo(hStdout, &screenInfo))
  1001. {
  1002. Cursor_Row = screenInfo.dwCursorPosition.Y;
  1003. Cursor_Col = screenInfo.dwCursorPosition.X;
  1004. }
  1005. }
  1006. static void win32_video_hscroll (int n)
  1007. {
  1008. SMALL_RECT rc;
  1009. COORD c;
  1010. CHAR_INFO ci;
  1011. WORD w = 227;
  1012. DWORD d;
  1013. win32_video_getxy ();
  1014. rc.Left = Cursor_Col;
  1015. rc.Right = SLtt_Screen_Cols;
  1016. rc.Top = rc.Bottom = Cursor_Row;
  1017. c.Y = Cursor_Row;
  1018. #if 1
  1019. c.X = SLtt_Screen_Cols - 1;
  1020. ReadConsoleOutputAttribute(hStdout, &w, 1, c, &d);
  1021. #else
  1022. /* New region gets the current color */
  1023. w = Attribute_Byte;
  1024. #endif
  1025. c.X = Cursor_Col + n;
  1026. ci.Char.AsciiChar = ' ';
  1027. ci.Attributes = w;
  1028. ScrollConsoleScreenBuffer(hStdout, &rc, &rc, c, &ci);
  1029. }
  1030. static void win32_video_deleol (int x)
  1031. {
  1032. DWORD d;
  1033. COORD c;
  1034. c.X = x;
  1035. c.Y = Cursor_Row;
  1036. x = SLtt_Screen_Cols - x;
  1037. FillConsoleOutputCharacter(hStdout, ' ', x, c, &d);
  1038. FillConsoleOutputAttribute(hStdout, (char)Attribute_Byte, x, c, &d);
  1039. }
  1040. static void win32_video_vscroll (int n)
  1041. {
  1042. SMALL_RECT rc, clip_rc;
  1043. COORD c;
  1044. CHAR_INFO ci;
  1045. SLtt_normal_video();
  1046. /* ScrollConsoleScreenBuffer appears to have a bug when
  1047. * Scroll_r1 == Scroll_r2. Sigh.
  1048. */
  1049. if (Scroll_r2 == Scroll_r1)
  1050. {
  1051. SLtt_goto_rc (0, 0);
  1052. win32_video_deleol (0);
  1053. return;
  1054. }
  1055. rc.Left = clip_rc.Left = 0;
  1056. rc.Right = clip_rc.Right = SLtt_Screen_Cols - 1;
  1057. rc.Top = clip_rc.Top = Scroll_r1;
  1058. rc.Bottom = clip_rc.Bottom = Scroll_r2;
  1059. c.X = 0;
  1060. c.Y = Scroll_r1 + n;
  1061. ci.Char.AsciiChar = ' ';
  1062. ci.Attributes = Attribute_Byte;
  1063. ScrollConsoleScreenBuffer(hStdout, &rc, &clip_rc, c, &ci);
  1064. }
  1065. void SLtt_begin_insert (void)
  1066. {
  1067. win32_video_hscroll (1);
  1068. }
  1069. void SLtt_end_insert (void)
  1070. {
  1071. }
  1072. void SLtt_delete_char (void)
  1073. {
  1074. win32_video_hscroll (-1);
  1075. }
  1076. void SLtt_erase_line (void)
  1077. {
  1078. Attribute_Byte = 0x7;
  1079. win32_video_deleol (0);
  1080. Current_Color = JNO_COLOR;
  1081. }
  1082. void SLtt_delete_nlines (int nlines)
  1083. {
  1084. win32_video_vscroll (-nlines);
  1085. }
  1086. void SLtt_reverse_index (int nlines)
  1087. {
  1088. win32_video_vscroll (nlines);
  1089. }
  1090. static void win32_invert_region (int top_row, int bot_row)
  1091. {
  1092. (void) top_row; (void) bot_row;
  1093. }
  1094. void SLtt_beep (void)
  1095. {
  1096. int audible; /* audible bell */
  1097. int special = 0; /* first row to invert */
  1098. int visual = 0; /* final row to invert */
  1099. if (!SLtt_Ignore_Beep) return;
  1100. audible = (SLtt_Ignore_Beep & 1);
  1101. if ( (SLtt_Ignore_Beep & 4) )
  1102. {
  1103. special = SLtt_Screen_Rows - 1;
  1104. visual = special--; /* only invert bottom status line */
  1105. }
  1106. else if ( (SLtt_Ignore_Beep & 2) )
  1107. {
  1108. visual = SLtt_Screen_Rows;
  1109. }
  1110. if (visual) win32_invert_region (special, visual);
  1111. if (audible) Beep (1500, 100); else Sleep (100);
  1112. if (visual) win32_invert_region (special, visual);
  1113. }
  1114. void SLtt_del_eol (void)
  1115. {
  1116. if (Current_Color != JNO_COLOR)
  1117. SLtt_normal_video ();
  1118. win32_video_deleol (Cursor_Col);
  1119. }
  1120. static void
  1121. write_attributes (SLsmg_Char_Type *src, unsigned int count)
  1122. {
  1123. unsigned short pair;
  1124. COORD coord, c;
  1125. CHAR_INFO *p;
  1126. unsigned int n;
  1127. SMALL_RECT rc;
  1128. /* write into a character/attribute pair */
  1129. n = count;
  1130. p = Line_Buffer;
  1131. while (n)
  1132. {
  1133. n--;
  1134. pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
  1135. src++;
  1136. SLtt_reverse_video (pair >> 8); /* color change */
  1137. p->Char.AsciiChar = pair & 0xff;
  1138. p->Attributes = Attribute_Byte;
  1139. p++;
  1140. }
  1141. c.X = count;
  1142. c.Y = 1;
  1143. coord.X = coord.Y = 0;
  1144. rc.Left = Cursor_Col;
  1145. rc.Right = Cursor_Col + count - 1;
  1146. rc.Top = rc.Bottom = Cursor_Row;
  1147. WriteConsoleOutput(hStdout, Line_Buffer, c, coord, &rc);
  1148. }
  1149. void SLtt_cls (void)
  1150. {
  1151. DWORD bytes;
  1152. COORD coord;
  1153. char ch;
  1154. SLtt_normal_video ();
  1155. /* clear the WIN32 screen in one shot */
  1156. coord.X = 0;
  1157. coord.Y = 0;
  1158. ch = ' ';
  1159. (void) FillConsoleOutputCharacter(hStdout,
  1160. ch,
  1161. SLtt_Screen_Cols * SLtt_Screen_Rows,
  1162. coord,
  1163. &bytes);
  1164. /* now set screen to the current attribute */
  1165. ch = Attribute_Byte;
  1166. (void) FillConsoleOutputAttribute(hStdout,
  1167. ch,
  1168. SLtt_Screen_Cols * SLtt_Screen_Rows,
  1169. coord,
  1170. &bytes);
  1171. }
  1172. void SLtt_putchar (char ch)
  1173. {
  1174. DWORD bytes;
  1175. WORD attr;
  1176. COORD c;
  1177. if (Current_Color) SLtt_normal_video ();
  1178. win32_video_getxy ();
  1179. switch (ch)
  1180. {
  1181. case 7: /* ^G - break */
  1182. SLtt_beep (); break;
  1183. case 8: /* ^H - backspace */
  1184. goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
  1185. case 13: /* ^M - carriage return */
  1186. goto_rc_abs (Cursor_Row, 0); break;
  1187. default: /* write character to screen */
  1188. c.X = Cursor_Col;
  1189. c.Y = Cursor_Row;
  1190. attr = Attribute_Byte;
  1191. WriteConsoleOutputCharacter(hStdout, &ch, 1, c, &bytes);
  1192. WriteConsoleOutputAttribute(hStdout, &attr, 1, c, &bytes);
  1193. goto_rc_abs (Cursor_Row, Cursor_Col + 1);
  1194. }
  1195. }
  1196. void SLtt_get_screen_size (void)
  1197. {
  1198. CONSOLE_SCREEN_BUFFER_INFO csbi;
  1199. HANDLE h;
  1200. h = hStdout;
  1201. if (h == INVALID_HANDLE_VALUE)
  1202. h = GetStdHandle (STD_OUTPUT_HANDLE);
  1203. if ((h == INVALID_HANDLE_VALUE)
  1204. || (FALSE == GetConsoleScreenBufferInfo(h, &csbi)))
  1205. {
  1206. SLang_exit_error ("Unable to determine the screen size");
  1207. return;
  1208. }
  1209. #if 0
  1210. SLtt_Screen_Rows = csbi.dwSize.Y;
  1211. SLtt_Screen_Cols = csbi.dwSize.X;
  1212. #else
  1213. SLtt_Screen_Rows = (csbi.srWindow.Bottom - csbi.srWindow.Top) + 1;
  1214. SLtt_Screen_Cols = (csbi.srWindow.Right - csbi.srWindow.Left) + 1;
  1215. #endif
  1216. }
  1217. void SLtt_get_terminfo (void)
  1218. {
  1219. SLtt_get_screen_size ();
  1220. }
  1221. static int win32_resize (void)
  1222. {
  1223. SMALL_RECT windowRect;
  1224. SLtt_get_screen_size ();
  1225. windowRect.Left = 0;
  1226. windowRect.Top = 0;
  1227. windowRect.Right = SLtt_Screen_Cols - 1;
  1228. windowRect.Bottom = SLtt_Screen_Rows - 1;
  1229. if (FALSE == SetConsoleWindowInfo(hStdout, TRUE, &windowRect))
  1230. return -1;
  1231. return 0;
  1232. }
  1233. static int win32_init (void)
  1234. {
  1235. SECURITY_ATTRIBUTES sec;
  1236. memset ((char *) &sec, 0, sizeof(SECURITY_ATTRIBUTES));
  1237. sec.nLength = sizeof (SECURITY_ATTRIBUTES);
  1238. sec.bInheritHandle = FALSE;
  1239. hStdout = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
  1240. FILE_SHARE_READ|FILE_SHARE_WRITE,
  1241. &sec,
  1242. CONSOLE_TEXTMODE_BUFFER,
  1243. 0);
  1244. if (hStdout == INVALID_HANDLE_VALUE)
  1245. return -1;
  1246. if ((FALSE == SetConsoleActiveScreenBuffer(hStdout))
  1247. || (FALSE == SetConsoleMode(hStdout, 0))
  1248. || (-1 == win32_resize ()))
  1249. {
  1250. SLtt_reset_video ();
  1251. return -1;
  1252. }
  1253. return 0;
  1254. }
  1255. int SLtt_init_video (void)
  1256. {
  1257. SLtt_reset_video ();
  1258. if (-1 == win32_init ())
  1259. return -1;
  1260. /* It is possible for SLtt_init_video to be called after suspension.
  1261. * For all I know, the window size may have changed. So, resize it
  1262. * now.
  1263. */
  1264. Cursor_Row = Cursor_Col = 0;
  1265. SLtt_Use_Ansi_Colors = IsColor = 1;
  1266. Blink_Killed = 1;
  1267. SLtt_reset_scroll_region ();
  1268. goto_rc_abs (0, 0);
  1269. fixup_colors ();
  1270. return 0;
  1271. }
  1272. int SLtt_reset_video (void)
  1273. {
  1274. if (hStdout == INVALID_HANDLE_VALUE)
  1275. return 0;
  1276. SLtt_reset_scroll_region ();
  1277. SLtt_goto_rc (SLtt_Screen_Rows - 1, 0);
  1278. Attribute_Byte = 0x7;
  1279. Current_Color = JNO_COLOR;
  1280. SLtt_del_eol ();
  1281. (void) CloseHandle (hStdout);
  1282. hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
  1283. if (hStdout != INVALID_HANDLE_VALUE)
  1284. (void) SetConsoleActiveScreenBuffer(hStdout);
  1285. hStdout = INVALID_HANDLE_VALUE;
  1286. return 0;
  1287. }
  1288. #endif
  1289. /*}}}*/
  1290. #ifdef OS2_VIDEO /*{{{*/
  1291. # define INCL_BASE
  1292. # define INCL_NOPM
  1293. # define INCL_VIO
  1294. # define INCL_KBD
  1295. # define INCL_DOSPROCESS
  1296. # include <os2.h>
  1297. # ifndef __IBMC__
  1298. # include <dos.h>
  1299. # endif
  1300. /* this is how to make a space character */
  1301. #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
  1302. /* buffer to hold a line of character/attribute pairs */
  1303. #define MAXCOLS 256
  1304. static unsigned char Line_Buffer [MAXCOLS*2];
  1305. void SLtt_write_string (char *str)
  1306. {
  1307. /* FIXME: Priority=medium
  1308. * This should not go to stdout. */
  1309. fputs (str, stdout);
  1310. }
  1311. void SLtt_goto_rc (int row, int col)
  1312. {
  1313. row += Scroll_r1;
  1314. VioSetCurPos (row, col, 0);
  1315. Cursor_Row = row;
  1316. Cursor_Col = col;
  1317. }
  1318. static void os2_video_getxy (void)
  1319. {
  1320. USHORT r, c;
  1321. VioGetCurPos (&r, &c, 0);
  1322. Cursor_Row = r;
  1323. Cursor_Col = c;
  1324. }
  1325. void SLtt_begin_insert (void)
  1326. {
  1327. USHORT n;
  1328. os2_video_getxy ();
  1329. n = SLtt_Screen_Cols - Cursor_Col;
  1330. n = 2 * (n - 1);
  1331. VioReadCellStr ((PCH)Line_Buffer, &n, Cursor_Row, Cursor_Col, 0);
  1332. VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col + 1, 0);
  1333. }
  1334. void SLtt_end_insert (void)
  1335. {
  1336. }
  1337. void SLtt_delete_char (void)
  1338. {
  1339. USHORT n;
  1340. os2_video_getxy ();
  1341. n = SLtt_Screen_Cols - Cursor_Col - 1;
  1342. n *= 2;
  1343. VioReadCellStr ((PCH)Line_Buffer, &n, Cursor_Row, Cursor_Col + 1, 0);
  1344. VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col, 0);
  1345. }
  1346. void SLtt_erase_line (void)
  1347. {
  1348. USHORT w;
  1349. Attribute_Byte = 0x07;
  1350. w = MK_SPACE_CHAR ();
  1351. VioWrtNCell ((BYTE*)&w, SLtt_Screen_Cols, Cursor_Row, 0, 0);
  1352. Current_Color = JNO_COLOR; /* since we messed with attribute byte */
  1353. }
  1354. void SLtt_delete_nlines (int nlines)
  1355. {
  1356. SLtt_normal_video ();
  1357. Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte;
  1358. VioScrollUp (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1,
  1359. nlines, (PCH) Line_Buffer, 0);
  1360. }
  1361. void SLtt_reverse_index (int nlines)
  1362. {
  1363. SLtt_normal_video ();
  1364. Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte;
  1365. VioScrollDn (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1,
  1366. nlines, (PCH) Line_Buffer, 0);
  1367. }
  1368. static void os2_video_invert_region (int top_row, int bot_row)
  1369. {
  1370. int row, col;
  1371. USHORT length = SLtt_Screen_Cols * 2;
  1372. for (row = top_row; row < bot_row; row++)
  1373. {
  1374. VioReadCellStr ((PCH)Line_Buffer, &length, row, 0, 0);
  1375. for (col = 1; col < length; col += 2)
  1376. Line_Buffer [col] ^= 0xff;
  1377. VioWrtCellStr ((PCH)Line_Buffer, length, row, 0, 0);
  1378. }
  1379. }
  1380. void SLtt_beep (void)
  1381. {
  1382. int audible; /* audible bell */
  1383. int special = 0; /* first row to invert */
  1384. int visual = 0; /* final row to invert */
  1385. if (!SLtt_Ignore_Beep) return;
  1386. audible = (SLtt_Ignore_Beep & 1);
  1387. if ( (SLtt_Ignore_Beep & 4) )
  1388. {
  1389. special = SLtt_Screen_Rows - 1;
  1390. visual = special--; /* only invert bottom status line */
  1391. }
  1392. else if ( (SLtt_Ignore_Beep & 2) )
  1393. {
  1394. visual = SLtt_Screen_Rows;
  1395. }
  1396. if (visual) os2_video_invert_region (special, visual);
  1397. if (audible) DosBeep (1500, 100); else DosSleep (100);
  1398. if (visual) os2_video_invert_region (special, visual);
  1399. }
  1400. void SLtt_del_eol (void)
  1401. {
  1402. USHORT w;
  1403. if (Current_Color != JNO_COLOR) SLtt_normal_video ();
  1404. w = MK_SPACE_CHAR ();
  1405. VioWrtNCell ((BYTE*)&w, (SLtt_Screen_Cols - Cursor_Col),
  1406. Cursor_Row, Cursor_Col, 0);
  1407. }
  1408. static void
  1409. write_attributes (SLsmg_Char_Type *src, unsigned int count)
  1410. {
  1411. register unsigned char *p = Line_Buffer;
  1412. register unsigned short pair;
  1413. int n = count;
  1414. /* write into a character/attribute pair */
  1415. while (n-- > 0)
  1416. {
  1417. pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
  1418. src++;
  1419. SLtt_reverse_video (pair >> 8); /* color change */
  1420. *(p++) = pair & 0xff; /* character byte */
  1421. *(p++) = Attribute_Byte; /* attribute byte */
  1422. }
  1423. VioWrtCellStr ((PCH)Line_Buffer, (USHORT)(2 * count),
  1424. (USHORT)Cursor_Row, (USHORT)Cursor_Col, 0);
  1425. }
  1426. void SLtt_cls (void)
  1427. {
  1428. SLtt_normal_video ();
  1429. Line_Buffer [0] = ' '; Line_Buffer [1] = Attribute_Byte;
  1430. VioScrollUp (0, 0, -1, -1, -1, (PCH)Line_Buffer, 0);
  1431. }
  1432. void SLtt_putchar (char ch)
  1433. {
  1434. unsigned short p, *pp;
  1435. if (Current_Color) SLtt_normal_video ();
  1436. os2_video_getxy (); /* get current position */
  1437. switch (ch)
  1438. {
  1439. case 7: /* ^G - break */
  1440. SLtt_beep (); break;
  1441. case 8: /* ^H - backspace */
  1442. goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
  1443. case 13: /* ^M - carriage return */
  1444. goto_rc_abs (Cursor_Row, 0); break;
  1445. default: /* write character to screen */
  1446. VioWrtCharStrAtt (&ch, 1, Cursor_Row, Cursor_Col,
  1447. (BYTE*)&Attribute_Byte, 0);
  1448. goto_rc_abs (Cursor_Row, Cursor_Col + 1);
  1449. }
  1450. }
  1451. void SLtt_get_screen_size (void)
  1452. {
  1453. #ifdef __os2__
  1454. # ifdef __IBMC__
  1455. VIOMODEINFO vioModeInfo;
  1456. # endif
  1457. vioModeInfo.cb = sizeof(vioModeInfo);
  1458. VioGetMode (&vioModeInfo, 0);
  1459. SLtt_Screen_Cols = vioModeInfo.col;
  1460. SLtt_Screen_Rows = vioModeInfo.row;
  1461. #endif
  1462. }
  1463. void SLtt_get_terminfo (void)
  1464. {
  1465. SLtt_get_screen_size ();
  1466. }
  1467. int SLtt_init_video (void)
  1468. {
  1469. VIOINTENSITY RequestBlock;
  1470. PTIB ptib;
  1471. PPIB ppib;
  1472. USHORT args[3] = { 6, 2, 1 };
  1473. Cursor_Row = Cursor_Col = 0;
  1474. IsColor = 1; /* is it really? */
  1475. /* Enable high-intensity background colors */
  1476. RequestBlock.cb = sizeof (RequestBlock);
  1477. RequestBlock.type = 2; RequestBlock.fs = 1;
  1478. VioSetState (&RequestBlock, 0); /* nop if !fullscreen */
  1479. DosGetInfoBlocks (&ptib, &ppib);
  1480. if ((ppib->pib_ultype) == 2) /* VIO */
  1481. Blink_Killed = 1;
  1482. else
  1483. { /* Fullscreen */
  1484. if (VioSetState (args, 0) == 0)
  1485. Blink_Killed = 1;
  1486. else
  1487. Blink_Killed = 0;
  1488. }
  1489. if (!Attribute_Byte)
  1490. {
  1491. /* find the attribute currently under the cursor */
  1492. USHORT len, r, c;
  1493. len = 2;
  1494. VioGetCurPos (&r, &c, 0);
  1495. VioReadCellStr ((PCH)Line_Buffer, &len, r, c, 0);
  1496. Attribute_Byte = Line_Buffer[1];
  1497. SLtt_set_color (JNORMAL_COLOR, NULL,
  1498. Color_Names[(Attribute_Byte) & 0xf],
  1499. Color_Names[(Attribute_Byte) >> 4]);
  1500. }
  1501. SLtt_Use_Ansi_Colors = IsColor;
  1502. SLtt_get_screen_size ();
  1503. SLtt_reset_scroll_region ();
  1504. fixup_colors ();
  1505. return 0;
  1506. }
  1507. #endif /* OS2_VIDEO */
  1508. /*}}}*/
  1509. #ifdef WATCOM_VIDEO /*{{{*/
  1510. # include <graph.h>
  1511. # define int86 int386 /* simplify code writing */
  1512. #include <dos.h>
  1513. /* this is how to make a space character */
  1514. #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
  1515. /* buffer to hold a line of character/attribute pairs */
  1516. #define MAXCOLS 256
  1517. static unsigned char Line_Buffer [MAXCOLS*2];
  1518. /* define for direct to memory screen writes */
  1519. static unsigned char *Video_Base;
  1520. #define MK_SCREEN_POINTER(row,col) \
  1521. ((unsigned short *)(Video_Base + 2 * (SLtt_Screen_Cols * (row) + (col))))
  1522. #define ScreenPrimary (0xb800 << 4)
  1523. #define ScreenSize (SLtt_Screen_Cols * SLtt_Screen_Rows)
  1524. #define ScreenSetCursor(x,y) _settextposition (x+1,y+1)
  1525. void ScreenGetCursor (int *x, int *y)
  1526. {
  1527. struct rccoord rc = _gettextposition ();
  1528. *x = rc.row - 1;
  1529. *y = rc.col - 1;
  1530. }
  1531. void ScreenRetrieve (unsigned char *dest)
  1532. {
  1533. memcpy (dest, (unsigned char *) ScreenPrimary, 2 * ScreenSize);
  1534. }
  1535. void ScreenUpdate (unsigned char *src)
  1536. {
  1537. memcpy ((unsigned char *) ScreenPrimary, src, 2 * ScreenSize);
  1538. }
  1539. void SLtt_write_string (char *str)
  1540. {
  1541. /* FIXME: Priority=medium
  1542. * This should not go to stdout. */
  1543. fputs (str, stdout);
  1544. }
  1545. void SLtt_goto_rc (int row, int col)
  1546. {
  1547. row += Scroll_r1;
  1548. if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
  1549. if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
  1550. ScreenSetCursor(row, col);
  1551. Cursor_Row = row;
  1552. Cursor_Col = col;
  1553. }
  1554. static void watcom_video_getxy (void)
  1555. {
  1556. ScreenGetCursor (&Cursor_Row, &Cursor_Col);
  1557. }
  1558. void SLtt_begin_insert (void)
  1559. {
  1560. unsigned short *p;
  1561. unsigned short *pmin;
  1562. int n;
  1563. watcom_video_getxy ();
  1564. n = SLtt_Screen_Cols - Cursor_Col;
  1565. p = MK_SCREEN_POINTER (Cursor_Row, SLtt_Screen_Cols - 1);
  1566. pmin = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
  1567. while (p-- > pmin) *(p + 1) = *p;
  1568. }
  1569. void SLtt_end_insert (void)
  1570. {
  1571. }
  1572. void SLtt_delete_char (void)
  1573. {
  1574. unsigned short *p;
  1575. register unsigned short *p1;
  1576. int n;
  1577. watcom_video_getxy ();
  1578. n = SLtt_Screen_Cols - Cursor_Col - 1;
  1579. p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
  1580. while (n--)
  1581. {
  1582. p1 = p + 1;
  1583. *p = *p1;
  1584. p++;
  1585. }
  1586. }
  1587. void SLtt_erase_line (void)
  1588. {
  1589. unsigned short w;
  1590. unsigned short *p = MK_SCREEN_POINTER (Cursor_Row, 0);
  1591. register unsigned short *pmax = p + SLtt_Screen_Cols;
  1592. Attribute_Byte = 0x07;
  1593. w = MK_SPACE_CHAR ();
  1594. while (p < pmax) *p++ = w;
  1595. Current_Color = JNO_COLOR; /* since we messed with attribute byte */
  1596. }
  1597. void SLtt_delete_nlines (int nlines)
  1598. {
  1599. union REGS r;
  1600. SLtt_normal_video ();
  1601. r.x.eax = nlines;
  1602. r.x.ecx = 0;
  1603. r.h.ah = 6;
  1604. r.h.ch = Scroll_r1;
  1605. r.h.dl = SLtt_Screen_Cols - 1;
  1606. r.h.dh = Scroll_r2;
  1607. r.h.bh = Attribute_Byte;
  1608. int86 (0x10, &r, &r);
  1609. }
  1610. void SLtt_reverse_index (int nlines)
  1611. {
  1612. union REGS r;
  1613. SLtt_normal_video ();
  1614. r.h.al = nlines;
  1615. r.x.ecx = 0;
  1616. r.h.ah = 7;
  1617. r.h.ch = Scroll_r1;
  1618. r.h.dl = SLtt_Screen_Cols - 1;
  1619. r.h.dh = Scroll_r2;
  1620. r.h.bh = Attribute_Byte;
  1621. int86 (0x10, &r, &r);
  1622. }
  1623. static void watcom_video_invert_region (int top_row, int bot_row)
  1624. {
  1625. unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */
  1626. unsigned char *b, *bmax;
  1627. b = buf + 1 + 2 * SLtt_Screen_Cols * top_row;
  1628. bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row;
  1629. ScreenRetrieve (buf);
  1630. while (b < bmax)
  1631. {
  1632. *b ^= 0xFF;
  1633. b += 2;
  1634. }
  1635. ScreenUpdate (buf);
  1636. }
  1637. void SLtt_beep (void)
  1638. {
  1639. int audible; /* audible bell */
  1640. int special = 0; /* first row to invert */
  1641. int visual = 0; /* final row to invert */
  1642. if (!SLtt_Ignore_Beep) return;
  1643. audible = (SLtt_Ignore_Beep & 1);
  1644. if ( (SLtt_Ignore_Beep & 4) )
  1645. {
  1646. special = SLtt_Screen_Rows - 1;
  1647. visual = special--; /* only invert bottom status line */
  1648. }
  1649. else if ( (SLtt_Ignore_Beep & 2) )
  1650. {
  1651. visual = SLtt_Screen_Rows;
  1652. }
  1653. if (visual) watcom_video_invert_region (special, visual);
  1654. if (audible) sound (1500); delay (100); if (audible) nosound ();
  1655. if (visual) watcom_video_invert_region (special, visual);
  1656. }
  1657. void SLtt_del_eol (void)
  1658. {
  1659. unsigned short *p, *pmax;
  1660. unsigned short w;
  1661. int n;
  1662. n = SLtt_Screen_Cols - Cursor_Col;
  1663. p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
  1664. pmax = p + n;
  1665. if (Current_Color != JNO_COLOR) SLtt_normal_video ();
  1666. w = MK_SPACE_CHAR ();
  1667. while (p < pmax) *p++ = w;
  1668. }
  1669. static void
  1670. write_attributes (SLsmg_Char_Type *src, unsigned int count)
  1671. {
  1672. register unsigned short pair;
  1673. register unsigned short *pos = MK_SCREEN_POINTER (Cursor_Row, 0);
  1674. /* write into a character/attribute pair */
  1675. while (count--)
  1676. {
  1677. pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
  1678. src++;
  1679. SLtt_reverse_video (pair >> 8); /* color change */
  1680. *(pos++) = ((unsigned short) Attribute_Byte << 8) | (pair & 0xff);
  1681. }
  1682. }
  1683. void SLtt_cls (void)
  1684. {
  1685. SLtt_normal_video ();
  1686. SLtt_reset_scroll_region ();
  1687. SLtt_goto_rc (0, 0);
  1688. SLtt_delete_nlines (SLtt_Screen_Rows);
  1689. }
  1690. void SLtt_putchar (char ch)
  1691. {
  1692. unsigned short p, *pp;
  1693. if (Current_Color) SLtt_normal_video ();
  1694. watcom_video_getxy ();
  1695. switch (ch)
  1696. {
  1697. case 7: /* ^G - break */
  1698. SLtt_beep (); break;
  1699. case 8: /* ^H - backspace */
  1700. goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
  1701. case 13: /* ^M - carriage return */
  1702. goto_rc_abs (Cursor_Row, 0); break;
  1703. default: /* write character to screen */
  1704. p = (Attribute_Byte << 8) | (unsigned char) ch;
  1705. pp = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
  1706. *pp = p;
  1707. goto_rc_abs (Cursor_Row, Cursor_Col + 1);
  1708. }
  1709. }
  1710. void SLtt_get_screen_size (void)
  1711. {
  1712. struct videoconfig vc;
  1713. _getvideoconfig(&vc);
  1714. SLtt_Screen_Rows = vc.numtextrows;
  1715. SLtt_Screen_Cols = vc.numtextcols;
  1716. }
  1717. void SLtt_get_terminfo (void)
  1718. {
  1719. SLtt_get_screen_size ();
  1720. }
  1721. int SLtt_init_video (void)
  1722. {
  1723. #ifdef HAS_SAVE_SCREEN
  1724. save_screen ();
  1725. #endif
  1726. Cursor_Row = Cursor_Col = 0;
  1727. Video_Base = (unsigned char *) ScreenPrimary;
  1728. if (!Attribute_Byte) Attribute_Byte = 0x17;
  1729. IsColor = 1; /* is it really? */
  1730. if (IsColor)
  1731. {
  1732. union REGS r;
  1733. r.x.eax = 0x1003; r.x.ebx = 0;
  1734. int86 (0x10, &r, &r);
  1735. Blink_Killed = 1;
  1736. }
  1737. SLtt_Use_Ansi_Colors = IsColor;
  1738. SLtt_get_screen_size ();
  1739. SLtt_reset_scroll_region ();
  1740. fixup_colors ();
  1741. return 0;
  1742. }
  1743. #endif /* WATCOM_VIDEO */
  1744. /*}}}*/
  1745. /* -------------------------------------------------------------------------*\
  1746. * The rest of the functions are, for the most part, independent of a specific
  1747. * video system.
  1748. \* ------------------------------------------------------------------------ */
  1749. /*----------------------------------------------------------------------*\
  1750. * Function: void SLtt_set_scroll_region (int r1, int r2);
  1751. *
  1752. * define a scroll region of top_row to bottom_row
  1753. \*----------------------------------------------------------------------*/
  1754. void SLtt_set_scroll_region (int top_row, int bottom_row)
  1755. {
  1756. Scroll_r1 = top_row;
  1757. Scroll_r2 = bottom_row;
  1758. }
  1759. /*----------------------------------------------------------------------*\
  1760. * Function: void SLtt_reset_scroll_region (void);
  1761. *
  1762. * reset the scrol region to be the entire screen,
  1763. * ie, SLtt_set_scroll_region (0, SLtt_Screen_Rows);
  1764. \*----------------------------------------------------------------------*/
  1765. void SLtt_reset_scroll_region (void)
  1766. {
  1767. Scroll_r1 = 0;
  1768. Scroll_r2 = SLtt_Screen_Rows - 1;
  1769. }
  1770. /*----------------------------------------------------------------------*\
  1771. * Function: int SLtt_flush_output (void);
  1772. \*----------------------------------------------------------------------*/
  1773. int SLtt_flush_output (void)
  1774. {
  1775. #if defined(WIN32_VIDEO)
  1776. return 0;
  1777. #else
  1778. /* FIXME: Priority=medium
  1779. * This should not go to stdout. */
  1780. fflush (stdout);
  1781. return 0;
  1782. #endif
  1783. }
  1784. int SLtt_set_cursor_visibility (int show)
  1785. {
  1786. #if defined(WIN32_VIDEO)
  1787. CONSOLE_CURSOR_INFO c;
  1788. if (0 == GetConsoleCursorInfo (hStdout, &c))
  1789. return -1;
  1790. c.bVisible = (show ? TRUE: FALSE);
  1791. if (0 == SetConsoleCursorInfo (hStdout, &c))
  1792. return -1;
  1793. return 0;
  1794. #else
  1795. (void) show;
  1796. return -1;
  1797. #endif
  1798. }
  1799. void SLtt_set_mono (int obj_unused, char *unused, SLtt_Char_Type c_unused)
  1800. {
  1801. (void) obj_unused;
  1802. (void) unused;
  1803. (void) c_unused;
  1804. }
  1805. /*----------------------------------------------------------------------*\
  1806. * Function: void SLtt_reverse_video (int color);
  1807. *
  1808. * set Attribute_Byte corresponding to COLOR.
  1809. * Use Current_Color to remember the color which was set.
  1810. * convert from the COLOR number to the attribute value.
  1811. \*----------------------------------------------------------------------*/
  1812. void SLtt_reverse_video (int color)
  1813. {
  1814. if ((color >= JMAX_COLORS) || (color < 0))
  1815. return;
  1816. Attribute_Byte = Color_Map [color];
  1817. Current_Color = color;
  1818. }
  1819. /*----------------------------------------------------------------------*\
  1820. * Function: void SLtt_normal_video (void);
  1821. *
  1822. * reset the attributes for normal video
  1823. \*----------------------------------------------------------------------*/
  1824. void SLtt_normal_video (void)
  1825. {
  1826. SLtt_reverse_video (JNORMAL_COLOR);
  1827. }
  1828. /*----------------------------------------------------------------------*\
  1829. * Function: void SLtt_smart_puts (SLsmg_Char_Type *new_string,
  1830. * SLsmg_Char_Type *old_string,
  1831. * int len, int row);
  1832. *
  1833. * puts NEW_STRING, which has length LEN, at row ROW. NEW_STRING contains
  1834. * characters/colors packed in the form value = ((color << 8) | (ch));
  1835. *
  1836. * the puts tries to avoid overwriting the same characters/colors
  1837. *
  1838. * OLD_STRING is not used, maintained for compatibility with other systems
  1839. \*----------------------------------------------------------------------*/
  1840. void SLtt_smart_puts (SLsmg_Char_Type *new_string,
  1841. SLsmg_Char_Type *old_string,
  1842. int len, int row)
  1843. {
  1844. (void) old_string;
  1845. Cursor_Row = row;
  1846. Cursor_Col = 0;
  1847. write_attributes (new_string, len);
  1848. }
  1849. /*----------------------------------------------------------------------*\
  1850. * Function: int SLtt_reset_video (void);
  1851. \*----------------------------------------------------------------------*/
  1852. #ifndef WIN32_VIDEO
  1853. int SLtt_reset_video (void)
  1854. {
  1855. SLtt_reset_scroll_region ();
  1856. SLtt_goto_rc (SLtt_Screen_Rows - 1, 0);
  1857. #ifdef HAS_SAVE_SCREEN
  1858. restore_screen ();
  1859. #endif
  1860. Attribute_Byte = 0x07;
  1861. Current_Color = JNO_COLOR;
  1862. SLtt_del_eol ();
  1863. return 0;
  1864. }
  1865. #endif
  1866. /*----------------------------------------------------------------------*\
  1867. * Function: void SLtt_set_color (int obj, char *what, char *fg, char *bg);
  1868. *
  1869. * set foreground and background colors of OBJ to the attributes which
  1870. * correspond to the names FG and BG, respectively.
  1871. *
  1872. * WHAT is the name corresponding to the object OBJ, but is not used in
  1873. * this routine.
  1874. \*----------------------------------------------------------------------*/
  1875. void SLtt_set_color (int obj, char *what, char *fg, char *bg)
  1876. {
  1877. int i, b = 0, f = 7;
  1878. (void) what;
  1879. if ((obj < 0) || (obj >= JMAX_COLORS))
  1880. return;
  1881. for (i = 0; i < JMAX_COLOR_NAMES; i++ )
  1882. {
  1883. if (!strcmp (fg, Color_Names [i]))
  1884. {
  1885. f = i;
  1886. break;
  1887. }
  1888. }
  1889. for (i = 0; i < JMAX_COLOR_NAMES; i++)
  1890. {
  1891. if (!strcmp (bg, Color_Names [i]))
  1892. {
  1893. if (Blink_Killed) b = i; else b = i & 0x7;
  1894. break;
  1895. }
  1896. }
  1897. if (f == b) return;
  1898. Color_Map [obj] = (b << 4) | f;
  1899. /* if we're setting the normal color, and the attribute byte hasn't
  1900. been set yet, set it to the new color */
  1901. if ((obj == 0) && (Attribute_Byte == 0))
  1902. SLtt_reverse_video (0);
  1903. if (_SLtt_color_changed_hook != NULL)
  1904. (*_SLtt_color_changed_hook)();
  1905. }
  1906. static void fixup_colors (void)
  1907. {
  1908. unsigned int i;
  1909. if (Blink_Killed)
  1910. return;
  1911. for (i = 0; i < JMAX_COLORS; i++)
  1912. Color_Map[i] &= 0x7F;
  1913. SLtt_normal_video ();
  1914. }