Imported Upstream version 6.0
[platform/upstream/dos2unix.git] / querycp.c
1 /* The code in this file is Public Domain */
2
3 #if (defined(__WATCOMC__) && defined(__NT__))
4 #  define WIN32
5 #endif
6
7 #ifdef DJGPP
8
9 #include <dpmi.h>
10 #include <go32.h>
11 #include <stdio.h>
12
13 /*
14  ----------------------------------------------------------------------
15  Tuesday, May 5, 2009    1:40pm
16  rugxulo _AT_ gmail _DOT_ com
17
18  This file is (obviously?) not copyrighted, "nenies proprajxo" !!
19
20  Tested successfully on DR-DOS 7.03, FreeDOS 1.0++, and MS-DOS 6.22.
21  (Doesn't work on XP or Vista, though.)
22  ----------------------------------------------------------------------
23
24  unsigned short query_con_codepage(void);
25
26  gets currently selected display CON codepage
27
28  int 21h, 6601h ("chcp") needs NLSFUNC.EXE + COUNTRY.SYS, but many
29     obscure codepages (e.g. FD's cp853 from EGA.CPX (CPIX.ZIP) or
30     Kosta Kostis' cp913 from ISOLATIN.CPI (ISOCP101.ZIP) have no
31     relevant data inside COUNTRY.SYS.
32
33  int 21h, 440Ch 6Ah only works in MS-DOS and DR-DOS (not FreeDOS) because
34     FreeDOS DISPLAY is an .EXE TSR, not a device driver, and hence doesn't
35     fully support IOCTL, so they use the undocumented int 2Fh, 0AD02h
36     (which doesn't work in DR-DOS!). But DR-DOS' DISPLAY doesn't respond
37     to the typical install check i.d. anyways. FreeDOS currently only
38     supports COUNTRY.SYS in their "unstable" kernel 2037, but at least
39     their KEYB, "gxoje", supports cp853 too (thanks, Henrique!).
40
41  P.S. For MS or DR: ren ega.cpx *.com ; upx -d ega.com ; ren ega.com *.cpi
42
43  ADDENDUM (2011):
44  Latest "stable" FreeDOS kernel is 2040, it now includes COUNTRY.SYS
45  support by default, but NLSFUNC (CHCP) 'system code page' support is
46  partially unimplemented (lacking some int 2Fh calls, yet Eduardo
47  Casino didn't seem too worried, so I dunno, nag him if necessary,
48  heh).
49  ----------------------------------------------------------------------
50 */
51
52 unsigned short query_con_codepage(void) {
53    __dpmi_regs regs;
54
55    unsigned short param_block[2] = { 0, 437 };
56
57    regs.d.eax = 0x440C;                /* GENERIC IO FOR HANDLES */
58    regs.d.ebx = 1;                     /* STDOUT */
59    regs.d.ecx = 0x036A;                /* 3 = CON, 0x6A = QUERY SELECTED CP */
60    regs.x.ds = __tb >> 4;              /* using transfer buffer for low mem. */
61    regs.x.dx = __tb & 0x0F;            /* (suggested by DJGPP FAQ, hi Eli!) */
62    regs.x.flags |= 1;                  /* preset carry for potential failure */
63    __dpmi_int (0x21, &regs);
64
65    if (!(regs.x.flags & 1))            /* if succeed (carry flag not set) */
66      dosmemget( __tb, 4, param_block);
67    else {                              /* (undocumented method) */
68      regs.x.ax = 0xAD02;               /* 440C -> MS-DOS or DR-DOS only */
69      regs.x.bx = 0xFFFE;               /* AD02 -> MS-DOS or FreeDOS only */
70      regs.x.flags |= 1;
71      __dpmi_int(0x2F, &regs);
72
73      if ((!(regs.x.flags & 1)) && (regs.x.bx < 0xFFFE))
74        param_block[1] = regs.x.bx;
75    }
76
77    return param_block[1];
78 }
79 #elif defined(__WATCOMC__) && defined(__I86__) /* Watcom C, 16 bit Intel */
80
81 /* rugxulo _AT_ gmail _DOT_ com */
82
83 #include <stdio.h>
84 #include <dos.h>
85 #include <i86.h>
86
87 unsigned short query_con_codepage(void) {
88    union REGS regs;
89    unsigned short param_block[2] = { 0, 437 };
90
91    regs.x.ax = 0x440C;           /* GENERIC IO FOR HANDLES */
92    regs.x.bx = 1;                /* STDOUT */
93    regs.x.cx = 0x036A;           /* 3 = CON, 0x6A = QUERY SELECTED CP */
94    regs.x.dx = (unsigned short)param_block;
95    regs.x.cflag |= 1;            /* preset carry for potential failure */
96    int86(0x21, &regs, &regs);
97
98    if (regs.x.cflag)             /* if not succeed (carry flag set) */
99    {
100      regs.x.ax = 0xAD02;         /* 440C -> MS-DOS or DR-DOS only */
101      regs.x.bx = 0xFFFE;         /* AD02 -> MS-DOS or FreeDOS only */
102      regs.x.cflag |= 1;
103      int86(0x2F, &regs, &regs);
104    }
105
106      if ((!(regs.x.cflag)) && (regs.x.bx < 0xFFFE))
107        param_block[1] = regs.x.bx;
108
109    return param_block[1];
110
111 }
112
113 #elif defined(__WATCOMC__) && defined(__DOS__) /* Watcom C, 32 bit DOS */
114
115 /* rugxulo _AT_ gmail _DOT_ com */
116
117 #include <stdio.h>
118 #include <dos.h>
119 #include <i86.h>
120
121 unsigned short query_con_codepage(void) {
122    union REGS regs;
123    unsigned short param_block[2] = { 0, 437 };
124
125    regs.x.eax = 0x440C;           /* GENERIC IO FOR HANDLES */
126    regs.x.ebx = 1;                /* STDOUT */
127    regs.x.ecx = 0x036A;           /* 3 = CON, 0x6A = QUERY SELECTED CP */
128    regs.x.edx = (unsigned short)param_block;
129    regs.x.cflag |= 1;             /* preset carry for potential failure */
130    int386(0x21, &regs, &regs);
131
132    if (regs.x.cflag)              /* if not succeed (carry flag set) */
133    {
134      regs.x.eax = 0xAD02;         /* 440C -> MS-DOS or DR-DOS only */
135      regs.x.ebx = 0xFFFE;         /* AD02 -> MS-DOS or FreeDOS only */
136      regs.x.cflag |= 1;
137      int386(0x2F, &regs, &regs);
138    }
139
140      if ((!(regs.x.cflag)) && (regs.x.ebx < 0xFFFE))
141        param_block[1] = regs.x.ebx;
142
143    return param_block[1];
144
145 }
146
147
148 #elif defined (WIN32) && !defined(__CYGWIN__) /* Windows, not Cygwin */
149
150 /* Erwin Waterlander */
151
152 #include <windows.h>
153 unsigned short query_con_codepage(void) {
154
155   /* Dos2unix is modelled after dos2unix under SunOS/Solaris.
156    * The original dos2unix ISO mode on SunOS supported code
157    * pages CP437, CP850, CP860, CP863, and CP865, which
158    * are DOS code pages. Therefore we request here the DOS
159    * code page of the Console. The DOS code page is used
160    * by DOS programs, for instance text editor 'edit'.
161    */
162
163   /* Get the console's DOS code page */
164    return((unsigned short)GetConsoleOutputCP());
165
166    /* Get the system's ANSI code page */
167    /* return((unsigned short)GetACP()); */
168
169 }
170
171 #elif defined (__OS2__) /* OS/2 Warp */
172
173 #define INCL_DOS
174 #include <os2.h>
175
176 unsigned short query_con_codepage(void) {
177   ULONG cp[3];
178   ULONG cplen;
179
180   DosQueryCp(sizeof(cp), cp, &cplen);
181   return((unsigned short)cp[0]);
182 }
183
184 #else  /* Unix, other */
185 unsigned short query_con_codepage(void) {
186    return(0);
187 }
188 #endif
189
190 #ifdef TEST
191 int main() {
192   printf("\nCP%u\n",query_con_codepage() );  /* should be same result as */
193   return 0;                                  /*   "mode con cp /status" */
194 }
195 #endif
196