Subject: cut/paste tools for DM and X
From: [email-masked] (Glen E Valante)
To: [email-masked]
Date: 15 Aug 90 23:49:00 GMT

Hello,
  
 After a lot of requests for this, here it is.......

--glen

How to use dm2x and x2dm cut/paste tools.

Since the dm and X do not share the same cut/paste buffers there has to 
be a mechanism to transfer the needed data between them.  The tools dm2x
and x2dm will transfer the data between the dm pastebuffer in `node_data/
paste_buffers/default.txt to the X buffer 0.

Place x2dm and dm2x in your ~/com, ~/bin or some place where search rules 
apply.

I will use Xterm as an example of an X window.  Note that all X clients do not
perform a cut/paste with the same keys but hopefully they will use the
same cutbuffer.

To cut text in Xterm, press mouse 1 button where you want to start highlighting
text.  Holding the button down, drag the mouse over the area and release
when you have what you want.  The area that will be cut will be highlighted.  

Execute the x2dm utility.

You will then be able to paste the text with the <paste> key into any Dm edit
window.

To cut text from a Dm window, Mark the text you want to transfer, then
press the 
<copy> key.

Execute the dm2x utility.

You will then be able to paste into the Xterm window with just positioning the
Xterm text cursor and pressing the mouse 2 button.
                                                                           
  If you run motif or uwm, you can customize your rc file to exicute
them from a 
roll down menu.

  If you use the Dm as your window manager, you can exicute them with a
dm keydeff.  
The keydeff will look something like this:

             kd f1 cps /com/sh -c '~/com/x2dm' -cps; msg 'x2dm' ke
             kd f2 cps /com/sh -c '~/com/dm2x' -cps; msg 'dm2x' ke

Limitations:   

/sys/node_data/paste_buffers/default.txt has to exist before running for
example x2dm
This can be created by a simple dm cut opperation.

Disclaimer:

Apollo/HP does not know this exists, and they don't want to know. Excuse
any typo's.

Any comments or suggestions or praise should be sent to
[email-masked].

ABOUT THE AUTHORS:

This meager tool came about because of the needs of many dm users that
were thrust into the X world.  The thought and technical abilities 
applied to this code are that of Peter Craine and Glen Valante.

ENJOY.........

**************cut here  cut here**************
/*    

dm2x.c

   Copies data from the DM paste buffer to the X-windows
paste buffer # 0
  
*/         

#include <X11/Xlib.h>
#include <strings.h>
#include <stdio.h>                       
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>

#define MAX_BUFFER_SIZE 4096

Display *display;
char * p;  
int i;
char *path = "`node_data/paste_buffers/default.txt";

main()
{
  int fd;
  struct stat Stat_Buf;
  char Buff[MAX_BUFFER_SIZE];
  int Size;

  if ( (display=XOpenDisplay(NULL)) == NULL )
     {
     fprintf(stderr, "basic: can't connect to x server
%s\n",XDisplayName(NULL));
     exit(-1);
     };

  fd = open( path, O_RDONLY );
  if ( fd < 0 )
     {
     perror( "ERROR: problem opening file" );
     exit( 1 );
     };

  i = fstat( fd, &Stat_Buf );
  if ( i < 0 )
     {
     perror( "ERROR: problem reading file" );
     exit( 1 );
     };

  Size = Stat_Buf.st_size;

  if ( Size > MAX_BUFFER_SIZE )
     {
     printf( "DM Paste buffer too large (%d chars).  Only moving %d chars.\n",
                       Stat_Buf.st_size, MAX_BUFFER_SIZE );
     Size = MAX_BUFFER_SIZE;
     };

  i = read( fd, Buff, Size );
  if ( i < Size )
     {
     printf( "OOPS:  Only got %d characters from DM paste buffer\n",i );
     Size = i;
     };

  close( fd );

  XStoreBuffer( display, Buff, Size, 0 );

  p = XFetchBuffer( display, &i, 0 );
    
  XCloseDisplay(display);

}; 

**************cut here  cut here**************
/*    

x2dm.c

   Copies data from X-windows paste buffer # 0 to the DM
paste buffer.
  
*/         

#include <X11/Xlib.h>
#include <strings.h>
#include <stdio.h>                       
#include <sys/file.h>

Display *display;
char * p;  
int i;
char *path = "`node_data/paste_buffers/default.txt";

main()
{
   int fd;
   int l;

   if ( (display=XOpenDisplay(NULL)) == NULL )
     {
     fprintf(stderr, "basic: can't connect to x server
%s\n",XDisplayName(NULL));
     exit(-1);
     };

   p = XFetchBuffer( display, &l, 0 );

   fd = open( path, O_WRONLY|O_TRUNC );
   if ( fd < 0 )
      {
      perror( "ERROR: problem opening file" );
      exit( 1 );
      };
    i = lseek( fd, 0, L_SET );
    if ( i < 0 )
      {
      perror( "ERROR: problem in lseek" );
      exit( 1 );
      };
    i = write( fd, p, l );
    if ( i < 0 )
      {
      perror( "ERROR: problem writing to file" );
      exit( 1 );
      };
    if ( i < l )
      {
      printf( "OOPS:  Only put %d chars in DM buffer\n",i );
      };
    close( fd );

    XCloseDisplay (display);

};
-------------------------------------------------------------------------------
  Glen Valante                     | These are my opinions...
  Apollo / Hewlett-Packard         |    
  North American Customer Support  |
________________________________________________________________________

Date: 16 Aug 90 20:20:31 GMT
From: denis%vlsisj%practic%weitek%ubvax%vsi1
      [email-masked]  (Denis Bohm)
Organization: VLSI Technology Inc., San Jose, CA
Subject: yacp (yet another cut/paste tool for DM and X)
Message-Id: <[email-masked]>
Sender: [email-masked]
To: [email-masked]

Here is a cut/paste tool that I wrote for DM and X a while
ago.  It should be able to handle any size cut/paste buffer.
It even comes with a man page...

Denis

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	xacp.man
#	xacp.c
#	Makefile
# This archive created: Thu Aug 16 13:09:08 1990
export PATH; PATH=/bin:$PATH
if test -f 'xacp.man'
then
	echo shar: will not over-write existing file "'xacp.man'"
else
cat << \SHAR_EOF > 'xacp.man'
.TH XACP L "1990 Aug 16"
.SH NAME
xacp \- X and apollo copy/paste utility.
.SH SYNOPSIS
.B xacp
.RB [\-hu]
.RB [\-xa]
.RB [\-b <buffer number>]
.RB [\-n <buffer name>]
.RB [\-t]
.RB [\-c]
.RB [\-p <text>]
.br
.SH DESCRIPTION
.LP
.B xacp
lets you do various things with X and apollo paste buffers.  It can be used
to transfer between the X and apollo buffers, copy from X or apollo buffer
to stdout, and paste text into an X or apollo buffer.
.SH OPTIONS
Terse help information can be accessed with
.RB (\-h).
Terse usage information can be accessed with
.RB (\-u).
To select an X buffer as the primary and an apollo buffer as the secondary use
.RB (\-x),
this is the default.
To select an apollo buffer as the primary and an X buffer as the secondary use
.RB (\-a).
The X buffer number can be selected with
.RB (\-b <buffer number>).
The apollo buffer name can be selected with
.RB (\-n <buffer name>).
The operation must be one of: transfer from primary to secondary
.RB (\-t),
copy from primary to stdout
.RB (\-c),
paste text to primary
.RB (\-p <text>).
.SH USAGE
The default options are:
.nf
  xacp -x -b 0 -n default.txt -t
.fi

.SH EXAMPLES
Copy X default paste buffer to apollo default paste buffer:
.nf
example% xacp
example% xacp -x
.fi

Copy apollo default paste buffer to X default paste buffer:
.nf
example% xacp -a
.fi

Copy any X paste buffer to any apollo paste buffer:
.nf
example% xacp -x -b 1 -n line_del
.fi

Setup the apollo numeric keypad + and - keys to transfer between the default X
and apollo cut/paste buffers (you might want to do put the next two lines
in ~/user_data/startup_dm.19l):
.nf
kd np+ cpo //lodi/users/denis/bin/xacp -a ke
kd np- cpo //lodi/users/denis/bin/xacp -x ke
.fi
.SH SEE ALSO
.B xcutsel (1)
.B dm (1)
.SH BUGS
.I None.
.SH AUTHORS
Denis Bohm
SHAR_EOF
fi # end of overwriting check
if test -f 'xacp.c'
then
	echo shar: will not over-write existing file "'xacp.c'"
else
cat << \SHAR_EOF > 'xacp.c'
/*
 * Author:  Denis Bohm
 * Address: denis@vlsisj
 * Created: 21-Dec-1989
 * File:    xacp.c
 *
 * This program (xacp) allows you to transfer the contents of the
 * X and apollo copy/paste buffers.  It has options so that you can
 * choose which of the X and apollo buffers to use.  It also has
 * options so that you can just copy a buffer to stdout and paste
 * a command line argument to any buffer.  It would be nice if it
 * could also paste from stdin, but it doesn't right now.
 *
 * Users may copy, modify or distribute this file at will.
 */

#include <stdio.h>
#include <X11/Xlib.h>
#include <apollo/base.h>
#include <apollo/error.h>
#include <apollo/type_uids.h>
#include <apollo/ios.h>
#include <apollo/pbufs.h>

extern void *malloc();

void check_status (
  status_$t &status
)
{
  if (status.all != status_$ok) {
    fprintf(stderr, "xacp: ");
    error_$print(status);
    exit(1);
  }
}

void check_status_2 (
  status_$t &status,
  long exception_1,
  long exception_2
)
{
  if ((status.all != status_$ok) && (status.all != exception_1) &&
    (status.all != exception_2)) {
    fprintf(stderr, "xacp: ");
    error_$print(status);
    exit(1);
  }
}

void pbufs_open (
  char      *buffer_name,
  boolean   &type,
  ios_$id_t *stream_id,
  status_$t *status
)
{
  name_$long_pname_t path_name;

  strcpy(path_name, "/sys/node_data/paste_buffers/");
  strncat(path_name, buffer_name, name_$long_pnamlen_max - strlen(path_name));
  *stream_id = ios_$open(path_name, strlen(path_name), ios_$unregulated_opt,
    status);
}

void pbufs_create (
  char      *buffer_name,
  boolean   &type,
  ios_$id_t *stream_id,
  status_$t *status
)
{
  name_$long_pname_t path_name;

  strcpy(path_name, "/sys/node_data/paste_buffers/");
  strncat(path_name, buffer_name, name_$long_pnamlen_max - strlen(path_name));
  ios_$create(path_name, strlen(path_name), unstruct_$uid, ios_$truncate_mode,
    ios_$write_opt | ios_$unregulated_opt, stream_id, status);
}

char *apollo_copy (
  char *name,
)
{
#define BUFFER_SIZE 32

  boolean type = false;
  ios_$id_t stream_id;
  status_$t status;
  char buffer[BUFFER_SIZE + 1];
  int amount;
  int offset;
  char *text;

/* how does type work?                              */
/* why doesn't pbufs_$open work? -denis 20-Dec-1989 */
/*
  pbufs_$open(name, type, &stream_id, &status);
*/
  pbufs_open(name, type, &stream_id, &status);
  check_status(status);

  amount = 0;
  do {
    amount += ios_$get(stream_id, ios_$no_put_get_opts, buffer, BUFFER_SIZE,
      &status);
    check_status_2(status, ios_$end_of_file, ios_$buffer_too_small);
  } while (status.all != ios_$end_of_file);

  text = (char *) malloc(amount);
  ios_$seek_to_bof(stream_id, &status);
  check_status;
  offset = 0;
  do {
    offset += ios_$get(stream_id, ios_$no_put_get_opts, &text[offset],
      amount - offset, &status);
    check_status_2(status, ios_$end_of_file, ios_$buffer_too_small);
  } while (status.all != ios_$end_of_file);
  check_status;

  ios_$close(stream_id, &status);
  check_status(status);

  return text;
}

void *apollo_paste (
  char *name,
  char *text
)
{
  boolean type = false;
  ios_$id_t stream_id;
  status_$t status;
  ios_$put_get_opts_t opts = ios_$no_put_get_opts;

/* how does type work?                                */
/* why doesn't pbufs_$create work? -denis 20-Dec-1989 */
/*
  pbufs_$create(name, type, &stream_id, &status);
*/
  pbufs_create(name, type, &stream_id, &status);
  check_status(status);
  ios_$put(stream_id, opts, text, strlen(text), &status);
  check_status(status);
  ios_$truncate(stream_id, &status);
  check_status(status);
  ios_$close(stream_id, &status);
  check_status(status);
}

char *X_copy (
  int buffer
)
{
  Display *display;
  char *text;
  int bytes;

  display = XOpenDisplay(NULL);
  if (! display) {
    fprintf(stderr, "xacp: can't open %s\n", XDisplayName(NULL));
    exit(1);
  }
  text = XFetchBuffer(display, &bytes, buffer);
/*
  fprintf(stderr, "%d %d\n", bytes, strlen(text));
*/
  {
    int i;

    for (i = 0; i < bytes; i++) {
      if (text[i] == '\0') {
        text[i] = '*';
        fprintf(stderr, "\\0 found at %d (replaced with \*)\n", i);
      }
    }
  }
  XCloseDisplay(display);

  return text;
}

void X_paste (
  int buffer,
  char *text
)
{
  Display *display;

  display = XOpenDisplay(NULL);
  if (! display) {
    fprintf(stderr, "xacp: can't open %s\n", XDisplayName(NULL));
    exit(1);
  }
  XStoreBuffer(display, text, strlen(text), buffer);
  XCloseDisplay(display);
}

void print_usage(void)
{
  fprintf(stderr,
    "Usage: xacp [-h | -u] [-x | -a] [-b number] [-n name] [-t | -c | -p text]\n");
}

void print_help(void)
{
  fprintf(stderr, "Name:\n");
  fprintf(stderr, "  xacp - X and apollo copy/paste utility.\n");
  fprintf(stderr, "Options:\n");
  fprintf(stderr, "  -h           print help message\n");
  fprintf(stderr, "  -u           print usage message\n");
  fprintf(stderr, "  -x           use X paste buffer as the primary (apollo as secondary)\n");
  fprintf(stderr, "  -a           use apollo paste buffer as the primary (X as secondary)\n");
  fprintf(stderr, "  -b [number]  specify the number of the X paste buffer to use\n");
  fprintf(stderr, "  -n [name]    specify the name of the apollo paste buffer to use\n");
  fprintf(stderr, "  -t           transfer from primary to secondary\n");
  fprintf(stderr, "  -c           copy from primary to stdout\n");
  fprintf(stderr, "  -p [text]    paste text to primary\n");
  fprintf(stderr, "Default options:\n");
  fprintf(stderr, "  xacp -x -b 0 -n default.txt -t\n");
  fprintf(stderr, "Examples:\n");
  fprintf(stderr, "  Copy X default paste buffer to apollo default paste buffer:\n");
  fprintf(stderr, "    xacp -x\n");
  fprintf(stderr, "    xacp\n");
  fprintf(stderr, "  Copy apollo default paste buffer to X default paste buffer:\n");
  fprintf(stderr, "    xacp -a\n");
  fprintf(stderr, "  Copy any X paste buffer to any apollo paste buffer:\n");
  fprintf(stderr, "    xacp -x -b 1 -n line_del\n");
}

main(argc, argv)
int argc;
char **argv;
{
  extern int optind;
  extern char *optarg;
  static char *options = "vhuaxn:b:tcp:";
  char *text;
  char *name = "default.txt";
  int buffer = 0;
  int src = 'x';
  int mode = 't';
  int opt;
  int verbose = 0;

  while ((opt = getopt(argc, argv, options)) != EOF) {
    switch (opt) {
      case 'x':
      case 'a':
        src = opt;
      break;

      case 't':
      case 'c':
      case 'p':
        mode = opt;
        if (mode == 'p') {
          text = optarg;
        }
      break;

      case 'n':
        name = ((! optarg) || (optarg[0] == '\0') ? "default.txt" : optarg);
      break;

      case 'b':
        buffer = ((! optarg) || (optarg[0] == '\0') ? 0 : atoi(optarg));
        if ((0 > buffer) || (buffer > 7)) {
          fprintf(stderr,
            "xacp: illegal X buffer %d (must be between 0 and 7)\n", buffer);
        }
      break;

      case 'v':
        verbose = 1;
        break;

      case 'h':
      case 'u':
      default:
        print_usage();
        if (opt == 'u') exit(0);
        print_help();
        if (opt == 'h') exit(0);
        exit(1);
    }
  }

  if (verbose) {
    printf("xacp: src: %c, buffer: %d, name: %s\n", src, buffer, name);
    if (mode == 'p') {
      printf("xacp: text: %s\n", text);
    }
  }

  if (mode == 't') {
    if (src == 'x') {
      apollo_paste(name, X_copy(buffer));
    } else {
      X_paste(buffer, apollo_copy(name));
    }
  } else if (mode == 'c') {
    printf("%s", (src == 'x' ? X_copy(buffer) : apollo_copy(name)));
  } else if (mode == 'p') {
    if (src == 'x') {
      X_paste(buffer, text);
    } else {
      apollo_paste(name, text);
    }
  }

  exit(0);
}
SHAR_EOF
chmod +x 'xacp.c'
fi # end of overwriting check
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
all: xacp

xacp: xacp.c
	cc -g xacp.c -o xacp

install: xacp
	cp xacp /usr/local/bin/xacp

install.man:
	cp xacp.man /usr/local/man/manl/xacp.l

clean:
	rm xacp
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0

In article <[email-masked]>, [email-masked] (Glenn P. Parker) writes:
> In article <[email-masked]>,
> [email-masked] (Glen E Valante) writes:
> > In article <[email-masked]>,
> > [email-masked] (Daniel Ammon) writes:
> >>
> >> Is there anyway to get a (Bourne) shell script to bring up a file
> >> in the dm editor?  Right now I am calling vi, but I would also like
> >> to be able to bring up the editor you get when pressing the EDIT key.
> > 
> > from the shell, you can execute:
> > 
> > /com/xdmc ce <file_name>
> 
> Unfortunately, /com/xdmc only works if it is executed from an Apollo pad,
> i.e. _not_ inside an xterm.  So, your script won't be as portable if you
> use this technique.  You _can_ do the following:
> 
> /usr/bin/X11/dmwin /usr/apollo/bin/xdmc ce <absolute_path_name>
> 
> But this leaves a "scrap" DM window lying around.  Ah well, if you like the
> DM editor, you probably don't care about xterms anyway...  :-/

You can also modify the 'dmwin' source (/usr/X11/examples/dmwin) to create
an EDIT pad instead of a TRANSCRIPT pad so that it doesn't leave a "scrap"
DM window laying around.  It also creates the EDIT pad a lot faster.

Here are my modifications to DMWIN.  Note: the code is not very clean cuz
I was in a hurry.

---------------  dmedit.c  -----------------

pad_$window_desc_t      w_desc = {200,300,875,650};

main(
        int             argc,
        char            **argv,
        char            **envp
     )
{
 extern char     *optarg, *getenv(char *a);
        extern int      optind;
        status_$t       st;
        ios_$id_t       fd;
        char            **ep;
        char            sw;
        char            *infile;
        int     errflag = 0, rawflag = 0, i;

        infile = "/usr/tmp/tempfile";    /* default file if none passed */

 while ( (getopt( argc, argv, "?fh" )) != EOF )
          switch(sw)
   {
   case 'f':
           infile = argv[optind];
                  break;
          case 'h':
          case '?':
                  errflag++;
          }

   if (errflag)
          {
                fprintf( stderr, "usage: %s [-f filename]\n", argv[0] );
                exit(2);
          }

   /* create an edit pad */
   pad_$create_window (infile, (short)strlen(infile), pad_$edit, 1, w_desc, &fd, &st);
   if (st.all != status_$ok) {
                fprintf (stderr, "%s: could not create window\n", argv[0]);
                exit (1);
          }

        close (fd);
        exit (1);
}

> --
> --------------------------------------------------------------------------
> Glenn P. Parker        Bitstream, Inc.
> uunet!huxley!glenn     215 First Street
> [email-masked]    Cambridge, MA 02142-1270

Enjoy!

-- 
Scott Schneider                  
Boeing Commercial Airplane
[email-masked]