benten@tigger.UUCP (Muhammad S. Benten) (11/07/88)
Posting-number: Volume 5, Issue 33 Submitted-by: "Muhammad S. Benten" <benten@tigger.UUCP> Archive-name: 3b1tools [Aside from some wishful thinking wrt. process stopping via ptrace (BSD, anyone? ;-) it almost makes me wish I hadn't sold the 3B1.... ++bsa] This posting contains the sources for a tool for the AT&T Unix-pc. It is called "3b1tools". It will allow Unix-pc users to do less! than what Sun users do with suntools. Thanks. ============================================================================ || Muhammad S. Benten | || Elect. & Comp. Eng. Dept. | || University of Colorado, Boulder | || | || email ----> benten@boulder.Colorado.EDU | || or ..{ncar|nbires}!boulder!benten | ============================================================================ ----------------------------Cut here---------------------------------------- #! /bin/sh # # Wrapped by tigger!benten on Tue Nov 1 14:07:53 MST 1988 # # 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: # # Contents: 3b1tools.c 3b1tools.doc 3b1tools.h Makefile README nkbd.c.patch # picture.c tools.c echo x - 3b1tools.c sed 's/^@//' > "3b1tools.c" <<'@//E*O*F 3b1tools.c//' /* 3b1tools.c - This file parses the command argument and performs ** all "windy" related processing. It will then call ** the icon handler. ** ** Copyright (C) 1988 by Muhammad S. Benten. ** benten@boulder.colorado.edu ** ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. ** ** ** A major portion of this file is extracted from the program windy ** which is available from "The STORE" with its sources. ** It will preserve most of windy's arguments. */ #include "3b1tools.h" #define NA 0xffff struct uwdata xuw = { NA, NA, NA, NA, NA}; struct utdata xut[WTXTNUM]; int bflag = 0; int Kflag = 0; char blot[81]; char *ttyname(); char * filenam; extern struct termio argg; extern char *optarg; extern int optind; main(ac,av) int ac; char **av; { int nflag = 0; char avname[256]; char *env,cavname[256]; int i, c,rows,cols,pid; FILE * ifd; ioctl(Wn,TCGETA,&argg); cols = 0; rows = 0; maxw = 672; maxh = 288; invert = 0; iconopen = 0; transpose = 0; if ( ac == 1 ) { /* no argument, get commands */ strcat(avname,".3b1tool"); if ( (ifd = fopen( avname, "r" )) != NULL) { startup(ifd,av); exit(0);} else { strcpy(avname,getenv("HOME")); strcat(avname,"/.3b1tool"); if ( (ifd = fopen( avname, "r" )) != NULL) { startup(ifd,av); exit(0);} else { printf("3b1tools: File .3b1tool doesn't exist\n3b1tools: Use 3b1tools -S for full screen shell\n"); exit(1); }}} else { ifd = (FILE *) -1; while((c = getopt(ac, av, "robSRTp:c:l:u:1:2:n:f:h:w:x:y:K:X:Y:I:W:H:")) != EOF) { switch(c) { case 'b':{ bflag++; break;} case 'h':{ xuw.uw_height = atoi(optarg); break;} case 'w':{ xuw.uw_width = atoi(optarg); break;} case 'x':{ xuw.uw_x = atoi(optarg); break;} case 'y':{ xuw.uw_y = atoi(optarg); break;} case 'f':{ xuw.uw_uflags = htoi(optarg); xuw.uw_uflags &= ~NOSETUFLAGS; break;} case 'p': utset(WTXTPROMPT, optarg);{ break;} case 'c':{ utset(WTXTCMD, optarg); break;} case 'l':{ utset(WTXTLABEL, optarg); break;} case 'n': case 'u':{ nflag = 1; utset(WTXTUSER, optarg); break;} case '1':{ utset(WTXTSLK1, optarg); break;} case '2':{ utset(WTXTSLK2, optarg); break;} case '?':{ fprintf(stderr, "usage: 3b1tools [args] [command-args]\n"); exit(2);} case 'K':{ strncpy(blot, optarg, 80); Kflag ++; break;} case 'I': { /* image file name */ if ( optarg[0] == '-' ) { ifd = stdin;} else { ifd = fopen( optarg, "r" ); if ( ifd == NULL ) { fprintf( stderr, "Image %s: can't open.\n", optarg); exit( 1 ); } filenam = optarg;} break;} case 'W': { /* overwrite image height */ cols = atoi(optarg); break;} case 'H': { /* overwrite image width */ rows = atoi(optarg); break;} case 'X': { /* icon width */ maxw = atoi(optarg); if (maxw > 672 ) maxw = 672; break;} case 'Y': { /* icon height */ maxh = atoi(optarg); if (maxh > 288 ) maxh = 288; break;} case 'R': { /* reverse image */ invert++; break;} case 'o': { /* start with an open window */ iconopen++; break;} case 'r': { /* start with an open window */ normal++; break;} case 'S':{ xuw.uw_x = 0; xuw.uw_y = 12; xuw.uw_width = 720; xuw.uw_height = 288; xuw.uw_uflags = 0x1; break;} case 'T': { /* transpoe icon */ transpose++; break;}} }} /* * if gave command args, put it in a new window * if gave window args, or no args at all, change window params */ if(optind < ac) { if( bflag) newwind(); avname[0] = 0; for(i=optind; i<ac; i++) { strcat(avname, av[i]); strcat(avname, " "); } if( bflag) if(!nflag) utset(WTXTUSER, avname); } fixwind(); if(bflag) { pid = fork(); if(pid > 0) exit(1); else if(pid == 0) { setpgrp(); ioctl(0, WIOCPGRP); } } icon_exec(av,rows,cols,ifd); exit(0); } utset(n, s) char *s; { xut[n].ut_num = 1; strncpy(xut[n].ut_text, s, WTXTLEN); } newwind() { char name[10]; struct termio t; int bad = 0, i, fd; if (!isatty(0)) return; if(strncmp("/dev/w", ttyname(0), 6)!=0 ) return; if (ioctl(0, TCGETA, &t) < 0) { perror("getting tty chars"); bad = 1; } fd = open("/dev/window",2); if (fd < 0) { perror("opening window"); return; } if(bflag) { ioctl(fd, WIOCSELECT); sprintf(name, "[w%d]\n", ioctl(fd, WIOCGCURR)); write(0, name, strlen(name)); } close(0); dup(fd); close(1); dup(fd); close(2); dup(fd); close(fd); /* Set in the previous edit characters to the new window */ if (!bad && ioctl(0, TCSETAF, &t) < 0) perror("setting tty chars"); for (i=0; environ[i]; ++i) { if (!strncmp(environ[i],"TERMCAP=",8)) { environ[i] = "TERMCAP=/etc/termcap"; } if (!strncmp(environ[i],"TERM=",5)) { environ[i] = "TERM=s4"; } } } fixwind() { struct uwdata uw; int i; if(Kflag) { xut[WTXTSLK1].ut_num = WTXTSLK1; xut[WTXTSLK2].ut_num = WTXTSLK2; keyfix(xut[WTXTSLK1].ut_text); keyfix(xut[WTXTSLK2].ut_text); } for(i=0; i<WTXTNUM; i++) { if(xut[i].ut_num) { xut[i].ut_num = i; ioctl(0, WIOCSETTEXT, &xut[i]); } } ioctl(0, WIOCGETD, &uw); if(xuw.uw_x != NA) {uw.uw_x = xuw.uw_x;new_wind++;} if(xuw.uw_y != NA) {uw.uw_y = xuw.uw_y;new_wind++;} if(xuw.uw_width != NA) {uw.uw_width = xuw.uw_width;new_wind++;} if(xuw.uw_height != NA) {uw.uw_height = xuw.uw_height;new_wind++;} if(xuw.uw_uflags != NA) {uw.uw_uflags = xuw.uw_uflags;new_wind++;} ioctl(0, WIOCSETD, &uw); } keyfix(s) char *s; { int c, i; for(i=0; i<80; i++) { c = s[i] & 0177; if(c == 0) c = ' '; switch(blot[i]) { case ' ': case 0: c = ' '; break; case 'r': case 'R': c |= 0200; break; } s[i] = c; } } char *utname[] = { "Prompt line", "Command line", "Label", "User", "SLK1", "SLK2", }; report(s) char *s; { struct uwdata uw; struct utdata ut; int i; printf("%s: ", s); ioctl(0, WIOCGETD, &uw); uwshow(&uw, (char *)0); for(i=0; i<WTXTNUM; i++) { ut.ut_num = i; ioctl(0, WIOCGETTEXT, &ut); if(ut.ut_text[0]) { printf("%s=<%.81s>\n", utname[i], ut.ut_text); } } } uwshow(p, s) struct uwdata *p; char *s; { printf("(x,y)=(%d,%d) ", p->uw_x, p->uw_y); printf("(width,height)=(%d,%d) ", p->uw_width, p->uw_height); printf("flags=%x\n ", p->uw_uflags); printf("(hs,vs)=(%d, %d)[RO] ", p->uw_hs, p->uw_vs); printf("baseline=%d[RO] ", p->uw_baseline); printf("(cx,cy)=(%d, %d)[RO]\n", p->uw_cx, p->uw_cy); } htoi(s) char *s; { int x = NA; sscanf(s, "%x", &x); return x; } startup(ifi,argv) int ifi; char *argv; { char cavname[256],avname[256],*sy; while ( fgets(avname,256,ifi) != 0 ) { cavname[0] =0; strcat(cavname,avname); sy = (char *) strtok(avname," "); if ( sy[0] != 0 ) if ( strncmp(sy,"3b1tools",5) !=0 ) { avname[0] =0; strcat(avname,cavname); strcpy(cavname , "3b1tools -b "); strcat(cavname,avname); system(cavname);} else{ printf("3b1tools: error in .3b1tool file\n"); printf("3b1tools: in %s\n",avname); printf("3b1tools: only arguments to 3b1tools are specified\n");}} close(ifi); } @//E*O*F 3b1tools.c// chmod u=rw,g=r,o=r 3b1tools.c echo x - 3b1tools.doc sed 's/^@//' > "3b1tools.doc" <<'@//E*O*F 3b1tools.doc//' 3b1tools 1 draft Name: 3b1tools - A Unix-pc windowing environment and image display tool. Copyright (c) 1988 by Muhammad S. Benten. Author: Muhammad S. Benten University Of Colorado Electrical & Computer Engineering Boulder, Co 80309 Usage: 3b1tools [-b] [-S] [-o] [-I <icon>] [-R] [-T] [-X nnn] [-Y nnn] [-H nnn] [-W nnn] [-x nnn] [-y nnn] [-h nnn] [-w nnn] [-n <string>] [-1 <string>] [-2 <string>] [-p <string>] [-c <string>] [-f <hex>] [-l <string>] [-K <string>] [ <command> [ <arguments>]] Description: 3b1tools is a general purpose windowing program designed to utilize the capabilities of the Unix-pc. It replaces the functionality of the program "windy", and can also be used as a general purpose image and icon display tool. The borders of a displayed icon, can be toggled on/off by the middle mouse button, B2. It can also be toggled by the function keys F2 or F7. You can open an icon by using the left mouse button B1, or using the functions keys F1 or F6. To exit and destroy an icon, you can use the right mouse button B3, or the function keys, F3 or F8. A confirmation will be requested when you destry an icon. Icons displayed using 3b1tools can be scrolled up, down, left and right using the scroll indicators on the icon borders. The size of the icon can also be controlled by the user through the -X and -Y options . A closed icon is either idle or stopped. A stopped icon can be resumed by the function key F1 in which case the screen would be restored and execution of the stopped command continues. Opening an idle icon would restore the screen to its last state before the icon was either created or closed and the execution of the command argument is attempted. This execution can be stopped at any point by the stop key ( CTRL-Z ). In this case the execution of the command would stop and the icon will close in a stopped state. There are five modes of operation in 3b1tools which can be specified by the options used to invoke 3b1tools. These modes are: mode-1: no command argument and no -b option In this mode, 3b1tools will close the invoking window saving its contents and display an icon as specified by the -I option. It will display a default icon if no icon is specfied. Note that the -S option must be specified if no argument is given to 3b1tools. Example: 3b1tools -I girls mode-2: no -b option but a command and its arguments are supplied In this mode, 3b1tools will close the invoking window saving its contents and display an icon as specified by the -I option. It will display a default icon if no icon is specfied. Upon exiting the executing command, the window will be closed and the icon is displayed again. You can also start with an open window executing the command argument by specifying the -o 3b1tools 2 draft option which will be iconified when the command terminates. Example: 3b1tools -I office ua mode-3: no command argument and a -b option This is similar to mode-1, except that the original window is left intact and the icon is displayed in a new window. Example: 3b1tools -b -I girls mode-4: with a command argument and a -b option This is similar to mode-2, except that the original window is left intact and the icon and its execution window will occupy a new window. Example: 3b1tools -b -I moon vi mode-5: no arguments at all. In this mode, 3b1tools will search for the file ./.3b1tool. If this file doesn't exist it searches for the file $HOME/3b1tool. If this file is not found 3b1tools will terminate with an error message. In this mode, 3b1tools expects the lines of either of these files to conain arguments for 3b1tools that will be executed with the -b option. Example: command: 3b1tools The file .3b1tool contain: -I horse ls -l -I dog ua options: -b dettach the new icon-window from the parent process. 3b1tools will create a new window. -S This flag is usefull only if it is the only argument to 3b1tools. It will expand the current window into full screen without executing commands from ~/.3b1tool or .3b1tool. 3b1tools 3 draft -o This option will instruct 3b1tools to start with an opened window. 3b1tools will default to a closed window (iconified). -I <icon> Use the file <icon> as the image file for the icon when the window is closed.a If <icon> is in a cbm (compact bitmap) format, height and width are taken from the file, if it isn't, they must be specified by the -H -W option. -R Reverse the bits in the displayed icon. -T Transpose the image of the icon. (not implemented). -X nnn Let the displayed width of the icon be nnn. -Y nnn Let the displayed height of the icon window be nnn. -W nnn Override the picture pixcell width to be nnn. -H nnn Override the picture pixcell height to be nnn. -w nnn Let the displayed width of the execution window be nnn. -h nnn Let the displayed height of the execution window window be nnn. -x nnn Position the icon and its execution window at x=nnn -y nnn Position the icon and its execution window at y=nnn -n <string> Use <string> as the name of the window as displayed by the window manager. -l <string> Use <string> as the window label. -1 <string> Use <string> as the string that will appear in the first line of the function keys lables. -2 <string> Use <string> as the string that will appear in the second 3b1tools 4 draft line of the function keys lables. -K <string> Use <string> as the pattern for the function keys lables. An "r" in <string> means reverse vedio at that position. -c <string> Display <string> in the command line. -p <string> Display <string> in the prompt line. -f <hex> Use <hex> as the flag that control the shape of the execution window. command [<arguments>] Any unix command and its arguments that will be executed when the icon is opened. @//E*O*F 3b1tools.doc// chmod u=rw,g=r,o=r 3b1tools.doc echo x - 3b1tools.h sed 's/^@//' > "3b1tools.h" <<'@//E*O*F 3b1tools.h//' #include <termio.h> #include <sys/window.h> #include <stdio.h> extern int maxw,maxh; extern int invert; extern int transpose; extern int iconopen; extern int normal; extern int new_wind; extern int Wn; extern char **environ; @//E*O*F 3b1tools.h// chmod u=rw,g=r,o=r 3b1tools.h echo x - Makefile sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//' MAKEINC=/usr/include include $(MAKEINC)/Makepre.h OBJ=tools.o picture.o 3b1tools.o all: $(OBJ) $(LD) $(LDFLAGS) $(SHAREDLIB) $(OBJ) $(LIBM) -o 3b1tools include $(MAKEINC)/Makepost.h @//E*O*F Makefile// chmod u=rw,g=rw,o=rw Makefile echo x - README sed 's/^@//' > "README" <<'@//E*O*F README//' /* 3b1tools ** ** ** ** Copyright (C) 1988 by Muhammad S. Benten. ** benten@boulder.colorado.edu ** ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. ** ** ** ** */ This program was originally written to display AT&T demo graphics on the Unix-pc. It was later on modified to display Compact BitMap (CBM) files, which opened the machine to a huge number of icon editors and raytracers. The program close.c triggered the idea of closing windows to a graphical icon. This idea was then modified to start with this program that can be opened to an executing window. It used to be invoked with "windy" for the purpose of detaching it from the invoking shell. With the availability of windy's sources I couldn't resist incorporating the whole shpang as a single tool that I called "pctools". Due to a name conflict, this was then renamed "3b1tools". The posting of the executable of this program provided me with great suggestions about the user interface and the choice of interaction keys. With some head knocking I decided to search for a way to suspend windows. I then wrote my own primitive keyboard device driver, which I then realized that it will interfere with both CAPSCTRL loadable device driver and the "keyfix" programs. I then though of using Ditto's kbd driver with minimal changes to support the interception of the suspend key and passing it to 3b1tools. The program as it stands now works fine and does most of what Sun's suntools (c) does. However, some minor problems may result from the way processes are suspended. This program suspends processes executing in 3b1tools windows in a trace mode (ptrace(2)). These processes when resumed will report their status to their parents through the wait(2) call. Thus, parent processes that call wait(2) and only check for signals wakeup otherwise they assume the child is dead will be executing with their children when the child is resumed. In this situation both the parent and its child will be competing for the keybord input. If the child wins this should present no problem, however, if the parent wins you may want to do something about. Enjoy using this tool and I'll try to respond to questions and bug reports. I also would like to hear about any modifications or enhancement to 3b1tools. It was my baby, but it has grown enough to fight its way by itself. You will need -=> Ford <=- CAPCTRL sources to be able to use the suspension feature of 3b1tools. The patches to the file nkbd.c are included in the file nkbd.c.patch. ** Copyright (C) 1988 by Muhammad S. Benten. ** benten@boulder.colorado.edu ** ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. @//E*O*F README// chmod u=rw,g=r,o=r README echo x - nkbd.c.patch sed 's/^@//' > "nkbd.c.patch" <<'@//E*O*F nkbd.c.patch//' 78a79 > 516,524d516 < < /* changes required for 3b1tools */ < if ( tp->t_cc[7] == 253 ) < if ( ch == 26 ) { < tp->t_cc[7] = 254; < return; < } < /* end changes required for 3b1tools */ < @//E*O*F nkbd.c.patch// chmod u=rw,g=r,o=r nkbd.c.patch echo x - picture.c sed 's/^@//' > "picture.c" <<'@//E*O*F picture.c//' /* picture.c - reads a compact bitmap and converts it into the Unix-pc ** format. ** ** Copyright (C) 1988 by Muhammad S. Benten. ** benten@boulder.colorado.edu ** ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. */ #include <stdio.h> /* default icon */ short deflt[]={ -1, -1, 1, -32768, -63, -30721, 1729, -27136, 193, -27136, 193, -27136, 193, -27136, 193, -27136, 193, -27136, 193, -27136, 193, -27136, 193, -29184, -159, -29185, -127, -30721, 16385, -32760, 32705, -24592, -31, -24577, -31, -28673, -31, -28673, 1, -32768, 1, -32768, 1, -32768, 1, -32768, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; extern char * filenam; extern int transpose; icon_exec(comm,rows,cols,ifd) char **comm; FILE *ifd; int rows, cols; { char engl[256]; char *bits; char tst,cbm; int i,index1, row, col,byte1,cols1,rows1; /* Was there an icon file specified? */ if (ifd != ((FILE *) -1) ) { /* Oh, yeh! Is it a Compact BitMap? */ if ( (tst = getc( ifd ) ) == 42 ){ if ( getc( ifd ) == 23 ) { cbm = 1; cols1 = getc( ifd ) << 8; cols1 += getc( ifd ); rows1 = getc( ifd ) << 8; rows1 += getc( ifd ); if (cols == 0) cols = cols1; if (rows == 0) rows = rows1; cols = cols /8; }} else /* Or is it Unix-pc raw BitMap? */ { cbm = 0; if ( ( rows == 0) || (cols == 0)){ printf("3b1tools: You must specify width and height. This is a raw icon!"); exit(1);} cols = cols/8; } rows = (rows/8)*8; bits = (char *) malloc(cols*rows) ; for (col = 0; col <= cols ; col++) for(row = 0; row < rows ; row += 2) /* handle CBM format ===> Unix-pc */ if (cbm == 1) { byte1 = 0; tst = getc( ifd ); /* flip the high byte */ if (tst & 0x1) byte1 |= 0x80; if (tst & 0x2) byte1 |= 0x40; if (tst & 0x4) byte1 |= 0x20; if (tst & 0x8) byte1 |= 0x10; if (tst & 0x10) byte1 |= 0x8; if (tst & 0x20) byte1 |= 0x4; if (tst & 0x40) byte1 |= 0x2; if (tst & 0x80) byte1 |= 0x1; bits[col*rows + (row+1)] = byte1; byte1 = 0; tst = getc( ifd ); /* flip the the low byte */ if (tst & 0x1) byte1 |= 0x80; if (tst & 0x2) byte1 |= 0x40; if (tst & 0x4) byte1 |= 0x20; if (tst & 0x8) byte1 |= 0x10; if (tst & 0x10) byte1 |= 0x8; if (tst & 0x20) byte1 |= 0x4; if (tst & 0x40) byte1 |= 0x2; if (tst & 0x80) byte1 |= 0x1; bits[col*rows + row] = byte1;} else /* It is already in Unix-pc format */ if ( col == 0 && row == 0) { bits[1] = tst; bits[0] = getc(ifd); } else { bits[col*rows + (row+1)] = getc(ifd); bits[col*rows + row] = getc(ifd); } fclose(ifd); } else /* use the built in (default) icon */ { cols = 4; rows = 32; bits = (char *) deflt; } /* transpose the bitmap */ if ( transpose ) { /* Not implemented. A1:Why? A2:very slooow. A1:But only for big pictures, isn't it? A2:Any way, who wants to transpose a small icon? A1:I do. A2:Go ahead and do it then. transpose_bits ( bits , rows , cols); i = rows/8; rows = cols*8; cols = i; */ } /* invoke the window manager in tools.c */ windowinit( comm,bits, cols , cols*8 ,rows); exit( 0 ); } @//E*O*F picture.c// chmod u=rw,g=r,o=r picture.c echo x - tools.c sed 's/^@//' > "tools.c" <<'@//E*O*F tools.c//' /* tools.c - Displays, opens, closes and resumes an icon. ** ** ** Copyright (C) 1988 by Muhammad S. Benten. ** benten@boulder.colorado.edu ** ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. ** ** */ # include <sys/ioctl.h> # include <signal.h> # include <sys/mouse.h> # include <kcodes.h> # include <message.h> # include "3b1tools.h" #define up 196 #define down 197 #define left 190 #define right 204 #define xdelta 40 #define ydelta 20 #define XMAX1 uwidth #define YMAX1 uheight /* inside the window */ #define XMAX uw.uw_width /* in pixels */ #define YMAX uw.uw_height /* in pixels */ #define BPERBY 8 /* bits per byte */ #define XMAXB ((XMAX+(BPERBY-1))/BPERBY) /* in bytes */ #define YMAXB YMAX /* same as pixels */ extern unsigned short patwhite[]; int Wn=1; int new_wind1; int new_wind; int maxw; int maxh; int transpose; int invert; int bord_flag; int iconopen=0; int normal=0; unsigned isig=0; short done=0; int statch; struct uwdata uw; /* current window data */ struct uwdata Suw; /* Saved window data */ struct uwdata Puw; /* Saved window data */ struct uwdata suw; /* Saved window data */ struct urdata urt; unsigned short Bitmap[ 15660 ]; /* Saved screen */ unsigned short Bitmap1[ 15660 ]; /* Saved screen */ struct umdata mouse; struct umdata mouse1; struct termio argg; struct termio argg1; struct termio argg2; struct termcb argcb; int xstart,ystart,width,height,uwidth,uheight; struct utdata sut[6]; struct utdata suti[6]; int (*intsig)(),(*quitsig)(); int closeit(); int sendit(); int frk=1; int pid=-9; int pppid,ppid; extern char *optarg; extern int optind; /* ** save the window state and close window ** then go and wait for user response */ windowinit(comm,ico,wid,wid1,hit1) char * ico, **comm; int wid,wid1,hit1; { int i; /* save original parameters */ if ( ioctl( Wn, WIOCGETD, &uw) != 0 ) { fprintf(stderr, "Can't close a non-window.\n"); exit(1); } winit(); keypad(0,1); /* save the bitmap */ new_wind = wrastop(Wn, 0,0, Bitmap, XMAXB, 0,0, 0,0, XMAX, YMAX, SRCSRC, DSTSRC, 0 ); new_wind1 = wrastop(Wn, 0,0, Bitmap1, XMAXB, 0,0, 0,0, XMAX, YMAX, SRCSRC, DSTSRC, 0 ); /* save the window state */ Suw = uw; Puw = uw; suw = uw; /* save USER texts */ for ( i=0; i<6 ; i++) { sut[i].ut_num=i; suti[i].ut_num=i; ioctl(Wn,WIOCGETTEXT,&sut[i]); ioctl(Wn,WIOCGETTEXT,&suti[i]); } sprintf(suti[WTXTCMD].ut_text,"Press CTRL-Z to close window"); /* Turn cursor off */ fprintf(stderr, "\033[=1C" ); /* set up function keys */ wslk(Wn, 0, " OPEN TOGGLE EXIT B1 TO B2 TO ", " BORDER OPEN TOGGLE EXIT"); /* set icon limits */ xstart=0; ystart=0; width = wid1; height = hit1; if (wid1 > maxw ) wid1 = maxw; if (hit1 > maxh ) hit1 = maxh; uwidth = wid1; uheight = hit1; bord_flag = 1; /* close window */ iconify(ico,wid,wid1,hit1); ioctl(Wn, WIOCGETMOUSE, &mouse); ioctl(Wn, WIOCGETMOUSE, &mouse1); mouse.um_flags = MSDOWN; ioctl(Wn, WIOCSETMOUSE, &mouse); manage_window(ico,wid,comm); } /* ** Turn the window into an "icon". */ iconify(ico,wid,wid1,hit1) char * ico; int wid,wid1,hit1; { int i; uw = suw; if (done != 1) { if ( bord_flag ) { uw.uw_uflags |= NBORDER ; } else { uw.uw_uflags &= ~(NBORDER); uw.uw_uflags |= BORDHSCROLL ; uw.uw_uflags |= BORDVSCROLL ; } uw.uw_height = hit1; uw.uw_width = wid1; ioctl( Wn, WIOCSETD, &uw ); done=1;} urt.ur_srcbase = (unsigned short *) ico; urt.ur_srcwidth = wid; urt.ur_height = 1; urt.ur_width = wid1; urt.ur_srcx = xstart; if (invert) { urt.ur_srcop = SRCXOR; urt.ur_pattern = patwhite; } for (i =0 ; i < hit1 ; i++) { urt.ur_srcy = ystart+i; urt.ur_dsty = i; ioctl( Wn, WIOCRASTOP, &urt ) ;} } /* ** Restore the window to the saved size and state. */ restore_window(restore) int restore; { int i; if (restore) { uw = Suw; ioctl( Wn, WIOCSETD, &uw ); if (new_wind >= 0) wrastop(Wn, Bitmap, XMAXB, 0,0, 0,0, 0,0, XMAX, YMAX, SRCSRC, DSTSRC, 0 ); /* position cursor and turn it on */ fprintf(stderr, "\033[10;8H\033[=0C"); } /* restore USER texts */ for (i=0; i<6;i++) { sut[i].ut_num=i; ioctl(Wn,WIOCSETTEXT,&sut[i]); } if (restore) { if ( pid > 0 ) kill(pid,9); kill(pppid,9); wexit( 0 ); } } manage_window(ico, wid,com1) unsigned short *ico; int wid; char **com1; { int c,cc; int x,y,b,r,io,i; ppid = getpid(); ioctl(Wn,TCGETA,&argg1); intsig = signal ( SIGINT , sendit ); quitsig= signal ( SIGQUIT , sendit ); (void) signal ( SIGTRAP , SIG_IGN ); (void) signal ( SIGUSR2 , sendit ); /* spawn a daemon process that would tell us if a CTRL-Z is caught */ if ( (pppid =fork()) == 0 ) { (void) signal ( SIGUSR2 , closeit ); /* It should have no control over the window */ setpgrp(); loop: /* sleep until the window is opened */ pause(); /* take short naps until a suspend key is pressed */ ioctl(0,TCGETA,&argg); while ( argg.c_cc[7] != 254 ) { sleep(1); ioctl(0,TCGETA,&argg); } /* tell the parent about it and go back to sleep */ argg.c_cc[7] = 0; ioctl(0,TCSETA,&argg); kill ( ppid , SIGUSR2 ); goto loop; } /* the paraent should loop forever */ for (;;) { if ( iconopen ) { iconopen=0; c = F1; } else c = wgetc(Wn); ioctl( Wn, WIOCGETD, &suw ); /* is it an exit command */ if ( c == Exit || c == Cancl || c == s_Cancl || c == F3 || c == F8 || c == EOF ) { if ( frk == 1 ) { confirm(); iconify(ico,wid,XMAX1,YMAX1); } } else /* is it a scroll left command */ if ( c == left ) { if ( xstart != 0 ) if ( (xstart - xdelta ) > 0 ) {xstart = xstart - xdelta; } else xstart =0; iconify(ico,wid,XMAX1,YMAX1); } else /* is it a scroll right command */ if ( c == right ) { if ((xstart + xdelta + XMAX1) < width ) { xstart = xstart + xdelta; } else xstart = width - XMAX1; iconify(ico,wid,XMAX1,YMAX1); } else /* is it a scroll down command */ if ( c == down ){ if ( ystart != 0 ) if ( (ystart - ydelta ) > 0 ) {ystart = ystart - ydelta; } else ystart =0; iconify(ico,wid,XMAX1,YMAX1); } else /* is it a scroll up command */ if ( c == up ){ if ((ystart + ydelta + YMAX1) < height ) { ystart = ystart + ydelta; } else ystart = height - YMAX1; iconify(ico,wid,XMAX1,YMAX1); } else if ( c == Mouse || c == F1 || c == F2 || c == F6 || c == F7) { b=0; if ( c == Mouse ) wreadmouse(Wn,&x,&y,&b,&r); /* is it open or resume command */ if ( b == 4 || c == F1 || c == F6) { uw = Puw; ioctl( Wn, WIOCSETD, &uw ); ioctl(Wn, WIOCSETMOUSE, &mouse1); if ( (new_wind >= 0) || (new_wind1 >= 0)) wrastop(Wn, Bitmap1, XMAXB, 0,0, 0,0, 0,0, XMAX , YMAX, SRCSRC, DSTSRC, 0 ); for ( i=0; i<6 ; i++) { suti[i].ut_num=i; ioctl(Wn,WIOCSETTEXT,&suti[i]); } fprintf(stderr, "\033[24;1H\033[=0C"); /*fprintf(stderr, "\033[=0C"); ioctl(0,LDSETT,argcb);*/ if ( frk == 1 ) { /* execute the user command */ /* the suspend key sould be in effect */ argg.c_cc[7] = 253; ioctl(0,TCSETA,&argg); frk = 0; if ( (pid=fork()) == 0 ) { /* I should have no control over the window */ /* my parent should, Hmmmm */ setpgrp(); (void) signal ( SIGINT , intsig ); (void) signal ( SIGQUIT , quitsig ); (void) signal ( SIGUSR2 , SIG_IGN ); ptrace(0,0,0,0); com1 +=optind; execvp(com1[0],com1); perror(com1[0]); exit(2); } } else { argg2.c_cc[7] = 253; ioctl(0,TCSETA,&argg2); } /* wakeup the daemon child */ kill (pppid , SIGUSR2 ); /* wakeup the executing child */ if ( isig != 0 ) ptrace(7, pid ,1,0); wait_it: /* uuuuh, it is my turn to sleep */ if ((wait(&statch)) == -1 ) { /* uuuuh, what is this noise? */ goto wait_it; } else { if ( (statch & 0xff) != 0x7f ) { isig = 0; pid = -1; frk = 1; } else { isig = statch >> 8; if ( isig != SIGUSR2 ) { /* wakeup son, it is no time to sleep */ ptrace(7,pid,1,isig); goto wait_it; } } } /* Oh, I'm late.. I should be working by now */ ioctl(0,TCGETA,&argg2); ioctl( Wn, WIOCGETD, &Puw ); for ( i=0; i<6 ; i++) { suti[i].ut_num=i; ioctl(Wn,WIOCGETTEXT,&suti[i]); } wcmd(Wn,0); /* set up function keys */ if ( frk == 0 ) { wslk(Wn, 0, " RESUME TOGGLE B1 TO B2 TO", " BORDER RESUME TOGGLE "); } else wslk(Wn, 0, " OPEN TOGGLE EXIT B1 TO B2 TO B3 TO", " BORDER OPEN TOGGLE EXIT"); new_wind1 = wrastop(Wn, 0,0, Bitmap1, XMAXB, 0,0, 0,0, XMAX , YMAX, SRCSRC, DSTSRC, 0 ); ioctl(Wn,TCSETA,&argg1); keypad(0,1); ioctl(Wn, WIOCGETMOUSE, &mouse1); ioctl(Wn, WIOCSETMOUSE, &mouse); done = 0; bord_flag = 1; fprintf(stderr, "\033[=1C" ); /*ioctl(0,LDGETT,argcb);*/ iconify(ico,wid,XMAX1,YMAX1); } else /* is it toggle border command */ if ( b == 2 || c == F2 || c == F7) { done = 0; if ( bord_flag ) {bord_flag = 0;} else bord_flag = 1; iconify(ico,wid,XMAX1,YMAX1); } else if ( b == 1 ) if ( frk == 1 ) { confirm(); iconify(ico,wid,XMAX1,YMAX1); } } } } confirm() { int c,i,j,k,l; done=0; uw.uw_uflags = 0; uw.uw_height = 64; uw.uw_width = 140; ioctl( Wn, WIOCSETD, &uw ); wlabel(Wn,"CONFIRM EXIT"); wprompt(Wn,"Do you want to exit? (Y/N or Enter/Cancel)"); wcmd(Wn,"Touch Enter to continue Cancel to STOP\n"); c= wgetc(Wn); if( (c == Return) || (c == Enter) || (c == 'y') || (c == 'Y') ) { wlabel(Wn,0); wprompt(Wn,0); wcmd(Wn,0); restore_window(1); } if (c == Mouse) wreadmouse(Wn,&i,&j,&k,&l); if ( k == 4 ) { wlabel(Wn,0); wprompt(Wn,0); wcmd(Wn,0); restore_window(1); } wlabel(Wn,0); wprompt(Wn,0); wcmd(Wn,0); } sendit(sig) int sig; { (void) signal ( sig , sendit ); kill ( (0 - pid ) , sig ); } closeit() { (void) signal ( SIGUSR2 , closeit ); } @//E*O*F tools.c// chmod u=rw,g=r,o=r tools.c exit 0