minitel.c
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 49k
Category:

Windows Develop

Development Platform:

Visual C++

  1. /* File: D:wackeremuminitel.c (Created: 05-Mar-1994)
  2.  *
  3.  * Copyright 1994, 1998 by Hilgraeve Inc. -- Monroe, MI
  4.  * All rights reserved
  5.  *
  6.  * $Revision: 2 $
  7.  * $Date: 2/05/99 3:20p $
  8.  */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. #include <time.h>
  12. #include <tdllstdtyp.h>
  13. #include <tdlltdll.h>
  14. #include <tdllsession.h>
  15. #include <tdllcloop.h>
  16. #include <tdllprint.h>
  17. #include <tdllcapture.h>
  18. #include <tdllassert.h>
  19. #include <tdllmc.h>
  20. #include <tdllupdate.h>
  21. #include <tdllchars.h>
  22. #include <tdllcnct.h>
  23. #include <tdllterm.h>
  24. #include <tdllbackscrl.h>
  25. #include <tdlltchar.h>
  26. #include <termres.h>
  27. #include "emu.h"
  28. #include "emu.hh"
  29. #include "emuid.h"
  30. #include "minitel.hh"
  31. #include "keytbls.h"
  32. #if defined(INCL_MINITEL)
  33. static void emuMinitelRedisplayLine(const HHEMU hhEmu,
  34. const int row,
  35. const int col);
  36. static int minitel_kbdin(const HHEMU hhEmu, int key, const int fTest);
  37. static ECHAR minitelMapMosaics(const HHEMU hhEmu, ECHAR ch);
  38. static void minitelFullScrnReveal(const HHEMU hhEmu);
  39. static void minitelFullScrnConceal(const HHEMU hhEmu);
  40. static void minitelSS2(const HHEMU hhEmu);
  41. static void minitelSS2Part2(const HHEMU hhEmu);
  42. static void minitelInsMode(const HHEMU hhEmu);
  43. static void minitelPRO1(const HHEMU hhEmu);
  44. static void minitelPRO2Part1(const HHEMU hhEmu);
  45. static void minitelPRO2Part2(const HHEMU hhEmu);
  46. static void minitelStatusReply(const HHEMU hhEmu);
  47. /*
  48. Here begins the famed and fabled Minitel emulator. Abandon all hope
  49. all ye who..., well you get the idea.  The Minitel emulator uses a
  50. combination of character attributes and field attributes.  See the
  51. book "minitel 1B" for description of field attributes. Page numbers
  52. referenced in this code refer to the before mentioned book. - mrw
  53. */
  54. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  55.  * FUNCTION:
  56.  * emuMinitelInit
  57.  *
  58.  * DESCRIPTION:
  59.  * Startup routine for the minitel emulator.
  60.  *
  61.  * ARGUMENTS:
  62.  * hhEmu - private emulator handle.
  63.  *
  64.  * RETURNS:
  65.  * void
  66.  *
  67.  */
  68. void emuMinitelInit(const HHEMU hhEmu)
  69. {
  70. int i;
  71. LOGFONT lf;
  72. HWND hwndTerm;
  73. PSTMTPRIVATE pstPRI;
  74. static struct trans_entry const minitel_tbl[] =
  75. {
  76. {NEW_STATE, 0, 0, 0}, // 0
  77. {0, ETEXT('x00'), ETEXT('x01'), nothing},
  78. {0, ETEXT('x20'), ETEXT('x7F'), minitelGraphic},
  79. {1, ETEXT('x1B'), ETEXT('x1B'), nothing},
  80. {0, ETEXT('x07'), ETEXT('x07'), emu_bell},
  81. {0, ETEXT('b'),   ETEXT('b'), minitelBackspace},
  82. {0, ETEXT('t'),   ETEXT('t'), minitelHorzTab},
  83. {0, ETEXT('n'),   ETEXT('n'), minitelLinefeed},
  84. {0, ETEXT('x0B'), ETEXT('x0B'), minitelVerticalTab},
  85. {0, ETEXT('x0C'), ETEXT('x0C'), minitelFormFeed},
  86. {0, ETEXT('r'),   ETEXT('r'), carriagereturn},
  87. {0, ETEXT('x0E'), ETEXT('x0F'), minitelCharSet},  // change char set
  88. {0, ETEXT('x11'), ETEXT('x11'), minitelCursorOn}, // cursor on
  89. {5, ETEXT('x12'), ETEXT('x12'), nothing},   // repeat
  90. {12,ETEXT('x13'), ETEXT('x13'), nothing},   // SEP
  91. {0, ETEXT('x14'), ETEXT('x14'), minitelCursorOff},// cursor off
  92. {20,ETEXT('x16'), ETEXT('x16'), nothing},   // SS2 (undocumented)
  93. {0, ETEXT('x18'), ETEXT('x18'), minitelCancel},   // cancel
  94. {20,ETEXT('x19'), ETEXT('x19'), nothing},    // SS2
  95. {0, ETEXT('x1C'), ETEXT('x1C'), nothing}, // really is nothing.
  96. {13,ETEXT('x1D'), ETEXT('x1D'), nothing}, // SS3,X ingnored, p99, 1.2.7
  97. {0, ETEXT('x1E'), ETEXT('x1E'), minitelRecordSeparator},
  98. {3, ETEXT('x1F'), ETEXT('x1F'), nothing}, // Unit Seperator
  99. //{0, ETEXT('x7F'), ETEXT('x7F'), minitelDel},
  100. {NEW_STATE, 0, 0, 0}, // 1 - seen ESC
  101. {1, ETEXT('x00'), ETEXT('x00'), nothing},
  102. {0, ETEXT('x01'), ETEXT('x1F'), minitelResync},
  103. {18,ETEXT('x23'), ETEXT('x23'), nothing},
  104. {14,ETEXT('x25'), ETEXT('x25'), nothing},
  105. {13,ETEXT('x35'), ETEXT('x37'), nothing}, // eat ESC,35-37,X sequences
  106. {6, ETEXT('x39'), ETEXT('x39'), nothing}, // PROT1, p134
  107. {7, ETEXT('x3A'), ETEXT('x3A'), nothing}, // PROT2, p134
  108. {8, ETEXT('x3B'), ETEXT('x3B'), nothing}, // PROT3, p134
  109. {2, ETEXT('x5B'), ETEXT('x5B'), ANSI_Pn_Clr},
  110. {0, ETEXT('x40'), ETEXT('x49'), emuMinitelCharAttr}, // forground color, flashing
  111. {0, ETEXT('x4C'), ETEXT('x4F'), emuMinitelCharAttr}, // char width & height
  112. {0, ETEXT('x50'), ETEXT('x5A'), emuMinitelFieldAttr},// background, underlining
  113. {0, ETEXT('x5F'), ETEXT('x5F'), emuMinitelFieldAttr},// reveal display
  114. {0, ETEXT('x5C'), ETEXT('x5D'), emuMinitelCharAttr}, // inverse
  115. {0, ETEXT('x61'), ETEXT('x61'), minitelCursorReport},
  116. {22,ETEXT('x20'), ETEXT('x2F'), nothing}, // p.99 ISO 2022
  117. {NEW_STATE, 0, 0, 0}, // 2 - seen ESC [
  118. {2, ETEXT('x00'), ETEXT('x00'), nothing},
  119. {2, ETEXT('x30'), ETEXT('x39'), ANSI_Pn},
  120. {2, ETEXT('x3B'), ETEXT('x3B'), ANSI_Pn_End},
  121. {2, ETEXT('x3A'), ETEXT('x3F'), ANSI_Pn},
  122. {0, ETEXT('x40'), ETEXT('x40'), minitelInsChars},
  123. {0, ETEXT('x41'), ETEXT('x41'), minitelCursorUp},
  124. {0, ETEXT('x42'), ETEXT('x42'), ANSI_CUD},
  125. {0, ETEXT('x43'), ETEXT('x43'), ANSI_CUF},
  126. {0, ETEXT('x44'), ETEXT('x44'), ANSI_CUB},
  127. {0, ETEXT('x48'), ETEXT('x48'), minitelCursorDirect},
  128. {0, ETEXT('x4A'), ETEXT('x4A'), minitelClrScrn},
  129. {0, ETEXT('x4B'), ETEXT('x4B'), minitelClrLn},
  130. {0, ETEXT('x4C'), ETEXT('x4C'), minitelInsRows},
  131. {0, ETEXT('x4D'), ETEXT('x4D'), minitelDelRows},
  132. {0, ETEXT('x50'), ETEXT('x50'), minitelDelChars},
  133. {0, ETEXT('x68'), ETEXT('x69'), minitelInsMode},
  134. {0, ETEXT('x7A'), ETEXT('x7B'), nothing}, //* p144 12.2
  135. {0, ETEXT('x7D'), ETEXT('x7D'), nothing}, //* p144 12.2
  136. {0, ETEXT('x7F'), ETEXT('x7F'), minitelResetTerminal}, //* p145, 13.2
  137. {NEW_STATE, 0, 0, 0}, // 3 - unit separtor character position
  138. {3, ETEXT('x00'), ETEXT('x00'), nothing},
  139. {4, ETEXT('x01'), ETEXT('xFF'), minitelUSRow},
  140. {NEW_STATE, 0, 0, 0}, // 4 - end of unit separtor character position
  141. {4, ETEXT('x00'), ETEXT('x00'), nothing},
  142. {0, ETEXT('x01'), ETEXT('xFF'), minitelUSCol},
  143. {NEW_STATE, 0, 0, 0}, // 5 - number of repeats
  144. {5, ETEXT('x00'), ETEXT('x00'), nothing},
  145. {0, ETEXT('x40'), ETEXT('x7F'), minitelRepeat},
  146. {0, ETEXT('x00'), ETEXT('xFF'), minitelResync},
  147. {NEW_STATE, 0, 0, 0}, // 6 - Protocol 1 sequence (PRO1,X)
  148. {6, ETEXT('x00'), ETEXT('x00'), nothing},
  149. {0, ETEXT('x01'), ETEXT('xFF'), minitelPRO1},
  150. {NEW_STATE, 0, 0, 0}, // 7 - Protocol 2 sequence (PRO2,X,Y)
  151. {7, ETEXT('x00'), ETEXT('x00'), nothing},
  152. {8, ETEXT('x01'), ETEXT('xFF'), minitelPRO2Part1},
  153. {NEW_STATE, 0, 0, 0}, // 8 - Protocol 2 sequence (PRO2,X,Y)
  154. {8, ETEXT('x00'), ETEXT('x00'), nothing},
  155. {0, ETEXT('x01'), ETEXT('xFF'), minitelPRO2Part2},
  156. {NEW_STATE, 0, 0, 0}, // 9 - Protocol 3 sequence (PRO3,X,Y,Z)
  157. {9, ETEXT('x00'), ETEXT('x00'), nothing},
  158. {10,ETEXT('x01'), ETEXT('xFF'), nothing},
  159. {NEW_STATE, 0, 0, 0}, // 10 - Protocol 3 sequence (PRO3,X,Y,Z)
  160. {10,ETEXT('x00'), ETEXT('x00'), nothing},
  161. {11,ETEXT('x01'), ETEXT('xFF'), nothing},
  162. {NEW_STATE, 0, 0, 0}, // 11 - Protocol 3 sequence (PRO3,X,Y,Z)
  163. {11,ETEXT('x00'), ETEXT('x00'), nothing},
  164. {0, ETEXT('x01'), ETEXT('xFF'), nothing},
  165. {NEW_STATE, 0, 0, 0}, // 12 - SEP
  166. {12,ETEXT('x00'), ETEXT('x00'), nothing},
  167. {0, ETEXT('x01'), ETEXT('xFF'), nothing},
  168. {NEW_STATE, 0, 0, 0}, // 13 - ESC,35-39,X sequences eaten, p99, 1.2.7
  169. {13,ETEXT('x00'), ETEXT('x00'), nothing},
  170. {0, ETEXT('x01'), ETEXT('xFF'), nothing},
  171. {NEW_STATE, 0, 0, 0}, // 14 - screen transparency mode
  172. {15,ETEXT('x1B'), ETEXT('x1B'), nothing},
  173. {14,ETEXT('x00'), ETEXT('xFF'), nothing},
  174. {23,ETEXT('x20'), ETEXT('x2F'), nothing}, // could be ISO 2022
  175. {NEW_STATE, 0, 0, 0}, // 15 - screen transparency mode continued, seen ESC
  176. {16,ETEXT('x25'), ETEXT('x25'), nothing},
  177. {17,ETEXT('x2F'), ETEXT('x2F'), nothing},
  178. {15,ETEXT('x00'), ETEXT('x00'), nothing},
  179. {14,ETEXT('x00'), ETEXT('xFF'), nothing},
  180. {NEW_STATE, 0, 0, 0}, // 16 - screen transparency mode continued, seen ESC x25
  181. {0, ETEXT('x40'), ETEXT('x40'), nothing},
  182. {16,ETEXT('x00'), ETEXT('x00'), nothing},
  183. {14,ETEXT('x00'), ETEXT('xFF'), nothing},
  184. {NEW_STATE, 0, 0, 0}, // 17 - screen transparency mode continued, seen ESC x2F
  185. {0, ETEXT('x3F'), ETEXT('x3F'), nothing},
  186. {17,ETEXT('x00'), ETEXT('x00'), nothing},
  187. {14,ETEXT('x00'), ETEXT('xFF'), nothing},
  188. {NEW_STATE, 0, 0, 0}, // 18 - Full screen reveal/hide, seen ESC x23
  189. {18,ETEXT('x00'), ETEXT('x00'), nothing},
  190. {19,ETEXT('x20'), ETEXT('x20'), nothing},
  191. {23,ETEXT('x20'), ETEXT('x2F'), nothing}, // could be ISO 2022
  192. {NEW_STATE, 0, 0, 0}, // 19 - Full screen reveal/hide, seen ESC x23 x20
  193. {19,ETEXT('x00'), ETEXT('x00'), nothing},
  194. {0, ETEXT('x58'), ETEXT('x58'), minitelFullScrnConceal},
  195. {0, ETEXT('x5F'), ETEXT('x5F'), minitelFullScrnReveal},
  196. {NEW_STATE, 0, 0, 0}, // 20 - SS2
  197. {20,ETEXT('x00'), ETEXT('x00'), nothing},
  198. {0, ETEXT('x00'), ETEXT('x1F'), minitelResync},
  199. {21,ETEXT('x20'), ETEXT('x7F'), minitelSS2}, // valid SS2
  200. {NEW_STATE, 0, 0, 0}, // 21 - SS2 part 2
  201. {21,ETEXT('x00'), ETEXT('x00'), nothing},
  202. {0, ETEXT('x20'), ETEXT('x7F'), minitelSS2Part2}, // valid SS2
  203. {NEW_STATE, 0, 0, 0}, // 22 - p.99 ISO 2022
  204. {23,ETEXT('x20'), ETEXT('x2F'), nothing},
  205. {0, ETEXT('x00'), ETEXT('x1F'), minitelResync},
  206. {NEW_STATE, 0, 0, 0}, // 23 - p.99 ISO 2022
  207. {24,ETEXT('x20'), ETEXT('x2F'), nothing},
  208. {0, ETEXT('x00'), ETEXT('x1F'), minitelResync},
  209. {NEW_STATE, 0, 0, 0}, // 24 - p.99 ISO 2022
  210. {25, ETEXT('x30'), ETEXT('x3F'), nothing}, // page 107.
  211. {0,  ETEXT('x30'), ETEXT('x7E'), nothing}, // final character
  212. {0,  ETEXT('x00'), ETEXT('x1F'), minitelResync},
  213. {NEW_STATE, 0, 0, 0}, // 25 - p.99 ISO 2022
  214. {0,  ETEXT('x0D'), ETEXT('x0D'), nothing}, // page 107. eat CR
  215. {0,  ETEXT('x00'), ETEXT('x7F'), minitelResync},
  216. };
  217. if (hhEmu == 0)
  218. {
  219. assert(0);
  220. return;
  221. }
  222. emuInstallStateTable(hhEmu, minitel_tbl, DIM(minitel_tbl));
  223. // Allocate and initialize private data for Minitel emulator.
  224. //
  225. if (hhEmu->pvPrivate != 0)
  226. {
  227. free(hhEmu->pvPrivate);
  228. hhEmu->pvPrivate = 0;
  229. }
  230. hhEmu->pvPrivate = malloc(sizeof(MTPRIVATE));
  231. if (hhEmu->pvPrivate == 0)
  232. {
  233. assert(FALSE);
  234. return;
  235. }
  236. pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  237. memset(pstPRI, 0, sizeof(MTPRIVATE));
  238. pstPRI->minitel_last_char = ETEXT(' ');
  239. /* load key array */
  240. emuKeyTableLoad(hhEmu, Minitel_KeyTable,
  241.  sizeof(Minitel_KeyTable)/sizeof(KEYTBLSTORAGE),
  242.  &hhEmu->stEmuKeyTbl);
  243. /* --- Allocate attribute buffer for Minitel junk --- */
  244. pstPRI->apstMT = malloc(MAX_EMUROWS * sizeof(PSTMINITEL));
  245. if (pstPRI->apstMT == 0)
  246. {
  247. assert(FALSE);
  248. return;
  249. }
  250. memset(pstPRI->apstMT, 0, MAX_EMUROWS * sizeof(PSTMINITEL));
  251. for (i = 0 ; i < MAX_EMUROWS ; ++i)
  252. {
  253. pstPRI->apstMT[i] = malloc(MAX_EMUCOLS * sizeof(STMINITEL));
  254. if (pstPRI->apstMT[i] == 0)
  255. {
  256. assert(FALSE);
  257. return;
  258. }
  259. memset(pstPRI->apstMT[i], 0, MAX_EMUCOLS * sizeof(STMINITEL));
  260. }
  261. /* --- Setup defaults --- */
  262. hhEmu->emu_maxrow = 24;     // 25 line emulator
  263. hhEmu->emu_maxcol = 39;     // start in 40 column mode
  264. hhEmu->top_margin = 1;    // access to row 0 is restricted.
  265. hhEmu->bottom_margin = hhEmu->emu_maxrow; // this has to equal emu_maxrow which changed
  266. hhEmu->emu_kbdin = minitel_kbdin;
  267. hhEmu->emu_graphic = minitelGraphic;
  268. hhEmu->emu_deinstall = emuMinitelDeinstall;
  269. hhEmu->emu_ntfy = minitelNtfy;
  270. hhEmu->emuHomeHostCursor = minitelHomeHostCursor;
  271. #ifdef INCL_TERMINAL_SIZE_AND_COLORS
  272.     hhEmu->emu_setscrsize = emuMinitelSetScrSize;
  273. #endif
  274. hhEmu->emu_highchar = (TCHAR)0xFF;
  275. if (hhEmu->emu_currow == 0)
  276. (*hhEmu->emu_setcurpos)(hhEmu, 1, hhEmu->emu_curcol - 1);
  277. // Also, set font to Arial Alternative
  278. //
  279. memset(&lf, 0, sizeof(LOGFONT));
  280. hwndTerm = sessQueryHwndTerminal(hhEmu->hSession);
  281. termGetLogFont(hwndTerm, &lf);
  282. if (StrCharCmpi(lf.lfFaceName, "Arial Alternative") != 0)
  283. {
  284. StrCharCopy(lf.lfFaceName, "Arial Alternative");
  285. lf.lfCharSet = DEFAULT_CHARSET;
  286. lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
  287. termSetLogFont(hwndTerm, &lf);
  288. }
  289. // Backscrol not supported in minitel
  290. //
  291. backscrlSetUNumLines(sessQueryBackscrlHdl(hhEmu->hSession), 0);
  292. // Initialize colors for the Minitel.
  293. //
  294. std_setcolors(hhEmu, VC_BRT_WHITE, VC_BLACK);
  295. // Set terminal to power-up state
  296. //
  297. minitelResetTerminal(hhEmu);
  298. // Turn backscroll off for minitels
  299. //
  300. backscrlSetShowFlag(sessQueryBackscrlHdl(hhEmu->hSession), FALSE);
  301. // Enable Minitel toolbar buttons
  302. //
  303. PostMessage(sessQueryHwnd(hhEmu->hSession), WM_SESS_SHOW_SIDEBAR, 0, 0);
  304. return;
  305. }
  306. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  307.  * FUNCTION:
  308.  * emuMinitelDeinstall
  309.  *
  310.  * DESCRIPTION:
  311.  * Frees the extra attribute buffer needed to manage serial attributes.
  312.  *
  313.  * ARGUMENTS:
  314.  * hhEmu - private emulator handle.
  315.  *
  316.  * RETURNS:
  317.  * void
  318.  *
  319.  */
  320. void emuMinitelDeinstall(const HHEMU hhEmu)
  321. {
  322. int i;
  323. PSTMTPRIVATE pstPRI;
  324. assert(hhEmu);
  325. pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  326. if (pstPRI)
  327. {
  328. if (pstPRI->apstMT)
  329. {
  330. for (i = 0 ; i < MAX_EMUROWS ; ++i)
  331. {
  332. if (pstPRI->apstMT[i])
  333. {
  334. free(pstPRI->apstMT[i]);
  335. pstPRI->apstMT[i] = NULL;
  336. }
  337. }
  338. free(pstPRI->apstMT);
  339. pstPRI->apstMT = 0;
  340. }
  341. free(hhEmu->pvPrivate);
  342. hhEmu->pvPrivate = 0;
  343. }
  344. // Hide Minitel toolbar buttons
  345. //
  346. ShowWindow(sessQuerySidebarHwnd(hhEmu->hSession), SW_HIDE);
  347. return;
  348. }
  349. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  350.  * FUNCTION:
  351.  * minitelReset
  352.  *
  353.  * DESCRIPTION:
  354.  * Sets emulator to an initial state. Used for record and unit
  355.  * separators.
  356.  *
  357.  * ARGUMENTS:
  358.  * hhEmu - private emulator handle.
  359.  *
  360.  * RETURNS:
  361.  * void
  362.  *
  363.  */
  364. void minitelReset(const HHEMU hhEmu)
  365. {
  366. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  367. pstPRI->minitelG1Active = FALSE;
  368. memset(&hhEmu->emu_charattr, 0, sizeof(hhEmu->emu_charattr));
  369. hhEmu->emu_charattr.txtclr = VC_BRT_WHITE;
  370. hhEmu->emu_charattr.bkclr = VC_BLACK;
  371. pstPRI->apstMT[hhEmu->emu_imgrow][hhEmu->emu_curcol].isattr = 0;
  372. memset(&pstPRI->stLatentAttr, 0, sizeof(pstPRI->stLatentAttr));
  373. pstPRI->stLatentAttr.fBkClr = TRUE;
  374. hhEmu->attrState[CS_STATE] =
  375. hhEmu->attrState[CSCLEAR_STATE] = hhEmu->emu_charattr;
  376. hhEmu->emu_clearattr = hhEmu->emu_charattr;
  377. minitelNtfy(hhEmu, 0);
  378. return;
  379. }
  380. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  381.  * FUNCTION:
  382.  * minitelGraphic
  383.  *
  384.  * DESCRIPTION:
  385.  * Handles displayable characters.
  386.  *
  387.  * ARGUMENTS:
  388.  * hhEmu - private emulator handle.
  389.  *
  390.  * RETURNS:
  391.  * void
  392.  *
  393.  */
  394. void minitelGraphic(const HHEMU hhEmu)
  395. {
  396. ECHAR ccode;
  397. ECHAR aechBuf[10];
  398. int r;
  399. int row = hhEmu->emu_currow;
  400. int col = hhEmu->emu_curcol;
  401. BOOL fRedisplay = FALSE;
  402.     BOOL fDblHi;
  403. STATTR stAttr;
  404. ECHAR *tp = hhEmu->emu_apText[hhEmu->emu_imgrow];
  405. const PSTATTR ap = hhEmu->emu_apAttr[hhEmu->emu_imgrow];
  406. const HUPDATE hUpdate = sessQueryUpdateHdl(hhEmu->hSession);
  407. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  408. ccode = hhEmu->emu_code;
  409. if (ccode == 0)
  410. return;
  411. pstPRI->minitel_last_char = ccode;
  412. if (hhEmu->mode_IRM == SET)
  413. {
  414. if (col < hhEmu->emu_maxcol)
  415. {
  416. memmove(&tp[col+1], &tp[col],
  417. (unsigned)(hhEmu->emu_maxcol-col) * sizeof(ECHAR));
  418. memmove(&ap[col+1], &ap[col],
  419. (unsigned)(hhEmu->emu_maxcol-col) * sizeof(STATTR));
  420. memmove(&pstPRI->apstMT[hhEmu->emu_imgrow][col+1],
  421. &pstPRI->apstMT[hhEmu->emu_imgrow][col],
  422. (unsigned)(hhEmu->emu_maxcol-col) * sizeof(STMINITEL));
  423. }
  424. }
  425. /* --- check if we are overwriting an attribute space --- */
  426. if (pstPRI->apstMT[hhEmu->emu_imgrow][col].isattr)
  427. {
  428. pstPRI->apstMT[hhEmu->emu_imgrow][col].isattr = FALSE;
  429. fRedisplay = TRUE;
  430. }
  431. /* --- If we receive a space and have latent attributes, validate --- */
  432. if (ccode == ETEXT('x20') && pstPRI->stLatentAttr.fModified
  433. && pstPRI->minitelG1Active == FALSE)
  434. {
  435. r = hhEmu->emu_imgrow;
  436. // Color
  437. //
  438. pstPRI->apstMT[r][col].fbkclr = pstPRI->stLatentAttr.fBkClr;
  439. pstPRI->apstMT[r][col].bkclr = pstPRI->stLatentAttr.bkclr;
  440. // Conceal
  441. //
  442. pstPRI->apstMT[r][col].conceal = pstPRI->stLatentAttr.conceal;
  443. // Underline
  444. //
  445. pstPRI->apstMT[r][col].undrln = pstPRI->stLatentAttr.undrln;
  446. pstPRI->apstMT[hhEmu->emu_imgrow][col].isattr  = TRUE;
  447. // This is truely wierd.  We don't reset the fBkclr, fConceal, or
  448. // fUndrln fields, only the fModified flag.  Thus if any serial
  449. // attributes are set, all latent values get updated.  The only
  450. // guy who appears to be able to turn off an attribute is the
  451. // mosaic character which validates the background color and sets
  452. // the fBkClr flag to false.  I can't think of a reason why it
  453. // should work this way.  Pretty damn confusing if you ask me. - mrw
  454. //
  455. pstPRI->stLatentAttr.fModified = FALSE;
  456.     fRedisplay = TRUE;
  457. }
  458. /* --- If we switched to G1, map char to location in new font --- */
  459. if (pstPRI->minitelG1Active)
  460. ccode = minitelMapMosaics(hhEmu, ccode);
  461. pstPRI->apstMT[hhEmu->emu_imgrow][col].ismosaic =
  462. (unsigned)pstPRI->minitelG1Active;
  463. /* --- If we switched to semigraphic mode, validate the background --- */
  464. if (pstPRI->minitelG1Active)
  465. {
  466. // Guess what? Latent background color is always adopted for mosaics.
  467. // This is a major undocumented find.  Basicly, mosaics
  468. // (semigraphics) always use the latent background color regardless
  469. // of the validation state.
  470. //
  471. ap[col].bkclr = pstPRI->stLatentAttr.bkclr;
  472. fRedisplay = TRUE;
  473. // Something tricky here.  Reception of a mosaic validates the
  474. // background color.  Validate means adopt the color.  It also
  475. // means that if we shift back to the alpha (G0 char set) and
  476. // recieve a space, we DON'T validate the background color a
  477. // second time.  So we keep a seperate flag for the background
  478. // color validation. - mrw
  479. //
  480. pstPRI->stLatentAttr.fBkClr = FALSE;
  481. }
  482. /* --- Normal character processing --- */
  483. tp[col] = ccode;
  484. // Update the end of row index if necessary.
  485. //
  486. if (col > hhEmu->emu_aiEnd[hhEmu->emu_imgrow])
  487. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = col;
  488. /* --- Find out this characters current attributes and adjust --- */
  489. stAttr = GetAttr(hhEmu, row, col);
  490. ap[col] = hhEmu->emu_charattr;
  491. ap[col].bkclr = stAttr.bkclr;
  492. ap[col].blank = stAttr.blank;
  493. ap[col].undrln = stAttr.undrln;
  494. if (pstPRI->minitelG1Active)
  495. ap[col].symbol = 1;
  496. // Documented: 0x7F (mosaic or alpha) always maps to 0x5F in the G1
  497. // character set (solid block).
  498. //
  499. if (tp[col] == ETEXT('x7F'))
  500. {
  501. tp[col] = ETEXT('x5F');
  502. ap[col].symbol = 1;
  503. }
  504. /* --- Double high stuff --- */
  505. if (hhEmu->emu_charattr.dblhilo)
  506. {
  507. if (row >= 2)
  508. {
  509. r = row_index(hhEmu, row-1);
  510. hhEmu->emu_apText[r][col] = ccode;
  511. hhEmu->emu_apAttr[r][col] = ap[col];
  512. hhEmu->emu_apAttr[r][col].dblhilo = 0;
  513. hhEmu->emu_apAttr[r][col].dblhihi = 1;
  514. pstPRI->apstMT[r][col] = pstPRI->apstMT[hhEmu->emu_imgrow][col];
  515. updateChar(hUpdate, row-1, col, col);
  516. }
  517. }
  518. /* --- Double wide stuff --- */
  519. if (hhEmu->emu_charattr.dblwilf)
  520. {
  521. if (row > 0 && col < hhEmu->emu_maxcol)
  522. {
  523. tp[col+1] = ccode;
  524. ap[col+1] = ap[col];
  525. ap[col+1].dblwilf = 0;
  526. ap[col+1].dblwirt = 1;
  527. // Major league bug.
  528. //
  529. pstPRI->apstMT[hhEmu->emu_imgrow][col+1] =
  530. pstPRI->apstMT[hhEmu->emu_imgrow][col];
  531. }
  532. if (hhEmu->emu_charattr.dblhilo)
  533. {
  534. r = row_index(hhEmu, row-1);
  535. hhEmu->emu_apText[r][col+1] = ccode;
  536. hhEmu->emu_apAttr[r][col+1] = ap[col];
  537. hhEmu->emu_apAttr[r][col+1].dblwilf = 0;
  538. hhEmu->emu_apAttr[r][col+1].dblwirt = 1;
  539. hhEmu->emu_apAttr[r][col+1].dblhilo = 0;
  540. hhEmu->emu_apAttr[r][col+1].dblhihi = 1;
  541. pstPRI->apstMT[r][col+1] = pstPRI->apstMT[hhEmu->emu_imgrow][col];
  542. }
  543. }
  544. /* --- Need to use old row and column --- */
  545. if (fRedisplay)
  546. emuMinitelRedisplayLine(hhEmu, row, col);
  547. /* --- Need to bump the column guy an extra notch if double wide --- */
  548. if (hhEmu->emu_charattr.dblwilf)
  549. {
  550. col += 1;
  551. hhEmu->emu_aiEnd[hhEmu->emu_imgrow] = col;
  552. }
  553. updateChar(hUpdate, row, hhEmu->emu_curcol, col);
  554. /* --- bump column position, check for wrap, etc. --- */
  555. if (++col > hhEmu->emu_maxcol)
  556. {
  557. // Escape code 0x18 is referred to as cancel in the minitel doco.
  558. // It fills from the cursor pos to the end of the row with blanks.
  559. // Note: Also, it does not force wrap in anyway since
  560. // the cursor position is not updated. That's why we have to
  561. // check here. - mrw:5/3/95
  562. //
  563. if (pstPRI->fInCancel || row == 0)
  564. {
  565. col = hhEmu->emu_maxcol;
  566. return;
  567. }
  568. printEchoString(hhEmu->hPrintEcho, tp,
  569. emuRowLen(hhEmu, hhEmu->emu_imgrow));
  570. CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), TEXT("rn"),
  571. StrCharGetByteCount(TEXT("rn")));
  572. printEchoString(hhEmu->hPrintEcho, aechBuf, sizeof(ECHAR) * 2);
  573. CaptureLine(sessQueryCaptureFileHdl(hhEmu->hSession), CF_CAP_LINES,
  574. tp, emuRowLen(hhEmu, hhEmu->emu_imgrow));
  575.         // Wrap around accounts for double high
  576. //
  577. fDblHi = (BOOL)hhEmu->emu_charattr.dblhilo;
  578. if (row == hhEmu->bottom_margin)
  579. {
  580. if (pstPRI->fScrollMode)
  581. minitel_scrollup(hhEmu, fDblHi ? 2 : 1);
  582. else
  583. row = fDblHi ? 2 : 1;
  584. }
  585. else if (row != 0)
  586. {
  587. row += fDblHi ? 2 : 1;
  588. if (row > hhEmu->emu_maxrow)
  589.                 row = 2;
  590. }
  591. col = 0;
  592. }
  593. // Finally, set the cursor position.  This will reset emu_currow
  594. // and emu_curcol.
  595. //
  596. (*hhEmu->emu_setcurpos)(hhEmu, row, col);
  597. return;
  598. }
  599. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  600.  * FUNCTION:
  601.  * emuMinitelRedisplayLine
  602.  *
  603.  * DESCRIPTION:
  604.  * The trick to field attributes is when you encounter one, you need to
  605.  * update the rest of the line that follows since changing or overwriting
  606.  * an attribute space affects stuff to the right.
  607.  *
  608.  * ARGUMENTS:
  609.  * hhEmu - private emulator handle.
  610.  * int row - row to redisplay
  611.  * int col - start column
  612.  *
  613.  * RETURNS:
  614.  * void
  615.  *
  616.  */
  617. static void emuMinitelRedisplayLine(const HHEMU hhEmu,
  618. const int row,
  619. const int col)
  620. {
  621. int i = row_index(hhEmu, row);
  622.     int fDblHi = FALSE;
  623. const ECHAR *tp = hhEmu->emu_apText[i];
  624. const PSTATTR ap = hhEmu->emu_apAttr[i];
  625. const PSTATTR apl = hhEmu->emu_apAttr[row_index(hhEmu, row-1)];
  626. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  627. const PSTMINITEL pstMT = pstPRI->apstMT[i];
  628. for (i = col ; i <= hhEmu->emu_maxcol ; ++i)
  629. {
  630. ap[i] = GetAttr(hhEmu, row, i);
  631. // Here's a wierd one.  Attribute spaces (as opposed to plain spaces)
  632. // validate but do not display the underline attribute.  I suspect
  633. // something similar with seperated mosaics. - mrw
  634. if (tp[i] == ETEXT('x20') && pstMT[i].isattr)
  635. ap[i].undrln = 0;
  636.         // If we're redisplaying a row that has a double hi character,
  637.         // then we have to redisplay the upper-half as well.
  638.         if (ap[i].dblhilo)
  639.             {
  640.             fDblHi = TRUE;
  641. apl[i] = GetAttr(hhEmu, row-1, i);
  642.             }
  643. }
  644. if (fDblHi)
  645. {
  646. updateChar(sessQueryUpdateHdl(hhEmu->hSession),
  647. row-1, col, hhEmu->emu_maxcol);
  648. }
  649. updateChar(sessQueryUpdateHdl(hhEmu->hSession),
  650. row, col, hhEmu->emu_maxcol);
  651. return;
  652. }
  653. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  654.  * FUNCTION:
  655.  * GetAttr
  656.  *
  657.  * DESCRIPTION:
  658.  * Walks the current row and builds a composite attribute based on
  659.  * the encountered attribute spaces.
  660.  *
  661.  * ARGUMENTS:
  662.  * hhEmu - private emulator handle.
  663.  * iRow - logical row
  664.  * iCol - logical col
  665.  *
  666.  * RETURNS:
  667.  * composite attribute.
  668.  *
  669.  */
  670. STATTR GetAttr(const HHEMU hhEmu, const int iRow, const int iCol)
  671. {
  672. int i;
  673. STATTR stAttr;
  674. const int r = row_index(hhEmu, iRow);
  675. const PSTATTR ap = hhEmu->emu_apAttr[r];
  676. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  677. const PSTMINITEL pstMT = pstPRI->apstMT[r];
  678. stAttr = hhEmu->emu_apAttr[r][iCol];
  679. stAttr.bkclr = 0;
  680. stAttr.undrln = 0;
  681. stAttr.blank = 0;
  682. for (i = 0 ; i <= iCol ; ++i)
  683. {
  684.         // Mosaics validate the background color.  Do it first however,
  685.         // because an attribute space can change it to something else.
  686. if (pstMT[i].ismosaic)
  687. stAttr.bkclr = ap[i].bkclr;
  688. if (pstMT[i].isattr)
  689. {
  690. if (pstMT[i].fbkclr)
  691. stAttr.bkclr = pstMT[i].bkclr;
  692. stAttr.undrln = pstMT[i].undrln;
  693. stAttr.blank = pstMT[i].conceal;
  694. }
  695. // Mosaics always cancel underlining.
  696. //
  697. if (pstMT[i].ismosaic)
  698. stAttr.undrln = 0;
  699. }
  700. return stAttr;
  701. }
  702. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  703.  * FUNCTION:
  704.  * emuMinitelCharAttr
  705.  *
  706.  * DESCRIPTION:
  707.  * Modifies the current character attribute.  Does not affect field
  708.  * attributes.
  709.  *
  710.  * mrw - 11/1/94: Went to high intensity colors to more closely match
  711.  * the minitel colors.
  712.  *
  713.  * ARGUMENTS:
  714.  * hhEmu - private emulator handle.
  715.  *
  716.  * RETURNS:
  717.  * void
  718.  *
  719.  */
  720. void emuMinitelCharAttr(const HHEMU hhEmu)
  721. {
  722. STATTR stAttr = hhEmu->attrState[CS_STATE];
  723. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  724. switch (hhEmu->emu_code)
  725. {
  726. case ETEXT('x40'):  stAttr.txtclr = 0;  break;
  727. case ETEXT('x41'):  stAttr.txtclr = 12; /*4*/ break;
  728. case ETEXT('x42'):  stAttr.txtclr = 10; /*2*/ break;
  729. case ETEXT('x43'):  stAttr.txtclr = 14; /*6*/ break;
  730. case ETEXT('x44'):  stAttr.txtclr = 9;  /*1*/ break;
  731. case ETEXT('x45'):  stAttr.txtclr = 13; /*5*/ break;
  732. case ETEXT('x46'):  stAttr.txtclr = 11; /*3*/ break;
  733. case ETEXT('x47'):  stAttr.txtclr = 15; break;
  734. case ETEXT('x48'):  stAttr.blink  = 1;  break;
  735. case ETEXT('x49'):  stAttr.blink  = 0;  break;
  736. case ETEXT('x4C'): // normal size
  737. if (pstPRI->minitelG1Active)
  738. return;
  739. stAttr.dblhilo = 0;
  740. stAttr.dblwilf = 0;
  741. break;
  742. case ETEXT('x4D'): // double height
  743. if (pstPRI->minitelG1Active || hhEmu->emu_currow <= 1)
  744. return;
  745. stAttr.dblhilo= 1;
  746. stAttr.dblwilf = 0;
  747. break;
  748. case ETEXT('x4E'): // double width
  749. if (pstPRI->minitelG1Active || hhEmu->emu_currow < 1)
  750. return;
  751. stAttr.dblhilo = 0;
  752. stAttr.dblwilf = 1;
  753. break;
  754. case ETEXT('x4F'): // double size
  755. if (pstPRI->minitelG1Active || hhEmu->emu_currow <= 1)
  756. return;
  757. stAttr.dblhilo = 1;
  758. stAttr.dblwilf = 1;
  759. break;
  760. case ETEXT(ETEXT('x5C')):    // normal polarity
  761. if (pstPRI->minitelG1Active)
  762. return;
  763. stAttr.revvid = 0;
  764. break;
  765. case ETEXT(ETEXT('x5D')):    // reverse polarity
  766. if (pstPRI->minitelG1Active)
  767. return;
  768. stAttr.revvid = 1;
  769. break;
  770. default:
  771. break;
  772. }
  773. /* --- commit changes --- */
  774. hhEmu->emu_charattr =
  775. hhEmu->attrState[CS_STATE] =
  776. hhEmu->attrState[CSCLEAR_STATE] = stAttr;
  777. hhEmu->attrState[CSCLEAR_STATE].revvid = 0;
  778. hhEmu->attrState[CSCLEAR_STATE].undrln = 0;
  779. hhEmu->emu_clearattr = hhEmu->attrState[CSCLEAR_STATE];
  780. return;
  781. }
  782. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  783.  * FUNCTION:
  784.  * emuMinitelFieldAttr
  785.  *
  786.  * DESCRIPTION:
  787.  * Dreaded field attributes.  Actually, this routine updates what is
  788.  * called a Latent Attribute. The attributes only become effective
  789.  * when a space is recieved.  Who invents this stupid stuff anyways?
  790.  *
  791.  * mrw - 11/1/94: Went to high intensity colors to more closely match
  792.  * the minitel colors.
  793.  *
  794.  * ARGUMENTS:
  795.  * hhEmu - private emulator handle.
  796.  *
  797.  * RETURNS:
  798.  * void
  799.  *
  800.  */
  801. void emuMinitelFieldAttr(const HHEMU hhEmu)
  802. {
  803. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  804. LATENTATTR * const pstLA = &pstPRI->stLatentAttr;
  805. switch (hhEmu->emu_code)
  806. {
  807. case ETEXT('x50'):  pstLA->bkclr = 0;  break;
  808. case ETEXT('x51'):  pstLA->bkclr = 12;  break;
  809. case ETEXT('x52'):  pstLA->bkclr = 10;  break;
  810. case ETEXT('x53'):  pstLA->bkclr = 14;  break;
  811. case ETEXT('x54'):  pstLA->bkclr = 9;  break;
  812. case ETEXT('x55'):  pstLA->bkclr = 13;  break;
  813. case ETEXT('x56'):  pstLA->bkclr = 11;  break;
  814. case ETEXT('x57'):  pstLA->bkclr = 15;  break;
  815. case ETEXT('x58'):  pstLA->conceal=1;  break;
  816. case ETEXT('x5F'):  pstLA->conceal=0;  break;
  817. case ETEXT('x59'): // separated mosaics off
  818. if (pstPRI->minitelG1Active)
  819. {
  820. pstPRI->minitelUseSeparatedMosaics = 0;
  821. return;
  822. }
  823. else
  824. {
  825. pstPRI->stLatentAttr.undrln = 0;
  826. }
  827. break;
  828. case ETEXT('x5A'): // separated mosaics on
  829. if (pstPRI->minitelG1Active)
  830. {
  831. pstPRI->minitelUseSeparatedMosaics = 1;
  832. return;
  833. }
  834. else
  835. {
  836. pstPRI->stLatentAttr.undrln = 1;
  837. }
  838. break;
  839. default:
  840.     return;
  841. }
  842. // Undocumented: setting any field attribute invalidates the
  843. // latent color context.
  844. //
  845. pstPRI->stLatentAttr.fBkClr = TRUE;
  846. pstPRI->stLatentAttr.fModified = TRUE;
  847. return;
  848. }
  849. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  850.  * minitel_kbdin
  851.  *
  852.  * DESCRIPTION:
  853.  *  Processes keys for the minitel emulator.
  854.  *
  855.  * ARGUMENTS:
  856.  * hhEmu - private emulator handle.
  857.  * key  - key to process
  858.  *
  859.  * RETURNS:
  860.  *  nothing
  861.  */
  862. static int minitel_kbdin(const HHEMU hhEmu, int key, const int fTest)
  863. {
  864. int index;
  865. TCHAR c;
  866. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  867. if ((index = emuKbdKeyLookup(hhEmu, key, &hhEmu->stEmuKeyTbl)) != -1)
  868. {
  869. if (!fTest)
  870. {
  871. emuSendKeyString(hhEmu, index, &hhEmu->stEmuKeyTbl);
  872. // This completes the code sent by emuSendKeyString(), page 124
  873. //
  874. if (key == (VK_RIGHT | VIRTUAL_KEY | SHIFT_KEY) ||
  875. key == (VK_RIGHT | VIRTUAL_KEY | SHIFT_KEY | EXTENDED_KEY))
  876. {
  877. c = (pstPRI->minitelSecondDep) ? TEXT('x6c') : TEXT('x68');
  878. CLoopCharOut(sessQueryCLoopHdl(hhEmu->hSession), c);
  879. }
  880. // Check for disconnect key.  If hit twice consecutively,
  881. // it posts a disconnect to the modem guy.
  882. //
  883. if (key == (VK_F9 | VIRTUAL_KEY))
  884. {
  885. pstPRI->F9 += 1;
  886. if (pstPRI->F9 == 2)
  887. {
  888. PostMessage(sessQueryHwnd(hhEmu->hSession),
  889. WM_DISCONNECT, 0, 0);
  890. }
  891. }
  892. }
  893. }
  894. else
  895. {
  896. // reset F9 counter, must have two consecutive to disconnect
  897. //
  898. pstPRI->F9 = 0;
  899. index = std_kbdin(hhEmu, key, fTest);
  900. }
  901. return index;
  902. }
  903. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  904.  * FUNCTION:
  905.  * minitelCharSet
  906.  *
  907.  * DESCRIPTION:
  908.  * We don't really switch character sets here.  Since minitel uses
  909.  * 7 bit ASCII, we can user the half of the ASCII table for the
  910.  * contigous and seperated mosaics that comprise the G1 char set.
  911.  * Other rule here is that switching the the G1 character set
  912.  * validates the background color on reception of the first mosaic.
  913.  * One thing I haven't figured out yet is when a field attribute is
  914.  * validated, does the latent attribute get reset or retain the last color?
  915.  *
  916.  * ARGUMENTS:
  917.  * hhEmu - private emulator handle.
  918.  *
  919.  * RETURNS:
  920.  * void
  921.  *
  922.  */
  923. void minitelCharSet(const HHEMU hhEmu)
  924. {
  925. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  926. pstPRI->stLatentAttr.undrln = 0;
  927. if (hhEmu->emu_code == ETEXT(0x0E)) // switch to G1
  928. {
  929. pstPRI->minitelG1Active = TRUE;
  930. pstPRI->minitelUseSeparatedMosaics = FALSE;
  931. }
  932. else
  933. {
  934. pstPRI->minitelG1Active = FALSE;
  935. }
  936. // underline, size and polarity attributes permanently canceled.
  937. //
  938. hhEmu->emu_charattr.undrln = 0;
  939. hhEmu->emu_charattr.dblhihi = 0;
  940. hhEmu->emu_charattr.dblhilo = 0;
  941. hhEmu->emu_charattr.dblwilf = 0;
  942. hhEmu->emu_charattr.dblwirt = 0;
  943. hhEmu->emu_charattr.revvid = 0;
  944. hhEmu->emu_charattr.symbol = 0;
  945. hhEmu->attrState[CS_STATE] =
  946. hhEmu->attrState[CSCLEAR_STATE] = hhEmu->emu_charattr;
  947. hhEmu->emu_clearattr = hhEmu->emu_charattr;
  948. return;
  949. }
  950. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  951.  * FUNCTION:
  952.  * minitelResetTerminal
  953.  *
  954.  * DESCRIPTION:
  955.  * Response to a 1B 39 7F sequence.  Puts terminal in power-up state.
  956.  *
  957.  * ARGUMENTS:
  958.  * hhEmu - private emulator handle.
  959.  *
  960.  * RETURNS:
  961.  * void
  962.  *
  963.  */
  964. void minitelResetTerminal(const HHEMU hhEmu)
  965. {
  966. minitelClearScreen(hhEmu, 0);  // clear screen
  967. (*hhEmu->emu_setcurpos)(hhEmu, 0, 0);
  968. minitelClearLine(hhEmu, 0);    // clear line 0
  969. (*hhEmu->emu_setcurpos)(hhEmu, 1, 0);
  970. minitelReset(hhEmu);  // reset attributes
  971. ((PSTMTPRIVATE)hhEmu->pvPrivate)->fScrollMode = 0;
  972. EmuStdSetCursorType(hhEmu, EMU_CURSOR_NONE);
  973. minitelNtfy(hhEmu, 0);
  974. return;
  975. }
  976. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  977.  * FUNCTION:
  978.  * minitelCursorOn
  979.  *
  980.  * DESCRIPTION:
  981.  * Turns minitel cursor on.
  982.  *
  983.  * ARGUMENTS:
  984.  * hhEmu - private emulator handle.
  985.  *
  986.  * RETURNS:
  987.  * void
  988.  *
  989.  */
  990. void minitelCursorOn(const HHEMU hhEmu)
  991. {
  992. EmuStdSetCursorType(hhEmu, EMU_CURSOR_BLOCK);
  993. return;
  994. }
  995. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  996.  * FUNCTION:
  997.  * minitelCursorOff
  998.  *
  999.  * DESCRIPTION:
  1000.  * Turns minitel cursor off
  1001.  *
  1002.  * ARGUMENTS:
  1003.  * hhEmu - private emulator handle.
  1004.  *
  1005.  * RETURNS:
  1006.  * void
  1007.  *
  1008.  */
  1009. void minitelCursorOff(const HHEMU hhEmu)
  1010. {
  1011. #if defined(NDEBUG)
  1012. EmuStdSetCursorType(hhEmu, EMU_CURSOR_NONE);
  1013. #else
  1014. EmuStdSetCursorType(hhEmu, EMU_CURSOR_BLOCK);
  1015. #endif
  1016. return;
  1017. }
  1018. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1019.  * FUNCTION:
  1020.  * mintelMapMosaics
  1021.  *
  1022.  * DESCRIPTION:
  1023.  * Maps regular character to a mosaic char for our font only.
  1024.  *
  1025.  * ARGUMENTS:
  1026.  * hhEmu - private emulator handle.
  1027.  * ch - character to convert
  1028.  *
  1029.  * RETURNS:
  1030.  * converted or original character.
  1031.  *
  1032.  */
  1033. static ECHAR minitelMapMosaics(const HHEMU hhEmu, ECHAR ch)
  1034. {
  1035. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  1036. if (ch >= ETEXT('x21') && ch <= ETEXT('x3F'))
  1037. ch += ETEXT('x1F');
  1038. // Another weird undocumented affect.  Columns 4 and 5 (except 5F)
  1039. // map to columns 6 and 7 (page 101)
  1040.     //
  1041. else if (ch >= ETEXT('x40') && ch <= ETEXT('x5E'))
  1042. ch += ETEXT('x20');
  1043. else if (ch >= ETEXT('x60') && ch <= ETEXT('x7E'))
  1044. ch += 0;
  1045. if (pstPRI->minitelUseSeparatedMosaics && ch >= ETEXT('x21') &&
  1046. ch <= ETEXT('x7F'))
  1047. {
  1048. ch += ETEXT('x40');
  1049. }
  1050. return ch;
  1051. }
  1052. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1053.  * FUNCTION:
  1054.  * minitelCursorReport
  1055.  *
  1056.  * DESCRIPTION:
  1057.  * Return the current cursor location as US row col.
  1058.  *
  1059.  * ARGUMENTS:
  1060.  * hhEmu - private emulator handle.
  1061.  *
  1062.  * RETURNS:
  1063.  * void
  1064.  *
  1065.  */
  1066. void minitelCursorReport(const HHEMU hhEmu)
  1067. {
  1068. TCHAR ach[40];
  1069. ECHAR aech[40];
  1070. wsprintf(ach, TEXT("US%c%c"), hhEmu->emu_currow, hhEmu->emu_curcol);
  1071. CnvrtMBCStoECHAR(aech, sizeof(aech), ach,
  1072.         StrCharGetByteCount(ach) + sizeof(TCHAR));
  1073. emuSendString(hhEmu, aech, StrCharGetEcharByteCount(aech));
  1074. return;
  1075. }
  1076. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1077.  * FUNCTION:
  1078.  * minitelFullScrnConceal
  1079.  *
  1080.  * DESCRIPTION:
  1081.  * Just sets the blank bits on all the attributes.
  1082.  *
  1083.  * ARGUMENTS:
  1084.  * hhEmu - private emulator handle.
  1085.  *
  1086.  * RETURNS:
  1087.  * void
  1088.  *
  1089.  */
  1090. static void minitelFullScrnConceal(const HHEMU hhEmu)
  1091. {
  1092. int i, j;
  1093. PSTATTR ap;
  1094. for (i = 1 ; i <= hhEmu->emu_maxrow ; ++i)
  1095. {
  1096. ap = hhEmu->emu_apAttr[row_index(hhEmu, i)];
  1097. for (j = 0 ; j <= hhEmu->emu_maxcol ; ++j, ++ap)
  1098. ap->blank = 1;
  1099. updateLine(sessQueryUpdateHdl(hhEmu->hSession),
  1100. 1, hhEmu->emu_maxrow);
  1101. }
  1102. return;
  1103. }
  1104. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1105.  * FUNCTION:
  1106.  * minitelFullScrnReveal
  1107.  *
  1108.  * DESCRIPTION:
  1109.  * Just sets the blank bits on all the attributes.
  1110.  *
  1111.  * ARGUMENTS:
  1112.  * hhEmu - private emulator handle.
  1113.  *
  1114.  * RETURNS:
  1115.  * void
  1116.  *
  1117.  */
  1118. static void minitelFullScrnReveal(const HHEMU hhEmu)
  1119. {
  1120. int i, j;
  1121. PSTATTR ap;
  1122. for (i = 1 ; i <= hhEmu->emu_maxrow ; ++i)
  1123. {
  1124. ap = hhEmu->emu_apAttr[row_index(hhEmu, i)];
  1125. for (j = 0 ; j <= hhEmu->emu_maxcol ; ++j, ++ap)
  1126. ap->blank = 0;
  1127. }
  1128. updateLine(sessQueryUpdateHdl(hhEmu->hSession), 1, hhEmu->emu_maxrow);
  1129. return;
  1130. }
  1131. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1132.  * FUNCTION:
  1133.  * minitelResync
  1134.  *
  1135.  * DESCRIPTION:
  1136.  * Certain codes will cause the emulator to resynchronize, (goto state
  1137.  * zero) and play the character thru.
  1138.  *
  1139.  * ARGUMENTS:
  1140.  * hhEmu - private emulator handle.
  1141.  *
  1142.  * RETURNS:
  1143.  * void
  1144.  *
  1145.  */
  1146. void minitelResync(const HHEMU hhEmu)
  1147. {
  1148. hhEmu->state = 0;
  1149. #if defined(EXTENDED_FEATURES)
  1150. (void)(*hhEmu->emu_datain)(hhEmu, hhEmu->emu_code);
  1151. #else
  1152. (void)(*hhEmu->emu_datain)((HEMU)hhEmu, hhEmu->emu_code);
  1153. #endif
  1154. return;
  1155. }
  1156. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1157.  * FUNCTION:
  1158.  * minitelSS2
  1159.  *
  1160.  * DESCRIPTION:
  1161.  * SS2 is an alternate character set. It only has about 15 symbols so
  1162.  * we just map them here to ones in our current minitel font.
  1163.  *
  1164.  * ARGUMENTS:
  1165.  * hhEmu - private emulator handle.
  1166.  *
  1167.  * RETURNS:
  1168.  * void
  1169.  *
  1170.  */
  1171. static void minitelSS2(const HHEMU hhEmu)
  1172. {
  1173. const int row = hhEmu->emu_currow;
  1174. const int col = hhEmu->emu_curcol;
  1175. BOOL  fNoAdvance = FALSE;
  1176. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  1177. /* --- SS2 codes are ignored in semigraphic mode --- */
  1178. if (pstPRI->minitelG1Active)
  1179. {
  1180. hhEmu->state = 0;
  1181. return;
  1182. }
  1183. /* --- Map the character --- */
  1184. switch (hhEmu->emu_code)
  1185. {
  1186. case ETEXT('x23'): hhEmu->emu_code = ETEXT('xA3');  break; // british pound
  1187. case ETEXT('x24'): hhEmu->emu_code = ETEXT('x24');  break; // Dollar sign
  1188. case ETEXT('x26'): hhEmu->emu_code = ETEXT('x23');  break; // pound sign
  1189. case ETEXT('x27'): hhEmu->emu_code = ETEXT('xA7');  break; // integral
  1190. case ETEXT('x2C'): hhEmu->emu_code = ETEXT('xC3');  break; // left arrow
  1191. case ETEXT('x2D'): hhEmu->emu_code = ETEXT('xC0');  break; // up arrow
  1192. case ETEXT('x2E'): hhEmu->emu_code = ETEXT('xC4');  break; // right arrow
  1193. case ETEXT('x2F'): hhEmu->emu_code = ETEXT('xC5');  break; // down arrow
  1194. case ETEXT('x30'): hhEmu->emu_code = ETEXT('xB0');  break; // degree
  1195. case ETEXT('x31'): hhEmu->emu_code = ETEXT('xB1');  break; // plus-minus
  1196. case ETEXT('x38'): hhEmu->emu_code = ETEXT('xF7');  break; // divide
  1197. case ETEXT('x3C'): hhEmu->emu_code = ETEXT('xBC');  break; // 1/4
  1198. case ETEXT('x3D'): hhEmu->emu_code = ETEXT('xBD');  break; // 1/2
  1199. case ETEXT('x3E'): hhEmu->emu_code = ETEXT('xBE');  break; // 3/4
  1200. case ETEXT('x41'): hhEmu->emu_code = ETEXT('x60');  fNoAdvance = TRUE;  break;
  1201. case ETEXT('x42'): hhEmu->emu_code = ETEXT('xB4');  fNoAdvance = TRUE;  break;
  1202. case ETEXT('x43'): hhEmu->emu_code = ETEXT('x5E');  fNoAdvance = TRUE;  break;
  1203. case ETEXT('x48'): hhEmu->emu_code = ETEXT('xA8');  fNoAdvance = TRUE;  break;
  1204. case ETEXT('x4A'): hhEmu->emu_code = ETEXT('xB8');  fNoAdvance = TRUE;  break;
  1205. case ETEXT('x4B'): hhEmu->emu_code = ETEXT('xB8');  fNoAdvance = TRUE;  break;
  1206. case ETEXT('x6A'): hhEmu->emu_code = ETEXT('x8C');  break;
  1207. case ETEXT('x7A'): hhEmu->emu_code = ETEXT('x9C');  break;
  1208. case ETEXT('x7B'): hhEmu->emu_code = ETEXT('xDF');  break;
  1209. default: hhEmu->emu_code = ETEXT('x5F');  break;
  1210. }
  1211. minitelGraphic(hhEmu);
  1212. if (fNoAdvance)
  1213. {
  1214. (*hhEmu->emu_setcurpos)(hhEmu, row, col); // don't advance cursor
  1215. }
  1216. else
  1217. {
  1218. // If we don't advance the cursor, we're done with this SS2
  1219. // sequence and reset the state to 0 - mrw, 2/3/95
  1220. //
  1221. hhEmu->state = 0;
  1222. }
  1223. return;
  1224. }
  1225. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1226.  * FUNCTION:
  1227.  * minitelSS2Part2
  1228.  *
  1229.  * DESCRIPTION:
  1230.  * The second half a an SS2 code is the vowel portion for the accents
  1231.  * page 90.
  1232.  *
  1233.  * ARGUMENTS:
  1234.  * hhEmu - private emulator handle.
  1235.  *
  1236.  * RETURNS:
  1237.  * void
  1238.  *
  1239.  */
  1240. static void minitelSS2Part2(const HHEMU hhEmu)
  1241. {
  1242. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  1243. switch (hhEmu->emu_code)
  1244. {
  1245. case ETEXT('a'):
  1246. switch (pstPRI->minitel_last_char)
  1247. {
  1248. case ETEXT('x60'): hhEmu->emu_code = ETEXT('xE0');    break;
  1249. case ETEXT('x5E'): hhEmu->emu_code = ETEXT('xE2');    break;
  1250. case ETEXT('xA8'): hhEmu->emu_code = ETEXT('xE4');    break;
  1251. default: break;
  1252. }
  1253. break;
  1254. case ETEXT('e'):
  1255. switch (pstPRI->minitel_last_char)
  1256. {
  1257. case ETEXT('x60'): hhEmu->emu_code = ETEXT('xE8');    break;
  1258. case ETEXT('xB4'): hhEmu->emu_code = ETEXT('xE9');    break;
  1259. case ETEXT('x5E'): hhEmu->emu_code = ETEXT('xEA');    break;
  1260. case ETEXT('xA8'): hhEmu->emu_code = ETEXT('xEB');    break;
  1261. default: break;
  1262. }
  1263. break;
  1264. case ETEXT('i'):
  1265. switch (pstPRI->minitel_last_char)
  1266. {
  1267. case ETEXT('x5E'): hhEmu->emu_code = ETEXT('xEE');    break;
  1268. case ETEXT('xA8'): hhEmu->emu_code = ETEXT('xEF');    break;
  1269. default: break;
  1270. }
  1271. break;
  1272. case ETEXT('o'):
  1273. switch (pstPRI->minitel_last_char)
  1274. {
  1275. case ETEXT('x5E'): hhEmu->emu_code = ETEXT('xF4');    break;
  1276. case ETEXT('xA8'): hhEmu->emu_code = ETEXT('xF6');    break;
  1277. default: break;
  1278. }
  1279. break;
  1280. case ETEXT('u'):
  1281. switch (pstPRI->minitel_last_char)
  1282. {
  1283. case ETEXT('x60'): hhEmu->emu_code = ETEXT('xF9');    break;
  1284. case ETEXT('x5E'): hhEmu->emu_code = ETEXT('xFB');    break;
  1285. case ETEXT('xA8'): hhEmu->emu_code = ETEXT('xFC');    break;
  1286. default: break;
  1287. }
  1288. break;
  1289. case ETEXT('c'):
  1290. switch (pstPRI->minitel_last_char)
  1291. {
  1292. case ETEXT('xB8'): hhEmu->emu_code = ETEXT('xE7'); break;
  1293. default: break;
  1294. }
  1295. break;
  1296. default:
  1297. // Docs say if we're not one of the above chars, then overwrite
  1298. // position with current char.
  1299. break;
  1300. }
  1301. minitelGraphic(hhEmu);
  1302. return;
  1303. }
  1304. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1305.  * FUNCTION:
  1306.  * minitelInsMode
  1307.  *
  1308.  * DESCRIPTION:
  1309.  * Sets or Resets the insert mode depending on received code.
  1310.  *
  1311.  * ARGUMENTS:
  1312.  * hhEmu - private emulator handle.
  1313.  *
  1314.  * RETURNS:
  1315.  * void
  1316.  *
  1317.  */
  1318. static void minitelInsMode(const HHEMU hhEmu)
  1319. {
  1320. hhEmu->mode_IRM = (hhEmu->emu_code == ETEXT('x68')) ? SET : RESET;
  1321. return;
  1322. }
  1323. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1324.  * FUNCTION:
  1325.  * minitelNtfy
  1326.  *
  1327.  * DESCRIPTION:
  1328.  * Paints an inverted F or C when connection/disconnection notifications
  1329.  * come in.
  1330.  *
  1331.  * ARGUMENTS:
  1332.  * hhEmuPass - change this to hhEmu when reentrancy done.
  1333.  * nNtfyCode - why it was called, (we don't use)
  1334.  *
  1335.  * RETURNS:
  1336.  * void
  1337.  *
  1338.  */
  1339. void minitelNtfy(const HHEMU hhEmu, const int nNtfyCode)
  1340. {
  1341. const int r = row_index(hhEmu, 0);
  1342. const int c = hhEmu->emu_maxcol - 1;
  1343. ECHAR chr;
  1344. BOOL  fFlash = FALSE;
  1345. switch (cnctQueryStatus(sessQueryCnctHdl(hhEmu->hSession)))
  1346. {
  1347. case CNCT_STATUS_FALSE:
  1348. default:
  1349. chr = ETEXT('F');
  1350. break;
  1351. case CNCT_STATUS_TRUE:
  1352. chr = ETEXT('C');
  1353. break;
  1354. case CNCT_STATUS_CONNECTING:
  1355. chr = ETEXT('C');
  1356. fFlash = TRUE;
  1357. break;
  1358. }
  1359. hhEmu->emu_apText[r][c] = chr;
  1360. hhEmu->emu_apAttr[r][c].revvid = 1;
  1361. hhEmu->emu_apAttr[r][c].blink = (unsigned)fFlash;
  1362. hhEmu->emu_apAttr[r][c].symbol = 0; // mrw-5/5/95
  1363. hhEmu->emu_aiEnd[r] = c;
  1364. updateChar(sessQueryUpdateHdl(hhEmu->hSession), 0, c, c);
  1365. NotifyClient(hhEmu->hSession, EVENT_TERM_UPDATE, 0);
  1366. return;
  1367. }
  1368. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1369.  * FUNCTION:
  1370.  * minitelPRO1
  1371.  *
  1372.  * DESCRIPTION:
  1373.  * Handles PRO1 sequences (ESC,39,X).
  1374.  *
  1375.  * ARGUMENTS:
  1376.  * hhEmu - private emulator handle
  1377.  *
  1378.  * RETURNS:
  1379.  * void
  1380.  *
  1381.  */
  1382. static void minitelPRO1(const HHEMU hhEmu)
  1383. {
  1384. ECHAR aechBuf[35];
  1385. static const TCHAR achID[] = "x01x43r0x04";
  1386. switch (hhEmu->emu_code)
  1387. {
  1388. case ETEXT('x7B'): // ENQROM (page 139)
  1389. // See pages 21 & 22.  Basicly we send back an indentification
  1390. // sequence delimited by SOH and EOT
  1391. //
  1392. CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), achID,
  1393.             StrCharGetByteCount(achID));
  1394. CLoopSend(sessQueryCLoopHdl(hhEmu->hSession), aechBuf, 5, 0);
  1395. break;
  1396. case ETEXT('x67'): // Disconnect (page 139)
  1397. PostMessage(sessQueryHwnd(hhEmu->hSession), WM_DISCONNECT, 0, 0);
  1398. break;
  1399. case ETEXT('x72'):
  1400. minitelStatusReply(hhEmu);
  1401. break;
  1402. default:
  1403. break;
  1404. }
  1405. return;
  1406. }
  1407. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1408.  * FUNCTION:
  1409.  * minitelPRO2Part1
  1410.  *
  1411.  * DESCRIPTION:
  1412.  * Handles first half of a PRO2 sequence.
  1413.  *
  1414.  * ARGUMENTS:
  1415.  * hhEmu - private emulator handle.
  1416.  *
  1417.  * RETURNS:
  1418.  * void
  1419.  *
  1420.  */
  1421. static void minitelPRO2Part1(const HHEMU hhEmu)
  1422. {
  1423. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  1424. pstPRI->minitel_PRO1 = hhEmu->emu_code;
  1425. return;
  1426. }
  1427. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1428.  * FUNCTION:
  1429.  * minitelPRO2Part2
  1430.  *
  1431.  * DESCRIPTION:
  1432.  * Handles the second half of a PRO2 sequence.
  1433.  *
  1434.  * ARGUMENTS:
  1435.  * hhEmu - private emulator handle
  1436.  *
  1437.  * RETURNS:
  1438.  * void
  1439.  *
  1440.  */
  1441. static void minitelPRO2Part2(const HHEMU hhEmu)
  1442. {
  1443. int fUpperCase;
  1444. BYTE abKey[256];
  1445. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  1446. switch (hhEmu->emu_code)
  1447. {
  1448. case ETEXT('x43'):   // scrolling
  1449. if (pstPRI->minitel_PRO1 == ETEXT('x69'))
  1450. pstPRI->fScrollMode = TRUE;
  1451. if (pstPRI->minitel_PRO1 == ETEXT('x6A'))
  1452. pstPRI->fScrollMode = FALSE;
  1453. minitelStatusReply(hhEmu);
  1454. break;
  1455. case ETEXT('x44'):   // error correction procedure (not implemented)
  1456. break;
  1457. case ETEXT('x45'):   // keyboard upper/lower case
  1458. if (pstPRI->minitel_PRO1 == ETEXT('x69'))
  1459. fUpperCase = FALSE;
  1460. else if (pstPRI->minitel_PRO1 == ETEXT('x6A'))
  1461. fUpperCase = TRUE;
  1462. else
  1463. break;
  1464. GetKeyboardState(abKey);
  1465. if (fUpperCase)
  1466. abKey[VK_CAPITAL] |= 0x01;
  1467. else
  1468. abKey[VK_CAPITAL] &= 0xfe;
  1469. SetKeyboardState(abKey);
  1470. minitelStatusReply(hhEmu);
  1471. break;
  1472. default:
  1473. return;
  1474. }
  1475. return;
  1476. }
  1477. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1478.  * FUNCTION:
  1479.  * minitelStatusReply
  1480.  *
  1481.  * DESCRIPTION:
  1482.  * Acknowledgement sequence for some PRO2 sequences and status requests.
  1483.  *
  1484.  * ARGUMENTS:
  1485.  * hhEmu - private emulator handle.
  1486.  *
  1487.  * RETURNS:
  1488.  * void
  1489.  *
  1490.  * AUTHOR: Mike Ward, 08-May-1995
  1491.  */
  1492. static void minitelStatusReply(const HHEMU hhEmu)
  1493. {
  1494. ECHAR ach[10];
  1495. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  1496. // The PRO2 sequences x43 and x45 all return and acknowledgement
  1497. // of the form PRO2,x73,status byte.  The format of the status byte
  1498. // is defined in page 143, section 11.2.
  1499. //
  1500. // strcpy(ach, "x1bx3Ax73");
  1501. CnvrtMBCStoECHAR(ach, sizeof(ach), "x1bx3Ax73",
  1502. (unsigned long)StrCharGetByteCount("x1bx3Ax73"));
  1503. ach[3] = ETEXT('x40');  // bit 7 is always 1.
  1504. ach[3] |= pstPRI->fScrollMode ? ETEXT('x02') : ETEXT('x00');
  1505. ach[3] |=(GetKeyState(VK_CAPITAL) > 0) ? ETEXT('x00') : ETEXT('x08');
  1506. ach[4] = ETEXT('');
  1507. CLoopSend(sessQueryCLoopHdl(hhEmu->hSession), ach, 4, 0);
  1508. return;
  1509. }
  1510. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1511.  * FUNCTION:
  1512.  * emuMinitelSendKey
  1513.  *
  1514.  * DESCRIPTION:
  1515.  * Used by the toolbar to emit the correct minitel sequence for the
  1516.  * specified button.
  1517.  *
  1518.  * ARGUMENTS:
  1519.  * hEmu - public emulator handle.
  1520.  * iCmd - command string to send.
  1521.  *
  1522.  * RETURNS:
  1523.  * void
  1524.  *
  1525.  * AUTHOR: Mike Ward, 10-Mar-1995
  1526.  */
  1527. void emuMinitelSendKey(const HEMU hEmu, const int iCmd)
  1528. {
  1529. TCHAR *pach;
  1530. ECHAR aechBuf[20];
  1531. const HHEMU hhEmu = (HHEMU)hEmu;
  1532. const PSTMTPRIVATE pstPRI = (PSTMTPRIVATE)hhEmu->pvPrivate;
  1533. switch (iCmd)
  1534. {
  1535. case IDM_MINITEL_INDEX:  pach = TEXT("x13") TEXT("F");    break;
  1536. case IDM_MINITEL_CANCEL: pach = TEXT("x13") TEXT("E");    break;
  1537. case IDM_MINITEL_PREVIOUS: pach = TEXT("x13") TEXT("B");    break;
  1538. case IDM_MINITEL_REPEAT: pach = TEXT("x13") TEXT("C");    break;
  1539. case IDM_MINITEL_GUIDE:  pach = TEXT("x13") TEXT("D");    break;
  1540. case IDM_MINITEL_CORRECT: pach = TEXT("x13") TEXT("G");    break;
  1541. case IDM_MINITEL_NEXT: pach = TEXT("x13") TEXT("H");    break;
  1542. case IDM_MINITEL_SEND: pach = TEXT("x13") TEXT("A");    break;
  1543. case IDM_MINITEL_CONFIN:
  1544. pach = TEXT("x13") TEXT("I");
  1545. pstPRI->F9 += 1;
  1546. if (pstPRI->F9 == 2)
  1547. PostMessage(sessQueryHwnd(hhEmu->hSession), WM_DISCONNECT, 0, 0);
  1548. break;
  1549. default:
  1550. assert(0);
  1551. return;
  1552. }
  1553. CnvrtMBCStoECHAR(aechBuf, sizeof(aechBuf), pach,
  1554. StrCharGetByteCount(pach) + sizeof(TCHAR));
  1555. emuSendString((HHEMU)hEmu, aechBuf, StrCharGetEcharByteCount(aechBuf));
  1556. return;
  1557. }
  1558. #ifdef INCL_TERMINAL_SIZE_AND_COLORS
  1559. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1560.  * FUNCTION:
  1561.  *  emuMinitelSetScrSize
  1562.  *
  1563.  * DESCRIPTION:
  1564.  *  Replaces std_setscrsize which was added to allow user settable screen
  1565.  * sizes. However, the Minitel doesn't allow this.
  1566.  *
  1567.  * ARGUMENTS:
  1568.  *  hhEmu - The internal emulator handle.
  1569.  *
  1570.  * RETURNS:
  1571.  *  void
  1572.  *
  1573.  * AUTHOR: Bob Everett - 1 Sep 1998
  1574.  */
  1575. void emuMinitelSetScrSize(const HHEMU hhEmu)
  1576.     {
  1577.     }
  1578. #endif
  1579. #endif // INCL_MINITEL