1/* $XFree86$ */
2/*****************************************************************************
3Copyright 1987, 1988, 1989, 1990, 1991, 1992 by Digital Equipment Corp.,
4Maynard, MA
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Digital not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22*****************************************************************************/
23/*
24 *
25 *  CONTRIBUTORS:
26 *
27 *      Dick Annicchiarico
28 *      Robert Chesler
29 *      Dan Coutu
30 *      Gene Durso
31 *      Marc Evans
32 *      Alan Jamison
33 *      Mark Henry
34 *      Ken Miller
35 *
36 */
37#ifndef vms
38#include    <signal.h>
39#else
40#include    <descrip.h>                     /* Character string descriptors */
41#include    <dvidef.h>                      /* GETDVI item codes */
42#include    <devdef.h>                      /* device independent codes */
43#include    <iodef.h>                       /* I/O function codes */
44#include    <psldef.h>                      /* PSL definitions */
45#include    <ssdef.h>                       /* System service codes */
46#include    <stsdef.h>                      /* System status masks and codes */
47#include    <ttdef.h>                       /* Terminal specific I/O defs */
48#include    <tt2def.h>                      /* Terminal specific I/O defs */
49#define CTRL_USER_MODE 3
50
51/*----------*
52 *  Macros  *
53 *----------*/
54
55#define     $CheckStatus(status)\
56            if (!(status & 1)) return(status);
57
58            /*  Allocate a quadword aligned VMS descriptor.
59             *  NOTE: This supersedes the $DESCRIPTOR macro in DESCRIP.H.
60             *  The only difference is the _align(QUADWORD) term.
61             */
62#define     $DESCRIPTOR_Q(name, string)\
63                struct dsc$descriptor_s _align (QUADWORD) name = \
64                { sizeof(string)-1, DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
65
66/*---------------------*
67 *  Data Declarations  *
68 *---------------------*/
69
70static $DESCRIPTOR_Q (sys_input, "SYS$INPUT:");
71
72static unsigned short
73                comm_chan,                      /* Communication channel */
74                comm_iosb[4];                   /* I/O status block */
75
76static struct getdvi_itmlst_struct
77    {                                           /* $GETDVI item list */
78    unsigned short int
79                buflen,
80                item_code;
81    unsigned int
82                bufadr,
83                retadr,
84                eol;
85    }  _align (LONGWORD) getdvi_itmlst   = { sizeof(int),
86                                             DVI$_DEVCHAR,
87                                             0,0,0 };
88
89static unsigned int dvi_characteristics,return_length;
90
91static struct exit_handler_blk
92    {
93    unsigned int    flink;
94    void            (*exit_routine)();
95    unsigned char   arg_cnt;
96    unsigned char   null_byte;
97    unsigned short  null_word;
98    unsigned int    cond_value;
99    } _align (LONGWORD) exit_block;
100
101static unsigned int vms_condition;
102
103#endif /* vms */
104
105
106
107#include <X11/extensions/xtraplib.h>
108#include <X11/extensions/xtraplibp.h>
109
110#include "XEKeybCtrl.h"
111
112int XEEnableCtrlKeys(void (*rtn)(int))
113{
114#ifndef vms
115    signal(SIGINT, rtn); /* CTRL-C */
116    return(1L);
117
118#else /* vms */
119
120    int status;
121
122    /*
123     *  Provide the addresses of the longword to receive device chars
124     *  and the return length of the information.
125     */
126    getdvi_itmlst.bufadr = &dvi_characteristics;
127    getdvi_itmlst.retadr = &return_length;
128
129    status = SYS$GETDVIW (0, 0, &sys_input, &getdvi_itmlst, 0, 0, 0, 0);
130    $CheckStatus(status);
131
132
133    /* If we have a terminal device, enable control-c and control-y */
134    if (dvi_characteristics & DEV$M_TRM)
135    {
136        /* Assign a channel to the communication device. */
137        status = SYS$ASSIGN ( &sys_input,    /* Device name */
138                              &comm_chan,    /* Channel returned */
139                              0, 0 );
140        $CheckStatus(status);
141
142        status = XEEnableCtrlC(rtn);
143        $CheckStatus(status);
144
145        status = XEEnableCtrlY(rtn);
146        $CheckStatus(status);
147    }
148    return (SS$_NORMAL);
149
150#endif /* vms */
151}
152
153
154int XEClearCtrlKeys(void)
155{
156#ifndef vms
157    signal(SIGINT,  SIG_DFL); /* CTRL-C */
158    return(1L);
159#else  /* vms */
160    int status;
161
162    if (dvi_characteristics & DEV$M_TRM)
163    {
164        status = SYS$DASSGN(comm_chan);
165        $CheckStatus(status);
166    }
167    return (SS$_NORMAL);
168#endif /* vms */
169}
170
171int XEEnableCtrlC(void (*rtn)(int))
172{
173#ifndef vms
174    signal(SIGINT, rtn); /* CTRL-C */
175    return(1);
176#else
177    int status;
178
179    status = SYS$QIOW ( 0,                  /*  Now set the characteristics */
180                        comm_chan,              /* Channel */
181                        IO$_SETMODE|IO$M_CTRLCAST, /* Set ctrl_c */
182                        comm_iosb,              /* iosb address */
183                        0, 0,                   /*  */
184                        rtn, 0,                 /* AST routine and param */
185                        CTRL_USER_MODE, 0, 0, 0 );
186    $CheckStatus(status);
187
188    return (SS$_NORMAL);
189#endif /* vms */
190}
191
192
193int XEEnableCtrlY(void (*rtn)(int))
194{
195#ifndef vms
196    signal(SIGQUIT,rtn); /* CTRL-backslash */
197    return(1);
198#else /* vms */
199    int status;
200
201    status = SYS$QIOW ( 0,                      /* Set characteristics */
202                        comm_chan,              /* Channel */
203                        IO$_SETMODE|IO$M_CTRLYAST, /* Set ctrl_y */
204                        comm_iosb,              /* iosb address */
205                        0, 0,                   /* */
206                        rtn, 0,                 /* AST routine and param */
207                        CTRL_USER_MODE, 0, 0, 0 );
208    $CheckStatus(status);
209
210    return (SS$_NORMAL);
211#endif /* vms */
212}
213
214
215int XEDeclExitHndlr(void (*rtn)(int))
216{
217#ifndef vms
218    return(1);  /* no real way for U*IX to do this */
219#else /* vms */
220    int status;
221
222    /*
223     *  The Exit handler routine must accept one argument.
224     *  This argument will be the condition that signaled the
225     *  the exit handler.
226     */
227    exit_block.exit_routine = rtn;
228    exit_block.arg_cnt    = 1;              /* The condition code is the first argument */
229    exit_block.cond_value = &vms_condition; /* Address of condition value written by VMS */
230
231    status = SYS$DCLEXH (&exit_block);  /* Set up the condition handler */
232    $CheckStatus(status);
233
234    return (SS$_NORMAL);
235#endif /* vms */
236}
237