home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tvos200.zip
/
TVISION
/
OS2STUFF.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-25
|
18KB
|
614 lines
/*
* os2stuff.cpp: OS/2 base mode translation & helper calls.
* ==========================================================
* (C)1995 F.Jalvingh; Public domain.
*
* $Header$
*
* $Log$
*/
#define INCL_OS2
#define INCL_BASE
#define INCL_SUB
#define INCL_DOSFILEMGR
#define INCL_DOSMISC
#include "ttypes.h"
#include <tvision/tvosdef.h>
#include <cpl/compiler.h>
#include <cpl/osdefs.h>
#include <string.h>
void MemCpyW(ushort *dest, ushort *src, ushort count)
{
while(count-- > 0)
*dest++ = *src++;
}
/****************************************************************************/
/* */
/* CODING: Timer interface. */
/* */
/****************************************************************************/
/*
* osTimeGetRunning() returns the current millisecond time for every OS.
*/
ulong osTimeGetRunning(void)
{
#if defined(__OS2__)
# if defined(__32BITS__)
ulong errc;
ulong msecs;
errc= DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msecs, sizeof(msecs));
if(errc != 0) return 0;
return msecs;
# else
/*
* For OS/2 1.xx get the Global Info Segment ONCE, then use it..
*/
SEL gsel, lsel;
if(tiGis == NULL)
{
DosGetInfoSeg(&gsel, &lsel);
tiGis = MAKEPGINFOSEG(gsel);
}
return tiGis->msecs;
# endif
#elif defined(__MSDOS__)
return biostime(0, 0) * 55ul;
#endif
}
/****************************************************************************/
/* */
/* CODING: Keyboard interface routines. */
/* */
/****************************************************************************/
/*
* This interface is made for OS/2, and allows entry of diacriticals by
* pressing CTRL-2, followed by pressing two compound characters. For instance,
* pressing CTRL-2 c , will result in the ç character.
*/
/*--------------------------------------------------------------------------*/
/* STRUCTURES: Diacritical Key translation table. */
/*--------------------------------------------------------------------------*/
struct KeyPair
{
unsigned char kp_c1, kp_c2, kp_cu;
};
/*--------------------------------------------------------------------------*/
/* STATIC GLOBALS: Diacritical key translation table. */
/*--------------------------------------------------------------------------*/
static struct KeyPair Pair_ar[] =
{
{'c', ',', 0x87}, // c cedille,
{'C', ',', 0x80}, // C cedille,
{'u', '"', 0x81}, // u umlaud
{'U', '"', 0x9a}, // U umlaud
{'e', 0x27,0x82}, // e accent grave,
{'E', 0x27,0x90}, // E accent grave,
{'a', '^', 0x83}, // A accent circonflex,
{'a', '"', 0x84}, // a trema,
{'A', '"', 0x8e}, // A trema,
{'a', '`', 0x85}, // A accent aigu
{'a', 'o', 0x86}, // a with o above,
{'A', 'o', 0x8F}, // A with o above,
{'e', '^', 0x88}, // e accent circonflex,
{'e', '"', 0x89}, // e trema,
{'e', '`', 0x8a}, // e accent aigu,
{'i', '"', 0x8b}, // i trema,
{'i', '^', 0x8c}, // i accent circonflex,
{'i', '`', 0x8d}, // i accent aigu,
{'a', 'e', 0x91}, // ae
{'A', 'E', 0x92}, // AE
{'o', '^', 0x93}, // o accent circonflex,
{'o', '"', 0x94}, // o trema,
{'O', '"', 0x99}, // O trema,
{'o', '`', 0x95}, // o accent aigu,
{'u', '^', 0x96}, // u accent circonflex,
{'u', '`', 0x97}, // u accent aigu,
{'y', '"', 0x98}, // Dutch 'lange ij'
{'c', '|', 0x9b}, // c with |
{'L', '^', 0x9c}, // Pound sign
{'Y', '=', 0x9d}, // Yen symbol?
{'P', 't', 0x9e}, // Pt
{'p', 't', 0x9e}, // Idem,
{'f', 'f', 0x9f}, // Dutch florin symbol,
{'f', 'l', 0x9f}, // Idem,
{'a', 0x27,0x0a0}, // a accent grave,
{'i', 0x27,0x0a1}, // i accent grave,
{'o', 0x27,0x0a2}, // o accent grave,
{'u', 0x27,0x0a3}, // u accent grave,
{'n', '~', 0x0a4}, // n ma(n)ana,
{'N', '~', 0x0a5}, // N ma(N)ana,
{'a', '-', 0x0a6}, // High a with - below,
{'o', '-', 0x0a7}, // as above, with o,
{'?', '?', 0x0a8}, // Query sign opposite dir,
{'1', '2', 0x0ab}, // 1/2
{'1', '4', 0x0ac}, // 1/4
{'!', '!', 0x0ad}, // Exclamation marker opposite dir.
{'<', '<', 0x0ae}, // <<
{'>', '>', 0x0af}, // >>
{0, 0, 0}
};
static HKBD hKbd = (HKBD)0xffff;
static int TwoKey; /* NZ if in twokey mode, */
static ushort CombKey; /* Key to be combined (1st one of TwoKey) */
ushort (*sv_kbLink)(ushort key);
/*
* CheckOpenKbd() ensures that a keyboard handle's open.
*/
static void CheckOpenKbd(void)
{
if(hKbd == 0xffff)
{
#if 0
/**** Open the keyboard.. ****/
KbdOpen(&hKbd); /* Open keybd -> MUST(!) work */
KbdGetFocus(IO_WAIT, hKbd);
#else
hKbd = 0;
#endif
}
}
/*
* TransKey() translates a keycode passed to an internal code.
*/
static ushort TransKey(KBDKEYINFO *ki)
{
#if 0
if(ki->chChar != 0 && ki->chChar != 0xe0) return (ushort)(uchar)ki->chChar;
/**** Is extended code... ****/
return (ushort)(uchar)ki->chScan << 8;
#else
if(ki->chChar == 0xe0)
return ushort ((uchar)ki->chScan << 8);
return ushort( (((uchar)ki->chScan) << 8) | ushort(ki->chChar));
#endif
}
/*
* TransDbl() translates a diacritical key code (one starting with CTRL-2).
*/
static ushort TransDbl(ushort key)
{
struct KeyPair *kp;
if(TwoKey) /* Are we in twokey mode ? */
{
/**** Is this the 2nd in a row? ****/
if(CombKey == 0)
{
CombKey = key; /* Save 1st key pressed, */
return 0;
}
/**** This is the 2nd key! Find the combination in the key table.. ****/
for(kp = Pair_ar; kp->kp_c1 != 0; kp++)
{
if( (kp->kp_c1 == key && kp->kp_c2 == CombKey) ||
(kp->kp_c2 == key && kp->kp_c1 == CombKey))
{
TwoKey = FALSE; /* End of TwoKey indicator, */
return kp->kp_cu;
}
}
/**** Unknown diacritical key-> Beep, then exit.. ****/
return 0;
}
else if(key == 0x0300) // CTRL-2 key
{
TwoKey = TRUE; /* Set 2key indicator, */
CombKey = 0; /* No combinator known, */
return 0; /* No key pressed, */
}
else
return key; /* Else return key pressed as-is. */
}
/*
* kbReadF() reads the keyboard quicky and returns a keycode when a key is
* pressed or ZERO if no key is buffered. It does not translate the key in any
* way.
*/
static ushort kbReadF(ushort *kstate)
{
KBDKEYINFO kki;
CheckOpenKbd(); /* Make sure keybd is open, */
KbdGetFocus(IO_WAIT, hKbd); /* Get this keyboard, */
if(KbdPeek(&kki, hKbd) != 0)
{
KbdFreeFocus(hKbd); /* Release focus, */
return 0;
}
KbdFreeFocus(hKbd);
if(kki.fbStatus != 0)
{
if(KbdCharIn(&kki, IO_WAIT, hKbd) == 0)
{
if(kki.fbStatus != 0)
{
if(kstate != NULL)
*kstate = kki.fsState; // Save current keybd state,
return TransKey(&kki);
}
}
}
#if !defined(__32BITS__)
DosSleep(25);
#endif
return 0;
}
#if 0
/*
* kbRead() reads the keyboard and waits till a key is pressed. It does NOT
* perform any translation or other auxiliary action.
*/
static ushort kbRead(void)
{
KBDKEYINFO kki;
CheckOpenKbd(); /* Make sure keybd is open, */
KbdGetFocus(IO_WAIT, hKbd); /* Get this keyboard, */
if(KbdCharIn(&kki, IO_WAIT, hKbd) != 0)
{
KbdFreeFocus(hKbd);
return 0; /* No key <> error! */
}
KbdFreeFocus(hKbd);
return TransKey(&kki);
}
#endif
/*
* osKeyFast() checks for a key quickly. It is the main entry point, it
* also translates keycodes when TwoKey (CTRL-2) is pressed AND it calls the
* sv_kbLink routine(s).
*/
ushort osKeyFast(ushort *kstate)
{
ushort key;
key = kbReadF(kstate); /* Read keyboard quickly, */
if(key != 0) /* Key has been read? */
key = TransDbl(key); /* Translate if double key, */
/**** Right. If there's a keyboard handler call it, ****/
if(sv_kbLink) return (*sv_kbLink)(key); /* Call handler and return, */
return key;
}
/*
* osKeyState() gets the current control key state.
*/
ushort osKeyState(void)
{
KBDINFO ki;
if(KbdGetStatus(&ki, hKbd) != 0) return 0; // Return no state on error.
return ki.fsState;
}
#if defined(__WATCOMC__) || defined(__ICC__)
int setdisk(int drive)
{
#if defined(__32BITS__)
return (int)DosSetDefaultDisk((ULONG)drive + 1);
#else
return (int)DosSelectDisk((USHORT)drive + 1); /* Bcc getdisk: 'A' = 0; MSC DosSelectdisk: 'A' = 1 */
#endif
}
int getdisk(void)
{
#ifdef __32BITS__
ULONG drive, numdrives;
DosQueryCurrentDisk(&drive, &numdrives);
#else
USHORT drive;
ULONG numdrives;
DosQCurDisk(&drive, &numdrives);
#endif
return (int)drive - 1;
}
int getcurdir(int drive, char *dir)
{
#ifdef __32BITS__
ULONG bytes;
bytes = 0;
DosQueryCurrentDir(drive, NULL, &bytes);
if(bytes > OS_MAXPATH) return -1;
DosQCurDir(drive, (PBYTE) dir, &bytes);
return 0;
#else
USHORT bytes;
bytes = 0;
DosQCurDir(drive, NULL, &bytes);
if(bytes > OS_MAXPATH) return -1;
DosQCurDir(drive, dir, &bytes);
return 0;
#endif
}
static void CopyIt(char *dst, const char *src, unsigned maxlen)
{
if (dst)
{
if(strlen(src) >= maxlen)
{
strncpy(dst, src, maxlen);
dst[maxlen] = 0;
}
else
strcpy(dst, src);
}
}
static int DotFound(char *pb)
{
if (*(pb-1) == '.')
pb--;
switch (*--pb)
{
case ':' : if (*(pb-2) != '\0') break;
case '/' :
case '\\' :
case '\0' : return 1;
}
return 0;
}
int fnsplit(const char *pathp, char *drivep, char *dirp, char *namep, char *extp)
{
register char *pb;
register int wrk;
int ret;
char buf[OS_MAXPATH+2];
/**** Set all string to default value zero ****/
ret = 0;
if (drivep) *drivep = 0;
if (dirp) *dirp = 0;
if (namep) *namep = 0;
if (extp) *extp = 0;
/**** Copy filename into template up to MAXPATH characters ****/
pb = buf;
while (*pathp == ' ') pathp++;
if ((wrk = strlen(pathp)) > OS_MAXPATH)
wrk = OS_MAXPATH;
*pb++ = 0;
strncpy(pb, pathp, wrk);
*(pb += wrk) = 0;
/**** Split the filename and fill corresponding nonzero pointers ****/
wrk = 0;
for (;;)
{
switch (*--pb)
{
case '.' : if (!wrk && (*(pb+1) == '\0')) wrk = DotFound(pb);
if ((!wrk) && ((ret & EXTENSION) == 0))
{
ret |= EXTENSION;
CopyIt(extp, pb, OS_MAXEXT - 1);
*pb = 0;
}
continue;
case ':' : if (pb != &buf[2]) continue;
case '\0' : if (wrk)
{
if (*++pb)
ret |= DIRECTORY;
CopyIt(dirp, pb, OS_MAXPATH - 1);
*pb-- = 0;
break;
}
case '/' :
case '\\' : if (!wrk)
{
wrk++;
if (*++pb)
ret |= FILENAME;
CopyIt(namep, pb, OS_MAXFILE - 1);
*pb-- = 0;
if (*pb == 0 || (*pb == ':' && pb == &buf[2]))
break;
}
continue;
case '*' :
case '?' : if (!wrk) ret |= WILDCARDS;
default : continue;
}
break;
}
if (*pb == ':')
{
if (buf[1])
ret |= DRIVE;
CopyIt(drivep, &buf[1], OS_MAXDRIVE - 1);
}
return (ret);
}
#include <errno.h>
void fnmerge(char *out, char const *drive, char const *dir, char const *name, char const *ext)
{
*out = '\0';
if(*drive != '\0') strcpy(out, drive);
if(*dir != '\0') strcat(out, dir);
if(*name != '\0') strcat(out, name);
if(*ext != '\0') strcat(out, ext);
}
/*
* findfirst() searches a '1st' file..
*/
int findfirst(const char *path, struct ffblk *ff, int attrib)
{
#ifdef __32BITS__
FILEFINDBUF3 fb;
HDIR hdir = 0xffff; /* HDIR_SYSTEM */
ULONG count = 1, /* File count, */
err;
err = DosFindFirst((PSZ)path, &hdir, attrib, &fb, sizeof(fb), &count, 1l);
if(err)
{
/**** Translate error.. ****/
switch(err)
{
case ERROR_PATH_NOT_FOUND: errno = ENOENT; break;
case ERROR_NO_MORE_FILES: errno = EMFILE; break;
default: errno = EINVAL; break;
}
return -1;
}
#else
FILEFINDBUF fb;
HDIR hdir = 0xffff; /* HDIR_SYSTEM */
USHORT count = 1, /* File count, */
err;
err = DosFindFirst(path, &hdir, attrib, &fb, sizeof(fb), &count, 0l);
if(err)
{
/**** Translate error.. ****/
switch(err)
{
case ERROR_PATH_NOT_FOUND: errno = ENOENT; break;
case ERROR_NO_MORE_FILES: errno = EMFILE; break;
default: errno = EINVAL; break;
}
return -1;
}
#endif
/**** Translate find buffer.. ****/
memcpy(ff->ff_reserved, &hdir, sizeof(hdir)); /* Save handle, */
ff->ff_attrib = (char)fb.attrFile; /* Copy file attributes, */
memcpy(&ff->ff_ftime, &fb.ftimeLastWrite, sizeof(ff->ff_ftime));
memcpy(&ff->ff_fdate, &fb.fdateLastWrite, sizeof(ff->ff_fdate));
ff->ff_fsize = fb.cbFile;
memcpy(ff->ff_name, fb.achName, sizeof(ff->ff_name));
return 0;
}
/*
* findnext() finds the next file..
*/
int findnext(struct ffblk *ff)
{
#ifdef __32BITS__
FILEFINDBUF3 fb;
HDIR hdir;
ULONG count = 1,
err;
/**** Get HDIR from reserved area, ****/
memcpy(&hdir, ff->ff_reserved, sizeof(hdir));
err = DosFindNext(hdir, &fb, sizeof(fb), &count);
if(err != 0)
{
switch(err)
{
case ERROR_PATH_NOT_FOUND: errno = ENOENT; break;
case ERROR_NO_MORE_FILES: errno = EMFILE; break;
default: errno = EINVAL; break;
}
return -1;
}
#else
FILEFINDBUF fb;
HDIR hdir;
USHORT count = 1,
err;
/**** Get HDIR from reserved area, ****/
memcpy(&hdir, ff->ff_reserved, sizeof(hdir));
err = DosFindNext(hdir, &fb, sizeof(fb), &count);
if(err != 0)
{
switch(err)
{
case ERROR_PATH_NOT_FOUND: errno = ENOENT; break;
case ERROR_NO_MORE_FILES: errno = EMFILE; break;
default: errno = EINVAL; break;
}
return -1;
}
#endif
/**** Copy.. ****/
ff->ff_attrib = (char)fb.attrFile; /* Copy file attributes, */
memcpy(&ff->ff_ftime, &fb.ftimeLastWrite, sizeof(ff->ff_ftime));
memcpy(&ff->ff_fdate, &fb.fdateLastWrite, sizeof(ff->ff_fdate));
ff->ff_fsize = fb.cbFile;
memcpy(ff->ff_name, fb.achName, sizeof(ff->ff_name));
return 0;
}
#endif