////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001-2024 DaqGroup daqgroup@mail.ru under MIT license        //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// This file is part of the CRW-DAQ project by DaqGroup - addon user program. //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Purpose:                                                                   //
// Window Manager query utility.                                              //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// History:                                                                   //
// 20241022 - Sample created by A.K.                                          //
// 20241116 - wmquery created                                                 //
////////////////////////////////////////////////////////////////////////////////

program wmquery; // Window Manager Query

{$I _crw_sysdef.inc}

{$I _crw_sysmode.inc}

{$R *.res}

uses
 //////////////////////////////////////////////////////
 {$I _crw_uses_first.inc} // NB: MUST BE FIRST USES !!!
 //////////////////////////////////////////////////////
 sysutils, classes, math, graphics, interfaces, forms,
 _crw_alloc, _crw_cmdargs, _crw_environ, _crw_proc, _crw_rtc, _crw_ef,
 _crw_str, _crw_utf8, _crw_fio, _crw_fifo, _crw_hl, _crw_ee, _crw_colors,
 _crw_wmctrl;

function GetVersionInfo(const Name:LongString):LongString;
begin
 Result:=CookieScan(GetFileVersionInfoAsText(ProgName),Name);
end;
function DotEnding(const S:LongString):LongString;
const dot='.';
begin
 Result:=S;
 if (Result<>'') then if (StrFetch(Result,Length(Result))<>dot) then Result:=Result+dot;
end;
procedure PrintVersionInfo(const Fallback:LongString);
begin
 if not IsEmptyStr(GetVersionInfo('ProductName')) then begin
  writeln(DotEnding(GetVersionInfo('ProductName')+' version '+GetVersionInfo('ProductVersion')));
  writeln(DotEnding(GetVersionInfo('LegalCopyright')));
  writeln(DotEnding(GetVersionInfo('FileDescription')));
 end else begin
  writeln(Fallback);
 end;
end;
procedure PrintVersion;
begin
 PrintVersionInfo(ProgBaseName+' - Window Manager Query utility to control desktop windows.');
end;

procedure PrintHelp;
var exe,msg:LongString;
begin
 PrintVersion;
 exe:=ProgBaseName;
 msg:='Syntax:'+EOL
     +' '+exe+' DisplayInfo -mode m'+EOL
     +' '+exe+' XlibInfo -mode m'+EOL
     +' '+exe+' ListModes'+EOL
     +' '+exe+' ListWindows -pid p -class "c" -title "t" -mode m'+EOL
     +' '+exe+' FindWindow -pid p -class "c" -title "t" -index i'+EOL
     +' '+exe+' WindowManagerName'+EOL
     +' '+exe+' DesktopCount'+EOL
     +' '+exe+' ActiveDesktop'+EOL
     +' '+exe+' SwitchToDesktop -desktop d'+EOL
     +' '+exe+' ActiveWindow'+EOL
     +' '+exe+' ActivateWindow -wnd w -switch-desktop s'+EOL
     +' '+exe+' ShowWindow -wnd w -sw n'+EOL
     +' '+exe+' ShowWindow -wnd w'+EOL
     +' '+exe+' HideWindow -wnd w'+EOL
     +' '+exe+' MinimizeWindow -wnd w'+EOL
     +' '+exe+' MaximizeWindow -wnd w'+EOL
     +' '+exe+' RestoreWindow -wnd w'+EOL
     +' '+exe+' WindowPid -wnd w'+EOL
     +' '+exe+' WindowDesktop -wnd w'+EOL
     +' '+exe+' WindowHost -wnd w'+EOL
     +' '+exe+' WindowTitle -wnd w'+EOL
     +' '+exe+' WindowClass -wnd w'+EOL
     +' '+exe+' WindowBounds -wnd w'+EOL
     +' '+exe+' WindowStateList -wnd w'+EOL
     +' '+exe+' WindowTypeList -wnd w'+EOL
     +' '+exe+' WindowStateFlags -wnd w'+EOL
     +' '+exe+' WindowTypeFlags -wnd w'+EOL
     +' '+exe+' SetWindowStateList -wnd w -wsc c -state-list l'+EOL
     +' '+exe+' SetWindowStateFlags -wnd w -wsc c -state-flags f'+EOL
     +' '+exe+' SetWindowDesktop -wnd w -desktop d'+EOL
     +' '+exe+' SetWindowTitle -wnd w -title "t"'+EOL
     +' '+exe+' SupportedList'+EOL
     +' '+exe+' MoveResizeWindow -wnd w -geom g'+EOL
     +' '+exe+' CloseWindow -wnd w -timeout t'+EOL
     +' '+exe+' KillWindow -wnd w -sig s -timeout t'+EOL
     +' '+exe+' IcccmClass -inst i -class c'+EOL
     +' '+exe+' ListDesktopManagers'+EOL
     +' '+exe+' DesktopManager -index i'+EOL
     +' '+exe+' ListTerminals'+EOL
     +' '+exe+' Terminal -index i'+EOL
     +'Notes:'+EOL
     +' 1) Option -wnd w mostly can be replaced to combination of'+EOL
     +'    other options: -pid p -class "c" -title "t" to find window.'+EOL
     +'    This feature uses to work with pid/class/title instead of wnd.'+EOL
     +' 2) Short option parameters explanation:'+EOL
     +'    -mode m           - operation mode, depends on command'+EOL
     +'    -index i          - index of window to find, 0-based'+EOL
     +'    -desktop d        - desktop number to switch'+EOL
     +'    -switch-desktop s - flag (0/1) to switch desktop on activate window'+EOL
     +'    -wnd w            - target window handle'+EOL
     +'    -win w            - target window handle'+EOL
     +'    -pid p            - target window process ID to find'+EOL
     +'    -class "c"        - target window class name to find'+EOL
     +'    -title "t"        - target window title text to find'+EOL
     +'    -sw n             - show window command n where n is 0..10 const:'+EOL
     +'                        HIDE,SHOWNORMAL,SHOWMINIMIZED,SHOWMAXIMIZED,'+EOL
     +'                        SHOWNOACTIVATE,SHOW,MINIMIZE,SHOWMINNOACTIVE,'+EOL
     +'                        SHOWNA,RESTORE,SHOWDEFAULT'+EOL
     +'    -state-list l     - window state list, subset of items:'+EOL
     +'                        MODAL,STICKY,MAXIMIZED_VERT,MAXIMIZED_HORZ,'+EOL
     +'                        SHADED,SKIP_TASKBAR,SKIP_PAGER,HIDDEN,FULLSCREEN,'+EOL
     +'                        ABOVE,BELOW,DEMANDS_ATTENTION,FOCUSED'+EOL
     +'    -state-flags f    - bit flags corresponded to state-list'+EOL
     +'    -wsc c            - window state command 0/1/2=remove/add/toggle'+EOL
     +'    -geom g           - geometry for MoveResize: g,x,y,w,h'+EOL
     +'                        g:gravity=0, x,y=left,top, w,h=width,height'+EOL
     +'    -timeout t        - timeout for close/kill window, ms'+EOL
     +'    -sig s            - signal number or name to kill window'+EOL
     +'                        by default uses -sig TERM'+EOL
     +'    -wndfmt f         - format of wnd to print: f=(0/1/2/3)=(d/u/x/$)'+EOL
     +'                        0:"%d",  1:"%u",  2:"0x%.8x", 3:"$%.8x"'+EOL
     +'    -inst i           - instance name for IcccmClass'+EOL
     +'Example:'+EOL
     +' '+exe+' ListWindows -mode 1'+EOL
     +' '+exe+' ActivateWindow -title "KCalc"'+EOL
     +' '+exe+' ShowWindow -title "KCalc"'+EOL
     +' '+exe+' HideWindow -title "KCalc"'+EOL
     +' '+exe+' FindWindow -title "KCalc"'+EOL
     +' '+exe+' FindWindow -title "KCalc" -wndfmt x'+EOL
     +' '+exe+' KillWindow -title "KCalc" -sig TERM'+EOL
     +' '+exe+' KillWindow -wnd 0x04c035b2 -sig TERM'+EOL
     +' '+exe+' MoveResizeWindow -title "KCalc" -geom 0,100,200'+EOL
     +' '+exe+' SetWindowStateList -title "KCalc" -wsc add -state-list HIDDEN'+EOL;
 write(msg);
end;

procedure RunWmquery;
var ans,cmd,arg:LongString;
begin
 with CmdArgs do
 if (Count<=1)
 or HasOption('-h')
 or HasOption('-help')
 or HasOption('--help') then begin
  PrintHelp;
  Exit;
 end else
 if HasOption('--version') then begin
  PrintVersion;
  Exit;
 end;
 wmctrl.DefWndFmt:=2;
 wmctrl.DefListMode:=5;
 cmd:=GetCommandLine;
 arg:=Trim(SkipPhrases(1,cmd,JustSpaces));
 ans:=wmctrl_query(arg);
 if (ans='')
 then ExitCode:=1
 else writeln(ans);
end;

begin
 try
  RunWmquery;
 except
  on E:Exception do begin
   BugReport(E,nil,'RunWmquery');
   ExitCode:=1;
  end;
 end;
end.

//////////////
// END OF FILE
//////////////
