Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
6.4 KiB

  1. /**************************************************/
  2. /* */
  3. /* */
  4. /* Setting code range */
  5. /* */
  6. /* */
  7. /* Copyright (c) 1997-1999 Microsoft Corporation. */
  8. /**************************************************/
  9. #include "stdafx.h"
  10. #include "eudcedit.h"
  11. #include "registry.h"
  12. #ifdef BUILD_ON_WINNT
  13. #include "extfunc.h"
  14. #endif // BUILD_ON_WINNT
  15. #include "util.h"
  16. #define S_UNICODE 0xE000
  17. #define E_UNICODE 0xE0ff
  18. BOOL SetCountryInfo( UINT LocalCP);
  19. int SetLeadByteRange(TCHAR * CodeRange,int nCode);
  20. void SetTrailByteRange();
  21. #ifdef BUILD_ON_WINNT
  22. void CorrectTrailByteRange(int nIndex);
  23. #endif // BUILD_ON_WINNT
  24. /****************************************/
  25. /* */
  26. /* Set Country Infomation */
  27. /* */
  28. /****************************************/
  29. BOOL
  30. SetCountryInfo(
  31. UINT LocalCP)
  32. {
  33. TCHAR CodePage[10], szUnicode[] = TEXT("Unicode");
  34. TCHAR Coderange[50];
  35. int nCode = 0;
  36. SetTrailByteRange(LocalCP);
  37. if (!CountryInfo.bOnlyUnicode){
  38. /* Read EUDC Coderange from Registry */
  39. #ifndef NEWREG
  40. /* Old Version */
  41. TCHAR CodeTmp[10];
  42. wsprintf( CodeTmp, TEXT("%d"), LocalCP);
  43. if( lstrlen( CodeTmp) == 3){
  44. lstrcpy(CodePage, TEXT("CP00"));
  45. }else{
  46. lstrcpy(CodePage, TEXT("CP0"));
  47. }
  48. lstrcat(CodePage, CodeTmp);
  49. #else
  50. /* New Version */
  51. wsprintf( CodePage, TEXT("%d"), LocalCP);
  52. #endif
  53. if( !InqCodeRange(CodePage, (BYTE *)Coderange, 50))
  54. return FALSE;
  55. if ((nCode = SetLeadByteRange ( Coderange, 0)) == -1)
  56. return FALSE;
  57. } //!CountryInfo.bOnlyUnicode
  58. #ifdef UNICODE
  59. // unicode range will always be the last one.
  60. lstrcpy(CodePage, szUnicode);
  61. if( !InqCodeRange(CodePage, (BYTE *)Coderange, 50))
  62. return FALSE;
  63. if (SetLeadByteRange (Coderange, nCode) == -1)
  64. return FALSE;
  65. #else
  66. //
  67. // Ansi version, we have to set end Unicode
  68. // code point to the last ansi range.
  69. //
  70. WCHAR RangeTmp[2];
  71. CHAR AnsiRange[2];
  72. CountryInfo.nRange = nCode+1;
  73. CountryInfo.nLeadByte = nCode+1;
  74. CountryInfo.sRange[nCode] = S_UNICODE;
  75. AnsiRange[0] = HIBYTE(CountryInfo.eRange[nCode-1]);
  76. AnsiRange[1] = LOBYTE(CountryInfo.eRange[nCode-1]);
  77. MultiByteToWideChar(CP_ACP, 0, AnsiRange,2,RangeTmp, 1);
  78. CountryInfo.eRange[nCode] = RangeTmp[0];
  79. CountryInfo.sLeadByte[nCode] = HIBYTE(CountryInfo.sRange[nCode]);
  80. CountryInfo.eLeadByte[nCode] = HIBYTE(CountryInfo.eRange[nCode]);
  81. #endif
  82. return TRUE;
  83. }
  84. void
  85. SetTrailByteRange(
  86. UINT LocalCP)
  87. {
  88. WORD UCode[MAX_CODE];
  89. BYTE SCode[MAX_CODE], sTral, cTral;
  90. int nTral = 0;
  91. if (!CountryInfo.bUnicodeMode){
  92. // calculate trailbyte range.
  93. UCode[0] = S_UNICODE;
  94. UCode[1] = '\0';
  95. WideCharToMultiByte( LocalCP, 0L, (const unsigned short *)UCode,
  96. -1, (char *)SCode, sizeof(SCode), NULL, NULL);
  97. sTral = cTral = SCode[1];
  98. CountryInfo.sTralByte[nTral] = sTral;
  99. for( WORD Cnt = S_UNICODE + 1; Cnt <= E_UNICODE; Cnt++){
  100. UCode[0] = Cnt;
  101. UCode[1] = '\0';
  102. WideCharToMultiByte( LocalCP, 0L, (const unsigned short *)UCode,
  103. -1, (char *)SCode, sizeof(SCode), NULL, NULL);
  104. if( cTral + 1 != SCode[1]){
  105. CountryInfo.eTralByte[nTral] = cTral;
  106. nTral++;
  107. if( sTral != SCode[1]){
  108. CountryInfo.sTralByte[nTral] = SCode[1];
  109. }
  110. }
  111. cTral = SCode[1];
  112. if( sTral == cTral)
  113. break;
  114. }
  115. CountryInfo.nTralByte = nTral;
  116. /* For Extend Wansung (test) */
  117. if( CountryInfo.LangID == EUDC_KRW){
  118. CountryInfo.nTralByte = 3;
  119. CountryInfo.sTralByte[0] = 0x41;
  120. CountryInfo.eTralByte[0] = 0x5a;
  121. CountryInfo.sTralByte[1] = 0x61;
  122. CountryInfo.eTralByte[1] = 0x7a;
  123. CountryInfo.sTralByte[2] = 0x81;
  124. CountryInfo.eTralByte[2] = 0xfe;
  125. }
  126. /* For CHS we have to remember the original trail byte range and calculate
  127. trail byte range dynamically
  128. */
  129. if( CountryInfo.LangID == EUDC_CHS){
  130. CountryInfo.nOrigTralByte = 2;
  131. CountryInfo.sOrigTralByte[0] = 0x40;
  132. CountryInfo.eOrigTralByte[0] = 0x7e;
  133. CountryInfo.sOrigTralByte[1] = 0x80;
  134. CountryInfo.eOrigTralByte[1] = 0xfe;
  135. //To start with, calculate trailbyte range for the default EUDC selection range.
  136. CorrectTrailByteRange(0);
  137. }else{
  138. CountryInfo.nOrigTralByte = 0;
  139. }
  140. }else { //!CountryInfo.bUnicodeMode
  141. CountryInfo.nTralByte = 1;
  142. CountryInfo.sTralByte[0] = 0x00;
  143. CountryInfo.eTralByte[0] = 0xff;
  144. } //!CountryInfo.bUnicodeMode
  145. }
  146. int
  147. SetLeadByteRange(
  148. TCHAR * Coderange,
  149. int nCode)
  150. {
  151. // Calculate LeadByte Range
  152. TCHAR *pStr1, *pStr2;
  153. WORD wLow, wHigh;
  154. pStr1 = pStr2 = Coderange;
  155. while(1){
  156. if(( pStr2 = Mytcschr( pStr1, '-')) != NULL){
  157. *pStr2 = '\0';
  158. wLow = (WORD)Mytcstol( pStr1, (TCHAR **)0, 16);
  159. CountryInfo.sRange[nCode] = wLow;
  160. CountryInfo.sLeadByte[nCode] = HIBYTE( wLow);
  161. pStr2++;
  162. pStr1 = pStr2;
  163. }else return -1;
  164. if(( pStr2 = Mytcschr( pStr1, ',')) != NULL){
  165. *pStr2 = '\0';
  166. wHigh = (WORD)Mytcstol( pStr1, (TCHAR **)0, 16);
  167. CountryInfo.eRange[nCode] = (unsigned short)wHigh;
  168. CountryInfo.eLeadByte[nCode] = HIBYTE( wHigh);
  169. pStr2++;
  170. pStr1 = pStr2;
  171. }else{
  172. wHigh = (WORD)Mytcstol( pStr1, (TCHAR **)0, 16);
  173. CountryInfo.eRange[nCode] = (unsigned short)wHigh;
  174. CountryInfo.eLeadByte[nCode] = HIBYTE( wHigh);
  175. break;
  176. }
  177. nCode++;
  178. }
  179. CountryInfo.nLeadByte = ++nCode;
  180. CountryInfo.nRange = nCode;
  181. return nCode;
  182. }
  183. #ifdef BUILD_ON_WINNT
  184. /**************************************************************************\
  185. * CorrectTralByteRange *
  186. * Correct trailbyte range of EUDC range with each of original trail byte *
  187. * ranges. It is used by countries where EUDC trail byte range changes *
  188. * with selection of different EUDC range, for example CHS. *
  189. \**************************************************************************/
  190. void
  191. CorrectTrailByteRange(
  192. int nIndex)
  193. {
  194. COUNTRYINFO *Info;
  195. int i, Unique=0;
  196. if (CountryInfo.bUnicodeMode)
  197. return;
  198. Info=&CountryInfo;
  199. for (i=0; i< Info->nOrigTralByte; i++){
  200. //take the smaller of the two ranges.
  201. Info->sTralByte[Unique] = max(LOBYTE(Info->sRange[nIndex]),
  202. Info->sOrigTralByte[i]);
  203. Info->eTralByte[Unique] = min(LOBYTE(Info->eRange[nIndex]),
  204. Info->eOrigTralByte[i]);
  205. //we keep valid ranges and overwrite invalid one with next loop
  206. if (Info->eTralByte[Unique] >= Info->sTralByte[Unique])
  207. Unique +=1;
  208. }
  209. Info->nTralByte=Unique;
  210. }
  211. #endif // BUILD_ON_WINNT