home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
showcp.zip
/
showcp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-28
|
90KB
|
3,247 lines
/*
* showcp: Show Codepages
*
* Function:
* This application display and prints codepages in OS/2 PM.
* This is done as a test of the PM codepage and font support.
* It also acts as online unicode and codepage documentation.
*
* Notes:
*
* Todo:
* - Font selecton
* - Help
*/
/*
* Include files
*/
#include <stdio.h>
#include <string.h>
#include <wcstr.h>
#include <stdlib.h>
#include <ctype.h>
#include <io.h>
#include <direct.h>
#define INCL_PM
#define INCL_SPL
#define INCL_SPLDOSPRINT
#define INCL_DOS
#include <os2.h>
#define INCL_GRE_STRINGS
#include <pmddi.h>
#include "showcp.h"
/*
* Global variables
*/
HWND hwndMainFrame = NULLHANDLE; /* handle to the main frame window */
HWND hwndMain; /* handle to the main client window */
HDC hdcMain; /* handle to the DC of the client */
HAB hab; /* anchor block for the process */
HMQ hmq; /* handle to the process' message queue */
CHAR szAppName[MAXNAMEL]; /* buffer for application name string */
BOOL fHelpEnabled; /* flag to determine if help is enabled */
UniChar * FileBuf, * CurFileBuf;
int FontNum;
int Linesize = 30;
int Textsize = 20;
int LineOffset = 7;
int TabSize = 34;
int Equalsize = 110;
int Leftmar = 50;
int Ward = 0;
int InWard = 0;
int Info = 0;
int InInfo = 0;
int HoverMax;
int HoverLen;
int HoverInfo;
char * Font;
char DbcsStarter[256];
char DbcsSecond[256];
UconvObject UconvO;
UconvObject Uconv1207, Uconv1386, Uconv949;
int Codepage;
char CodeName[64];
int FontCp;
int FontSize;
int TopPos, LeftPos;
int IsDbcs;
int Match4, Match5;
char * UniTable;
char Debugflag;
char Sizeflag;
int doargs(int argc, char * * argv);
void setsizes(void);
int QueryPrintQueue(char * qname, char * drvname);
VOID Print(int showuni);
/*
* Font name mapping
*/
char * Fonts[] = {
"Times New Roman", "Times New Roman Bold", "Times New Roman Italic", "Times New Roman Bold Italic",
"Helvetica", "Helvetica Bold", "Helvetica Italic", "Helvetica Bold Italic",
"Courier", "Courier Bold", "Courier Italic", "Courier Bold Italic",
"System Proportional", "System Proportional", "System Proportional", "System Proportional",
"System VIO", "System VIO", "System VIO", "System VIO",
"Times New Roman MT 30", "DFP-SMTWSong", "Times New Roman MT 30", "Times New Roman MT 30",
"Arial", "Arial Bold", "Arial Italic", "Arial Bold Italic",
"Symbol", "Symbol", "Symbol", "Symbol",
"Wingdings", "Wingdings", "Wingdings", "Wingdings",
"ITC Zapf Dingbats", "ITC Zapf Dingbats", "ITC Zapf Dingbats", "ITC Zapf Dingbats",
"Tms Rmn", "Tms Rmn ISO", "Tms Rmn", "Tms Rmn",
"Helv", "Helv ISO", "Helv", "Helv",
"Courier New", "Courier New Bold", "Courier New Italic", "Courier New Bold Italic",
"Bitstream Cyberbit", "Bitstream Cyberbit", "Bitstream Cyberbit", "Bitstream Cyberbit",
"Lucida Sans Unicode", "Lucida Sans Unicode", "Monotype.com", "Monotype.com",
"HeiseiMincho-W3-90-TT", "HeiseiKakuGothic-W5-90-TT", "HeiseiMincho-W3-90-TT", "HeiseiKakuGothic-W5-90-TT",
"Times New Roman WT J", "Times New Roman WT J", "Times New Roman WT J", "Times New Roman WT J",
"Monotype Sans Duospace WT J", "Monotype Sans WT", "Monotype Sans Duospace WT J", "Monotype Sans Duospace WT J",
"", "", "", "",
};
/*
*
* main: Set up PM
*
*/
int main(int argc, char * * argv) {
QMSG qmsg; /* message structure */
ULONG ctldata; /* frame control data */
int i, rc;
char * arg;
UniChar glyphs[20];
SWP deskp, winp;
/*
* Create the HAB and Message Queues
*/
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
/*
* Process arguments and do initialization
*/
doargs(argc, argv);
if (!Init()) {
MessageBox(HWND_DESKTOP, IDMSG_INITFAILED,
MB_OK | MB_ERROR, TRUE);
return 1;
}
/* NOTE: clean up from here is handled by the DosExitList processing */
/*
* create the main window
*/
ctldata = FCF_STANDARD;
hwndMainFrame = WinCreateStdWindow(HWND_DESKTOP,
WS_VISIBLE,
&ctldata,
(PSZ)szAppName,
(PSZ)NULL,
WS_VISIBLE,
(HMODULE)NULL,
IDR_MAIN,
(PHWND)&hwndMain);
if (!hwndMainFrame) {
MessageBox(HWND_DESKTOP,
IDMSG_MAINWINCREATEFAILED,
MB_OK | MB_ERROR,
TRUE);
return 1;
}
/*
* Make sure the window is on the screen. This is important because
* we do not support scrolling.
*/
hdcMain = WinOpenWindowDC(hwndMain);
WinQueryWindowPos(HWND_DESKTOP, &deskp);
setsizes();
WinSetWindowPos(hwndMainFrame, NULL, 0, 0, TabSize*18, Linesize*20, SWP_SIZE);
WinQueryWindowPos(hwndMainFrame, &winp);
if (winp.y + Linesize*20 > deskp.cy) {
WinSetWindowPos(hwndMainFrame, NULL, winp.x, deskp.cy - Linesize*20, 0, 0, SWP_MOVE);
}
/*
* No help yet
*/
/* InitHelp(); */
/*
* Get/Dispatch Message loop
*/
while(WinGetMsg(hab, (PQMSG)&qmsg, (HWND)NULL, (ULONG)NULL, (ULONG)NULL))
WinDispatchMsg(hab, (PQMSG)&qmsg);
/*
* No help yet
*/
/* DestroyHelpInstance(); */
return 0;
}
/*
* doargs: Process arguments
*/
int doargs(int argc, char * * argv) {
int argcnt;
char * argp;
char swchar;
argcnt = 1;
Sizeflag = 2;
FontSize = 14;
/*
* Read the arguments and decide what we are doing
*/
while (argcnt<argc) {
argp = argv[argcnt];
/*
* Check for switches.
*/
if (*argp == '-' && argp[1]) {
/* Process switches */
swchar = (char)tolower(argp[1]);
argp += 2;
switch (swchar) {
/*
* -s -- Small flag
*/
case 's':
Sizeflag = 1;
FontSize = 12;
break;
/*
* -l -- Large flag
*/
case 'l':
Sizeflag = 3;
FontSize = 14;
break;
/*
* -d -- Debug option.
*/
case 'd':
Debugflag = 1;
if (argp[-1]=='D') Debugflag=2;
break;
}
} else {
Codepage = atoi(argp);
}
argcnt++;
}
return 0;
}
/*
* setsizes: Set basic sizes
*/
void setsizes(void) {
HPS hps;
HDC hdc;
LONG fontres;
/*
* If size is not set by user, default it based on screen resolution
*/
if (Sizeflag==2) {
hps = WinGetPS(HWND_DESKTOP);
hdc = GpiQueryDevice(hps);
DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1, &fontres);
if (fontres<100) {
Sizeflag = 1;
FontSize = 12;
} else {
Sizeflag = 3;
FontSize = 14;
}
}
/*
* Set for small size
*/
if (Sizeflag<2) {
Linesize = 24;
Textsize = 16;
LineOffset = 6;
TabSize = 27;
}
/*
* Set for large size
*/
else {
Linesize = 30;
Textsize = 20;
LineOffset = 7;
TabSize = 34;
}
}
/*
* MainWndProc: Main window procedure
*
*/
MRESULT EXPENTRY MainWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
int i;
int dodefault = 0;
RECTL rect;
switch(msg) {
case WM_CREATE:
return InitMainWindow(hwnd, mp1, mp2);
break;
case WM_PAINT:
MainPaint(hwnd);
break;
case WM_MOUSEMOVE:
dodefault = 1;
i = getposition(SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
if (i != HoverInfo) {
rect.xLeft = 0;
rect.xRight = HoverLen;
rect.yTop = HoverMax;
rect.yBottom = HoverMax-Linesize;
WinInvalidateRect(hwnd, &rect, FALSE);
HoverInfo = i;
}
break;
case WM_BUTTON1DOWN:
dodefault = 1;
i = getposition(SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
if (i>255) {
if (InInfo) {
InInfo = 0;
Info = 0;
setupfont(hwnd);
} else {
if (InWard) {
Ward = 0;
InWard = 0;
setupfont(hwnd);
}
}
break;
}
if (InWard == 0 && DbcsStarter[i]==2) {
Ward = i;
InWard = 1;
setupfont(hwnd);
break;
}
if ((InWard == 0 && DbcsStarter[i]==1) ||
(InWard && DbcsSecond[i]==1) ) {
Info = i;
InInfo = 1;
setupfont(hwnd);
}
break;
case WM_COMMAND:
MainCommand(mp1, mp2, hwnd);
break;
case WM_INITMENU:
InitMenu(mp1, mp2);
break;
case HM_QUERY_KEYS_HELP:
return (MRESULT)PANEL_HELPKEYS; /* return id of key help panel */
break;
default: /* default must call WinDefWindowProc() */
dodefault = 1;
break;
}
if (dodefault)
return WinDefWindowProc(hwnd, msg, mp1, mp2);
return (MRESULT)0;
}
/*
* MessageBox: Show a message
*/
ULONG MessageBox(HWND hwndOwner, ULONG idMsg, ULONG fsStyle, BOOL fBeep) {
CHAR szText[MESSAGELEN];
if (!WinLoadMessage(hab, (HMODULE)NULL, idMsg, MESSAGELEN, (PSZ)szText)) {
WinAlarm(HWND_DESKTOP, WA_ERROR);
return MBID_ERROR;
}
if (fBeep)
WinAlarm(HWND_DESKTOP, WA_ERROR);
return(WinMessageBox(HWND_DESKTOP, hwndOwner, szText, (PSZ)NULL, MSGBOXID,
fsStyle));
}
/*
* setupfont: Set up font
*/
void setupfont(HWND hwnd) {
int rc;
ULONG codepage;
char fontname[128];
/*
* Change the Win codepage. This should not really be necessary, but
* it has the virtue of actually working.
*/
if (Codepage == 1200) {
if (Ward>=0x34 && Ward<0xf8) {
if (Ward>=0xac && Ward<0xd8)
WinSetCp(hmq, 949);
else
WinSetCp(hmq, 1386);
} else {
WinSetCp(hmq, 1207);
}
}
sprintf(fontname, "%d.%s", FontSize, Font);
/*
* This should be changed someday since this has significant problems
* when there are multiple fonts by the same name.
*/
WinSetPresParam(hwndMain, PP_FONTNAMESIZE,
(ULONG)strlen(fontname) + 1,
(PVOID)fontname);
WinInvalidateRect( hwnd, NULL, FALSE );
UpdateTitleText(hwndMainFrame);
}
/*
* setupcp: Set up codepage
*/
int setupcp(int codepage) {
UniChar cpname[64];
ULONG cplist[128], * cpl;
int rc;
int count;
uconv_attribute_t attr;
UconvObject uo;
/*
* Make sure PM knows about this codepage
*/
count = WinQueryCpList(hab, 128, cplist);
cpl = cplist;
while (count) {
if (*cpl == codepage)
break;
count--;
cpl++;
}
if (count==0 && codepage != 1200) {
MessageBox(HWND_DESKTOP, IDMSG_NOCP, MB_OK | MB_ERROR, TRUE);
return 1;
}
/*
* Make sure we have a ULS conversion object
*/
UniMapCpToUcsCp(codepage, cpname, 16);
UniStrcat(cpname, L"@path=no,map=display");
rc = UniCreateUconvObject(cpname, &uo);
if (rc) {
MessageBox(HWND_DESKTOP, IDMSG_NOCP, MB_OK | MB_ERROR, TRUE);
return 1;
}
/*
* Make sure we have the other necessary converters
*/
if (codepage == 1200 && !Uconv1207) {
UniCreateUconvObject(L"IBM-1207", &Uconv1207);
UniCreateUconvObject(L"IBM-1386@path=no", &Uconv1386);
UniCreateUconvObject(L"IBM-949@path=no", &Uconv949);
if (!Uconv1207 || !Uconv1386 || !Uconv949) {
MessageBox(HWND_DESKTOP, IDMSG_NOCP, MB_OK | MB_ERROR, TRUE);
return 1;
}
}
/*
* This is supposed to always work since we checked if the codepage
* was supported above. This fails for some DBCS versions. In any
* case, the return code is unreliable, so we ignore it. (The return
* code is bad due to an uninitialized variable in winres.c which will
* be fixed for Aurora).
*/
rc = WinSetCp(hmq, codepage==1200?1207:codepage);
/*
* Switch to the new codepage
*/
Codepage = codepage;
CodeName[0] = 0;
WinLoadString(hab, (HMODULE)0, Codepage+IDM_CODEPAGE, 64, CodeName);
Ward = 0;
InWard = 0;
if (UconvO)
UniFreeUconvObject(UconvO);
UconvO = uo;
/*
* Circumvent a bug in QueryUconvObject. This is fixed now, but this
* makes it work on older systems.
*/
UniQueryUconvObject(UconvO, &attr, sizeof(attr), DbcsStarter, DbcsSecond, NULL);
if (Codepage == 1200) {
memset(DbcsStarter, 2, 256);
memset(DbcsStarter+0xD8, 0xff, 8);
memset(DbcsSecond, 1, 256);
}
if (Codepage == 1207) {
memset(DbcsStarter, 1, 128);
memset(DbcsStarter+0x80, 2, 128);
memset(DbcsStarter+0xe8, 0xff, 8);
memset(DbcsStarter+0xF0, 3, 4);
memset(DbcsSecond, 0, 128);
memset(DbcsSecond+0x80, 1, 128);
}
if (Codepage == 1208) {
memset(DbcsStarter, 1, 128);
memset(DbcsStarter+0x80, 0xff, 64);
memset(DbcsStarter+0xc0, 2, 32);
memset(DbcsStarter+0xe0, 3, 32);
memset(DbcsSecond, 0, 256);
memset(DbcsSecond+0x80, 1, 64);
}
/*
* Select if this is DBCS
*/
if (attr.mb_max_len > 1)
IsDbcs = 1;
else
IsDbcs = 0;
return 0;
}
/*
* createfonts: Create logical fonts
*/
void createfonts(HPS hps) {
FATTRS fat;
HDC hdc;
int rc;
char names[256];
LONG types[16], ids[16];
FONTMETRICS * fm, * buf;
LONG count, i, fontres;
/*
* If we have already found the font, do not look again
*/
if (!Match4) {
buf = malloc(64000);
count = 64000/sizeof(FONTMETRICS);
hps = WinGetPS(HWND_DESKTOP);
hdc = GpiQueryDevice(hps);
DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1, &fontres);
rc = GpiQueryFonts (hps, QF_PUBLIC, "Helv", &count,
sizeof(*fm), (FONTMETRICS *)buf);
fm = buf;
for (i=0; i<count; i++) {
if (fontres==fm->sXDeviceRes) {
if (fm->sNominalPointSize == ((Sizeflag<2) ? 80 : 100))
Match4 = fm->lMatch;
if (fm->sNominalPointSize == ((Sizeflag<2) ? 100 : 120))
Match5 = fm->lMatch;
}
fm++;
}
free(buf);
}
/*
* Create the fonts in this PS
*/
memset(&fat, 0, sizeof(FATTRS));
fat.usRecordLength = sizeof(FATTRS);
strcpy(fat.szFacename, "Helv");
fat.usCodePage = 850;
fat.lMatch = Match4;
rc = GpiCreateLogFont(hps, (PSTR8)"helv10", 4, &fat);
fat.lMatch = Match5;
rc = GpiCreateLogFont(hps, (PSTR8)"helv12", 5, &fat);
rc = GpiQuerySetIds(hps, 16, types, (PSTR8)names, ids);
}
/*
* MainCommand: Process dialog commands
*/
VOID MainCommand(MPARAM mp1, MPARAM mp2, HWND hwnd) {
UniChar * pos;
int i;
int rc;
i = SHORT1FROMMP(mp1);
/*
* Select a codepage
*/
if (i>IDM_CODEPAGE && i<IDM_CODEPAGE+4095) {
setupcp(i-10000);
setupfont(hwnd);
return;
}
/*
* Select a font
*/
if (i>IDM_FONT && i<IDM_FONT+100) {
FontNum = i-IDM_FONT-4;
Font = Fonts[FontNum];
setupfont(hwnd);
return;
}
/*
* Set size
*/
if (i>IDM_SIZE && i<IDM_SIZE+100) {
FontSize = i-IDM_SIZE;
setupfont(hwnd);
return;
}
switch(i) {
/*
* Set attibutes
*/
case IDM_NORMAL:
Font = Fonts[FontNum];
setupfont(hwnd);
break;
case IDM_BOLD:
Font = Fonts[FontNum + 1];
setupfont(hwnd);
break;
case IDM_ITALIC:
Font = Fonts[FontNum + 2];
setupfont(hwnd);
break;
case IDM_BOLDITALIC:
Font = Fonts[FontNum + 3];
setupfont(hwnd);
break;
/*
* Terminate
*/
case IDM_EXIT:
exit(1);
break;
/*
* Go back a level (escape key)
*/
case IDM_ESCAPE:
if (InInfo) {
InInfo = 0;
Info = 0;
setupfont(hwnd);
break;
}
if (InWard) {
Ward = 0;
InWard = 0;
setupfont(hwnd);
}
break;
/*
* Previous page
*/
case IDM_PAGEUP:
if (InInfo) {
Info--;
if (Info<0)
Info = 255;
WinInvalidateRect( hwnd, NULL, FALSE );
break;
}
if (InWard) {
i = Ward - 1;
while (i >= 0) {
if (DbcsStarter[i] == 2) {
Ward = i;
setupfont(hwnd);
break;
}
i--;
}
if (i<0) {
Ward = 0;
InWard = 0;
}
setupfont(hwnd);
}
break;
/*
* Next page
*/
case IDM_PAGEDOWN:
if (InInfo) {
Info++;
if (Info>255)
Info = 0;
WinInvalidateRect( hwnd, NULL, FALSE );
break;
}
if (InWard) {
i = Ward + 1;
while (i < 256) {
if (DbcsStarter[i] == 2) {
Ward = i;
setupfont(hwnd);
break;
}
i++;
}
if (i>255) {
InWard = 0;
Ward = 0;
}
setupfont(hwnd);
}
break;
/*
* Print with annotation
*/
case IDM_PRINT:
Print(1);
break;
/*
* Print without annotation
*/
case IDM_PRINTI:
Print(2);
break;
/*
* Print without annotation
*/
case IDM_PRINTNU:
Print(0);
break;
case IDM_HELPINDEX:
HelpIndex();
break;
case IDM_HELPGENERAL:
HelpGeneral();
break;
case IDM_HELPUSINGHELP:
HelpUsingHelp();
break;
case IDM_HELPKEYS:
HelpKeys();
break;
case IDM_HELPTUTORIAL:
HelpTutorial();
break;
case IDM_HELPPRODUCTINFO:
HelpProductInfo();
break;
default:
break;
}
}
/*
* getposition: Get mouse position
*/
int getposition(int x, int y) {
int xx, yy;
int topoff;
if (InInfo) {
return 256;
}
topoff = TopPos - LineOffset;
if (x<LeftPos || x>(LeftPos+16*TabSize) ||
y>(topoff) || y<(topoff-16*Linesize) ) {
return 256;
}
xx = (x-LeftPos)/TabSize;
yy = -(y-topoff)/Linesize;
return (yy<<4) + xx;
}
/*
* painthover: Paint the hover information
*/
void painthover(HPS hps) {
char info[256];
int rc;
POINTL point;
char charbuf[4];
UniChar unis[4];
char * cp, * token[16], temp[128];
if (HoverInfo<256) {
if (!InWard && DbcsStarter[HoverInfo] != 1) {
return;
}
if (Codepage == 1200) {
unis[0] = (Ward<<8) | HoverInfo;
unis[1] = 0;
} else {
if (InWard == 0) {
charbuf[0] = HoverInfo;
charbuf[1] = 0;
} else {
charbuf[0] = Ward;
charbuf[1] = HoverInfo;
charbuf[2] = 0;
}
UniStrToUcs(UconvO, unis, charbuf, 4);
}
if (InWard) {
sprintf(info, "%02x%02x %3d/%-3d", Ward, HoverInfo, Ward, HoverInfo);
} else {
sprintf(info, "0x%02x %3d", HoverInfo, HoverInfo);
}
if (unis[0] != 0xfffd) {
sprintf(info+strlen(info), " U%04x", unis[0]);
getglyph(unis[0]);
if (!*GlyphAdobe && !*GlyphIBM && unis[0]) {
cp = getuniinfo(unis[0]);
if (*cp) {
tokenuni(cp, temp, token);
if (token[1]) {
cp = info+strlen(info);
strcpy(cp, " - ");
strcat(cp, token[1]);
strlwr(cp);
}
}
} else {
if (*GlyphAdobe) {
strcat(info, " - ");
strcat(info, GlyphAdobe);
}
if (*GlyphIBM) {
strcat(info, " - ");
strcat(info, GlyphIBM);
}
}
}
GpiSetCharSet(hps, 4);
point.x = LeftPos;
point.y = HoverMax-Textsize;
GpiMove(hps, &point);
rc = GpiCharString(hps, strlen(info), info);
}
}
/*
* dogrid: Put out the grid system
*/
void dogrid(HPS hps) {
int rc, i;
ULONG len, ulen;
char charbuf[4];
POINTL point;
point.x = LeftPos -8;
for (i=0; i<=16; i++) {
point.y = TopPos - LineOffset;
GpiMove(hps, &point);
point.y -= Linesize * 16;
GpiLine(hps, &point);
point.x += TabSize;
}
point.y = TopPos - LineOffset;
for (i=0; i<=16; i++) {
point.x = 42;
GpiMove(hps, &point);
point.x += TabSize * 16;
GpiLine(hps, &point);
point.y -= Linesize;
}
point.x = LeftPos;
point.y = TopPos;
charbuf[0] = '-';
charbuf[2] = 0;
len = 2;
GpiSetCharSet(hps, 5);
for (i=0; i<16; i++) {
GpiMove(hps, &point);
charbuf[1] = hexstr[i];
rc = GpiCharString(hps, len, charbuf);
point.x += TabSize;
}
point.x = LeftPos - 35;
point.y = TopPos - Linesize;
charbuf[1] = '-';
charbuf[2] = 0;
len = 2;
GpiSetCharSet(hps, 5);
for (i=0; i<16; i++) {
GpiMove(hps, &point);
charbuf[0] = hexstr[i];
rc = GpiCharString(hps, len, charbuf);
point.y -= Linesize;
}
}
/*
* MainPaint: Paint the client window
*/
VOID MainPaint(HWND hwnd) {
RECTL rclUpdate;
RECTL rectl;
POINTL point;
SIZEF sizef;
HPS hps;
int rc, i;
ULONG len, ulen;
char charbuf[4], strbuf[100], temp[256];
char * token[16];
long saveid, saveclr;
UniChar unis[4];
char * cp, * tp;
hps = WinBeginPaint(hwnd, NULLHANDLE, &rclUpdate);
/*
* fill update rectangle with window color
*/
WinQueryWindowRect( hwnd, &rectl );
WinFillRect(hps, &rectl, SYSCLR_WINDOW);
if (!Font) {
Font = "Times New Roman MT 30";
FontNum = 20;
if (!Codepage) {
Codepage = WinQueryCp(hmq);
}
if (setupcp(Codepage)) {
Codepage = WinQueryCp(hmq);
setupcp(Codepage);
}
setupfont(hwnd);
}
TopPos = rectl.yTop - Textsize;
HoverMax = TopPos - (Linesize*16+LineOffset);
LeftPos = 50;
HoverLen = LeftPos + TabSize * 16;
saveid = GpiQueryCharSet(hps);
createfonts(hps);
GpiSetCp(hps, 850);
/*
* Show the info page
*/
if (InInfo) {
GpiSetCharSet(hps, 5);
point.x = Leftmar;
point.y = TopPos - 220;
GpiMove(hps, &point);
GpiCharString(hps, 8, "Codepage");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
sprintf(strbuf, "= %d - %s", Codepage, CodeName);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 4, "Font");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
sprintf(strbuf, "= %s", Font);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 9, "Codepoint");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
if (InWard) {
sprintf(strbuf, "= %02X%02X", Ward, Info);
} else {
sprintf(strbuf, "= %02X (%d)", Info, Info);
}
rc = GpiCharString(hps, strlen(strbuf), strbuf);
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiMove(hps, &point);
GpiCharString(hps, 7, "UniCode");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
if (Codepage == 1200) {
unis[0] = (Ward<<8) | Info;
unis[1] = 0;
memset(charbuf, 0, 4);
if (Ward>=0x34 && Ward<0xf8) {
if (Ward>=0xac && Ward<0xd8)
UniStrFromUcs(Uconv949, charbuf, unis, 4);
else
UniStrFromUcs(Uconv1386, charbuf, unis, 4);
} else {
UniStrFromUcs(Uconv1207, charbuf, unis, 4);
}
len = strlen(charbuf);
} else {
if (InWard == 0) {
charbuf[0] = Info;
charbuf[1] = 0;
len = 1;
} else {
charbuf[0] = Ward;
charbuf[1] = Info;
charbuf[2] = 0;
len = 2;
}
UniStrToUcs(UconvO, unis, charbuf, 4);
}
sprintf(strbuf, "= %04X", unis[0]);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
/*
* Put out Adobe glyph name
*/
getglyph(unis[0]);
if (*GlyphAdobe) {
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 10, "Glyph name");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
sprintf(strbuf, "= %s", GlyphAdobe);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
}
/*
* Put out IBM Glpyh name
*/
if (*GlyphIBM) {
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 9, "IBM glyph");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
sprintf(strbuf, "= %s", GlyphIBM);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
}
/*
* Put out the data from the unicode tables
*/
cp = getuniinfo(unis[0]);
if (*cp) {
tokenuni(cp, temp, token);
/*
* Description
*/
if (*token[1]) {
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 11, "Description");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
if (!strcmp(token[1], "<control>")) {
sprintf(strbuf, "= %s %s", token[1], token[10]);
} else {
sprintf(strbuf, "= %s", token[1]);
}
strlwr(strbuf);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
}
/*
* Type
*/
if (*token[2]) {
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 4, "Type");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
cp = getdesc(token[2], UniTypes);
sprintf(strbuf, "= %s", cp);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
}
/*
* Direction
*/
if (*token[4]) {
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 9, "Direction");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
if (*token[9] == 'Y') {
cp = getdesc("MN", BidiTypes);
} else {
cp = getdesc(token[4], BidiTypes);
}
sprintf(strbuf, "= %s", cp);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
}
/*
* Compose
*/
if (*token[5]) {
point.x = Leftmar;
point.y -= Textsize;
GpiMove(hps, &point);
GpiCharString(hps, 7, "Compose");
point.x = Leftmar+Equalsize;
GpiMove(hps, &point);
sprintf(strbuf, "= %s", token[5]);
rc = GpiCharString(hps, strlen(strbuf), strbuf);
}
}
/*
* Set the codepage
*/
if (Codepage != 1200) {
GpiSetCp(hps, Codepage);
} else {
if (Ward>=0x34 && Ward<0xf8)
if (Ward>=0xac && Ward<0xd8)
GpiSetCp(hps, 949);
else
GpiSetCp(hps, 1386);
else
GpiSetCp(hps, 1207);
}
/*
* Set the font back to the original
*/
GpiSetCharSet(hps, saveid);
/*
* Show a big version of the character
*/
point.x = 100;
point.y = TopPos-150;
GpiMove(hps, &point);
sizef.cx = MAKEFIXED(150, 0);
sizef.cy = MAKEFIXED(150, 0);
GpiSetCharBox(hps, &sizef);
GpiCharString(hps, len, charbuf);
}
/*
* Show a grid page
*/
else {
if (rclUpdate.yTop <= HoverMax) {
painthover(hps);
WinEndPaint(hps);
return;
}
/*
* Output the grid
*/
dogrid(hps);
painthover(hps);
/*
* Put out DBCS
*/
if (IsDbcs) {
saveclr = GpiQueryColor(hps);
GpiSetColor(hps, CLR_RED);
point.y = TopPos - Linesize;
GpiSetCharSet(hps, 4);
point.x = LeftPos;
for (i=0; i<256; i++) {
if (InWard == 0 && DbcsStarter[i] == 2) {
rc = GpiSetCurrentPosition(hps, &point);
charbuf[0] = hexstr[i>>4];
charbuf[1] = hexstr[i&0xf];
rc = GpiCharString(hps, 2, charbuf);
}
point.x += TabSize;
if ((i&0x0f) == 0x0f) {
point.x = LeftPos;
point.y -= Linesize;
}
}
GpiSetColor(hps, saveclr);
GpiSetCharSet(hps, saveid);
}
/*
* Set the codepage and font for the character display
*/
if (Codepage != 1200) {
GpiSetCp(hps, Codepage);
} else {
if (Ward>=0x34 && Ward<0xf8)
if (Ward>=0xac && Ward<0xd8)
GpiSetCp(hps, 949);
else
GpiSetCp(hps, 1386);
else
GpiSetCp(hps, 1207);
}
GpiSetCharSet(hps, saveid);
/*
* Show all characters
*/
point.y = TopPos - Linesize;
point.x = LeftPos;
for (i=0; i<256; i++) {
/*
* Single byte or zero ward
*/
if (InWard == 0) {
charbuf[0] = i;
charbuf[1] = 0;
len = 1;
UniStrToUcs(UconvO, unis, charbuf, 4);
if (unis[0] == 0xfffd)
len = 0;
} else {
/*
* Unicode
*/
if (Codepage == 1200) {
unis[0] = (Ward<<8) | i;
unis[1] = 0;
if (Ward>=0x34 && Ward<0xf8) {
if (Ward>=0xac && Ward<0xd8)
UniStrFromUcs(Uconv949, charbuf, unis, 4);
else
UniStrFromUcs(Uconv1386, charbuf, unis, 4);
} else {
UniStrFromUcs(Uconv1207, charbuf, unis, 4);
}
len = strlen(charbuf);
}
/*
* DBCS
*/
else {
charbuf[0] = Ward;
charbuf[1] = i;
charbuf[2] = 0;
len = 2;
UniStrToUcs(UconvO, unis, charbuf, 4);
if (unis[0] == 0xfffd)
len = 0;
}
}
/*
* Display the character
*/
if ((InWard == 0 && DbcsStarter[i] == 1) ||
(InWard != 0 && DbcsSecond[i] != 0)) {
if (len) {
/*
* Ignore controls
*/
if (!UniQueryChar(unis[0], CT_CNTRL)) {
rc = GpiSetCurrentPosition(hps, &point);
rc = GpiCharString(hps, len, charbuf);
}
}
}
/*
* Move to the next character
*/
point.x += TabSize;
if ((i&0x0f) == 0x0f) {
point.x = LeftPos;
point.y -= Linesize;
}
}
}
WinEndPaint(hps);
}
/*
* createprintfonts: Create fonts for the printer
*/
void createprintfonts(HPS hps) {
FATTRS fat;
ULONG rc;
ULONG cp;
FONTMETRICS * fm, * buf;
LONG count, i, fontres;
LONG match;
/*
* Force the use of non-device outline fonts
*/
buf = malloc(64000);
count = 64000/sizeof(FONTMETRICS);
rc = GpiQueryFonts (hps, QF_PUBLIC | QF_NO_DEVICE, Font, &count,
sizeof(*fm), (FONTMETRICS *)buf);
fm = buf;
for (i=0; i<count; i++) {
if (fm->fsDefn & FM_DEFN_OUTLINE) {
match = fm->lMatch;
break;
}
fm++;
}
free(buf);
memset(&fat, 0, sizeof(FATTRS));
fat.usRecordLength = sizeof(FATTRS);
fat.fsFontUse = FATTR_FONTUSE_OUTLINE;
fat.lMatch = match;
cp = Codepage;
if (Codepage == 1200) {
if (Ward>=0x34 && Ward<0xf8) {
if (Ward>=0xac && Ward<0xd8)
cp = 949;
else
cp = 1386;
} else {
cp = 1207;
}
}
GpiSetCp(hps, cp);
strcpy(fat.szFacename, Font);
rc = GpiCreateLogFont(hps, (PSTR8)"basefnt", 2, &fat);
WinSetCp(hmq, 850);
strcpy(fat.szFacename, "Helvetica");
fat.lMatch = 0;
rc = GpiCreateLogFont(hps, (PSTR8)"helv10", 1, &fat);
}
/*
* Print: Print the page
*
* Function:
* Draw a grid containing 256 codepoints to the default printer
*
*
*/
VOID Print(int showuni) {
POINTL point;
SIZEF sizef;
HPS hps;
int rc, i;
ULONG len, ulen;
char charbuf[20], strbuf[256], temp[256];
char * token[16];
long saveid, saveclr;
UniChar unis[4];
char * cp, * tp;
DEVOPENSTRUC dos;
SIZEL sizel;
HDC prhdc;
HPS prhps;
SIZEF cbox, svbox;
int topPos, leftPos, lineSize, tabSize, lineOffset;
UniChar uni[256];
UNICTYPE * utype;
/*
* Set up the DC for printing. Use the default printer
*/
rc = QueryPrintQueue(strbuf, temp);
if (rc) {
MessageBox(HWND_DESKTOP, IDMSG_NOPRINTER,
MB_OK | MB_ERROR, TRUE);
return;
}
if (strchr(temp, '.'))
*(strchr(temp, '.')) = 0;
memset(&dos, 0, sizeof(dos));
dos.pszLogAddress = strbuf;
dos.pszDriverName = temp;
dos.pszDataType = "PM_Q_RAW";
prhdc = DevOpenDC( hab, OD_QUEUED, "*", 4L, (PVOID)&dos, (HDC)NULL );
/*
* Create a PS over the printer device. Use whatever paper size exists.
* Create the units as 1/1440 inch.
*/
sizel.cx = 0;
sizel.cy = 0;
prhps = GpiCreatePS( hab, prhdc, &sizel, PU_TWIPS | GPIA_ASSOC );
/*
* Start the job
*/
if (InWard) {
sprintf(temp, "Codepage %d [%02x]", Codepage, Ward);
} else {
sprintf(temp, "Codepage %d", Codepage);
}
DevEscape( prhdc, DEVESC_STARTDOC, strlen(temp), (PBYTE)temp,
(PLONG)NULL, (PBYTE)NULL );
/*
* Specify the size and positions. All units in 1/1440 inch
*/
topPos = 12300;
leftPos = 1200;
lineSize = 580;
tabSize = 580;
lineOffset = 200;
/*
* Create the fonts in this PS. We create two fonts, the character font,
* and a Helvetica font for other information.
*/
createprintfonts(prhps);
/*
* Put out the title and font lines
*/
GpiSetCp(prhps, 850);
GpiSetCharSet(prhps, 1);
cbox.cx = MAKEFIXED(400, 0);
cbox.cy = MAKEFIXED(400, 0);
GpiSetCharBox(prhps, &cbox);
if (InWard) {
sprintf(temp, "Codepage %d [%02x] - %s", Codepage, Ward, CodeName);
} else {
sprintf(temp, "Codepage %d - %s", Codepage, CodeName);
}
point.y = topPos + lineSize*2;
point.x = leftPos - 380;
GpiMove(prhps, &point);
len = strlen(temp);
rc = GpiCharString(prhps, len, temp);
cbox.cx = MAKEFIXED(240, 0);
cbox.cy = MAKEFIXED(240, 0);
GpiSetCharBox(prhps, &cbox);
point.y -= 400;
GpiMove(prhps, &point);
len = strlen(Font);
rc = GpiCharString(prhps, len, Font);
/*
* Output the vertical lines of the grid
*/
point.x = leftPos - 100;
for (i=0; i<=16; i++) {
point.y = topPos - lineOffset;
GpiMove(prhps, &point);
point.y -= lineSize * 16;
GpiLine(prhps, &point);
point.x += tabSize;
}
/*
* Output the horizontal lines of the grid
*/
point.y = topPos - lineOffset;
for (i=0; i<=16; i++) {
point.x = leftPos - 100;
GpiMove(prhps, &point);
point.x += tabSize * 16;
GpiLine(prhps, &point);
point.y -= lineSize;
}
/*
* Output the top legend
*/
point.x = leftPos + 100;
point.y = topPos - 90;
charbuf[0] = '-';
charbuf[2] = 0;
len = 2;
for (i=0; i<16; i++) {
GpiMove(prhps, &point);
charbuf[1] = hexstr[i];
rc = GpiCharString(prhps, len, charbuf);
point.x += tabSize;
}
/*
* Output the left legend
*/
point.x = leftPos - 400;
point.y = topPos - lineSize;
charbuf[1] = '-';
charbuf[2] = 0;
len = 2;
GpiSetCharSet(prhps, 1);
for (i=0; i<16; i++) {
GpiMove(prhps, &point);
charbuf[0] = hexstr[i];
rc = GpiCharString(prhps, len, charbuf);
point.y -= lineSize;
}
/*
* Put out DBCS sections
*/
if (IsDbcs) {
saveclr = GpiQueryColor(prhps);
GpiSetColor(prhps, CLR_RED);
point.y = topPos - lineSize;
cbox.cx = MAKEFIXED(180, 0);
cbox.cy = MAKEFIXED(180, 0);
GpiSetCharBox(prhps, &cbox);
point.x = leftPos;
for (i=0; i<256; i++) {
if (InWard == 0 && DbcsStarter[i] == 2) {
rc = GpiSetCurrentPosition(prhps, &point);
charbuf[0] = hexstr[i>>4];
charbuf[1] = hexstr[i&0xf];
rc = GpiCharString(prhps, 2, charbuf);
}
point.x += tabSize;
if ((i&0x0f) == 0x0f) {
point.x = leftPos;
point.y -= lineSize;
}
}
GpiSetColor(prhps, saveclr);
}
/*
* Set the codepage for the characters
*/
if (Codepage != 1200) {
GpiSetCp(prhps, Codepage);
} else {
if (Ward>=0x34 && Ward<0xf8)
if (Ward>=0xac && Ward<0xd8)
GpiSetCp(prhps, 949);
else
GpiSetCp(prhps, 1386);
else
GpiSetCp(prhps, 1207);
}
/*
* Set the font for the characters
*/
GpiSetCharSet(prhps, 2);
cbox.cx = MAKEFIXED(340, 0);
cbox.cy = MAKEFIXED(340, 0);
GpiSetCharBox(prhps, &cbox);
/*
* Draw the characters
*/
memset(uni, 0, 512);
point.y = topPos - lineSize;
point.x = leftPos;
for (i=0; i<256; i++) {
/*
* Single byte or leading byte
*/
if (InWard == 0) {
charbuf[0] = i;
charbuf[1] = 0;
len = 1;
UniStrToUcs(UconvO, unis, charbuf, 4);
if (unis[0] == 0xfffd)
len = 0;
} else {
/*
* Unicode display
*/
if (Codepage == 1200) {
unis[0] = (Ward<<8) | i;
unis[1] = 0;
if (Ward>=0x34 && Ward<0xf8) {
if (Ward>=0xac && Ward<0xd8)
UniStrFromUcs(Uconv949, charbuf, unis, 4);
else
UniStrFromUcs(Uconv1386, charbuf, unis, 4);
} else {
UniStrFromUcs(Uconv1207, charbuf, unis, 4);
}
len = strlen(charbuf);
/*
* Do not show characters which are not defined in unicode
*/
utype = UniQueryCharType(unis[0]);
if (utype->charset == CHS_NONCHAR)
len = 0;
}
/*
* DBCS display
*/
else {
charbuf[0] = Ward;
charbuf[1] = i;
charbuf[2] = 0;
len = 2;
UniStrToUcs(UconvO, unis, charbuf, 4);
if (unis[0] == 0xfffd)
len = 0;
}
}
/*
* Draw the character itself
*/
if ((InWard == 0 && DbcsStarter[i] == 1) ||
(InWard != 0 && DbcsSecond[i] != 0)) {
if (len) {
if (!UniQueryChar(unis[0], CT_CNTRL)) {
rc = GpiSetCurrentPosition(prhps, &point);
rc = GpiCharString(prhps, len, charbuf);
}
uni[i] = unis[0];
}
}
/*
* Move to next character
*/
point.x += tabSize;
if ((i&0x0f) == 0x0f) {
point.x = leftPos;
point.y -= lineSize;
}
}
/*
* Put in the annotations
*/
if (showuni) {
/*
* Set up the font and position
*/
GpiSetCharSet(prhps, 1);
GpiSetCp(prhps, 850);
cbox.cx = MAKEFIXED(100, 0);
cbox.cy = MAKEFIXED(100, 0);
GpiSetCharBox(prhps, &cbox);
point.y = topPos - lineSize - lineOffset + 26;
point.x = leftPos + ((showuni==1) ? 190 : 0);
/*
* Put out annotation for each character with a unicode map
*/
for (i=0; i<256; i++) {
if (uni[i]) {
if (showuni==2) {
getglyph(uni[i]);
if (*GlyphIBM) {
strcpy(charbuf, GlyphIBM);
strupr(charbuf);
} else {
if (UniQueryChar(uni[i], CT_CNTRL)) {
*charbuf = 0;
} else {
sprintf(charbuf, "U000%04X", uni[i]);
}
}
} else {
sprintf(charbuf, "%04X", uni[i]);
}
rc = GpiSetCurrentPosition(prhps, &point);
rc = GpiCharString(prhps, strlen(charbuf), charbuf);
}
/*
* Move to next character
*/
point.x += tabSize;
if ((i&0x0f) == 0x0f) {
point.x = leftPos + ((showuni==1) ? 190 : 0);
point.y -= lineSize;
}
}
}
DevEscape( prhdc, DEVESC_ENDDOC,
0L, (PBYTE)NULL, (PLONG)NULL, (PBYTE)NULL );
/*
* Release and destroy the PS
*/
GpiAssociate( prhps, (HDC)NULLHANDLE );
GpiDestroyPS( prhps );
/*
* Inform the user we are done
*/
DosBeep(1000, 200);
}
/**************************************************************************
*
* Name : UpdateTitleText
*
* Description: Updates the text in the main window's title bar to
* display the app name, followed by the separator,
* followed by the file name.
*
* Concepts : Called at init time and when the text file is changed.
* Gets the program name, appends the separator, and
* appends the file name.
*
* API's : WinLoadString
* WinSetWindowText
* WinWindowFromID
*
* Parameters : hwnd = window handle
*
* Return : [none]
*
*************************************************************************/
VOID UpdateTitleText(HWND hwnd)
{
CHAR szBuf[256];
CHAR szSeparator[TITLESEPARATORLEN+1];
char codepg[16];
PSZ pszT;
ULONG codepage;
WinLoadString(hab, (HMODULE)0, IDS_CODEPAGE, MAXNAMEL, szBuf);
WinLoadString(hab, (HMODULE)0, IDS_TITLEBARSEPARATOR, TITLESEPARATORLEN, szSeparator);
itoa(Codepage, codepg, 10);
strcat(szBuf, codepg);
if (InWard) {
sprintf(codepg, "[%02x]", Ward);
strcat(szBuf, codepg);
}
if (*CodeName) {
strcat(szBuf, szSeparator);
strcat(szBuf, CodeName);
}
strcat(szBuf, szSeparator);
if (Font) {
strcat(szBuf, Font);
}
WinSetWindowText(WinWindowFromID(hwnd, FID_TITLEBAR), szBuf);
} /* End of UpdateTitleText */
/**************************************************************************
*
* Name : ProductInfoDlgProc(hwnd, msg, mp1, mp2)
*
* Description: Processes all messages sent to the Product information
* dialog
*
* Concepts: The Product information dialog has only a button control,
* so this routine processes only WM_COMMAND messages. Any
* WM_COMMAND posted must have come from the OK
* button, so we dismiss the dialog upon receiving it.
*
* API's : WinDismissDlg
* WinDefDlgProc
*
* Parameters : hwnd = window handle
* msg = message i.d.
* mp1 = first message parameter
* mp2 = second message parameter
*
* Return : dependent on message sent
*
*************************************************************************/
MRESULT EXPENTRY ProductInfoDlgProc(
HWND hwnd, /* handle of window */
USHORT msg, /* id of message */
MPARAM mp1, /* first message parameter */
MPARAM mp2) /* second message parameter */
{
switch(msg)
{
case WM_INITDLG:
SetSysMenu(hwnd); /* system menu for this dialog */
return MRFROMSHORT(FALSE);
case WM_COMMAND:
/* no matter what the command, close the dialog */
WinDismissDlg(hwnd, TRUE);
break;
default:
return(WinDefDlgProc(hwnd, msg, mp1, mp2));
break;
}
return (MRESULT)NULL;
} /* End of ProductInfoDlgProc */
/**************************************************************************
*
* Name : SetSysMenu(hDlg)
*
* Description: Sets only the Move and Close items of the system menu
*
* Concepts: Any dialog box is free to call this routine, to edit
* which menu items will appear on its System Menu pulldown.
*
* API's : WinWindowFromID
* WinSendMsg
*
* Parameters : hDlg = window handle of the dialog
*
* Return : [none]
*
*************************************************************************/
VOID SetSysMenu(HWND hDlg)
{
HWND hSysMenu;
MENUITEM Mi;
ULONG Pos;
MRESULT Id;
SHORT cItems;
/******************************************************************/
/* We only want Move and Close in the system menu. */
/******************************************************************/
hSysMenu = WinWindowFromID(hDlg, FID_SYSMENU);
WinSendMsg( hSysMenu, MM_QUERYITEM
, MPFROM2SHORT(SC_SYSMENU, FALSE), MPFROMP((PCH) & Mi));
Pos = 0L;
cItems = (SHORT)WinSendMsg( Mi.hwndSubMenu, MM_QUERYITEMCOUNT,
(MPARAM)NULL, (MPARAM)NULL);
while (cItems--)
{
Id = WinSendMsg( Mi.hwndSubMenu, MM_ITEMIDFROMPOSITION
, MPFROMLONG(Pos), (MPARAM)NULL);
switch (SHORT1FROMMR(Id))
{
case SC_MOVE:
case SC_CLOSE:
Pos++; /* Don't delete that one. */
break;
default:
WinSendMsg( Mi.hwndSubMenu, MM_DELETEITEM
, MPFROM2SHORT((USHORT)Id, TRUE), (MPARAM)NULL);
}
}
} /* End of SetSysMenu */
/**************************************************************************
*
* Name : EditUndo(mp2)
*
* Description: Processes selection of the Undo choice of the Edit
* pulldown
*
* Concepts: called whenever Undo from the Edit menu is selected
*
* API's : [none]
*
* Parameters : mp2 = second message parameter
*
* Return : [none]
*
*************************************************************************/
VOID EditUndo(MPARAM mp2)
{
/* This routine currently doesn't use the mp2 parameter but
* it is referenced here to prevent an 'Unreferenced Parameter'
* warning at compile time.
*/
mp2;
} /* End of EditUndo */
/**************************************************************************
*
* Name : EditCut(mp2)
*
* Description: Processes selection of the Cut choice of the Edit
* pulldown
*
* Concepts: called whenever Cut from the Edit menu is selected
*
* API's : [none]
*
* Parameters : mp2 = second message parameter
*
* Return : [none]
*
*************************************************************************/
VOID EditCut(MPARAM mp2)
{
/* This routine currently doesn't use the mp2 parameter but
* it is referenced here to prevent an 'Unreferenced Parameter'
* warning at compile time.
*/
mp2;
} /* End of EditCut */
/**************************************************************************
*
* Name : EditCopy(mp2)
*
* Description: Processes selection of the Copy choice of the Edit
* pulldown
*
* Concepts: called whenever Copy from the Edit menu is selected
*
* API's : [none]
*
* Parameters : mp2 = second message parameter
*
* Return : [none]
*
*************************************************************************/
VOID EditCopy(MPARAM mp2)
{
/* This routine currently doesn't use the mp2 parameter but
* it is referenced here to prevent an 'Unreferenced Parameter'
* warning at compile time.
*/
mp2;
} /* End of EditCopy */
/**************************************************************************
*
* Name : EditPaste(mp2)
*
* Description: Processes selection of the Paste choice of the Edit
* pulldown
*
* Concepts: called whenever Paste from the Edit menu is selected
*
* API's : [none]
*
* Parameters : mp2 = second message parameter
*
* Return : [none]
*
*************************************************************************/
VOID EditPaste(MPARAM mp2)
{
/* This routine currently doesn't use the mp2 parameter but
* it is referenced here to prevent an 'Unreferenced Parameter'
* warning at compile time.
*/
mp2;
} /* End of EditPaste */
/**************************************************************************
*
* Name : EditClear(mp2)
*
* Description: Processes selection of the Clear choice of the Edit
* pulldown
*
* Concepts: called whenever Clear from the Edit menu is selected
*
* API's : [none]
*
* Parameters : mp2 = second message parameter
*
* Return : [none]
*
*************************************************************************/
VOID EditClear(MPARAM mp2)
{
/* This routine currently doesn't use the mp2 parameter but
* it is referenced here to prevent an 'Unreferenced Parameter'
* warning at compile time.
*/
mp2;
} /* End of EditClear */
/**************************************************************************
*
* Name : InitMenu()
*
* Description: Processes the WM_INITMENU message for the main window,
* disabling any menus that are not active.
*
* Concepts: Routine is called each time a menu is dropped.
*
* A switch statement branches control based upon
* the id of the menu that is being displayed.
*
* API's : [none]
*
* Parameters : mp1 = first message parameter
* mp2 = second message parameter
*
* Return : [none]
*
*************************************************************************/
VOID InitMenu(MPARAM mp1, MPARAM mp2)
{
/* define a shorthand way of denoting the menu handle */
#define hwndMenu HWNDFROMMP(mp2)
switch(SHORT1FROMMP(mp1))
{
case IDM_FILE:
break;
case IDM_HELP:
/*
* Enable or disable the Help menu depending upon whether the
* help manager has been enabled
*/
EnableMenuItem(hwndMenu, IDM_HELPUSINGHELP, fHelpEnabled);
EnableMenuItem(hwndMenu, IDM_HELPGENERAL, fHelpEnabled);
EnableMenuItem(hwndMenu, IDM_HELPKEYS, fHelpEnabled);
EnableMenuItem(hwndMenu, IDM_HELPINDEX, fHelpEnabled);
/* REMEMBER: add a case for IDM_HELPTUTORIAL if you include
* the Tutorial menu item.
*/
break;
default:
break;
}
#undef hwndMenu
} /* End of InitMenu */
/**************************************************************************
*
* Name : EnableMenuItem(hwndMenu, idItem, fEnable)
*
* Description: Enables or disables the menu item
*
* Concepts: Called whenever a menu item is to be enabled or
* disabled
*
* Sends a MM_SETITEMATTR to the menu with the
* given item id. Sets the MIA_DISABLED attribute
* flag if the item is to be disabled, clears the flag
* if enabling.
*
* API's : WinSendMsg
*
* Parameters : hwndmenu = menu window handle
* idItem = menu item i.d.
* fEnable = enable (yes) or disable (no)
*
* Return : [none]
*
*************************************************************************/
VOID EnableMenuItem(HWND hwndMenu, USHORT idItem, BOOL fEnable)
{
SHORT fsFlag;
if(fEnable)
fsFlag = 0;
else
fsFlag = MIA_DISABLED;
WinSendMsg(hwndMenu,
MM_SETITEMATTR,
MPFROM2SHORT(idItem, TRUE),
MPFROM2SHORT(MIA_DISABLED, fsFlag));
} /* End of EnableMenuItem() */
/*************************** End of user.c ****************************/
/**************************************************************************
*
* Name : Init()
*
* Description: Performs initialization functions required
* before the main window can be created.
*
* Concepts: Called once before the main window is created.
*
* - Installs the routine ExitProc into the
* DosExitList chain
* - registers all window classes
* - performs any command line processing
*
* API's : DosExitList
* DosExit
* WinLoadString
* WinRegisterClass
*
* Parameters : [none]
*
* Return : TRUE = initialization is successful
* FALSE = initialization failed
*
*************************************************************************/
BOOL Init(VOID)
{
/* Add ExitProc to the exit list to handle the exit processing. If
* there is an error, then terminate the process since there have
* not been any resources allocated yet.
*/
if(DosExitList(EXLST_ADD, (PFNEXITLIST)ExitProc))
{
MessageBox(HWND_DESKTOP,
IDMSG_CANNOTLOADEXITLIST,
MB_OK | MB_ERROR,
TRUE);
DosExit(EXIT_PROCESS, RETURN_ERROR);
}
/* load application name from resource file */
if(0 == WinLoadString(hab, (HMODULE)0, IDS_APPNAME, MAXNAMEL, szAppName))
return FALSE;
/* register the main client window class */
if(!WinRegisterClass(hab,
(PSZ)szAppName,
(PFNWP)MainWndProc,
CS_SIZEREDRAW | CS_CLIPCHILDREN,
0L))
return FALSE;
/* If you wish to create a thread for background processing, define
* the BACKGROUND_THREAD constant
* the routine commented out here. The routines for the background
* thread are in the thrd.c file.
*/
return TRUE;
} /* End of Init */
/**************************************************************************
*
* Name : InitMainWindow(hwnd, mp1, mp2)
*
* Description: Performs initialization functions required
* when the main window is created.
*
* Concepts: Called once during the WM_CREATE processing when
* the main window is created.
*
* API's : [none]
*
* Parameters : hwnd = window handle
* mp1 = first message parameter
* mp2 = second message parameter
*
* Return : value to be returned from the WM_CREATE message:
* TRUE = window creation should stop
* FALSE = window creation should continue
*
*************************************************************************/
MRESULT InitMainWindow(HWND hwnd, MPARAM mp1, MPARAM mp2)
{
char fontname[128];
HWND hwndParent;
hwndParent = ((PCREATESTRUCT)PVOIDFROMMP(mp2))->hwndParent;
UpdateTitleText(hwndParent);
/* return FALSE to continue window creation, TRUE to abort it */
return (MRESULT)FALSE;
/* This routine currently doesn't use the hwnd, mp1, and mp2 parameters
* so they are referenced here to prevent an 'Unreferenced Parameter'
* warning at compile time.
*/
hwnd;
mp1;
mp2;
} /* End of InitMainWindow */
/**************************************************************************
*
* Name : ExitProc(usTermCode)
*
* Description: Cleans up certain resources when the application
* terminates.
*
* Concepts: Routine is called by DosExitList when the
* application exits.
*
* Global resources, such as the main window and
* message queue, are destroyed and any system
* resources used are freed.
*
* API's : WinIsWindow
* WinDestroyWindow
* WinDestroyMsgQueue
* WinTerminate
* DosExitList
*
* Parameters : usTermCode = termination code number
*
* Return : Returns EXLST_EXIT to the DosExitList handler
*
*************************************************************************/
VOID ExitProc(USHORT usTermCode) {
/*
* destroy the main window if it exists
*/
if (WinIsWindow(hab, hwndMainFrame))
WinDestroyWindow(hwndMainFrame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL); /* termination complete */
/* This routine currently doesn't use the usTermCode parameter so
* it is referenced here to prevent an 'Unreferenced Parameter'
* warning at compile time
*/
usTermCode;
}
#define HELPLIBRARYNAMELEN 20
/* If DEBUG is defined, then the help panels will display their
* id values on their title bar. This is useful for determining
* which help panels are being shown for each dialog item. When
* the DEBUG directive is not defined, then the panel ids are not
* displayed.
*/
/* #define DEBUG */
/*
* Global variables
*/
static HWND hwndHelpInstance;
static CHAR szLibName[HELPLIBRARYNAMELEN];
static CHAR szWindowTitle[HELPLIBRARYNAMELEN];
/**************************************************************************
*
* Name : InitHelp()
*
* Description: Initializes the IPF help facility
*
* Concepts: Called once during initialization of the program
*
* Initializes the HELPINIT structure and creates the
* help instance. If successful, the help instance
* is associated with the main window.
*
* API's : WinLoadString
* WinCreateHelpInstance
* WinAssociateHelpInstance
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID InitHelp(VOID) {
HELPINIT hini;
/* if we return because of an error, Help will be disabled */
fHelpEnabled = FALSE;
/* initialize help init structure */
hini.cb = sizeof(HELPINIT);
hini.ulReturnCode = 0;
hini.pszTutorialName = (PSZ)NULL; /* if tutorial added, add name here */
hini.phtHelpTable = (PHELPTABLE)MAKELONG(TEMPLATE_HELP_TABLE, 0xFFFF);
hini.hmodHelpTableModule = 0;
hini.hmodAccelActionBarModule = 0;
hini.idAccelTable = 0;
hini.idActionBar = 0;
if(!WinLoadString(hab,
(HMODULE)0,
IDS_HELPWINDOWTITLE,
HELPLIBRARYNAMELEN,
(PSZ)szWindowTitle))
{
MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
return;
}
hini.pszHelpWindowTitle = (PSZ)szWindowTitle;
/* if debugging, show panel ids, else don't */
#ifdef DEBUG
hini.fShowPanelId = CMIC_SHOW_PANEL_ID;
#else
hini.fShowPanelId = CMIC_HIDE_PANEL_ID;
#endif
if(!WinLoadString(hab,
(HMODULE)0,
IDS_HELPLIBRARYNAME,
HELPLIBRARYNAMELEN,
(PSZ)szLibName))
{
MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
return;
}
hini.pszHelpLibraryName = (PSZ)szLibName;
/* creating help instance */
hwndHelpInstance = WinCreateHelpInstance(hab, &hini);
if(hwndHelpInstance == NULLHANDLE || hini.ulReturnCode)
{
MessageBox(hwndMainFrame, IDMSG_HELPLOADERROR, MB_OK | MB_ERROR, TRUE);
return;
}
/* associate help instance with main frame */
if(!WinAssociateHelpInstance(hwndHelpInstance, hwndMainFrame))
{
MessageBox(hwndMainFrame, IDMSG_HELPLOADERROR, MB_OK | MB_ERROR, TRUE);
return;
}
/* help manager is successfully initialized so set flag to TRUE */
fHelpEnabled = TRUE;
} /* End of InitHelp */
/**************************************************************************
*
* Name : HelpGeneral()
*
* Description: Processes the WM_COMMAND message posted by the
* General Help item of the Help menu.
*
* Concepts: Called from MainCommand when the General Help
* menu item is selected.
*
* Sends an HM_EXT_HELP message to the help
* instance so that the default Extended Help is
* displayed.
*
* API's : WinSendMsg
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID HelpGeneral(VOID)
{
/* this just displays the system extended help panel */
if(fHelpEnabled)
if(NULL != WinSendMsg(hwndHelpInstance, HM_EXT_HELP,
(MPARAM)NULL, (MPARAM)NULL))
MessageBox(hwndMain,
IDMSG_HELPDISPLAYERROR,
MB_OK | MB_ERROR,
FALSE);
} /* End of HelpGeneral */
/**************************************************************************
*
* Name : HelpUsingHelp()
*
* Description: Processes the WM_COMMAND message posted by the
* Using Help item of the Help menu.
*
* Concepts: Called from MainCommand when the Using Help
* menu item is selected.
*
* Sends an HM_DISPLAY_HELP message to the help
* instance so that the default Using Help is
* displayed.
*
* API's : WinSendMsg
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID HelpUsingHelp(VOID)
{
/* this just displays the system help for help panel */
if(fHelpEnabled)
if(NULL != WinSendMsg(hwndHelpInstance, HM_DISPLAY_HELP,
(MPARAM)NULL, (MPARAM)NULL))
MessageBox(hwndMain,
IDMSG_HELPDISPLAYERROR,
MB_OK | MB_ERROR,
FALSE);
} /* End of HelpUsingHelp */
/**************************************************************************
*
* Name : HelpKeys()
*
* Description: Processes the WM_COMMAND message posted by the
* Keys Help item of the Help menu.
*
* Concepts: Called from MainCommand when the Keys Help
* menu item is selected.
*
* Sends an HM_KEYS_HELP message to the help
* instance so that the default Keys Help is
* displayed.
*
* API's : WinSendMsg
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID HelpKeys(VOID)
{
/* this just displays the system keys help panel */
if(fHelpEnabled)
if(NULL != WinSendMsg(hwndHelpInstance, HM_KEYS_HELP,
(MPARAM)NULL, (MPARAM)NULL))
MessageBox(hwndMain,
IDMSG_HELPDISPLAYERROR,
MB_OK | MB_ERROR,
FALSE);
} /* End of HelpKeys */
/**************************************************************************
*
* Name : HelpIndex()
*
* Description: Processes the WM_COMMAND message posted by the
* Help Index item of the Help menu.
*
* Concepts: Called from MainCommand when the Help Index
* menu item is selected.
*
* Sends an HM_INDEX_HELP message to the help
* instance so that the default Help Index is
* displayed.
*
* API's : WinSendMsg
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID HelpIndex(VOID)
{
/* this just displays the system help index panel */
if(fHelpEnabled)
if(NULL != WinSendMsg(hwndHelpInstance, HM_HELP_INDEX,
(MPARAM)NULL, (MPARAM)NULL))
MessageBox(hwndMain,
IDMSG_HELPDISPLAYERROR,
MB_OK | MB_ERROR,
FALSE);
} /* End of HelpIndex() */
/**************************************************************************
*
* Name : HelpTutorial()
*
* Description: Processes the WM_COMMAND message posted by the
* Tutorial Help item of the Help menu. While the
* standard template application does not include a
* Tutorial menu item, you can add one if your
* application has a tutorial.
*
* Concepts: Called from MainCommand when the Tutorial Help
* menu item is selected.
*
* API's : WinLoadMessage
* WinMessageBox
* WinAlarm
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID HelpTutorial(VOID)
{
CHAR szText[MESSAGELEN];
/*
* Insert code for any tutorial below in place of the message box.
*/
if(!WinLoadMessage(hab,
(HMODULE)NULLHANDLE,
IDMSG_YOURTUTORIAL,
MESSAGELEN,
(PSZ)szText))
{
WinAlarm(HWND_DESKTOP, WA_ERROR);
return;
}
WinMessageBox(HWND_DESKTOP,
hwndMain,
szText,
"Tutorial",
MB_OK | MB_INFORMATION,
FALSE);
} /* End of HelpTutorial */
/**************************************************************************
*
* Name : HelpProductInfo()
*
* Description: Processes the WM_COMMAND message posted by the
* Product information item of the Help Menu.
*
* Concepts: Called from MainCommand when the Product information
* menu item is selected
*
* Calls WinDlgBox to display the Product information dialog.
*
* API's : WinDlgBox
*
* Parameters : [none]
*
* Return : [none]
*
*************************************************************************/
VOID HelpProductInfo(VOID)
{
/* display the Product Information dialog. */
WinDlgBox(HWND_DESKTOP,
hwndMain,
(PFNWP)ProductInfoDlgProc,
0,
IDD_PRODUCTINFO,
(PVOID)NULL);
} /* End of HelpProductInfo() */
/**************************************************************************
*
* Name : DisplayHelpPanel(idPanel)
*
* Description: Displays the help panel whose id is given
*
* Concepts: Called whenever a help panel is desired to be
* displayed, usually from the WM_HELP processing
* of the dialog boxes.
*
* Sends HM_DISPLAY_HELP message to the help instance.
*
* API's : WinSendMsg
*
* Parameters : idPanel = panel i.d.
*
* Return : [none]
*
*************************************************************************/
VOID DisplayHelpPanel(ULONG idPanel)
{
if(fHelpEnabled)
if(NULL != WinSendMsg(hwndHelpInstance,
HM_DISPLAY_HELP,
MPFROMLONG(idPanel),
MPFROMSHORT(HM_RESOURCEID)))
MessageBox(hwndMainFrame,
IDMSG_HELPDISPLAYERROR,
MB_OK | MB_ERROR,
TRUE);
} /* End of DisplayHelpPanel */
/*
* DestroyHelpInstance:
*/
VOID DestroyHelpInstance(VOID) {
if (hwndHelpInstance)
WinDestroyHelpInstance(hwndHelpInstance);
}
/*
* getglyph: Get the glyph name in IBM and Adobe styles
*/
int getglyph(UniChar uni) {
NAMETAB * np;
GlyphIBM[0] = 0;
GlyphAdobe[0] = 0;
if (!Unitext) {
if (getnames(&Unicode, "unicode.nam", &Unitext, Utab))
Unitext = (char *)1;
}
if (Unitext == (char *)1)
return 0;
np = Utab[uni>>8];
if (!np)
return 0;
while (np->name) {
if (np->uni==uni) {
if (np->len==8 && isdigit(np->name[6]) && isdigit(np->name[7])) {
strcpy(GlyphIBM, np->name);
strupr(GlyphIBM);
np++;
if (np->uni != uni)
return 1;
}
strcpy(GlyphAdobe, np->name);
return 1;
}
np++;
}
return 0;
}
/*
* getline: Get the line a remember it for an error message
*/
char * getline(char * buf, FILE * f) {
char * ret;
char * cp;
*buf = 0;
ret = fgets(buf, 255, f);
/* Strip CR and LF from the end of the line */
cp = buf+strlen(buf)-1;
while (*cp=='\n' || *cp=='\r') {
cp--;
}
cp[1]=0;
cp[2]=0;
strncpy(InLine, buf, 255);
return ret;
}
/*
* getnames: Read in a name table.
* The file is read twice, once to get the sizes, and
* a second time to make the actual tables.
*
* Notes:
* The code in this section is taken from the original code within
* makekb. Several of the support routines came with it even though
* they are minimally used.
*/
int getnames(NAMETAB * * tab, char * name, char * * text, NAMETAB * * utab) {
FILE * f;
int len;
NAMETAB * np;
char * tp;
char line[256];
long val;
long entrycount;
long stringlen;
f = findopen(name, "r", "PATH", 0);
if (!f) return 1;
entrycount = 0;
stringlen = 0;
/*
* Process one pass to find the sizes of stuff
*/
line[255]=0;
getline(line, f);
while (!feof(f) && !ferror(f)) {
if (*line!='*' && *line!=';' && *line!='#') {
val = parse(line, &Value);
nullword(Value);
if (val && val<=0xffff) {
while (*Value && *Value!=';') {
entrycount++;
stringlen += (strlen(Value)+1);
Value = nexttoken(Value);
}
} else {
if (val)
printf("Bad name entry - %s\n", InLine);
}
}
getline(line, f);
}
if (ferror(f)) {
printf("Error reading file - %s\n", name);
return 2;
}
/*
* Allocate the tables
*/
entrycount++;
stringlen += 8;
*tab = malloc(entrycount*sizeof(NAMETAB));
*text = malloc(stringlen);
np = *tab;
tp = *text;
/*
* Process second pass to create the tables
*/
rewind(f);
getline(line, f);
while (!feof(f) && !ferror(f)) {
val = parse(line, &Value);
nullword(Value);
if (val && val<=0xffff) {
while (*Value && *Value!=';') {
np->name = tp;
strcpy(tp, Value);
len = strlen(Value);
tp += (len+1);
np->len = len;
np->uni = val;
Value = nexttoken(Value);
if (!utab[val>>8]) {
utab[val>>8] = np;
}
np++;
}
}
getline(line, f);
}
np->name = 0;
np->uni = 0;
np->len = 0;
fclose(f);
return 0;
}
/*
* parse: Parse the input line
*/
long parse (char * line, char * * value) {
char * cp, * kp;
/* Strip CR and LF from the end of the line */
cp = line+strlen(line)-1;
while (*cp=='\n' || *cp=='\r') {
cp--;
}
cp[1]=0;
cp[2]=0;
*value = line;
cp = line;
/*
* Skip leading spaces and detect comments
*/
while (*cp==' ' || *cp=='\t')
cp++;
if (*cp=='*' || *cp==';' || *cp=='#' || *cp=='/' || *cp==0 || *cp==0x1a) {
return 0;
}
/* Find the keyword */
kp = cp;
while (*cp && *cp!=' ' && *cp!='\t' && *cp!='=') {
*cp = (char) tolower(*cp);
cp++;
}
*cp++=0; /* Make keyword into string */
/* Skip blanks and = after keyword */
while (*cp==' ' || *cp=='\t') cp++; /* Skip blanks after keyword */
if (*cp=='=') { /* If = found, skip it and trailing blank */
cp++;
if(*cp==' ' || *cp=='\t') cp++;
}
*value = cp;
return gethexval(kp);
}
/*
* gethexval: Get a hex number. Convert a hex value with an optional
* leading 0x.
*/
long gethexval(char * cp) {
long val;
char gotone;
char ch;
val = 0;
gotone = 0;
if (*cp=='0') {
cp++;
if (!*cp) return 0;
if (*cp=='x') cp++;
}
while (*cp) {
if (*cp>='0' && *cp<='9') {
ch = *cp-'0';
} else {
if (*cp>='a' && *cp<='f') {
ch = *cp-'a'+10;
} else {
if (*cp>='A' && *cp<='F') {
ch = *cp-'A'+10;
} else {
if (*cp == ';')
break;
return NOTHEXVAL;
}
}
}
val *= 16;
val += ch;
gotone = 1;
cp++;
}
if (!gotone)
return NOTHEXVAL;
return val;
}
/*
* nexttoken: Set value to the next token
*/
char * nexttoken(char * value) {
if (!*value) return value;
value += strlen(value);
value++;
while (*value==' ' || *value=='\t') value++;
nullword(value);
return value;
}
/*
* nullword: Put a null at the end of the word
*/
void nullword(char * cptr) {
char * cp;
cp = cptr;
while (*cp>' ') cp++;
*cp = 0;
}
/*
* findopen: Common file open routine
*/
FILE * findopen(char * fname, char * mode, char * path, int msg) {
FILE * f;
searchenv(fname, path, Fn);
if (*Fn==0 && msg) {
printf("File not found - %s\n", fname);
return NULL;
}
f = fopen(Fn, mode);
if (!f && msg) {
printf("Unable to open file - %s\n", fname);
return NULL;
}
return f;
}
#define PATHSEP '/'
/*
* searchenv: Search for file along paths from environment variable
*/
void searchenv(const char *fname, const char *env_var, register char *path) {
register char *p;
register int c;
char *env_p;
/* Check for fully specified file name */
if (*fname=='/' || *fname=='\\' || fname[1]==':') {
if (access(fname, 0)==0) {
strcpy(path, fname);
} else {
*path = 0;
}
return;
}
/* Check exists in current directory */
if (access(fname, 0) == 0) {
getcwd(path, 256);
p = path + strlen(path);
if (((c = *(p - 1)) != '/') && (c != '\\') && (c != ':')) {
*p++ = PATHSEP;
*p = 0;
}
strcat(path, fname);
return;
}
/* Get environment variable. Return if it does not exist */
env_p = getenv(env_var);
if (!env_p || !*env_p) {
*path = 0;
return;
}
/* Loop thru all paths in the environment variable */
env_p = getpath(env_p, path);
while (env_p && *path) {
p = path + strlen(path);
if (((c = *(p - 1)) != '/') && (c != '\\') && (c != ':')) {
*p++ = PATHSEP;
}
strcpy(p, fname);
if (access(path, 0) == 0)
return;
strcpy(p, "codepage/");
strcpy(p+9, fname);
if (access(path, 0) == 0)
return;
env_p = getpath(env_p, path);
}
/* File not found, return an empty string */
*path = 0;
}
/*
* getpath: Extract a pathname from a semicolon-delimited list of pathnames
*/
char * getpath(register char *src, register char *dst) {
const char *keepsrc;
keepsrc = src;
while (*src && *src != ';') {
if (*src != '"') { /* Process quoted path */
*dst++ = *src++;
} else {
src++; /* skip over opening quote */
while (*src && (*src != '"')) {
*dst++ = *src++;
}
if (*src) src++; /* skip over closing quote */
}
}
while ( *src == ';' ) src++;
*dst = 0;
return((keepsrc != src) ? src : NULL);
}
/*
* getuniinfo: Get Unicode Information
*/
char * getuniinfo(UniChar uc) {
char * unip;
UniChar thisuc;
int i;
if (uc>=0x4e00 && uc<=0x9fa5)
return "4E00;<CJK Ideograph>;Lo;0;L;;;;;N;;;;;";
if (uc>=0xac00 && uc<=0xd7a3)
return "AC00;<Hangul Syllable>;Lo;0;L;;;;;N;;;;;";
if (uc>=0xd800 && uc<=0xdbff)
return "DB80;<High Surrogate>;Cs;0;L;;;;;N;;;;;";
if (uc>=0xdc00 && uc<=0xdfff)
return "DC00;<Low Surrogate>;Cs;0;L;;;;;N;;;;;";
if (uc>=0xe000 && uc<=0xf83c)
return "E000;<User defined character>;Co;0;L;;;;;N;;;;;";
if (!UniTable)
readunitab();
if (UniTable == (char *)1)
return "";
unip = UniTable;
while (*unip != 1) {
i = gethexval(unip);
thisuc = (UniChar)i;
if (thisuc > uc && i != NOTHEXVAL)
break;
if (thisuc == uc)
return unip;
unip += strlen(unip);
while (*unip == 0) {
unip++;
}
}
return "";
}
/*
* readunitab: Read table file
*/
int readunitab(void) {
FILE * f;
ULONG len;
char * unip;
int count;
UniTable = (char *)1;
f = findopen("unicode.tab", "rb", "PATH", 0);
if (!f)
return 1;
len = filelength(fileno(f));
UniTable = malloc(len+2);
if (!UniTable) {
UniTable = (char *)1;
return 1;
}
count = fread(UniTable, len, 1, f);
if (count != 1) {
free(UniTable);
UniTable = (char *)1;
return 1;
}
UniTable[len] = 0x00;
UniTable[len+1] = 0x01;
unip = UniTable;
while (*unip != 0x01) {
if (*unip == '\r' || *unip == '\n')
*unip = 0;
unip++;
}
return 0;
}
/*
* tokenuni: Tokenize the unicode information
*/
void tokenuni(char * str, char * temp, char * token[16]) {
char * cp;
int tok;
strcpy(temp, str);
cp = temp;
while (*cp) {
if (*cp == ';')
*cp = 0;
cp++;
}
memset(cp, 0, 16);
cp = temp;
for (tok=0; tok<16; tok++) {
token[tok]=cp;
cp += strlen(cp) + 1;
}
}
/*
* getdesc: Get description
*/
char * getdesc(char * name, char * table[]) {
char * * tab;
tab = table;
while (tab[0]) {
if (!strcmp(name, tab[0])) {
return tab[1];
}
tab += 2;
}
return name;
}
/*
* QueryPrintQueue: Return the default queue name
*/
int QueryPrintQueue(char * qname, char * drvname) {
ULONG rc, Returned, Total, Needed;
PPRQINFO3 QueueInfo, pqi;
LONG i;
/*
* Get count of total number of print queues and the size of the
* buffer needed (cbNeeded) to hold them.
*/
rc = SplEnumQueue( NULL, /* pszComputerName - local machine */
3, /* information level 3 requested */
NULL, /* pBuf - NULL for first call */
0L, /* cbBuf - 0 to get size needed */
&Returned, /* number of queues returned */
&Total, /* total number of queues */
&Needed, /* number bytes needed */
NULL ); /* reserved */
if (!Total)
return 1;
QueueInfo = malloc(Needed) ;
/* Call again to get print queue data. */
rc = SplEnumQueue( NULL, /* pszComputerName - local machine */
3, /* information level 3 requested */
QueueInfo, /* pBuf - gets enumerated queues */
Needed, /* cbBuf - size of pBuf */
&Returned, /* number of queues returned */
&Total, /* total number of queues */
&Needed, /* number bytes needed to store */
/* all requested information */
NULL ); /* reserved */
strcpy( qname, QueueInfo->pszName );
strcpy( drvname, QueueInfo->pszDriverName );
for (i = 0; i < Total; ++i) {
if ( QueueInfo[i].fsType & PRQ3_TYPE_APPDEFAULT) {
strcpy(qname, QueueInfo[i].pszName );
strcpy( drvname, QueueInfo[i].pszDriverName );
break;
}
}
free (QueueInfo);
return 0;
}
/*
* Types from Unicode tables
*/
char * UniTypes[] = {
"Lu", "Uppercase letter",
"Ll", "Lowercase letter",
"Lm", "Modifier letter ",
"Lo", "Other letter",
"Lt", "Titlecase letter ",
"Mn", "Non-spacing mark",
"Mc", "Combining mark",
"Nd", "Decimal number",
"No", "Other number",
"Pd", "Dash punctuation",
"Ps", "Open punctuation",
"Pc", "Under punctuation",
"Pe", "Close punctuation",
"Po", "Other punctuation",
"Sm", "Math symbol",
"Sc", "Currency symbol",
"Sk", "Modifier symbol",
"So", "Other symbol",
"Zs", "Space separator",
"Zt", "Tab separator",
"Zl", "Line separator",
"Zp", "Paragraph separator",
"Cc", "Control or format character",
"Co", "Other character",
"Cn", "Non-character",
"Cs", "Surrogate character",
0, 0,
};
/*
* Bidi types from unicode tables
*/
char * BidiTypes[] = {
"L", "Left to right",
"R", "Right to left",
"EN", "European number",
"ES", "European number separator",
"ET", "European number terminator",
"AN", "Arabic number",
"CS", "Common number separator",
"B", "Block separator",
"S", "Segment separator",
"WS", "Whitespace",
"MN", "Mirrored neutral",
"ON", "Other neutral",
0, 0,
};