
%*******************************************************************************
%*                    START OF AUTOMATICALLY GENERATED TEX FILE                *
%*******************************************************************************
%*                                                                             *
%* This TeX file was automatically generated by the FunnelWeb preprocessor.    *
%* You can typeset this file to produce printed documentation by running it    *
%* through the TeX typesetter using a command such as:                         *
%*    tex thisfilename                                                         *
%* The resultant file thisfilename.dvi can be printed using a command such as: *
%*    lpr -Plaser -d thisfilename.dvi                                          *
%*                                                                             *
%* FunnelWeb is a preprocessor that allows programmers to weave programs and   *
%* their documentation together in a single document. The FunnelWeb program    *
%* analyses such documents producing both program files and typeset            *
%* documentation such as this TeX file.                                        *
%* FunnelWeb was created by Ross N. Williams.                                  *
%*                                                                             *
%* For more information on FunnelWeb see http://www.ross.net/funnelweb/        *
%*                                                                             *
%*******************************************************************************


%===================== Start of FunnelWeb TeX Definitions ======================


% Version
% -------
% This is FunnelWeb TeX Macro Library Version 1.0.


% Copyright
% ---------
% This set of FunnelWeb TeX definitions was written by Ross Williams and was
% originally Copyright (C) 1992 Ross N. Williams.  However, I, Ross Williams,
% hereby forego any claim to Copyright in this set of FunnelWeb TeX definitions
% and hereby authorize that the set of TeX definitions pass into the public
% domain. -- Ross N. Williams, 3:41pm 07-May-1992, Adelaide, Australia.


% Modification
% ------------
% Please record all modifications to these TeX definitions here. Unless
% otherwise specified, all modified definitions fall in the public domain too.
%
% Programmers:
%    RNW  Ross N. Williams  ross@ross.net
%
% Changes:
%    07-May-1992  RNW  Prepared this work for public domain release.
%    10-May-1999  RNW  Added \fwlib macro.


% General Comments
% ----------------
% This set of TeX definitions exists for two reasons:
%
%    1. To shorten and neaten the FunnelWeb TeX output.
%    2. To allow users to fiddle with the output format in their input files
%       (by inserting redefining "\def"s) without having to resort to
%       modifying the FunnelWeb code.
%
% The user is warned that these definitions may be changed from time to time
% (but probably not much). The user should not be too sneaky. In particular,
% users wishing to redefine some of these macros should do so in an explicitly
% defined section at the top of their input file. This will mean that in the
% event of problems, that section can simply be deleted or commented out to
% allow the document to at least be typeset in the default format. Users should
% limit themselves to redefining these macros in such a section and should
% refrain from using the macros throughout their documents.


% Environment Parameters
% ----------------------
% \tolerance tells TeX how tolerant it should be about making bad line and
% page breaks. Here we set it to it's maximum, as
%   1) Computer programs are likely to cause lots of bad breaks.
%   2) In most cases the user would probably rather get the TeX file through
%      TeX without any errors than fiddle with spacings for perfection.
\tolerance=10000

% I don't like indentation as it makes the page look more busy. Instead,
% paragraphs are separated by a little space (see next).
\parindent=0pt

% In many cases, users will produce documents with long runs of paragraphs.
% In order to space out these paragraphs, it is convenient to maintain a
% prevailing non-zero \parskip (end-of-paragaph skip). The only trouble is
% that the skip becomes a problem in macro definitions which require no skip
% and so we have to turn the skip on and off. The following two macros
% simplify this process.
\def\fwparskipon{\parskip=\medskipamount}
\def\fwparskipoff{\parskip=0pt}
\fwparskipon

% Setting raggedbottom allows TeX to leave a bit of space at the bottom of the
% page in order to better vertically align the rest of the page (e.g. skips
% won't stretch as much). It also means that headings are less likely to be
% isolated at the bottom of the page without any following text.
\raggedbottom


% Fonts
% -----
% Most of the typeset output is set in 10pt roman and 10pt tt font.
% The major extra font needs spring from titles and headings.
% For portability's sake we use only the following fonts:
%    cmr10
%    cmbx10
%    cmtt10
% and some enlargements of them. These fonts are all "standard" fonts
% in Plain TeX. See The TeXbook p.350.
\font\fwfontnote=cmr7

\font\fwfontnorm=cmr10
\font\fwfontnorma=cmr10 scaled \magstep1
\font\fwfontnormb=cmr10 scaled \magstep2

\font\fwfontbold=cmbx10
\font\fwfontbolda=cmbx10 scaled \magstep1
\font\fwfontboldb=cmbx10 scaled \magstep2
\font\fwfontboldc=cmbx10 scaled \magstep3
\font\fwfontboldd=cmbx10 scaled \magstep4


% Macros for Stylistic Details
% ----------------------------
% This section contains all the fiddly little macros for setting the details
% of each macro definition.

% Macro definitions are sandwiched by calls to these macros which can be used
% to sort out the spacing before and after the macro definition.
\def\fwbeginmacro{\fwparskipoff\bigskip}
\def\fwendmacro{\fwparskipon\par}

% These macros deal with the macro name and definition line.
\def\fwmacroname#1#2{{\sl #1\/}$\lbrack$#2$\rbrack$}
\def\fwfilename#1#2{{\bf #1}$\lbrack$#2$\rbrack$}
\def\fwzero#1{{\bf Z}}
\def\fwmany#1{{\bf M}}
\def\fwlib#1{{\bf L}}
\def\fwequals{ $\equiv$}
\def\fwplusequals{ $+\equiv$}

% Now for the actual body of the definition. It looks nice to have the tt
% code indented a little. Again, we use macros instead of writing direct TeX,
% so as to allow the user to fiddle this stuff to taste without having to
% modify the FunnelWeb C code.
\def\fwodef{\parindent=15pt\vskip0pt$\lbrace$\parindent=20pt}
\def\fwcdef{$\rbrace$\vskip0pt\parindent=0pt}
\def\fwoquote{`}
\def\fwcquote{'}
\def\fwoparen{$($}
\def\fwcomma{$,$}
\def\fwcparen{$)$}
\def\fwparam#1{$\diamond #1$}
\def\fwparams#1{$(\diamond #1)$}

% These macros deal with the notes that are appended at the end of each
% macro definition. Note that even though \fwisafile,\fwusedin, and \fwseealso
% have the same definition, they are given different names so as to allow the
% user to redefine these macros to typeset each kind of information differently
% if desired.
\def\fwbeginmacronotes{\begingroup\baselineskip=9pt\smallskip}
\def\fwnote#1{{\fwfontnote #1}\par}
\def\fwisafile#1{\fwnote{#1}}
\def\fwusedin#1{\fwnote{#1}}
\def\fwseealso#1{\fwnote{#1}}
\def\fwendmacronotes{\endgroup}


% Macros to Typeset Program Code Verbatim
% ---------------------------------------
% This is by far the hairiest and most difficult part of the typesetting task
% because we have to turn off most of TeX's natural instincts in order to
% typeset the program text exactly as it appears in the input file.
% Two macros are defined to pull this off: \fwbtx and \fwverbatimgobble.
% Their code was inspired by the following sections of "The TeXbook":
%    Appendix D: Dirty Tricks, 3.Verbatim listing, p.380-382.
%    Appendix E: Example Formats, p.421.
% The \fwbtx[ (for "FunnelWeb Begin TeXt") macro does most of the hard work.
% The liberal use of "%" is because I don't understand TeX well enough to
% understand when an end of line will cause trouble, and I am playing it safe.

% Before defining the main \fwbtx macro, we have to stash away some definitions
% in the hidden part of TeX's environment. Let's hope that these "hidden"
% definitions don't affect anything except what is desired to be affected.

% The tt font in which we wish to set the text has two Latin lurking ligatures!
% These are ?` and !`. To disable them, we define the left quote when ACTIVE
% to be defined in such a way as to prevent ligatures. The main TeX text will
% normally not be exposed to this definition because normally the leftquote
% character is not active. The \fwbtx macro temporarily makes the left quote
% character active thus activating the deactivation of left quote ligatures.
% See The TeXbook p.381.
{\catcode`\`=\active \gdef`{\relax\lq}}

% TeX is fairly carefree about spaces and so we have to make it more serious.
% To do so we pull the same trick as above, setting up a definition for active
% space, but only making space active during the span of the verbatim text.
% In Plain TeX the active space is defined to be simply a space, but here we
% define it to be a control space. This ensures that the space cannot
% be gobbled up by one of TeX's mysterious mechanisms when activated.
% See The TeXbook, p.381 and p.352.
{\obeyspaces\global\let =\ }

% Here is the main \fwbtx verbatim text macro.
% Note: The order in which all these pieces of business have to be done is
% still a partial mystery to me. Don't fiddle with this stuff unless you
% think you know what you are doing.
\def\fwbtx[{%
%
% The funnies involved in getting verbatim output are safely housed inside
% this \begingroup, and the \endgroup in \fwverbatimgobble. Groups are used
% instead of curly braces because we have to be able to signal the end of
% this macro with a curly brace.
\begingroup%
%
% \pars at the end of empty lines in the verbatim text won't come out normally
% because TeX is in vertical mode and they get gobbled up. To prevent this,
% we force \par to exit vertical mode first. See The TeXbook p.381.
\def\par{\leavevmode\endgraf}%
%
% Activate the leftquote character so as to avoid ligatures (see above).
\catcode`\`=\active%
%
% The \obeylines macro simply defines end of line (^M) to be \par. This ensures
% that TeX will treat each verbatim line as a new paragraph.
\obeylines%
%
% To get verbatim output, we have to desex all the special characters. This
% is explained in detail in The TeXbook p.380.
\def\do##1{\catcode`##1=12 }\dospecials%
%
% Activate the space character so as to make TeX treat blanks seriously.
% This activation invokes an eralier definition (see above).
\obeyspaces
%
% Interparagraph skips do not help the cause.
% Note: We have to preserve the indentation though, as the code is actually
% indented in the final output. See \fwodef in an earlier section.
\parskip=0pt%
%
% We typeset the verbatim text in tt font (courier on the Macintosh) for a
% number of reasons:
%    - tt font has the same horizontal spacing for each character.
%    - tt font covers the ASCII character set.
%    - tt font doesn't have many surprises (e.g. ligatures).
%    - tt font looks much what you might see on a computer terminal screen.
\tt%
%
% Having set up an environment for verbatim, we are ready to use it.
% By invoking \fwverbatimgobble, this \fwbtx macro gobbles up text verbatim (as
% part of the parameter of \fwverbatimgobble) until it sees the termination
% string "]fwetx=" (the "=" was thrown in to add obscurity as this sequence
% must never occur in the verbatim text).
\fwverbatimgobble}

% The \fwverbatimgobble macro exists to allow \fwbtx to bracket verbatim text.
\def\fwverbatimgobble#1]fwetx={#1\endgroup}


% Table of Contents
% -----------------
% The five levels of table of contents that FunnelWeb supports are identified
% by the five letters [A..E]. These are used throughout the following macros.

% The following macros are utilities to the TOC macros to follow.
\def\fwrule{\medskip\hrule\medskip}
\def\fwqh{\hskip1.5em\relax}
\def\fwbeforesec{\penalty-200\bigskip\medskip\par}

% The following macros are used to typeset the table of contents.
\def\fwtocstart#1{\fwrule\leftline{\fwfontbolda Table of Contents}\fwrule}
\def\fwtoca#1#2{\leftline{{\bf #1 #2}}}
\def\fwtocb#1#2{\leftline{\fwqh #1 #2}}
\def\fwtocc#1#2{\leftline{\fwqh\fwqh #1 #2}}
\def\fwtocd#1#2{\leftline{\fwqh\fwqh\fwqh #1 #2}}
\def\fwtoce#1#2{\leftline{\fwqh\fwqh\fwqh\fwqh #1 #2}}
\def\fwtocfinish#1{\fwrule}

% The following "library" macros define five different strengths of headings
% which can be used later in the section macros.
\def\fwliba#1#2{\vfill\eject{\fwfontboldc #1 #2}\penalty200\smallskip}
\def\fwlibb#1#2{\fwbeforesec{\fwfontboldb #1 #2}\penalty200\smallskip}
\def\fwlibc#1#2{\fwbeforesec{\fwfontnormb #1 #2}\penalty200\smallskip}
\def\fwlibd#1#2{\fwbeforesec{\bf          #1 #2}\penalty200}
\def\fwlibe#1#2{\fwbeforesec{\bf          #1 #2}}

% Here are the macros that actually typeset the section headings throughout
% the document. The fwlib system has been employed so as to easily allow the
% user to redefine the strengths of headings to taste. For example, the
% user could insert in the input document a similar set of definitions to these
% but with the b..e headings set to \fwlibc. This would tone down the output.
\def\fwseca#1#2{\fwliba{#1}{#2}}
\def\fwsecb#1#2{\fwlibb{#1}{#2}}
\def\fwsecc#1#2{\fwlibc{#1}{#2}}
\def\fwsecd#1#2{\fwlibd{#1}{#2}}
\def\fwsece#1#2{\fwlibe{#1}{#2}}


% Support for Explicit Typesetting
% --------------------------------
% FunnelWeb supports pragmas and other constructs that allow
% typesetter-independent typesetting commands to be given. The
% following macros support these features.

% The in-text literal @{sloth@} and emphasise @[walrus@] features.
\def\fwlit#1{{\tt #1}}
\def\fwemp#1{{\it #1}}

% The "@p new_page" pragma.
\def\fwnewpage{\vfill\eject}

% The "@p vskip Nmm" pragma.
\def\fwvskip#1{\null\vskip #1mm}

% The "@p title <font> <align> <text>" pragma.
\def\fwfontnormal#1{{\fwfontnorm {#1}}}
\def\fwfonttitle#1{{\fwfontboldd {#1}}}
\def\fwfontsmalltitle#1{{\fwfontboldb {#1}}}
\def\fwleftline#1{\leftline{#1}}
\def\fwcenterline#1{\centerline{#1}}
\def\fwrightline#1{\rightline{#1}}


% Support for Old FunnelWeb
% -------------------------
% The following macros were used extensively in the first version of
% FunnelWeb and are retained so that these older input files will still
% typeset cleanly.
\def\p#1{{\tt #1}}  % P for Program text.
\def\flagpage#1#2{
   \null
   \vfill
   \centerline{\fwfontboldd #1}
   \vskip 1cm
   \centerline{\fwfontboldd #2}
   \vfill
   \null
   \vfill
}

%====================== End of FunnelWeb TeX Definitions =======================
\font\sc=cmcsc10
\def\title{turntab}
\def\version{0.4.2 extremely $\alpha$}
\def\updatedate{October, 2020}

\fwvskip{25}
\fwcenterline{\fwfontnormal{BREYDON's}}
\fwvskip{3}
\fwcenterline{\fwfonttitle{turntab}}
\fwvskip{3}
\fwcenterline{\fwfontsmalltitle{turner of tablet}}
\fwvskip{30}
Version: \version

\updatedate

---

K.F. B{\sc reydon}

www.breydon.id.au
\fwvskip{5}

\fwtocstart{}
\fwtoca{1}{Acknowledgement of Country}
\fwtoca{2}{Overview}
\fwtocb{2.1}{Cataloguing}
\fwtocb{2.2}{What is turntab?}
\fwtocb{2.3}{Features}
\fwtoca{3}{Follow command line instructions}
\fwtoca{4}{Figure things out}
\fwtocb{4.1}{Suss out orientation of graphical display}
\fwtocb{4.2}{Find all the forms of tablet input}
\fwtocb{4.3}{Suss out orientation of tablet input}
\fwtoca{5}{Change things}
\fwtocb{5.1}{Translate terminology}
\fwtocb{5.2}{Increment rotation goals}
\fwtocb{5.3}{Orient graphical display}
\fwtocb{5.4}{Orient tablet input}
\fwtocb{5.5}{Orient frame-buffer consoles}
\fwtoca{6}{Supply information without accompanying action}
\fwtocb{6.1}{Offer help}
\fwtocb{6.2}{Cite origins}
\fwtoca{7}{Finish}
\fwtocfinish{}


\footline={\fwfontnorm
\ifodd \pageno
    {\title\hfill v \version\hfill\the\pageno}
\else
    {\the\pageno\hfill v \version\hfill \title}
\fi}

\fwseca{1}{Acknowledgement of Country}

\fwbeginmacro
\fwmacroname{Acknowledgement of Country}{1}\fwequals \fwodef \fwbtx[turntab has been written on Boon Wurrung land.
I pay my respects to the Boon Wurrung people,
especially their Elders, and to all Indigineous
communities within whose lands, waters or skies
this software is read, adapted or run.

                       \342\237\244\342\237\245
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 22.}
\fwendmacronotes
\fwendmacro


\fwlit{\char`\\342\char`\\237\char`\\244} and \fwlit{\char`\\342\char`\\237\char`\\245} are C
octal escaped UTF-8 representations of modal
operator symbols ``was always'' and ``will
always be'' --- used here in allusion to the
phrase {\it Always was and always will be
Aboriginal land}.

\fwseca{2}{Overview}

\fwsecb{2.1}{Cataloguing}

Reference, in the script, to version number,
update dates and so on draws on the following
few macros.  These macros haven't been connected
to their \TeX~equivalents --- I still edit
footline and coverpage mentions separately.

\fwbeginmacro
\fwmacroname{Version}{2}\fwmany{}\fwequals \fwodef \fwbtx[v0.4.2 extremely alpha]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definitions 9 and 22.}
\fwendmacronotes
\fwendmacro


\fwbeginmacro
\fwmacroname{Dates}{3}\fwmany{}\fwequals \fwodef \fwbtx[Written October 2020.
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 22.}
\fwendmacronotes
\fwendmacro


\fwbeginmacro
\fwmacroname{Credits}{4}\fwmany{}\fwequals \fwodef \fwbtx[Author: Kermie BREYDON (they/them/their).
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 22.}
\fwendmacronotes
\fwendmacro


\fwbeginmacro
\fwmacroname{URL for turntab}{5}\fwmany{}\fwequals \fwodef \fwbtx[https://www.breydon.id.au/puting/turntab/]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definitions 9 and 22.}
\fwendmacronotes
\fwendmacro


Should this web address fall out of date, kindly
change it to a freely available record held by a
public library or similar.  (If nowhere has
\fwlit{turntab} these days, consider donating this
copy you are reading).  Thanks :)

\fwbeginmacro
\fwmacroname{Copyright status}{6}\fwmany{}\fwequals \fwodef \fwbtx[This software is in the public domain. It is
free for use by anyone and for any purpose. The
software is offered "as is", without warranty of
any kind.
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definitions 7 and 22.}
\fwendmacronotes
\fwendmacro


Gonna pop that last passage into in a file named
\fwlit{COPYING}, for those folks relying on
automated searches for one.

\fwbeginmacro
\fwfilename{COPYING}{7}\fwequals \fwodef \fwmacroname{Copyright status}{6}\fwbtx[
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwisafile{This macro is attached to an output file.}
\fwendmacronotes
\fwendmacro


I'd rather \fwlit{COPYING} consist of a Creative
Commons CC0 statement, but for a regrettable
dependence of that notice on ``he or she''
phrasing (as of CC0
1.0).{\footnote{$^1$}{http://creativecommons.org/publicdomain/zero/1.0/}}  Alternative standardised
statements that boil down to the above ---
public domain dedication, fallback licence,
warrantilessness --- don't seem to be worth
their disadvantages.  I think I might have
borrowed the ``free for use by anyone and for
any purpose'' phrasing from the SQLite
website.{\footnote{$^2$}{https://www.sqlite.org}}
 While I intend that middle statement as a
fallback licence, I may too be open to issuing
individual licences, for umpteen dollary-doos,
in special cases.

\fwsecb{2.2}{What is turntab?}

\fwbeginmacro
\fwfilename{README}{8}\fwequals \fwodef \fwbtx[turntab is a programme,
which is in these files:

README describes the files.

turntab.sh is the file that computers use to run turntab.

turntab.pdf is a book for people to read turntab.

COPYING says that turntab belongs to everybody.

turntab.tex is for putting turntab into other publications.

turntab.fw is what the files are made out of.
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwisafile{This macro is attached to an output file.}
\fwendmacronotes
\fwendmacro


\fwbeginmacro
\fwmacroname{Introduce self}{9}\fwequals \fwodef \fwbtx[#!/usr/bin/env sh
#      turntab ]fwetx=%
\fwmacroname{Version}{2}\fwbtx[
#         written by Kermie BREYDON
#          on Boon Wurrung country
#                  in 2020
#           for the public domain
#
# ]fwetx=%
\fwmacroname{URL for turntab}{5}\fwbtx[

printf "Hello, turntab speaking. I get the orientations
of tablet input and display to match each other.\n"
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 10.}
\fwendmacronotes
\fwendmacro


If you'll excuse a few paragraphs' jargon,
\fwlit{turntab} is a work of literate programming.
Its executable component --- \fwlit{turntab.sh} ---
is a script designed to be run by {\sc posix}y
shells, either at the command-line or when
triggered by a shortcut.  The documentation
(which you are reading now) and the script are
both derived from the same source file ---
\fwlit{turntab.fw} --- which follows the formatting
conventions of the FunnelWeb macro
preprocessor{\footnote{$^3$}{http://www.ross.net/funnelweb/}
(but eschews FunnelWeb's extremely 1990s {\sc
html} dialect for a slightly heavier investment
in the \TeX~typesetting
system{\footnote{$^4$}{https://tug.org/} than is
quite standard for FunnelWeb).

I wrote \fwlit{turntab} as an accessibility aid to
using the
X~Window~System{\footnote{$^5$}{http://www.x.org/}
on a touchscreen device.  \fwlit{turntab}'s script
probes and very slightly manipulates
\fwlit{xsetwacom} (a utility for the \fwlit{wacom} input
driver for
X){\footnote{$^6$}{http://linuxwacom.sourceforge.net}
and \fwlit{xrandr} (an interface for the RandR
extension to X), to align their respective
rotation settings.  Perhaps most distinctively,
\fwlit{turntab} also co-ordinates the system console
and virtual TTYs with that graphical stuff.
\fwlit{turntab} presumes an interface for this last
part at
\fwlit{/sys/class/graphics/fbcon/rotate\_all}; some
systems might require a different approach, or
lack the capacity.  Note that the method given
here for adjusting frame-buffered consoles
depends on superuser privileges --- so do take
appropriate precaution if you are out to exploit
this particular function.

At version \version, \fwlit{turntab} is likely to
behave over-exuberantly in systems that involve
multiple displays and/or multiple
\fwlit{wacom}-compatible tablet~surfaces.  I expect
it could adjust more of them than necessary, and
in some cases take the wrong readings.  It is
also likely to mess up around some custom RandR
efforts to compensate for projector distortion,
and so on.  But in a standalone unit --- for
communication~boards or basic tablet~computing
--- I find it effective, versatile, and
uncommonly simple to implement.  May you benefit
from this work, in some way, too.

\fwsecb{2.3}{Features}

\fwlit{turntab.sh} can perform the following tasks.
Their definition numbers are indicated in square
brackets, for ease of cross-reference.

\fwbeginmacro
\fwfilename{turntab.sh}{10}\fwequals \fwodef \fwmacroname{Introduce self}{9}\fwbtx[
]fwetx=%
\fwmacroname{Have functions}{11}\fwbtx[
]fwetx=%
\fwmacroname{Follow command line instructions}{12}\fwbtx[
]fwetx=%
\fwmacroname{Finish}{23}\fwbtx[
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwisafile{This macro is attached to an output file.}
\fwendmacronotes
\fwendmacro


``Have functions''?  No, it's not throwing a party;
it is being ready to do a range of things in
various sequences.  These things:

\fwbeginmacro
\fwmacroname{Have functions}{11}\fwequals \fwodef \fwbtx[# Functions!

]fwetx=%
\fwmacroname{Cite origins}{22}\fwbtx[
]fwetx=%
\fwmacroname{Offer help}{21}\fwbtx[
]fwetx=%
\fwmacroname{Translate terminology}{16}\fwbtx[
]fwetx=%
\fwmacroname{Increment rotation goals}{17}\fwbtx[
]fwetx=%
\fwmacroname{Suss out orientation of graphical display}{13}\fwbtx[
]fwetx=%
\fwmacroname{Find all the forms of tablet input}{14}\fwbtx[
]fwetx=%
\fwmacroname{Suss out orientation of tablet input}{15}\fwbtx[
]fwetx=%
\fwmacroname{Orient graphical display}{18}\fwbtx[
]fwetx=%
\fwmacroname{Orient tablet input}{19}\fwbtx[
]fwetx=%
\fwmacroname{Orient frame-buffer consoles}{20}\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 10.}
\fwendmacronotes
\fwendmacro


\fwseca{3}{Follow command line instructions}

\fwlit{turntab} commands aim to suit a few
demographics, with contrasting needs.

People using stenography, text-to-speech or
(some) predictive-text utilities will typically
find it easiest to issue a command in ordinary
words --- like \fwlit{turntab help}.  The word
``turntab'' will of course still need to be
added to lexicon of the appropriate software.
Fuller support of text-to-speech users might
require an interactive mode, something
\fwlit{turntab} {\version} lacks.

Serial typists (entering one letter at a time),
are sometimes better served by a concise command
without punctuation --- like \fwlit{turntab h}.
This group might like copies of \fwlit{turntab.sh}
reassigned to a shorter name; but I'll leave
that step to you.

Sticklers for tradition go in for symbols. One
or two hyphens and a full word --- as in
\fwlit{turntab --help} --- facillitates the writing
of intelligible scripts. One hyphen and
initial(s) offers consistency on a wider range
of operating systems (and for some users is
easier to input) --- as with \fwlit{turntab -h}.

Obviously the approach outlined below is very
English Language, but it's easy to bung in
additional terms.  Certain phrases might clash
with instances of shorthands like \fwlit{*cw},
necessitating replacement with \fwlit{--cw\char`\|cw\char`\|-cw}
patterns (in the macros \fwlit{Following command line
instructions} and \fwlit{Translate terminology}).

\fwbeginmacro
\fwmacroname{Follow command line instructions}{12}\fwequals \fwodef \fwbtx[# Making sense of commands!

case "$1" in
  ""|*help|h|-h)
    printf "\nThings you can write after $0:\n"
    help
    ;;
  *version|v|-v)
    software
    ;;
  *increment|*cycle|c|-c)
    sussxoutputori
    incrementgoals
    orientxoutput
    orientxinput
    orientfbc
    ;;
  *input|i|-i)
    sussxoutputori
    orientxinput
    orientfbc
    ;;
  *output|o|-o)
    sussxinputori
    orientxoutput
    orientfbc
    ;;
  *0|*1|*2|*3|*normal|*right|*inverted|*left|*none|*cw|*half|*ccw)
    goal="$1"
    translate
    orientxoutput
    orientxinput
    orientfbc
    ;;
  *x)
    case "$2" in
      *increment|*cycle|c|-c)
        sussxoutputori
        incrementgoals
        orientxoutput
        orientxinput
        ;;
      ""|*input|i|-i)
        sussxoutputori
        orientxinput
        ;;
      *output|o|-o)
        sussxinputori
        orientxoutput
        ;;
      *0|*1|*2|*3|*normal|*right|*inverted|*left|*none|*cw|*half|*ccw)
        goal="$2"
        translate
        orientxoutput
        orientxinput
        ;;
      *)
        printf "Sorry, do what?"
        ;;
    esac
    ;;
  *)
    printf "
Sorry, I do not know what you mean by $1.
Here are some other things we could try next:\n"
    help
    ;;
esac
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 10.}
\fwendmacronotes
\fwendmacro


There have got to be more efficient ways of
allowing X-only behaviour.  We could check for
an \fwlit{x} on beginning an \fwlit{orientfbc} step ---
skipping the rest of the step should there be an
\fwlit{x}.  Problem is, I don't know how to neatly
ask a shell script to follow the same procedure
regardless of whether a command-line option is
tacked on in the 1st or 2nd position.  Shame.
Maybe one day.

\fwseca{4}{Figure things out}

\fwsecb{4.1}{Suss out orientation of graphical display}

Often, our reference will be the orientation of
the main graphical display.

\fwlit{xrandr} doesn't seem to allow us to ask after
a datum directly. Present orientation is left
out of the default query response, and I haven't
managed to get \fwlit{xrandr} to report in detail on
fewer than ALLLL OF THE SCREENS at once.  With
some regret, let us wade into \fwlit{xrandr
--verbose}.

The resulting output does not appear cleanly
delineated. (Although maybe it uses some kind of
invisible record-separator?) Furthermore,
identifying features are inconsistent; there's
not always a ``\fwlit{primary}'' marker on the entry
we want, for example.

Have a squiz at this first five lines
of a (pretend) \fwlit{xrandr --verbose} result:

\fwlit{Screen 0: minimum 8 x 8, current 600 x 400, maximum 12345 x 12345}
\leftline{\fwlit{LVDS1 connected primary 600x400+0+0 (0x2c) normal (normal left inverted right x axis y axis) 120mm x 800mm}}
\leftline{{\hskip 4em} \fwlit{Identifier: } \fwlit{0x57}}
\leftline{{\hskip 4em} \fwlit{Timestamp: }\fwlit{ 54321543}}
\leftline{{\hskip 4em} \fwlit{Subpixel: }{ }\fwlit{ horizontal rgb}}

We could take a stab that the first
non-``\fwlit{Screen}'' line is practically always
the one for us.

We could try something like \fwlit{\char`\| grep
\char`\"Screen\char`\"}~\fwlit{-v -m 1}, saying invert match
(thereby {\it skip} lines announcing ``\fwlit{Screen
0}'' etc) and return only the first result.
Left clutching just the first line of the first
monitor's data and the vain hope that a whole
bunch of things {\it do} stay consistent, we
might go to something like \fwlit{\char`\| awk -F
\char`\"}~\fwlit{\char`\"}~\fwlit{\char`\"\char`\{ print \$6 \char`\}\char`\"} or ``show us the
6th word of the remaining line''.

But if we're gonna be so sketchy anyway, we
might as well straight-up lie to \fwlit{awk}, for
improved accuracy and less piping.

In any case, we should see if we got a
plausible-sounding result, and if not, bow out.

\fwbeginmacro
\fwmacroname{Suss out orientation of graphical display}{13}\fwequals \fwodef \fwbtx[sussxoutputori () {
  printf "\nSussing out display (via xrandr)...\n"
  xoutputori="$(xrandr --verbose | awk -e 'BEGIN {RS ="\\(normal left inverted"} $0 ~ "Screen" {print $NF}')"
  if test "$xoutputori" = "normal" -o "$xoutputori" = "left" -o "$xoutputori" = "inverted" -o "$xoutputori" = "right"; then
    goal="$xoutputori"
    translate
    printf "OK. I reckon the display is $orientation.\n"
  else
    printf "
Sorry, but this time I could not tell which way
the graphical display has been turned.
(Assuming that there even is one?)

Please note that I depend on the X Window System
for graphical matters and am not very clever.\n"
    exit
  fi
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


\fwsecb{4.2}{Find all the forms of tablet input}

In practice, \fwlit{xsetwacom} treats each type of
tablet input, or ``device'', separately ---
despite the driver's manual claiming that
changing one input device's orientation will
change them all.  One implication of this is
that we must identify every form of contact that
we wish to reorient.  Another implication is
that reading the orientation of one device at
random does not guarantee the orientation of
whatever device(s) the user has observed.  For
instance, they might be exclusively using the
eraser end of a stylus, whereas we might happen
to base our assumptions on the ``device'' for
generic touches.

We should be able to automate the referencing of
a complete set of Wacom devices, in a single
line, surely?  \fwlit{xsetwacom list \char`\| sed -E
's/.*id: //; s/\char`\\t.*//'} returns ID numbers that
\fwlit{xsetwacom} will be happy with.

\fwbeginmacro
\fwmacroname{Find all the forms of tablet input}{14}\fwequals \fwodef \fwbtx[findtab () {
printf "\nIdentifying forms of tablet input (via xsetwacom)...\n"
devices="$( xsetwacom list | sed -E 's/.*id: //; s/\t.*//')"
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


\fwsecb{4.3}{Suss out orientation of tablet input}

\fwbeginmacro
\fwmacroname{Suss out orientation of tablet input}{15}\fwequals \fwodef \fwbtx[sussxinputori () {
findtab
printf "\nSussing out tablet orientation (via xsetwacom)...\n"
for device in $devices; do
  xinputori="$(xsetwacom get $device rotate)"
  break
done
if test "$xinputori" = "none" -o "$xinputori" = "ccw" -o "$xinputori" = "half" -o "$xinputori" = "cw"; then
  goal="$xinputori"
  translate
  printf "OK. I reckon the tablet input is $orientation.\n"
else
  printf "
Sorry, but this time I could not tell which way
any tablet input is oriented.

Please note that the only tablets I handle are
Wacom hardware in use by the X Window System.\n"
  exit
fi
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


Evidently, we are risking the surprise reading
outcome (by only examining one \fwlit{\$device}'s
orientation).

\fwseca{5}{Change things}

\fwsecb{5.1}{Translate terminology}

In order to match orientations, we connect a
piece of \fwlit{xrandr}, \fwlit{xsetwacom} or \fwlit{fbcon}
terminology with its equivalents.  While we are
at it, let's express the terms' shared meaning
more clearly.

\fwbeginmacro
\fwmacroname{Translate terminology}{16}\fwequals \fwodef \fwbtx[translate () {
case "$goal" in
  *normal|*none|*0)
    xoutputori="normal";
    xinputori="none";
    fbcori="0";
    orientation="upright (not rotated)";;
  *left|*ccw|*3)
    xoutputori="left";
    xinputori="ccw";
    fbcori="3";
    orientation="turned on its left";;
  *inverted|*half|*2)
    xoutputori="inverted";
    xinputori="half";
    fbcori="2";
    orientation="upside-down to usual";;
  *right|*cw|*1)
    xoutputori="right";
    xinputori="cw";
    fbcori="1";
    orientation="turned on its right";;
esac
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


\fwsecb{5.2}{Increment rotation goals}

For cycling through orientations, we reassign
those meanings.

\fwbeginmacro
\fwmacroname{Increment rotation goals}{17}\fwequals \fwodef \fwbtx[incrementgoals () {
case "$goal" in
  normal|none|0)
    xoutputori="right";
    xinputori="cw";
    fbcori="1";
    orientation="turned on its right";;
  right|cw|1)
    xoutputori="inverted";
    xinputori="half";
    fbcori="2";
    orientation="upside-down to usual";;
  inverted|half|2)
    xoutputori="left";
    xinputori="ccw";
    fbcori="3";
    orientation="turned on its left";;
  left|ccw|3)
    xoutputori="normal";
    xinputori="none";
    fbcori="0";
    orientation="upright (not rotated)";;
esac
printf "\nLet's make it $orientation.\n"
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


\fwsecb{5.3}{Orient graphical display}

\fwbeginmacro
\fwmacroname{Orient graphical display}{18}\fwequals \fwodef \fwbtx[orientxoutput () {
printf "
Trying to orient graphical display (via xrandr)...\n"
xrandr -o $xoutputori
if test "$(xrandr --verbose | awk -e 'BEGIN {RS ="\\(normal left inverted"} $0 ~ "Screen" {print $NF}')" = "$xoutputori"; then
  printf "Seems OK, from my perspective.\n"
else
  printf "Sorry, I could not correct the graphical display.\n"
fi
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


This manner of testing does not strike me as terribly efficient.

\fwsecb{5.4}{Orient tablet input}

Of course, \fwlit{xsetwacom set \$device rotate
\$xinputori} is a task that need only be done
once per \fwlit{\$device}.  So, at a glance,
enclosing it in a \fwlit{for device in \$devices;}
loop which is itself inside another \fwlit{for device
in \$devices} loop might appear redundant.

The outer loop we don't actually care to repeat.
The main point is to see if we seem to be
handing \fwlit{xsetwacom} back the right sort of
datum: a likely-sounding id number.  As a
programme inclined to loose assumption,
\fwlit{turntab} figures that this'll do, this vague
spot check.

However, with the knowledge that we cannot
necessarily rely on \fwlit{xsetwacom} to sort the
rest out for us, we do need to be prepared to
repeat the inner loop should there be more than
one id-number in \fwlit{\$devices}.

\fwbeginmacro
\fwmacroname{Orient tablet input}{19}\fwequals \fwodef \fwbtx[orientxinput () {
findtab
if test "$devices" = ""; then
  printf "Sorry, I can't find any.

Please note that I can only do so within the
X Window System and for certain Wacom devices.\n"
else
  for device in $devices; do
    if test "$device" -gt 0 -a "$device" -lt 100; then
      printf "Trying to correct tablet orientation (via xsetwacom)...\n"
      for device in $devices; do
        xsetwacom set $device rotate $xinputori
      done
      printf "Done. Hopefully.\n"
    else
      printf "Sorry, this time, I cannot make sense of
the system's response.\n"
    fi
    break
  done
fi
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


\fwsecb{5.5}{Orient frame-buffer consoles}

When successful, the command \fwlit{echo \$fbcori \char`\|
sudo tee /sys/class/graphics/fbcon/rotate\_all}
spits out the value of \fwlit{\$fbcori}.  By catching
that output in \fwlit{\$fbcresult}, we stop a
decontextualised number from popping out onto
the user interface.  If we don't catch a number,
we can be confident of failure.  Nice.

\fwbeginmacro
\fwmacroname{Orient frame-buffer consoles}{20}\fwequals \fwodef \fwbtx[orientfbc () {
printf "
About to orient the text consoles that use a
frame-buffer. This requires special permission,
so you might be asked for a password...\n"
fbcresult="$(echo $fbcori | sudo tee /sys/class/graphics/fbcon/rotate_all)"
if test "$fbcresult" = "$fbcori"; then
  printf "OK. I think that worked.\n"
else
  printf "\nSorry, I could not correct them.\n"
fi
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


\fwseca{6}{Supply information without accompanying action}

\fwsecb{6.1}{Offer help}

\fwbeginmacro
\fwmacroname{Offer help}{21}\fwequals \fwodef \fwbtx[help () {
  printf "
  help       Shows this usage list.
  version    Shows the current software version.

  input      Makes the tablet input and the
             teletype-style consoles that use a
             frame-buffer (FBTTYs) match the
             graphical display's orientation.

  output     Orients the graphical display and
             FBTTYs to match the tablet input.

  increment  Corrects tablet input and FBTTYs to
             match the graphical display, then
             turns them all 90 degrees clockwise.

  [o]        Sets all frame-buffer consoles,
             graphical display and tablet input
             to the [o] orientation.

  x          Affects only the graphical display
             and tablet input.

  Options for [o] include 0, 1, 2, or 3
  but also terms such as left or ccw.
  For instance:  turntab x right\n"
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


I am yet to encounter unambiguous language
around the subject of text interfaces for
operating systems that holds up after, say,
1960-something.  Even ``graphical display'' is
horribly imprecise.  I'm sorry for any
confusion.

\fwsecb{6.2}{Cite origins}

\fwbeginmacro
\fwmacroname{Cite origins}{22}\fwequals \fwodef \fwbtx[software () {
  printf '
This is turntab ]fwetx=%
\fwmacroname{Version}{2}\fwbtx[.
<]fwetx=%
\fwmacroname{URL for turntab}{5}\fwbtx[>
]fwetx=%
\fwmacroname{Dates}{3}\fwmacroname{Credits}{4}\fwbtx[
]fwetx=%
\fwmacroname{Copyright status}{6}\fwbtx[
]fwetx=%
\fwmacroname{Acknowledgement of Country}{1}\fwbtx['
}
]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 11.}
\fwendmacronotes
\fwendmacro


\fwseca{7}{Finish}

\fwbeginmacro
\fwmacroname{Finish}{23}\fwequals \fwodef \fwbtx[# Humphrey, we're leaving!

exit $?]fwetx=%
\fwcdef 
\fwbeginmacronotes
\fwusedin{This macro is invoked in definition 10.}
\fwendmacronotes
\fwendmacro


Tada, the end... Actually, there is endless room for improvement.  Thanks for reading!
\vskip 7.5 mm
\leftline{\hskip 8cm Catch you round like}
\leftline{\hskip 8cm all the way you've come}
\leftline{\hskip 8cm after four \fwlit{turntab increment}s,}
\vskip 5 mm \leftline{\hskip 8cm Kermie~F.~B{\sc
reydon}} \leftline{\hskip 8cm
Boon~Wurrung~Country, 7 October~2020}
\bye


%*******************************************************************************
%*                    END OF AUTOMATICALLY GENERATED TEX FILE                  *
%*******************************************************************************

