home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
WordPerfect for Linux Bible
/
WP4LinuxBible.iso
/
sdk
/
wpc
/
code
/
unixtpi.c
next >
Wrap
C/C++ Source or Header
|
1999-06-25
|
10KB
|
388 lines
/** Sample third-party interface, loaded from the "third.ini" file **/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "unixtpi.h"
#define WRULER 0x6f
#define WPRTSLC 0xcf
#define FUNCT 0x80
#define DUP 0x40
static unsigned char buf[256];
static char macbuf[2048];
static int fd;
static int in,out;
static int system = 0;
static int sysoff = 0;
/* data for xwp */
static char amessage[] = "You pressed the Ctrl-Shift-3 key!";
/* data for wp */
static char msg[] = {
0, 0, /* space for the length - calculated as needed */
0, 0, 0, 0, /* space for state */
'Y', 0, 'o', 0, 'u', 0, ' ', 0,
'p', 0, 'r', 0, 'e', 0, 's', 0,
's', 0, 'e', 0, 'd', 0, ' ', 0,
't', 0, 'h', 0, 'e', 0, ' ', 0,
'C', 0, 't', 0, 'r', 0, 'l', 0,
'-', 0, 'S', 0, 'h', 0, 'i', 0,
'f', 0, 't', 0, '-', 0, '3', 0,
' ', 0, 'k', 0, 'e', 0, 'y', 0,
'!', 0, 0 ,0
};
static char Alt_F4[] = {
12, 0, /* length */
0,0,0,0, /* state */
0xd, 0xfc, /* display on */
0x32,0x80, /* Print key */
'S',0, /* "Select" */
0, 0 /* NULL terminate macro */
};
static char Menu_number[] = {
14, 0, /* length */
0,0,0,0, /* state */
0x35, 0xfc, /* SYSTEM macro command */
'1', 0, /* SYSTEM variable number */
'3', 0, /* SYSTEM variable number */
'~', 0, /* end of SYSTEM command */
0, 0 /* NULL terminate macro */
};
static char Menu_prompt[] = {
46, 0, /* length */
0,0,0,0, /* state */
0xd, 0xfc, /* display on */
0x1f, 0xfc, /* PROMPT command */
0x10, 0x80, /* PROMPT POSITION command */
0x01, 0x80, /* column */
0x01, 0x80, /* row */
'M', 0,
'e', 0,
'n', 0,
'u', 0,
' ', 0,
'=', 0,
' ', 0,
' ', 0,
' ', 0,
' ', 0,
' ', 0,
' ', 0,
' ', 0,
' ', 0,
' ', 0,
0,0 /* NULL terminate macro */
};
/* convert 4 bytes in Intel order into an unsigned int (32 bits) */
unsigned long BtoI(b)
unsigned char *b;
{
unsigned long val;
val = *b++;
val += (unsigned int)*b++ << 8;
val += (unsigned int)*b++ << 16;
val += (unsigned int)*b << 24;
return val;
}
/********************************************************************
* Function: bread *
* *
* WordPerfect 5.1 doesn't put information in the pipe all at once. *
* It will get some information, put it in the pipe, get the next *
* piece of information, put it in the pipe, and so on. *
* *
* WP 5.1 may do several "gets" to produce one buffer. Because of *
* this, your TPI program should NEVER read the pipe directly. If *
* it does, you will never have a complete buffer to read from and *
* you will not know which part of the current buffer you are *
* getting the information for. *
* *
* The function "bread" has been provided for this purpose. This *
* function will gather the size of the current buffer and will *
* return the information for a buffer only when the buffer is *
* complete. Your program should always use this function. *
********************************************************************/
/* read cnt bytes from file decriptor fd */
bread(fd,buf,cnt)
int fd,cnt;
char *buf;
{
int br = 0;
for (;;) {
br += read(fd,buf+br,cnt-br); /* read bytes */
if (br == cnt) { /* did we get them all ? */
break; /* yes - return */
} /* no - loop for another read */
}
}
/* convert a character string to 2 byte tokens */
char *str2tok(str,len)
char *str;
int *len;
{
static char *buf = 0;
char *calloc();
int i;
char *tptr;
if (buf) {
free(buf); /* free the previous malloc if needed */
}
*len = 2*strlen(str);
buf = calloc(*len,1);
tptr = buf;
for (i=0;i<strlen(str);i++) {
*tptr++ = str[i];
tptr++;
}
return buf;
}
/* return a character unchanged to WP */
sendback()
{
write(out,buf,8);
}
main(argc,argv)
char *argv[];
{
int cnt,i,gui,len;
char *tptr;
unsigned long fsize, macoff, state;
in = atoi(argv[1]); /* get the input file descriptor */
out = atoi(argv[2]); /* get the output file descriptor */
bread(in,buf,2); /* read the length field from the first packet */
cnt = buf[0] + ((int)buf[1] << 8); /* read the intialization packet */
bread(in,buf+2,cnt); /* it is cnt bytes long */
/* return a packet to let the WPApp know we are here */
len = buf[8] + ((int)buf[9] << 8);
/* determine if WP is character or GUI version */
gui = buf[10+len] == 1;
if (gui) { /* message from xwp ? */
/* yes */
buf[2] = 2; /* token lower bound (lo byte) */
buf[3] = 0xfe; /* token lower bound (hi byte) */
buf[4] = 7; /* token upper bound (lo byte) */
buf[5] = 0xfe; /* token upper bound (hi byte) */
}
else {
/* from character wp */
buf[2] = 0x1; /* token lower bound (lo byte) */
buf[3] = 0xff; /* token lower bound (hi byte) */
buf[4] = 0x5; /* token upper bound (lo byte) */
buf[5] = 0xff; /* token upper bound (hi byte) */
}
buf[0] = 4; /* length of return packet (lo byte) */
buf[1] = 0; /* length of return packet (hi byte) */
write(out,buf,6); /* send the packet */
for (;;) { /* handle tokens */
bread(in,buf,2); /* read the count bytes */
cnt = buf[0] + ((int)(buf[1]) << 8);
bread(in,buf+2,cnt); /* read the rest of the packet */
state = BtoI(buf+2); /* get WP state */
if (state == EXITING) { /* Is WP about to exit ? */
exit(0); /* yes - exit now */
}
if (cnt == 6) { /* regular characters */
if (gui) { /* this branch is for GUI wp (xwp) */
if (buf[7] == 0xfe) { /* Ctrl-Shift-# key ? */
switch (buf[6]) { /* yes */
case 2: /* Ctrl-Shift-1 */
/* Enter an 'A' */
buf[0] = 6;
buf[1] = 0;
buf[6] = 'A';
buf[7] = 0;
write(out,buf,8);
break;
case 4: /* Ctrl-Shift-3 */
/* send back a string */
tptr = str2tok(amessage,&len);
memcpy(buf+6,tptr,len);
buf[0] = len+4;
buf[1] = 0;
write(out,buf,len+6);
break;
case 5: /* Ctrl-Shift-4 */
/* Printer Select Dialog */
buf[0] = 6;
buf[1] = 0;
buf[6] = WPRTSLC;
buf[7] = DUP;
write(out,buf,8);
break;
case 6: /* Ctrl-Shift-5 */
/* execute hex conversion macro */
fd = open("unixtest.wgm",O_RDONLY);
if (fd != -1) {
bread(fd,macbuf,8);
macoff = BtoI(macbuf+4);
fsize = lseek(fd,0L,SEEK_END);
fsize -= macoff;
lseek(fd,macoff,SEEK_SET);
bread(fd,macbuf+6,fsize);
macbuf[0] = (fsize+4) & 0xff;
macbuf[1] = ((fsize+4) >> 8) & 0xff;
macbuf[2] = buf[2];
macbuf[3] = buf[3];
macbuf[4] = buf[4];
macbuf[5] = buf[5];
write(out,macbuf,fsize+6);
break;
}
/* fall through and send it back if the open failed */
default: /* keys we don't care about */
case 3: /* Ctrl-Shift-2 */
sendback();
break;
case 7: /* Ctrl-Shift-6 */
/* toggle the ruler */
buf[0] = 8;
buf[1] = 0;
buf[6] = WRULER;
buf[7] = FUNCT;
buf[8] = buf[9] = 0;
write(out,buf,10);
break;
}
}
else {
sendback();
}
}
else { /* character branch */
if (system) { /* in the process of saving a system var ? */
if (!(state & MACEXE)) { /* done ? */
/* yes */
write(out,Menu_prompt,sizeof(Menu_prompt));
system = 0;
}
else if (state & POLLING) {
buf[0] = 4;
buf[1] = 0;
write(out,buf,6);
continue;
}
else if (buf[7] <= 0x0d) { /* regular char */
Menu_prompt[sysoff] = buf[6]; /* save the character */
sysoff += 2;
buf[0] = 4; /* tell WP it's deleted */
buf[1] = 0;
write(out,buf,6);
}
else { /* send back everything but chars */
sendback();
}
}
else if (state & POLLING) {
buf[0] = 4;
buf[1] = 0;
write(out,buf,6);
continue;
}
else if (state & MACEXE) {
sendback();
}
else if (buf[7] == 0xff) { /* Ctrl-Shift-# key ? */
switch (buf[6]) { /* yes */
case 1: /* Ctrl-Shift-1 */
/* Enter an 'A' */
buf[0] = 6;
buf[1] = 0;
buf[6] = 'A';
buf[7] = 0;
write(out,buf,8);
break;
case 2: /* Ctrl-Shift-2 */
/* display value of SYSTEM menu variable */
for (i=0;i<8;i++) {
Menu_prompt[(2*i)+30] = ' ';
}
system = 1; /* getting value of system var */
sysoff = 30;
write(out,Menu_number,sizeof(Menu_number));
break;
case 3: /* Ctrl-Shift-3 */
/* send back a string */
msg[0] = sizeof(msg) - 2;
write(out,msg,sizeof(msg));
break;
case 4: /* Ctrl-Shift-4 */
/* Printer Select Dialog */
write(out,Alt_F4,sizeof(Alt_F4));
break;
case 5: /* Ctrl-Shift-5 */
/* execute hex conversion macro */
fd = open("unixtest.wpm",O_RDONLY);
if (fd != -1) {
bread(fd,macbuf,8);
macoff = BtoI(macbuf+4);
fsize = lseek(fd,0L,SEEK_END);
fsize -= macoff;
lseek(fd,macoff,SEEK_SET);
bread(fd,macbuf+8,fsize);
fsize += 6; /* two bytes for display on code */
/* and 4 for state bytes */
macbuf[0] = fsize & 0xff;
macbuf[1] = (fsize >> 8) & 0xff;
macbuf[6] = 0xd; /* force display on */
macbuf[7] = 0xfc;
write(out,macbuf,fsize+2);
break;
}
/* fall through and send it back if the open failed */
default: /* keys we don't care about */
sendback();
break;
}
}
else {
sendback();
}
}
}
else {
/* not a regular character - send buffer back unchanged */
write(out,buf+2,cnt+2);
}
}
}