2019-03-31 15:57:52 -04:00
|
|
|
|
/* con_dosx.cpp
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 1994-1996, Marko Macek
|
|
|
|
|
* Free 1996 F.Jalvingh
|
|
|
|
|
*
|
|
|
|
|
* You may distribute under the terms of either the GNU General Public
|
|
|
|
|
* License or the Artistic License, as specified in the README file.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// include
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#ifdef DJGPP
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "sysdep.h"
|
|
|
|
|
#include "console.h"
|
|
|
|
|
#include "gui.h"
|
2019-03-31 17:13:55 -04:00
|
|
|
|
#include "c_config.h"
|
2019-03-31 15:57:52 -04:00
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <process.h>
|
|
|
|
|
#include "port.h" // DOS portability calls,
|
|
|
|
|
|
|
|
|
|
#define MAX_PIPES 4
|
|
|
|
|
#define PIPE_BUFLEN 4096
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
int used;
|
|
|
|
|
int id;
|
|
|
|
|
// int reading;
|
|
|
|
|
int stopped;
|
|
|
|
|
// TID tid;
|
|
|
|
|
// HMTX Access;
|
|
|
|
|
// HEV ResumeRead;
|
|
|
|
|
// HEV NewData;
|
|
|
|
|
// char *buffer;
|
|
|
|
|
// int buflen;
|
|
|
|
|
// int bufused;
|
|
|
|
|
// int bufpos;
|
|
|
|
|
EModel *notify;
|
|
|
|
|
// char *Command;
|
|
|
|
|
// int RetCode;
|
|
|
|
|
// int DoTerm;
|
|
|
|
|
FILE *fp;
|
|
|
|
|
} GPipe;
|
|
|
|
|
|
|
|
|
|
static GPipe Pipes[MAX_PIPES] = {
|
|
|
|
|
{ 0 }, { 0 }, { 0 }, { 0 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-03-31 16:44:55 -04:00
|
|
|
|
#if defined(__DJGPP__) || defined(WATCOM)
|
2019-03-31 15:57:52 -04:00
|
|
|
|
|
|
|
|
|
// adapted from djgpp library source - redirects stderr as well as stdout
|
|
|
|
|
// Original author: pacetti@fl-ngnet.army.mil
|
|
|
|
|
|
|
|
|
|
#include <io.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
/* hold file pointer, descriptor, command, mode, temporary file name,
|
|
|
|
|
and the status of the command */
|
|
|
|
|
struct pipe_list {
|
|
|
|
|
FILE *fp;
|
|
|
|
|
int fd;
|
|
|
|
|
int exit_status;
|
|
|
|
|
char *command, mode[10], temp_name[L_tmpnam];
|
|
|
|
|
struct pipe_list *next;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* static, global list pointer */
|
|
|
|
|
static struct pipe_list *pl = NULL;
|
|
|
|
|
|
|
|
|
|
static FILE *
|
|
|
|
|
xpopen (const char *cm, const char *md) /* program name, pipe mode */
|
|
|
|
|
{
|
|
|
|
|
struct pipe_list *l1, *l2;
|
|
|
|
|
|
|
|
|
|
/* make new node */
|
|
|
|
|
if ((l1 = (struct pipe_list *) malloc (sizeof (struct pipe_list))) == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* zero out elements to we'll get here */
|
|
|
|
|
l1->fd = 0;
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
l1->next = NULL;
|
|
|
|
|
|
|
|
|
|
/* if empty list - just grab new node */
|
|
|
|
|
if (!pl)
|
|
|
|
|
pl = l1;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* otherwise, find last node in list */
|
|
|
|
|
++(l1->fd);
|
|
|
|
|
l2 = pl;
|
|
|
|
|
while (l2->next)
|
|
|
|
|
{
|
|
|
|
|
++(l1->fd);
|
|
|
|
|
l2 = l2->next;
|
|
|
|
|
};
|
|
|
|
|
/* add new node to list */
|
|
|
|
|
l2->next = l1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* stick in elements we know already */
|
|
|
|
|
l1->exit_status = -1;
|
|
|
|
|
strcpy (l1->mode, md);
|
|
|
|
|
if (tmpnam (l1->temp_name) == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* if can save the program name, build temp file */
|
|
|
|
|
if ((l1->command = (char *) malloc(strlen(cm)+1)))
|
|
|
|
|
{
|
|
|
|
|
strcpy(l1->command, cm);
|
|
|
|
|
/* if caller wants to read */
|
|
|
|
|
if (l1->mode[0] == 'r')
|
|
|
|
|
{
|
|
|
|
|
#if 1
|
|
|
|
|
int fd2 = -1;
|
|
|
|
|
#endif
|
|
|
|
|
/* dup stdout */
|
|
|
|
|
if ((l1->fd = dup (fileno (stdout))) == EOF)
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
else if (!(l1->fp = freopen (l1->temp_name, "wb", stdout)))
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
#if 1
|
|
|
|
|
/* dup stderr */
|
|
|
|
|
else if ((fd2 = dup (STDERR_FILENO)) == EOF)
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
/* redirect stderr to new stdout */
|
|
|
|
|
else if (dup2(fileno(l1->fp),STDERR_FILENO) == EOF)
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
else
|
|
|
|
|
/* exec cmd */
|
|
|
|
|
if ((l1->exit_status = system (cm)) == EOF)
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
/* reopen real stdout */
|
|
|
|
|
if (dup2 (l1->fd, fileno (stdout)) == EOF)
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
else
|
|
|
|
|
/* open file for reader */
|
|
|
|
|
l1->fp = fopen (l1->temp_name, l1->mode);
|
|
|
|
|
close(l1->fd);
|
|
|
|
|
#if 1
|
|
|
|
|
/* restore stderr */
|
|
|
|
|
if (fd2 >= 0) {
|
|
|
|
|
(void) dup2(fd2, STDERR_FILENO);
|
|
|
|
|
(void) close(fd2);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* if caller wants to write */
|
|
|
|
|
if (l1->mode[0] == 'w')
|
|
|
|
|
/* open temp file */
|
|
|
|
|
l1->fp = fopen (l1->temp_name, l1->mode);
|
|
|
|
|
else
|
|
|
|
|
/* unknown mode */
|
|
|
|
|
l1->fp = NULL;
|
|
|
|
|
}
|
|
|
|
|
return l1->fp; /* return == NULL ? ERROR : OK */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
xpclose (FILE *pp)
|
|
|
|
|
{
|
|
|
|
|
struct pipe_list *l1, *l2; /* list pointers */
|
|
|
|
|
int retval=0; /* function return value */
|
|
|
|
|
|
|
|
|
|
/* if pointer is first node */
|
|
|
|
|
if (pl->fp == pp)
|
|
|
|
|
{
|
|
|
|
|
/* save node and take it out the list */
|
|
|
|
|
l1 = pl;
|
|
|
|
|
pl = l1->next;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* if more than one node in list */
|
|
|
|
|
if (pl->next)
|
|
|
|
|
{
|
|
|
|
|
/* find right node */
|
|
|
|
|
for (l2 = pl, l1 = pl->next; l1; l2 = l1, l1 = l2->next)
|
|
|
|
|
if (l1->fp == pp)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* take node out of list */
|
|
|
|
|
l2->next = l1->next;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
/* if FILE not in list - return error */
|
|
|
|
|
if (l1->fp == pp)
|
|
|
|
|
{
|
|
|
|
|
/* close the (hopefully) popen()ed file */
|
|
|
|
|
fclose (l1->fp);
|
|
|
|
|
|
|
|
|
|
/* if pipe was opened to write */
|
|
|
|
|
if (l1->mode[0] == 'w')
|
|
|
|
|
{
|
|
|
|
|
/* dup stdin */
|
|
|
|
|
if ((l1->fd = dup (fileno (stdin))) == EOF)
|
|
|
|
|
retval = -1;
|
|
|
|
|
else
|
|
|
|
|
/* open temp stdin */
|
|
|
|
|
if (!(l1->fp = freopen (l1->temp_name, "rb", stdin)))
|
|
|
|
|
retval = -1;
|
|
|
|
|
else
|
|
|
|
|
/* exec cmd */
|
|
|
|
|
if ((retval = system (l1->command)) != EOF)
|
|
|
|
|
{
|
|
|
|
|
/* reopen stdin */
|
|
|
|
|
if (dup2 (l1->fd, fileno (stdin)) == EOF)
|
|
|
|
|
retval = -1;
|
|
|
|
|
}
|
|
|
|
|
close(l1->fd);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* if pipe was opened to read, return the exit status we saved */
|
|
|
|
|
if (l1->mode[0] == 'r')
|
|
|
|
|
retval = l1->exit_status;
|
|
|
|
|
else
|
|
|
|
|
/* invalid mode */
|
|
|
|
|
retval = -1;
|
|
|
|
|
}
|
|
|
|
|
remove (l1->temp_name); /* remove temporary file */
|
|
|
|
|
free (l1->command); /* dealloc memory */
|
|
|
|
|
free (l1); /* dealloc memory */
|
|
|
|
|
l1 = NULL; /* make pointer bogus */
|
|
|
|
|
|
|
|
|
|
return retval; /* retval==0 ? OK : ERROR */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* defined(__DJGPP__) */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static long MouseAutoDelay = 400;
|
|
|
|
|
static long MouseAutoRepeat = 5;
|
|
|
|
|
static long MouseMultiClick = 300;
|
|
|
|
|
|
|
|
|
|
static int Initialized = 0;
|
|
|
|
|
static int MousePresent = 0;
|
|
|
|
|
static int CursorVisible = 1; /* 1 means visible */
|
|
|
|
|
static int MouseVisible = 0; /* 0 means hidden */
|
|
|
|
|
static TEvent MouseEv = { evNone };
|
|
|
|
|
static TEvent EventBuf = { evNone };
|
|
|
|
|
//static HMOU MouseHandle = 0;
|
|
|
|
|
//static KBDINFO SaveKbdState;
|
|
|
|
|
|
|
|
|
|
// misc
|
|
|
|
|
|
|
|
|
|
static void DrawCursor(int Show) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void DrawMouse(int Show)
|
|
|
|
|
{
|
|
|
|
|
if (!MousePresent) return;
|
|
|
|
|
if (Show)
|
|
|
|
|
MOUSCursen(TRUE);
|
|
|
|
|
else
|
|
|
|
|
MOUSCursen(FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct { // TransCharScan
|
|
|
|
|
unsigned short CharScan;
|
|
|
|
|
TKeyCode KeyCode;
|
|
|
|
|
} TransCharScan[] = {
|
|
|
|
|
{ 0x0100, kbEsc }, { 0x011B, kbEsc },
|
|
|
|
|
{ 0x1C0D, kbEnter }, { 0x1C0A, kbEnter },
|
|
|
|
|
{ 0x1C00, kbEnter }, { 0xE00D, kbEnter | kfGray },
|
|
|
|
|
{ 0xA600, kbEnter | kfGray }, { 0xE00A, kbEnter | kfGray },
|
|
|
|
|
{ 0x0E08, kbBackSp }, { 0x0E7F, kbBackSp },
|
|
|
|
|
{ 0x0E00, kbBackSp }, { 0x0F09, kbTab },
|
|
|
|
|
{ 0x9400, kbTab }, { 0xA500, kbTab },
|
|
|
|
|
{ 0x0F00, kbTab }, { 0x4E00, '+' | kfGray },
|
|
|
|
|
{ 0x9000, '+' | kfGray }, { 0x4E2B, '+' | kfGray },
|
|
|
|
|
{ 0x4A00, '-' | kfGray }, { 0x8E00, '-' | kfGray },
|
|
|
|
|
{ 0x4A2D, '-' | kfGray }, { 0x3700, '*' | kfGray },
|
|
|
|
|
{ 0x9600, '*' | kfGray }, { 0x372A, '*' | kfGray },
|
|
|
|
|
{ 0xE02F, '/' | kfGray }, { 0xA400, '/' | kfGray },
|
|
|
|
|
{ 0x9500, '/' | kfGray }, { 0x0300, 0 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct { // TransScan
|
|
|
|
|
int ScanCode;
|
|
|
|
|
TKeyCode KeyCode;
|
|
|
|
|
} TransScan[] = {
|
|
|
|
|
{ 0x78, '1' }, { 0x79, '2' }, { 0x7A, '3' }, { 0x7B, '4' }, { 0x7C, '5' },
|
|
|
|
|
{ 0x7D, '6' }, { 0x7E, '7' }, { 0x7F, '8' }, { 0x80, '9' }, { 0x81, '0' },
|
|
|
|
|
|
|
|
|
|
{ 0x10, 'Q' }, { 0x11, 'W' }, { 0x12, 'E' }, { 0x13, 'R' }, { 0x14, 'T' },
|
|
|
|
|
{ 0x15, 'Y' }, { 0x16, 'U' }, { 0x17, 'I' }, { 0x18, 'O' }, { 0x19, 'P' },
|
|
|
|
|
|
|
|
|
|
{ 0x1E, 'A' }, { 0x1F, 'S' }, { 0x20, 'D' }, { 0x21, 'F' }, { 0x22, 'G' },
|
|
|
|
|
{ 0x23, 'H' }, { 0x24, 'J' }, { 0x25, 'K' }, { 0x26, 'L' },
|
|
|
|
|
|
|
|
|
|
{ 0x2C, 'Z' }, { 0x2D, 'X' }, { 0x2E, 'C' }, { 0x2F, 'V' }, { 0x30, 'B' },
|
|
|
|
|
{ 0x31, 'N' }, { 0x32, 'M' },
|
|
|
|
|
|
|
|
|
|
{ 0x29, '`' }, { 0x82, '-' }, { 0x83, '=' }, { 0x2B, '\\' }, { 0x1A, '[' },
|
|
|
|
|
{ 0x1B, ']' }, { 0x27, ';' }, { 0x28, '\'' }, { 0x33, ',' }, { 0x34, '.' },
|
|
|
|
|
{ 0x35, '/' }, { 0x37, '*' }, { 0x4E, '+' }, { 0x4A, '-' },
|
|
|
|
|
|
|
|
|
|
{ 0x3B, kbF1 }, { 0x3C, kbF2 }, { 0x3D, kbF3 },
|
|
|
|
|
{ 0x3E, kbF4 }, { 0x3F, kbF5 }, { 0x40, kbF6 },
|
|
|
|
|
{ 0x41, kbF7 }, { 0x42, kbF8 }, { 0x43, kbF9 },
|
|
|
|
|
{ 0x44, kbF10 }, { 0x85, kbF11 }, { 0x86, kbF12 },
|
|
|
|
|
|
|
|
|
|
{ 0x54, kbF1 }, { 0x55, kbF2 }, { 0x56, kbF3 },
|
|
|
|
|
{ 0x57, kbF4 }, { 0x58, kbF5 }, { 0x59, kbF6 },
|
|
|
|
|
{ 0x5A, kbF7 }, { 0x5B, kbF8 }, { 0x5C, kbF9 },
|
|
|
|
|
{ 0x5D, kbF10 }, { 0x87, kbF11 }, { 0x88, kbF12 },
|
|
|
|
|
|
|
|
|
|
{ 0x5E, kbF1 }, { 0x5F, kbF2 }, { 0x60, kbF3 },
|
|
|
|
|
{ 0x61, kbF4 }, { 0x62, kbF5 }, { 0x63, kbF6 },
|
|
|
|
|
{ 0x64, kbF7 }, { 0x65, kbF8 }, { 0x66, kbF9 },
|
|
|
|
|
{ 0x67, kbF10 }, { 0x89, kbF11 }, { 0x8A, kbF12 },
|
|
|
|
|
|
|
|
|
|
{ 0x68, kbF1 }, { 0x69, kbF2 }, { 0x6A, kbF3 },
|
|
|
|
|
{ 0x6B, kbF4 }, { 0x6C, kbF5 }, { 0x6D, kbF6 },
|
|
|
|
|
{ 0x6E, kbF7 }, { 0x6F, kbF8 }, { 0x70, kbF9 },
|
|
|
|
|
{ 0x71, kbF10 }, { 0x8B, kbF11 }, { 0x8C, kbF12 },
|
|
|
|
|
|
|
|
|
|
{ 0x47, kbHome }, { 0x48, kbUp }, { 0x49, kbPgUp },
|
|
|
|
|
{ 0x4B, kbLeft }, { 0x4C, kbCenter}, { 0x4D, kbRight },
|
|
|
|
|
{ 0x4F, kbEnd }, { 0x50, kbDown }, { 0x51, kbPgDn },
|
|
|
|
|
{ 0x52, kbIns }, { 0x53, kbDel },
|
|
|
|
|
|
|
|
|
|
{ 0x77, kbHome }, { 0x8D, kbUp }, { 0x84, kbPgUp },
|
|
|
|
|
{ 0x73, kbLeft }, { 0x74, kbRight },
|
|
|
|
|
{ 0x75, kbEnd }, { 0x91, kbDown }, { 0x76, kbPgDn },
|
|
|
|
|
{ 0x92, kbIns }, { 0x93, kbDel },
|
|
|
|
|
|
|
|
|
|
{ 0x97, kbHome | kfGray }, { 0x98, kbUp | kfGray }, { 0x99, kbPgUp | kfGray },
|
|
|
|
|
{ 0x9B, kbLeft | kfGray }, { 0x9D, kbRight | kfGray },
|
|
|
|
|
{ 0x9F, kbEnd | kfGray }, { 0xA0, kbDown | kfGray }, { 0xA1, kbPgDn | kfGray },
|
|
|
|
|
{ 0xA2, kbIns | kfGray }, { 0xA3, kbDel | kfGray }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int ReadKbdEvent(TEvent *Event, int Wait)
|
|
|
|
|
{
|
|
|
|
|
struct plKbdInfo ki;
|
|
|
|
|
|
|
|
|
|
UBYTE CharCode, ScanCode;
|
|
|
|
|
ULONG KeyCode, KeyFlags;
|
|
|
|
|
UWORD CharScan, Flags;
|
|
|
|
|
static ULONG PrevFlags = 0;
|
|
|
|
|
int I;
|
|
|
|
|
const int Tcs = (int) (sizeof(TransCharScan)/sizeof(TransCharScan[0]));
|
|
|
|
|
const int Ts = (int) (sizeof(TransScan)/sizeof(TransScan[0]));
|
|
|
|
|
|
|
|
|
|
Event->What = evNone;
|
|
|
|
|
if(! plKbdReadF(&ki)) return 0; // No data-> no read..
|
|
|
|
|
Event->What = evKeyDown;
|
|
|
|
|
|
|
|
|
|
CharCode = ki.ki_ascii;
|
|
|
|
|
ScanCode = ki.ki_scan;
|
|
|
|
|
CharScan = (UWORD)((((UWORD)ScanCode) << 8) | ((UWORD)CharCode));
|
|
|
|
|
Flags = ki.ki_flags;
|
|
|
|
|
KeyCode = 0;
|
|
|
|
|
KeyFlags = 0;
|
|
|
|
|
|
|
|
|
|
/* printf("Key: %X %X %X %X %X \n", (unsigned long) ki.bNlsShift, (unsigned long) ki.fbStatus, (unsigned long) Flags, (unsigned long) CharCode, (unsigned long) ScanCode);*/
|
|
|
|
|
|
|
|
|
|
if ((Flags & PLKF_SHIFT) != 0) KeyFlags |= kfShift;
|
|
|
|
|
if ((Flags & PLKF_CTRL) != 0) KeyFlags |= kfCtrl;
|
|
|
|
|
|
|
|
|
|
/* cpCount = sizeof(cpList);*/
|
|
|
|
|
/* rc = DosQueryCp(sizeof(cpList), cpList, &cpCount); // get active code page*/
|
|
|
|
|
if (CharCode != 0) {
|
|
|
|
|
// if ((Flags & PLKF_ALT) != 0) KeyFlags |= kfAlt;
|
|
|
|
|
} else {
|
|
|
|
|
if((Flags & PLKF_ALT) != 0) KeyFlags |= kfAlt;
|
|
|
|
|
}
|
|
|
|
|
/* if (rc != 0) printf("rc = %d\n", rc);*/
|
|
|
|
|
|
|
|
|
|
if (CharScan == 0) { /* shift/alt/ctrl/caps/scroll/num */
|
|
|
|
|
|
|
|
|
|
} else if (ScanCode == 0) { /* alt numeric */
|
|
|
|
|
KeyCode = CharCode;
|
|
|
|
|
KeyFlags |= kfAltXXX;
|
|
|
|
|
} else { /* now check special combinations */
|
|
|
|
|
for (I = 0; I < Tcs; I++)
|
|
|
|
|
if (TransCharScan[I].CharScan == CharScan) {
|
|
|
|
|
KeyCode = TransCharScan[I].KeyCode;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (KeyCode == 0) {
|
|
|
|
|
if ((CharCode == 0) || (CharCode == 0xE0)) {
|
|
|
|
|
if (CharCode == 0xE0)
|
|
|
|
|
KeyFlags |= kfGray;
|
|
|
|
|
for (I = 0; I < Ts; I++)
|
|
|
|
|
if (TransScan[I].ScanCode == ScanCode) {
|
|
|
|
|
KeyCode = TransScan[I].KeyCode;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
KeyCode = CharCode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Event->Key.Code = KeyCode | KeyFlags;
|
|
|
|
|
PrevFlags = Flags;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define TM_DIFF(x,y) ((long)(((long)(x) < (long)(y)) ? ((long)(y) - (long)(x)) : ((long)(x) - (long)(y))))
|
|
|
|
|
|
|
|
|
|
int ReadMouseEvent(TEvent *Event, unsigned long EventMask)
|
|
|
|
|
{
|
|
|
|
|
static unsigned short PrevState = 0;
|
|
|
|
|
static unsigned short PrevButtons = 0;
|
|
|
|
|
static TEvent LastMouseEvent = { evNone };
|
|
|
|
|
static ULONG LastEventTime = 0;
|
|
|
|
|
static ULONG LastClick = 0;
|
|
|
|
|
static ULONG LastClickTime = 0;
|
|
|
|
|
static ULONG LastClickCount = 0;
|
|
|
|
|
// MOUEVENTINFO mi;
|
|
|
|
|
unsigned short Buttons, State, Btn;
|
|
|
|
|
// USHORT fWait = MOU_NOWAIT;
|
|
|
|
|
// MOUQUEINFO mq;
|
|
|
|
|
ULONG CurTime;
|
|
|
|
|
UWORD cx, cy;
|
|
|
|
|
int butf;
|
|
|
|
|
boolean rb, lb;
|
|
|
|
|
static int Scx = -1, Scy = -1;
|
|
|
|
|
static boolean Slb, Srb;
|
|
|
|
|
|
|
|
|
|
// CurTime = plTmGet(); // 2do!
|
|
|
|
|
Event->What = evNone;
|
|
|
|
|
|
|
|
|
|
//** Distill an event from the current position & button state of the mouse.
|
|
|
|
|
MOUSPos(&cx, &cy, &lb, &rb);
|
|
|
|
|
cx /= 8;
|
|
|
|
|
cy /= 8;
|
|
|
|
|
if(Scx == -1)
|
|
|
|
|
{
|
|
|
|
|
Scx = cx; // Force initial state to here.
|
|
|
|
|
Scy = cy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//** Assume something happened.. Set the mouse' position,
|
|
|
|
|
butf = (lb ? 0x01 : 0) | (rb ? 0x02 : 0);
|
|
|
|
|
Event->Mouse.X = cx;
|
|
|
|
|
Event->Mouse.Y = cy;
|
|
|
|
|
Event->Mouse.Count = 1;
|
|
|
|
|
|
|
|
|
|
//** 1. Has the buttons state changed?
|
|
|
|
|
if(Slb != lb)
|
|
|
|
|
{
|
|
|
|
|
Event->What = lb ? evMouseDown : evMouseUp;
|
|
|
|
|
Event->Mouse.Buttons = 0x01; //lb ? 0x01 : 0;
|
|
|
|
|
Slb = lb;
|
|
|
|
|
}
|
|
|
|
|
else if(Srb != rb)
|
|
|
|
|
{
|
|
|
|
|
Event->What = rb ? evMouseDown : evMouseUp;
|
|
|
|
|
Event->Mouse.Buttons = 0x02; // rb ? 0x02 : 0;
|
|
|
|
|
Srb = rb;
|
|
|
|
|
}
|
|
|
|
|
else if(cx != Scx || cy != Scy)
|
|
|
|
|
{
|
|
|
|
|
//** Mouse move.
|
|
|
|
|
Event->What = evMouseMove;
|
|
|
|
|
Event->Mouse.Buttons = butf;
|
|
|
|
|
Event->Mouse.Count = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//** Any event?
|
|
|
|
|
if(Event->What == evNone)
|
|
|
|
|
{
|
|
|
|
|
//** Handle repeat here!!
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// printf("[ev=%d, b=%d] ", Event->What, Event->Mouse.Buttons);
|
|
|
|
|
|
|
|
|
|
//** Something happened..
|
|
|
|
|
Scx = cx;
|
|
|
|
|
Scy = cy;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MouGetNumQueEl(&mq, MouseHandle);
|
|
|
|
|
if (mq.cEvents == 0) {
|
|
|
|
|
if (LastMouseEvent.What == evMouseAuto && (EventMask & evMouseAuto)) {
|
|
|
|
|
if (TM_DIFF(CurTime, LastEventTime) >= MouseAutoRepeat) {
|
|
|
|
|
*Event = LastMouseEvent;
|
|
|
|
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &LastEventTime, 4);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((LastMouseEvent.What == evMouseDown || LastMouseEvent.What == evMouseMove)
|
|
|
|
|
&&
|
|
|
|
|
(LastMouseEvent.Mouse.Buttons)
|
|
|
|
|
&& (EventMask & evMouseAuto))
|
|
|
|
|
{
|
|
|
|
|
if (TM_DIFF(CurTime, LastEventTime) >= MouseAutoDelay) {
|
|
|
|
|
LastMouseEvent.What = evMouseAuto;
|
|
|
|
|
*Event = LastMouseEvent;
|
|
|
|
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &LastEventTime, 4);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MouReadEventQue(&mi, &fWait, MouseHandle) != 0) return 0;
|
|
|
|
|
Event->Mouse.X = mi.col;
|
|
|
|
|
Event->Mouse.Y = mi.row;
|
|
|
|
|
State = mi.fs;
|
|
|
|
|
Btn = Buttons = ((State & (2 | 4))?1:0) |
|
|
|
|
|
((State & (8 | 16))?2:0) |
|
|
|
|
|
((State & (32 | 64))?4:0);
|
|
|
|
|
if (Buttons != PrevButtons) {
|
|
|
|
|
Buttons ^= PrevButtons;
|
|
|
|
|
if (PrevButtons & Buttons)
|
|
|
|
|
Event->What = evMouseUp;
|
|
|
|
|
else
|
|
|
|
|
Event->What = evMouseDown;
|
|
|
|
|
} else
|
|
|
|
|
Event->What = evMouseMove;
|
|
|
|
|
Event->Mouse.Buttons = Buttons;
|
|
|
|
|
Event->Mouse.Count = 1;
|
|
|
|
|
PrevState = State;
|
|
|
|
|
PrevButtons = Btn;
|
|
|
|
|
|
|
|
|
|
if (Event->What == evMouseDown) {
|
|
|
|
|
if (LastClickCount) {
|
|
|
|
|
if (LastClick == Event->Mouse.Buttons) {
|
|
|
|
|
if (TM_DIFF(CurTime, LastClickTime) <= MouseMultiClick) {
|
|
|
|
|
Event->Mouse.Count = ++LastClickCount;
|
|
|
|
|
} else {
|
|
|
|
|
LastClickCount = 0;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
LastClick = 0;
|
|
|
|
|
LastClickCount = 0;
|
|
|
|
|
LastClickTime = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LastClick = Event->Mouse.Buttons;
|
|
|
|
|
if (LastClickCount == 0)
|
|
|
|
|
LastClickCount = 1;
|
|
|
|
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &LastClickTime, 4);
|
|
|
|
|
}
|
|
|
|
|
/* if (Event->What == evMouseMove) {
|
|
|
|
|
LastClick = 0;
|
|
|
|
|
LastClickCount = 0;
|
|
|
|
|
LastClickTime = 0;
|
|
|
|
|
}*/
|
|
|
|
|
{
|
|
|
|
|
KBDINFO ki;
|
|
|
|
|
USHORT Flags;
|
|
|
|
|
TKeyCode KeyFlags = 0;
|
|
|
|
|
|
|
|
|
|
ki.cb = sizeof(ki);
|
|
|
|
|
KbdGetStatus(&ki, 0);
|
|
|
|
|
Flags = ki.fsState;
|
|
|
|
|
|
|
|
|
|
if ((Flags & (LEFTSHIFT | RIGHTSHIFT)) != 0) KeyFlags |= kfShift;
|
|
|
|
|
if ((Flags & (LEFTCONTROL | RIGHTCONTROL)) != 0) KeyFlags |= kfCtrl;
|
|
|
|
|
if ((Flags & (LEFTALT | RIGHTALT)) != 0) KeyFlags |= kfAlt;
|
|
|
|
|
|
|
|
|
|
Event->Mouse.KeyMask = KeyFlags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LastMouseEvent = *Event;
|
|
|
|
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &LastEventTime, 4);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int ConClear()
|
|
|
|
|
{
|
|
|
|
|
plScnSetCell(0, 0, plScnWidth(), plScnHeight(), 0x0720);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConPutBox(int X, int Y, int W, int H, PCell Cell) {
|
|
|
|
|
int I;
|
|
|
|
|
int MX, MY;
|
|
|
|
|
int MouseHidden = 0;
|
|
|
|
|
char *p = (char *) Cell;
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
ConQueryMousePos(&MX, &MY);
|
|
|
|
|
|
|
|
|
|
for (I = 0; I < H; I++) {
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
if (Y + I == MY)
|
|
|
|
|
if ((MX >= X) && (MX <= X + W)) {
|
|
|
|
|
DrawMouse(0);
|
|
|
|
|
MouseHidden = 1;
|
|
|
|
|
}
|
|
|
|
|
plScnWrite(X, Y+I, (UWORD *)p, W);
|
|
|
|
|
|
|
|
|
|
if (MouseHidden) {
|
|
|
|
|
DrawMouse(1);
|
|
|
|
|
MouseHidden = 0;
|
|
|
|
|
}
|
|
|
|
|
p += W << 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConGetBox(int X, int Y, int W, int H, PCell Cell) {
|
|
|
|
|
int I;
|
|
|
|
|
int MX, MY;
|
|
|
|
|
int MouseHidden = 0;
|
|
|
|
|
// USHORT WW = (U)(W << 1);
|
|
|
|
|
char *p = (char *) Cell;
|
|
|
|
|
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
ConQueryMousePos(&MX, &MY);
|
|
|
|
|
|
|
|
|
|
for (I = 0; I < H; I++) {
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
if (Y + I == MY)
|
|
|
|
|
if (MX >= X && MX < X + W) {
|
|
|
|
|
DrawMouse(0);
|
|
|
|
|
MouseHidden = 1;
|
|
|
|
|
}
|
|
|
|
|
plScnRead(X, Y+I, (unsigned short*) p, W);
|
|
|
|
|
|
|
|
|
|
if (MouseHidden) {
|
|
|
|
|
DrawMouse(1);
|
|
|
|
|
MouseHidden = 0;
|
|
|
|
|
}
|
|
|
|
|
p += W << 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConPutLine(int X, int Y, int W, int H, PCell Cell)
|
|
|
|
|
{
|
|
|
|
|
int I;
|
|
|
|
|
int MX, MY;
|
|
|
|
|
int MouseHidden = 0;
|
|
|
|
|
char *p = (char *) Cell;
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
ConQueryMousePos(&MX, &MY);
|
|
|
|
|
|
|
|
|
|
for (I = 0; I < H; I++) {
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
if (Y + I == MY)
|
|
|
|
|
if (MX >= X && MX < X + W) {
|
|
|
|
|
DrawMouse(0);
|
|
|
|
|
MouseHidden = 1;
|
|
|
|
|
}
|
|
|
|
|
plScnWrite(X, Y+I, (UWORD *) p, W);
|
|
|
|
|
|
|
|
|
|
if (MouseHidden) {
|
|
|
|
|
DrawMouse(1);
|
|
|
|
|
MouseHidden = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConSetBox(int X, int Y, int W, int H, TCell Cell) {
|
|
|
|
|
int I;
|
|
|
|
|
int MX, MY;
|
|
|
|
|
int MouseHidden = 0;
|
|
|
|
|
char *p = (char *) &Cell;
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
ConQueryMousePos(&MX, &MY);
|
|
|
|
|
|
|
|
|
|
for (I = 0; I < H; I++) {
|
|
|
|
|
if (MouseVisible)
|
|
|
|
|
if (Y + I == MY)
|
|
|
|
|
if (MX >= X && MX < X + W) {
|
|
|
|
|
DrawMouse(0);
|
|
|
|
|
MouseHidden = 1;
|
|
|
|
|
}
|
|
|
|
|
plScnSetCell(X, Y+I, W, 1, (UWORD)Cell);
|
|
|
|
|
// VioWrtNCell(p, (USHORT)(W), (USHORT)(Y + I), (USHORT)X, 0);
|
|
|
|
|
|
|
|
|
|
if (MouseHidden) {
|
|
|
|
|
DrawMouse(1);
|
|
|
|
|
MouseHidden = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConScroll(int Way, int X, int Y, int W, int H, TAttr Fill, int Count)
|
|
|
|
|
{
|
|
|
|
|
int MX, MY;
|
|
|
|
|
int MouseHidden = 0;
|
|
|
|
|
TCell FillCell = (TCell)(Fill << 8);
|
|
|
|
|
|
|
|
|
|
if (MousePresent && MouseVisible)
|
|
|
|
|
{
|
|
|
|
|
ConQueryMousePos(&MX, &MY);
|
|
|
|
|
if (MX >= X && MX < X + W && MY >= Y && MY < Y + H)
|
|
|
|
|
{
|
|
|
|
|
DrawMouse(0);
|
|
|
|
|
MouseHidden = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (Way)
|
|
|
|
|
{
|
|
|
|
|
case csUp: plScnScrollUp(X, Y, X+W, Y+H, Count, (UWORD)FillCell); break;
|
|
|
|
|
case csDown:plScnScrollDown(X, Y, X+W, Y+H, Count, (UWORD)FillCell); break;
|
|
|
|
|
case csLeft:
|
|
|
|
|
// VioScrollLf((USHORT)Y, (USHORT)X, (USHORT)(Y + H - 1), (USHORT)(X + W - 1), (USHORT)Count, (PBYTE)&FillCell, 0);
|
|
|
|
|
break;
|
|
|
|
|
case csRight:
|
|
|
|
|
// VioScrollRt((USHORT)Y, (USHORT)X, (USHORT)(Y + H - 1), (USHORT)(X + W - 1), (USHORT)Count, (PBYTE)&FillCell, 0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (MouseHidden)
|
|
|
|
|
DrawMouse(1);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConSetSize(int X, int Y) {
|
2019-03-31 17:13:55 -04:00
|
|
|
|
// explicitly turn off/on the mouse and reset it's boundaries at the
|
|
|
|
|
// same time. the turn off/on thing ensures the cursor doesn't disappear
|
|
|
|
|
// after the screen mode switch
|
|
|
|
|
MOUSCursen(FALSE);
|
|
|
|
|
plScnSetSize(X, Y);
|
|
|
|
|
MOUSSetBounds();
|
|
|
|
|
MOUSCursen(TRUE);
|
2019-03-31 15:57:52 -04:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConQuerySize(int *X, int *Y) {
|
|
|
|
|
*X = plScnWidth();
|
|
|
|
|
*Y = plScnHeight();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConSetCursorPos(int X, int Y) {
|
|
|
|
|
plScnCursorPos(X, Y);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConQueryCursorPos(int *X, int *Y) {
|
|
|
|
|
plScnCursorPosGet(X, Y);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConShowCursor() {
|
|
|
|
|
CursorVisible = 1;
|
|
|
|
|
plScnCursorOn(TRUE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConHideCursor() {
|
|
|
|
|
CursorVisible = 0;
|
|
|
|
|
plScnCursorOn(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConSetCursorSize(int Start, int End) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//int ConSetMousePos(int X, int Y) {
|
|
|
|
|
// return 0;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* */
|
|
|
|
|
/* CODING: Mouse stuff. */
|
|
|
|
|
/* */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ConQueryMousePos(int *X, int *Y) {
|
|
|
|
|
UWORD a, b;
|
|
|
|
|
boolean lb, rb;
|
|
|
|
|
|
|
|
|
|
if(! MOUSIsPresent()) return -1;
|
|
|
|
|
|
|
|
|
|
MOUSPos(&a, &b, &lb, &rb);
|
|
|
|
|
*X = a / 8;
|
|
|
|
|
*Y = b / 8;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConShowMouse()
|
|
|
|
|
{
|
|
|
|
|
MouseVisible = TRUE;
|
|
|
|
|
if(! MOUSIsPresent()) return -1;
|
|
|
|
|
MOUSCursen(TRUE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConHideMouse()
|
|
|
|
|
{
|
|
|
|
|
MouseVisible = FALSE;
|
|
|
|
|
if(! MOUSIsPresent()) return -1;
|
|
|
|
|
MOUSCursen(FALSE);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConMouseVisible() {
|
|
|
|
|
return MouseVisible;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConQueryMouseButtons(int *ButtonCount) {
|
|
|
|
|
if(ButtonCount != 0) *ButtonCount = 2;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ConInit(int XSize, int YSize)
|
|
|
|
|
{
|
|
|
|
|
if(Initialized) return 0;
|
|
|
|
|
|
|
|
|
|
EventBuf.What = evNone;
|
2019-03-31 17:13:55 -04:00
|
|
|
|
ConSetSize(XSize, YSize);
|
2019-03-31 15:57:52 -04:00
|
|
|
|
MousePresent = MOUSInit();
|
|
|
|
|
ConContinue();
|
|
|
|
|
Initialized = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConDone()
|
|
|
|
|
{
|
|
|
|
|
return ConSuspend();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConSuspend()
|
|
|
|
|
{
|
|
|
|
|
plScnSetFlash(TRUE); // Set "flash" mode, not bright mode
|
|
|
|
|
ConHideMouse();
|
|
|
|
|
#if defined(SIGBREAK)
|
|
|
|
|
signal(SIGBREAK, SIG_DFL);
|
|
|
|
|
#endif
|
|
|
|
|
signal(SIGINT, SIG_DFL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConContinue()
|
|
|
|
|
{
|
|
|
|
|
#if defined(SIGBREAK)
|
|
|
|
|
signal(SIGBREAK, SIG_IGN);
|
|
|
|
|
#endif
|
|
|
|
|
signal(SIGINT, SIG_IGN);
|
|
|
|
|
plScnSetFlash(FALSE); // Set "bright" mode, not flashing
|
|
|
|
|
ConShowMouse();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetPipeEvent(TEvent *Event) {
|
2019-03-31 16:44:55 -04:00
|
|
|
|
#if defined(DJGPP) || defined(WATCOM)
|
2019-03-31 15:57:52 -04:00
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
Event->What = evNone;
|
|
|
|
|
for (i = 0; i < MAX_PIPES; i++) {
|
|
|
|
|
if (Pipes[i].used == 0) continue;
|
|
|
|
|
if (Pipes[i].notify == 0) continue;
|
|
|
|
|
if (1) {
|
|
|
|
|
//fprintf(stderr, "Pipe New Data: %d\n", i);
|
|
|
|
|
Event->What = evNotify;
|
|
|
|
|
Event->Msg.View = 0;
|
|
|
|
|
Event->Msg.Model = Pipes[i].notify;
|
|
|
|
|
Event->Msg.Command = cmPipeRead;
|
|
|
|
|
Event->Msg.Param1 = i;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConGetEvent(TEventMask EventMask, TEvent *Event, int WaitTime, int Delete)
|
|
|
|
|
{
|
|
|
|
|
if (EventBuf.What != evNone)
|
|
|
|
|
{
|
|
|
|
|
*Event = EventBuf;
|
|
|
|
|
if (Delete) EventBuf.What = evNone;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (MouseEv.What != evNone)
|
|
|
|
|
{
|
|
|
|
|
*Event = MouseEv;
|
|
|
|
|
if (Delete) MouseEv.What = evNone;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
EventBuf.What = evNone;
|
|
|
|
|
Event->What = evNone;
|
|
|
|
|
|
|
|
|
|
if(! (ReadKbdEvent(Event, WaitTime) == 1) && (EventMask & evKeyboard))
|
|
|
|
|
{
|
|
|
|
|
if(MousePresent && (ReadMouseEvent(Event, EventMask) == 1) && (EventMask & evMouse))
|
|
|
|
|
;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(GetPipeEvent(Event) != 1)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (Event->What != evNone)
|
|
|
|
|
{
|
|
|
|
|
if (Event->What == evMouseMove)
|
|
|
|
|
{
|
|
|
|
|
while (ReadMouseEvent(&MouseEv, EventMask) == 1)
|
|
|
|
|
{
|
|
|
|
|
if (MouseEv.What == evMouseMove)
|
|
|
|
|
{
|
|
|
|
|
*Event = MouseEv;
|
|
|
|
|
MouseEv.What = evNone;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EventBuf = *Event;
|
|
|
|
|
if (Delete) EventBuf.What = evNone;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static PCell SavedScreen = 0;
|
|
|
|
|
static int SavedX, SavedY, SaveCursorPosX, SaveCursorPosY;
|
|
|
|
|
|
|
|
|
|
int SaveScreen() {
|
|
|
|
|
if (SavedScreen)
|
|
|
|
|
free(SavedScreen);
|
|
|
|
|
|
|
|
|
|
ConQuerySize(&SavedX, &SavedY);
|
|
|
|
|
|
|
|
|
|
SavedScreen = (PCell) malloc(SavedX * SavedY * sizeof(PCell));
|
|
|
|
|
|
|
|
|
|
if (SavedScreen)
|
|
|
|
|
ConGetBox(0, 0, SavedX, SavedY, SavedScreen);
|
|
|
|
|
ConQueryCursorPos(&SaveCursorPosX, &SaveCursorPosY);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int RestoreScreen() {
|
|
|
|
|
if (SavedScreen) {
|
2019-03-31 17:13:55 -04:00
|
|
|
|
ConSetSize(SavedX, SavedY);
|
2019-03-31 15:57:52 -04:00
|
|
|
|
ConPutBox(0, 0, SavedX, SavedY, SavedScreen);
|
|
|
|
|
ConSetCursorPos(SaveCursorPosX, SaveCursorPosY);
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GUI::GUI(int &argc, char **argv, int XSize, int YSize) {
|
|
|
|
|
fArgc = argc;
|
|
|
|
|
fArgv = argv;
|
|
|
|
|
SaveScreen();
|
2019-03-31 17:13:55 -04:00
|
|
|
|
::ConInit(XSize, YSize);
|
2019-03-31 15:57:52 -04:00
|
|
|
|
gui = this;
|
|
|
|
|
#ifdef DJGPP
|
|
|
|
|
// speed up directory access by turning off unused stat functionality
|
|
|
|
|
_djstat_flags |= _STAT_INODE;
|
|
|
|
|
_djstat_flags |= _STAT_EXEC_EXT;
|
|
|
|
|
_djstat_flags |= _STAT_EXEC_MAGIC;
|
|
|
|
|
_djstat_flags |= _STAT_DIRSIZE;
|
|
|
|
|
_djstat_flags |= _STAT_ROOT_TIME;
|
|
|
|
|
_djstat_flags |= _STAT_WRITEBIT;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GUI::~GUI() {
|
|
|
|
|
RestoreScreen();
|
2019-03-31 17:13:55 -04:00
|
|
|
|
// HACK: clearing the screen to hide the fact that there's something
|
|
|
|
|
// screwy going on with the screen restore when using non-80x25 mode
|
|
|
|
|
// that i cannot pin down ...
|
|
|
|
|
::ConClear();
|
2019-03-31 15:57:52 -04:00
|
|
|
|
::ConDone();
|
|
|
|
|
|
|
|
|
|
if(SavedScreen)
|
|
|
|
|
{
|
|
|
|
|
free(SavedScreen);
|
|
|
|
|
SavedScreen = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gui = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::ConSuspend(void) {
|
|
|
|
|
RestoreScreen();
|
|
|
|
|
return ::ConSuspend();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::ConContinue(void) {
|
|
|
|
|
SaveScreen();
|
|
|
|
|
return ::ConContinue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::ShowEntryScreen() {
|
|
|
|
|
TEvent E;
|
|
|
|
|
|
|
|
|
|
ConHideMouse();
|
|
|
|
|
RestoreScreen();
|
|
|
|
|
do { gui->ConGetEvent(evKeyDown, &E, -1, 1, 0); } while (E.What != evKeyDown);
|
2019-03-31 17:13:55 -04:00
|
|
|
|
ConSetSize(ScreenSizeX, ScreenSizeY);
|
2019-03-31 15:57:52 -04:00
|
|
|
|
ConShowMouse();
|
|
|
|
|
if (frames)
|
|
|
|
|
frames->Repaint();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//static int CreatePipeChild(PID &pid, HPIPE &hfPipe, char *Command) {
|
|
|
|
|
// return 0;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
static void PipeThread(void *p) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::OpenPipe(char *Command, EModel *notify) {
|
2019-03-31 16:44:55 -04:00
|
|
|
|
#if defined(DJGPP) || defined(WATCOM)
|
2019-03-31 15:57:52 -04:00
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAX_PIPES; i++) {
|
|
|
|
|
if (Pipes[i].used == 0) {
|
|
|
|
|
Pipes[i].id = i;
|
|
|
|
|
Pipes[i].notify = notify;
|
|
|
|
|
Pipes[i].stopped = 1;
|
|
|
|
|
|
2019-03-31 17:13:55 -04:00
|
|
|
|
// when a long-ish running command gets run here, sometimes
|
|
|
|
|
// the mouse cursor disappears on returning from the command,
|
|
|
|
|
// so we turn it off/on here just to be safe
|
|
|
|
|
MOUSCursen(FALSE);
|
|
|
|
|
|
2019-03-31 15:57:52 -04:00
|
|
|
|
Pipes[i].fp = xpopen(Command,"r");
|
2019-03-31 17:13:55 -04:00
|
|
|
|
|
|
|
|
|
MOUSSetBounds();
|
|
|
|
|
MOUSCursen(TRUE);
|
|
|
|
|
|
2019-03-31 15:57:52 -04:00
|
|
|
|
if (Pipes[i].fp == NULL)
|
|
|
|
|
return -1;
|
|
|
|
|
Pipes[i].used = 1;
|
|
|
|
|
//fprintf(stderr, "Pipe Open: %d\n", i);
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
#else
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::SetPipeView(int id, EModel *notify) {
|
2019-03-31 16:44:55 -04:00
|
|
|
|
#if defined(DJGPP) || defined(WATCOM)
|
2019-03-31 15:57:52 -04:00
|
|
|
|
if (id < 0 || id >= MAX_PIPES)
|
|
|
|
|
return -1;
|
|
|
|
|
if (Pipes[id].used == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
//fprintf(stderr, "Pipe View: %d %08X\n", id, notify);
|
|
|
|
|
Pipes[id].notify = notify;
|
|
|
|
|
#endif
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::ReadPipe(int id, void *buffer, int len) {
|
2019-03-31 16:44:55 -04:00
|
|
|
|
#if defined(DJGPP) || defined(WATCOM)
|
2019-03-31 15:57:52 -04:00
|
|
|
|
int rc;
|
|
|
|
|
if (id < 0 || id >= MAX_PIPES)
|
|
|
|
|
return -1;
|
|
|
|
|
if (Pipes[id].used == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
//fprintf(stderr, "Pipe Read: Get %d %d\n", id, len);
|
|
|
|
|
|
|
|
|
|
rc = fread(buffer,1,len,Pipes[id].fp);
|
|
|
|
|
//fprintf(stderr, "Pipe Read: Got %d %d\n", id, rc);
|
|
|
|
|
if (ferror(Pipes[id].fp)) {
|
|
|
|
|
Pipes[id].stopped = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return rc == 0 ? -1 : rc;
|
|
|
|
|
#else
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::ClosePipe(int id) {
|
2019-03-31 16:44:55 -04:00
|
|
|
|
#if defined(DJGPP) || defined(WATCOM)
|
2019-03-31 15:57:52 -04:00
|
|
|
|
if (id < 0 || id >= MAX_PIPES)
|
|
|
|
|
return -1;
|
|
|
|
|
if (Pipes[id].used == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
Pipes[id].used = 0;
|
|
|
|
|
//fprintf(stderr, "Pipe Close: %d\n", id);
|
|
|
|
|
return xpclose(Pipes[id].fp);
|
|
|
|
|
#else
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GUI::RunProgram(int mode, char *Command) {
|
2019-03-31 17:13:55 -04:00
|
|
|
|
int rc, W, H;
|
2019-03-31 15:57:52 -04:00
|
|
|
|
|
|
|
|
|
ConQuerySize(&W, &H);
|
|
|
|
|
ConHideMouse();
|
|
|
|
|
ConSuspend();
|
|
|
|
|
|
|
|
|
|
if (*Command == 0) // empty string = shell
|
|
|
|
|
Command = getenv(
|
|
|
|
|
"COMSPEC"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
rc = system(Command);
|
|
|
|
|
|
|
|
|
|
ConContinue();
|
|
|
|
|
ConShowMouse();
|
|
|
|
|
|
2019-03-31 17:13:55 -04:00
|
|
|
|
// HACK: there used to be conditional logic here to check if a screen
|
|
|
|
|
// resize was actually needed using another call to ConQuerySize() to
|
|
|
|
|
// check the current size... i might need to revisit this again, but
|
|
|
|
|
// i opted to just always resize and repaint to ensure a consistent
|
|
|
|
|
// screen state always.
|
|
|
|
|
ConSetSize(W, H);
|
|
|
|
|
frames->Resize(W, H);
|
2019-03-31 15:57:52 -04:00
|
|
|
|
frames->Repaint();
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConSetTitle(char *Title, char *STitle) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConGetTitle(char *Title, int MaxLen, char *STitle, int SMaxLen) {
|
|
|
|
|
strcpy(Title, "FTE");
|
|
|
|
|
strcpy(STitle, "FTE");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConCursorVisible() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ConPutEvent(TEvent Event)
|
|
|
|
|
{
|
|
|
|
|
EventBuf = Event;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char ConGetDrawChar(int index) {
|
|
|
|
|
// static char tab[] = "ڿ<><DABF>ij<EFBFBD>ô<EFBFBD><C3B4>\x1A<31><04><19><>";
|
|
|
|
|
static const char tab[] = "ڿ<EFBFBD><EFBFBD>ij<EFBFBD>ô<EFBFBD><EFBFBD>\x1A<EFBFBD>\x04<EFBFBD>\x18\x19<EFBFBD><EFBFBD>\x1B\x1A";
|
|
|
|
|
|
|
|
|
|
assert(strlen(tab) > 20);
|
|
|
|
|
assert(index >= 0);
|
|
|
|
|
|
|
|
|
|
assert(index >= 0 && index < (int)strlen(tab));
|
|
|
|
|
|
|
|
|
|
return tab[index];
|
|
|
|
|
}
|