Mercurial > hg > xemacs-beta
view src/hftctl.c @ 844:047d37eb70d7
[xemacs-hg @ 2002-05-16 13:30:23 by ben]
ui fixes for things that were bothering me
bytecode.c, editfns.c, lisp.h, lread.c: Fix save-restriction to use markers rather than pseudo-markers
(integers representing the amount of text on either side of the
region). That way, all inserts are handled correctly, not just
those inside old restriction.
Add buffer argument to save_restriction_save().
process.c: Clean up very dirty and kludgy code that outputs into a buffer --
use proper unwind protects, etc.
font-lock.c: Do save-restriction/widen around the function -- otherwise, incorrect
results will ensue when a buffer has been narrowed before a call to
e.g. `buffer-syntactic-context' -- something that happens quite often.
fileio.c: Look for a handler for make-temp-name.
window.c, winslots.h: Try to solve this annoying problem: have two frames displaying the
buffer, in different places; in one, temporarily switch away to
another buffer and then back -- and you've lost your position;
it's reset to the other one in the other frame. My current
solution involves window-level caches of buffers and points (also
a cache for window-start); when set-window-buffer is called, it
looks to see if the buffer was previously visited in the window,
and if so, uses the most recent point at that time. (It's a
marker, so it handles changes.)
#### Note: It could be argued that doing it on the frame level
would be better -- e.g. if you visit a buffer temporarily through
a grep, and then go back to that buffer, you presumably want the
grep's position rather than some previous position provided
everything was in the same frame, even though the grep was in
another window in the frame. However, doing it on the frame level
fails when you have two windows on the same frame. Perhaps we
keep both a window and a frame cache, and use the frame cache if
there are no other windows on the frame showing the buffer, else
the window's cache? This is probably something to be configurable
using a specifier. Suggestions please please please?
window.c: Clean up a bit code that deals with the annoyance of window-point
vs. point.
dialog.el: Function to ask a
multiple-choice question, automatically choosing a dialog box or
minibuffer representation as necessary. Generalized version of
yes-or-no-p, y-or-n-p.
files.el: Use get-user-response to ask "yes/no/diff" question when recovering.
"diff" means that a diff is displayed between the current file and the
autosave. (Converts/deconverts escape-quoted as necessary. No more
complaints from you, Mr. Turnbull!) One known problem: when a dialog
is used, it's modal, so you can't scroll the diff. Will fix soon.
lisp-mode.el: If we're filling a string, don't treat semicolon as a comment,
which would give very unfriendly results.
Uses `buffer-syntactic-context'.
simple.el: all changes back to the beginning. (Useful if you've saved the file
in the middle of the changes.)
simple.el: Add option kill-word-into-kill-ring, which controls whether words
deleted with kill-word, backward-kill-word, etc. are "cut" into the
kill ring, or "cleared" into nothingness. (My preference is the
latter, by far. I'd almost go so far as suggesting we make it the
default, as you can always select a word and then cut it if you want
it cut.)
menubar-items.el: Add option corresponding to kill-word-into-kill-ring.
author | ben |
---|---|
date | Thu, 16 May 2002 13:30:58 +0000 |
parents | b39c14581166 |
children | a8d8f419b459 |
line wrap: on
line source
/* IBM has disclaimed copyright on this module. */ /* Synched up with: FSF 19.30. */ /***************************************************************/ /* */ /* Function: hftctl */ /* */ /* Syntax: */ /* #include <sys/ioctl.h> */ /* #include <sys/hft.h> */ /* */ /* int hftctl(fildes, request, arg ) */ /* int fildes, request; */ /* char *arg; */ /* */ /* Description: */ /* */ /* Does the following: */ /* 1. determines if fildes is pty */ /* does normal ioctl it is not */ /* 2. places fildes into raw mode */ /* 3. converts ioctl arguments to data stream */ /* 4. waits for 2 secs for acknowledgement before */ /* timing out. */ /* 5. places response in callers buffer ( just like */ /* ioctl. */ /* 6. returns fildes to its original mode */ /* */ /* User of this program should review steps 1,4, and 3. */ /* hftctl makes no check on the request type. It must be */ /* a HFT ioctl that is supported remotely. */ /* This program will use the SIGALRM and alarm(2). Any */ /* Previous alarms are lost. */ /* */ /* Users of this program are free to modify it any way */ /* they want. */ /* */ /* Return Value: */ /* */ /* If ioctl fails, a value of -1 is returned and errno */ /* is set to indicate the error. */ /* */ /***************************************************************/ #include <config.h> #include "lisp.h" #include "sysfile.h" #include <sys/signal.h> #include <errno.h> #include <stdio.h> #include <fcntl.h> #include <setjmp.h> #include <sys/ioctl.h> #include <sys/devinfo.h> #include <termios.h> #include <termio.h> #include <sys/hft.h> #include <sys/uio.h> #include <sys/tty.h> /* #include <sys/pty.h> */ #define REMOTE 0x01 #undef ioctl static char SCCSid[] = "com/gnuemacs/src,3.1,9021-90/05/03-5/3/90"; /*************** LOCAL DEFINES **********************************/ #define QDEV ((HFQPDEVCH<<8)|HFQPDEVCL) #define QLOC ((HFQLOCCH<<8)|HFQLOCCL) #define QPS ((HFQPRESCH<<8)|HFQPRESCL) #ifndef TCGETS #define TCGETS TCGETA #endif #ifndef TCSETS #define TCSETS TCSETA #endif /*************** EXTERNAL / GLOBAL DATA AREA ********************/ static int hfqry(); static int hfskbd(); extern int errno; static JMP_BUF hftenv; static int is_ack_vtd; static SIGTYPE (*sav_alrm) (); static struct hfctlreq req = { 0x1b,'[','x',0,0,0,21,HFCTLREQCH,HFCTLREQCL}; static struct hfctlack ACK = { 0x1b,'[','x',0,0,0,21,HFCTLACKCH,HFCTLACKCL}; /* FUNC signal(); */ /*************** LOCAL MACROS ***********************************/ #define HFTYPE(p) ((p->hf_typehi<<8)|(p->hf_typelo)) #define BYTE4(p) ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3]) /* read a buffer */ #define RD_BUF(f,p,l) \ while ((l)) \ if ((j = read ((f),(p),(l))) < 0) \ if (errno != EINTR) return (-1); \ else continue; \ else { (l) -= j; (p) += j; } /*************** function prototypes ***************************/ #ifdef __STDC__ static GT_ACK (int fd, int req, char *buf); static WR_REQ (int fd, int request, int cmdlen, char *cmd, int resplen); static void hft_alrm(int sig); #else static GT_ACK (); static WR_REQ (); static void hft_alrm (); #endif /*************** HFTCTL FUNCTION *******************************/ hftctl (fd, request, arg) int fd; int request; union { struct hfintro *intro; struct hfquery *query; char *c; } arg; { int i; int fd_flag; /* fcntl flags */ union { struct hfintro *cmd; /* p.cmd - intro des. */ struct hfqphdevc *ph; /* p.ph - physical dev.*/ char *c; /* p.c - char ptr */ } p; /* general pointer */ int pty_new; /* pty modes */ int pty_old; int retcode; struct termios term_new; /* terminal attributes */ struct termios term_old; struct devinfo devInfo; /* defined in sys/devinfo.h */ if (ioctl (fd, IOCINFO, &devInfo) == -1) return(-1); if (devInfo.devtype != DD_PSEU) /* is it a pty? */ return (ioctl(fd, request, arg)); /* no, do IOCTL */ /******* START PTY **************/ /** Pty found, possible HFT */ /** set new file des as raw */ /** as you can. */ /********************************/ /* Get current state of file */ /* descriptor & save */ if ((fd_flag = fcntl (fd, F_GETFL, 0)) == -1) return (-1); if (ioctl (fd, TCGETS, &term_old) == -1) return (-1); /* set terminal attr to raw */ /* and to delay on read */ pty_new = pty_old | REMOTE; memcpy (&term_new, &term_old, sizeof (term_new)); term_new.c_iflag = 0; term_new.c_oflag = 0; term_new.c_lflag = 0; /* term_new.c_line = 0; */ for (i = 1; i <= 5; i++) term_new.c_cc[i] = 0; term_new.c_cc[0] = -1; ioctl (fd, TCSETS, &term_new); if (fcntl (fd, F_SETFL, fd_flag & ~O_NDELAY) == -1) return(-1); /* call spacific function */ if (request == HFSKBD) retcode = hfskbd (fd, request, arg.c); else /* assume HFQUERY */ retcode = hfqry (fd, request, arg.c); fcntl (fd, F_SETFL, fd_flag); /* reset terminal to original */ ioctl (fd, TCSETS, &term_old); return (retcode); /* return error */ } /*************** HFSKBD FUNCTION ******************************/ static int hfskbd (fd, request, arg) int fd; int request; struct hfbuf *arg; { WR_REQ(fd, request, arg->hf_buflen, arg->hf_bufp,0); return (GT_ACK(fd, request, arg->hf_bufp)); } /*************** HFQUERY FUNCTION ******************************/ static int hfqry (fd, request, arg) int fd; int request; struct hfquery *arg; { WR_REQ(fd, request, arg->hf_cmdlen, arg->hf_cmd, arg->hf_resplen); return (GT_ACK(fd, request, arg->hf_resp)); } /*************** GT_ACK FUNCTION ******************************/ static int GT_ACK (fd, req, buf) int fd; int req; char *buf; { struct hfctlack ack; int i = sizeof (ack); int j = 0; union { char *c; struct hfctlack *ack; } p; is_ack_vtd = 0; /* flag no ACT VTD yet */ if (SETJMP (hftenv)) /* set environment in case */ { /* of time out */ errno = ENODEV; /* if time out, set errno */ return (-1); /* flag error */ } alarm(3); /* time out in 3 secs */ sav_alrm = signal (SIGALRM, hft_alrm); /* prepare to catch time out */ p.ack = &ack; while (! is_ack_vtd) /* do until valid ACK VTD */ { RD_BUF(fd, p.c, i); /* read until a ACK VTD is fill*/ if (! memcmp (&ack, &ACK, sizeof (HFINTROSZ)) /* the ACK intro & */ && (ack.hf_request == req)) /* is it the response we want ?*/ { /* yes, ACK VTD found */ is_ack_vtd = 1; /* quickly, flag it */ break; /* get the %$%#@ out of here */ } p.ack = &ack; /* no, then skip 1st */ ++p.c; /* char and start over */ i = sizeof (ack) - 1; /* one less ESC to cry over */ while ((*p.c != 0x1b) && i) /* scan for next ESC */ { ++p.c; --i; } /* if any */ (i ? memcpy (&ack, p.c, i) : 0); /* if any left over, then move */ p.ack = &ack; /* ESC to front of ack struct */ p.c += i; /* skip over what's been read */ i = sizeof (ack) - i; /* set what's left to be read */ } /***** TRY AGAIN */ alarm(0); /* ACK VTD received, reset alrm*/ signal (SIGALRM, sav_alrm); /* reset signal */ if (i = ack.hf_arg_len) /* any data following ? */ { /* yes, */ RD_BUF(fd,buf,i); /* read until it is received */ } if (errno = ack.hf_retcode) /* set errno based on returned */ return (-1); /* code, if 0, then no error */ else return (0); /* if set, then error returned */ } /*************** HFT_ALRM FUNCTION ******************************/ static void hft_alrm (sig) /* Function hft_alrm - handle */ int sig; /* alarm signal */ { signal (SIGALRM, sav_alrm); /* reset to previous */ if (is_ack_vtd) /* has ack vtd arrived ? */ return; /* yes, then continue */ else /* no, then return with error */ LONGJMP (hftenv, -1); } /*********************************************************************/ /*** ***/ /*** NOTE: Both the HFCTLREQ and the arg structure should be ***/ /*** sent in one io write operation. If terminal ***/ /*** emulators are in NODELAY mode then multiple writes ***/ /*** may cause bogus information to be read by the emulator ***/ /*** depending on the timing. ***/ /*** ***/ /*********************************************************************/ static int WR_REQ (fd, request, cmdlen, cmd, resplen) int fd; int request; int cmdlen; char *cmd; int resplen; { struct { char *c; struct hfctlreq *req; } p; int size; req.hf_request = request; req.hf_arg_len = cmdlen; req.hf_rsp_len = resplen; if (cmdlen) /* if arg structure to pass */ { size = sizeof (struct hfctlreq) + cmdlen; if ((p.c = xmalloc(size)) == NULL) /* malloc one area */ return (-1); memcpy (p.c, &req, sizeof (req)); /* copy CTL REQ struct */ memcpy (p.c + sizeof (req), cmd, cmdlen); /* copy arg struct */ } else { p.req = &req; /* otherwise use only CTL REQ */ size = sizeof (req); } /* write request to terminal */ if (write(fd,p.c,size) == -1) return (-1); if (p.req != &req) /* free if allocated */ xfree (p.c); return (0); }