<> <> <> <> <<>> <> <<>> <> <<>> <> <<>> <> <<>> 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] = { <> 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: BOOL _ TRUE, application: ATOM ¬ NIL] = { mustDec: BOOL _ FALSE; 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 = { <> 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 { 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 { 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.