From 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 Mon Sep 17 00:00:00 2001 From: Joe Hunkeler Date: Tue, 11 Aug 2015 16:51:37 -0400 Subject: Repatch (from linux) of OSX IRAF --- sys/gio/stdgraph/README | 77 ++++ sys/gio/stdgraph/font.com | 207 ++++++++++ sys/gio/stdgraph/font.h | 29 ++ sys/gio/stdgraph/mkpkg | 80 ++++ sys/gio/stdgraph/stdgraph.com | 46 +++ sys/gio/stdgraph/stdgraph.h | 98 +++++ sys/gio/stdgraph/stgcancel.x | 16 + sys/gio/stdgraph/stgclear.x | 16 + sys/gio/stdgraph/stgclose.x | 47 +++ sys/gio/stdgraph/stgclws.x | 28 ++ sys/gio/stdgraph/stgctrl.x | 82 ++++ sys/gio/stdgraph/stgdeact.x | 54 +++ sys/gio/stdgraph/stgdraw.x | 27 ++ sys/gio/stdgraph/stgdrawch.x | 144 +++++++ sys/gio/stdgraph/stgencode.x | 539 +++++++++++++++++++++++++ sys/gio/stdgraph/stgescape.x | 99 +++++ sys/gio/stdgraph/stgfa.x | 115 ++++++ sys/gio/stdgraph/stgfaset.x | 18 + sys/gio/stdgraph/stgfilter.x | 165 ++++++++ sys/gio/stdgraph/stgflush.x | 14 + sys/gio/stdgraph/stggcell.x | 15 + sys/gio/stdgraph/stggcur.x | 52 +++ sys/gio/stdgraph/stggdisab.x | 17 + sys/gio/stdgraph/stggenab.x | 17 + sys/gio/stdgraph/stggim.x | 919 ++++++++++++++++++++++++++++++++++++++++++ sys/gio/stdgraph/stggrstr.x | 16 + sys/gio/stdgraph/stginit.x | 193 +++++++++ sys/gio/stdgraph/stglkcur.x | 18 + sys/gio/stdgraph/stgmove.x | 27 ++ sys/gio/stdgraph/stgonerr.x | 17 + sys/gio/stdgraph/stgonint.x | 21 + sys/gio/stdgraph/stgopen.x | 103 +++++ sys/gio/stdgraph/stgopenws.x | 220 ++++++++++ sys/gio/stdgraph/stgoutput.x | 28 ++ sys/gio/stdgraph/stgoutstr.x | 30 ++ sys/gio/stdgraph/stgpcell.x | 85 ++++ sys/gio/stdgraph/stgpl.x | 126 ++++++ sys/gio/stdgraph/stgplset.x | 20 + sys/gio/stdgraph/stgpm.x | 118 ++++++ sys/gio/stdgraph/stgpmset.x | 19 + sys/gio/stdgraph/stgrcur.x | 425 +++++++++++++++++++ sys/gio/stdgraph/stgreact.x | 41 ++ sys/gio/stdgraph/stgres.x | 85 ++++ sys/gio/stdgraph/stgreset.x | 54 +++ sys/gio/stdgraph/stgrtty.x | 137 +++++++ sys/gio/stdgraph/stgscur.x | 36 ++ sys/gio/stdgraph/stgtx.x | 528 ++++++++++++++++++++++++ sys/gio/stdgraph/stgtxqual.x | 17 + sys/gio/stdgraph/stgtxset.x | 34 ++ sys/gio/stdgraph/stgtxsize.x | 31 ++ sys/gio/stdgraph/stgunkown.x | 14 + sys/gio/stdgraph/stgwtty.x | 118 ++++++ sys/gio/stdgraph/t_gkideco.x | 63 +++ sys/gio/stdgraph/t_showcap.x | 210 ++++++++++ sys/gio/stdgraph/t_stdgraph.x | 110 +++++ sys/gio/stdgraph/x_stdgraph.x | 5 + sys/gio/stdgraph/zzdebug.x | 37 ++ 57 files changed, 5907 insertions(+) create mode 100644 sys/gio/stdgraph/README create mode 100644 sys/gio/stdgraph/font.com create mode 100644 sys/gio/stdgraph/font.h create mode 100644 sys/gio/stdgraph/mkpkg create mode 100644 sys/gio/stdgraph/stdgraph.com create mode 100644 sys/gio/stdgraph/stdgraph.h create mode 100644 sys/gio/stdgraph/stgcancel.x create mode 100644 sys/gio/stdgraph/stgclear.x create mode 100644 sys/gio/stdgraph/stgclose.x create mode 100644 sys/gio/stdgraph/stgclws.x create mode 100644 sys/gio/stdgraph/stgctrl.x create mode 100644 sys/gio/stdgraph/stgdeact.x create mode 100644 sys/gio/stdgraph/stgdraw.x create mode 100644 sys/gio/stdgraph/stgdrawch.x create mode 100644 sys/gio/stdgraph/stgencode.x create mode 100644 sys/gio/stdgraph/stgescape.x create mode 100644 sys/gio/stdgraph/stgfa.x create mode 100644 sys/gio/stdgraph/stgfaset.x create mode 100644 sys/gio/stdgraph/stgfilter.x create mode 100644 sys/gio/stdgraph/stgflush.x create mode 100644 sys/gio/stdgraph/stggcell.x create mode 100644 sys/gio/stdgraph/stggcur.x create mode 100644 sys/gio/stdgraph/stggdisab.x create mode 100644 sys/gio/stdgraph/stggenab.x create mode 100644 sys/gio/stdgraph/stggim.x create mode 100644 sys/gio/stdgraph/stggrstr.x create mode 100644 sys/gio/stdgraph/stginit.x create mode 100644 sys/gio/stdgraph/stglkcur.x create mode 100644 sys/gio/stdgraph/stgmove.x create mode 100644 sys/gio/stdgraph/stgonerr.x create mode 100644 sys/gio/stdgraph/stgonint.x create mode 100644 sys/gio/stdgraph/stgopen.x create mode 100644 sys/gio/stdgraph/stgopenws.x create mode 100644 sys/gio/stdgraph/stgoutput.x create mode 100644 sys/gio/stdgraph/stgoutstr.x create mode 100644 sys/gio/stdgraph/stgpcell.x create mode 100644 sys/gio/stdgraph/stgpl.x create mode 100644 sys/gio/stdgraph/stgplset.x create mode 100644 sys/gio/stdgraph/stgpm.x create mode 100644 sys/gio/stdgraph/stgpmset.x create mode 100644 sys/gio/stdgraph/stgrcur.x create mode 100644 sys/gio/stdgraph/stgreact.x create mode 100644 sys/gio/stdgraph/stgres.x create mode 100644 sys/gio/stdgraph/stgreset.x create mode 100644 sys/gio/stdgraph/stgrtty.x create mode 100644 sys/gio/stdgraph/stgscur.x create mode 100644 sys/gio/stdgraph/stgtx.x create mode 100644 sys/gio/stdgraph/stgtxqual.x create mode 100644 sys/gio/stdgraph/stgtxset.x create mode 100644 sys/gio/stdgraph/stgtxsize.x create mode 100644 sys/gio/stdgraph/stgunkown.x create mode 100644 sys/gio/stdgraph/stgwtty.x create mode 100644 sys/gio/stdgraph/t_gkideco.x create mode 100644 sys/gio/stdgraph/t_showcap.x create mode 100644 sys/gio/stdgraph/t_stdgraph.x create mode 100644 sys/gio/stdgraph/x_stdgraph.x create mode 100644 sys/gio/stdgraph/zzdebug.x (limited to 'sys/gio/stdgraph') diff --git a/sys/gio/stdgraph/README b/sys/gio/stdgraph/README new file mode 100644 index 00000000..6007b9b1 --- /dev/null +++ b/sys/gio/stdgraph/README @@ -0,0 +1,77 @@ +gio$stdgraph + + This directory contains the source and executables for the STDGRAPH and +GKIDECODE graphics kernels. The two kernels are implemented both as libraries +and as executable tasks. + + gkidecode This kernel is used standalone to examine GKI + metafiles. The real work is done by the GKIPRINT + library module in the GIO package. + + stdgraph A graphics kernel for graphics terminals. Implemented + both as the library "libstdg.a" and as the kernel task + STDGRAPH. The library is required for this kernel to + permit inclusion of the stdgraph kernel in the CL + process. + +Both kernels are available as CL callable tasks in the executable file +x_kernel.e. + + +GKIPRINT -- Graphics kernel for decoding metacode. This graphics kernel +formats metacode instructions into readable form and prints them on the output +file. The gkiprint kernel is useful for examining metafiles and for +debugging kernels which drive specific devices. The driver consists of the +following procedures: + + gkp_openws (devname, n, mode) + gkp_closews (devname, n) + gkp_mftitle (title, n) ** + gkp_clear (dummy) + gkp_cancel (dummy) + gkp_flush (dummy) + gkp_polyline (p, npts) + gkp_polymarker (p, npts) + gkp_text (x, y, text, n) + gkp_fillarea (p, npts) + gkp_getcellarray (m, nx, ny, x1,y1, x2,y2) + gkp_putcellarray (m, nx, ny, x1,y1, x2,y2) + gkp_setcursor (x, y, cursor) + gkp_plset (gki) + gkp_pmset (gki) + gkp_txset (gki) + gkp_faset (gki) + gkp_getcursor (cursor) + gkp_escape (fn, instruction, nwords) ** + gkp_setwcs (wcs, nwords) ** + gkp_getwcs (wcs, nwords) ** + gkp_unknown (gki) ** + +A GKI driven device driver may implement any subset of these procedures. +The starred procedures should be omitted by most drivers. In particular, +the SETWCS and GETWCS instructions are internal instructions which should +be ignored by ordinary device drivers. The procedure names may be anything, +but the arguments lists must be as shown. All coordinates are in GKI units, +0 to 32767. Character strings are passed in ASCII, one character per metacode +word. Whenever a GKI character string appears as an array argument in the +argument list of a procedure, the count N of the number of characters in the +string follows as the next argument. GKI character strings are not EOS +delimited. Polyline, polymarker, and fillarea data is passed as an array +of (x,y) points P, in GKI coordinates, defining the polyline or polygon to +be plotted. + +One additional procedure, GKP_INSTALL, is called by the main program of the +graphics kernel task to install the debugging driver, i.e., to fill the DD +array with the entry point addresses of the driver procedures. For a normal +driver this function is performed by a user supplied procedure named +GKOPEN (graphics kernel open). The user supplied kernel procedures will +be called to execute each instruction as the instructions are decoded by the +main routine. The user supplied procedure GKCLOSE will be called when +interpretation ends and the task is about to exit. + + gkopen (dd) + gkclose () + +Do not confuse GKOPEN and GKCLOSE, which open and close the graphics kernel, +with GKI_OPENWS and GKI_CLOSEWS, the metacode instructions used to direct +an opened kernel to open and close workstations. diff --git a/sys/gio/stdgraph/font.com b/sys/gio/stdgraph/font.com new file mode 100644 index 00000000..ec1b0ec9 --- /dev/null +++ b/sys/gio/stdgraph/font.com @@ -0,0 +1,207 @@ +# CHRTAB -- Table of strokes for the printable ASCII characters. Each character +# is encoded as a series of strokes. Each stroke is expressed by a single +# integer containing the following bitfields: +# +# 2 1 +# 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 +# | | | | | | | +# | | | +---------+ +---------+ +# | | | | | +# | | | X Y +# | | | +# | | +-- pen up/down +# | +---- begin paint (not used at present) +# +------ end paint (not used at present) +# +#------------------------------------------------------------------------------ + +# Define the database. + +short chridx[96] # character index in chrtab +short chrtab[800] # stroke data to draw the characters + +# Index into CHRTAB of each printable character (starting with SP). + +data (chridx(i), i=01,05) / 1, 3, 12, 21, 30/ +data (chridx(i), i=06,10) / 45, 66, 79, 85, 92/ +data (chridx(i), i=11,15) / 99, 106, 111, 118, 121/ +data (chridx(i), i=16,20) / 128, 131, 141, 145, 154/ +data (chridx(i), i=21,25) / 168, 177, 187, 199, 203/ +data (chridx(i), i=26,30) / 221, 233, 246, 259, 263/ +data (chridx(i), i=31,35) / 268, 272, 287, 307, 314/ +data (chridx(i), i=36,40) / 327, 336, 344, 352, 359/ +data (chridx(i), i=41,45) / 371, 378, 385, 391, 398/ +data (chridx(i), i=46,50) / 402, 408, 413, 425, 433/ +data (chridx(i), i=51,55) / 445, 455, 468, 473, 480/ +data (chridx(i), i=56,60) / 484, 490, 495, 501, 506/ +data (chridx(i), i=61,65) / 511, 514, 519, 523, 526/ +data (chridx(i), i=66,70) / 529, 543, 554, 563, 574/ +data (chridx(i), i=71,75) / 585, 593, 607, 615, 625/ +data (chridx(i), i=76,80) / 638, 645, 650, 663, 671/ +data (chridx(i), i=81,85) / 681, 692, 703, 710, 723/ +data (chridx(i), i=86,90) / 731, 739, 743, 749, 754/ +data (chridx(i), i=91,95) / 759, 764, 776, 781, 793/ +data (chridx(i), i=96,96) / 801/ + +# Stroke data. + +data (chrtab(i), i=001,005) / 36, 1764, 675, 29328, 585/ +data (chrtab(i), i=006,010) / 21063, 21191, 21193, 21065, 29383/ +data (chrtab(i), i=011,015) / 1764, 355, 29023, 351, 29027/ +data (chrtab(i), i=016,020) / 931, 29599, 927, 29603, 1764/ +data (chrtab(i), i=021,025) / 603, 29066, 842, 29723, 1302/ +data (chrtab(i), i=026,030) / 28886, 143, 29839, 1764, 611/ +data (chrtab(i), i=031,035) / 29256, 78, 20810, 21322, 21581/ +data (chrtab(i), i=036,040) / 21586, 21334, 20822, 20569, 20573/ +data (chrtab(i), i=041,045) / 20833, 21345, 29789, 1764, 419/ +data (chrtab(i), i=046,050) / 20707, 20577, 20574, 20700, 20892/ +data (chrtab(i), i=051,055) / 21022, 21025, 20899, 1187, 28744/ +data (chrtab(i), i=056,060) / 717, 21194, 21320, 21512, 21642/ +data (chrtab(i), i=061,065) / 21645, 21519, 21327, 21197, 1764/ +data (chrtab(i), i=066,070) / 1160, 20700, 20704, 20835, 21027/ +data (chrtab(i), i=071,075) / 21152, 21149, 20561, 20556, 20744/ +data (chrtab(i), i=076,080) / 21192, 29841, 1764, 611, 21023/ +data (chrtab(i), i=081,085) / 21087, 21155, 21091, 1764, 739/ +data (chrtab(i), i=086,090) / 21087, 21018, 21009, 21068, 29384/ +data (chrtab(i), i=091,095) / 1764, 547, 21151, 21210, 21201/ +data (chrtab(i), i=096,100) / 21132, 29192, 1764, 93, 29774/ +data (chrtab(i), i=101,105) / 608, 29259, 78, 29789, 1764/ +data (chrtab(i), i=106,110) / 604, 29260, 84, 29780, 1764/ +data (chrtab(i), i=111,115) / 516, 21062, 21065, 21001, 21000/ +data (chrtab(i), i=116,120) / 21064, 1764, 84, 29780, 1764/ +data (chrtab(i), i=121,125) / 585, 21063, 21191, 21193, 21065/ +data (chrtab(i), i=126,130) / 21191, 1764, 72, 29859, 1764/ +data (chrtab(i), i=131,135) / 419, 20573, 20558, 20872, 21320/ +data (chrtab(i), i=136,140) / 21646, 21661, 21347, 20899, 1764/ +data (chrtab(i), i=141,145) / 221, 21155, 29320, 1764, 95/ +data (chrtab(i), i=146,150) / 20835, 21411, 21663, 21655, 20556/ +data (chrtab(i), i=151,155) / 20552, 29832, 1764, 95, 20899/ +data (chrtab(i), i=156,160) / 21347, 21663, 21658, 21334, 29270/ +data (chrtab(i), i=161,165) / 854, 5266, 21644, 21320, 20872/ +data (chrtab(i), i=166,170) / 28749, 1764, 904, 21411, 21283/ +data (chrtab(i), i=171,175) / 20561, 20559, 21391, 911, 13455/ +data (chrtab(i), i=176,180) / 1764, 136, 21320, 21645, 21652/ +data (chrtab(i), i=181,185) / 21337, 20889, 20565, 20579, 29859/ +data (chrtab(i), i=186,190) / 1764, 83, 20888, 21336, 21651/ +data (chrtab(i), i=191,195) / 21645, 21320, 20872, 20557, 20563/ +data (chrtab(i), i=196,200) / 20635, 29347, 1764, 99, 21667/ +data (chrtab(i), i=201,205) / 29064, 1764, 355, 20575, 20570/ +data (chrtab(i), i=206,210) / 20822, 20562, 20556, 20808, 21384/ +data (chrtab(i), i=211,215) / 21644, 21650, 21398, 20822, 918/ +data (chrtab(i), i=216,220) / 5274, 21663, 21411, 20835, 1764/ +data (chrtab(i), i=221,225) / 648, 21584, 21656, 21662, 21347/ +data (chrtab(i), i=226,230) / 20899, 20574, 20568, 20883, 21331/ +data (chrtab(i), i=231,235) / 21656, 1764, 602, 21210, 21207/ +data (chrtab(i), i=236,240) / 21079, 21082, 21207, 592, 21069/ +data (chrtab(i), i=241,245) / 21197, 21200, 21072, 21197, 1764/ +data (chrtab(i), i=246,250) / 602, 21146, 21143, 21079, 21082/ +data (chrtab(i), i=251,255) / 21143, 585, 21132, 21136, 21072/ +data (chrtab(i), i=256,260) / 21071, 21135, 1764, 988, 20628/ +data (chrtab(i), i=261,265) / 29644, 1764, 1112, 28824, 144/ +data (chrtab(i), i=266,270) / 29776, 1764, 156, 21460, 28812/ +data (chrtab(i), i=271,275) / 1764, 221, 20704, 20899, 21218/ +data (chrtab(i), i=276,280) / 21471, 21466, 21011, 21007, 521/ +data (chrtab(i), i=281,285) / 20999, 21127, 21129, 21001, 21127/ +data (chrtab(i), i=286,290) / 1764, 908, 20812, 20560, 20571/ +data (chrtab(i), i=291,295) / 20831, 21407, 21659, 21651, 21521/ +data (chrtab(i), i=296,300) / 21393, 21331, 21335, 21210, 21018/ +data (chrtab(i), i=301,305) / 20887, 20883, 21009, 21201, 21331/ +data (chrtab(i), i=306,310) / 1764, 72, 20963, 21219, 29768/ +data (chrtab(i), i=311,315) / 210, 5074, 1764, 99, 21411/ +data (chrtab(i), i=316,320) / 21663, 21658, 21398, 20566, 918/ +data (chrtab(i), i=321,325) / 5266, 21644, 21384, 20552, 20579/ +data (chrtab(i), i=326,330) / 1764, 1165, 21320, 20872, 20557/ +data (chrtab(i), i=331,335) / 20574, 20899, 21347, 29854, 1764/ +data (chrtab(i), i=336,340) / 99, 21347, 21662, 21645, 21320/ +data (chrtab(i), i=341,345) / 20552, 20579, 1764, 99, 20552/ +data (chrtab(i), i=346,350) / 29832, 86, 13078, 99, 29859/ +data (chrtab(i), i=351,355) / 1764, 99, 20552, 86, 13078/ +data (chrtab(i), i=356,360) / 99, 29859, 1764, 722, 21650/ +data (chrtab(i), i=361,365) / 29832, 1165, 4936, 20872, 20557/ +data (chrtab(i), i=366,370) / 20574, 20899, 21347, 29854, 1764/ +data (chrtab(i), i=371,375) / 99, 28744, 85, 5269, 1160/ +data (chrtab(i), i=376,380) / 29859, 1764, 291, 29603, 611/ +data (chrtab(i), i=381,385) / 4680, 328, 29576, 1764, 77/ +data (chrtab(i), i=386,390) / 20872, 21256, 21581, 29795, 1764/ +data (chrtab(i), i=391,395) / 99, 28744, 1160, 20887, 82/ +data (chrtab(i), i=396,400) / 13475, 1764, 99, 20552, 29832/ +data (chrtab(i), i=401,405) / 1764, 72, 20579, 21077, 21603/ +data (chrtab(i), i=406,410) / 29768, 1764, 72, 20579, 21640/ +data (chrtab(i), i=411,415) / 29859, 1764, 94, 20899, 21347/ +data (chrtab(i), i=416,420) / 21662, 21645, 21320, 20872, 20557/ +data (chrtab(i), i=421,425) / 20574, 862, 29859, 1764, 72/ +data (chrtab(i), i=426,430) / 20579, 21411, 21663, 21656, 21396/ +data (chrtab(i), i=431,435) / 20564, 1764, 94, 20557, 20872/ +data (chrtab(i), i=436,440) / 21320, 21645, 21662, 21347, 20899/ +data (chrtab(i), i=441,445) / 20574, 536, 29828, 1764, 72/ +data (chrtab(i), i=446,450) / 20579, 21411, 21663, 21657, 21398/ +data (chrtab(i), i=451,455) / 20566, 918, 13448, 1764, 76/ +data (chrtab(i), i=456,460) / 20808, 21384, 21644, 21649, 21397/ +data (chrtab(i), i=461,465) / 20822, 20570, 20575, 20835, 21411/ +data (chrtab(i), i=466,470) / 29855, 1764, 648, 21155, 99/ +data (chrtab(i), i=471,475) / 29923, 1764, 99, 20557, 20872/ +data (chrtab(i), i=476,480) / 21320, 21645, 29859, 1764, 99/ +data (chrtab(i), i=481,485) / 21064, 29795, 1764, 99, 20808/ +data (chrtab(i), i=486,490) / 21141, 21448, 29923, 1764, 99/ +data (chrtab(i), i=491,495) / 29832, 72, 29859, 1764, 99/ +data (chrtab(i), i=496,500) / 21079, 29256, 599, 13411, 1764/ +data (chrtab(i), i=501,505) / 99, 21667, 20552, 29832, 1764/ +data (chrtab(i), i=506,510) / 805, 20965, 20935, 29447, 1764/ +data (chrtab(i), i=511,515) / 99, 29832, 1764, 421, 21221/ +data (chrtab(i), i=516,520) / 21191, 29063, 1764, 288, 21091/ +data (chrtab(i), i=521,525) / 29600, 1764, 3, 29891, 1764/ +data (chrtab(i), i=526,530) / 547, 29341, 1764, 279, 21207/ +data (chrtab(i), i=531,535) / 21396, 21387, 21127, 20807, 20555/ +data (chrtab(i), i=536,540) / 20558, 20753, 21201, 21391, 907/ +data (chrtab(i), i=541,545) / 13447, 1764, 99, 28744, 76/ +data (chrtab(i), i=546,550) / 4424, 21256, 21516, 21523, 21271/ +data (chrtab(i), i=551,555) / 20823, 20563, 1764, 981, 21271/ +data (chrtab(i), i=556,560) / 20823, 20563, 20556, 20808, 21256/ +data (chrtab(i), i=561,565) / 29642, 1764, 1043, 4887, 20823/ +data (chrtab(i), i=566,570) / 20563, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=571,575) / 1032, 29731, 1764, 80, 5136/ +data (chrtab(i), i=576,580) / 21523, 21271, 20823, 20563, 20556/ +data (chrtab(i), i=581,585) / 20808, 21256, 29707, 1764, 215/ +data (chrtab(i), i=586,590) / 29591, 456, 20958, 21153, 21409/ +data (chrtab(i), i=591,595) / 29727, 1764, 67, 20800, 21248/ +data (chrtab(i), i=596,600) / 21508, 29719, 1043, 21271, 20823/ +data (chrtab(i), i=601,605) / 20563, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=606,610) / 1764, 99, 28744, 83, 4439/ +data (chrtab(i), i=611,615) / 21271, 21523, 29704, 1764, 541/ +data (chrtab(i), i=616,620) / 21019, 21147, 21149, 21021, 21147/ +data (chrtab(i), i=621,625) / 533, 21077, 29256, 1764, 541/ +data (chrtab(i), i=626,630) / 21019, 21147, 21149, 21021, 21147/ +data (chrtab(i), i=631,635) / 533, 21077, 21058, 20928, 20736/ +data (chrtab(i), i=636,640) / 28802, 1764, 99, 28744, 84/ +data (chrtab(i), i=641,645) / 29530, 342, 13320, 1764, 483/ +data (chrtab(i), i=646,650) / 21089, 21066, 29384, 1764, 87/ +data (chrtab(i), i=651,655) / 28744, 584, 21076, 84, 4375/ +data (chrtab(i), i=656,660) / 20951, 21076, 21207, 21399, 21588/ +data (chrtab(i), i=661,665) / 29768, 1764, 87, 28744, 83/ +data (chrtab(i), i=666,670) / 20823, 21271, 21523, 29704, 1764/ +data (chrtab(i), i=671,675) / 83, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=676,680) / 21523, 21271, 20823, 20563, 1764/ +data (chrtab(i), i=681,685) / 87, 28736, 83, 20823, 21271/ +data (chrtab(i), i=686,690) / 21523, 21516, 21256, 20808, 20556/ +data (chrtab(i), i=691,695) / 1764, 1047, 29696, 1036, 21256/ +data (chrtab(i), i=696,700) / 20808, 20556, 20563, 20823, 21271/ +data (chrtab(i), i=701,705) / 21523, 1764, 87, 28744, 83/ +data (chrtab(i), i=706,710) / 20823, 21271, 29716, 1764, 74/ +data (chrtab(i), i=711,715) / 20808, 21256, 21514, 21518, 21264/ +data (chrtab(i), i=716,720) / 20816, 20562, 20565, 20823, 21271/ +data (chrtab(i), i=721,725) / 21461, 1764, 279, 29591, 970/ +data (chrtab(i), i=726,730) / 21320, 21128, 21002, 21025, 1764/ +data (chrtab(i), i=731,735) / 87, 20556, 20808, 21256, 21516/ +data (chrtab(i), i=736,740) / 1032, 29719, 1764, 151, 21064/ +data (chrtab(i), i=741,745) / 29719, 1764, 87, 20808, 21077/ +data (chrtab(i), i=746,750) / 21320, 29783, 1764, 151, 29704/ +data (chrtab(i), i=751,755) / 136, 29719, 1764, 87, 21064/ +data (chrtab(i), i=756,760) / 320, 29783, 1764, 151, 21527/ +data (chrtab(i), i=761,765) / 20616, 29704, 1764, 805, 21157/ +data (chrtab(i), i=766,770) / 21026, 21017, 20951, 20822, 20949/ +data (chrtab(i), i=771,775) / 21011, 21001, 21127, 21255, 1764/ +data (chrtab(i), i=776,780) / 611, 29273, 594, 29256, 1764/ +data (chrtab(i), i=781,785) / 485, 21093, 21218, 21209, 21271/ +data (chrtab(i), i=786,790) / 21398, 21269, 21203, 21193, 21063/ +data (chrtab(i), i=791,795) / 29127, 1764, 83, 20758, 20950/ +data (chrtab(i), i=796,800) / 21265, 21457, 29844, 1764, 0/ diff --git a/sys/gio/stdgraph/font.h b/sys/gio/stdgraph/font.h new file mode 100644 index 00000000..c33dc6ee --- /dev/null +++ b/sys/gio/stdgraph/font.h @@ -0,0 +1,29 @@ +# NCAR font definitions. + +define CHARACTER_START 32 +define CHARACTER_END 126 +define CHARACTER_HEIGHT 26 +define CHARACTER_WIDTH 17 + +define FONT_LEFT 0 +define FONT_CENTER 9 +define FONT_RIGHT 27 +define FONT_TOP 36 +define FONT_CAP 34 +define FONT_HALF 23 +define FONT_BASE 9 +define FONT_BOTTOM 0 +define FONT_WIDTH 27 +define FONT_HEIGHT 36 + +define COORD_X_START 7 +define COORD_Y_START 1 +define COORD_PEN_START 13 +define COORD_X_LEN 6 +define COORD_Y_LEN 6 +define COORD_PEN_LEN 1 + +define PAINT_BEGIN_START 14 +define PAINT_END_START 15 +define PAINT_BEGIN_LEN 1 +define PAINT_END_LEN 1 diff --git a/sys/gio/stdgraph/mkpkg b/sys/gio/stdgraph/mkpkg new file mode 100644 index 00000000..8530f2c9 --- /dev/null +++ b/sys/gio/stdgraph/mkpkg @@ -0,0 +1,80 @@ +# Make the STDGRAPH GIO graphics kernel. + +$checkout libstg.a lib$ +$update libstg.a +$checkin libstg.a lib$ +$exit + +update: # update lib$x_stdgraph.e + $call relink + $call install + ; + +relink: # make x_stdgraph.e in local directory + $omake x_stdgraph.x + $link x_stdgraph.o -lstg + ; + +install: # install in system library + $move x_stdgraph.e bin$ + ; + +libstg.a: + # $set xflags = "$(xflags) -qfx" + + stgcancel.x stdgraph.com stdgraph.h + stgclear.x stdgraph.com stdgraph.h + stgclose.x stdgraph.com stdgraph.h + stgclws.x stdgraph.h stdgraph.com + stgctrl.x stdgraph.com stdgraph.h + stgdeact.x stdgraph.com stdgraph.h + stgdraw.x stdgraph.com stdgraph.h + stgdrawch.x font.com font.h stdgraph.com stdgraph.h \ + + stgencode.x stdgraph.com stdgraph.h + stgescape.x + stgfa.x stdgraph.com stdgraph.h + stgfaset.x stdgraph.com stdgraph.h + stgfilter.x stdgraph.com stdgraph.h + stgflush.x stdgraph.com stdgraph.h + stggcell.x + stggcur.x stdgraph.com stdgraph.h + stggdisab.x stdgraph.com stdgraph.h + stggim.x stdgraph.com stdgraph.h \ + + stggenab.x stdgraph.com stdgraph.h + stggrstr.x stdgraph.com stdgraph.h + stginit.x stdgraph.com stdgraph.h \ + + stglkcur.x stdgraph.com stdgraph.h + stgmove.x stdgraph.com stdgraph.h + stgonerr.x stdgraph.com stdgraph.h + stgonint.x stdgraph.h + stgopen.x stdgraph.com stdgraph.h + stgopenws.x stdgraph.com stdgraph.h \ + + stgoutput.x stdgraph.com stdgraph.h + stgoutstr.x stdgraph.com stdgraph.h + stgpcell.x stdgraph.com stdgraph.h + stgpl.x stdgraph.com stdgraph.h + stgplset.x stdgraph.com stdgraph.h + stgpm.x stdgraph.com stdgraph.h + stgpmset.x stdgraph.com stdgraph.h + stgrcur.x stdgraph.com stdgraph.h \ + + stgreact.x stdgraph.com stdgraph.h + stgres.x stdgraph.com stdgraph.h + stgreset.x stdgraph.com stdgraph.h + stgrtty.x stdgraph.com stdgraph.h + stgscur.x stdgraph.com stdgraph.h + stgtx.x stdgraph.com stdgraph.h \ + + stgtxqual.x stdgraph.com stdgraph.h + stgtxset.x stdgraph.com stdgraph.h + stgtxsize.x stdgraph.com stdgraph.h + stgunkown.x + stgwtty.x stdgraph.com stdgraph.h + t_gkideco.x + t_showcap.x stdgraph.h + t_stdgraph.x + ; diff --git a/sys/gio/stdgraph/stdgraph.com b/sys/gio/stdgraph/stdgraph.com new file mode 100644 index 00000000..3d3c43c5 --- /dev/null +++ b/sys/gio/stdgraph/stdgraph.com @@ -0,0 +1,46 @@ +# STDGRAPH common. A common is necessary since there is no graphics descriptor +# in the argument list of the kernel procedures. The stdgraph data structures +# are designed along the lines of FIO: a small common is used to hold the time +# critical data elements, and an auxiliary dynamically allocated descriptor is +# used for everything else. For maximum efficiency the polyline generation and +# coordinate transformation datums are kept in the common. + +pointer g_sg # stdgraph graphics descriptor +pointer g_tty # graphcap descriptor +pointer g_term # termcap descriptor for terminal +pointer g_pbtty # script graphcap, playback mode +int g_nopen # open count for the kernel +int g_active # workstation is open for graphics i/o +int g_enable # graphics is enabled +int g_message # message mode (output text) +pointer g_msgbuf # message buffer (input text) +int g_msgbuflen # allocated size of message buffer +int g_msglen # amount of data in message +int g_keycol # used to show keys in playback mode +int g_keyline # used to show keys in playback mode +pointer g_xy # pointer to coord encoding string +int g_stream # graphics stream (metacode) +int g_in, g_out # input, output streams to device +int g_ucaseout # stty ucaseout status flag +int g_xres, g_yres # desired device resolution +int g_dxres, g_dyres # scale down to resolution coords +real g_dx, g_dy # scale GKI to window coords +int g_x1, g_y1 # origin of device window +int g_x2, g_y2 # upper right corner of device window +int g_lastx, g_lasty # used to clip unresolved points +int g_hardchar # controls use of hardware character gen +int g_cursor # user override of logical cursor +int g_reg[NREGISTERS] # encoder registers +char g_mem[SZ_MEMORY] # encoder memory +char g_device[SZ_GDEVICE] # device name for forced device output +char g_pbdevice[SZ_GDEVICE] # device name of playback script +char g_hixy[TEK_XRES] # lookup tables for tek encoding +char g_lox[TEK_XRES] # " " +char g_loy[TEK_YRES] # " " + +common /stgcom/ g_sg, g_tty, g_term, g_pbtty, g_nopen, g_active, g_enable, + g_message, g_msgbuf, g_msgbuflen, g_msglen, + g_keycol, g_keyline, g_xy, g_stream, g_in, g_out, + g_ucaseout, g_xres, g_yres, g_dxres, g_dyres, g_dx, g_dy, g_x1, + g_y1, g_x2, g_y2, g_lastx, g_lasty, g_hardchar, g_cursor, g_reg, + g_mem, g_device, g_pbdevice, g_hixy, g_lox, g_loy diff --git a/sys/gio/stdgraph/stdgraph.h b/sys/gio/stdgraph/stdgraph.h new file mode 100644 index 00000000..de216065 --- /dev/null +++ b/sys/gio/stdgraph/stdgraph.h @@ -0,0 +1,98 @@ +# STDGRAPH definitions. + +define MAX_CHARSIZES 10 # max discreet device char sizes +define SZ_SBUF 2048 # initial string buffer size +define SZ_MEMORY 1024 # encoder memory size +define SZ_GDEVICE 256 # force output to named device +define SZ_UIFNAME 199 # user interface file name +define SZ_MSGBUF 4096 # default size message buffer +define FLUSH_MEMORY 117 # time to flush encoded polyline +define LEN_STACK 20 # encoder stack size +define NREGISTERS 12 # number of encoder registers +define E_IOP 11 # encoder i/o pointer register +define E_TOP 12 # encoder top memory register +define LONG_POLYLINE 50 # big enough to post X_INT +define PADCHAR 0 # used to gen. delays + +# The user can have private copies of UI specifications in GUIDIR. +define GUIDIR "guidir" + +# The STDGRAPH state/device descriptor. + +define LEN_SG 91 + +define SG_SBUF Memi[$1] # string buffer +define SG_SZSBUF Memi[$1+1] # size of string buffer +define SG_NEXTCH Memi[$1+2] # next char pos in string buf +define SG_NCHARSIZES Memi[$1+3] # number of character sizes +define SG_POLYLINE Memi[$1+4] # polyline output permitted +define SG_POLYMARKER Memi[$1+5] # device supports polymarker +define SG_FILLAREA Memi[$1+6] # device supports fillarea +define SG_ENCODEXY Memi[$1+7] # format for encoding coords +define SG_STARTDRAW Memi[$1+8] # pointer to DS string +define SG_ENDDRAW Memi[$1+9] # pointer to DE string +define SG_STARTMOVE Memi[$1+10] # pointer to VS string +define SG_ENDMOVE Memi[$1+11] # pointer to VE string +define SG_STARTMARK Memi[$1+12] # pointer to MS string +define SG_ENDMARK Memi[$1+13] # pointer to ME string +define SG_STARTFILL Memi[$1+14] # pointer to FS string +define SG_ENDFILL Memi[$1+15] # pointer to FE string +define SG_STARTTEXT Memi[$1+16] # start text draw +define SG_ENDTEXT Memi[$1+17] # end text draw +define SG_CURSOR Memi[$1+18] # last cursor accessed +define SG_UPDCURSOR Memi[$1+19] # update cursor pos before read +define SG_CURSOR_X Memi[$1+20] # current cursor X position +define SG_CURSOR_Y Memi[$1+21] # current cursor Y position +define SG_COLOR Memi[$1+22] # last color set +define SG_TXSIZE Memi[$1+23] # last text size set +define SG_TXFONT Memi[$1+24] # last text font set +define SG_PLTYPE Memi[$1+25] # last line type set +define SG_FASTYLE Memi[$1+26] # last fill area style set +define SG_PLWIDTH Memi[$1+27] # last line width set +define SG_DEVNAME Memi[$1+28] # name of open device +define SG_UIFNAME Memi[$1+29] # user interface file name +define SG_UIFDATE Memi[$1+30] # UI file date + # empty +define SG_CHARHEIGHT Memi[$1+40+$2-1] # character height +define SG_CHARWIDTH Memi[$1+50+$2-1] # character width +define SG_CHARSIZE Memr[P2R($1+60+$2-1)] # text sizes permitted +define SG_PLAP ($1+70) # polyline attributes +define SG_PMAP ($1+74) # polymarker attributes +define SG_FAAP ($1+78) # fill area attributes +define SG_TXAP ($1+81) # default text attributes + +# Substructure definitions. + +define LEN_PL 4 +define PL_STATE Memi[$1] # polyline attributes +define PL_LTYPE Memi[$1+1] +define PL_WIDTH Memi[$1+2] +define PL_COLOR Memi[$1+3] + +define LEN_PM 4 +define PM_STATE Memi[$1] # polymarker attributes +define PM_LTYPE Memi[$1+1] +define PM_WIDTH Memi[$1+2] +define PM_COLOR Memi[$1+3] + +define LEN_FA 3 # fill area attributes +define FA_STATE Memi[$1] +define FA_STYLE Memi[$1+1] +define FA_COLOR Memi[$1+2] + +define LEN_TX 10 # text attributes +define TX_STATE Memi[$1] +define TX_UP Memi[$1+1] +define TX_SIZE Memi[$1+2] +define TX_PATH Memi[$1+3] +define TX_SPACING Memr[P2R($1+4)] +define TX_HJUSTIFY Memi[$1+5] +define TX_VJUSTIFY Memi[$1+6] +define TX_FONT Memi[$1+7] +define TX_QUALITY Memi[$1+8] +define TX_COLOR Memi[$1+9] + +# TEK 4012 definitions for optimized tek coordinate encoding. + +define TEK_XRES 1024 +define TEK_YRES 780 diff --git a/sys/gio/stdgraph/stgcancel.x b/sys/gio/stdgraph/stgcancel.x new file mode 100644 index 00000000..d47e24df --- /dev/null +++ b/sys/gio/stdgraph/stgcancel.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_CANCEL -- Cancel any buffered output. + +procedure stg_cancel (dummy) + +int dummy # not used at present +include "stdgraph.com" + +begin + call fseti (g_out, F_CANCEL, YES) + call stg_reset() +end diff --git a/sys/gio/stdgraph/stgclear.x b/sys/gio/stdgraph/stgclear.x new file mode 100644 index 00000000..9573c972 --- /dev/null +++ b/sys/gio/stdgraph/stgclear.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_CLEAR -- Clear the workstation screen. All attribute packets are +# initialized to their default values when the screen is cleared. + +procedure stg_clear (dummy) + +int dummy # not used at present +include "stdgraph.com" + +begin + call stg_ctrl ("CL") + call stg_reset() +end diff --git a/sys/gio/stdgraph/stgclose.x b/sys/gio/stdgraph/stgclose.x new file mode 100644 index 00000000..3d7eb70b --- /dev/null +++ b/sys/gio/stdgraph/stgclose.x @@ -0,0 +1,47 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_CLOSE -- Close the STDGRAPH kernel. Free all storage associated with the +# stdgraph descriptor. Note that the stdgraph kernel may be multiply opened +# (connected to two or more graphics steams, e.g., both STDGRAPH and STDIMAGE), +# hence we do not physically close down until the last stream is closed. + +procedure stg_close() + +include "stdgraph.com" + +begin + g_nopen = g_nopen - 1 + + if (g_nopen <= 0) { + call stg_deactivatews (0) + call flush (g_out) + call mfree (SG_SBUF(g_sg), TY_CHAR) + call mfree (g_sg, TY_STRUCT) + + if (g_tty != NULL) { + call ttycdes (g_tty) + g_tty = NULL + } + + if (g_term != NULL) { + call ttycdes (g_term) + g_term = NULL + } + + if (g_pbtty != NULL) { + call ttycdes (g_pbtty) + g_pbtty = NULL + } + + if (g_msgbuf != NULL) { + call mfree (g_msgbuf, TY_CHAR) + g_msgbuf = NULL + g_msgbuflen = 0 + g_msglen = 0 + } + + g_nopen = 0 + } +end diff --git a/sys/gio/stdgraph/stgclws.x b/sys/gio/stdgraph/stgclws.x new file mode 100644 index 00000000..137784cd --- /dev/null +++ b/sys/gio/stdgraph/stgclws.x @@ -0,0 +1,28 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_CLOSEWS -- Close the named workstation. Output the termination string, +# if any, and flush the output. Buffer deallocation is handled by STGCLOSE. + +procedure stg_closews (devname, n) + +short devname[ARB] # device name (not used) +int n # length of device name + +include "stdgraph.com" + +begin + call stg_ctrl ("CW") + call flush (g_out) + + g_active = NO + g_enable = NO + + # Reenable stty ucaseout mode if it was set when the workstation + # was activated. + + if (g_ucaseout == YES) + call ttseti (g_out, TT_UCASEOUT, YES) +end diff --git a/sys/gio/stdgraph/stgctrl.x b/sys/gio/stdgraph/stgctrl.x new file mode 100644 index 00000000..6689de8a --- /dev/null +++ b/sys/gio/stdgraph/stgctrl.x @@ -0,0 +1,82 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +define SZ_PROGRAM 256 + +# STG_CTRL -- Fetch an encoder format string from the graphcap entry and +# use it to encode zero, one, or two integer arguments into a control string. +# Put the control string to the output device. + +procedure stg_ctrl (cap) + +char cap[ARB] # name of device capability to be encoded +pointer sp, prog +int stg_encode(), ttygets() +include "stdgraph.com" + +begin + call smark (sp) + call salloc (prog, SZ_PROGRAM, TY_CHAR) + + # Fetch the program from the graphcap file. Zero is returned if the + # device does not have the named capability, in which case the function + # is inapplicable and should be ignored. + + if (ttygets (g_tty, cap, Memc[prog], SZ_PROGRAM) > 0) { + # Encode the output string and write the encoded string to the + # output file. + g_reg[E_IOP] = 1 + if (stg_encode (Memc[prog], g_mem, g_reg) == OK) { + g_mem[g_reg[E_IOP]] = EOS + call ttyputs (g_out, g_tty, g_mem, 1) + } + } + + call sfree (sp) +end + + +# STG_CTRL1 -- Encode one integer argument. + +procedure stg_ctrl1 (cap, arg1) + +char cap[ARB] # device capability +int arg1 +include "stdgraph.com" + +begin + g_reg[1] = arg1 + call stg_ctrl (cap) +end + + +# STG_CTRL2 -- Encode two integer arguments. + +procedure stg_ctrl2 (cap, arg1, arg2) + +char cap[ARB] # device capability +int arg1, arg2 +include "stdgraph.com" + +begin + g_reg[1] = arg1 + g_reg[2] = arg2 + call stg_ctrl (cap) +end + + +# STG_CTRL3 -- Encode three integer arguments. + +procedure stg_ctrl3 (cap, arg1, arg2, arg3) + +char cap[ARB] # device capability +int arg1, arg2, arg3 +include "stdgraph.com" + +begin + g_reg[1] = arg1 + g_reg[2] = arg2 + g_reg[3] = arg3 + call stg_ctrl (cap) +end diff --git a/sys/gio/stdgraph/stgdeact.x b/sys/gio/stdgraph/stgdeact.x new file mode 100644 index 00000000..b11e4a07 --- /dev/null +++ b/sys/gio/stdgraph/stgdeact.x @@ -0,0 +1,54 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "stdgraph.h" + +# STG_DEACTIVATEWS -- Deactivate the workstation, i.e., disable graphics, +# leaving the terminal in text mode. Note that it is the CW (close +# workstation) sequence which is actually output, since the GD sequence is +# used only to write single lines of text to the status line. + +procedure stg_deactivatews (flags) + +int flags # action modifier flags + +char buf[1] +int stg_readtty(), and() +include "stdgraph.com" + +begin + if (g_out <= 0) + return + + # The g_active and g_out test permits us to be called before the + # kernel is opened and causes redundant calls to be ignored. + + if (g_active == YES) { + # Pause before deactivating? + if (and (flags, AW_PAUSE) != 0) { + call stg_putline (g_out, "\n[Hit return to continue]\n") + while (stg_readtty (STDIN, buf, 1) != EOF) + if (buf[1] == '\r' || buf[1] == '\n') + break + } + + # Deactivate the workstation. + call stgctrl ("CW") + + g_active = NO + g_enable = NO + + # Reenable stty ucaseout mode if it was set when the workstation + # was activated. + + if (g_ucaseout == YES) + call ttseti (g_out, TT_UCASEOUT, YES) + } + + # Clear the text screen? + if (and (flags, AW_CLEAR) != 0 && g_term != NULL) + call ttyclear (g_out, g_term) + + call flush (g_out) +end diff --git a/sys/gio/stdgraph/stgdraw.x b/sys/gio/stdgraph/stgdraw.x new file mode 100644 index 00000000..ae5a4ace --- /dev/null +++ b/sys/gio/stdgraph/stgdraw.x @@ -0,0 +1,27 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_DRAW -- Output a device draw line-segment instruction to draw from the +# current position to the position (x,y) in GKI coordinates. + +procedure stg_draw (x, y) + +int x, y # destination +int stg_encode() +include "stdgraph.com" + +begin + # Transform the first point from GKI coords to device coords and + # draw to the transformed point. + + call ttyputs (g_out, g_tty, Memc[SG_STARTDRAW(g_sg)], 1) + + g_reg[1] = x * g_dx + g_x1 + g_reg[2] = y * g_dy + g_y1 + g_reg[E_IOP] = 1 + if (stg_encode (Memc[g_xy], g_mem, g_reg) == OK) + call write (g_out, g_mem, g_reg[E_IOP] - 1) + + call ttyputs (g_out, g_tty, Memc[SG_ENDDRAW(g_sg)], 1) +end diff --git a/sys/gio/stdgraph/stgdrawch.x b/sys/gio/stdgraph/stgdrawch.x new file mode 100644 index 00000000..fd317d2b --- /dev/null +++ b/sys/gio/stdgraph/stgdrawch.x @@ -0,0 +1,144 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include +include "stdgraph.h" +include "font.h" + +define ITALIC_TILT 0.30 # fraction of xsize to tilt italics at top +define MAXPTS 40 # max points in a char drawing polyline + + +# STG_DRAWCHAR -- Draw a character of the given size and orientation at the +# given position. + +procedure stg_drawchar (ch, x, y, xsize, ysize, orien, font) + +char ch # character to be drawn +int x, y # lower left GKI coords of character +int xsize, ysize # width, height of char in GKI units +int orien # orientation of character (0 degrees normal) +int font # desired character font + +pointer pl, tx +real px, py, coso, sino, theta +int stroke, tab1, tab2, i, pen, mx, my +int save_ltype, save_lwidth, save_color +int bitupk() +include "font.com" +include "stdgraph.com" + +begin + if (ch < CHARACTER_START || ch > CHARACTER_END) + i = '?' - CHARACTER_START + 1 + else + i = ch - CHARACTER_START + 1 + + # Set the font. + if (SG_TXFONT(g_sg) != font) { + call stg_ctrl1 ("TF", font - GT_ROMAN + 1) + SG_TXFONT(g_sg) = font + } + + # Since we will be using the polyline generator, set the polyline + # linetype to solid and save the current linetype for later restoration. + + pl = SG_PLAP(g_sg) + tx = SG_TXAP(g_sg) + save_color = PL_COLOR(pl) + save_ltype = PL_LTYPE(pl) + save_lwidth = PL_WIDTH(pl) + PL_COLOR(pl) = TX_COLOR(tx) + PL_LTYPE(pl) = GL_SOLID + PL_WIDTH(pl) = 1 + + tab1 = chridx[i] + tab2 = chridx[i+1] - 1 + + theta = -DEGTORAD(orien) + coso = cos(theta) + sino = sin(theta) + + do i = tab1, tab2 { + stroke = chrtab[i] + px = bitupk (stroke, COORD_X_START, COORD_X_LEN) + py = bitupk (stroke, COORD_Y_START, COORD_Y_LEN) + pen = bitupk (stroke, COORD_PEN_START, COORD_PEN_LEN) + + # Scale size of character. + px = px / FONT_WIDTH * xsize + py = py / FONT_HEIGHT * ysize + + # The italic font is implemented applying a tilt. + if (font == GT_ITALIC) + px = px + ((py / ysize) * xsize * ITALIC_TILT) + + # Rotate and shift. + mx = x + px * coso + py * sino + my = y - px * sino + py * coso + + # Draw the line segment or move pen. + if (pen == 0) + call sgch_move (mx, my) + else + call sgch_draw (mx, my) + } + + # Flush any remaining points. + call sgch_flush() + + # Restore polyline linetype and color. + PL_LTYPE(pl) = save_ltype + PL_WIDTH(pl) = save_lwidth + PL_COLOR(pl) = save_color +end + + +# SGCH_MOVE -- Start accumulating a new polyline. + +procedure sgch_move (mx, my) + +int mx, my +short pl[MAXPTS], op +common /sgchcm/ pl, op + +begin + call sgch_flush() + + pl[1] = mx + pl[2] = my + op = 3 +end + + +# SGCH_DRAW -- Add a point to the polyline. + +procedure sgch_draw (mx, my) + +int mx, my +short pl[MAXPTS], op +common /sgchcm/ pl, op + +begin + pl[op] = mx + pl[op+1] = my + op = min (MAXPTS, op + 2) +end + + +# SGCH_FLUSH -- Flush the polyline to the output device. + +procedure sgch_flush() + +int npts +short pl[MAXPTS], op +common /sgchcm/ pl, op + +begin + if (op > 2) { + npts = op / 2 + call stg_polyline (pl, npts) + } + op = 1 +end diff --git a/sys/gio/stdgraph/stgencode.x b/sys/gio/stdgraph/stgencode.x new file mode 100644 index 00000000..3c7a6ffb --- /dev/null +++ b/sys/gio/stdgraph/stgencode.x @@ -0,0 +1,539 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +.help stg_encode +.nf _________________________________________________________________________ +STG_ENCODE -- Table driven binary encoder/decoder. The encoder (which can +also decode) processes a format string, also referred to as a program, to +either encode an output string or decode an input string. Internally the +encoder operates in two modes, copy mode and execute mode. In copy mode +all format characters are copied to the output except the following special +characters: + + ' escape next character (literal) + % begin a formatted output string + ( switch to execute mode (stack driven, RPN interpreter) + +An ( appearing in the format string causes a mode switch to execute mode. +In execute mode characters are metacode instructions to be executed. An +unescaped ) causes reversion to copy mode. Parens may not be nested; an +( in execute mode is an instruction to push the binary value of ( on the +stack, and an ) in copy mode is copied to the output as a character. In +execute mode the following characters are recognized as special instructions. +All other characters are instructions too, telling the encoder to push the +ASCII value of the character on the stack. + + ' escape next character (recognized everywhere) + % formatted output + ) revert to copy mode + #nnn push signed decimal integer number nnn + $ switch case construct + . pop number from stack and place in output string + , get next character from input string and push on stack + & modulus (similar to AND of low bits) + + add (similar to OR) + - subtract (similar to AND) + * multiply (shift left if pwr of 2) + / divide (shift right if pwr of 2) + < less than (0=false, 1=true) + > greater than (0=false, 1=true) + = equals (0=false, 1=true) + ; branch if: ;. The ; is at offset zero. + 0-9 push register + !N pop stack into register N + !! pop N from stack and output an N millisecond delay + +The encoder communicates with the outside world via three general purpose +data structures. + + registers 0-9 (integer only) + memory char array + program char array + +The registers are used for parameter input and output as well as for storing +intermediate results. R 1-3 are used for input and output arguments. R 4-9 +and R0 (R10) are reserved for use by the program. R11 is the i/o pointer into +encoder memory, used for character input and output. R12 should contain the +maximum memory address upon input. Memory may be used for anything but is +normally used only for the input string or output string. The program is the +format string. + +Further documentation is given in the GIO reference manual. +.endhelp _____________________________________________________________________ + +define SZ_FORMAT 10 # max length printf format +define SZ_NUMSTR 10 # encoded numeric string + +define R1 registers[1] # argument +define R2 registers[2] # argument +define R3 registers[3] # argument +define R4 registers[4] # scratch +define R5 registers[5] # scratch +define R6 registers[6] # scratch +define R7 registers[7] # scratch +define R8 registers[8] # scratch +define R9 registers[9] # scratch +define R0 registers[10] # scratch +define IOP registers[11] # i/o pointer into encoder memory +define TOP registers[12] # max memory location + +# Inline macros. + +define memory_overflow_ 1 +define stack_underflow_ 2 +define stack_overflow_ 3 + +define input {$1=memory[iop];iop=iop+1} +define output {memory[iop]=($1);iop=iop+1;if(iop>top)goto memory_overflow_} +define push {stack[sp]=($1);sp=sp+1} +define pop {sp=sp-1;$1=stack[sp]} + + +# STG_ENCODE -- Interpret a program, encoding values passed in registers into +# memory, or decoding memory into registers. + +int procedure stg_encode (program, memory, registers) + +char program[ARB] # program to be executed +char memory[ARB] # data space +int registers[NREGISTERS] # general purpose registers + +int x, y, num, ch, status +int stack[LEN_STACK] +int sp, pc, iop, top, incase +common /sgecom/ pc, sp, iop, top, incase, stack +int sge_execute() +include "stdgraph.com" + +begin + # TEK format, %t. This format deserves special treatment due to the + # prevalence of tektronix compatible graphics terminals. + + if (program[1] == '%' && program[2] == 't') { + x = R1 + y = R2 + iop = IOP + 4 + if (iop > top) + goto memory_overflow_ + + memory[iop-4] = g_hixy[y+1] + memory[iop-3] = g_loy[y+1] + memory[iop-2] = g_hixy[x+1] + memory[iop-1] = g_lox[x+1] + + IOP = iop + if (program[3] == EOS) + return (OK) + } + + # Process a general format string (as well as any chars following the + # %t format). + + incase = NO + iop = IOP + top = TOP + pc = 1 + sp = 1 + + for (ch=program[pc]; ch != EOS; ch=program[pc]) { + pc = pc + 1 + if (ch == '%' && program[pc] != EOS) { + if (program[pc] == 't') { + # Tek format again. + pc = pc + 1 + x = R1 + y = R2 + iop = iop + 4 + if (iop > top) + goto memory_overflow_ + + memory[iop-4] = g_hixy[y+1] + memory[iop-3] = g_loy[y+1] + memory[iop-2] = g_hixy[x+1] + memory[iop-1] = g_lox[x+1] + + } else { + # Extract a general format specification and use it to + # encode the number on top of the stack. + pop (num) + if (sp < 1) { + IOP = iop + return (stack_underflow_) + } else + call sge_printf (num, memory, iop, top, program, pc) + } + + } else if (ch == '(' && program[pc] != EOS) { + # Switch to execute mode. + status = sge_execute (program, memory, registers) + if (status != OK) + return (status) + + } else if (ch == '\'' && program[pc] != EOS) { + # Escape next character. + output (program[pc]) + pc = pc + 1 + + } else { + # Copy an ordinary character to the output string. + output (ch) + } + } + + IOP = iop + return (OK) + +memory_overflow_ + IOP = iop + return (memory_overflow_) +end + + +# SGE_EXECUTE -- Execute a metacode program stored in encoder memory starting +# at the location of the PC. The stack, program counter, i/o pointer, and +# registers are shared by the copy and execute mode procedures via common. + +int procedure sge_execute (program, memory, registers) + +char program[ARB] # program to be executed +char memory[ARB] # data space +int registers[NREGISTERS] # general purpose registers + +int num, ch, a, b, neg, x, y +int stack[LEN_STACK] +int sp, pc, iop, top, incase, msec, npad, baud, envgeti(), btoi() +common /sgecom/ pc, sp, iop, top, incase, stack +include "stdgraph.com" +errchk envgeti + +begin + # Execute successive single character instructions until either ) or + # EOS is seen. On a good host machine this case will be compiled as + # a vectored goto with a loop overhead of only a dozen or so machine + # instructions per loop. + + for (ch=program[pc]; ch != EOS; ch=program[pc]) { + pc = pc + 1 + + switch (ch) { + case '\'': + # Escape next character (recognized everywhere). + ch = program[pc] + if (ch != EOS) { + # Push ASCII value of character. + push (ch) + pc = pc + 1 + } + + case '%': + if (program[pc] == 't') { + # Tek format again. + pc = pc + 1 + x = R1 + y = R2 + iop = iop + 4 + if (iop > top) + goto memory_overflow_ + + memory[iop-4] = g_hixy[y+1] + memory[iop-3] = g_loy[y+1] + memory[iop-2] = g_hixy[x+1] + memory[iop-1] = g_lox[x+1] + + } else { + # Formatted output. + if (program[pc] != EOS) { + pop (num) + call sge_printf (num, memory, iop, top, program, pc) + } else + output (ch) + } + + case ')': + # End interpreter mode. + return (OK) + + case '#': + # Push signed decimal integer number. + neg = NO + if (program[pc] == '-') { + neg = YES + pc = pc + 1 + } + + num = 0 + while (IS_DIGIT (program[pc])) { + num = num * 10 + TO_INTEG (program[pc]) + pc = pc + 1 + } + + if (neg == YES) + push (-num) + else + push (num) + + case '$': + # Switch case instruction. + + if (incase == NO) { + # Pop the switch off the stack. + pop (num) + + # Search for case number 'num'. + for (ch=program[pc]; ch != EOS; ch=program[pc]) { + if (ch == '$') { + # End of switch statement. + pc = pc + 1 + incase = NO + break + + } else if (program[pc+1] == '-') { + # Range of cases. + a = TO_INTEG (ch) + b = TO_INTEG (program[pc+2]) + pc = pc + 3 + if (a <= num && num <= b) { + incase = YES + break + } + } else if (ch == 'D' || TO_INTEG(ch) == num) { + # Default or requested case. + pc = pc + 1 + incase = YES + break + + } + + # Advance to the next case. Leave pc pointing to the + # N of case $N. + + if (ch != '$' && incase == NO) { + while (program[pc] != EOS && program[pc] != '$') + pc = pc + 1 + if (program[pc] == '$') + pc = pc + 1 + } + } + + } else { + # $ encountered delimiting a case. Search forward for + # $$ or EOS. + + if (program[pc] != '$') + for (ch=program[pc]; ch != EOS; ch=program[pc]) { + pc = pc + 1 + if (ch == '$' && program[pc] == '$') + break + } + + if (program[pc] == '$') + pc = pc + 1 + + incase = NO + } + + case '.': + # Pop number from stack and place in output string as a + # binary character. + pop (num) + output (num) + + case ',': + # Get next character from input string and push on stack. + input (num) + push (num) + + case '&': + # Modulus (similar to AND of low bits). + pop (b) + pop (a) + push (mod (a, b)) + + case '+': + # Add (similar to OR). + pop (b) + pop (a) + push (a + b) + + case '-': + # Subtract (similar to AND). + pop (b) + pop (a) + push (a - b) + + case '*': + # Multiply (shift left if pwr of 2). + pop (b) + pop (a) + push (a * b) + + case '/': + # Divide (shift right if pwr of 2). + pop (b) + pop (a) + push (a / b) + + case '<': + # Less than (0=false, 1=true). + pop (b) + pop (a) + push (btoi (a < b)) + + case '>': + # Greater than (0=false, 1=true). + pop (b) + pop (a) + push (btoi (a > b)) + + case '=': + # Equals (0=false, 1=true). + pop (b) + pop (a) + push (btoi (a == b)) + + case ';': + # If 2nd value on stack is true add 1st value on stack to PC. + # Example: "12<#-8;". The ; is at offset zero. + pop (a) + pop (b) + if (b != 0) + pc = pc - 1 + a + + case '0': + # Push contents of register 0 (10). + push (R0) + case '1': + # Push contents of register 1. + push (R1) + case '2': + # Push contents of register 2. + push (R2) + case '3': + # Push contents of register 3. + push (R3) + case '4': + # Push contents of register 4. + push (R4) + case '5': + # Push contents of register 5. + push (R5) + case '6': + # Push contents of register 6. + push (R6) + case '7': + # Push contents of register 7. + push (R7) + case '8': + # Push contents of register 8. + push (R8) + case '9': + # Push contents of register 9. + push (R9) + + case '!': + if (program[pc] == '!') { + # !!: Pop stack and generate delay. + pc = pc + 1 + pop (msec) + iferr (baud = envgeti ("ttybaud")) + baud = 9600 + npad = real(msec) * (real(baud) / 8. / 1000.) + while (npad > 0) { + output (PADCHAR) + npad = npad - 1 + } + } else { + # !N: Pop stack into register N. + num = TO_INTEG (program[pc]) + if (num >= 0 && num <= 9) { + if (num == 0) + num = 10 + pop (registers[num]) + pc = pc + 1 + } else + output (ch) + } + + default: + # Push ASCII value of character. + push (ch) + } + + if (sp <= 0) + return (stack_underflow_) + if (sp > LEN_STACK) + return (stack_overflow_) + } + + return (OK) + +memory_overflow_ + return (memory_overflow_) +end + + +# SGE_PRINTF -- Process a %.. format specification. The number to be encoded +# has already been popped from the stack into the first argument. The encoded +# number is returned in memory at IOP, leaving IOP positioned to the first +# char following the encoded number. The format used to encode the number is +# extracted from the program starting at PC. PC is left pointing to the first +# character following the format. + +procedure sge_printf (number, memory, iop, top, program, pc) + +int number # number to be encoded +char memory[top] # output buffer +int iop # index of first char to be written (in/out) +int top # size of output buffer +char program[ARB] # contains printf format string +int pc # index of first char of format string (in/out) + +char format[SZ_FORMAT] +char numstr[SZ_NUMSTR] +int op, ch, junk +int gstrcpy(), itoc() + +begin + # Extract format %w.dC, a string of digits, -, or ., delimited by a + # letter. The format %w.dr is followed by a single character which + # must also be included in the format string. + + format[1] = '%' + op = 2 + for (ch=program[pc]; ch != EOS; ch=program[pc]) { + pc = pc + 1 + format[op] = ch + op = op + 1 + if (IS_LOWER(ch)) { + if (ch == 'r' && program[pc] != EOS) { + # Radix digit follows %r. + format[op] = program[pc] + op = op + 1 + pc = pc + 1 + } + break + } + } + format[op] = EOS + + # Encode the number using the extracted format string. The case of + # a simple decimal encoding is optimized. + + if (format[2] == 'd') + junk = itoc (number, numstr, SZ_NUMSTR) + else { + iferr { + call sprintf (numstr, SZ_NUMSTR, format) + call pargi (number) + } then + numstr[1] = EOS + } + + # Move the encoded number to encoder memory, advancing the i/o + # pointer and taking care not to overrun memory. Leave the iop + # pointing AT, not after, the EOS output by gstrcpy. + + iop = iop + gstrcpy (numstr, memory[iop], top - iop + 1) +end diff --git a/sys/gio/stdgraph/stgescape.x b/sys/gio/stdgraph/stgescape.x new file mode 100644 index 00000000..b52ffd0c --- /dev/null +++ b/sys/gio/stdgraph/stgescape.x @@ -0,0 +1,99 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# STGESCAPE.X -- Stdgraph kernel escape handing code. This is the interface +# between the stdgraph kernel and any supported escape packages. These driver +# routines return TRUE if they recognize the escape and it is private to the +# package, FALSE if the other escape packages may also be interested in the +# routine. +# +# stg_escape standard GKI escape entry point +# +# sge_wstran transform and output escape +# sge_spoolesc process and escape into frame buffer +# +# To add support for a new package of escapes, and entry for the driver routine +# for each family of escapes must be added to each of these procedures. + + +# STG_ESCAPE -- Pass a device dependent instruction on to the kernel. +# The stdgraph kernel does not have any escape functions at present. + +procedure stg_escape (fn, instruction, nwords) + +int fn #I function code +short instruction[ARB] #I instruction data words +int nwords #I length of instruction + +bool sgm_execute() # GIM (Gterm) imaging excapes + +begin + if (sgm_execute (fn, instruction, nwords)) + return +end + + +# SGE_WSTRAN -- Stdgraph escape handling routine called by an interactive +# client (e.g the CL in cursor mode) to apply the workstation transformation +# to a escape and execute the escape. This routine is called for all +# escapes regardless of whether any transformation is necessary, leaving +# it up to the escape code to decide what to do. + +procedure sge_wstran (fn, instruction, x1,y1, x2,y2) + +int fn #I escape sequence function opcode +short instruction[ARB] #I escape instruction data +real x1, y1 #I NDC coords of display rect +real x2, y2 #I NDC coords of display rect + +bool sgm_wstran() # GIM (Gterm) imaging excapes + +begin + if (sgm_wstran (fn, instruction, x1,y1, x2,y2)) + return +end + + +# SGE_WSENABLE -- Stdgraph escape handling routine called by an +# interactive client (e.g the CL in cursor mode) to test whether cursor mode +# scaling of graphics instructions is enabled when cursor mode zoom/pan is +# done. Cursor mode scaling may be disabled if the kernel or graphics device +# does the scaling itself. + +bool procedure sge_wsenable () + +bool enable +bool sgm_wsenable() + +begin + if (sgm_wsenable (enable)) + return (enable) +end + + +# SGE_SPOOLESC -- Stdgraph escape handling routine called by an interactive +# client (e.g the CL in cursor mode) to retain, delete, or edit an escape +# instruction stored in a frame buffer. Ordinary drawing instructions are +# normally retained. If the instruction should only be executed when issued +# it should be deleted. Sometimes an instruction is edited or replaced by +# a different one to be executed the next time the buffered graphics is drawn. +# Sometimes when an instruction is seen earlier instructions must be edited +# or deleted. This routine is called for all escapes, it is up to the escape +# code to decide what to do. The delete instruction callback is called as +# delete_fcn(tr,gki) to delete the instruction pointed to by GKI. + +procedure sge_spoolesc (tr, gki, fn, instruction, bp, buftop, delete_fcn) + +pointer tr #I arg to delete_fcn +pointer gki #I pointer to escape instruction +int fn #U escape sequence function opcode +short instruction[ARB] #U escape instruction data +pointer bp #I frame buffer pointer +pointer buftop #I top+1 of buffered data +int delete_fcn #I function called to delete an instruction + +bool sgm_spoolesc() # GIM (Gterm) imaging excapes + +begin + if (sgm_spoolesc (tr, gki, fn, instruction, bp, buftop, delete_fcn)) + return +end diff --git a/sys/gio/stdgraph/stgfa.x b/sys/gio/stdgraph/stgfa.x new file mode 100644 index 00000000..10cf4d61 --- /dev/null +++ b/sys/gio/stdgraph/stgfa.x @@ -0,0 +1,115 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_FILLAREA -- Fill a closed area. The area is defined by the array of +# points P, consisting of successive (x,y) coordinate pairs outlining the +# area to be filled. + +procedure stg_fillarea (p, npts) + +short p[ARB] #I points defining area outline +int npts #I number of points, i.e., (x,y) pairs + +pointer fa +bool tek_encoding +int lowres_x, lowres_y +int ip, n, sx, sy, len_p, iop, i +int stg_encode() +include "stdgraph.com" + +begin + if (g_enable == NO) + call stg_genab() + + len_p = npts * 2 + + # Update fillarea attributes if necessary. + + fa = SG_FAAP(g_sg) + if (SG_COLOR(g_sg) != FA_COLOR(fa)) { + call stg_ctrl1 ("FC", FA_COLOR(fa)) + SG_COLOR(g_sg) = FA_COLOR(fa) + } + if (SG_FASTYLE(g_sg) != FA_STYLE(fa)) { + call stg_ctrl1 ("FT", FA_STYLE(fa)) + SG_FASTYLE(g_sg) = FA_STYLE(fa) + } + + # Tektronix encoding is treated as a special case for max efficiency. + tek_encoding = + (Memc[g_xy] == '%' && Memc[g_xy+1] == 't' && Memc[g_xy+2] == EOS) + + # Draw the fillarea. If the startfill sequence is defined we assume + # that the device can draw a multipoint fillarea. + + if (Memc[SG_STARTFILL(g_sg)] != EOS) { + for (ip=1; ip <= len_p; ip=ip+2) { + # Output start fillarea sequence. + call ttyputs (g_out, g_tty, Memc[SG_STARTFILL(g_sg)], 1) + n = len_p + + # Encode the points of the fillarea outline (or move to the + # single point to be drawn). + + g_lastx = -1 # clip unresolved points only in the interior + g_lasty = -1 # of the area being drawn. + + g_reg[E_IOP] = 1 + do i = ip, n, 2 { + sx = p[i] + sy = p[i+1] + + # Discard the point if it is not resolved. + lowres_x = sx / g_dxres + lowres_y = sy / g_dyres + if (lowres_x == g_lastx && lowres_y == g_lasty) + next + + g_lastx = lowres_x + g_lasty = lowres_y + + # Transform point into the device window. + sx = int (sx * g_dx) + g_x1 + sy = int (sy * g_dy) + g_y1 + + # Encode the point, appending encoded bytes to g_mem. + # Tek encoding is treated as a special case since it is + # so common; the encoder is used for non-Tek encodings. + + if (tek_encoding) { + iop = g_reg[E_IOP] + 4 + g_mem[iop-4] = g_hixy[sy+1] + g_mem[iop-3] = g_loy[sy+1] + g_mem[iop-2] = g_hixy[sx+1] + g_mem[iop-1] = g_lox[sx+1] + g_reg[E_IOP] = iop + } else { + g_reg[1] = sx + g_reg[2] = sy + if (stg_encode (Memc[g_xy], g_mem, g_reg) != OK) + break + } + + # Flush buffer if nearly full. + if (g_reg[E_IOP] > FLUSH_MEMORY) { + call write (g_out, g_mem, g_reg[E_IOP] - 1) + g_reg[E_IOP] = 1 + } + } + ip = n + + # Flush any output remaining in encoder memory. + if (g_reg[E_IOP] > 1) { + call write (g_out, g_mem, g_reg[E_IOP] - 1) + g_reg[E_IOP] = 1 + } + + # Output end polymarker sequence, or draw the point. + call ttyputs (g_out, g_tty, Memc[SG_ENDFILL(g_sg)], 1) + } + } else { + # If can't do a fill area, just draw the area outline. + call stg_polyline (p, npts) + } +end diff --git a/sys/gio/stdgraph/stgfaset.x b/sys/gio/stdgraph/stgfaset.x new file mode 100644 index 00000000..d5b4c4e7 --- /dev/null +++ b/sys/gio/stdgraph/stgfaset.x @@ -0,0 +1,18 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_FASET -- Set the fillarea attributes. + +procedure stg_faset (gki) + +short gki[ARB] # attribute structure +pointer fa +include "stdgraph.com" + +begin + fa = SG_FAAP(g_sg) + FA_STYLE(fa) = gki[GKI_FASET_FS] + FA_COLOR(fa) = gki[GKI_FASET_CI] +end diff --git a/sys/gio/stdgraph/stgfilter.x b/sys/gio/stdgraph/stgfilter.x new file mode 100644 index 00000000..674f190f --- /dev/null +++ b/sys/gio/stdgraph/stgfilter.x @@ -0,0 +1,165 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include +include "stdgraph.h" + +define MAXCH 16 +define RESET "reset" + + +# SGF_POST_FILTER -- Post the stdgraph tty input filter to the VOS tty driver. +# This input filter is used to intercept and process escape sequences sent by +# the terminal to the IRAF client, to notify the client of events such as a +# terminal reset. + +procedure sgf_post_filter (fd) + +int fd #I terminal file + +int locpr() +extern sgf_ttyfilter() + +begin + # Install stdgraph filter in terminal driver. + call ttseti (fd, TT_FILTER, locpr(sgf_ttyfilter)) + call ttseti (fd, TT_FILTERKEY, ESC) + + # Register escapes with terminal. + call stg_outstr ("EZ", RESET) + call stg_outstr ("ER", "R") +end + + +# SGF_TTYFILTER -- Terminal input filter. + +procedure sgf_ttyfilter (fd, buf, maxch, status) + +int fd #I input file +char buf[ARB] #U input buffer +int maxch #I max chars in buffer +int status #U number of chars in buffer + +char escape[MAXCH] +char svbuf[MAXCH+4] +int ip, op, sp, ch, iomode + +bool streq() +int sgf_getchar(), fstati() +include "stdgraph.com" +define failed_ 91 + +begin + # Disable the filter if reading from the terminal in nonblocking + # raw mode. We shouldn't receive a stdgraph escape at such a time, + # and this code isn't prepared to deal with nonblocking i/o. This + # case occurs, e.g., during a screen size query, where the terminal + # returns an escape sequence to the client (in nonblocking raw mode). + + iomode = fstati (STDIN, F_IOMODE) + if (and (iomode, IO_NDELAY) != 0) + return + + # The escape sequence is of the form "ESC P ESC \", the ANSI + # device control string (DCS). This escape sequence is recognized by + # the vt100 terminal emulator in xgterm, which will accumulate and + # ignore the sequence. This is important because when a terminal + # (xgterm) reset occurs when IRAF is not reading from the terminal in + # raw mode, the character are echoed to the terminal and would be + # printed on the screen if not recognized by the terminal as an + # escape. By using a known escape which xgterm ignores the escape is + # transmitted without being seen by (and probably confusing) the + # user. If the reset occurs while in graphics mode and a cursor read + # is in progress, the terminal will be in raw mode and the sequence + # will not be echoed, hence the problem does not occur. + + ip = 1 + sp = 1 + ch = sgf_getchar (fd, svbuf, sp, buf, ip, maxch, status) + if (ch != ESC) + goto failed_ + ch = sgf_getchar (fd, svbuf, sp, buf, ip, maxch, status) + if (ch != 'P') + goto failed_ + + # Accumulate escape data string. + op = 1 + repeat { + ch = sgf_getchar (fd, svbuf, sp, buf, ip, maxch, status) + if (ch < 0 || op > MAXCH) + goto failed_ + if (ch == ESC) { + escape[op] = EOS + ch = sgf_getchar (fd, svbuf, sp, buf, ip, maxch, status) + break + } else { + escape[op] = ch + op = op + 1 + } + } + + # Process the escape. + if (streq (escape, RESET)) { + call stg_reset() + call ttseti (fd, TT_FILTER, NULL) + if (g_sg != NULL) + SG_UIFDATE(g_sg) = 0 + } else # add additional escapes here + goto failed_ + + # Edit the input buffer to remove the escape. + op = 1 + for ( ; ip <= status && op <= maxch; ip=ip+1) { + buf[op] = buf[ip] + op = op + 1 + } + status = op - 1 + return + +failed_ + # Unrecognized escape. Append any newly read data to the input + # buffer and return all the data. + + if (sp > 1) { + call amovc (svbuf, buf[status+1], sp - 1) + status = status + sp - 1 + } +end + + +# SGF_GETCHAR -- Get a character from the input terminal. ERR or EOF is +# returned if the input is exhausted. If reading in raw mode additional +# reads will be performed as necessary. + +int procedure sgf_getchar (fd, svbuf, sp, buf, ip, maxch, nchars) + +int fd #I input file +char svbuf[ARB] #O save chars as they are read +int sp #U pointer into save buffer +char buf[ARB] #U input buffer +int ip #I input index +int maxch #I max chars in buffer +int nchars #U number of chars in buffer + +int ch +int status + +begin + if (ip > nchars) { + if (maxch == 1) { + call zgetty (fd, svbuf[sp], maxch, status) + if (status <= 0) + return (ERR) + ch = svbuf[sp] + sp = sp + 1 + return (ch) + } else + return (EOF) + } + + ch = buf[ip] + ip = ip + 1 + + return (ch) +end diff --git a/sys/gio/stdgraph/stgflush.x b/sys/gio/stdgraph/stgflush.x new file mode 100644 index 00000000..aada3927 --- /dev/null +++ b/sys/gio/stdgraph/stgflush.x @@ -0,0 +1,14 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_FLUSH -- Flush output. + +procedure stg_flush (dummy) + +int dummy # not used at present +include "stdgraph.com" + +begin + call flush (g_out) +end diff --git a/sys/gio/stdgraph/stggcell.x b/sys/gio/stdgraph/stggcell.x new file mode 100644 index 00000000..2a9aea8c --- /dev/null +++ b/sys/gio/stdgraph/stggcell.x @@ -0,0 +1,15 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# STG_GETCELLARRAY -- Input a cell array, i.e., two dimensional array of pixels +# (greylevels or colors). + +procedure stg_getcellarray (nx, ny, x1,y1, x2,y2) + +int nx, ny # number of pixels in X and Y +int x1, y1 # lower left corner of input window +int x2, y2 # lower left corner of input window + +begin + # Not implemented yet. Won't do much for a graphics terminal, + # but should be functionional. +end diff --git a/sys/gio/stdgraph/stggcur.x b/sys/gio/stdgraph/stggcur.x new file mode 100644 index 00000000..08f2b8b7 --- /dev/null +++ b/sys/gio/stdgraph/stggcur.x @@ -0,0 +1,52 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_GETCURSOR -- Get the position of a cursor. The cursor value is returned +# as a GKI structure on the graphics metacode stream. + +procedure stg_getcursor (cursor) + +int cursor #I cursor to be read or 0 + +int cur, cn +int key, sx, sy, raster, rx, ry +include "stdgraph.com" + +begin + # If cursor=0 read the last cursor referenced, e.g., in a write. + if (cursor > 0) { + SG_CURSOR(g_sg) = cursor + cur = cursor + } else + cur = max (1, SG_CURSOR(g_sg)) + + # Restore graphics mode in case the user has forgotten the \n while + # writing to the status line. + + if (g_enable == NO) + call stg_genab() + + # If the user has locked the logical cursor override runtime selection. + if (g_cursor > 0) + cur = g_cursor + + # Restore the software cursor position before reading? + if (SG_UPDCURSOR(g_sg) == YES) { + sx = SG_CURSOR_X(g_sg) + sy = SG_CURSOR_Y(g_sg) + if (sx != 0 && sy != 0) + call stg_setcursor (sx, sy, cur) + } + + # Physically read the cursor and return value to caller. + call stg_readcursor (cur, cn, key, sx, sy, raster, rx, ry) + call gki_retcursorvalue (g_stream, cn, key, sx, sy, raster, rx, ry) + call flush (g_stream) + + # Save the new position of the cursor for next time. + if (SG_UPDCURSOR(g_sg) == YES) { + SG_CURSOR_X(g_sg) = sx + SG_CURSOR_Y(g_sg) = sy + } +end diff --git a/sys/gio/stdgraph/stggdisab.x b/sys/gio/stdgraph/stggdisab.x new file mode 100644 index 00000000..42ddec62 --- /dev/null +++ b/sys/gio/stdgraph/stggdisab.x @@ -0,0 +1,17 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_GDISAB -- Disable graphics, i.e., issue the GD control sequence. + +procedure stg_gdisab() + +include "stdgraph.com" + +begin + if (g_active == YES && g_out > 0) { + call stgctrl ("GD") + call flush (g_out) + g_enable = NO + } +end diff --git a/sys/gio/stdgraph/stggenab.x b/sys/gio/stdgraph/stggenab.x new file mode 100644 index 00000000..5e350e33 --- /dev/null +++ b/sys/gio/stdgraph/stggenab.x @@ -0,0 +1,17 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_GENAB -- Enable graphics, i.e., issue the GE control sequence. + +procedure stg_genab() + +include "stdgraph.com" + +begin + if (g_active == YES && g_out > 0) { + call stgctrl ("GE") + call flush (g_out) + g_enable = YES + } +end diff --git a/sys/gio/stdgraph/stggim.x b/sys/gio/stdgraph/stggim.x new file mode 100644 index 00000000..a71cd448 --- /dev/null +++ b/sys/gio/stdgraph/stggim.x @@ -0,0 +1,919 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include +include +include +include +include +include "stdgraph.h" + +# STGGIM.X -- GIO.GIM gterm imaging escapes for the stdgraph kernel. The +# routines in this file decode GKI escape instructions and encode serial +# byte sequences which are sent to the server to execute the instruction. +# In some cases the server returns a response which is decoded here and +# encoded as a GKI return value which is returned to the client. + +define SZ_PATBUF 512 +define MAX_ARGS 32 +define TIMEOUT 10000 + + +# SGM_EXECUTE -- Test whether the given instruction is a GIM escape, and +# if so execute it. Return true if the instruction was recognized and +# executed. + +bool procedure sgm_execute (fn, gim, nwords) + +int fn #I function code +short gim[ARB] #I instruction data words +int nwords #I length of gim + +int raster +common /sgmcom/ raster + +begin + switch (fn) { + case GKI_OPENWS, GKI_CLEAR: + call sgm_output ("RI", gim, GIM_RASTERINIT_LEN) + return (false) + + case GIM_RASTERINIT: + call sgm_output ("RI", gim, GIM_RASTERINIT_LEN) + case GIM_CREATERASTER: + call sgm_output ("CR", gim, GIM_CREATERASTER_LEN) + case GIM_DESTROYRASTER: + call sgm_output ("DR", gim, GIM_DESTROYRASTER_LEN) + case GIM_QUERYRASTER: + call sgm_queryraster (gim) + case GIM_SETRASTER: + raster = gim[GIM_SETRASTER_RN] + call sgm_output ("SR", gim, GIM_SETRASTER_LEN) + case GIM_WRITEPIXELS: + call sgm_writepixels (gim) + case GIM_READPIXELS: + call sgm_readpixels (gim) + case GIM_REFRESHPIXELS: + call sgm_output ("RX", gim, GIM_REFRESHPIXELS_LEN) + case GIM_SETPIXELS: + call sgm_output ("SP", gim, GIM_SETPIXELS_LEN) + case GIM_WRITECMAP: + call sgm_writecmap (gim) + case GIM_READCMAP: + call sgm_readcmap (gim) + case GIM_LOADCMAP: + call sgm_output ("LM", gim, GIM_LOADCMAP_LEN) + case GIM_FREECMAP: + call sgm_output ("FL", gim, GIM_FREECMAP_LEN) + case GIM_WRITEIOMAP: + call sgm_iomapwrite (gim) + case GIM_READIOMAP: + call sgm_iomapread (gim) + case GIM_INITMAPPINGS: + call sgm_output ("IM", gim, GIM_INITMAPPINGS_LEN) + case GIM_FREEMAPPING: + call sgm_output ("FM", gim, GIM_FREEMAPPING_LEN) + case GIM_COPYRASTER: + call sgm_output ("CP", gim, GIM_COPYRASTER_LEN) + case GIM_SETMAPPING: + call sgm_output ("SM", gim, GIM_SETMAPPING_LEN) + case GIM_GETMAPPING: + call sgm_getmapping (gim) + case GIM_ENABLEMAPPING: + call sgm_output ("MN", gim, GIM_ENABLEMAPPING_LEN) + case GIM_DISABLEMAPPING: + call sgm_output ("MD", gim, GIM_DISABLEMAPPING_LEN) + case GIM_REFRESHMAPPING: + call sgm_output ("RF", gim, GIM_REFRESHMAPPING_LEN) + + default: + return (false) + } + + return (true) +end + + +# SGM_WSTRAN -- Transform and output a GIM escape. Ignore escapes we +# know nothing about. TRUE is returned if the escape is one which is private +# to the GIM interface. + +bool procedure sgm_wstran (fn, gim, rx1,ry1, rx2,ry2) + +int fn #I escape sequence function opcode +short gim[ARB] #I escape instruction data +real rx1,ry1 #I NDC coords of display rect +real rx2,ry2 #I NDC coords of display rect + +real scale +pointer sp, n_gim +bool status, xflip, yflip +int width, height, dst, src, dt +int wx1, wy1, wx2, wy2, p1, p2 +int sx1, sy1, sx2, sy2, snx, sny +int dx1, dy1, dx2, dy2, dnx, dny +int n_dx1, n_dy1, n_dx2, n_dy2, n_dnx, n_dny +int n_sx1, n_sy1, n_sx2, n_sy2 +int w_dx1, w_dy1, w_dx2, w_dy2 +bool sgm_execute() +define exe_ 91 + +begin + switch (fn) { + case GIM_RASTERINIT, GIM_INITMAPPINGS, + GIM_CREATERASTER, GIM_DESTROYRASTER, GIM_QUERYRASTER, + GIM_GETMAPPING, GIM_ENABLEMAPPING, GIM_DISABLEMAPPING, + GIM_REFRESHMAPPING, GIM_FREEMAPPING, + GIM_READPIXELS, GIM_WRITEPIXELS, GIM_REFRESHPIXELS, GIM_SETPIXELS, + GIM_WRITECMAP, GIM_READCMAP, GIM_LOADCMAP, GIM_FREECMAP, + GIM_WRITEIOMAP, GIM_READIOMAP, + GIM_COPYRASTER, GIM_SETRASTER: + + # These instructions do not require any transformation. + status = sgm_execute (fn, gim, 0) + + case GIM_SETMAPPING: + # Edit setmapping instructions which write to the display window. + # Raster 0 is the display window; only display window coordinates + # are affected by the workstation transformation. + + src = gim[GIM_SETMAPPING_SR] + dst = gim[GIM_SETMAPPING_DR] + dt = gim[GIM_SETMAPPING_DT] + + if (dst == 0 && src != dst) { + call smark (sp) + call salloc (n_gim, GIM_SETMAPPING_LEN, TY_SHORT) + + xflip = false + yflip = false + + # Convert the display rect NDC coordinates to window pixels + # or GKI units, depending upon which coordinate system is + # in use. Note that for NDC the Y axis is flipped relative + # to display window pixel coordinates. + + if (dt == CT_PIXEL) { + call sgm_winsize (width, height) + wx1 = rx1 * (width - 1); wy1 = (1.0 - ry2) * (height - 1) + wx2 = rx2 * (width - 1); wy2 = (1.0 - ry1) * (height - 1) + } else { + width = GKI_MAXNDC + 1; height = GKI_MAXNDC + 1 + wx1 = rx1 * (width - 1); wy1 = ry1 * (height - 1) + wx2 = rx2 * (width - 1); wy2 = ry2 * (height - 1) + } + + sx1 = gim[GIM_SETMAPPING_SX] + snx = gim[GIM_SETMAPPING_SW] + sy1 = gim[GIM_SETMAPPING_SY] + sny = gim[GIM_SETMAPPING_SH] + sx2 = sx1 + snx - 1; sy2 = sy1 + sny - 1 + + dx1 = gim[GIM_SETMAPPING_DX] + dnx = gim[GIM_SETMAPPING_DW] + if (dnx < 0) { + dnx = -dnx + xflip = !xflip + } + dy1 = gim[GIM_SETMAPPING_DY] + dny = gim[GIM_SETMAPPING_DH] + if (dny < 0) { + dny = -dny + yflip = !yflip + } + dx2 = dx1 + dnx - 1; dy2 = dy1 + dny - 1 + + # Compute the intersection of the destination (screen) rect + # of the mapping with the region of the screen WS mapped by + # the workstation transformation. + + n_dx1 = max (wx1, dx1); n_dy1 = max (wy1, dy1) + n_dx2 = min (wx2, dx2); n_dy2 = min (wy2, dy2) + + # If the rectangles do not intersect set up a null mapping + # to temporarily disable the mapping. + + n_dnx = n_dx2 - n_dx1 + 1; n_dny = n_dy2 - n_dy1 + 1 + if (n_dnx <= 0 || n_dny <= 0) { + call amovs (gim, Mems[n_gim], GIM_SETMAPPING_LEN) + Mems[n_gim+GIM_SETMAPPING_SX-1] = 0 + Mems[n_gim+GIM_SETMAPPING_SW-1] = 0 + Mems[n_gim+GIM_SETMAPPING_SY-1] = 0 + Mems[n_gim+GIM_SETMAPPING_SH-1] = 0 + Mems[n_gim+GIM_SETMAPPING_DX-1] = 0 + Mems[n_gim+GIM_SETMAPPING_DW-1] = 0 + Mems[n_gim+GIM_SETMAPPING_DY-1] = 0 + Mems[n_gim+GIM_SETMAPPING_DH-1] = 0 + goto exe_ + } + + # Compute the source rect which maps to the new (intersection) + # destination rect. + + if (snx == 1 || dnx == 1) { + n_sx1 = sx1 + n_sx2 = sx2 + } else { + scale = real(snx - 1) / real(dnx - 1) + n_sx1 = max(0, min(GKI_MAXNDC, + nint((n_dx1 - dx1) * scale + sx1))) + n_sx2 = max(0, min(GKI_MAXNDC, + nint((n_dx2 - dx2) * scale + sx2))) + if (xflip) { + p1 = sx1 + (sx2 - n_sx2) + p2 = sx2 - (n_sx1 - sx1) + n_sx1 = p1; n_sx2 = p2 + } + } + + if (sny == 1 || dny == 1) { + n_sy1 = sy1 + n_sy2 = sy2 + } else { + scale = real(sny - 1) / real(dny - 1) + n_sy1 = max(0, min(GKI_MAXNDC, + nint((n_dy1 - dy1) * scale + sy1))) + n_sy2 = max(0, min(GKI_MAXNDC, + nint((n_dy2 - dy2) * scale + sy2))) + if (yflip) { + p1 = sy1 + (sy2 - n_sy2) + p2 = sy2 - (n_sy1 - sy1) + n_sy1 = p1; n_sy2 = p2 + } + } + + # Scale the destination rect by the amount needed to make the + # WS rect fill the full display window. + + if (wx1 == wx2) { + w_dx1 = 0 + w_dx1 = width - 1 + } else { + scale = real(width - 1) / real(wx2 - wx1) + w_dx1 = max(0, min(GKI_MAXNDC, + nint((n_dx1 - wx1) * scale))) + w_dx2 = max(0, min(GKI_MAXNDC, + nint((n_dx2 - wx1) * scale))) + } + + if (wy1 == wy2) { + w_dy1 = 0 + w_dy1 = height - 1 + } else { + scale = real(height - 1) / real(wy2 - wy1) + w_dy1 = max(0, min(GKI_MAXNDC, + nint((n_dy1 - wy1) * scale))) + w_dy2 = max(0, min(GKI_MAXNDC, + nint((n_dy2 - wy1) * scale))) + } + + # Construct the edited instruction. + call amovs (gim, Mems[n_gim], GIM_SETMAPPING_LEN) + Mems[n_gim+GIM_SETMAPPING_SX-1] = n_sx1 + Mems[n_gim+GIM_SETMAPPING_SW-1] = n_sx2 - n_sx1 + 1 + Mems[n_gim+GIM_SETMAPPING_SY-1] = n_sy1 + Mems[n_gim+GIM_SETMAPPING_SH-1] = n_sy2 - n_sy1 + 1 + Mems[n_gim+GIM_SETMAPPING_DX-1] = w_dx1 + Mems[n_gim+GIM_SETMAPPING_DY-1] = w_dy1 + + n_dnx = max(0, min(GKI_MAXNDC, w_dx2 - w_dx1 + 1)) + if (gim[GIM_SETMAPPING_DW] < 0) + n_dnx = -n_dnx + Mems[n_gim+GIM_SETMAPPING_DW-1] = n_dnx + + n_dny = max(0, min(GKI_MAXNDC, w_dy2 - w_dy1 + 1)) + if (gim[GIM_SETMAPPING_DH] < 0) + n_dny = -n_dny + Mems[n_gim+GIM_SETMAPPING_DH-1] = n_dny + +exe_ + # Execute the edited instruction. + status = sgm_execute (fn, Mems[n_gim], 0) + call sfree (sp) + + } else + status = sgm_execute (fn, gim, 0) + + default: + status = false + } + + return (status) +end + + +# SGM_WSENABLE -- Test if client scaling of graphics drawing instructions is +# enabled. For the stdgraph kernel, these transformations are disabled if +# the raster is other than zero, in which case the graphics server does the +# scaling. + +bool procedure sgm_wsenable (enable) + +bool enable +int raster +common /sgmcom/ raster + +begin + enable = (raster == 0) + return (true) +end + + +# SGM_SPOOLESC -- Process a GIM escape into a frame buffer. All GIM escapes +# are executed when first issued; we just determine whether the escapes are +# preserved in the frame buffer to be executed when the frame is redrawn. +# Ignore escapes we know nothing about. TRUE is returned if the escape is +# one which is private to the GIM interface, i.e., if the escape has been +# processed fully by sgm_spoolesc. + +bool procedure sgm_spoolesc (tr, gki, fn, gim, bp, buftop, delete_fcn) + +pointer tr #I arg to delete_fcn +pointer gki #I pointer to escape instruction +int fn #U escape sequence function opcode +short gim[ARB] #U escape instruction data +pointer bp #I frame buffer pointer +pointer buftop #I top+1 of buffered data +int delete_fcn #I function called to delete an instruction + +pointer ip, itop, esc +int nleft, length, opcode, escape, mp + +begin + switch (fn) { + case GIM_RASTERINIT, GIM_INITMAPPINGS, GIM_FREEMAPPING, + GIM_CREATERASTER, GIM_DESTROYRASTER, GIM_QUERYRASTER, + GIM_GETMAPPING, GIM_ENABLEMAPPING, GIM_DISABLEMAPPING, + GIM_REFRESHMAPPING, GIM_WRITEPIXELS, GIM_READPIXELS, + GIM_REFRESHPIXELS, GIM_SETPIXELS, GIM_COPYRASTER, + GIM_WRITEIOMAP, GIM_READIOMAP, GIM_WRITECMAP, GIM_READCMAP, + GIM_LOADCMAP, GIM_FREECMAP: + + # These escapes are only executed once. + call zcall2 (delete_fcn, tr, gki) + + case GIM_SETRASTER: + ; # Preserve this instruction. + + case GIM_SETMAPPING: + # This escape is saved in the frame buffer and rexecuted when + # the frame is redrawn. This allows the server to buffer the + # image data, but still allows the graphics to be redrawn and + # possibly rescaled in cursor mode. Rexecution of copyraster + # after a screen clear will cause any rasters created and written + # to with createraster/writepixels to be redrawn on the screen. + + ip = bp + itop = gki + + while (ip < itop) { + # Search for the beginning of the next instruction. + while (Mems[ip] != BOI && ip < itop) + ip = ip + 1 + + nleft = itop - ip + if (nleft < 3) + break + else { + length = Mems[ip+GKI_HDR_LENGTH-1] + if (length > nleft) + break + + opcode = Mems[ip+GKI_HDR_OPCODE-1] + escape = Mems[ip+GKI_ESCAPE_FN-1] + + # Disable instruction if same mapping number. + if (opcode == GKI_ESCAPE && escape == GIM_SETMAPPING) { + esc = ip + GKI_ESCAPE_DC - 1 + mp = Mems[esc+GIM_SETMAPPING_MP-1] + if (mp == gim[GIM_SETMAPPING_MP]) + Mems[ip+GKI_HDR_OPCODE-1] = GKI_UNKNOWN + } + + ip = ip + length + } + } + + default: + return (false) + } + + return (true) +end + + +# SGM_WINSIZE -- Get the graphics window size in display pixels. + +procedure sgm_winsize (width, height) + +int width, height #O window size + +short gim_query[GIM_QUERYRASTER_LEN] +short retval[GIM_RET_QRAS_LEN] + +begin + gim_query[GIM_QUERYRASTER_RN] = 0 + call sgm_query ("QR", gim_query, GIM_QUERYRASTER_LEN, + "Qr", retval, GIM_RET_QRAS_LEN) + width = retval[GIM_RET_QRAS_NX] + height = retval[GIM_RET_QRAS_NY] +end + + +# SGM Private Functions. +# --------------------------- + +# SGM_QUERYRASTER -- Return the attributes of a raster. + +procedure sgm_queryraster (gim) + +short gim[ARB] #I encoded instruction +short retval[GIM_RET_QRAS_LEN] +include "stdgraph.com" + +begin + call sgm_query ("QR", gim, GIM_QUERYRASTER_LEN, + "Qr", retval, GIM_RET_QRAS_LEN) + call write (g_stream, retval, GIM_RET_QRAS_LEN * SZ_SHORT) + call flush (g_stream) +end + + +# SGM_WRITEPIXELS -- Write a block of pixels to a raster. + +procedure sgm_writepixels (gim) + +short gim[ARB] #I encoded instruction + +char bias +pointer sp, bp +int nx, ny, npix, i +include "stdgraph.com" + +begin + # Send the write-pixels escape sequence. + call sgm_output ("WP", gim, GIM_WRITEPIXELS_LEN) + + # For the moment this code assumes 8 bit pixels. + nx = gim[GIM_WRITEPIXELS_NX] + ny = gim[GIM_WRITEPIXELS_NY] + npix = nx * ny + + call smark (sp) + call salloc (bp, npix, TY_CHAR) + bias = 040B + + # Send the pixel data encoded in printable ASCII. + call achtbc (gim[GIM_WRITEPIXELS_DATA], Memc[bp], npix) + do i = 1, npix + Memc[bp+i-1] = Memc[bp+i-1] + bias + call write (g_out, Memc[bp], npix) + call putci (g_out, GS) + + call sfree (sp) +end + + +# SGM_READPIXELS -- Read a block of pixels from a raster and return it +# to the client. + +procedure sgm_readpixels (gim) + +short gim[ARB] #I encoded instruction + +pointer sp, bp +int sv_iomode, ch +int npix, nx, ny, i +short retval[GIM_RET_RPIX_LEN] +int fstati(), getci() +include "stdgraph.com" + +begin + sv_iomode = fstati (g_in, F_IOMODE) + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, IO_RAW) + + # Send the read-pixels escape sequence. + call sgm_output ("RP", gim, GIM_READPIXELS_LEN) + call flush (g_out) + + # For the moment this code assumes 8 bit pixels. + nx = gim[GIM_READPIXELS_NX] + ny = gim[GIM_READPIXELS_NY] + npix = nx * ny + + call smark (sp) + call salloc (bp, npix, TY_CHAR) + + # Get the pixel data. This is a block of pixel data encoded as for + # writepixels (040 bias), bracked by ESC at the front and a single + # control character such as \r or \n at the end. + + while (getci (g_in, ch) != EOF) + if (ch == ESC) + break + for (i=0; getci (g_in, ch) >= 040B; ) + if (i < npix) { + Memc[bp+i] = ch - 040B + i = i + 1 + } + npix = i + + # Send the RPIX header to the client. + retval[GIM_RET_RPIX_NP] = npix + call write (g_stream, retval, GIM_RET_RPIX_LEN * SZ_SHORT) + + # Return the data to the client. + call achtcb (Memc[bp], Memc[bp], npix) + call write (g_stream, Memc[bp], (npix + SZB_CHAR-1) / SZB_CHAR) + call flush (g_stream) + + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, sv_iomode) + call sfree (sp) +end + + +# SGM_WRITECMAP -- Write to a segment of the colormap. + +procedure sgm_writecmap (gim) + +short gim[ARB] #I encoded instruction + +short mask +pointer sp, bp, op +int ncells, nchars, ip, i +include "stdgraph.com" + +begin + call smark (sp) + + # Send the write-colormap escape sequence. + call sgm_output ("WM", gim, GIM_WRITECMAP_LEN) + + # Each cell consists of a RGB triplet encoded 2 chars per color. + ncells = gim[GIM_WRITECMAP_NC] + nchars = ncells * 3 * 2 + + call salloc (bp, nchars, TY_CHAR) + ip = GIM_WRITECMAP_DATA + op = bp + + mask = 017B + do i = 1, ncells*3 { + Memc[op] = gim[ip] / 16 + 040B; op = op + 1 + Memc[op] = and (gim[ip], mask) + 040B; op = op + 1 + ip = ip + 1 + } + + call write (g_out, Memc[bp], nchars) + call putci (g_out, GS) + + call sfree (sp) +end + + +# SGM_READCMAP -- Read a segment of the colormap. + +procedure sgm_readcmap (gim) + +short gim[ARB] #I encoded instruction + +pointer sp, bp, cm, ip +int sv_iomode, ncells, nchars, ch, i +short retval[GIM_RET_RCMAP_LEN] +int fstati(), getci() +include "stdgraph.com" + +begin + sv_iomode = fstati (g_in, F_IOMODE) + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, IO_RAW) + + # Send the read-cmap escape sequence. + call sgm_output ("RM", gim, GIM_READCMAP_LEN) + call flush (g_out) + + # Each cell consists of a RGB triplet encoded 2 chars per color. + ncells = gim[GIM_READCMAP_NC] + nchars = ncells * 3 * 2 + + call smark (sp) + call salloc (bp, nchars, TY_CHAR) + call salloc (cm, ncells * 3, TY_SHORT) + + # Get the colormap data. This is a block of RGB colormap triplets + # encoded 2 bytes per color, bracked by a ESC at the front and a + # single control character such as \r or \n at the end. + + while (getci (g_in, ch) != EOF) + if (ch == ESC) + break + for (i=0; getci (g_in, ch) >= 040B; ) + if (i < nchars) { + Memc[bp+i] = ch - 040B + i = i + 1 + } + ncells = i / (3 * 2) + + # Decode the packed colormap data. + ip = bp + do i = 1, ncells * 3 { + Mems[cm+i-1] = (Memc[ip] - 040B) * 16 + (Memc[ip+1] - 040B) + ip = ip + 2 + } + + # Send the read-cmap header to the client. + retval[GIM_RET_RCMAP_NC] = ncells + call write (g_stream, retval, GIM_RET_RCMAP_LEN * SZ_SHORT) + + # Return the colormap data to the client. + call write (g_stream, Mems[cm], (ncells * 3) * SZ_SHORT) + call flush (g_stream) + + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, sv_iomode) + call sfree (sp) +end + + +# SGM_IOMAPWRITE -- Write to the iomap. + +procedure sgm_iomapwrite (gim) + +short gim[ARB] #I encoded instruction + +short mask +pointer sp, bp, op +int ncells, nchars, ip, i +include "stdgraph.com" + +begin + call smark (sp) + + # Send the write-iomap escape sequence. + call sgm_output ("WO", gim, GIM_WRITEIOMAP_LEN) + + # Each cell consists of a single short integer colormap index + # encoded 2 chars per cell. + + ncells = gim[GIM_WRITEIOMAP_NC] + nchars = ncells * 2 + + call salloc (bp, nchars, TY_CHAR) + ip = GIM_WRITEIOMAP_DATA + op = bp + + mask = 017B + do i = 1, ncells { + Memc[op] = gim[ip] / 16 + 040B; op = op + 1 + Memc[op] = and (gim[ip], mask) + 040B; op = op + 1 + ip = ip + 1 + } + + call write (g_out, Memc[bp], nchars) + call putci (g_out, GS) + + call sfree (sp) +end + + +# SGM_IOMAPREAD -- Read a segment of the iomap. + +procedure sgm_iomapread (gim) + +short gim[ARB] #I encoded instruction + +pointer sp, bp, data, ip +int sv_iomode, ncells, nchars, ch, i +short retval[GIM_RET_RIOMAP_LEN] +int fstati(), getci() +include "stdgraph.com" + +begin + sv_iomode = fstati (g_in, F_IOMODE) + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, IO_RAW) + + # Send the read-iomap escape sequence. + call sgm_output ("RO", gim, GIM_READIOMAP_LEN) + call flush (g_out) + + # The data is encoded two bytes per short integer value. + ncells = gim[GIM_READIOMAP_NC] + nchars = ncells * 2 + + call smark (sp) + call salloc (bp, nchars, TY_CHAR) + call salloc (data, ncells, TY_SHORT) + + # Get the iomap data. This is a block of iomap values encoded + # 2 bytes per value, bracked by a ESC at the front and a single + # control character such as \r or \n at the end. + + while (getci (g_in, ch) != EOF) + if (ch == ESC) + break + for (i=0; getci (g_in, ch) >= 040B; ) + if (i < nchars) { + Memc[bp+i] = ch - 040B + i = i + 1 + } + ncells = i / 2 + + # Decode the packed iomap data. + ip = bp + do i = 1, ncells { + Mems[data+i-1] = (Memc[ip] - 040B) * 16 + (Memc[ip+1] - 040B) + ip = ip + 2 + } + + # Send the read-iomap header to the client. + retval[GIM_RET_RIOMAP_NC] = ncells + call write (g_stream, retval, GIM_RET_RIOMAP_LEN * SZ_SHORT) + + # Return the iomap data to the client. + call write (g_stream, Mems[data], ncells * SZ_SHORT) + call flush (g_stream) + + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, sv_iomode) + call sfree (sp) +end + + +# SGM_GETMAPPING -- Return the attributes of a mapping. + +procedure sgm_getmapping (gim) + +short gim[ARB] #I encoded instruction +short retval[GIM_RET_GMAP_LEN] +include "stdgraph.com" + +begin + call sgm_query ("GM", gim, GIM_GETMAPPING_LEN, + "Gm", retval, GIM_RET_GMAP_LEN) + call write (g_stream, retval, GIM_RET_GMAP_LEN * SZ_SHORT) + call flush (g_stream) +end + + +# SGM_OUTPUT -- Format and output a control sequence to the graphics server +# device. + +procedure sgm_output (cap, gim, nargs) + +char cap[ARB] #I graphcap capability name +short gim[ARB] #I instruction (array of int args) +int nargs #I number of arguments + +int ival, i +pointer sp, fmt, ctrl +include "stdgraph.com" +int ttygets() +errchk ttygets + +begin + call smark (sp) + call salloc (fmt, SZ_LINE, TY_CHAR) + call salloc (ctrl, SZ_LINE, TY_CHAR) + + if (ttygets (g_tty, cap, Memc[fmt], SZ_LINE) > 0) { + call sprintf (Memc[ctrl], SZ_LINE, Memc[fmt]) + do i = 1, nargs { + # Pass the argument as an integer to avoid INDEF + # processing of -32767, a valid GKI value. + ival = gim[i] + iferr (call pargi (ival)) + ; + } + call ttyputs (g_out, g_tty, Memc[ctrl], 1) + } + + call sfree (sp) +end + + +# SGM_QUERY -- Output an inquiry control sequence to the server and read and +# decode the server's response. + +procedure sgm_query (query_cap, gim, nargs, retval_cap, retval, nout) + +char query_cap[ARB] #I server query cap name +short gim[ARB] #I query instruction (args) +int nargs #I number of args for server query +char retval_cap[ARB] #I cap name for return value format +short retval[ARB] #O decoded output arguments +int nout #I number of output arguments + +int index[MAX_ARGS] +pointer sp, ctrl, patbuf, pat, buf, ip, op +int sv_iomode, arg, ch, nchars, start, value, ival, i +int patmake(), patindex(), ttyread(), ctoi() +int ttygets(), fstati(), gstrcpy() +include "stdgraph.com" +define done_ 91 +errchk ttygets + +begin + call smark (sp) + call salloc (ctrl, SZ_LINE, TY_CHAR) + call salloc (buf, SZ_LINE, TY_CHAR) + call salloc (pat, SZ_LINE, TY_CHAR) + call salloc (patbuf, SZ_PATBUF, TY_CHAR) + + call aclrs (retval, nout) + + # Set raw mode i/o. + sv_iomode = fstati (g_in, F_IOMODE) + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, IO_RAW) + + # Pass the query on to the server. + if (ttygets (g_tty, query_cap, Memc[pat], SZ_LINE) > 0) { + call sprintf (Memc[ctrl], SZ_LINE, Memc[pat]) + do i = 1, nargs { + # Pass the argument as an integer to avoid INDEF + # processing of -32767, a valid GKI value. + ival = gim[i] + iferr (call pargi (ival)) + ; + } + call ttyputs (g_out, g_tty, Memc[ctrl], 1) + call flush (g_out) + + } else + goto done_ + + # Encode a pattern to match the server's response as given by the + # pattern in retval_cap. + + if (ttygets (g_tty, retval_cap, Memc[pat], SZ_LINE) <= 0) + goto done_ + + # Process the retval_cap string, used to specify the format of the + # string returned by the server, to map the %N fields therein into + # the pattern strings "%[0-9]*", noting the index positions of the + # pattern substrings for later decoding. + + call aclri (index, MAX_ARGS) + arg = 0 + + op = buf + for (ip=pat; Memc[ip] != EOS; ip=ip+1) { + if (Memc[ip] == '%') { + if (Memc[ip+1] == '%') { + Memc[op] = Memc[ip] + op = op + 1 + ip = ip + 1 + } else { + op = op + gstrcpy ("%[0-9]*", Memc[op], ARB) + ip = ip + 1 + + # Arguments are %1 ... %9, %a, %b, etc. + ch = Memc[ip] + if (IS_DIGIT(ch)) + i = TO_INTEG(ch) + else if (IS_UPPER(ch)) + i = ch - 'A' + 10 + else + i = ch - 'a' + 10 + + arg = arg + 1 + i = min(MAX_ARGS, max(1, i)) + index[i] = arg + } + } else if (Memc[ip] == '[') { + Memc[op] = '\\'; op = op + 1 + Memc[op] = '[' ; op = op + 1 + } else { + Memc[op] = Memc[ip] + op = op + 1 + } + } + + Memc[op] = EOS + if (patmake (Memc[buf], Memc[patbuf], SZ_PATBUF) >= SZ_PATBUF) + goto done_ + + # Scan the input stream from the server until data matching the + # response pattern is received, or a timeout occurs. + + nchars = ttyread (g_in, g_tty,Memc[buf],SZ_LINE,Memc[patbuf], TIMEOUT) + if (nchars > 0) { + do i = 1, nout { + value = 0 + if (index[i] > 0) { + start = patindex (Memc[patbuf], index[i]) + if (ctoi (Memc[buf], start, value) <= 0) + value = 0 + } + retval[i] = value + } + } +done_ + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, sv_iomode) + call sfree (sp) +end diff --git a/sys/gio/stdgraph/stggrstr.x b/sys/gio/stdgraph/stggrstr.x new file mode 100644 index 00000000..946b52d9 --- /dev/null +++ b/sys/gio/stdgraph/stggrstr.x @@ -0,0 +1,16 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_GRSTREAM -- Set the FD of the graphics stream, from which we shall read +# metacode instructions and to which we shall return cell arrays and cursor +# values. + +procedure stg_grstream (stream) + +int stream # FD of the new graphics stream +include "stdgraph.com" + +begin + g_stream = stream +end diff --git a/sys/gio/stdgraph/stginit.x b/sys/gio/stdgraph/stginit.x new file mode 100644 index 00000000..3e393be4 --- /dev/null +++ b/sys/gio/stdgraph/stginit.x @@ -0,0 +1,193 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include +include +include "stdgraph.h" + +# STG_INIT -- Initialize the stdgraph data structures from the graphcap entry +# for the device. Called once, at OPENWS time, with the TTY pointer already +# set in the common. The companion routine STG_RESET initializes the attribute +# packets when the screen is cleared. + +procedure stg_init (tty, devname) + +pointer tty # graphcap descriptor +char devname[ARB] # device name + +pointer nextch +bool first_time +int maxch, i, junk +real char_height, char_width, char_size + +bool ttygetb() +real ttygetr() +pointer stg_gstring() +int ttygets(), ttygeti(), btoi(), stg_encode(), gstrcpy() +include "stdgraph.com" +data first_time /true/ + +begin + # One time initialization. + if (first_time) { + # Initialize the Tek 4012 coordinate encoding lookup tables. + do i = 1, TEK_XRES { + g_hixy[i] = (i-1) / 40B + 40B + g_lox[i] = mod ((i-1), 40B) + 100B + } + do i = 1, TEK_YRES + g_loy[i] = mod ((i-1), 40B) + 140B + + first_time = false + } + + # Allocate the stdgraph descriptor and the string buffer. + call calloc (g_sg, LEN_SG, TY_STRUCT) + call malloc (SG_SBUF(g_sg), SZ_SBUF, TY_CHAR) + + # Init string buffer parameters. The first char of the string buffer + # is reserved as a null string, used for graphcap control strings + # omitted from the graphcap entry for the device. + + SG_SZSBUF(g_sg) = SZ_SBUF + SG_NEXTCH(g_sg) = SG_SBUF(g_sg) + 1 + Memc[SG_SBUF(g_sg)] = EOS + + # Set the software device resolution and the coordinate transformations + # to the resolution space and from GKI to device coords. The values + # g_[xy]res were initialized when the kernel was opened by the main + # program. + + call stg_resolution (g_xres, g_yres) + + # Initialize the encoder. The graphcap parameter LR contains encoder + # instructions to perform any device dependent initialization required. + + call aclri (g_reg, NREGISTERS) + nextch = SG_NEXTCH(g_sg) + + g_reg[E_IOP] = 1 + g_reg[E_TOP] = SZ_MEMORY + if (ttygets (tty, "LR", Memc[nextch], SZ_SBUF-1) > 0) + junk = stg_encode (Memc[nextch], g_mem, g_reg) + + # If the device does not support hardware character generation, set + # txquality to high to get software character generation. + + if (!ttygetb (tty, "tx")) + g_hardchar = GT_HIGH + + # Initialize the character scaling parameters, required for text + # generation. The heights are given in NDC units in the graphcap + # file, which we convert to GKI units. Estimated values are + # supplied if the parameters are missing in the graphcap entry. + + char_height = ttygetr (tty, "ch") + if (char_height < EPSILON) + char_height = 1.0 / 35.0 + char_height = char_height * GKI_MAXNDC + + char_width = ttygetr (tty, "cw") + if (char_width < EPSILON) + char_width = 1.0 / 80.0 + char_width = char_width * GKI_MAXNDC + + # If the device has a set of discrete character sizes, get the + # size of each by fetching the parameter "tN", where the N is + # a digit specifying the text size index. Compute the height and + # width of each size character from the "ch" and "cw" parameters + # and the relative scale of character size I. + + SG_NCHARSIZES(g_sg) = min (MAX_CHARSIZES, ttygeti (tty, "th")) + nextch = SG_NEXTCH(g_sg) + + if (SG_NCHARSIZES(g_sg) <= 0) { + SG_NCHARSIZES(g_sg) = 1 + SG_CHARSIZE(g_sg,1) = 1.0 + } else { + Memc[nextch+2] = EOS + for (i=1; i <= SG_NCHARSIZES(g_sg); i=i+1) { + Memc[nextch] = 't' + Memc[nextch+1] = TO_DIGIT(i) + char_size = ttygetr (tty, Memc[nextch]) + SG_CHARSIZE(g_sg,i) = char_size + SG_CHARHEIGHT(g_sg,i) = char_height * char_size + SG_CHARWIDTH(g_sg,i) = char_width * char_size + } + } + + # Initialize the output parameters. All boolean parameters are stored + # as integer flags. All string valued parameters are stored in the + # string buffer, saving a pointer to the string in the stdgraph + # descriptor. If the capability does not exist the pointer is set to + # point to the null string at the beginning of the string buffer. + + SG_POLYLINE(g_sg) = btoi (ttygetb (tty, "PL")) + SG_POLYMARKER(g_sg) = btoi (ttygetb (tty, "pm")) + SG_FILLAREA(g_sg) = btoi (ttygetb (tty, "fa")) + + SG_ENCODEXY(g_sg) = stg_gstring ("XY") + g_xy = SG_ENCODEXY(g_sg) + + SG_STARTDRAW(g_sg) = stg_gstring ("DS") + SG_ENDDRAW(g_sg) = stg_gstring ("DE") + SG_STARTMOVE(g_sg) = stg_gstring ("VS") + SG_ENDMOVE(g_sg) = stg_gstring ("VE") + SG_STARTMARK(g_sg) = stg_gstring ("MS") + SG_ENDMARK(g_sg) = stg_gstring ("ME") + SG_STARTFILL(g_sg) = stg_gstring ("FS") + SG_ENDFILL(g_sg) = stg_gstring ("FE") + SG_STARTTEXT(g_sg) = stg_gstring ("TS") + SG_ENDTEXT(g_sg) = stg_gstring ("TE") + + # Initialize the input parameters. + SG_CURSOR(g_sg) = 0 + SG_UPDCURSOR(g_sg) = btoi (ttygetb (tty, "UC")) + SG_CURSOR_X(g_sg) = 0 + SG_CURSOR_Y(g_sg) = 0 + + # Save the device string in the descriptor. + nextch = SG_NEXTCH(g_sg) + SG_DEVNAME(g_sg) = nextch + maxch = SG_SBUF(g_sg) + SZ_SBUF - nextch + 1 + nextch = nextch + gstrcpy (devname, Memc[nextch], maxch) + 1 + + # Initialize the UIFNAME field. + SG_UIFNAME(g_sg) = nextch + Memc[nextch] = EOS + nextch = nextch + SZ_UIFNAME + 1 + SG_NEXTCH(g_sg) = nextch +end + + +# STG_GSTRING -- Get a string value parameter from the graphcap table, +# placing the string at the end of the string buffer. If the device does +# not have the named capability return a pointer to the null string, +# otherwise return a pointer to the string. Since pointers are used, +# rather than indices, the string buffer is fixed in size. The additional +# degree of indirection required with an index was not considered worthwhile +# in this application since the graphcap entries are never very large. + +pointer procedure stg_gstring (cap) + +char cap[ARB] # device capability to be fetched +pointer strp, nextch +int maxch, nchars +int ttygets() +include "stdgraph.com" + +begin + nextch = SG_NEXTCH(g_sg) + maxch = SG_SBUF(g_sg) + SZ_SBUF - nextch + 1 + + nchars = ttygets (g_tty, cap, Memc[nextch], maxch) + if (nchars > 0) { + strp = nextch + nextch = nextch + nchars + 1 + } else + strp = SG_SBUF(g_sg) + + SG_NEXTCH(g_sg) = nextch + return (strp) +end diff --git a/sys/gio/stdgraph/stglkcur.x b/sys/gio/stdgraph/stglkcur.x new file mode 100644 index 00000000..6152534b --- /dev/null +++ b/sys/gio/stdgraph/stglkcur.x @@ -0,0 +1,18 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_LOCKCURSOR -- Lock the logical cursor number. Called interactively by +# cursor mode in response to a ":.cursor N" command by the user. When the +# cursor is not locked the logical cursor may be selected under program +# control. + +procedure stg_lockcursor (new_cursor) + +int new_cursor # desired new logical cursor +include "stdgraph.com" + +begin + g_cursor = new_cursor +end diff --git a/sys/gio/stdgraph/stgmove.x b/sys/gio/stdgraph/stgmove.x new file mode 100644 index 00000000..5f7396a3 --- /dev/null +++ b/sys/gio/stdgraph/stgmove.x @@ -0,0 +1,27 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_MOVE -- Output a device move instruction to move to the position (x,y) +# in GKI coordinates. + +procedure stg_move (x, y) + +int x, y # destination +int stg_encode() +include "stdgraph.com" + +begin + # Transform the first point from GKI coords to device coords and + # move to the transformed point. + + call ttyputs (g_out, g_tty, Memc[SG_STARTMOVE(g_sg)], 1) + + g_reg[1] = x * g_dx + g_x1 + g_reg[2] = y * g_dy + g_y1 + g_reg[E_IOP] = 1 + if (stg_encode (Memc[g_xy], g_mem, g_reg) == OK) + call write (g_out, g_mem, g_reg[E_IOP] - 1) + + call ttyputs (g_out, g_tty, Memc[SG_ENDMOVE(g_sg)], 1) +end diff --git a/sys/gio/stdgraph/stgonerr.x b/sys/gio/stdgraph/stgonerr.x new file mode 100644 index 00000000..047c6152 --- /dev/null +++ b/sys/gio/stdgraph/stgonerr.x @@ -0,0 +1,17 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_ONERROR -- Called when error recovery takes place to deactivate the +# stdgraph workstation, i.e., take the terminal out of graphics mode. If +# this is not done error messages will be written as vectors. + +procedure stg_onerror (errcode) + +int errcode +include "stdgraph.com" + +begin + if (g_active == YES) + call stg_deactivatews (0) +end diff --git a/sys/gio/stdgraph/stgonint.x b/sys/gio/stdgraph/stgonint.x new file mode 100644 index 00000000..2aed03ee --- /dev/null +++ b/sys/gio/stdgraph/stgonint.x @@ -0,0 +1,21 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "stdgraph.h" + +# STG_ONINT -- Interrupt handler for the stdgraph kernel. If an interrupt +# occurs while we are posted to an exception, branch to the last ZSVJMP. +# (This library procedure is not currently used by the kernel). + +procedure stg_onint (vex, next_handler) + +int vex # virtual exception +int next_handler # next exception handler in chain +int jmpbuf[LEN_JUMPBUF] +common /stgxin/ jmpbuf + +begin + call xer_reset() + call zdojmp (jmpbuf, vex) +end diff --git a/sys/gio/stdgraph/stgopen.x b/sys/gio/stdgraph/stgopen.x new file mode 100644 index 00000000..47fb2b61 --- /dev/null +++ b/sys/gio/stdgraph/stgopen.x @@ -0,0 +1,103 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "stdgraph.h" + +# STG_OPEN -- Install the STDGRAPH kernel as a graphics kernel device driver. +# The device table DD consists of an array of the entry point addresses for +# the driver procedures. If a driver does not implement a particular +# instruction the table entry for that procedure may be set to zero, causing +# the interpreter to ignore the instruction. + +procedure stg_open (devname, dd, in, out, xres, yres, hardchar) + +char devname[ARB] # if nonnull, force output to device +int dd[ARB] # device table to be initialized +int in # input file +int out # output file +int xres # number of resolved pixels in X +int yres # number of resolved pixels in Y +int hardchar # use hardware character generator + +bool first_time +pointer sp, devns +int len_devname +int locpr(), strlen() + +extern stg_openws(), stg_closews(), stg_clear(), stg_cancel() +extern stg_flush(), stg_polyline(), stg_polymarker(), stg_text() +extern stg_fillarea(), stg_putcellarray(), stg_setcursor(), stg_plset() +extern stg_pmset(), stg_txset(), stg_faset(), stg_getcursor() +extern stg_getcellarray(), stg_escape() +extern stg_reactivatews(), stg_deactivatews() +include "stdgraph.com" +data first_time /true/ + +begin + call smark (sp) + call salloc (devns, SZ_FNAME, TY_SHORT) + + if (first_time) { + g_nopen = 0 + g_sg = NULL + g_tty = NULL + g_term = NULL + g_pbtty = NULL + g_cursor = 0 + first_time = false + } + + g_in = in + g_out = out + g_xres = xres + g_yres = yres + g_nopen = g_nopen + 1 + g_stream = STDGRAPH + g_hardchar = hardchar + g_active = NO + g_enable = NO + g_message = NO + g_msgbuf = NULL + g_msgbuflen = 0 + g_msglen = 0 + call strcpy (devname, g_device, SZ_GDEVICE) + + # Install the device driver. + dd[GKI_OPENWS] = locpr (stg_openws) + dd[GKI_CLOSEWS] = locpr (stg_closews) + dd[GKI_REACTIVATEWS] = locpr (stg_reactivatews) + dd[GKI_DEACTIVATEWS] = locpr (stg_deactivatews) + dd[GKI_MFTITLE] = 0 + dd[GKI_CLEAR] = locpr (stg_clear) + dd[GKI_CANCEL] = locpr (stg_cancel) + dd[GKI_FLUSH] = locpr (stg_flush) + dd[GKI_POLYLINE] = locpr (stg_polyline) + dd[GKI_POLYMARKER] = locpr (stg_polymarker) + dd[GKI_TEXT] = locpr (stg_text) + dd[GKI_FILLAREA] = locpr (stg_fillarea) + dd[GKI_PUTCELLARRAY] = locpr (stg_putcellarray) + dd[GKI_SETCURSOR] = locpr (stg_setcursor) + dd[GKI_PLSET] = locpr (stg_plset) + dd[GKI_PMSET] = locpr (stg_pmset) + dd[GKI_TXSET] = locpr (stg_txset) + dd[GKI_FASET] = locpr (stg_faset) + dd[GKI_GETCURSOR] = locpr (stg_getcursor) + dd[GKI_GETCELLARRAY] = locpr (stg_getcellarray) + dd[GKI_ESCAPE] = locpr (stg_escape) + dd[GKI_SETWCS] = 0 + dd[GKI_GETWCS] = 0 + dd[GKI_UNKNOWN] = 0 + + # If a device was named open the workstation as well. This is + # necessary to permit processing of metacode files which do not + # contain the open workstation instruction. + + len_devname = strlen (devname) + if (len_devname > 0) { + call achtcs (devname, Mems[devns], len_devname) + call stg_openws (Mems[devns], len_devname, NEW_FILE) + } + + call sfree (sp) +end diff --git a/sys/gio/stdgraph/stgopenws.x b/sys/gio/stdgraph/stgopenws.x new file mode 100644 index 00000000..a70a51f7 --- /dev/null +++ b/sys/gio/stdgraph/stgopenws.x @@ -0,0 +1,220 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include +include +include +include "stdgraph.h" + +# STG_OPENWS -- Open the named workstation. Once a workstation has been +# opened we leave it open until some other workstation is opened or the +# kernel is closed. Opening a workstation involves initialization of the +# kernel data structures, followed by initialization of the device itself. + +procedure stg_openws (devname, n, mode) + +short devname[ARB] #I device name (actually device[,uifname]) +int n #I length of device name +int mode #I access mode + +bool reinit +long fi[LEN_FINFO] +int dummy, init_file +pointer sp, ip, op, buf, device, uifname, fname + +pointer ttygdes(), ttyodes() +bool ttygetb(), strne(), streq() +int ttygets(), open(), ttstati(), finfo(), gstrcpy() +int nowhite(), envfind(), strlen(), fnroot(), access() +extern stg_onerror() +include "stdgraph.com" +define ow_ 91 + +begin + call smark (sp) + call salloc (buf, max (SZ_PATHNAME, n), TY_CHAR) + call salloc (fname, SZ_PATHNAME, TY_CHAR) + + # Open a termcap descriptor for the terminal too, in case we need + # to talk to the terminal as a terminal. + + if (g_term == NULL) + iferr (g_term = ttyodes ("terminal")) + g_term = NULL + + # If we are appending merely reactivate the device without performing + # any initialization. + + if (g_sg != NULL && mode == APPEND) { + if (g_active == NO) { + g_ucaseout = ttstati (g_out, TT_UCASEOUT) + if (g_ucaseout == YES) + call ttseti (g_out, TT_UCASEOUT, NO) + + g_active = YES + g_enable = YES + } + goto ow_ + } + + # If a device was named when the kernel was opened then output will + # always go to that device (g_device) regardless of the device named + # in the OPENWS instruction. If no device was named (null string) + # then unpack the device name, passed as a short integer array. + + if (g_device[1] == EOS) { + call achtsc (devname, Memc[buf], n) + Memc[buf+n] = EOS + } else + call strcpy (g_device, Memc[buf], SZ_FNAME) + + # Parse the "device,uifname" specification into the two fields. + device = buf + uifname = NULL + for (ip=buf; Memc[ip] != EOS; ip=ip+1) + if (Memc[ip] == ',') { + Memc[ip] = EOS + if (Memc[ip+1] != EOS) + uifname = ip + 1 + if (nowhite (Memc[uifname], Memc[uifname], ARB) == 0) + uifname = NULL + break + } + + # If the kernel is already open for this device skip most of the + # initialization. If already open for a different device free + # storage before reinitialization. + + reinit = true + if (g_sg != NULL) + if (strne (Memc[device], Memc[SG_DEVNAME(g_sg)])) { + call mfree (SG_SBUF(g_sg), TY_CHAR) + call mfree (g_sg, TY_STRUCT) + reinit = true + } else + reinit = false + + # Reinitialize the kernel datastructures. Open graphcap descriptor + # for the named device, allocate and initialize descriptor and common. + + if (reinit) { + if (g_tty != NULL) { + call ttycdes (g_tty) + g_tty = NULL + } + + iferr (g_tty = ttygdes (Memc[device])) { + g_tty = ttygdes ("4012") + call erract (EA_WARN) + } + + # Initialize data structures. + call stg_init (g_tty, Memc[device]) + } + + call stg_reset() + + if (g_active == NO) { + # Must disable stty ucaseout mode when in graphics mode, else + # plotting commands may be modified by the terminal driver. + + g_ucaseout = ttstati (g_out, TT_UCASEOUT) + if (g_ucaseout == YES) + call ttseti (g_out, TT_UCASEOUT, NO) + + # Post ONERROR cleanup routine. + call onerror (stg_onerror) + g_active = YES + g_enable = YES + } + + # If no UI file was specified but the device has the EM capability, + # use the default UI if any specified in the graphcap entry. If the + # EM capability is missing, ignore any uifname specified when the + # device was opened. + + if (ttygetb (g_tty, "EM")) { + if (uifname == NULL) { + uifname = buf + strlen(Memc[device]) + 1 + if (ttygets (g_tty, "ED", Memc[uifname], ARB) <= 0) + uifname = NULL + } + + # If the user has a version of the named UI file in their GUIDIR, + # use that instead. + + if (envfind (GUIDIR, Memc[fname], SZ_PATHNAME) > 0) { + op = fname + strlen (Memc[fname]) + op = op + fnroot (Memc[uifname], Memc[op], + fname + SZ_PATHNAME - op) + op = op + gstrcpy (".gui", Memc[op], fname + SZ_PATHNAME - op) + if (access (Memc[fname], 0, 0) == YES) + uifname = fname + } + + # If the UI is already running and has not been modified there + # is no need to download it again. + + if (g_sg != NULL) + if (streq (Memc[uifname], Memc[SG_UIFNAME(g_sg)])) + if (finfo (Memc[uifname], fi) != ERR) + if (SG_UIFDATE(g_sg) == FI_MTIME(fi)) + uifname = NULL + } else { + # Ignore UI file if no EM capability. + Memc[SG_UIFNAME(g_sg)] = EOS + SG_UIFDATE(g_sg) = 0 + uifname = NULL + } + + # Open and Initialize the device. Output contents of UI definition + # file if any, followed by graphics device initialization file, + # if any. + + if (mode == NEW_FILE) { + # Output UI definition file. + if (uifname != NULL) { + iferr (init_file = open (Memc[uifname], READ_ONLY, TEXT_FILE)) { + call erract (EA_WARN) + call stg_ctrl ("OW") + } else { + call flush (g_out) + call stg_ctrl ("EM") + + # Download the UI. + call putline (g_out, "server ") + iferr (call fcopyo (init_file, g_out)) + call erract (EA_WARN) + call close (init_file) + + # Record particulars of active UI file. + call strcpy (Memc[uifname], Memc[SG_UIFNAME(g_sg)], + SZ_UIFNAME) + if (finfo (Memc[uifname], fi) != ERR) + SG_UIFDATE(g_sg) = FI_MTIME(fi) + call sgf_post_filter (g_out) + + call putci (g_out, US) + call flush (g_out) + } + } else + call stg_ctrl ("OW") + + # Output device graphics initialization file if any. + if (ttygets (g_tty, "IF", Memc[buf], SZ_FNAME) > 0) { + iferr (init_file = open (Memc[buf], READ_ONLY, TEXT_FILE)) + call erract (EA_WARN) + iferr (call fcopyo (init_file, g_out)) + call erract (EA_WARN) + call close (init_file) + } + + # Clear the screen if device is being opened in new_file mode. + call stg_clear (dummy) + + } else +ow_ call stg_ctrl ("OW") + + call sfree (sp) +end diff --git a/sys/gio/stdgraph/stgoutput.x b/sys/gio/stdgraph/stgoutput.x new file mode 100644 index 00000000..098af6e7 --- /dev/null +++ b/sys/gio/stdgraph/stgoutput.x @@ -0,0 +1,28 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_OUTPUT2 -- Encode two arguments using the program given and write the +# encoded character string to the output file. + +procedure stg_output2 (fd, program, arg1, arg2) + +int fd # output file +char program[ARB] # encoder program defining encoding +int arg1 # argument to be placed in register 1 +int arg2 # argument to be placed in register 2 + +int stg_encode() +include "stdgraph.com" + +begin + # Set up encoder. + g_reg[1] = arg1 + g_reg[2] = arg2 + g_reg[E_IOP] = 1 + + # Encode the output string and write the encoded string to the output + # file. + if (stg_encode (g_xy, g_mem, g_reg) == OK) + call write (fd, g_mem, g_reg[E_IOP] - 1) +end diff --git a/sys/gio/stdgraph/stgoutstr.x b/sys/gio/stdgraph/stgoutstr.x new file mode 100644 index 00000000..2d854e75 --- /dev/null +++ b/sys/gio/stdgraph/stgoutstr.x @@ -0,0 +1,30 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_OUTSTR -- Format and output a control sequence containing a string +# string argument to the output device. + +procedure stg_outstr (cap, strval) + +char cap[ARB] #I graphcap capability name +char strval[ARB] #I string data + +pointer sp, fmt, ctrl +include "stdgraph.com" +int ttygets() +errchk ttygets + +begin + call smark (sp) + call salloc (fmt, SZ_LINE, TY_CHAR) + call salloc (ctrl, SZ_LINE, TY_CHAR) + + if (ttygets (g_tty, cap, Memc[fmt], SZ_LINE) > 0) { + call sprintf (Memc[ctrl], SZ_LINE, Memc[fmt]) + call pargstr (strval) + call ttyputs (g_out, g_tty, Memc[ctrl], 1) + } + + call sfree (sp) +end diff --git a/sys/gio/stdgraph/stgpcell.x b/sys/gio/stdgraph/stgpcell.x new file mode 100644 index 00000000..476d90cf --- /dev/null +++ b/sys/gio/stdgraph/stgpcell.x @@ -0,0 +1,85 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +define ZSTEP 4 # bit to be tested (step function width) + + +# STG_PUTCELLARRAY -- Draw a cell array, i.e., two dimensional array of pixels +# (greylevels or colors). The algorithm used here maps 8 bits in into 1 bit +# out, using a step function lookup table. The result is a band-contoured +# image, where the spacing and width of the contour bands decreases as the +# rate of change of intensity in the input cell array increases. + +procedure stg_putcellarray (m, nx, ny, ax1,ay1, ax2,ay2) + +short m[nx,ny] # cell array +int nx, ny # number of pixels in X and Y +int ax1, ay1 # lower left corner of output window +int ax2, ay2 # upper right corner of output window + +real dx, dy +int my, i1, i2, v, i, j, k +include "stdgraph.com" +int and() + +begin + # Set polyline width to 1 for max y-res. + call stg_ctrl1 ("LW", 1) + SG_PLWIDTH(g_sg) = 1 + + # Determine the width of a cell array pixel in GKI units. + dx = real (ax2 - ax1) / nx + + # Determine the height of a device pixel in GKI units. + dy = max (1.0, real(GKI_MAXNDC) / real(g_yres)) + + # Process the cell array. The outer loop runs over device pixels in Y; + # each iteration writes one line of the output raster. The inner loop + # runs down a line of the cell array. + + k = 0 + for (my = ay1 + dy/2; my < ay2; my = k * dy + ay1) { + j = max(1, min(ny, int (real(my-ay1) / real(ay2-ay1) * (ny-1)) + 1)) + my = min (my, int (ay2 - dy/2)) + + for (i=1; i <= nx; ) { + do i = i, nx { + v = m[i,j] + if (and (v, ZSTEP) != 0) + break + } + + if (i <= nx) { + i1 = i + i2 = nx + do i = i1 + 1, nx { + v = m[i,j] + if (and (v, ZSTEP) == 0) { + i2 = i + break + } + } + + # The following decreases the length of dark line segments + # to make features more visible. + + if (i2 - i1 >= 2) + if (i1 > 1 && i2 < nx) { + i1 = i1 + 1 + i2 = i2 - 1 + } + + # Draw the line segment. + call stg_move (int ((i1-1) * dx + ax1), my) + call stg_draw (int (i2 * dx + ax1), my) + + if (i2 >= nx) + i = nx + 1 + } + } + + k = k + 1 + } +end diff --git a/sys/gio/stdgraph/stgpl.x b/sys/gio/stdgraph/stgpl.x new file mode 100644 index 00000000..894a92c3 --- /dev/null +++ b/sys/gio/stdgraph/stgpl.x @@ -0,0 +1,126 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_POLYLINE -- Draw a polyline. The polyline is defined by the array of +# points P, consisting of successive (x,y) coordinate pairs. The first point +# is not plotted but rather defines the start of the polyline. The remaining +# points define line segments to be drawn. + +procedure stg_polyline (p, npts) + +short p[ARB] # points defining line +int npts # number of points, i.e., (x,y) pairs + +pointer pl +bool tek_encoding +int lowres_x, lowres_y +int ip, n, sx, sy, len_p, iop, i +int stg_encode() +include "stdgraph.com" + +begin + if (g_enable == NO) + call stg_genab() + + len_p = npts * 2 + + # Update polyline attributes if necessary. + + pl = SG_PLAP(g_sg) + if (SG_PLTYPE(g_sg) != PL_LTYPE(pl)) { + call stg_ctrl1 ("LT", PL_LTYPE(pl)) + SG_PLTYPE(g_sg) = PL_LTYPE(pl) + } + if (SG_PLWIDTH(g_sg) != PL_WIDTH(pl)) { + call stg_ctrl1 ("LW", PL_WIDTH(pl)) + SG_PLWIDTH(g_sg) = PL_WIDTH(pl) + } + if (SG_COLOR(g_sg) != PL_COLOR(pl)) { + call stg_ctrl1 ("LC", PL_COLOR(pl)) + SG_COLOR(g_sg) = PL_COLOR(pl) + } + + # Transform the first point from GKI coords to device coords and + # move to the transformed point. + + sx = p[1]; sy = p[2] + call stg_move (sx, sy) + + # Tektronix encoding is treated as a special case for max efficiency. + tek_encoding = + (Memc[g_xy] == '%' && Memc[g_xy+1] == 't' && Memc[g_xy+2] == EOS) + + # Draw the polyline. If the device has the "polyline" capability + # we can encode and output successive points without enclosing each + # individual point in the startdraw and enddraw strings. + + for (ip=3; ip <= len_p; ip=ip+2) { + # Output start draw sequence. + call ttyputs (g_out, g_tty, Memc[SG_STARTDRAW(g_sg)], 1) + + # Determine number of points to output. + if (SG_POLYLINE(g_sg) == YES) + n = len_p + else + n = ip + 2 + + # Encode the points of the polyline. + + g_lastx = -1 # clip unresolved points only in the interior + g_lasty = -1 # of the polyline being drawn. + + g_reg[E_IOP] = 1 + do i = ip, n, 2 { + sx = p[i] + sy = p[i+1] + + # Discard the point if it is not resolved. + lowres_x = sx / g_dxres + lowres_y = sy / g_dyres + if (lowres_x == g_lastx && lowres_y == g_lasty) + next + + g_lastx = lowres_x + g_lasty = lowres_y + + # Transform point into the device window. + sx = int (sx * g_dx) + g_x1 + sy = int (sy * g_dy) + g_y1 + + # Encode the point, appending encoded bytes to g_mem. Tek + # encoding is treated as a special case since it is so common; + # the encoder is used for non-Tek encodings. + + if (tek_encoding) { + iop = g_reg[E_IOP] + 4 + g_mem[iop-4] = g_hixy[sy+1] + g_mem[iop-3] = g_loy[sy+1] + g_mem[iop-2] = g_hixy[sx+1] + g_mem[iop-1] = g_lox[sx+1] + g_reg[E_IOP] = iop + } else { + g_reg[1] = sx + g_reg[2] = sy + if (stg_encode (Memc[g_xy], g_mem, g_reg) != OK) + break + } + + # Flush buffer if nearly full. + if (g_reg[E_IOP] > FLUSH_MEMORY) { + call write (g_out, g_mem, g_reg[E_IOP] - 1) + g_reg[E_IOP] = 1 + } + } + ip = n + + # Flush any output remaining in encoder memory. + if (g_reg[E_IOP] > 1) { + call write (g_out, g_mem, g_reg[E_IOP] - 1) + g_reg[E_IOP] = 1 + } + + # Output end draw sequence. + call ttyputs (g_out, g_tty, Memc[SG_ENDDRAW(g_sg)], 1) + } +end diff --git a/sys/gio/stdgraph/stgplset.x b/sys/gio/stdgraph/stgplset.x new file mode 100644 index 00000000..c435feb5 --- /dev/null +++ b/sys/gio/stdgraph/stgplset.x @@ -0,0 +1,20 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_PLSET -- Set the polyline attributes. The polyline width parameter is +# passed to the encoder as a packed floating point number, i.e., int(LWx100). + +procedure stg_plset (gki) + +short gki[ARB] # attribute structure +pointer pl +include "stdgraph.com" + +begin + pl = SG_PLAP(g_sg) + PL_LTYPE(pl) = gki[GKI_PLSET_LT] + PL_WIDTH(pl) = max (1, nint (GKI_UNPACKREAL (gki[GKI_PLSET_LW]))) + PL_COLOR(pl) = gki[GKI_PLSET_CI] +end diff --git a/sys/gio/stdgraph/stgpm.x b/sys/gio/stdgraph/stgpm.x new file mode 100644 index 00000000..3808d63b --- /dev/null +++ b/sys/gio/stdgraph/stgpm.x @@ -0,0 +1,118 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_POLYMARKER -- Draw a polymarker. The polymarker is defined by the array +# of points P, consisting of successive (x,y) coordinate pairs, each of which +# is to be plotted as a point. If the marker start sequence MS is defined the +# polymarker will be drawn as ... , otherwise +# ther marker is draw using the polyline move and draw commands to draw each +# individual point. + +procedure stg_polymarker (p, npts) + +short p[ARB] # points defining line +int npts # number of points, i.e., (x,y) pairs + +pointer pm +bool tek_encoding +int lowres_x, lowres_y +int ip, n, sx, sy, len_p, iop, i +int stg_encode() +include "stdgraph.com" + +begin + if (g_enable == NO) + call stg_genab() + + len_p = npts * 2 + + # Update polymarker attributes if necessary. + + pm = SG_PMAP(g_sg) + if (SG_COLOR(g_sg) != PM_COLOR(pm)) { + call stg_ctrl1 ("MC", PM_COLOR(pm)) + SG_COLOR(g_sg) = PM_COLOR(pm) + } + + # Tektronix encoding is treated as a special case for max efficiency. + tek_encoding = + (Memc[g_xy] == '%' && Memc[g_xy+1] == 't' && Memc[g_xy+2] == EOS) + + # Draw the polymarker. If the startmark sequence is defined we assume + # that the device can draw a multipoint polymarker, else low level move + # and draw sequences are used. + + if (Memc[SG_STARTMARK(g_sg)] != EOS) { + for (ip=1; ip <= len_p; ip=ip+2) { + # Output start marker sequence [revised to use the encoder]. + call ttyputs (g_out, g_tty, Memc[SG_STARTMARK(g_sg)], 1) + n = len_p + + # Encode the points of the polymarker (or move to the single + # point to be drawn). + + g_lastx = -1 # clip unresolved points only in the interior + g_lasty = -1 # of the polymarker being drawn. + + g_reg[E_IOP] = 1 + do i = ip, n, 2 { + sx = p[i] + sy = p[i+1] + + # Discard the point if it is not resolved. + lowres_x = sx / g_dxres + lowres_y = sy / g_dyres + if (lowres_x == g_lastx && lowres_y == g_lasty) + next + + g_lastx = lowres_x + g_lasty = lowres_y + + # Transform point into the device window. + sx = int (sx * g_dx) + g_x1 + sy = int (sy * g_dy) + g_y1 + + # Encode the point, appending encoded bytes to g_mem. + # Tek encoding is treated as a special case since it is + # so common; the encoder is used for non-Tek encodings. + + if (tek_encoding) { + iop = g_reg[E_IOP] + 4 + g_mem[iop-4] = g_hixy[sy+1] + g_mem[iop-3] = g_loy[sy+1] + g_mem[iop-2] = g_hixy[sx+1] + g_mem[iop-1] = g_lox[sx+1] + g_reg[E_IOP] = iop + } else { + g_reg[1] = sx + g_reg[2] = sy + if (stg_encode (Memc[g_xy], g_mem, g_reg) != OK) + break + } + + # Flush buffer if nearly full. + if (g_reg[E_IOP] > FLUSH_MEMORY) { + call write (g_out, g_mem, g_reg[E_IOP] - 1) + g_reg[E_IOP] = 1 + } + } + ip = n + + # Flush any output remaining in encoder memory. + if (g_reg[E_IOP] > 1) { + call write (g_out, g_mem, g_reg[E_IOP] - 1) + g_reg[E_IOP] = 1 + } + + # Output end polymarker sequence, or draw the point. + call ttyputs (g_out, g_tty, Memc[SG_ENDMARK(g_sg)], 1) + } + } else { + for (ip=1; ip <= len_p; ip=ip+2) { + sx = p[ip]; sy = p[ip+1] + call stg_move (sx, sy) + call stg_draw (sx, sy) + } + } +end diff --git a/sys/gio/stdgraph/stgpmset.x b/sys/gio/stdgraph/stgpmset.x new file mode 100644 index 00000000..6651564f --- /dev/null +++ b/sys/gio/stdgraph/stgpmset.x @@ -0,0 +1,19 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_PMSET -- Set the polymarker attributes. + +procedure stg_pmset (gki) + +short gki[ARB] # attribute structure +pointer pm +include "stdgraph.com" + +begin + pm = SG_PMAP(g_sg) + PM_LTYPE(pm) = gki[GKI_PMSET_MT] + PM_WIDTH(pm) = max (1, nint (GKI_UNPACKREAL (gki[GKI_PMSET_MW]))) + PM_COLOR(pm) = gki[GKI_PMSET_CI] +end diff --git a/sys/gio/stdgraph/stgrcur.x b/sys/gio/stdgraph/stgrcur.x new file mode 100644 index 00000000..e0ab890a --- /dev/null +++ b/sys/gio/stdgraph/stgrcur.x @@ -0,0 +1,425 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include +include +include +include +include +include +include "stdgraph.h" + +define MAX_LENCUR 17 +define MAX_KEYLINES 30 +define KEYSIZE 1 +define QUIT 'q' +define GO 'g' + +# STG_READCURSOR -- Physically read the cursor, returning the cursor position +# in GKI coordinates and the keystroke value as output arguments. The cursor +# value string is read in raw mode with interrupts disabled. Receipt of the +# EOF character or CR causes EOF to be returned as the key value. +# +# The cursor is described by two parameters, a pattern string (CD) and a string +# length parameter (CN). +# +# CD A pattern specifying either the delimiter sequence if +# len_curval > 0, or the entire cursor value string if +# len_curval <= 0. +# +# CN If no pattern is given, CN is the number of characters to be +# read and automatic error detection is not possible. If a +# pattern is given, a negative CN specifies the minimum number +# of characters in the cursor value string, with the pattern +# being used to match the characters in the actual cursor value +# string. A positive CN specifies a fixed length cursor value +# string, which which case the pattern is used only to determine +# when a valid cursor value string has been received. +# +# The cursor read algorithm tries to ignore unsolicited input and recover from +# bad cursor reads, or loss of hardware cursor mode during a cursor read, e.g., +# if the screen is accidentally cleared or the terminal otherwise initialized. +# +# The physical cursor read sequence is implemented by the stg_rdcursor routine. +# The purpose of the higher level routine is to support STTY playback mode. +# In playback mode, terminal input is taken from a logfile rather than from +# the physical terminal; this is used to prepare automatic scripts to test +# software and for demos. If playback mode is enabled and `verify' is enabled, +# the logged cursor position will be read, a WC will be issued to move the +# cursor to that position, and then the physical cursor will be read and the +# return value discard, returning the logged position to the calling program. +# In playback mode with `verify' disabled, we need only disable the RC +# instruction and read the logged cursor position; the physical cursor is +# never turned on. + +procedure stg_readcursor (cursor, cn, key, sx, sy, raster, rx, ry) + +int cursor #I cursor to be read +int cn #O cursor which was read +int key #O keystroke which terminated cursor read +int sx, sy #O screen coordinates of cursor in GKI units +int raster #O raster number +int rx, ry #O raster coordinates of cursor in GKI units + +short texts[4] +char textc[4], ch +pointer sp, pbdevice, tx, o_tx +int delay, nchars, mx, my, i, j, k +bool playback_mode, pbverify_mode + +bool strne() +pointer ttygdes() +int ttstati(), ttstats(), ctocc() +errchk ttygdes, syserr +include "stdgraph.com" +define samedev_ 91 + +begin + playback_mode = (ttstati (STDIN, TT_PLAYBACK) == YES) + + if (!playback_mode) { + call stg_rdcursor (g_tty, cursor, YES, + cn, key, sx, sy, raster, rx, ry) + return + } + + call smark (sp) + call salloc (pbdevice, SZ_GDEVICE, TY_CHAR) + call salloc (o_tx, LEN_TX, TY_STRUCT) + + # The playback script may have been generated on a different graphics + # terminal than the one we are playing it back on. Open the graphcap + # descriptor for the device used when the script was recorded. This + # must be used when decoding cursor input from the logfile. If device + # name not recorded in logfile, try to make do with the descriptor for + # the current stdgraph device. + + if (ttstats (STDIN, TT_GDEVICE, Memc[pbdevice], SZ_GDEVICE) <= 0) { + # Device name not recorded in logfile. + call syserr (SYS_STTYNOGDEV) + + } else if (g_pbtty == NULL || strne (g_pbdevice, Memc[pbdevice])) { + # Device name was recorded; try to load graphcap for it if not + # already loaded. + + if (g_pbtty != NULL) + call ttycdes (g_pbtty) + iferr (g_pbtty = ttygdes (Memc[pbdevice])) { + g_pbtty = NULL + call erract (EA_ERROR) + } + + call strcpy (Memc[pbdevice], g_pbdevice, SZ_GDEVICE) + } + + # Set the playback delay to 0 msec while reading the cursor, else + # the multicharacter cursor read will take forever. We issue the + # delay below, ourselves, one per cursor read. + + delay = ttstati (STDIN, TT_PBDELAY) + call ttseti (STDIN, TT_PBDELAY, 0) + + # Read the logged cursor position with RC disabled. + call stg_rdcursor (g_pbtty, cursor, NO, + cn, key, sx, sy, raster, rx, ry) + + # Determine if verify mode is set for this cursor read. This must + # be done after the call to stg_rdcursor to permit processing of + # any \{ .. \} in the logfile. + + pbverify_mode = (ttstati (STDIN, TT_PBVERIFY) == YES) + + # Set passthru mode to read/write the device directly. + call ttseti (STDIN, TT_PASSTHRU, YES) + + # Encode the logged keystroke as a character string. + if (key == EOF) { + call strcpy ("EOF", textc, 4) + nchars = 3 + } else if (key <= ' ') { + ch = key + nchars = ctocc (ch, textc, 4) + } else { + nchars = 1 + textc[1] = key + } + + # Pack the string in a short array for the GKI operator. + call achtcs (textc, texts, nchars) + + # Set the text drawing attributes. + tx = SG_TXAP(g_sg) + call amovi (Memi[tx], Memi[o_tx], LEN_TX) + TX_SIZE(tx) = KEYSIZE + TX_HJUSTIFY(tx) = GT_LEFT + TX_VJUSTIFY(tx) = GT_BOTTOM + + # Echo the key character in graphics mode on the top line of the screen, + # duplicating the text drawn at the cursor position. + + mx = nint ((g_keycol + 0.5) * SG_CHARWIDTH(g_sg,1)) + my = GKI_MAXNDC - nint ((g_keyline + 0.2) * SG_CHARHEIGHT(g_sg,KEYSIZE)) + + call stg_text (mx, my, texts, nchars) + g_keyline = g_keyline + 1 + if (g_keyline > MAX_KEYLINES) { + g_keycol = g_keycol + 1 + g_keyline = 1 + } + + # Echo the logged keystroke at the position of the cursor. This may + # not always be readable, but at least it marks the cursor position. + + call stg_text (sx, sy, texts, nchars) + + if (pbverify_mode) { + # Issue a WC to set the cursor position, and perform a normal + # cursor read in passthru mode, discarding the return value. + + call stg_setcursor (sx, sy, cursor) + call stg_rdcursor (g_tty, cursor, YES, i, i, j, k, i, j, k) + + # User wants to terminate playback mode? + if (k == QUIT || k == INTCHAR) { + call ttseti (STDIN, TT_PLAYBACK, NO) + call stg_ctrl ("GD") + call putline (STDOUT, "[playback mode terminated]") + call stg_ctrl ("GE") + call flush (STDOUT) + call zwmsec (500) + if (k == INTCHAR) + key = EOF + } else if (k == GO) + call ttseti (STDIN, TT_PBVERIFY, NO) + } else + call zwmsec (delay) + + # Restore everything modified earlier. + call ttseti (STDIN, TT_PASSTHRU, NO) + call ttseti (STDIN, TT_PBDELAY, delay) + call amovi (Memi[o_tx], Memi[tx], LEN_TX) + + call sfree (sp) +end + + +# STG_RDCURSOR -- Physically read the cursor; an internal routine called only +# by the stg_readcursor procedure. A lower level routine is needed since +# two cursor reads may be required in STTY playback mode, one to read the +# logged cursor position and another to read the physical cursor to synch +# with the user. This is the real cursor read routine; the only concession +# to playback mode is the `output_rc' switch, to disable output of the RC +# instruction to the terminal, so that the routine does only input from the +# logical device. + +procedure stg_rdcursor (tty, cursor, output_rc, cn, key, sx,sy, raster, rx,ry) + +pointer tty #I graphcap descriptor +int cursor #I cursor to be read +int output_rc #I flag to output the RC instruction +int cn #O cursor which was read +int key #O keystroke which terminated cursor read +int sx, sy #O cursor screen position in GKI coords +int raster #O raster number +int rx, ry #O cursor raster position in GKI coords + +pointer decodecur, delimcur, pattern, patbuf, sp, otop +int len_pattern, len_curval, sv_iomode, nchars, ip, op, i1, i2, ch + +bool ttygetb() +int getci(), stg_encode() +int ttygets(), ttygeti(), gstrcpy(), gpatmatch(), patmake(), fstati() +include "stdgraph.com" +define quit_ 91 + +begin + call smark (sp) + call salloc (pattern, SZ_LINE, TY_CHAR) + call salloc (patbuf, SZ_LINE, TY_CHAR) + call salloc (decodecur, SZ_LINE, TY_CHAR) + call salloc (delimcur, SZ_FNAME, TY_CHAR) + + key = EOF + + # Make sure there is a cursor before going any further. + if (!ttygetb (g_tty, "RC")) + goto quit_ + + len_curval = ttygeti (tty, "CN") + if (ttygets (tty, "SC", Memc[decodecur], SZ_LINE) <= 0) + goto quit_ + + len_pattern = 0 + if (ttygets (tty, "CD", Memc[delimcur], SZ_FNAME) > 0) + len_pattern = gstrcpy (Memc[delimcur], Memc[pattern], SZ_LINE) + + # Either len_curval or pattern must be given, preferably both. + if (len_curval == 0 && len_pattern == 0) + goto quit_ + + # Encode the cursor value pattern, which may be either a pattern + # matching the entire cursor value, or just the delimiter. The value + # of len_curval may be negative if a pattern is given, but must be + # positive otherwise. If the pattern is a delimiter string, append + # the $ metacharacter to match only at the end of the string. + + if (len_pattern > 0) { + if (len_curval > 0) { + Memc[pattern+len_pattern] = '$' + len_pattern = len_pattern + 1 + Memc[pattern+len_pattern] = EOS + } + if (patmake (Memc[pattern], Memc[patbuf], SZ_LINE) == ERR) + goto quit_ + } else if (len_curval < 0) + len_curval = -len_curval + + # Set raw mode on the input file (the graphics terminal). + call flush (STDOUT); call flush (STDERR) + sv_iomode = fstati (g_in, F_IOMODE) + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, IO_RAW) + + repeat { + # Initiate a cursor read. + if (output_rc == YES) { + call stg_ctrl1 ("RC", cursor) + call flush (g_out) + } + + # Read the cursor value string. If a pattern is given accumulate + # at least abs(len_curval) characters and stop when the pattern + # is matched, returning the last len_curval characters if + # len_curval > 0, else the matched substring. If no pattern is + # given simply accumulate len_curval characters. The number of + # characters we will accumulate in one iteration is limited to + # MAX_LENCUR to permit retransmission of the RC control sequence + # in the event that hardware cursor mode is accidentally cleared. + + for (op=1; op <= MAX_LENCUR; op=op+1) { + g_mem[op] = getci (g_in, key) + g_mem[op+1] = EOS + + if (key == EOF) { + # Turn off raw input mode and return EOF. + key = EOF + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, sv_iomode) + goto quit_ + + } else if (len_pattern > 0) { + # A pattern string was given. Once the minimum number of + # chars have been accumulated, try to match the pattern, + # which may match either the cursor string delimiter (in + # the case of a fixed length cursor value), or the entire + # cursor string (which may then be variable length). + + if (op < abs(len_curval)) + next + else if (gpatmatch (g_mem[1], Memc[patbuf], i1,i2) > 0) { + if (len_curval > 0) + ip = op - len_curval + 1 # fixed length cur + else + ip = i1 # variable length cur + break + } + + } else if (op >= len_curval) { + # No pattern was given. Terminate the cursor read once + # the len_curval characters have been accumulated. + + ip = 1 + break + } + } + + # We have received too many characters, indicating that cursor + # mode was lost and the user has been pounding on the keyboard + # trying to get the cursor back. Discard the chars, restart + # the cursor and try again. + + if (op > MAX_LENCUR) + op = -1 + + } until (op >= abs(len_curval) || len_curval == 0) + + # Decode the cursor value string and return the position and key + # as output values. Return the cursor position in GKI coordinates. + # If extra characters were typed, e.g., before the cursor was turned + # on, and the cursor has a delimiter string, the extra characters will + # have been read into low memory and we should be able to ignore them + # and still get a valid read. + + g_reg[E_IOP] = ip + call aclri (g_reg, 7) + if (stg_encode (Memc[decodecur], g_mem, g_reg) != OK) + call syserr (SYS_GGCUR) + + # Multiple cursors are not implemented yet so just echo input. + cn = cursor + + # Standard cursor value. + sx = nint ((g_reg[1] - g_x1) / g_dx) + sy = nint ((g_reg[2] - g_y1) / g_dy) + key = g_reg[3] + + # Only some devices return the following fields. Note that FX,FY + # are returned by stg_encode in GKI coordinates. + + nchars = g_reg[4] + raster = g_reg[5] + if (raster == 0) { + rx = sx + ry = sy + } else { + rx = g_reg[6] + ry = g_reg[7] + } + + # If the NCHARS field is nonzero then a data block of length nchars + # follows the cursor value struct returned by the terminal. Read this + # into the g_msgbuf message buffer. The client makes a subsequent + # call to stg_readtty to access this data, otherwise it is discarded + # in the next cursor read. + + if (nchars > 0) { + if (nchars > g_msgbuflen) { + g_msgbuflen = (nchars + SZ_MSGBUF - 1) / SZ_MSGBUF * SZ_MSGBUF + call realloc (g_msgbuf, g_msgbuflen, TY_CHAR) + } + + # We should encode this data transfer in a way that permits + # detection and recovery from lost data. For the moment, the + # following assumes that nchars of data will actually be received. + + op = g_msgbuf + otop = g_msgbuf + nchars + while (op < otop && getci (g_in, ch) != EOF) { + Memc[op] = ch + op = op + 1 + } + g_msglen = op - g_msgbuf + Memc[op] = EOS + + } else + g_msglen = 0 + + # Turn off raw input mode. + if (sv_iomode != IO_RAW) + call fseti (g_in, F_IOMODE, sv_iomode) + + # Return EOF if any EOF character (e.g., or ) or the + # interrupt character is typed. + + if (key == EOFCHAR || key == INTCHAR || key == '\004' || key == '\032') + key = EOF +quit_ + # Terminate the cursor read. + if (output_rc == YES) { + call stg_ctrl1 ("RE", cursor) + call flush (g_out) + } + + call sfree (sp) +end diff --git a/sys/gio/stdgraph/stgreact.x b/sys/gio/stdgraph/stgreact.x new file mode 100644 index 00000000..21c2a821 --- /dev/null +++ b/sys/gio/stdgraph/stgreact.x @@ -0,0 +1,41 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "stdgraph.h" + +# STG_REACTIVATEWS -- Reactivate the workstation, i.e., enable graphics. + +procedure stg_reactivatews (flags) + +int flags # action flags (handled by cursor mode) + +int junk +int ttstati(), ttyctrl(), and() +extern stg_onerror() +include "stdgraph.com" + +begin + if (g_active == NO) { + junk = ttyctrl (g_out, g_tty, "OW", 1) + + # Post error handler to be called if we abort. + call onerror (stg_onerror) + + g_active = YES + g_enable = YES + + # Must disable stty ucaseout mode when in graphics mode, else + # plotting commands may be modified by the terminal driver. + + g_ucaseout = ttstati (g_out, TT_UCASEOUT) + if (g_ucaseout == YES) + call ttseti (g_out, TT_UCASEOUT, NO) + + # Clear the graphics screen? + if (and (flags, AW_CLEAR) != 0) + call stg_clear (0) + + call flush (g_out) + } +end diff --git a/sys/gio/stdgraph/stgres.x b/sys/gio/stdgraph/stgres.x new file mode 100644 index 00000000..d6355bd9 --- /dev/null +++ b/sys/gio/stdgraph/stgres.x @@ -0,0 +1,85 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_RESOLUTION -- Set the "soft" device resolution. When plotting GKI +# coordinates are transformed into a space with the indicated resolution and +# unresolved points are discarded, before transforming to device coordinates. +# We must set up both the transformation to resolution space and the +# transformation to device space. + +procedure stg_resolution (xres, yres) + +int xres # device X resolution +int yres # device Y resolution +int nx, ny +int ttygeti() +include "stdgraph.com" + +begin + if (g_tty == NULL) { + g_xres = xres + g_yres = yres + return + } + + # Set the resolution value in the stdgraph common only if a nonzero + # value is given. A value of zero does not change the resolution. + + if (xres > 0) + g_xres = xres + if (yres > 0) + g_yres = yres + + + # If we still have a zero resolution then we use the full resolution + # of the device. The 3/4 reduction in resolution is needed to clip + # points that would be unresolved due to integer truncation effects. + + if (g_xres <= 0) { + g_xres = ttygeti (g_tty, "xr") + if (g_xres <= 0) + g_xres = 1024 + g_xres = max (2, g_xres * 3 / 4) + } + if (g_yres <= 0) { + g_yres = ttygeti (g_tty, "yr") + if (g_yres <= 0) + g_yres = 1024 + g_yres = max (2, g_yres * 3 / 4) + } + + # Set up coordinate transformations. The first transformation is from + # GKI coordinates to device resolution coordinates (0:xres-1,0:yres-1) + # and is defined by xres, yres, and GKI_MAXNDC. Clipping of unresolved + # points is performed after this first transformation. The second + # transformation maps resolved points into the device window. + + # GKI -> resolution coords. + g_dxres = max (1, (GKI_MAXNDC + 1) / g_xres) + g_dyres = max (1, (GKI_MAXNDC + 1) / g_yres) + + g_x1 = ttygeti (g_tty, "X1") + g_y1 = ttygeti (g_tty, "Y1") + g_x2 = ttygeti (g_tty, "X2") + g_y2 = ttygeti (g_tty, "Y2") + nx = g_x2 - g_x1 + 1 + ny = g_y2 - g_y1 + 1 + + if (nx <= 1 || ny <= 1) { + call eprintf ("openws: illegal graphics device window\n") + nx = g_xres + ny = g_yres + } + + # GKI -> window coords. + g_dx = real (nx - 1) / GKI_MAXNDC + g_dy = real (ny - 1) / GKI_MAXNDC + + # The last point in resolution coords is used to clip unresolved + # points when drawing polylines. + + g_lastx = -1 + g_lasty = -1 +end diff --git a/sys/gio/stdgraph/stgreset.x b/sys/gio/stdgraph/stgreset.x new file mode 100644 index 00000000..0f2fd1e2 --- /dev/null +++ b/sys/gio/stdgraph/stgreset.x @@ -0,0 +1,54 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_RESET -- Reset the state of the stdgraph common, i.e., in response to +# a clear or a cancel. Initialize all attribute packets to their default +# values and set the current state of the device to undefined, forcing the +# device state to be reset when the next output instruction is executed. + +procedure stg_reset() + +pointer pl, pm, fa, tx +include "stdgraph.com" + +begin + # Set pointers to attribute substructures. + pl = SG_PLAP(g_sg) + pm = SG_PMAP(g_sg) + fa = SG_FAAP(g_sg) + tx = SG_TXAP(g_sg) + + # Initialize the attribute packets. + PL_LTYPE(pl) = 1 + PL_WIDTH(pl) = 1 + PL_COLOR(pl) = 1 + PM_COLOR(pm) = 1 + FA_STYLE(fa) = 1 + FA_COLOR(fa) = 1 + TX_UP(tx) = 90 + TX_SIZE(tx) = 1 + TX_PATH(tx) = GT_RIGHT + TX_HJUSTIFY(tx) = GT_LEFT + TX_VJUSTIFY(tx) = GT_BOTTOM + TX_FONT(tx) = GT_ROMAN + TX_COLOR(tx) = 1 + TX_SPACING(tx) = 0.0 + + # Set the device attributes to undefined, forcing them to be reset + # when the next output instruction is executed. + + SG_COLOR(g_sg) = -1 + SG_TXSIZE(g_sg) = -1 + SG_TXFONT(g_sg) = -1 + SG_PLTYPE(g_sg) = -1 + SG_FASTYLE(g_sg) = -1 + SG_PLWIDTH(g_sg) = -1 + g_lastx = -1 + g_lasty = -1 + g_keycol = 1 + g_keyline = 1 + g_message = NO + g_msglen = 0 +end diff --git a/sys/gio/stdgraph/stgrtty.x b/sys/gio/stdgraph/stgrtty.x new file mode 100644 index 00000000..237a7c7b --- /dev/null +++ b/sys/gio/stdgraph/stgrtty.x @@ -0,0 +1,137 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "stdgraph.h" + +# STG_READTTY -- Read a line of text from the graphics terminal. +# If the workstation is currently activated the read is performed in raw mode, +# presumably with the cursor positioned to the end of a prompt string on the +# status line. The workstation will have been put into text mode and the +# cursor positioned to the status line by an immediately preceding call to +# stg_writetty, which is called by pseudofile i/o when the user task writes +# to STDOUT or STDERR while the workstation is activated. The input sequence +# terminates when the user types return or newline, causing exit with +# transmission of the GE sequence to restore the terminal to graphics mode. + +int procedure stg_readtty (fd, obuf, maxch) + +int fd #I input stream [NOT USED] +char obuf[ARB] #O output buffer +int maxch #I max chars to read + +int nchars, op, ch +int read(), getci(), fstati() +include "stdgraph.com" +errchk read, getci, ttyctrl +string delstr "\010 \010" + +begin + call flush (STDERR) + call flush (STDOUT) + + if (g_active == NO) { + # Workstation in normal text mode; normal text input. + return (read (STDIN, obuf, maxch)) + + } else if (g_msglen > 0) { + # The message data has already been transmitted and resides in + # the message buffer. + + nchars = min (maxch, g_msglen) + call amovc (Memc[g_msgbuf], obuf, nchars) + obuf[nchars+1] = EOS + g_msglen = 0 + return (nchars) + + } else { + # Workstation is activated; read status line in raw mode. + # If already in rew mode, read a single char with no echo. + # Note that genable is not automatic in raw input mode. + + if (g_enable == YES) + call stg_gdisab() + + if (fstati (g_in, F_RAW) == YES) { + if (getci (g_in, ch) == EOF) { + obuf[1] = EOS + return (EOF) + } else if (ch == '\004' || ch == '\032') { + obuf[1] = EOS + return (EOF) + } else { + obuf[1] = ch + obuf[2] = EOS + return (1) + } + } else + call fseti (g_in, F_RAW, YES) + + for (op=1; getci (g_in, ch) != EOF; op=min(maxch,op)) { + switch (ch) { + case EOF, '\004', '\032': # EOF + call stg_genab() + break + case '\n', '\r': + obuf[op] = '\n' + op = op + 1 + call putline (g_out, "\r\n") + call stg_genab() + break + case INTCHAR, '\025': # + for (; op > 1; op=op-1) + call putline (g_out, delstr) + case BS, '\177': + if (op > 1) { + call putline (g_out, delstr) + op = op - 1 + } else { + call stg_genab() + break # exit + } + default: + call putci (g_out, ch) + obuf[op] = ch + op = op + 1 + } + call flush (g_out) + } + + obuf[op] = EOS + call fseti (g_in, F_RAW, NO) + + if (op > 1) + return (op - 1) + else + return (EOF) + } +end + + +# STG_GETLINE -- Get a line of text from the graphics terminal, reading from +# the status line if the workstation is activated, and doing a normal text +# read otherwise. + +int procedure stg_getline (fd, obuf) + +int fd #I input file +char obuf[SZ_LINE] #O output buffer + +int stg_readtty() + +begin + return (stg_readtty (fd, obuf, SZ_LINE)) +end + + +# STG_MSGLEN -- This routine is called to determine if there is any message +# data buffered in the kernel, to be returned in the next call to stg_readtty. + +int procedure stg_msglen (fd) + +int fd #I input file +include "stdgraph.com" + +begin + return (g_msglen) +end diff --git a/sys/gio/stdgraph/stgscur.x b/sys/gio/stdgraph/stgscur.x new file mode 100644 index 00000000..e40d4a3d --- /dev/null +++ b/sys/gio/stdgraph/stgscur.x @@ -0,0 +1,36 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include "stdgraph.h" + +# STG_SETCURSOR -- Set the position of a cursor. + +procedure stg_setcursor (x, y, cursor) + +int x, y # new position of cursor +int cursor # cursor to be set +int mx, my, cur +include "stdgraph.com" + +begin + # If cursor=0, write the cursor last referenced. + if (cursor > 0) { + SG_CURSOR(g_sg) = cursor + cur = cursor + } else + cur = max (1, SG_CURSOR(g_sg)) + + # If the user has locked the logical cursor override runtime selection. + if (g_cursor > 0) + cur = g_cursor + + # Restore the software cursor position before reading? + if (SG_UPDCURSOR(g_sg) == YES) { + SG_CURSOR_X(g_sg) = x + SG_CURSOR_Y(g_sg) = y + } + + mx = max(g_x1, min(g_x2, nint (x * g_dx) + g_x1)) + my = max(g_y1, min(g_y2, nint (y * g_dy) + g_y1)) + + call stg_ctrl3 ("WC", mx, my, cur) +end diff --git a/sys/gio/stdgraph/stgtx.x b/sys/gio/stdgraph/stgtx.x new file mode 100644 index 00000000..ff5abae2 --- /dev/null +++ b/sys/gio/stdgraph/stgtx.x @@ -0,0 +1,528 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include +include +include "stdgraph.h" + +# STG_TEXT -- Draw a text string. The string is drawn at the position (X,Y) +# using the text attributes set by the last GKI_TXSET instruction. The text +# string to be drawn may contain embedded set font escape sequences of the +# form \fR (roman), \fG (greek), etc. We break the input text sequence up +# into segments at font boundaries and draw these on the output device, +# setting the text size, color, font, and position at the beginning of each +# segment. Two levels of character quality are implemented: MEDIUM and HIGH, +# wherein characters are generated in software, and everything else, wherein +# the characters are generated by the hardware. + +procedure stg_text (xc, yc, text, n) + +int xc, yc # where to draw text string +short text[ARB] # text string +int n # number of characters + +bool hard +real x, y +int x1, x2, y1, y2, mx, my +int x0, y0, dx, dy, ch, cw, sz +int xstart, ystart, newx, newy +int totlen, polytext, font, seglen, orien, hwsz +pointer sp, seg, ip, op, tx, first +int stx_segment(), stg_encode() +include "stdgraph.com" + +begin + call smark (sp) + call salloc (seg, n + 2, TY_CHAR) + + if (g_enable == NO) + call stg_genab() + + # Set pointer to the text attribute structure. + tx = SG_TXAP(g_sg) + + # Break the text string into segments at font boundaries and count + # the total number of printable characters. + + totlen = stx_segment (text, n, Memc[seg], TX_FONT(tx)) + + # Compute the text drawing parameters, i.e., the coordinates of the + # first character to be drawn, the step between successive characters, + # and the polytext flag (GKI coords). + + call stx_parameters (xc,yc, totlen, x0,y0, dx,dy, polytext, orien) + + # Set the text size and color if not already set. Both should be + # invalidated when the screen is cleared. Text color should be + # invalidated whenever another color is set. If software (!hard) + # character generation is indicated then size 1 is simply scaled by + # the indicated factor, otherwise the text size is converted to a + # hardware size index by stg_txsize. + + call stx_chars (tx, ch, cw, hwsz, hard, orien) + sz = TX_SIZE(tx) + + if (hard) + if (SG_TXSIZE(g_sg) != sz) { + call stg_ctrl1 ("TH", hwsz) + SG_TXSIZE(g_sg) = sz + } + + if (TX_COLOR(tx) != SG_COLOR(g_sg)) { + call stg_ctrl1 ("TC", TX_COLOR(tx)) + SG_COLOR(g_sg) = TX_COLOR(tx) + } + + # Draw the segments, setting the font at the beginning of each segment. + # The first segment is drawn at (X0,Y0). The separation between + # characters is DX,DY. A segment is drawn as a block if the polytext + # flag is set, otherwise each character is drawn individually. + # All computations are in GKI coordinates. + + x = x0 + y = y0 + + for (ip=seg; Memc[ip] != EOS; ip=ip+1) { + # Process the font control character heading the next segment. + font = Memc[ip] + ip = ip + 1 + if (hard) + if (SG_TXFONT(g_sg) != font) { + call stg_ctrl1 ("TF", font - GT_ROMAN + 1) + SG_TXFONT(g_sg) = font + } + + # Draw the segment. + while (Memc[ip] != EOS) { + # Clip leading out of bounds characters. + for (; Memc[ip] != EOS; ip=ip+1) { + x1 = x; x2 = x1 + cw + y1 = y; y2 = y1 + ch + + if (x1 >= 0 && x2 <= GKI_MAXNDC && + y1 >= 0 && y2 <= GKI_MAXNDC) { + + break + + } else { + x = x + dx + y = y + dy + } + + if (polytext == NO) { + ip = ip + 1 + break + } + } + + # Coords of first char to be drawn. + xstart = x + ystart = y + + # Move OP to first out of bounds char. + for (op=ip; Memc[op] != EOS; op=op+1) { + x1 = x; x2 = x1 + cw + y1 = y; y2 = y1 + ch + + if (x1 <= 0 || x2 >= GKI_MAXNDC || + y1 <= 0 || y2 >= GKI_MAXNDC) { + + break + + } else { + x = x + dx + y = y + dy + } + + if (polytext == NO) { + op = op + 1 + break + } + } + + # Count number of inbounds chars. + seglen = op - ip + + # Leave OP pointing to the end of this segment. + if (polytext == NO) + op = ip + 1 + else { + while (Memc[op] != EOS) + op = op + 1 + } + + # Compute X,Y of next segment. + newx = xstart + (dx * (op - ip)) + newy = ystart + dy + + # Quit if no inbounds chars. + if (seglen == 0) { + x = newx + y = newy + ip = op + next + } + + # Output the inbounds chars. + if (hard) { + g_reg[1] = xstart * g_dx + g_x1 + g_reg[2] = ystart * g_dy + g_y1 + g_reg[E_IOP] = 1 + if (stg_encode (Memc[SG_STARTTEXT(g_sg)],g_mem,g_reg) == OK) + call write (g_out, g_mem, g_reg[E_IOP] - 1) + } + + first = ip + x = xstart + y = ystart + + # Draw the characters. + while (seglen > 0 && (polytext == YES || ip == first)) { + if (hard) + call putc (g_out, Memc[ip]) + else { + mx = nint(x) + my = nint(y) + call stg_drawchar (Memc[ip], mx,my, cw, ch, orien, font) + x = x + dx + y = y + dy + } + + ip = ip + 1 + seglen = seglen - 1 + } + + x = newx + y = newy + ip = op + + if (hard) { + g_reg[E_IOP] = 1 + if (stg_encode (Memc[SG_ENDTEXT(g_sg)], g_mem, g_reg) == OK) + call write (g_out, g_mem, g_reg[E_IOP] - 1) + } + } + } + + call sfree (sp) +end + + +# STX_SEGMENT -- Process the text string into segments, in the process +# converting from type short to char. The only text attribute that can +# change within a string is the font, so segments are broken by \fI, \fG, +# etc. font select sequences embedded in the text. The segments are encoded +# sequentially in the output string. The first character of each segment is +# the font number. A segment is delimited by EOS. A font number of EOS +# marks the end of the segment list. The output string is assumed to be +# large enough to hold the segmented text string. + +int procedure stx_segment (text, n, out, start_font) + +short text[ARB] # input text +int n # number of characters in text +char out[ARB] # output string +int start_font # initial font code + +int ip, op +int totlen, font + +begin + out[1] = start_font + totlen = 0 + op = 2 + + for (ip=1; ip <= n; ip=ip+1) { + if (text[ip] == '\\' && text[ip+1] == 'f') { + # Select font. + out[op] = EOS + op = op + 1 + ip = ip + 2 + + switch (text[ip]) { + case 'B': + font = GT_BOLD + case 'I': + font = GT_ITALIC + case 'G': + font = GT_GREEK + default: + font = GT_ROMAN + } + + out[op] = font + op = op + 1 + + } else { + # Deposit character in segment. + out[op] = text[ip] + op = op + 1 + totlen = totlen + 1 + } + } + + # Terminate last segment and add null segment. + + out[op] = EOS + out[op+1] = EOS + + return (totlen) +end + + +# STX_PARAMETERS -- Set the text drawing parameters, i.e., the coordinates +# of the lower left corner of the first character to be drawn, the spacing +# between characters, and the polytext flag. Input consists of the coords +# of the text string, the length of the string, and the text attributes +# defining the character size, justification in X and Y of the coordinates, +# and orientation of the string. All coordinates are in GKI units. + +procedure stx_parameters (xc, yc, totlen, x0, y0, dx, dy, polytext, orien) + +int xc, yc # coordinates at which string is to be drawn +int totlen # number of characters to be drawn +int x0, y0 # lower left corner of first char to be drawn +int dx, dy # step in X and Y between characters +int polytext # OK to output text segment all at once +int orien # rotation angle of characters + +pointer tx +bool hard +int up, path, hwsz, ch, cw, i +real dir, cosv, sinv, space +real xsize, ysize, xvlen, yvlen, xu, yu, xv, yv, p, q +include "stdgraph.com" + +begin + tx = SG_TXAP(g_sg) + + # Compute the character rotation angle. This is independent of the + # direction in which characters are drawn. A character up vector of + # 90 degrees (normal) corresponds to a rotation angle of zero. + + up = TX_UP(tx) + orien = up - 90 + + # Get character sizes in GKI(NSPP) coords. + call stx_chars (tx, ch, cw, hwsz, hard, orien) + + # Determine the direction in which characters are to be plotted. + # This depends on both the character up vector and the path, which + # is defined relative to the up vector. + + path = TX_PATH(tx) + switch (path) { + case GT_UP: + dir = up + case GT_DOWN: + dir = up - 180 + case GT_LEFT: + dir = up + 90 + default: # GT_NORMAL, GT_RIGHT + dir = up - 90 + } + + # If hardware character generation is enabled the character up vector + # is constrained to 90 degrees. Flip the direction in which characters + # will be drawn if necessary to draw from left to right or from top + # down, the readable directions. + + if (hard) { + # Constrain the up vector. + orien = 0 + + # Flip direction vector if in 2nd or 3rd quadrant. + i = nint(dir) + if (i < 0) + i = i + 360 + if (i >= 90 && i < 180) + i = i + 180 + if (i >= 360) + i = i - 360 + dir = real(i) + } + + # ------- DX, DY --------- + # Convert the direction vector into the step size between characters. + # Note CW and CH are in GKI coordinates, hence DX and DY are too. + # Additional spacing of some fraction of the character size is used + # if TX_SPACING is nonzero. + + dir = -DEGTORAD(dir) + cosv = cos (dir) + sinv = sin (dir) + + # Correct for spacing (unrotated). + space = (1.0 + TX_SPACING(tx)) + if ((path == GT_UP || path == GT_DOWN) || + (hard && abs(cosv) < .9)) { + p = ch * space + } else + p = cw * space + q = 0 + + # Correct for rotation. + dx = p * cosv + q * sinv + dy = -p * sinv + q * cosv + + # ------- XU, YU --------- + # Determine the coordinates of the center of the first character req'd + # to justify the string, assuming dimensionless characters spaced on + # centers DX,DY apart. + + xvlen = dx * (totlen - 1) + yvlen = dy * (totlen - 1) + + switch (TX_HJUSTIFY(tx)) { + case GT_CENTER: + xu = - (xvlen / 2.0) + case GT_RIGHT: + # If right justify and drawing to the left, no offset req'd. + if (xvlen < 0) + xu = 0 + else + xu = -xvlen + default: # GT_LEFT, GT_NORMAL + # If left justify and drawing to the left, full offset right req'd. + if (xvlen < 0) + xu = -xvlen + else + xu = 0 + } + + switch (TX_VJUSTIFY(tx)) { + case GT_CENTER: + yu = - (yvlen / 2.0) + case GT_TOP: + # If top justify and drawing downward, no offset req'd. + if (yvlen < 0) + yu = 0 + else + yu = -yvlen + default: # GT_BOTTOM, GT_NORMAL + # If bottom justify and drawing downward, full offset up req'd. + if (yvlen < 0) + yu = -yvlen + else + yu = 0 + } + + # ------- XV, YV --------- + # Compute the offset from the center of a single character required + # to justify that character, given a particular character up vector. + # (This could be combined with the above case but is clearer if + # treated separately.) + + p = -DEGTORAD(orien) + cosv = cos(p) + sinv = sin(p) + + # Compute the rotated character in size X and Y. + xsize = abs ( cw * cosv + ch * sinv) + ysize = abs (-cw * sinv + ch * cosv) + + switch (TX_HJUSTIFY(tx)) { + case GT_CENTER: + xv = 0 + case GT_RIGHT: + xv = - (xsize / 2.0) + default: # GT_LEFT, GT_NORMAL + xv = xsize / 2 + } + + switch (TX_VJUSTIFY(tx)) { + case GT_CENTER: + yv = 0 + case GT_TOP: + yv = - (ysize / 2.0) + default: # GT_BOTTOM, GT_NORMAL + yv = ysize / 2 + } + + # ------- X0, Y0 --------- + # The center coordinates of the first character to be drawn are given + # by the reference position plus the string justification vector plus + # the character justification vector. + + x0 = xc + xu + xv + y0 = yc + yu + yv + + # The character drawing primitive requires the coordinates of the + # lower left corner of the character (irrespective of orientation). + # Compute the vector from the center of a character to the lower left + # corner of a character, rotate to the given orientation, and correct + # the starting coordinates by addition of this vector. + + p = - (cw / 2.0) + q = - (ch / 2.0) + + x0 = x0 + ( p * cosv + q * sinv) + y0 = y0 + (-p * sinv + q * cosv) + + # ------- POLYTEXT --------- + # Set the polytext flag. Polytext output is possible only if chars + # are to be drawn to the right with no extra spacing between chars. + + if (abs(dy) == 0 && dx == cw) + polytext = YES + else + polytext = NO +end + + +# STX_CHARS -- Get the character drawing parameters, i.e., the size of a +# character in X and Y and whether or not to use the hardware character +# generator. The decision whether or not to use the hardware character +# generator is based on the text attribute QUALITY, unless overridden by +# the g_hardchar switch in common (set explicitly in cursor mode or by a +# stdgraph task parameter). + +procedure stx_chars (tx, ch, cw, hwsz, hard, orien) + +pointer tx # pointer to text attribute structure +int ch, cw # character height, width, GKI coords +int hwsz # size index if hardware character +bool hard # use/dontuse hardware character generation +int orien # rotation angle of character (0=normal) + +int sz, quality +real txsize, aspect, q +int stg_txsize() +real ttygetr() +include "stdgraph.com" + +begin + sz = TX_SIZE(tx) + if (g_hardchar == 0) + quality = TX_QUALITY(tx) + else + quality = g_hardchar + hard = (quality != GT_MEDIUM && quality != GT_HIGH) + + # Get character size in GKI units. + if (hard) { + hwsz = stg_txsize (sz) + ch = SG_CHARHEIGHT(g_sg,hwsz) + cw = SG_CHARWIDTH (g_sg,hwsz) + + } else { + # If character generation is in software scale character sizes + # by the size of the size 1 hardware character. If the character + # is rotated correct for the device aspect ratio so that the + # character comes out the same size regardless of the orientation. + + txsize = GKI_UNPACKREAL(sz) + cw = SG_CHARWIDTH (g_sg,1) * txsize + ch = SG_CHARHEIGHT(g_sg,1) * txsize + + if (orien != 0) { + aspect = ttygetr (g_tty, "ar") + if (aspect > EPSILON && abs (aspect - 1.0) > .01) { + q = 1.0 + abs(sin(real(orien))) * (aspect - 1.0) + cw = cw / q + ch = ch * q + } + } + } +end diff --git a/sys/gio/stdgraph/stgtxqual.x b/sys/gio/stdgraph/stgtxqual.x new file mode 100644 index 00000000..122cf303 --- /dev/null +++ b/sys/gio/stdgraph/stgtxqual.x @@ -0,0 +1,17 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_TXQUALITY -- Select the type of character generator to be used. If the +# selected flag value is 0 this decision will be deferred to the set text +# attribute instruction at runtime (default). + +procedure stg_txquality (quality) + +int quality # text generation quality flag +include "stdgraph.com" + +begin + g_hardchar = quality +end diff --git a/sys/gio/stdgraph/stgtxset.x b/sys/gio/stdgraph/stgtxset.x new file mode 100644 index 00000000..8db3e8c3 --- /dev/null +++ b/sys/gio/stdgraph/stgtxset.x @@ -0,0 +1,34 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "stdgraph.h" + +# STG_TXSET -- Set the text drawing attributes. + +procedure stg_txset (gki) + +short gki[ARB] # attribute structure +pointer tx +include "stdgraph.com" + +begin + tx = SG_TXAP(g_sg) + + TX_UP(tx) = gki[GKI_TXSET_UP] + TX_PATH(tx) = gki[GKI_TXSET_P ] + TX_HJUSTIFY(tx) = gki[GKI_TXSET_HJ] + TX_VJUSTIFY(tx) = gki[GKI_TXSET_VJ] + TX_FONT(tx) = gki[GKI_TXSET_F ] + TX_QUALITY(tx) = gki[GKI_TXSET_Q ] + TX_COLOR(tx) = gki[GKI_TXSET_CI] + + # Unpack the packed-real character spacing parameter. + TX_SPACING(tx) = GKI_UNPACKREAL (gki[GKI_TXSET_SP]) + + # The character size is left as a packed real as we must defer the + # decision to use a discreet hardware character size or to draw + # characters in software. + + TX_SIZE(tx) = gki[GKI_TXSET_SZ] +end diff --git a/sys/gio/stdgraph/stgtxsize.x b/sys/gio/stdgraph/stgtxsize.x new file mode 100644 index 00000000..71829e04 --- /dev/null +++ b/sys/gio/stdgraph/stgtxsize.x @@ -0,0 +1,31 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +# STG_TXSIZE -- Given the relative character size as a packed real, select +# the discreet closest device character size. + +int procedure stg_txsize (pksize) + +int pksize # packed real relative character size +int i, best_size +real txsize, diff, least_diff +include "stdgraph.com" + +begin + txsize = GKI_UNPACKREAL (pksize) + + best_size = 1 + least_diff = abs (txsize - SG_CHARSIZE(g_sg,1)) + + do i = 2, SG_NCHARSIZES(g_sg) { + diff = abs (txsize - SG_CHARSIZE(g_sg,i)) + if (diff < least_diff) { + best_size = i + least_diff = diff + } + } + + return (best_size) +end diff --git a/sys/gio/stdgraph/stgunkown.x b/sys/gio/stdgraph/stgunkown.x new file mode 100644 index 00000000..55327b62 --- /dev/null +++ b/sys/gio/stdgraph/stgunkown.x @@ -0,0 +1,14 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +# STG_UNKNOWN -- The unknown instruction. Called by the interpreter whenever +# an unrecognized opcode is encountered. Should never be called. + +procedure stg_unknown (gki) + +short gki[ARB] # the GKI instruction +int fd, verbose +common /stgcom/ fd, verbose + +begin + call fprintf (fd, "unknown\n") +end diff --git a/sys/gio/stdgraph/stgwtty.x b/sys/gio/stdgraph/stgwtty.x new file mode 100644 index 00000000..c01bd93c --- /dev/null +++ b/sys/gio/stdgraph/stgwtty.x @@ -0,0 +1,118 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include "stdgraph.h" + +# STG_WRITETTY -- Write one or more lines of text to the terminal in text +# mode. If the workstation is currently activated normal output is to the +# status line, otherwise output is to the indicated stream (STDOUT or +# STDERR). If the worstation is activated and the text to be output is +# preceded by the EM code, the text is a message being sent by GIO to a user +# interface parameter, and the text is passed on as is without formatting for +# the status line. +# +# Terminal output is directed to the status line by the GD sequence, and +# graphics output is reenabled by the GE sequence. The output text should +# consist of only a single line, but if multiple lines are present they are +# output line by line, without the trailing newline, since the status line +# can display only a single line of text. +# +# NOTE - If output occurs while in graphics mode and the output text is newline +# terminated, the GE (graphics enable) sequence is output to restore the +# terminal to graphics mode before exiting. If the text is not newline +# terminated, e.g., if it is a prompt, the workstation is left in alpha mode, +# ready for a read from STDIN. Thus one can write a prompt to STDOUT and read +# the user response from STDIN, while in graphics mode. +# +# This procedure is called by pseudofile i/o (gio/cursor/prpsio) whenever a +# task writes to STDOUT or STDERR. + +procedure stg_writetty (fd, text, nchars) + +int fd #I output stream +char text[ARB] #I text to be output +int nchars #I nchars to be written + +int ip, delim +pointer sp, lbuf, op +include "stdgraph.com" +bool ttygetb() +errchk write + +begin + if (g_active == NO) { + # Workstation not activated (normal text mode); normal text output. + call write (fd, text, nchars) + call flush (fd) + + } else if (text[1] == EM || g_message == YES) { + # Workstation is activated; the output text is a message to be + # sent to a UI parameter. The output stream is assumed to be + # flushed before and after a UI message, so we assume that the + # control codes used to bracket the message are the first and + # last characters in the output write packets. Multiple writes + # may be used to write output text, and messages can be any + # length. If the output device does not support messaging (no + # "EM" capability) the messages are discarded. + + g_message = YES + if (ttygetb (g_tty, "EM")) + call write (g_out, text, nchars) + delim = text[nchars] + if (delim == GS || delim == US) + g_message = NO + + } else { + # Workstation is activated; write to status line. Writing + # anything when graphics is enabled causes the status line to be + # cleared; newline causes a graphics enable; the string "\n\n" + # will always clear the status line and leave the terminal in + # graphics mode, regardless of the state of g_enable when issued. + + call smark (sp) + call salloc (lbuf, SZ_LINE, TY_CHAR) + + if (g_enable == YES) + call stg_gdisab() + + op = lbuf + for (ip=1; ip <= nchars; ip=ip+1) { + if (text[ip] == '\n') { + if (g_enable == YES) + call stg_gdisab() + if (op > lbuf) + call write (g_out, Memc[lbuf], op-lbuf) + call stg_genab() + op = lbuf + } else { + Memc[op] = text[ip] + op = min (lbuf+SZ_LINE, op+1) + } + } + + # Output a partial line, leaving graphics disabled. + if (op > lbuf) { + if (g_enable == YES) + call stg_gdisab() + call write (g_out, Memc[lbuf], op-lbuf) + } + + call flush (g_out) + call sfree (sp) + } +end + + +# STG_PUTLINE -- Output an EOS delimited line of text to the graphics terminal +# with stg_writetty. + +procedure stg_putline (fd, text) + +int fd # output file +char text[ARB] # EOS delimited line of text +int strlen() + +begin + call stg_writetty (fd, text, strlen(text)) +end diff --git a/sys/gio/stdgraph/t_gkideco.x b/sys/gio/stdgraph/t_gkideco.x new file mode 100644 index 00000000..200cf33a --- /dev/null +++ b/sys/gio/stdgraph/t_gkideco.x @@ -0,0 +1,63 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include + +# GKIDECODE -- Decode the contents of one or more metacode files, printing +# the decoded metacode instructions in readable form on the standard output. + +procedure t_gkidecode() + +int fd, list, verbose, gkiunits +pointer gki, sp, fname +int dd[LEN_GKIDD] + +bool clgetb() +int clpopni(), clgfil(), clplen(), open(), btoi() +int gki_fetch_next_instruction() + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + + # Open list of metafiles to be decoded. + list = clpopni ("input") + + if (clgetb ("generic")) { + verbose = NO + gkiunits = NO + } else { + verbose = btoi (clgetb ("verbose")) + gkiunits = btoi (clgetb ("gkiunits")) + } + + # Set up the decoding graphics kernel. + call gkp_install (dd, STDOUT, verbose, gkiunits) + + # Process a list of metacode files, writing the decoded metacode + # instructions on the standard output. + + while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) { + # Print header if new file. + if (clplen (list) > 1) { + call printf ("\n# METAFILE '%s':\n") + call pargstr (Memc[fname]) + } + + # Open input file. + iferr (fd = open (Memc[fname], READ_ONLY, BINARY_FILE)) { + call erract (EA_WARN) + next + } else + call gkp_grstream (fd) + + # Process the metacode. + while (gki_fetch_next_instruction (fd, gki) != EOF) + call gki_execute (Mems[gki], dd) + + call close (fd) + } + + call clpcls (list) + call sfree (sp) +end diff --git a/sys/gio/stdgraph/t_showcap.x b/sys/gio/stdgraph/t_showcap.x new file mode 100644 index 00000000..ddb8407c --- /dev/null +++ b/sys/gio/stdgraph/t_showcap.x @@ -0,0 +1,210 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include "stdgraph.h" + +define SZ_PROGRAM 256 +define MAXARGSTR 15 + + +# SHOWCAP - Show the ascii control string sent to a device to implement a +# control function. Useful for testing graphcap entries. + +procedure t_showcap() + +char cap[2] +int g_reg[NREGISTERS] +char g_mem[SZ_MEMORY] +char argstr[MAXARGSTR] +int arg1, arg2, arg3, op, len_prog, status, nchars +pointer tty, sp, prog, ip, cmd +pointer ttygdes(), ttycaps() +int stg_encode(), ctoi(), getline(), strncmp() +int ttygets(), ctowrd(), strlen() +bool ttygetb(), streq() +define getargs_ 91 + +begin + call smark (sp) + call salloc (cmd, SZ_LINE, TY_CHAR) + call salloc (prog, SZ_PROGRAM, TY_CHAR) + + # Print instructions. + call printf ("cmd : `set' device\n") + call printf (" | `*' (to dump full graphcap entry\n") + call printf (" | cc [arg1 [arg2 [arg3]]]\n") + call printf (" ;\n") + call printf ("\n") + call printf ("cc : a two chararacter capcode (e.g., 'cm')\n") + call printf (" | an encoder program (non alpha first char)\n") + call printf (" ;\n") + call printf ("\n") + + # Interpret and translate control commands until EOF or "bye" + # is typed. + + tty = NULL + + repeat { + # Prompt for input. + call printf ("* ") + call flush (STDOUT) + + if (getline (STDIN, Memc[cmd]) == EOF) { + call printf ("\n") + break + } + + for (ip=cmd; IS_WHITE (Memc[ip]); ip=ip+1) + ; + + if (Memc[ip] == '\n') { + next + } else if (strncmp (Memc[ip], "set", 3) == 0) { + ip = ip + 3 + len_prog = ctowrd (Memc, ip, Memc[prog], SZ_PROGRAM) + if (tty != NULL) + call ttycdes (tty) + tty = ttygdes (Memc[prog]) + call sgc_dump (STDOUT, Memc[ttycaps(tty)], + strlen (Memc[ttycaps(tty)])) + next + } else if (Memc[ip] == '*') { + call sgc_dump (STDOUT, Memc[ttycaps(tty)], + strlen (Memc[ttycaps(tty)])) + next + } else if (!IS_ALPHA (Memc[ip])) { + len_prog = ctowrd (Memc, ip, Memc[prog], SZ_PROGRAM) + cap[1] = EOS + goto getargs_ + } else if (strncmp (Memc[ip], "bye", 3) == 0) + break + + # Parse command with optional arguments, e.g., "RC 1". + # Extract 2 character capability name (required). + + op = 1 + while (IS_ALNUM(Memc[ip])) { + cap[op] = Memc[ip] + ip = ip + 1 + op = min (2, op + 1) + } + cap[3] = EOS +getargs_ + # Argument type depends on whether encoding or decoding. + if (streq ("SC", cap)) { + nchars = ctowrd (Memc, ip, argstr, MAXARGSTR) + if (nchars == 0) { + call printf ("SC must have 1 contiguous string argument\n") + next + } + + } else { + # Extract up to three arguments (optional). + if (ctoi (Memc, ip, arg1) <= 0) + arg1 = 0 + if (ctoi (Memc, ip, arg2) <= 0) + arg2 = 0 + if (ctoi (Memc, ip, arg3) <= 0) + arg3 = 0 + } + + # Fetch the program from the graphcap file. Zero is returned if + # the device does not have the named capability, in which case + # the function is inapplicable and should be ignored. + + if (cap[1] != EOS) + if (tty == NULL) { + call printf ("use `set' to specify device name\n") + next + } else + len_prog = ttygets (tty, cap, Memc[prog], SZ_PROGRAM) + + if (len_prog > 0) { + if (Memc[prog] == '#') + call sgc_dump (STDOUT, Memc[prog+1], len_prog - 1) + else { + # Dump the program on the standard output. + if (cap[1] != EOS) { + call printf ("program: ") + call sgc_dump (STDOUT, Memc[prog], len_prog) + } + + # Set memory or registers depending on whether encoding or + # decoding. + if (streq ("SC", cap)) + call strcpy (argstr, g_mem, nchars) + + else { + g_reg[1] = arg1 + g_reg[2] = arg2 + g_reg[3] = arg3 + } + g_reg[E_IOP] = 1 + g_reg[E_TOP] = SZ_MEMORY + + # If scan_cursor, decode the input string and write the + # registers to the output file. Else, encode the output + # string and write the encoded string to the output file. + + status = stg_encode (Memc[prog], g_mem, g_reg) + if (status == OK) { + nchars = g_reg[E_IOP] - 1 + + if (streq ("SC", cap)) { + call printf ("X(R1)=%d, Y(R2)=%d, key=%c\n") + call pargi (g_reg[1]) + call pargi (g_reg[2]) + call pargi (g_reg[3]) + } else { + call printf ("encoding: ") + call sgc_dump (STDOUT, g_mem, nchars) + } + + } else + call printf ("error encoding control string\n") + call printf (" status = %d\n") + call pargi (status) + } + + } else if (len_prog == 0) + if (ttygetb (tty, cap)) + call printf ("boolean capability is true\n") + + else { + call printf ("device capability `%s' not found\n") + call pargstr (cap) + } + } + + if (tty != NULL) + call ttycdes (tty) + call sfree (sp) +end + + +# SGC_DUMP -- Dump a sequence of ascii characters in printable form. + +procedure sgc_dump (fd, data, nchars) + +int fd # output file +char data[ARB] # chars to be dumped +int nchars + +int ip +int col + +begin + col = 1 + for (ip=1; ip <= nchars; ip=ip+1) { + call putcc (fd, data[ip]) + if (data[ip] == ':' && col > 60) { + call putci (fd, '\\') + call putci (fd, '\n') + col = 1 + } else + col = col + 1 + } + + call putci (fd, '\n') +end diff --git a/sys/gio/stdgraph/t_stdgraph.x b/sys/gio/stdgraph/t_stdgraph.x new file mode 100644 index 00000000..8d6856fc --- /dev/null +++ b/sys/gio/stdgraph/t_stdgraph.x @@ -0,0 +1,110 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +include +include +include + +define SZ_TXQUALITY 1 + +# STDGRAPH -- Graphics kernel for the standard graphics output (interactive +# graphics terminal). + +procedure t_stdgraph() + +int fd, list +char txquality[SZ_TXQUALITY] +pointer gki, sp, fname, devname +int dev[LEN_GKIDD], deb[LEN_GKIDD] +int debug, verbose, gkiunits, xres, yres, quality +bool clgetb() +int clpopni(), clgfil(), open(), btoi(), clgeti() +int gki_fetch_next_instruction() + +begin + call smark (sp) + call salloc (fname, SZ_FNAME, TY_CHAR) + call salloc (devname, SZ_FNAME, TY_CHAR) + + # Open list of metafiles to be decoded. + list = clpopni ("input") + + # Get parameters. + call clgstr ("device", Memc[devname], SZ_FNAME) + + if (clgetb ("generic")) { + debug = NO + verbose = NO + gkiunits = NO + quality = 0 + xres = 0 + yres = 0 + + } else { + debug = btoi (clgetb ("debug")) + if (debug == YES) { + verbose = btoi (clgetb ("verbose")) + gkiunits = btoi (clgetb ("gkiunits")) + } + + # Get the quality parameter for the text generator. + call clgstr ("txquality", txquality, SZ_TXQUALITY) + switch (txquality[1]) { + case 'l': + quality = GT_LOW + case 'm': + quality = GT_MEDIUM + case 'h': + quality = GT_HIGH + default: + quality = 0 + } + + xres = clgeti ("xres") + yres = clgeti ("yres") + } + + # Open the graphics kernel. + + call stg_open (Memc[devname], dev, STDIN, STDOUT, xres, yres, quality) + call gkp_install (deb, STDERR, verbose, gkiunits) + + # Process a list of metacode files, writing the decoded metacode + # instructions on the standard output. + + while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) { + # Open input file. + iferr (fd = open (Memc[fname], READ_ONLY, BINARY_FILE)) { + call erract (EA_WARN) + next + } else + call stg_grstream (fd) + + # Process the metacode instruction stream. + while (gki_fetch_next_instruction (fd, gki) != EOF) + switch (Mems[gki+GKI_HDR_OPCODE-1]) { + case GKI_CLOSEWS, GKI_DEACTIVATEWS, GKI_REACTIVATEWS: + # These instructions are passed directly to the kernel via + # the PSIOCTRL stream at runtime, but are ignored in + # metacode to avoid unnecessary mode switching of the + # terminal. + ; + default: + if (debug == YES) + call gki_execute (Mems[gki], deb) + call gki_execute (Mems[gki], dev) + } + + call close (fd) + } + + # Make sure we finish with CLOSEWS so that the terminal is left in + # text mode. + + call stg_closews (NULL, NULL) + + # Finish up. + call gkp_close() + call stg_close() + call clpcls (list) + call sfree (sp) +end diff --git a/sys/gio/stdgraph/x_stdgraph.x b/sys/gio/stdgraph/x_stdgraph.x new file mode 100644 index 00000000..37c5a055 --- /dev/null +++ b/sys/gio/stdgraph/x_stdgraph.x @@ -0,0 +1,5 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +task gkidecode = t_gkidecode, + stdgraph = t_stdgraph, + showcap = t_showcap diff --git a/sys/gio/stdgraph/zzdebug.x b/sys/gio/stdgraph/zzdebug.x new file mode 100644 index 00000000..ce11d4ea --- /dev/null +++ b/sys/gio/stdgraph/zzdebug.x @@ -0,0 +1,37 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +task slio = t_slio + +procedure t_slio() + +pointer gp +char lbuf[SZ_LINE] +real x[5], y[5] + +pointer gopen() +int getline() + +begin + x[1] = .25; y[1] = .25 + x[2] = .75; y[2] = .25 + x[3] = .75; y[3] = .75 + x[4] = .25; y[4] = .75 + x[5] = .25; y[5] = .25 + + gp = gopen ("stdgraph", NEW_FILE, STDGRAPH) + call gpline (gp, x, y, 5) + call gflush (gp) + + call putline (STDOUT, "enter text: ") + call flush (STDOUT) + + if (getline (STDIN, lbuf) != EOF) { + call zwmsec (3000) + call printf ("text = %s") + call pargstr (lbuf) + call flush (STDOUT) + } + + call zwmsec (3000) + call gclose (gp) +end -- cgit