diff options
Diffstat (limited to 'nx-X11/programs/xterm/vms.c')
-rw-r--r-- | nx-X11/programs/xterm/vms.c | 725 |
1 files changed, 0 insertions, 725 deletions
diff --git a/nx-X11/programs/xterm/vms.c b/nx-X11/programs/xterm/vms.c deleted file mode 100644 index 155cdb41b..000000000 --- a/nx-X11/programs/xterm/vms.c +++ /dev/null @@ -1,725 +0,0 @@ -/* $XFree86: xc/programs/xterm/vms.c,v 1.2 2003/10/27 01:07:58 dickey Exp $ */ - -/* vms.c - * - * This module contains the VMS version of the routine SPAWN (from the module - * MAIN.C) and the routines that do IO to the pseudo terminal. - * - * Modification History: - * Stephan Jansen 1-Mar-1990 Original version - * Hal R. Brand 5-Sep-1990 Added code to propagate DECW$DISPLAY - * Aaron Leonard 11-Sep-1990 Fix string descriptor lengths - * Stephan Jansen 2-Dec-1991 Modify to use new Pseudo terminal drivers - * (patterned after photo.c by Forrest A. Kenney) - * Patrick Mahan 7-Jan-1991 Removed reference to <dvidef.h> from VMS.C - * Forced device type to be VT102 since that is - * what we are emulating. - */ - -#include <libdef.h> -#include <lnmdef.h> - -#include <stdio.h> -#include <string.h> - -#include "xterm.h" -#include "data.h" -#include "vms.h" - -#define PTD$C_SEND_XON 0 /* Pseudo Terminal Driver event */ -#define PTD$C_SEND_BELL 1 -#define PTD$C_SEND_XOFF 2 -#define PTD$C_STOP_OUTPUT 3 -#define PTD$C_RESUME_OUTPUT 4 -#define PTD$C_CHAR_CHANGED 5 -#define PTD$C_ABORT_OUTPUT 6 -#define PTD$C_START_READ 7 -#define PTD$C_MIDDLE_READ 8 -#define PTD$C_END_READ 9 -#define PTD$C_ENABLE_READ 10 -#define PTD$C_DISABLE_READ 11 -#define PTD$C_MAX_EVENTS 12 - -#define BUFFERS 6 -#define PAGE 512 - -typedef struct tt_buffer -{ -unsigned int flink; -unsigned int blink; -short int status; -short int length; -char data[VMS_TERM_BUFFER_SIZE]; -} TT_BUF_STRUCT; - -TT_BUF_STRUCT *tt_w_buff; -struct q_head _align(QUADWORD) buffer_queue = (0,0); -struct q_head _align(QUADWORD) read_queue = (0,0); - -static char tt_name[64]; -static $DESCRIPTOR (tt_name_desc, &tt_name); - -static char ws_name[64]; -static $DESCRIPTOR (ws_name_desc, &ws_name); - -static struct tt_char { - char class; - char type; - short int page_width; - char characteristics[3]; - char length; - int extended; - } tt_mode, tt_chars, orig_tt_chars; - -struct mem_region -{ - TT_BUF_STRUCT *start; - TT_BUF_STRUCT *end; -} ret_addr; - -int read_stopped = FALSE; -int write_stopped = FALSE; - -int tt_width; -int tt_length; -int tt_changed; -int tt_pasting=FALSE; /* drm */ -int tt_new_output=FALSE; /* Cleared by flushlog(), set whenever something new - goes to the screen through tt_write */ - -int trnlnm(char *in,int id,char *out); -int tt_write(char *tt_write_buf,int size); -void spawn (void); - -static void tt_echo_ast(TT_BUF_STRUCT *buff_addr); -static void tt_read_ast(TT_BUF_STRUCT *buff_addr); - -/* -static void tt_start_read(void); -*/ -void tt_start_read(void); -int tt_read(char *buffer); -static void send_xon(void); -static void send_xoff(void); -static void send_bell(void); -static void char_change(void); -static void freeBuff (TT_BUF_STRUCT *buff_addr); -TT_BUF_STRUCT *getBuff(void); -static void CloseDown(int exit_status); -static void mbx_read_ast(void); -static void mbx_read(void); - - - -#define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \ -{ strlen(string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string } - -int trnlnm(char *in, int id, char *out) -{ - int status, num, len, attr = LNM$M_CASE_BLIND, foo = id; - short outlen; - struct itemlist - { - short buffer_length; - short item_code; - char *buffer_addr; - int *return_length; - } itmlst[] = - { - 4 , LNM$_INDEX , &foo, 0, - 255, LNM$_STRING , out , &outlen, - 4 , LNM$_MAX_INDEX, &num, &len, - 0 , 0 - }; - DESCRIPTOR(lognam,in); - DESCRIPTOR(tabnam,"LNM$DCL_LOGICAL"); - - status = sys$trnlnm(&attr,&tabnam,&lognam,0,itmlst); - if(status != SS$_NORMAL) return(-1); /* error status */ - out[outlen] = 0; /* terminate the output string */ - return(++num); /* return number of translations */ -} - -static int pty; -static int Xsocket; - -void spawn (void) -{ - int status; - static $DESCRIPTOR (dtime, "0 00:00:00.01"); - static int delta[2]; - register TScreen *screen = &term->screen; - static struct IOSB iosb; - static unsigned int flags; - static unsigned int uic; - static char imagename[64]; - static int privs; - static $DESCRIPTOR(device, "FTA0:"); - static int type; - static int class; - static int devdepend; - static int mem_size; - int i; - - /* if pid and mbx_chan are nonzero then close them in CloseDown() */ - pid = 0; - mbx_chan = 0; - - status = SYS$EXPREG (BUFFERS, &ret_addr, 0, 0); - if(!(status & SS$_NORMAL)) lib$signal(status); - - tt_w_buff = (char *)ret_addr.end - PAGE + 1; - - /* use one buffer for writing, the reset go in the free buffer queue */ - for(i=0; i < BUFFERS-1; i++) - { - freeBuff((char *)ret_addr.start +i*PAGE); - } - - /* avoid double MapWindow requests, for wm's that care... */ - XtSetMappedWhenManaged( screen->TekEmu ? XtParent(tekWidget) : - XtParent(term), False ); - /* Realize the Tek or VT widget, depending on which mode we're in. - If VT mode, this calls VTRealize (the widget's Realize proc) */ - XtRealizeWidget (screen->TekEmu ? XtParent(tekWidget) : - XtParent(term)); - - /* get the default device characteristics of the pseudo terminal */ - - itemlist[0].buflen = 4; - itemlist[0].code = DVI$_DEVTYPE; - itemlist[0].buffer = &type; - itemlist[0].return_addr = &tt_name_desc.dsc$w_length; - - itemlist[1].buflen = 4; - itemlist[1].code = DVI$_DEVCLASS; - itemlist[1].buffer = &class; - itemlist[1].return_addr = &tt_name_desc.dsc$w_length; - - itemlist[2].buflen = 4; - itemlist[2].code = DVI$_DEVDEPEND; - itemlist[2].buffer = &devdepend; - itemlist[2].return_addr = &tt_name_desc.dsc$w_length; - - itemlist[3].buflen = 4; - itemlist[3].code = DVI$_DEVDEPEND2; - itemlist[3].buffer = &tt_chars.extended; - itemlist[3].return_addr = &tt_name_desc.dsc$w_length; - - itemlist[4].buflen = 0; - itemlist[4].code = 0; - - - status = sys$getdviw(0,0,&device,&itemlist,&iosb,0,0,0); - if(!(status & SS$_NORMAL)) lib$signal(status); - if(!(iosb.status & SS$_NORMAL)) lib$signal(iosb.status); - - tt_chars.type = DT$_VT102; /* XTerm supports VT102 mode */ - tt_chars.class = class; - tt_chars.page_width = screen->max_col+1; - tt_chars.length = screen->max_row+1; - - /* copy the default char's along with the created window size */ - - bcopy(&devdepend, &tt_chars.characteristics, 3); - - tt_chars.extended |= TT2$M_ANSICRT | TT2$M_AVO | TT2$M_DECCRT; - - - /* create the pseudo terminal with the proper char's */ - status = ptd$create(&tt_chan,0,&tt_chars,12,0,0,0,&ret_addr); - if(!(status & SS$_NORMAL)) lib$signal(status); - - - /* get the device name of the Pseudo Terminal */ - - itemlist[0].buflen = 64; - itemlist[0].code = DVI$_DEVNAM; - itemlist[0].buffer = &tt_name; - itemlist[0].return_addr = &tt_name_desc.dsc$w_length; - - /* terminate the list */ - itemlist[1].buflen = 0; - itemlist[1].code = 0; - - status = sys$getdviw(0,tt_chan,0,&itemlist,&iosb,0,0,0); - if(!(status & SS$_NORMAL)) CloseDown(status); - if(!(iosb.status & SS$_NORMAL)) CloseDown(iosb.status); - - /* - * set up AST's for XON, XOFF, BELL and characteristics change. - */ - - status = ptd$set_event_notification(tt_chan,&send_xon,0,0,PTD$C_SEND_XON); - if(!(status & SS$_NORMAL)) CloseDown(status); - - status = ptd$set_event_notification(tt_chan,&send_xoff,0,0,PTD$C_SEND_XOFF); - if(!(status & SS$_NORMAL)) CloseDown(status); - - status = ptd$set_event_notification(tt_chan,&send_bell,0,0,PTD$C_SEND_BELL); - if(!(status & SS$_NORMAL)) CloseDown(status); - - status = ptd$set_event_notification(tt_chan,&char_change,0,0,PTD$C_CHAR_CHANGED); - if(!(status & SS$_NORMAL)) CloseDown(status); - - /* create a mailbox for the detached process to detect hangup */ - - status = sys$crembx(0,&mbx_chan,ACC$K_TERMLEN,0,255,0,0); - if(!(status & SS$_NORMAL)) CloseDown(status); - - - /* - * get the device unit number for created process completion - * status to be sent to. - */ - - itemlist[0].buflen = 4; - itemlist[0].code = DVI$_UNIT; - itemlist[0].buffer = &mbxunit; - itemlist[0].return_addr = 0; - - /* terminate the list */ - itemlist[1].buflen = 0; - itemlist[1].code = 0; - - status = sys$getdviw(0,mbx_chan,0,&itemlist,&iosb,0,0,0); - if(!(status & SS$_NORMAL)) CloseDown(status); - if(!(iosb.status & SS$_NORMAL)) CloseDown(iosb.status); - - - tt_start_read(); - - /* - * find the current process's UIC so that it can be used in the - * call to sys$creprc - */ - itemlist[0].buflen = 4; - itemlist[0].code = JPI$_UIC; - itemlist[0].buffer = &uic; - itemlist[0].return_addr = 0; - - /* terminate the list */ - itemlist[1].buflen = 0; - itemlist[1].code = 0; - - status = sys$getjpiw(0,0,0,&itemlist,0,0,0); - if(!(status & SS$_NORMAL)) CloseDown(status); - - /* Complete a descriptor for the WS (DECW$DISPLAY) device */ - - trnlnm("DECW$DISPLAY",0,ws_name); - ws_name_desc.dsc$w_length = strlen(ws_name); - - /* create the process */ - /* Set sys$error to be the WS (DECW$DISPLAY) device. LOGINOUT */ - /* has special code for DECWINDOWS that will: */ - /* 1) do a DEFINE/JOB DECW$DISPLAY 'f$trnlnm(sys$error)' */ - /* 2) then redefine SYS$ERROR to match SYS$OUTPUT! */ - /* This will propogate DECW$DISPLAY to the XTERM process!!! */ - /* Thanks go to Joel M Snyder who posted this info to INFO-VAX */ - - flags = PRC$M_INTER | PRC$M_NOPASSWORD | PRC$M_DETACH; - status = sys$creprc(&pid,&image,&tt_name_desc,&tt_name_desc, - &ws_name_desc,0,0,0,4,uic,mbxunit,flags); - if(!(status & SS$_NORMAL)) CloseDown(status); - - - /* hang a read on the mailbox waiting for completion */ - mbx_read(); - - -/* set time value and schedule a periodic wakeup (every 1/100 of a second) - * this is used to prevent the controlling process from using up all the - * CPU. The controlling process will hibernate at strategic points in - * the program when it is just waiting for input. - */ - - status = sys$bintim(&dtime,&delta); - if (!(status & SS$_NORMAL)) CloseDown(status); - - status = sys$schdwk(0,0,&delta,&delta); - if (!(status & SS$_NORMAL)) CloseDown(status); - - - /* - * This is rather funky, but it saves me from having to totally - * rewrite some parts of the code (namely in_put in module CHARPROC.C) - */ - pty = 1; - screen->respond = pty; - pty_mask = 1 << pty; - Select_mask = pty_mask; - X_mask = 1 << Xsocket; - -} - - -/* - * This routine handles completion of write with echo. It takes the - * echo buffer and puts it on the read queue. It will then be processed - * by the routine tt_read. If the echo buffer is empty, it is put back - * on the free buffer queue. - */ - -static void tt_echo_ast(TT_BUF_STRUCT *buff_addr) -{ - int status; - - if (buff_addr->length != 0) - { - status = LIB$INSQTI(buff_addr, &read_queue); - if((status != SS$_NORMAL) && (status != LIB$_ONEENTQUE)) - { - CloseDown(status); - } - } - else - { - freeBuff(buff_addr); - } -} - - -/* - * This routine writes to the pseudo terminal. If there is a free - * buffer then write with an echo buffer completing asyncronously, else - * write syncronously using the buffer reserved for writing. All errors - * are fatal, except DATAOVERUN and DATALOST,these errors can be ignored. - - CAREFUL! Whatever calls this must NOT pass more than VMS_TERM_BUFFER_SIZE - bytes at a time. This definition has been moved to VMS.H - - */ - -int tt_write(char *tt_write_buf, int size) -{ - int status; - TT_BUF_STRUCT *echoBuff; - - /* if writing stopped, return 0 until Xon */ - if(write_stopped) return (0); - - memmove(&tt_w_buff->data,tt_write_buf,size); - - echoBuff = getBuff(); - if (echoBuff != LIB$_QUEWASEMP) - { - status = PTD$WRITE (tt_chan, &tt_echo_ast, echoBuff, - &tt_w_buff->status, size, - &echoBuff->status, VMS_TERM_BUFFER_SIZE); - } - else - { - status = PTD$WRITE (tt_chan, 0, 0, &tt_w_buff->status, size, 0, 0); - } - if (status & SS$_NORMAL) - { - if ((tt_w_buff->status != SS$_NORMAL) && - (tt_w_buff->status != SS$_DATAOVERUN) && - (tt_w_buff->status != SS$_DATALOST)) - { - CloseDown(tt_w_buff->status); - } - } - else - { - CloseDown(status); - } - - return(size); -} - - -/* - * This routine is called when a read to the pseudo terminal completes. - * Put the newly read buffer onto the read queue. It will be processed - * and freed in the routine tt_read. - */ - -static void tt_read_ast(TT_BUF_STRUCT *buff_addr) -{ - int status; - - if (buff_addr->status & SS$_NORMAL) - { - status = LIB$INSQTI(buff_addr, &read_queue); - if ((status != SS$_NORMAL) && (status != LIB$_ONEENTQUE)) - { - CloseDown(status); - } - } - else - CloseDown(buff_addr->status); - - tt_start_read(); - sys$wake(0,0); - return; -} - - -/* - * If there is a free buffer on the buffer queue then Start a read from - * the pseudo terminal, otherwise set a flag, the reading will be restarted - * in the routine freeBuff when a buffer is freed. - */ - -void tt_start_read(void) -{ - int status; - static int size; - TT_BUF_STRUCT *buff_addr; - - buff_addr = getBuff(); - if (buff_addr != LIB$_QUEWASEMP) - { - if(!tt_pasting){ - status = PTD$READ (0, tt_chan, &tt_read_ast, buff_addr, - &buff_addr->status, VMS_TERM_BUFFER_SIZE); - if ((status & SS$_NORMAL) != SS$_NORMAL) - { - CloseDown(status); - } - } - } - else - { - read_stopped = TRUE; - } - return; -} - - -/* - * Get data from the pseudo terminal. Return the data from the first item - * on the read queue, and put that buffer back onto the free buffer queue. - * Return the length or zero if the read queue is empty. - * - */ - -int tt_read(char *buffer) -{ - TT_BUF_STRUCT *read_buff; - int status; - int len; - - status = LIB$REMQHI(&read_queue, &read_buff); - if(status == LIB$_QUEWASEMP){ - return(0); - } - else if (status & SS$_NORMAL) - { - len = read_buff->length; - memmove(buffer,&read_buff->data,len); - freeBuff(read_buff); - tt_new_output=TRUE; /* DRM something will be written */ - } - else - CloseDown(status); - - return(len); -} - - -/* - * if xon then it is safe to start writing again. - */ - -static void send_xon(void) -{ - write_stopped = FALSE; -} - - -/* - * If Xoff then stop writing to the pseudo terminal until you get Xon. - */ -static void send_xoff(void) -{ - write_stopped = TRUE; -} - - - -/* - * Beep the terminal to let the user know data will be lost because - * of too much data. - */ - -static void send_bell(void) -{ - Bell(); -} - -/* - * if the pseudo terminal's characteristics change, check to see if the - * page size changed. If it did, resize the widget, otherwise, ignore - * it! This routine just gets the new term dimensions and sets a flag - * to indicate the term chars have changed. The widget gets resized in - * the routine in_put in the module CHARPROC.C. You cant resize the - * widget in this routine because this is an AST and X is not reenterent. - */ - -static void char_change(void) -{ - int status; - - /* - * Dont do anything if in Tek mode - */ - - if(!(term->screen.TekEmu)) - { - status = sys$qiow(0,tt_chan,IO$_SENSEMODE,0,0,0,&tt_mode,8,0,0,0,0); - if(!(status & SS$_NORMAL)) CloseDown(status); - - if((term->screen.max_row != tt_mode.length) || - (term->screen.max_col != tt_mode.page_width)) - { - tt_length = tt_mode.length; - tt_width = tt_mode.page_width; - - tt_changed = TRUE; - - } - } -} - - -/* - * Put a free buffer back onto the buffer queue. If reading was - * stopped for lack of free buffers, start reading again. - */ - -static void freeBuff (TT_BUF_STRUCT *buff_addr) -{ - int ast_stat; - int status; - - ast_stat = SYS$SETAST(0); - if (!read_stopped) - { - LIB$INSQHI(buff_addr, &buffer_queue); - } - else - { - status = PTD$READ (0, tt_chan, &tt_read_ast, buff_addr, - &buff_addr->status, VMS_TERM_BUFFER_SIZE); - if (status & SS$_NORMAL) - { - read_stopped = FALSE; - } - else - { - CloseDown(status); - } - } - if (ast_stat == SS$_WASSET) ast_stat = SYS$SETAST(1); -} - - -/* - * return a free buffer from the buffer queue. - */ - -TT_BUF_STRUCT *getBuff(void) -{ - int status; - TT_BUF_STRUCT *buff_addr; - - status = LIB$REMQHI(&buffer_queue, &buff_addr); - if (status & SS$_NORMAL) - { - return(buff_addr); - } - else - { - return(status); - } -} - - -/* - * Close down and exit. Kill the detached process (if it still - * exists), deassign mailbox channell (if assigned), cancel any - * waiting IO to the pseudo terminal and delete it, exit with any - * status information. - */ - -static void CloseDown(int exit_status) -{ - int status; - - /* if process has not terminated, do so now! */ - if(pid != 0) - { - status = sys$forcex(&pid,0,0); - if(!(status & SS$_NORMAL)) lib$signal(status); - } - - /* if mbx_chan is assigned, deassign it */ - if(mbx_chan != 0) - { - sys$dassgn(mbx_chan); - } - - /* cancel pseudo terminal IO requests */ - status = ptd$cancel(tt_chan); - if(!(status & SS$_NORMAL)) lib$signal(status); - - /* delete pseudo terminal */ - status = ptd$delete(tt_chan); - if(!(status & SS$_NORMAL)) lib$signal(status); - - if(!(exit_status & SS$_NORMAL)) lib$signal(exit_status); - - exit(1); - -} - - -/* - * This routine gets called when the detached process terminates (for - * whatever reason). The mailbox buffer has final exit status. Close - * down and exit. - */ - -static void mbx_read_ast(void) -{ - int status; - - pid = 0; - - status = mbx_read_iosb.status; - if (!(status & SS$_NORMAL)) CloseDown(status); - - status = (unsigned long int) mbx_buf.acc$l_finalsts; - if (!(status & SS$_NORMAL)) CloseDown(status); - - CloseDown(1); - -} - - -/* - * This routine starts a read on the mailbox associated with the detached - * process. The AST routine gets called when the detached process terminates. - */ - -static void mbx_read(void) -{ -int status; -static int size; - - size = ACC$K_TERMLEN; - status = sys$qio(0,mbx_chan, - IO$_READVBLK, - &mbx_read_iosb, - &mbx_read_ast, - 0, - &mbx_buf, - size,0,0,0,0); - - if (!(status & SS$_NORMAL)) CloseDown(status); - - return; -} |