/** Sample third-party interface, loaded from the "third.ini" file **/ #include #include #include #include #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> 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); } } }