Mercurial > emacs
view src/hftctl.c @ 68953:0ddd5b380ffb
Use allout invisible-text overlays instead of
selective display for concealed text. Also, lots of general
cleanup, and improved compatibility code.
(allout-version) Incremented, corrected, revised, and refined
module commentary.
(provide 'allout): Moved to the bottom, added a require of overlay.
(allout-encrypt-unencrypted-on-saves): Defaults to t instead of
`except-current'.
(allout-write-file-hook-handler): Minimize delay.
(count-trailing-whitespace-region): New function so
auto-encryption of current topic can resituate cursor exactly.
PGP/GPG encryption trims trailing whitespace from lines, which
must be accounted for across encryption then decryption.
(allout-command-prefix): Now defaults to "\C-c<space>" rather than
just plain "\C-c", to avoid intruding on user's keybinding space.
(allout-toggle-current-subtree-encryption): Pass along fetch-pass
parameter, so user request to provide a new password is done.
(allout-outside-normal-auto-fill-function, allout-auto-fill):
Refined mechanism for auto-filling behavior while in allout mode.
(allout-mode): Explicitly specify the mode map in the docstring.
Clarify provision for various write-file hook var names.
Adjusted for invisible-text overlays instead of selective-display.
(allout-depth): Really return 0 if not within any topic. This
rectifies `allout-beginning-of-level' and sequence numbering
errors that occur when cutting and pasting numbered topics.
Changed from a in-line subst to a regular function, as well.
(allout-pre-next-prefix): Renamed from allout-pre-next-preface.
(allout-end-of-subtree, allout-end-of-subtree)
(allout-end-of-entry, allout-end-of-current-heading)
(allout-next-visible-heading, allout-open-topic, allout-show-entry)
(allout-show-children, allout-show-to-offshoot)
(allout-hide-current-entry, allout-show-current-entry): Rectified
handling of trailing blank lines between items.
(allout-line-boundary-regexp, set-allout-regexp, allout-depth)
(allout-current-depth, allout-unprotected, allout-hidden-p)
(allout-on-current-heading-p, allout-listify-exposed)
(allout-chart-subtree, allout-goto-prefix)
(allout-back-to-current-heading, allout-get-body-text)
(allout-snug-back, allout-flag-current-subtree, allout-show-all)
(allout-hide-region-body, allout-toggle-subtree-encryption)
(allout-encrypt-string, allout-encrypted-key-info)
(allout-next-topic-pending-encryption, allout-encrypt-decrypted)
(allout-file-vars-section-data): Adjusted for use with
invisible-text overlays instead of selective-display.
(allout-kill-line, allout-kill-topic, allout-yank-processing):
Reworked for use with invisible text overlays.
(allout-current-topic-collapsed-p): New function.
(allout-hide-current-subtree): Use allout-current-topic-collapsed-p
to know when to close the containing topic.
(allout-pre-command-business, allout-post-command-business):
Simplify undo-batching and dynamic isearch exposure.
(allout-set-overlay-category): New for invisible-text overlays.
Sets properties of allout-overlay-category, used by
allout-flag-region to set invisible-text overlay properties.
(allout-get-invisibility-overlay): Get the first qualifying
invisibility overlay, so we can find the extent of it.
(allout-back-to-visible-text): Get to just before the beginnining
of the current invisibility overlay, if any.
(allout-overlay-insert-in-front-handler)
(allout-overlay-interior-modification-handler)
(allout-before-change-handler, allout-isearch-end-handler): New
functions to handle extraordinary actions affecting concealed
text.
(allout-flag-region): Use overlays instead of selective-display
for invisible text - by inheritence from the properties of
allout-overlay-category in mainline emacs, and applied
property-by-property in xemacs, some recent versions of which
don't inherit the properties from the category. Provisions to
respond to concealed-text edits simplified drastically.
(allout-isearch-rectification, allout-isearch-was-font-lock)
(allout-isearch-expose, allout-enwrap-isearch)
(allout-isearch-abort, allout-pre-was-isearching)
(allout-isearch-prior-pos, allout-isearch-did-quit)
(allout-isearch-dynamic-expose)
(allout-hide-current-entry-completely): Functions deleted.
(allout-undo-aggregation): Explicit undo aggregation no longer
necessary due to transition away from selective-display.
(set-allout-regexp, allout-up-current-level)
(allout-next-visible-heading, allout-forward-current-level)
(allout-open-topic, allout-reindent-body, allout-rebullet-topic)
(allout-kill-line, allout-yank-processing, allout-show-children)
(allout-expose-topic, allout-old-expose-topic)
(allout-listify-exposed, allout-insert-latex-header)
(allout-toggle-subtree-encryption, allout-encrypt-string)
(remove-from-invisibility-spec, allout-hide-current-subtree):
Ditched unused variables.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Fri, 17 Feb 2006 10:52:30 +0000 |
parents | 695cf19ef79e |
children | 375f2633d815 |
line wrap: on
line source
/* IBM has disclaimed copyright on this module. */ /***************************************************************/ /* */ /* 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 datastream */ /* 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 <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(); char *xmalloc(); 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 = emacs_read (f, p, l)) < 0) \ if (errno != EINTR) return (-1); \ else continue; \ else { (l) -= j; (p) += j; } /*************** function prototypes ***************************/ #ifdef PROTOTYPES 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 */ register 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 whats been read */ i = sizeof (ack) - i; /* set whats 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 (emacs_write (fd, p.c, size) == -1) return (-1); if (p.req != &req) /* free if allocated */ xfree (p.c); return (0); } /* arch-tag: cfd4f3bd-fd49-44e6-9f69-c8abdf367650 (do not change this comment) */