From: cmcmanis@pepper.Eng.Sun.COM (Chuck McManis)
Newsgroups: comp.sys.amiga.programmer
Subject: Re: Console RAW mode.
Date: 31 Dec 1992 07:37:13 GMT
Organization: Sun
NNTP-Posting-Host: pepper

Some very old code that did this at one time for SAS/C programs.

Newsgroups: comp.sys.amiga
Subject: Re: MsgPorts, DOS, ACTION_SCREEN_MODE help needed
Summary: 
Expires: 
Reply-To: cmcmanis@sun.UUCP (Chuck McManis)
Followup-To: 
Distribution: 
Organization: Sun Microsystems, Mountain View
Keywords: 

In article <378NU105451@NDSUVM1> NU105451@NDSUVM1.BITNET (Walter Reed) writes:
>I am working on a version of MicroEmacs that would support either opening
>a new window or useing the current window and setting its mode to RAW.

The following code I cooked up (pun intended) to emulate the curses functions
for putting the console into raw() or cooked() (they call it noraw()) modes.
Note that it depends on knowing how the structure FILE * stores the internal
amiga file handle. If someone would port it to Aztec C and post it that would
be appreciated. Anyway, it's short so I'll include it here. It's a shar
file so cut off the message and feed it to the unix shell, or the Amiga
shar program (shar -u) available on one of the Fish disks.

--Chuck
#       This is a shell archive.
#       Remove everything above and including the cut line.
#       Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#       Run the following text with /bin/sh to create:
#       testraw.c
#       raw.c
#       sendpacket.c
# This archive created: Tue Jun 16 01:47:01 1987
cat << \SHAR_EOF > testraw.c
/*
 *       testraw.c
 *
 *   This program shows how to use the functions raw() and cooked() to
 * control the way characters are read from a Level 2 file pointer.
 * These are only useful if the file pointer points at an instance of
 * the console.device, which means one of 'stdin', 'stdout', or 'stderr'
 * or a console opened with fp = fopen("CON:x/y/wid/len/Title","w+");
 * like this example does. 
 *
 * Written : 16-Jun-87 By Chuck McManis, do with it what you will.
 *
 */

#include <stdio.h>
#ifndef u_char
#define u_char  unsigned char
#endif

void main()
 
{
  FILE  *win;
  char  c;
  long  i;

  printf("This program shows how to use raw mode file pointers.\n");
  printf("First we open the window...\n");
  win = fopen("CON:10/10/400/100/Test Console","w+");
  setnbf(win); /* This is IMPORTANT, set file pointer to 'unbuffered' */
  fprintf(win,"Using the default mode, type some characters ... \n");  
  i = 0;
  while ((c = fgetc(win)) != 'Q') {
    i = (i + 1) % 25;
    if (i == 0) printf("\n");
    printf(" %02x",(u_char) c);
  }
  printf("\n************\n");
  fprintf(win,"Now switching to 'raw' mode ...\n");
  if (raw(win) != 0) perror("raw");
  i = 0;
  while ((c = fgetc(win)) != 'Q') {
    i = (i + 1) % 25;
    if (i == 0) printf("\n");
    printf(" %02x",(u_char) c);
  }
  printf("\n************\n");
  fprintf(win,"Now back to 'cooked' mode ... \n");
  if (cooked(win) != 0) perror("cooked");
  i = 0;
  while ((c = fgetc(win)) != 'Q') {
    i = (i + 1) % 25;
    if (i == 0) printf("\n");
    printf(" %02x",(u_char) c); 
  }
}
SHAR_EOF
cat << \SHAR_EOF > raw.c 
/* 
 *      raw.c
 *
 *    This is a routine for setting a given stream to raw or cooked mode.
 * This is useful when you are using Lattice C to produce programs that
 * want to read single characters with the "getch()" or "fgetc" call.
 *
 * Written : 18-Jun-87 By Chuck McManis. 
 *           If you use it I would appreciate credit for it somewhere.
 */
#include <exec/types.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#include <ios1.h>
#include <error.h>

/* New Packet in 1.2 */
#define ACTION_SCREEN_MODE      994L

extern  int     errno;          /* The error variable */
 
/*
 * Function raw() - Convert the specified file pointer to 'raw' mode. This
 * only works on TTY's and essentially keeps DOS from translating keys for
 * you, also (BIG WIN) it means getch() will return immediately rather than
 * wait for a return. You lose editing features though.
 */
long
raw(fp)

FILE *fp;
 
{
  struct MsgPort        *mp; /* The File Handle message port */
  struct FileHandle     *afh;
  struct UFB            *ufb;
  long                  Arg[1],res;

  ufb = (struct UFB *) chkufb(fileno(fp));  /* Step one, get the file handle */
  afh = (struct FileHandle *)(ufb->ufbfh); 

  if (!IsInteractive(afh)) {    /* Step two, check to see if it's a console */
    errno = ENOTTY;
    return(-1);
  }
                              /* Step three, get it's message port. */
  mp  = ((struct FileHandle *)(BADDR(afh)))->fh_Type;
  Arg[0] = -1L;
  res = SendPacket(mp,ACTION_SCREEN_MODE,Arg,1); /* Put it in RAW: mode */
  if (res == 0) {
    errno = ENXIO;
    return(-1);
  }
  return(0);
}
 
/*
 * Function - cooked() this function returns the designate file pointer to
 * it's normal, wait for a <CR> mode. This is exactly like raw() except that
 * it sends a 0 to the console to make it back into a CON: from a RAW:
 */

long
cooked(fp)
 
FILE *fp;
 
{
  struct MsgPort        *mp; /* The File Handle message port */
  struct FileHandle     *afh;
  struct UFB            *ufb;
  long                  Arg[1],res;
 
  ufb = (struct UFB *) chkufb(fileno(fp));
  afh = (struct FileHandle *)(ufb->ufbfh);
  if ( ! IsInteractive(afh)) {
    errno = ENOTTY;
    return(-1);
  }
  mp  = ((struct FileHandle *)(BADDR(afh)))->fh_Type;
  Arg[0] = 0;
  res = SendPacket(mp,ACTION_SCREEN_MODE,Arg,1);
  if (res == 0) {
    errno = ENXIO;
    return(-1);
  }
  return(0);
}
SHAR_EOF
cat << \SHAR_EOF > sendpacket.c
/*
 *      Sendpacket.c 
 *
 *  An invaluable addition to your Amiga.lib file. This code sends a packet
 * the given message port. This makes working around DOS lots easier.
 * 
 * Note, I didn't write this, those wonderful folks at CBM did. I do suggest
 * however that you may wish to add it to Amiga.Lib, to do so, compile it
 * and say 'oml lib:amiga.lib -r sendpacket.o' 
 */

#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
 
/*
 * Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and
 * Andy Finkel. This function will send a packet of the given type to the
 * Message Port supplied.
 */
 
long
SendPacket(pid,action,args,nargs)
 
struct MsgPort *pid;  /* process indentifier ... (handlers message port ) */
long action,          /* packet type ... (what you want handler to do )   */
     args[],          /* a pointer to a argument list */
     nargs;           /* number of arguments in list  */
{
  struct MsgPort        *replyport;
  struct StandardPacket *packet;
 
  long  count, *pargs, res1;
 
  replyport = (struct MsgPort *) CreatePort(NULL,0);
  if(!replyport) return(0);
 
  /* Allocate space for a packet, make it public and clear it */
  packet = (struct StandardPacket *) 
    AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
  if(!packet) {
    DeletePort(replyport);
    return(0);
  }
 
  packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
  packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);
  packet->sp_Pkt.dp_Port         = replyport;
  packet->sp_Pkt.dp_Type         = action;
 
  /* copy the args into the packet */
  pargs = &(packet->sp_Pkt.dp_Arg1);       /* address of first argument */
  for(count=0;count < nargs;count++) 
    pargs[count]=args[count];
 
  PutMsg(pid,packet); /* send packet */

  WaitPort(replyport);
  GetMsg(replyport); 
 
  res1 = packet->sp_Pkt.dp_Res1;
 
  FreeMem(packet,(long)sizeof(struct StandardPacket));
  DeletePort(replyport); 

  return(res1);
}
SHAR_EOF
#       End of shell archive
exit 0
--
--Chuck McManis			    Mr. NIS+			    Sunsoft
uucp: {anywhere}!sun!cmcmanis   BIX: <none>   Internet: cmcmanis@Eng.Sun.COM
These opinions are my own and no one elses, but you knew that didn't you.