home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-19 | 50.5 KB | 1,740 lines |
- Newsgroups: comp.sources.misc
- Path: sparky!kent
- From: fbm@ptcburp.ptcbu.oz.au (Farrell McKay)
- Subject: v33i092: xcb-2.1 - X cut buffers, v2.1, Part01/01
- Message-ID: <1992Nov20.045437.12496@sparky.imd.sterling.com>
- Followup-To: comp.sources.d
- X-Md4-Signature: 7eb82da8ae07d187ea3e56a97db6fa70
- Keywords: X, cut and paste, cut buffers, pigeon holes
- Sender: kent@sparky.imd.sterling.com (Kent Landfield)
- Organization: Pyramid Technology Corporation
- Date: Fri, 20 Nov 1992 04:54:37 GMT
- Approved: kent@sparky.imd.sterling.com
- Lines: 1725
-
- Submitted-by: fbm@ptcburp.ptcbu.oz.au (Farrell McKay)
- Posting-number: Volume 33, Issue 92
- Archive-name: xcb-2.1/part01
- Environment: X11
-
- This is to announce the fourth release of xcb, an X11 program for
- providing easy access to your X server cut buffers.
-
- This release fixes two (all) bugs reported in version 2.0 and provides
- a few minor enhancements. The bug fixes are relevant to everyone
- who is already using xcb. You can obtain xcb in any one of a number
- of ways. See the README file below for full details.
-
- Many thanks go to all those people who took the time to send
- back their comments/suggestions/patches after the last release.
- Keep that feedback rolling in!
-
- And once again, *be warned*, using this program can be addictive. :-)
-
- Enjoy.
- Farrell.
- --
- -m------- Farrell McKay, fbm@ptcburp.oz.au
- ---mmm----- Pyramid Technology Aust., ...!munnari!ptcburp.oz!fbm
- -----mmmmm--- Research Park, Bond University, +61 75 950256
- -------mmmmmmm- Gold Coast, Qld 4229, AUSTRALIA +61 75 722475 FAX
- --------------------------------------------------------------------------------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: README CHANGES Imakefile Makefile.std Xcb.ad ack cb.h
- # patchlevel.h xcb.c xcb.man
- # Wrapped by kent@sparky on Wed Nov 18 22:28:53 1992
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 1 (of 1)."'
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(5412 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- XWhat is xcb?
- X============
- XDo you ever wish you could cut two or more separate pieces of text
- Xat once from a window? Do you ever need to save the output from one
- Xcommand for reuse in several subsequent tasks? Do you ever find
- Xyourself wanting some easy means of globally exporting data, e.g.
- Xto a parent shell, to another xterm or application, or to another
- Xmachine or user? If you answer yes to any of these questions, then
- Xxcb is for you.
- X
- XXcb provides access to the 8 cut buffers built into every X server.
- XIt allows the buffers to be manipulated either via the command line,
- Xor with the mouse in a point and click manner. The buffers can be
- Xused as holding pens to store and retrieve arbitrary data fragments,
- Xso up to 8 different pieces of data can be saved and recalled later.
- XThe program is designed primarily for use with textual data.
- X
- X
- XWhat is so good about this release?
- X===================================
- XRelease 2.1 addresses two bugs found since the 2.0 release,
- Xboth of which are described in the CHANGES file. A few minor
- Xenhancements and porting mods have been made to the code also.
- XThis is, in effect, a patch release.
- X
- X
- XYes, but has it been ported to WHIZ-IX 12.1A.00x, on SRS-80 27-bit CPUs?
- X========================================================================
- XXcb has been ported to a wide variety of sites and systems.
- XIn no particular order, the machines and operating systems known
- Xto be running xcb include:-
- X
- X o OSx (5.1a) - Pyramid MIS-2/02
- X o DC/OSx (1.0) - Pyramid MIServer-S 1/32 r3000
- X o AT&T SYSV (SVR3.2, SVR4) - i386, DG Aviion 5200
- X o HP-UX (lots of versions) - HP 9000/710,720,730,750
- X o SunOS (4.1) - Sun3, Sun4, Solbourne Series5, SPARCstations
- X o SPARC/OS (1.1)
- X o Irix (4.0) - SGI
- X o ULTRIX (4.2) - DECstations
- X o UNICOS (6.1) - Cray Y-MP
- X o ConvexOS (10.0.2) - Convex 3100
- X o DYNIX (V3.0.17.10) - Sequent Symmetry S81
- X o AIX (3.2) - RS6000
- X o RISC/os (4.52) - MIPS
- X o Domain/OS (10.4) - Apollo DN3000, 3500, 4500, 5500
- X o Linux (0.96b) - i386
- X o VMS (5.5)
- X
- X
- XXcb has been written to compile using both ANSI and non-ANSI compilers.
- XIt is in use in X11 R3, R4 and R5 environments. The current version
- Xis built on top of the Athena widgets (libXaw.a) and the X Toolkit library
- X(libXt.a). If you do not have the Athena widgets on your machine, and
- Xyou do not wish to install them, then you may want to revert to version
- X1.1 of xcb. Version 1.1 has a smaller feature set, but is based only
- Xthe X11 library (libX11.a), so is more portable.
- X
- X
- XOk, where is it available?
- X==========================
- XVersions of xcb can be obtained.....
- X
- X o from the comp.sources.misc newsgroup, or any of its archive sites.
- X o by ftp, from export.lcs.mit.edu in the file contrib/xcb-2.1.tar.Z,
- X o by ftp, from any of the sites that mirror export.lcs.mit.edu
- X (Australian users look for ./X11/contrib/xcb-2.1.tar.Z on archie.au).
- X o by sending me an email message.
- X
- X
- XSo, it will compile, will it?
- X=============================
- XYes! The only compile time switch in the source is -DXVIEW. If you
- Xwish to cut and paste text between xcb and XView applications, you
- Xshould add this switch to the Imakefile or Makefile.std.
- X
- XAT&T SVR4 sites need libnsl.a during linking. If you are using
- XSVR4, and you don't like Imakefiles, you will need to add -lnsl to the
- XLIBS in Makefile.std.
- X
- XHP-UX users may find that the Athena widgets are not installed on their
- Xmachine, even though the components are freely available as part of the
- XMIT X11 distribution. There is an HP maintained, but unsupported, set
- Xof X11R4 libraries and utilities (including the Athena widgets) for the
- XHP 9000 Series 300, 400, 700, and 800. You can get the libraries,
- Xinclude files, and config files (imake) via anonymous FTP from
- Xhpcvaaz.cv.hp.com (15.255.72.15) - look for pub/MitX11R4/libs.s*00.tar.Z
- X
- XAIX 3.2 users may find their Athena components are installed in a
- Xnon-standard place. Check the directory /usr/lpp/X11/Xamples/lib/Xaw.
- X
- XVMS and ULTRIX users may find their Athena components are installed in
- Xa non-standard place too. Check the directory /usr/include/mit for the
- XAthena include files.
- X
- X
- XAnd how do I set the thing up?
- X==============================
- XThat is pretty easy too. Once you have compiled the program,
- Xyou can start using it straight away - just put it in your favourite
- Xbin directory. The program contains fallback resources so that it will
- Xbehave itself even if there are no X resource specifications for it to
- Xfeed on. To install the program, plus its application defaults file, and
- Xthe man page, simply type 'make install install.man', after checking
- Xthe target directories for the install in the Imakefile/Makefile.std.
- X
- X
- XWho is to blame? Where do I send complaints?
- X=============================================
- XBlame me. The xcb factory is in the sunny Gold Coast region of
- XQueensland, Australia. Don't bother trying to find us - even
- Xthe postman has trouble getting here sometimes.
- X
- XIf you ever get around to compiling and installing xcb on your machine,
- Xplease tell me. I am interested in tracking the size of xcb's user base.
- XI am also interested in bug reports, porting problems, comments,
- Xsuggestions, patches, etc. etc. If typing a mail message seems like
- Xtoo much bother to you, then just run the "ack" script enclosed. It
- Xwill do all the work for you.
- X
- XEnjoy.
- XFarrell McKay (fbm@ptcburp.ptcbu.oz.au)
- XNovember 1992
- END_OF_FILE
- if test 5412 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'CHANGES' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'CHANGES'\"
- else
- echo shar: Extracting \"'CHANGES'\" \(2182 characters\)
- sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
- X
- XVersion 2.1 (patchlevel 1):
- X o Added the WM_DELETE_WINDOW protocol.
- X o Bug fix: on some platforms (SunOS, ULTRIX and VMS) xcb could
- X not hand off the PRIMARY selection between its own windows,
- X so windows remained highlighted, and could not be re-selected.
- X o Bug fix: rotating the buffers when using fewer than 8 cut
- X buffer windows, either via mouse button 3 or via the arrow
- X keys, caused the program to dump core.
- X
- XVersion 2.0 (patchlevel 0):
- X o Went to an Xaw and Xt based implementation. Many pros and
- X cons to this decision. Some of the pros: standardized
- X support for Toolkit command line switches, support for
- X resource specifications .Xdefaults app-defaults files etc.,
- X control over individual subwindow sizes, placement,
- X translations etc. Some of the cons: program is noticeably
- X fatter and slower (Booo, hiss).
- X o User selectable number of cut buffers - any number from
- X 1 upwards; no longer limited to 8.
- X o Added code for compatibility with XView 2.0 and 3.0 applications
- X (code provided Danny Vanderryn; thanks Danny!).
- X o Added XIO error handler for graceful shutdown when killed.
- X o Changed list processing for '-p' and '-s' options so that
- X list order and duplicates are significant.
- X
- XVersion 1.1 (patchlevel 1):
- X o Added WM_CLASS hints to the client properties. This fixed
- X failures by some window managers (e.g. mwm, olwm) to honour
- X client decoration directives.
- X o Removed 9x15bold default font specification (sigh, reluctantly).
- X o #include <stdlib.h> directive is now conditional upon __STDC__.
- X o Added another example to the man page.
- X o Several porting changes to Imakefile and Makefile.std
- X o Fallback geometry in vertical mode altered to give a tall, thin
- X window size.
- X o Support for non-standard implementations of realloc() added, i.e.
- X '-s' option never passes a NULL pointer value to realloc() now.
- X o Function declarations rewritten for compilation in both
- X ANSI and non-ANSI environments.
- X o usage() string concatenated.
- X o Warnings/complaints from some compilers re parameter type
- X mismatch in XChangeProperty() calls fixed.
- X
- XVersion 1.0:
- X o Initial version
- END_OF_FILE
- if test 2182 -ne `wc -c <'CHANGES'`; then
- echo shar: \"'CHANGES'\" unpacked with wrong size!
- fi
- # end of 'CHANGES'
- fi
- if test -f 'Imakefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Imakefile'\"
- else
- echo shar: Extracting \"'Imakefile'\" \(311 characters\)
- sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
- X
- XDEPLIBS = $(DEPXALIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
- XLOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
- XSYS_LIBRARIES =
- XSRCS = xcb.c
- XOBJS = xcb.o
- X
- X# Add your favourite compiler flags here.
- X#
- XDEFINES = # -DXVIEW # If you use XView apps.
- X
- XComplexProgramTarget(xcb)
- X
- XInstallAppDefaults(Xcb)
- END_OF_FILE
- if test 311 -ne `wc -c <'Imakefile'`; then
- echo shar: \"'Imakefile'\" unpacked with wrong size!
- fi
- # end of 'Imakefile'
- fi
- if test -f 'Makefile.std' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile.std'\"
- else
- echo shar: Extracting \"'Makefile.std'\" \(1104 characters\)
- sed "s/^X//" >'Makefile.std' <<'END_OF_FILE'
- X#
- X# $Header: /home/fbm/src/misc+/xcb/RCS/Makefile.std,v 1.9 1992/11/18 07:00:11 fbm Exp $
- X
- XINCS =
- X#INCS = -I/usr/include/mit # ULTRIX may need this
- XHDRS = cb.h patchlevel.h
- XSRCS = xcb.c
- XOBJS = xcb.o
- XMISC = README CHANGES xcb.man Xcb.ad ack Imakefile Makefile.std
- XSHARS = $(MISC) $(SRCS) $(HDRS)
- X
- X# Add your favourite compiler flags here.
- X#
- XCFLAGS = $(INCS) -O # -DXVIEW
- XLDFLAGS =
- X#LDFLAGS= -L /usr/lpp/X11/Xamples/lib/Xaw # AIX 3.2 may need this
- X
- X# These are the libraries required for linking.
- X#
- XLIBS = -lXaw -lXmu -lXt -lXext -lX11
- X#LIBS = -lXaw -lXmu -lXt -lXext -lX11 -lnsl # SVR4 needs libnsl.a
- X
- Xall: xcb
- X
- Xxcb: $(OBJS)
- X $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
- X
- X# You will need to check and possibly adjust the target
- X# directories for these install rules.
- X#
- Xinstall: xcb
- X install -c xcb /usr/bin/X11
- X install -c -m 0644 -o bin -g bin Xcb.ad /usr/lib/X11/app-defaults/Xcb
- X
- Xinstall.man:
- X install -c -m 0644 -o bin -g bin xcb.man /usr/share/man/mrd/man1/xcb.1
- X
- Xclean clobber:
- X rm -f *.o xcb
- X
- Xtags ctags: $(HDRS) $(SRCS)
- X ctags -tw $(HDRS) $(SRCS)
- X
- Xshar:
- X shar -c -f part -p -x X $(SHARS)
- END_OF_FILE
- if test 1104 -ne `wc -c <'Makefile.std'`; then
- echo shar: \"'Makefile.std'\" unpacked with wrong size!
- fi
- # end of 'Makefile.std'
- fi
- if test -f 'Xcb.ad' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Xcb.ad'\"
- else
- echo shar: Extracting \"'Xcb.ad'\" \(1934 characters\)
- sed "s/^X//" >'Xcb.ad' <<'END_OF_FILE'
- X
- X! Xcb application defaults resource file.
- X! ======================================================================
- X
- X! The xcb widget hierarchy consists of a number of custom buffer
- X! widgets contained within a single Athena form widget.
- X! The widget names and classes are as follows:
- X!
- X! buffer widgets name = "buffer<NN>" class = "Buffer"
- X! form widget name = "container" class = "Form"
- X!
- X! Buffer widgets are numbered from 0... onwards, and are named accordingly.
- X! As well as the standard core resources, each buffer widget supports
- X! resources for "foreground" and "font".
- X
- X! Application wide resources are as follows:
- X!
- X! "bufferCount" (default value 8)
- X! This is the number of buffer widgets to create.
- X! Any number of widgets (greater than zero) can be created.
- X!
- X! "layout" (default value "h")
- X! Only the first character of the resource value is significant.
- X! This is the geometry arrangement to apply in the form widget.
- X! The layout can be "h" (horizontal), "v" (vertical), or some
- X! other value to disable the geometry code and allow you to build
- X! your own custom layout scheme. An example is provided below.
- X! Refer to the "Athena Widget Set" manual for further details.
- X
- XXcb.bufferCount: 8
- XXcb.layout: horizontal
- XXcb*font: fixed
- XXcb*borderWidth: 1
- XXcb*container.defaultDistance: 0
- XXcb*Buffer.width: 60
- XXcb*Buffer.height: 60
- X
- X! Below is an example of a layout scheme which arranges
- X! 10 cut buffer widgets in two rows of 5 windows.
- X!
- X!Xcb.bufferCount: 10
- X!Xcb.layout: custom
- X!Xcb*buffer1.fromHoriz: buffer0
- X!Xcb*buffer2.fromHoriz: buffer1
- X!Xcb*buffer3.fromHoriz: buffer2
- X!Xcb*buffer4.fromVert: buffer0
- X!Xcb*buffer5.fromHoriz: buffer4
- X!Xcb*buffer5.fromVert: buffer1
- X!Xcb*buffer6.fromHoriz: buffer5
- X!Xcb*buffer6.fromVert: buffer2
- X!Xcb*buffer7.fromHoriz: buffer6
- X!Xcb*buffer7.fromVert: buffer3
- X!Xcb*buffer8.fromHoriz: buffer7
- X!Xcb*buffer9.fromHoriz: buffer8
- END_OF_FILE
- if test 1934 -ne `wc -c <'Xcb.ad'`; then
- echo shar: \"'Xcb.ad'\" unpacked with wrong size!
- fi
- # end of 'Xcb.ad'
- fi
- if test -f 'ack' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ack'\"
- else
- echo shar: Extracting \"'ack'\" \(582 characters\)
- sed "s/^X//" >'ack' <<'END_OF_FILE'
- X#!/bin/sh
- X
- X# Simple minded little shell script to send an
- X# acknowledgment message back to the factory.
- X
- X# Some people are upset by this script. Don't worry!
- X# It is nothing more than a very rough way of surveying
- X# a group of people, a group of machines, and the sizes
- X# of those machines. No invasion of privacy is intended.
- X
- X(
- X echo "Xcb 2.1 has been installed here."
- X echo "who am i:" `who am i`
- X echo "id :" `id`
- X echo "uname :" `uname -a`
- X echo "hostname:" `hostname`
- X echo "#users :" `wc /etc/passwd`
- X
- X) 2>/dev/null | mail fbm@ptcburp.ptcbu.oz.au && echo Mail sent
- END_OF_FILE
- if test 582 -ne `wc -c <'ack'`; then
- echo shar: \"'ack'\" unpacked with wrong size!
- fi
- chmod +x 'ack'
- # end of 'ack'
- fi
- if test -f 'cb.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cb.h'\"
- else
- echo shar: Extracting \"'cb.h'\" \(1012 characters\)
- sed "s/^X//" >'cb.h' <<'END_OF_FILE'
- X/*
- X * xcb: Copyright (C) 1992 by Farrell McKay.
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appears in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X *
- X * This header file contains the definitions and typedefs
- X * for the custom cut buffer widget.
- X */
- X#ifndef _cb_h
- X#define _cb_h
- X
- X#include <X11/IntrinsicP.h> /* needed for CorePart et.al.*/
- X
- X#define XtNatom "atom"
- X#define XtCAtom "Atom"
- X
- X
- Xtypedef struct _CbClassRec {
- X CoreClassPart core_class;
- X} CbClassRec, *CbWidgetClass;
- X
- Xtypedef struct _CbRec {
- X CorePart core;
- X Pixel fgnd;
- X XFontStruct *font;
- X int font_width;
- X int font_height;
- X GC gc;
- X GC gc_inv;
- X Atom atom;
- X} CbRec, *CbWidget;
- X
- X
- Xextern WidgetClass cbWidgetClass;
- Xextern CbClassRec cbClassRec;
- X
- X#endif
- END_OF_FILE
- if test 1012 -ne `wc -c <'cb.h'`; then
- echo shar: \"'cb.h'\" unpacked with wrong size!
- fi
- # end of 'cb.h'
- fi
- if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'patchlevel.h'\"
- else
- echo shar: Extracting \"'patchlevel.h'\" \(95 characters\)
- sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
- X
- X/* PATCHLEVEL: 1 */
- X
- Xstatic char version[] = "@(#) Xcb 2.1 pl1 $Date: 1992/11/18 07:23:08 $";
- END_OF_FILE
- if test 95 -ne `wc -c <'patchlevel.h'`; then
- echo shar: \"'patchlevel.h'\" unpacked with wrong size!
- fi
- # end of 'patchlevel.h'
- fi
- if test -f 'xcb.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xcb.c'\"
- else
- echo shar: Extracting \"'xcb.c'\" \(22716 characters\)
- sed "s/^X//" >'xcb.c' <<'END_OF_FILE'
- X/*
- X * xcb: Copyright (C) 1992 by Farrell McKay.
- X * XView modifications provided by Danny Vanderryn.
- X *
- X * Simple X interface to the cut buffers in an X server.
- X * The program creates a window subdivided into a number of subwindows,
- X * one per cut buffer. The user may copy cut buffer contents around
- X * using mouse buttons 1 and 2, or rotate the buffers using mouse
- X * button 3. Buffers may be cleared by using Shift-button 2.
- X *
- X * Note that this program assumes the cut buffers contain textual
- X * information, and displays buffer contents using the XDrawString
- X * function. It is not suitable for use in any other environment.
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted, provided
- X * that the above copyright notice appears in all copies and that both that
- X * copyright notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without express or
- X * implied warranty.
- X */
- X#include <ctype.h>
- X#include <stdio.h>
- X#include <string.h> /* for strcmp() */
- X#ifdef __STDC__
- X#include <stdlib.h> /* for exit()... */
- X#endif
- X#ifndef VMS
- X#include <unistd.h> /* for read(), write() */
- X#endif
- X#include <X11/Xatom.h> /* for pre-defined atom names */
- X#include <X11/StringDefs.h> /* for XtNforeground et.al.*/
- X#include <X11/Intrinsic.h>
- X#ifndef VMS
- X#include <X11/Xaw/Form.h>
- X#else
- X#include <Xaw/Form.h>
- X#endif
- X
- X#include "cb.h"
- X#include "patchlevel.h"
- X
- X#define _printf (void) printf
- X#define _fprintf (void) fprintf
- X#define _sprintf (void) sprintf
- X
- X#define eq(a,b) (strcmp((a),(b)) == 0)
- X#define min(a,b) ((a) < (b)? (a): (b))
- X#define max(a,b) ((a) > (b)? (a): (b))
- X
- X#define XtNbufferCount "bufferCount" /* Application resources */
- X#define XtCBufferCount "BufferCount"
- X#define XtNlayout "layout"
- X#define XtCLayout "Layout"
- X
- X#define PGM_NAME "xcb"
- X#define PGM_CLASS "Xcb"
- X#define BUFINC 2048
- X
- Xstatic Display *dpy;
- Xstatic Window root;
- Xstatic XtAppContext app;
- Xstatic Widget top, box, *wdg;
- Xstatic Atom delwin;
- Xstatic Atom *atom;
- Xstatic int natoms, nbuffs;
- Xstatic Window seln;
- X
- X#ifdef XVIEW
- Xstatic Atom caret, clipboard, yield;
- Xstatic Atom length, lengthc;
- Xstatic Atom text, ctext;
- X#endif
- X
- X
- X/*
- X * Fetch the contents of cut buffer n from the root window.
- X */
- Xstatic char *
- Xfetch_buffer(a, nb)
- XAtom a;
- Xint *nb;
- X{
- X Atom actl_type;
- X int actl_format;
- X unsigned long nitems, after;
- X char *data;
- X
- X *nb = 0;
- X if (XGetWindowProperty(dpy, root, a,
- X 0L, 10000000L, False, XA_STRING,
- X &actl_type, &actl_format, &nitems,
- X &after, (unsigned char **) &data) != Success)
- X return NULL;
- X
- X if (actl_type == XA_STRING && actl_format != 32) {
- X *nb = nitems;
- X return data;
- X }
- X if (data != NULL)
- X XFree(data);
- X return NULL;
- X}
- X
- X/*
- X * Store the string p into cut buffer n on the root window.
- X */
- Xstatic void
- Xstore_buffer(p, nb, atom)
- Xchar *p;
- Xint nb;
- XAtom atom;
- X{
- X XChangeProperty(dpy, root, atom, XA_STRING,
- X 8, PropModeReplace, (unsigned char *) p, nb);
- X}
- X
- X/*
- X * Add an atom to the program's atom cache.
- X */
- Xstatic Atom
- Xget_atom(n, ifexists)
- Xint n, ifexists;
- X{
- X char tmp[32];
- X
- X if (n >= natoms) {
- X atom = (Atom *) XtRealloc((char *) atom, (n+1) * sizeof(Atom));
- X while (natoms < n+1)
- X atom[natoms++] = 0;
- X }
- X if (!atom[n]) {
- X _sprintf(tmp, "CUT_BUFFER%d", n);
- X atom[n] = XInternAtom(dpy, tmp, (Bool) ifexists);
- X }
- X return atom[n];
- X}
- X
- X/*
- X * Draw a string in the window with top-left corner justification.
- X */
- Xstatic void
- Xplace_text(cb, str, len, y)
- XCbWidget cb;
- Xchar *str;
- Xint len, y;
- X{
- X int cols;
- X GC gc;
- X
- X gc = (cb->core.window == seln)? cb->gc_inv: cb->gc;
- X if (y <= (int) cb->core.height) {
- X cols = ((int) cb->core.width + cb->font_width - 1)
- X / cb->font_width;
- X len = min(len, cols);
- X if (len > 0) {
- X y += cb->font->ascent;
- X XDrawImageString(dpy, cb->core.window, gc,
- X 0, y, str, len);
- X }
- X }
- X}
- X
- X/*
- X * ============================================================================
- X * The following collection of functions and data structures define
- X * the cb widget. Each cb widget displays a single cut buffer value
- X * in a window, and provides cut and paste access to that buffer.
- X */
- X
- Xstatic void
- Xcb_initialize(req, wdg, args, nargs) /*ARGSUSED*/
- XWidget req, wdg;
- XArgList args;
- XCardinal *nargs;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X
- X cb->font_width = cb->font->max_bounds.width;
- X cb->font_height = cb->font->ascent + cb->font->descent;
- X cb->gc = 0;
- X cb->gc_inv = 0;
- X
- X XChangeProperty(dpy, root, cb->atom, XA_STRING,
- X 8, PropModeAppend, (unsigned char *) "", 0);
- X}
- X
- Xstatic void
- Xcb_realize(wdg, mask, attrs)
- XWidget wdg;
- XXtValueMask *mask;
- XXSetWindowAttributes *attrs;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X XtGCMask v_mask = 0L;
- X XGCValues values;
- X
- X XtCreateWindow(wdg, InputOutput, CopyFromParent, *mask, attrs);
- X
- X values.font = cb->font->fid;
- X values.foreground = cb->fgnd;
- X values.background = cb->core.background_pixel;
- X v_mask = GCFont | GCForeground | GCBackground;
- X cb->gc = XtGetGC(wdg, v_mask, &values);
- X
- X values.foreground = cb->core.background_pixel;
- X values.background = cb->fgnd;
- X cb->gc_inv = XtGetGC(wdg, v_mask, &values);
- X}
- X
- X/*
- X * Redraw the contents of one of the subwindows.
- X * The function assumes the cut buffer contains text data, and parses
- X * it accordingly. The data is split into lines at each '\n' character.
- X * Lines which extend beyond the subwindow's borders are clipped; no
- X * wrap-around processing is done.
- X * Keep it simple.
- X */
- Xstatic void
- Xcb_redisplay(wdg, event, region) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XRegion region;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X char *p, *pp, *base;
- X int y, nbytes;
- X
- X y = 0;
- X p = pp = base = fetch_buffer(cb->atom, &nbytes);
- X while (pp < base + nbytes) {
- X if (*pp == '\n') {
- X place_text(cb, p, pp - p, y);
- X p = pp + 1;
- X y += cb->font_height;
- X }
- X pp++;
- X }
- X place_text(cb, p, pp - p, y);
- X XFree(base);
- X}
- X
- Xstatic void
- Xcb_destroy(wdg)
- XWidget wdg;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X
- X XtReleaseGC(wdg, cb->gc);
- X XtReleaseGC(wdg, cb->gc_inv);
- X}
- X
- X/*
- X * Make this widget the owner of the PRIMARY selection.
- X * The window contents are then redrawn with highlighting.
- X *
- X * It seems that if a XSetSelectionOwner is performed on a client's
- X * window, no SelectionClear event is generated if another window
- X * within the same client is already the selection owner.
- X * This function originally attempted to avoid that problem and force
- X * a SelectionClear event by firstly setting the selection ownership
- X * to None and then setting it to this widget's window. Apparently
- X * that didn't work for all X servers.
- X *
- X * Therefore the function must do the SelectionClear logic itself,
- X * which means it must know when another xcb widget has selection
- X * ownership, which brings about the need for the 'seln' global variable.
- X * This breaks all the rules for object oriented widgets. Disgusting, no?
- X */
- Xstatic void
- Xcb_cut(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X Window win = cb->core.window;
- X Window w, tmp;
- X
- X if (win == seln)
- X return;
- X
- X XSetSelectionOwner(dpy, XA_PRIMARY, win, event->xbutton.time);
- X w = XGetSelectionOwner(dpy, XA_PRIMARY);
- X if (seln && w != seln) {
- X tmp = seln;
- X seln = 0;
- X XClearArea(dpy, tmp, 0,0,0,0, False);
- X cb_redisplay(XtWindowToWidget(dpy,tmp), (XEvent *)0, (Region)0);
- X }
- X
- X if (w == win) {
- X seln = win;
- X XClearArea(dpy, win, 0,0,0,0, False);
- X cb_redisplay(wdg, (XEvent *)0, (Region)0);
- X#ifdef XVIEW
- X XSetSelectionOwner(dpy, caret, win, event->xbutton.time);
- X XSetSelectionOwner(dpy, clipboard, win, event->xbutton.time);
- X#endif
- X }
- X}
- X
- Xstatic void
- Xcb_paste(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X Window w;
- X char *ptr;
- X int n;
- X
- X w = XGetSelectionOwner(dpy, XA_PRIMARY);
- X if (w == None) {
- X ptr = fetch_buffer(atom[0], &n); /* copy from cb0 */
- X store_buffer(ptr, n, cb->atom);
- X XFree(ptr);
- X }
- X else if (w != cb->core.window)
- X XConvertSelection(dpy, XA_PRIMARY, XA_STRING,
- X cb->atom, root, event->xbutton.time);
- X}
- X
- Xstatic void
- Xcb_clear(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X Window win = cb->core.window;
- X
- X store_buffer("", 0, cb->atom);
- X if (win == seln) {
- X seln = 0;
- X XSetSelectionOwner(dpy, XA_PRIMARY, None, event->xbutton.time);
- X }
- X}
- X
- Xstatic void
- Xcb_rotate(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X int n = 0;
- X
- X if (*nparms > 0)
- X n = atoi(parms[0]);
- X if (n != 0)
- X XRotateWindowProperties(dpy, root, atom, nbuffs, n);
- X}
- X
- Xstatic void
- Xcb_quit(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X exit(0);
- X}
- X
- X/*
- X * Clear and redraw the widget's window.
- X */
- Xstatic void
- Xcb_refresh(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X XClearArea(dpy, wdg->core.window, 0,0,0,0, False);
- X cb_redisplay(wdg, (XEvent *)0, (Region)0);
- X}
- X
- X/*
- X * Someone or something wants a copy of the current PRIMARY selection.
- X * Such a request is only satisfied if the target type is STRING.
- X * (No conversion facilities are provided by this program).
- X * The selection request is met by copying the current contents
- X * of the cut buffer to the target window+atom.
- X */
- Xstatic void
- Xcb_selreq(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X int nbytes;
- X char *ptr;
- X XSelectionEvent notify;
- X XSelectionRequestEvent *rq;
- X CbWidget cb = (CbWidget) wdg;
- X Window win = cb->core.window;
- X#ifdef XVIEW
- X unsigned long data;
- X#endif
- X
- X rq = (XSelectionRequestEvent *) event;
- X
- X notify.type = SelectionNotify;
- X notify.display = rq->display;
- X notify.requestor = rq->requestor;
- X notify.selection = rq->selection;
- X notify.target = rq->target;
- X notify.property = None;
- X notify.time = rq->time;
- X
- X#ifdef XVIEW
- X if (rq->selection == XA_PRIMARY) {
- X if (rq->target == yield) {
- X /* tell 'em we'll give it up */
- X data = 1;
- X XChangeProperty(dpy, rq->requestor, rq->property,
- X rq->target, 32, PropModeReplace,
- X (unsigned char *) &data, 1);
- X notify.property = rq->property;
- X }
- X else {
- X#endif
- X
- X if (win == seln && rq->target == XA_STRING) {
- X ptr = fetch_buffer(cb->atom, &nbytes);
- X XChangeProperty(dpy, rq->requestor, rq->property,
- X XA_STRING, 8, PropModeReplace,
- X (unsigned char *) ptr, nbytes);
- X notify.property = rq->property;
- X XFree(ptr);
- X }
- X
- X#ifdef XVIEW
- X }
- X }
- X else if (rq->selection == caret) {
- X if (rq->target == yield) {
- X /*
- X * Give up the caret (which meant that we
- X * own the clipboard)
- X */
- X XSetSelectionOwner(dpy, caret, None,
- X event->xselectionrequest.time);
- X data = 1;
- X XChangeProperty(dpy, rq->requestor, rq->property,
- X rq->target, 32, PropModeReplace,
- X (unsigned char *) &data, 1);
- X notify.property = rq->property;
- X }
- X }
- X else if (rq->selection == clipboard && win == seln) {
- X ptr = fetch_buffer(cb->atom, &nbytes);
- X if (rq->target == lengthc || rq->target == length) {
- X /*
- X * Send the length of the selection.
- X */
- X data = nbytes;
- X XChangeProperty(dpy, rq->requestor, rq->property,
- X rq->target, 32, PropModeReplace,
- X (unsigned char *) &data, 1);
- X notify.property = rq->property;
- X }
- X else if (rq->target == XA_STRING ||
- X rq->target == text || rq->target == ctext) {
- X /*
- X * Send the selection itself.
- X * All of our selections will be XA_STRING,
- X * but if they ask for COMPOUND_TEXT, it's ok
- X * to say that that's what we've got...
- X */
- X XChangeProperty(dpy, rq->requestor, rq->property,
- X (rq->target == ctext? ctext: XA_STRING), 8,
- X PropModeReplace, ptr, nbytes);
- X notify.property = rq->property;
- X }
- X XFree(ptr);
- X }
- X#endif
- X
- X XSendEvent(dpy, rq->requestor, False, 0, (XEvent *) ¬ify);
- X}
- X
- X/*
- X * Boo hiss, someone has taken the PRIMARY selection ownership
- X * away from this widget. The current window contents must
- X * be redrawn without highlighting.
- X */
- Xstatic void
- Xcb_selclear(wdg, event, parms, nparms) /*ARGSUSED*/
- XWidget wdg;
- XXEvent *event;
- XString *parms;
- XCardinal *nparms;
- X{
- X CbWidget cb = (CbWidget) wdg;
- X#ifdef XVIEW
- X Window w;
- X Time t;
- X#endif
- X
- X seln = 0;
- X XClearArea(dpy, cb->core.window, 0,0,0,0, False);
- X cb_redisplay(wdg, (XEvent *)0, (Region)0);
- X#ifdef XVIEW
- X /*
- X * Since we don't have ownership of PRIMARY anymore,
- X * we'd better get rid of CLIPBOARD and _SUN_SELN_CARET,
- X * if they're still ours.
- X */
- X t = event->xselectionclear.time;
- X w = XGetSelectionOwner(dpy, caret);
- X if (w == cb->core.window)
- X XSetSelectionOwner(dpy, caret, None, t);
- X w = XGetSelectionOwner(dpy, clipboard);
- X if (w == cb->core.window)
- X XSetSelectionOwner(dpy, clipboard, None, t);
- X#endif
- X}
- X
- Xstatic XtResource resources[] = {
- X#define offset(field) XtOffset(CbWidget, field)
- X /* {name, class, type, size, offset, default_type, default_addr}, */
- X { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
- X offset(fgnd), XtRString, (XtPointer) "XtDefaultForeground"},
- X { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
- X offset(font), XtRString, (XtPointer) "fixed" },
- X { XtNatom, XtCAtom, XtRAtom, sizeof(Atom), /* internal use */
- X offset(atom), XtRImmediate, (XtPointer)0 },
- X#undef offset
- X};
- X
- Xstatic XtActionsRec actions[] = {
- X { "cut", cb_cut },
- X { "paste", cb_paste },
- X { "clear", cb_clear },
- X { "rotate", cb_rotate },
- X { "quit", cb_quit },
- X { "refresh", cb_refresh },
- X { "selreq", cb_selreq },
- X { "selclear", cb_selclear },
- X};
- X
- Xstatic char cb_transl[] = "\
- X <Btn1Down>: cut() \n\
- X Shift <Btn2Down>: clear() \n\
- X <Btn2Down>: paste() \n\
- X Shift <Btn3Down>: rotate(-1) \n\
- X <Btn3Down>: rotate(1) \n\
- X <Key>Left: rotate(-1) \n\
- X <Key>Right: rotate(1) \n\
- X <Key>Up: rotate(-1) \n\
- X <Key>Down: rotate(1) \n\
- X <Key>q: quit() \n\
- X <SelReq>: selreq() \n\
- X <SelClr>: selclear() \n\
- X ";
- X
- XCbClassRec cbClassRec = {
- X {
- X (WidgetClass) &widgetClassRec, /* superclass */
- X "Buffer", /* class_name */
- X sizeof(CbRec), /* widget_size */
- X NULL, /* class_initialize */
- X NULL, /* class_part_initialize */
- X FALSE, /* class_inited */
- X cb_initialize, /* initialize */
- X NULL, /* initialize_hook */
- X cb_realize, /* realize */
- X actions, /* actions */
- X XtNumber(actions), /* num_actions */
- X resources, /* resources */
- X XtNumber(resources), /* num_resources */
- X NULLQUARK, /* xrm_class */
- X TRUE, /* compress_motion */
- X TRUE, /* compress_exposure */
- X TRUE, /* compress_enterleave */
- X FALSE, /* visible_interest */
- X cb_destroy, /* destroy */
- X NULL, /* resize */
- X cb_redisplay, /* expose */
- X NULL, /* set_values */
- X NULL, /* set_values_hook */
- X XtInheritSetValuesAlmost, /* set_values_almost */
- X NULL, /* get_values_hook */
- X NULL, /* accept_focus */
- X XtVersion, /* version */
- X NULL, /* callback_private */
- X cb_transl, /* tm_table */
- X XtInheritQueryGeometry, /* query_geometry */
- X XtInheritDisplayAccelerator, /* display_accelerator */
- X NULL /* extension */
- X },
- X};
- X
- XWidgetClass cbWidgetClass = (WidgetClass) &cbClassRec;
- X
- X/*
- X * Here endeth the section concerned with the cb widget.
- X * Normal viewing shall now be resumed.
- X * ============================================================================
- X */
- X
- X
- Xstatic void
- Xusage()
- X{
- X _fprintf(stderr,
- X "Usage: %s [Xt option] [-l layout] [-n count] [-p|-s list] [-r count]\n",
- X PGM_NAME);
- X exit(1);
- X}
- X
- X/*
- X * Gracefully exit after an XIO error, or after a "delete window"
- X * directive from the window manager.
- X * xioerror() avoids messy error messages sometimes seen from xterm
- X * or in the xdm-errors file when forcibly destroying the client program.
- X */
- Xstatic int
- Xxioerror(d) /*ARGSUSED*/
- XDisplay *d;
- X{
- X exit(1); /*NOTREACHED*/
- X}
- X
- Xstatic void
- Xwmdel(wdg, ptr, ep, cont) /*ARGSUSED*/
- XWidget wdg;
- XXtPointer ptr;
- XXEvent *ep;
- XBoolean *cont;
- X{
- X if (ep->type == ClientMessage && ep->xclient.data.l[0] == delwin)
- X exit(0);
- X}
- X
- X/*
- X * Print the contents of a cut buffer on stdout.
- X */
- Xstatic void
- Xdoprint(n, ptr, nb)
- Xint n;
- Xchar *ptr;
- Xint nb;
- X{
- X Atom a;
- X
- X a = get_atom(n, True);
- X if (a) {
- X ptr = fetch_buffer(a, &nb);
- X if (write(1, ptr, nb) != nb) {
- X _fprintf(stderr, "Write error\n");
- X exit(1);
- X }
- X XFree(ptr);
- X }
- X}
- X
- X/*
- X * Load a new value into one of the cut buffers.
- X */
- Xstatic void
- Xdoset(n, ptr, nb)
- Xint n;
- Xchar *ptr;
- Xint nb;
- X{
- X store_buffer(ptr, nb, get_atom(n, False));
- X}
- X
- X/*
- X * Process an ASCII list of cut buffer numbers.
- X * Lists must obey the form "buffno[,buffno...]"
- X * where buffno is a non-negative integer or a range
- X * of the form M-N. A processing function is called
- X * for each buffer number in the list. Duplicates and
- X * list ordering is significant.
- X */
- Xstatic void
- Xdolist(list, fn, data, nbytes)
- Xchar *list;
- Xvoid (*fn)();
- Xchar *data;
- Xint nbytes;
- X{
- X int m, n, x;
- X
- X while (*list) {
- X if (!isdigit(*list))
- X usage();
- X for (m = 0; isdigit(*list); list++)
- X m = m * 10 + *list - '0';
- X
- X (*fn)(m, data, nbytes);
- X
- X if (*list == '-') {
- X list++;
- X if (!isdigit(*list))
- X usage();
- X for (n = 0; isdigit(*list); list++)
- X n = n * 10 + *list - '0';
- X
- X x = (m > n)? -1: 1;
- X while (m != n) {
- X m += x;
- X (*fn)(m, data, nbytes);
- X }
- X }
- X
- X if (*list == ',')
- X list++;
- X else if (*list)
- X usage();
- X }
- X}
- X
- X/*
- X * Perform a task mode command, i.e.
- X * do something to the cut buffers immediately,
- X * without the need to create any X windows first.
- X */
- Xstatic void
- Xdotask(cmd, arg)
- Xint cmd;
- Xchar *arg;
- X{
- X char *ptr;
- X int i, n, nb;
- X
- X ptr = (char *)0;
- X n = nb = 0;
- X
- X switch (cmd) {
- X case 'p': /* print one or more buffers */
- X dolist(arg, doprint, (char *)0, 0);
- X break;
- X case 'r': /* rotate the buffer contents */
- X n = atoi(arg);
- X if (n == 0)
- X break;
- X for (i = nbuffs - 1; i >= 0; i--)
- X (void) get_atom(i, False);
- X for (i = nbuffs - 1; i >= 0; i--)
- X XChangeProperty(dpy, root, atom[i], XA_STRING,
- X 8, PropModeAppend, (unsigned char *) "", 0);
- X
- X XRotateWindowProperties(dpy, root, atom, nbuffs, n);
- X break;
- X case 's': /* store data in one or more buffers */
- X do {
- X ptr = XtRealloc(ptr, nb + BUFINC);
- X i = BUFINC;
- X do {
- X n = read(0, ptr + nb, i);
- X nb += n;
- X i -= n;
- X } while (n > 0 && i > 0);
- X } while (n > 0);
- X if (n == -1) {
- X _fprintf(stderr, "Read error\n");
- X exit(1);
- X }
- X dolist(arg, doset, ptr, nb);
- X XtFree(ptr);
- X break;
- X }
- X}
- X
- Xtypedef struct {
- X int nbuffs;
- X char *layout;
- X} ares_t, *ares_ptr;
- X
- Xstatic ares_t ares;
- X
- Xstatic XtResource res[] = {
- X#define offset(field) XtOffset(ares_ptr, field)
- X { XtNbufferCount, XtCBufferCount, XtRInt, sizeof(int),
- X offset(nbuffs), XtRImmediate, (XtPointer) 8 },
- X { XtNlayout, XtCLayout, XtRString, sizeof(char *),
- X offset(layout), XtRImmediate, "horiz" },
- X#undef offset
- X};
- X
- Xstatic char *def[] = { /* default resource values */
- X ".bufferCount: 8",
- X ".layout: horizontal",
- X "*font: fixed",
- X "*Buffer.width: 60",
- X "*Buffer.height: 60",
- X 0,
- X};
- X
- Xstatic XrmOptionDescRec opt[] = {
- X { "-n", ".bufferCount", XrmoptionSepArg, (caddr_t) 8 },
- X { "-l", ".layout", XrmoptionSepArg, (caddr_t) "horiz" },
- X};
- X
- X/*
- X * Parse the command line options, and
- X * perform all the windows initializations.
- X */
- Xstatic void
- Xinit(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int i, n;
- X char **p;
- X char *attach = 0;
- X char name[16];
- X Arg args[2];
- X
- X /*
- X * Set up the atoms that we already know about.
- X */
- X natoms = 8;
- X atom = (Atom *) XtMalloc(natoms * sizeof(Atom));
- X atom[0] = XA_CUT_BUFFER0;
- X atom[1] = XA_CUT_BUFFER1;
- X atom[2] = XA_CUT_BUFFER2;
- X atom[3] = XA_CUT_BUFFER3;
- X atom[4] = XA_CUT_BUFFER4;
- X atom[5] = XA_CUT_BUFFER5;
- X atom[6] = XA_CUT_BUFFER6;
- X atom[7] = XA_CUT_BUFFER7;
- X
- X /*
- X * Initialize the toolkit, parse the command line,
- X * initialize the resources database, and find out
- X * how many buffers to deal with.
- X */
- X top = XtAppInitialize(&app, PGM_CLASS, opt, 2, &argc, argv, def, 0, 0);
- X dpy = XtDisplay(top);
- X root = RootWindow(dpy, DefaultScreen(dpy));
- X
- X XtGetApplicationResources(top, &ares, res, XtNumber(res), 0, 0);
- X nbuffs = max(ares.nbuffs, 1);
- X
- X /*
- X * If the command line contains one of the task mode
- X * switches (print, set, rotate), it is processed here.
- X * If there are multiple task mode args, only the first
- X * one is processed.
- X */
- X for (p = argv + 1; p < argv + argc; p++) {
- X if (eq(*p, "-p") || eq(*p, "-r") || eq(*p, "-s")) {
- X if (p == argv + argc - 1)
- X usage();
- X
- X dotask(p[0][1], p[1]);
- X XCloseDisplay(dpy);
- X exit(0);
- X }
- X }
- X
- X /*
- X * If no task mode request has been made of us, this code
- X * proceeds with the rest of the windows initialization.
- X * The container widget is created, the sub-widgets are
- X * created and then everything is realized.
- X */
- X if (argc > 1)
- X usage();
- X if (ares.layout[0] == 'h')
- X attach = XtNfromHoriz;
- X if (ares.layout[0] == 'v')
- X attach = XtNfromVert;
- X
- X wdg = (Widget *) XtMalloc(nbuffs * sizeof(Widget));
- X
- X box = XtCreateWidget("container", formWidgetClass, top, 0, 0);
- X XtManageChild(box);
- X
- X for (i = 0; i < nbuffs; i++) {
- X XtSetArg(args[0], XtNatom, get_atom(i, False));
- X n = 1;
- X if (attach && i > 0) {
- X XtSetArg(args[1], attach, wdg[i-1]);
- X n = 2;
- X }
- X
- X _sprintf(name, "buffer%d", i);
- X wdg[i] = XtCreateWidget(name, cbWidgetClass, box, args, n);
- X XtManageChild(wdg[i]);
- X }
- X
- X XSelectInput(dpy, root, PropertyChangeMask);
- X XSetIOErrorHandler(xioerror);
- X
- X XtRealizeWidget(top);
- X
- X delwin = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- X XSetWMProtocols(dpy, XtWindow(top), &delwin, 1);
- X XtAddEventHandler(top, 0, True, wmdel, (XtPointer)0);
- X
- X#ifdef XVIEW
- X clipboard = XInternAtom(dpy, "CLIPBOARD", False);
- X caret = XInternAtom(dpy, "_SUN_SELN_CARET", False);
- X yield = XInternAtom(dpy, "_SUN_SELN_YIELD", False);
- X length = XInternAtom(dpy, "LENGTH", False);
- X lengthc = XInternAtom(dpy, "LENGTH_CHARS", False);
- X text = XInternAtom(dpy, "TEXT", False);
- X ctext = XInternAtom(dpy, "COMPOUND_TEXT", False);
- X#endif
- X}
- X
- X/*
- X * Process incoming events.
- X * The program needs to know when a cut buffer value changes.
- X * We achieve this by eavesdropping on PropertyNotify events arising
- X * on the root window. If such an event is delivered to us, the
- X * function immediately clears the window displaying that property
- X * and causes an Expose event to be generated for the window.
- X * This is horrible nasty stuff.
- X */
- Xstatic void
- Xxevents()
- X{
- X XEvent event;
- X int i;
- X
- X for (;;) {
- X XtAppNextEvent(app, &event);
- X if (event.type != PropertyNotify) {
- X (void) XtDispatchEvent(&event);
- X continue;
- X }
- X
- X for (i = 0; i < nbuffs; i++)
- X if (event.xproperty.atom == atom[i])
- X XClearArea(dpy, XtWindow(wdg[i]), 0,0,0,0,True);
- X }
- X}
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X init(argc, argv);
- X xevents();
- X return 0;
- X}
- END_OF_FILE
- if test 22716 -ne `wc -c <'xcb.c'`; then
- echo shar: \"'xcb.c'\" unpacked with wrong size!
- fi
- # end of 'xcb.c'
- fi
- if test -f 'xcb.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xcb.man'\"
- else
- echo shar: Extracting \"'xcb.man'\" \(8737 characters\)
- sed "s/^X//" >'xcb.man' <<'END_OF_FILE'
- X.TH XCB 1 "May 6 1992" "X Version 11"
- X.SH NAME
- Xxcb \- X Cut Buffers \- Pigeon holes for your cut and paste selections.
- X.SH SYNOPSIS
- X.B xcb
- X[\fIXt option\fP]
- X[\fB\-l\fP \fIlayout\fP]
- X[\fB\-n\fP \fIcount\fP]
- X[\fB\-p\fP|\fB\-s\fP \fIlist\fP]
- X[\fB\-r\fP \fIcount\fP]
- X.SH DESCRIPTION
- X\fIXcb\fP provides easy access to the cut buffers built into every X server.
- XIt allows the buffers to be manipulated either via the command line,
- Xor with the mouse in a point and click manner.
- XThe buffers can be used as holding pens to store and retrieve
- Xarbitrary data fragments.
- XAny number of cut buffers may be created,
- Xso any number of different pieces of data can be saved and recalled later.
- XBy default, 8 cut buffers are created.
- XThe program is designed primarily for use with textual data.
- X.LP
- X\fIXcb\fP has two modes of operation.
- XNormally \fIxcb\fP provides an array of windows on your display,
- Xone per cut buffer, tiled horizontally, vertically, or in some
- Xuser specified layout.
- XEach window displays the contents of its respective cut buffer.
- XData can be cut from and pasted to the windows in a similar manner
- Xto xterm.
- XThe buffers can also be rotated.
- X.LP
- XIn task mode, \fIxcb\fP lets you access the cut buffers from the command line.
- XCut buffers can be loaded from stdin, copied or concatenated
- Xto stdout, or rotated an arbitrary number of positions.
- XIn this mode of operation, \fIxcb\fP performs the requested task
- Xand then exits.
- XIt does not create any windows and
- Xhas no interaction with the mouse or keyboard.
- X.SH OPTIONS
- X\fIXcb\fP supports the full set of X Toolkit Intrinsics options,
- Xas well as those listed below.
- X\fIXcb\fP options can appear in any order.
- XThe presence of the
- X\fB\-p\fP,
- X\fB\-r\fP or
- X\fB\-s\fP
- Xoptions causes \fIxcb\fP to execute in task mode,
- Xdescribed above.
- X.IP "\fB\-l\fP \fIlayout\fP"
- XThis option controls the geometry arrangement of \fIxcb's\fP subwindows.
- XIt is the command line equivalent of the \fB.layout\fP resource,
- Xdescribed below.
- X.LP
- X.IP "\fB\-n\fP \fIcount\fP"
- XCreate \fIcount\fP cut buffers.
- X\fICount\fP can be any integer greater than zero.
- XThis option is the command line equivalent of the \fB.bufferCount\fP
- Xresource, described below.
- X.LP
- X.IP "\fB\-p\fP \fIlist\fP"
- XPrint the contents of the listed buffer(s) on stdout.
- XThe buffered data is printed exactly as it is stored in the server.
- XSelecting two or more buffers has the effect of concatenating
- Xthe data on stdout.
- XThe cut buffers are numbered from 0... onwards.
- XThe list can be either a single digit,
- Xa comma separated list of digits,
- Xa range of the form m\-n,
- Xor some combination of lists and ranges.
- XThe buffers are printed in listed order,
- Xso repeated numbers in the list can be used to
- Xduplicate buffer contents.
- X.LP
- X.IP "\fB\-r\fP \fIcount\fP"
- XRotate the buffers by \fIcount\fP positions.
- X\fICount\fP can be any integer, positive or negative.
- XThis option may be used in conjunction with the
- X\fB\-n\fP \fIcount\fP option to rotate
- Xa specific number of buffers.
- XIf the \fB\-n\fP option is not used, \fIxcb\fP will rotate
- Xthe number of buffers given by the \fB.bufferCount\fP resource.
- X.LP
- X.IP "\fB\-s\fP \fIlist\fP"
- XStore the data from stdin in the listed buffer(s).
- XIf two or more buffers are selected the input data is duplicated
- Xin each buffer.
- XRefer to the \fB\-p\fP option for the definition of a list.
- X.SH WIDGETS and RESOURCES
- XThe \fIxcb\fP widget hierarchy consists of a collection of
- Xcustom buffer widgets contained within a single Athena form widget.
- X.LP
- XThe name of the form widget is "container",
- Xand its class name is "Form".
- XThe names of the buffer widgets are "buffer0", "buffer1",
- X"buffer2", .... etc., and their class name is "Buffer".
- XEach buffer widget supports all the standard core widget
- Xresources, plus the \fB\.foreground\fP and \fB\.font\fP resources.
- X.LP
- XApplication wide resources are as follows:
- X.br
- X.sp 1
- X.nf
- X \fB\.bufferCount\fP (default value 8)
- X.in +8
- XThis is the number of buffer widgets to create.
- XAny number of widgets (greater than zero) can be created.
- X.in -8
- X.sp 1
- X \fB\.layout\fP (default value "h")
- X.in +8
- XOnly the first character of the resource value is significant.
- XThis is the geometry arrangement to apply in the form widget.
- XThe layout can be "h" (horizontal), "v" (vertical), or some
- Xother value to disable the geometry code and allow you to build
- Xyour own custom layout scheme. An example is provided in the
- Xapplication default resources file.
- X.in -8
- X.fi
- X.SH EVENTS and TRANSLATIONS
- X\fIXcb's\fP input semantics are coded into a Toolkit translation table.
- XThe default bindings have been chosen to conform with the default
- Xconfiguration of other cut and paste clients, such as xterm.
- XThe bindings may be altered or overridden according to your needs.
- XThe actions functions provided by \fIxcb\fP are:\-
- X.br
- X.sp 1
- X.ns
- X.ta 16n
- X.nf
- Xcut() causes the contents of the chosen cut buffer to become
- X the PRIMARY selection. The window contents, if any,
- X are highlighted, and can then be pasted into other
- X cut buffers or applications.
- X.sp 1
- Xpaste() causes the value of the PRIMARY selection to be
- X converted into text and pasted into the chosen cut
- X buffer, overwriting any previous buffer contents.
- X If no PRIMARY selection is present, \fIxcb\fP pastes
- X the contents of cut buffer zero into the chosen buffer.
- X.sp 1
- Xclear() clears the chosen cut buffer.
- X.sp 1
- Xrotate(NN) rotates the cut buffers by NN positions. NN may
- X be any positive or negative number.
- X.sp 1
- Xrefresh() causes the cut buffer window to be cleared and redrawn.
- X.sp 1
- Xselreq() this action function handles paste requests
- X from other clients, or other \fIxcb\fP windows.
- X It should always be bound to SelectionRequest events.
- X.sp 1
- Xselclear() this action function responds to the loss of
- X ownership of the PRIMARY selection property.
- X It should always be bound to SelectionClear events.
- X.sp 1
- Xquit() causes \fIxcb\fP to terminate.
- X.fi
- X.ta 8n
- X.sp 1
- XThe default bindings are as follows:\-
- X.sp 1
- X.ta 20n
- X.nf
- X<Btn1Down>: cut() \\n\\
- XShift <Btn2Down>: clear() \\n\\
- X<Btn2Down>: paste() \\n\\
- XShift <Btn3Down>: rotate(-1) \\n\\
- X<Btn3Down>: rotate(1) \\n\\
- X<Key>Left: rotate(-1) \\n\\
- X<Key>Right: rotate(1) \\n\\
- X<Key>Up: rotate(-1) \\n\\
- X<Key>Down: rotate(1) \\n\\
- X<Key>q: quit() \\n\\
- X<SelReq>: selreq() \\n\\
- X<SelClr>: selclear()
- X.fi
- X.ta 8n
- X.sp 1
- X.SH EXAMPLES
- XThe following are some examples of \fIxcb\fP task mode usage:\-
- X.sp 1
- Xxcb \-s 0\-7 < /dev/null
- X.br
- XThis clears the first 8 cut buffers in your server.
- X.sp 1
- Xecho "G'day." | xcb \-display bigears:0.0 \-s 1,3,5,7
- X.br
- XThis loads the string "G'day." into four of the cut buffers
- Xon the display "bigears".
- X.sp 1
- Xls \`xcb \-p 2,3\`
- X.br
- XThis produces a listing of all the files named in
- Xcut buffers 2 and 3.
- X.br
- X.sp 1
- Xxcb \-p 0\-7 | xcb \-s 0
- X.br
- XThis concatenates the values in the first 8 cut buffers, and places
- Xthe result back in cut buffer zero.
- X.sp 1
- X.nf
- Xfor i in 0 1 2 3 4 5 6 7
- Xdo
- X xcb \-p $i > $HOME/.xcb/$i
- Xdone
- Xfor i in 0 1 2 3 4 5 6 7
- Xdo
- X xcb \-s $i < $HOME/.xcb/$i
- Xdone
- X.fi
- XThis first loop saves the contents of each of the cut buffers
- Xin a separate file under your home directory. The second loop
- Xrestores the cut buffer contents from those files.
- XWhen placed in your .logout and .login scripts respectively,
- Xthe commands are a simple method of preserving your cut buffers
- Xacross login sessions.
- X.sp 1
- X.nf
- Xfunction g {
- X echo "$1\\\\c" | xcb \-s 7
- X grep "$@"
- X}
- Xfunction vg {
- X vi +/\`xcb \-p 7\` "$@"
- X}
- X.fi
- XThese two shell functions exemplify a simple mechanism for saving and
- Xreusing regular expressions.
- XThe first function saves the regex used for grep\-ing into
- Xcut buffer 7. The second function reuses the most recent
- Xgrep regex as a search command in vi.
- XThere is considerable scope for expanding and improving these ideas.
- X.SH SEE ALSO
- Xxterm(1), xcutsel(1), xclipboard(1), xprop(1)
- X.br
- XAthena Widget Set \- C Language Interface
- X.SH AUTHORS
- XFarrell McKay
- X.br
- XE\-mail: fbm\@ptcburp.ptcbu.oz.au
- X.br
- X.sp 1
- XXView modifications provided by Danny Vanderryn
- X.br
- XE\-mail: dvanderr\@us.oracle.com
- X.SH COPYRIGHT
- XCopyright (C) 1992 by Farrell McKay.
- X.br
- X.sp 1
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted, provided
- Xthat the above copyright notice appears in all copies and that both that
- Xcopyright notice and this permission notice appear in supporting
- Xdocumentation. This software is provided "as is" without express or
- Ximplied warranty.
- X.SH "BUGS :\-)"
- XXlib's underlying protocol for moving selection data
- Xbetween client and server can sometimes be slow,
- Xdepending on the amount of data involved.
- XDo not expect fast performance if your selections are
- Xbig or you want to store big files in your cut buffers!
- X("big" means, say, over 10k bytes \- but your mileage
- Xmay vary).
- END_OF_FILE
- if test 8737 -ne `wc -c <'xcb.man'`; then
- echo shar: \"'xcb.man'\" unpacked with wrong size!
- fi
- # end of 'xcb.man'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-