X11CommanderOpsImpl.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Christian Jacobi, October 9, 1992 0:04 am PDT
Willie-s, September 30, 1991 2:04 pm PDT
Allows access to X window connection from command procedures. Selects X server according to environment parameters. (The X11 command)
ALSO: hack which fills in the connection into shell widgets by reading commander options
It is a separate module to not introduce dependencies of higher level Cedar modules into XTkShellWidgets. The trick to make it mutually independent is to use global notifications and a convention in XTkShellWidgetsImpl.
September 25, 1992: I don't remember why this shouldn't import XTkShellWidgets and made an import.
DIRECTORY
Atom, Commander, CommanderOps, ProcessProps, Rope, X11CommanderOps, Xl, XTk, XTkDB, XTkShellWidgets, XTkNotification;
X11CommanderOpsImpl: CEDAR PROGRAM
IMPORTS Atom, Commander, CommanderOps, ProcessProps, Rope, Xl, XTkDB, XTkNotification, XTkShellWidgets
EXPORTS X11CommanderOps ~
BEGIN
CreateOrFail: PROC [serverName: Rope.ROPE, synch: BOOL] RETURNS [connection: Xl.Connection ¬ NIL] = {
And raise CommanderOps.Failed on troubles
reason: Rope.ROPE;
connection ¬ Xl.CreateConnection[server: serverName, synchronized: synch ! Xl.connectionNotCreated => {reason ¬ why.reason; CONTINUE}];
IF ~Xl.Alive[connection] THEN
ERROR CommanderOps.Failed[Rope.Concat["** ", reason]];
};
SetConnection: PROC [widget: XTk.Widget, connection: Xl.Connection] = {
IF Xl.Alive[connection] THEN {
widget.connection ¬ connection;
Xl.IncRefCount[connection, widget];
Xl.DecRefCount[connection];
};
};
FillInConnection: XTk.WidgetNotifyProc = {
--This procedure is called when a connection is needed.
--It hopes to find arguments from properties.
IF Xl.Alive[widget.connection] THEN RETURN;
WITH ProcessProps.GetProp[$CommanderHandle] SELECT FROM
cmd: Commander.Handle => {--we won't need cmd; finding cmd guarantees that we are called from a commander and are allowed to raise CommanderOps.Failed
server: REF ¬ ProcessProps.GetProp[$X11server];
geometry: REF ¬ ProcessProps.GetProp[$X11geometry];
synch: BOOL ¬ ProcessProps.GetProp[$X11synch]=$TRUE;
IF geometry#NIL THEN {
hints: REF XTkShellWidgets.ICCCMHints ¬ NIL;
s: Xl.Size; p: Xl.Point; xneg, yneg: BOOL;
[s, p, xneg, yneg] ¬ XTkDB.ScanGeometry[geometry];
IF XTkShellWidgets.IsShell[widget] THEN {
hints ¬ XTkShellWidgets.GetHints[widget];
};
IF s.width>0 AND s.height>0 THEN {
widget.s.geometry.size ¬ s;
IF hints#NIL THEN {
hints.wmNormalHints.obsoleteSz ¬ hints.wmNormalHints.baseSz ¬ s;
hints.wmNormalHints.userSize ¬ hints.wmNormalHints.clientSize ¬ TRUE;
hints.wmNormalHintsChanged ¬ TRUE;
};
};
IF p.x>=0 AND p.y>=0 AND ~xneg AND ~yneg THEN {
widget.s.geometry.pos ¬ p;
IF hints#NIL THEN {
hints.wmNormalHints.obsoletePos ¬ p;
hints.wmNormalHints.userPos ¬ hints.wmNormalHints.clientPos ¬ TRUE;
hints.wmNormalHintsChanged ¬ TRUE;
};
};
};
WITH server SELECT FROM
r: Rope.ROPE => {
connection: Xl.Connection ¬ CreateOrFail[r, synch];
SetConnection[widget, connection];
};
connection: Xl.Connection => {
IF ~Xl.Alive[connection] THEN
CommanderOps.Failed["** Dead default connection"];
widget.connection ¬ connection;
Xl.IncRefCount[connection, widget];
--The DecRefCount is done by the X11 command...
};
ENDCASE => {
connection: Xl.Connection;
IF server#NIL THEN
CommanderOps.Failed["** Default for connection not recognized"];
connection ¬ CreateOrFail[NIL, synch];
SetConnection[widget, connection];
};
};
ENDCASE => {}
};
DoWithConnection: PUBLIC PROC [proc: X11CommanderOps.ConnectionProc, catchXErrors: BOOLTRUE, application: ATOM ¬ NIL] = {
mustDec: BOOLFALSE;
connection: Xl.Connection;
server: REF ¬ ProcessProps.GetProp[$X11server];
synch: BOOL ¬ ProcessProps.GetProp[$X11synch]=$TRUE;
Cleanup: PROC [] = {
IF mustDec THEN Xl.DecRefCount[connection];
};
WITH server SELECT FROM
r: Rope.ROPE => {
connection ¬ CreateOrFail[r, synch];
mustDec ¬ TRUE;
};
c: Xl.Connection => {connection ¬ c};
ENDCASE => {
IF server#NIL THEN
CommanderOps.Failed["** Default for connection not recognized"];
connection ¬ CreateOrFail[NIL, synch];
mustDec ¬ TRUE;
};
IF ~Xl.Alive[connection] THEN CommanderOps.Failed["** Dead connection"];
proc[connection !
Xl.XError => {IF catchXErrors THEN CommanderOps.Failed[err.explanation]};
UNWIND => Cleanup[];
];
Cleanup[];
};
X11Command: Commander.CommandProc = {
This X11 command reads in default values and puts them onto properties, ready for eventual connection creators and then executes the rest of the command line.
decRefCountOnThis: Xl.Connection ¬ NIL;
server: Rope.ROPE ¬ NIL;
check, synch: BOOL ¬ FALSE;
appIdx: NAT ¬ 0;
i: NAT ¬ 1;
propList: Atom.PropList ¬ NIL;
argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd];
pos: INT ¬ Rope.Find[cmd.commandLine, " -- "];
IF pos<0 THEN CommanderOps.Failed[" ** must specify -- and a command"];
DO
IF i>=argv.argc THEN CommanderOps.Failed[" ** missed --"]
ELSE {
this: Rope.ROPE ~ argv[i];
i ¬ i+1;
SELECT TRUE FROM
(Rope.Equal["-display", this, FALSE] OR Rope.Equal["-server", this, FALSE]) AND i<argv.argc => {
server ¬ argv[i]; i ¬ i+1;
propList ¬ Atom.PutPropOnList[propList, $X11server, server];
};
Rope.Equal["-synch", this, FALSE] OR Rope.Equal["-sync", this, FALSE] => {
synch ¬ TRUE;
propList ¬ Atom.PutPropOnList[propList, $X11synch, $TRUE];
};
Rope.Equal["-check", this, FALSE] => {
check ¬ TRUE;
};
Rope.Equal["-geometry", this, FALSE] AND i<argv.argc => {
propList ¬ Atom.PutPropOnList[propList, $X11geometry, argv[i]];
i ¬ i+1;
};
Rope.Equal["--", this] => {
appIdx ¬ i;
EXIT
};
ENDCASE => CommanderOps.Failed[Rope.Cat[" ** unrecognized argument: ", this, "\n"]];
};
ENDLOOP;
IF appIdx=0 THEN ERROR CommanderOps.Failed[" ** missed --"];
IF check THEN {
c: Xl.Connection ¬ decRefCountOnThis ¬ CreateOrFail[server, synch];
propList ¬ Atom.PutPropOnList[propList, $X11server, c];
};
BEGIN
ExecuteRealCommand: PROC ~ {
commandLine: Rope.ROPE ¬ Rope.Substr[cmd.commandLine, pos+4];
result ¬ CommanderOps.DoCommand[commandLine, cmd];
};
ProcessProps.AddPropList[propList: propList, inner: ExecuteRealCommand];
END;
IF decRefCountOnThis#NIL THEN Xl.DecRefCount[decRefCountOnThis];
};
XTkNotification.RegisterGlobal[$GetShellConnection, FillInConnection, NIL, TRUE];
Commander.Register["X11", X11Command, "Executes command following -- with default server.\n Format: X11 [-display ServerName] [-sync] [-check] [-geometry wXh[+x+y]] -- Real Command\n"];
END.