#include "file.bi"

Function String_Split(s_in As String,chars As String,result() As String) As Long
    Dim As Long ctr,ctr2,k,n,LC=Len(chars)
    Dim As boolean tally(Len(s_in))
    #macro check_instring()
    n=0
    While n<Lc
        If chars[n]=s_in[k] Then
            tally(k)=true
            If (ctr2-1) Then ctr+=1
            ctr2=0
            Exit While
        End If
        n+=1
    Wend
    #endmacro

    #macro split()
    If tally(k) Then
        If (ctr2-1) Then ctr+=1:result(ctr)=Mid(s_in,k+2-ctr2,ctr2-1)
        ctr2=0
    End If
    #endmacro
    '==================  LOOP TWICE =======================
    For k  =0 To Len(s_in)-1
        ctr2+=1:check_instring()
    Next k
     if ctr=0 then
         if len(s_in) andalso instr(chars,chr(s_in[0])) then ctr=1':beep
         end if
    If ctr Then Redim result(1 To ctr): ctr=0:ctr2=0 Else  Return 0
    For k  =0 To Len(s_in)-1
        ctr2+=1:split()
    Next k
    '===================== Last one ========================
    If ctr2>0 Then
        Redim Preserve result(1 To ctr+1)
        result(ctr+1)=Mid(s_in,k+1-ctr2,ctr2)
    End If

    Return Ubound(result)
End Function

Function loadfile(file As String) As String
	If Fileexists(file)=0 Then Print file;" not found":Sleep:End
    Dim As Long  f=Freefile
    Open file For Binary Access Read As #f
    Dim As String text
    If Lof(f) > 0 Then
        text = String(Lof(f), 0)
        Get #f, , text
    End If
    Close #f
    Return text
End Function

Function tally(SomeString As String,PartString As String) As Long
    Dim As Long LenP=Len(PartString),count
    Dim As Long position=Instr(SomeString,PartString)
    If position=0 Then Return 0
    While position>0
        count+=1
        position=Instr(position+LenP,SomeString,PartString)
    Wend
    Return count
End Function

Sub show(g As String,file As String,byref matches as long,minsize as long,mustdo as string)
    Redim As String s()
    Var L=lcase(loadfile(file))
    g=lcase(g)
    string_split(L,Chr(10),s())
    For m As Long=minsize To len(g)
        For n As Long=Lbound(s) To Ubound(s)
            If Len(s(n))=m Then
                For k As Long=0 To m-1
                    If Instr(g,Chr(s(n)[k]))=0 Then Goto lbl
                Next k
                If Instr(s(n),mustdo) Then
                    For j As Long=0 To Len(s(n))-1
                        If tally(s(n),Chr(s(n)[j]))>tally(g,Chr(s(n)[j])) Then Goto lbl
                    Next j
                    Print s(n)
                    matches+=1
                End If
            End If
            lbl:
        Next n
    Next m
End Sub

dim as long matches
dim as double t=timer
show("ndeokgelw","unixdict.txt",matches,3,"k")
print
print "Overall time taken ";timer-t;" seconds"
print matches;" matches"
Sleep


package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "log"
    "sort"
    "strings"
)

func main() {
    b, err := ioutil.ReadFile("unixdict.txt")
    if err != nil {
        log.Fatal("Error reading file")
    }
    letters := "deegklnow"
    wordsAll := bytes.Split(b, []byte{'\n'})
    // get rid of words under 3 letters or over 9 letters
    var words [][]byte
    for _, word := range wordsAll {
        word = bytes.TrimSpace(word)
        le := len(word)
        if le > 2 && le < 10 {
            words = append(words, word)
        }
    }
    var found []string
    for _, word := range words {
        le := len(word)
        if bytes.IndexByte(word, 'k') >= 0 {
            lets := letters
            ok := true
            for i := 0; i < le; i++ {
                c := word[i]
                ix := sort.Search(len(lets), func(i int) bool { return lets[i] >= c })
                if ix < len(lets) && lets[ix] == c {
                    lets = lets[0:ix] + lets[ix+1:]
                } else {
                    ok = false
                    break
                }
            }
            if ok {
                found = append(found, string(word))
            }
        }
    }
    fmt.Println("The following", len(found), "words are the solutions to the puzzle:")
    fmt.Println(strings.Join(found, "\n"))

    // optional extra
    mostFound := 0
    var mostWords9 []string
    var mostLetters []byte
    // extract 9 letter words
    var words9 [][]byte
    for _, word := range words {
        if len(word) == 9 {
            words9 = append(words9, word)
        }
    }
    // iterate through them
    for _, word9 := range words9 {
        letterBytes := make([]byte, len(word9))
        copy(letterBytes, word9)
        sort.Slice(letterBytes, func(i, j int) bool { return letterBytes[i] < letterBytes[j] })
        // get distinct bytes
        distinctBytes := []byte{letterBytes[0]}
        for _, b := range letterBytes[1:] {
            if b != distinctBytes[len(distinctBytes)-1] {
                distinctBytes = append(distinctBytes, b)
            }
        }
        distinctLetters := string(distinctBytes)
        for _, letter := range distinctLetters {
            found := 0
            letterByte := byte(letter)
            for _, word := range words {
                le := len(word)
                if bytes.IndexByte(word, letterByte) >= 0 {
                    lets := string(letterBytes)
                    ok := true
                    for i := 0; i < le; i++ {
                        c := word[i]
                        ix := sort.Search(len(lets), func(i int) bool { return lets[i] >= c })
                        if ix < len(lets) && lets[ix] == c {
                            lets = lets[0:ix] + lets[ix+1:]
                        } else {
                            ok = false
                            break
                        }
                    }
                    if ok {
                        found = found + 1
                    }
                }
            }
            if found > mostFound {
                mostFound = found
                mostWords9 = []string{string(word9)}
                mostLetters = []byte{letterByte}
            } else if found == mostFound {
                mostWords9 = append(mostWords9, string(word9))
                mostLetters = append(mostLetters, letterByte)
            }
        }
    }
    fmt.Println("\nMost words found =", mostFound)
    fmt.Println("Nine letter words producing this total:")
    for i := 0; i < len(mostWords9); i++ {
        fmt.Println(mostWords9[i], "with central letter", string(mostLetters[i]))
    }
}


import Data.Char (toLower)
import Data.List (sort)
import System.IO (readFile)

------------------------ WORD WHEEL ----------------------

gridWords :: [String] -> [String] -> [String]
gridWords grid =
  filter
    ( ((&&) . (2 <) . length)
        <*> (((&&) . elem mid) <*> wheelFit wheel)
    )
  where
    cs = toLower <$> concat grid
    wheel = sort cs
    mid = cs !! 4

wheelFit :: String -> String -> Bool
wheelFit wheel = go wheel . sort
  where
    go _ [] = True
    go [] _ = False
    go (w : ws) ccs@(c : cs)
      | w == c = go ws cs
      | otherwise = go ws ccs

--------------------------- TEST -------------------------
main :: IO ()
main =
  readFile "unixdict.txt"
    >>= ( mapM_ putStrLn
            . gridWords ["NDE", "OKG", "ELW"]
            . lines
        )


(() => {
    "use strict";

    // ------------------- WORD WHEEL --------------------

    // gridWords :: [String] -> [String] -> [String]
    const gridWords = grid =>
        lexemes => {
            const
                wheel = sort(toLower(grid.join(""))),
                wSet = new Set(wheel),
                mid = wheel[4];

            return lexemes.filter(w => {
                const cs = [...w];

                return 2 < cs.length && cs.every(
                    c => wSet.has(c)
                ) && cs.some(x => mid === x) && (
                    wheelFit(wheel, cs)
                );
            });
        };

    // wheelFit :: [Char] -> [Char] -> Bool
    const wheelFit = (wheel, word) => {
        const go = (ws, cs) =>
            0 === cs.length ? (
                true
            ) : 0 === ws.length ? (
                false
            ) : ws[0] === cs[0] ? (
                go(ws.slice(1), cs.slice(1))
            ) : go(ws.slice(1), cs);

        return go(wheel, sort(word));
    };

    // ---------------------- TEST -----------------------
    // main :: IO ()
    const main = () =>
        gridWords(["NDE", "OKG", "ELW"])(
            lines(readFile("unixdict.txt"))
        )
        .join("\n");

    // ---------------- GENERIC FUNCTIONS ----------------

    // lines :: String -> [String]
    const lines = s =>
        // A list of strings derived from a single string
        // which is delimited by \n or by \r\n or \r.
        Boolean(s.length) ? (
            s.split(/\r\n|\n|\r/u)
        ) : [];

    // readFile :: FilePath -> IO String
    const readFile = fp => {
        // The contents of a text file at the
        // given file path.
        const
            e = $(),
            ns = $.NSString
            .stringWithContentsOfFileEncodingError(
                $(fp).stringByStandardizingPath,
                $.NSUTF8StringEncoding,
                e
            );

        return ObjC.unwrap(
            ns.isNil() ? (
                e.localizedDescription
            ) : ns
        );
    };

    // sort :: Ord a => [a] -> [a]
    const sort = xs =>
        Array.from(xs).sort();

    // toLower :: String -> String
    const toLower = s =>
        // Lower-case version of string.
        s.toLocaleLowerCase();

    // MAIN ---
    return main();
})();


using Combinatorics

const tfile = download("http://wiki.puzzlers.org/pub/wordlists/unixdict.txt")
const wordlist = Dict(w => 1 for w in split(read(tfile, String), r"\s+"))

function wordwheel(wheel, central)
    returnlist = String[]
    for combo in combinations([string(i) for i in wheel])
        if central in combo && length(combo) > 2
            for perm in permutations(combo)
                word = join(perm)
                if haskey(wordlist, word) && !(word in returnlist)
                    push!(returnlist, word)
                end
            end
        end
    end
    return returnlist
end

println(wordwheel("ndeokgelw", "k"))


LetterCounter = {
  new = function(self, word)
    local t = { word=word, letters={} }
    for ch in word:gmatch(".") do t.letters[ch] = (t.letters[ch] or 0) + 1 end
    return setmetatable(t, self)
  end,
  contains = function(self, other)
    for k,v in pairs(other.letters) do
      if (self.letters[k] or 0) < v then return false end
    end
    return true
  end
}
LetterCounter.__index = LetterCounter

grid = "ndeokgelw"
midl = grid:sub(5,5)
ltrs = LetterCounter:new(grid)
file = io.open("unixdict.txt", "r")
for word in file:lines() do
  if #word >= 3 and word:find(midl) and ltrs:contains(LetterCounter:new(word)) then
    print(word)
  end
end


ClearAll[possible]
possible[letters_List][word_String] := Module[{c1, c2, m},
  c1 = Counts[[email protected]];
  c2 = Counts[letters];
  m = Merge[{c1, c2}, Identity];
  Length[Select[Select[m, Length /* GreaterThan[1]], Apply[Greater]]] == 0
  ]
chars = [email protected]"ndeokgelw";
words = Import["http://wiki.puzzlers.org/pub/wordlists/unixdict.txt", "String"];
words = StringSplit[ToLowerCase[words], "\n"];
words //= Select[StringLength /* GreaterEqualThan[3]];
words //= Select[StringContainsQ["k"]];
words //= Select[StringMatchQ[Repeated[Alternatives @@ chars]]];
words //= Select[possible[chars]];
words


import strutils, sugar, tables

const Grid = """N D E
                O K G
                E L W"""

let letters = Grid.toLowerAscii.splitWhitespace.join()

let words = collect(newSeq):
              for word in "unixdict.txt".lines:
                if word.len in 3..9:
                  word

let midLetter = letters[4]

let gridCount = letters.toCountTable
for word in words:
  block checkWord:
    if midLetter in word:
      for ch, count in word.toCountTable.pairs:
        if count > gridCount[ch]:
          break checkWord
      echo word


program WordWheel;

{$mode objfpc}{$H+}

uses
  SysUtils;

const
  WheelSize = 9;
  MinLength = 3;
  WordListFN = 'unixdict.txt';

procedure search(Wheel : string);
var
  Allowed, Required, Available, w : string;
  Len, i, p : integer;
  WordFile : TextFile;
  Match : boolean;
begin
  AssignFile(WordFile, WordListFN);
  try
    Reset(WordFile);
  except
    writeln('Could not open dictionary file: ' + WordListFN);
    exit;
  end;
  Allowed := LowerCase(Wheel);
  Required := copy(Allowed, 5, 1);  { central letter is required }
  while not eof(WordFile) do
    begin
      readln(WordFile, w);
      Len := length(w);
      if (Len < MinLength) or (Len > WheelSize) then continue;
      if pos(Required, w) = 0 then continue;
      Available := Allowed;
      Match := True;
      for i := 1 to Len do
        begin
          p := pos(w[i], Available);
          if p > 0 then
            { prevent re-use of letter }
            delete(Available, p, 1)
          else
            begin
              Match := False;
              break;
            end;
        end;
      if Match then
        writeln(w);
    end;
  CloseFile(WordFile);
end;

{ exercise the procedure }
begin
  search('NDE' + 'OKG' + 'ELW');
end.


#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Word_wheel
use warnings;

$_ = <<END;
                    N  D  E
                    O  K  G
                    E  L  W
END

my $file = do { local(@ARGV, $/) = 'unixdict.txt'; <> };
my $length = my @letters = lc =~ /\w/g;
my $center = $letters[@letters / 2];
my $toomany = (join '', sort @letters) =~ s/(.)\1*/
  my $count = length "$1$&"; "(?!(?:.*$1){$count})" /ger;
my $valid = qr/^(?=.*$center)$toomany([@letters]{3,$length}$)$/m;

my @words = $file =~ /$valid/g;

print @words . " words for\n$_\n@words\n" =~ s/.{60}\K /\n/gr;


with javascript_semantics
requires("1.0.1") -- (fixed another glitch in unique())
constant wheel = "ndeokgelw",
         musthave = wheel[5]
sequence words = unix_dict(),
         word9 = {} -- (for the optional extra part)
integer found = 0
for i=1 to length(words) do
    string word = lower(words[i])
    integer lw = length(word)
    if lw>=3 then
        if lw<=9 then
            word9 = append(word9,word)
        end if
        if find(musthave,word) then
            string remaining = wheel
            while lw do
                integer k = find(word[lw],remaining)
                if k=0 then exit end if
                remaining[k] = '\0' -- (prevent re-use)
                lw -= 1
            end while
            if lw=0 then
                found += 1
                words[found] = word
            end if
        end if
    end if
end for
string jbw = join_by(words[1..found],1,9," ","\n ")
printf(1, "The following %d words were found:\n %s\n",{found,jbw})

-- optional extra
if platform()!=JS then  -- (works but no progress/blank screen for 2min 20s)
                        -- (the "working" won't show, even w/o the JS check)
    integer mostFound = 0
    sequence mostWheels = {},
             mustHaves = {}
    for i=1 to length(word9) do
        string try_wheel = word9[i]
        if length(try_wheel)=9 then
            string musthaves = unique(try_wheel)
            for j=1 to length(musthaves) do
                found = 0
                for k=1 to length(word9) do
                    string word = word9[k]
                    if find(musthaves[j],word) then
                        string rest = try_wheel
                        bool ok = true
                        for c=1 to length(word) do
                            integer ix = find(word[c],rest)
                            if ix=0 then
                                ok = false
                                exit
                            end if
                            rest[ix] = '\0'
                        end for
                        found += ok
                    end if
                end for
                if platform()!=JS then -- (wouldn't show up anyway)
                    printf(1,"working (%s)\r",{try_wheel})
                end if
                if found>mostFound then
                    mostFound = found
                    mostWheels = {try_wheel}
                    mustHaves = {musthaves[j]}
                elsif found==mostFound then
                    mostWheels = append(mostWheels,try_wheel)
                    mustHaves = append(mustHaves,musthaves[j])
                end if
            end for
        end if
    end for
    printf(1,"Most words found = %d\n",mostFound)
    printf(1,"Nine letter words producing this total:\n")
    for i=1 to length(mostWheels) do
        printf(1,"%s with central letter '%c'\n",{mostWheels[i],mustHaves[i]})
    end for
end if


main =>
  MinLen = 3,
  MaxLen = 9,
  Chars = "ndeokgelw",
  MustContain = 'k',

  WordList = "unixdict.txt",
  Words = read_file_lines(WordList),
  Res = word_wheel(Chars,Words,MustContain,MinLen, MaxLen),
  println(Res),
  println(len=Res.len),
  nl.

word_wheel(Chars,Words,MustContain,MinLen,MaxLen) = Res.reverse =>
  Chars := to_lowercase(Chars),
  D = make_hash(Chars),
  Res = [],
  foreach(W in Words, W.len >= MinLen, W.len <= MaxLen, membchk(MustContain,W))
    WD = make_hash(W),
    Check = true,
    foreach(C in keys(WD), break(Check == false))
      if not D.has_key(C) ; WD.get(C,0) > D.get(C,0) then
        Check := false
      end
    end,
    if Check == true then
      Res := [W|Res]
    end
  end.

% Returns a map of the elements and their occurrences
% in the list L.
make_hash(L) = D =>
  D = new_map(),
  foreach(E in L)
    D.put(E,D.get(E,0)+1)
  end.


Procedure.b check_word(word$)
  Shared letters$
  If Len(word$)<3 Or FindString(word$,"k")<1
    ProcedureReturn #False
  EndIf
  For i=1 To Len(word$)
    If CountString(letters$,Mid(word$,i,1))<CountString(word$,Mid(word$,i,1))
      ProcedureReturn #False
    EndIf
  Next
  ProcedureReturn #True
EndProcedure

If ReadFile(0,"./Data/unixdict.txt")
  txt$=LCase(ReadString(0,#PB_Ascii|#PB_File_IgnoreEOL))
  CloseFile(0)
EndIf

If OpenConsole()
  letters$="ndeokgelw"
  wordcount=1
  Repeat
    buf$=StringField(txt$,wordcount,~"\n")
    wordcount+1
    If check_word(buf$)=#False
      Continue
    EndIf
    PrintN(buf$) : r+1
  Until buf$=""
  PrintN("- Finished: "+Str(r)+" words found -")
  Input()
EndIf
End


import urllib.request
from collections import Counter

GRID = """
N 	D 	E
O 	K 	G
E 	L 	W
"""

def getwords(url='http://wiki.puzzlers.org/pub/wordlists/unixdict.txt'):
    "Return lowercased words of 3 to 9 characters"
    words = urllib.request.urlopen(url).read().decode().strip().lower().split()
    return (w for w in words if 2 < len(w) < 10)

def solve(grid, dictionary):
    gridcount = Counter(grid)
    mid = grid[4]
    return [word for word in dictionary
            if mid in word and not (Counter(word) - gridcount)]

if __name__ == '__main__':
    chars = ''.join(GRID.strip().lower().split())
    found = solve(chars, dictionary=getwords())
    print('\n'.join(found))


ce:count each
lc:ce group@                                              / letter count
dict:"\n"vs .Q.hg "http://wiki.puzzlers.org/pub/wordlists/unixdict.txt"
// dictionary of 3-9 letter words
d39:{x where(ce x)within 3 9}{x where all each x in .Q.a}dict

solve:{[grid;dict]
  i:where(grid 4)in'dict;
  dict i where all each 0<=(lc grid)-/:lc each dict i }[;d39]


use Terminal::Boxer;

my %*SUB-MAIN-OPTS = :named-anywhere;

unit sub MAIN ($wheel = 'ndeokgelw', :$dict = './unixdict.txt', :$min = 3);

my $must-have = $wheel.comb[4].lc;

my $has = $wheel.comb».lc.Bag;

my %words;
$dict.IO.slurp.words».lc.map: {
    next if not .contains($must-have) or .chars < $min;
    %words{.chars}.push: $_ if .comb.Bag ⊆ $has;
};

say "Using $dict, minimum $min letters.";

print rs-box :3col, :3cw, :indent("\t"), $wheel.comb».uc;

say "{sum %words.values».elems} words found";

printf "%d letters:  %s\n", .key, .value.sort.join(', ') for %words.sort;


/*REXX pgm finds (dictionary) words which can be found in a specified word wheel (grid).*/
parse arg grid minL iFID .                       /*obtain optional arguments from the CL*/
if grid==''|grid==","  then grid= 'ndeokgelw'    /*Not specified?  Then use the default.*/
if minL==''|minL==","  then minL= 3              /* "      "         "   "   "     "    */
if iFID==''|iFID==","  then iFID= 'UNIXDICT.TXT' /* "      "         "   "   "     "    */
oMinL= minL;                minL= abs(minL)      /*if negative, then don't show a list. */
gridU= grid;  upper gridU                        /*get an uppercase version of the grid.*/
Lg= length(grid);           Hg= Lg % 2  +  1     /*get length of grid & the middle char.*/
ctr= substr(grid, Hg, 1);   upper ctr            /*get uppercase center letter in grid. */
wrds= 0                                          /*# words that are in the dictionary.  */
wees= 0                                          /*"   "     "   "  too short.          */
bigs= 0                                          /*"   "     "   "  too long.           */
dups= 0                                          /*"   "     "   "  duplicates.         */
ills= 0                                          /*"   "     "   contain  "not" letters.*/
good= 0                                          /*"   "     "   contain center letter. */
nine= 0                                          /*" wheel─words that contain 9 letters.*/
say '                                Reading the file: ' iFID         /*align the text. */
@.= .                                            /*uppercase non─duplicated dict. words.*/
$=                                               /*the list of dictionary words in grid.*/
     do recs=0  while lines(iFID)\==0            /*process all words in the dictionary. */
     u= space( linein(iFID), 0);   upper u       /*elide blanks;  uppercase the word.   */
     L= length(u)                                /*obtain the length of the word.       */
     if @.u\==.           then do; dups= dups+1; iterate; end  /*is this a duplicate?   */
     if L<minL            then do; wees= wees+1; iterate; end  /*is the word too short? */
     if L>Lg              then do; bigs= bigs+1; iterate; end  /*is the word too long?  */
     if \datatype(u,'M')  then do; ills= ills+1; iterate; end  /*has word non─letters?  */
     @.u=                                        /*signify that  U  is a dictionary word*/
     wrds= wrds + 1                              /*bump the number of "good" dist. words*/
     if pos(ctr, u)==0        then iterate       /*word doesn't have center grid letter.*/
     good= good + 1                              /*bump # center─letter words in dict.  */
     if verify(u, gridU)\==0  then iterate       /*word contains a letter not in grid.  */
     if pruned(u, gridU)      then iterate       /*have all the letters not been found? */
     if L==9  then nine= nine + 1                /*bump # words that have nine letters. */
     $= $ u                                      /*add this word to the "found" list.   */
     end   /*recs*/
say
say '    number of  records (words) in the dictionary: '   right( commas(recs), 9)
say '    number of ill─formed words in the dictionary: '   right( commas(ills), 9)
say '    number of  duplicate words in the dictionary: '   right( commas(dups), 9)
say '    number of  too─small words in the dictionary: '   right( commas(wees), 9)
say '    number of  too─long  words in the dictionary: '   right( commas(bigs), 9)
say '    number of acceptable words in the dictionary: '   right( commas(wrds), 9)
say '    number center─letter words in the dictionary: '   right( commas(good), 9)
say '    the minimum length of words that can be used: '   right( commas(minL), 9)
say '                the word wheel (grid) being used: '   grid
say '      center of the word wheel (grid) being used: '   right('↑', Hg)
say;  #= words($);   $= strip($)
say '    number of word wheel words in the dictionary: '   right( commas(#   ), 9)
say '    number of   nine-letter   wheel words  found: '   right( commas(nine), 9)
if #==0  |  oMinL<0  then exit #
say
say '    The list of word wheel words found:';   say copies('─', length($));  say lower($)
exit #                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
lower:  arg aa; @='abcdefghijklmnopqrstuvwxyz'; @[email protected]; upper @u;  return translate(aa,@,@U)
commas: parse arg _;  do jc=length(_)-3  to 1  by -3; _=insert(',', _, jc); end;  return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
pruned: procedure; parse arg aa,gg               /*obtain word to be tested, & the grid.*/
           do n=1  for length(aa);    p= pos( substr(aa,n,1), gg);  if p==0  then return 1
           gg= overlay(., gg, p)                 /*"rub out" the found character in grid*/
           end   /*n*/;               return 0   /*signify that the  AA  passed the test*/


wheel  = "ndeokgelw"
middle, wheel_size = wheel[4], wheel.size

res = File.open("unixdict.txt").each_line.select do |word|
  w = word.chomp
  next unless w.size.between?(3, wheel_size)
  next unless w.match?(middle)
  wheel.each_char{|c| w.sub!(c, "") } #sub! substitutes only the first occurrence (gsub would substitute all)
  w.empty?
end

puts res


#lang transd

MainModule: {
  maxwLen: 9,
  minwLen: 3,
  dict: Vector<String>(),
  subWords: Vector<String>(),

  procGrid: (λ grid String() cent String() subs Bool()
    (with cnt 0 (sort grid)
    (for w in dict where (and (neq (find w cent) -1)
                              (match w "^[[:alpha:]]+$")) do
      (if (is-subset grid (sort (cp w))) (+= cnt 1)
        (if subs (append subWords w))
      )
    )
    (ret cnt)
  )),

  _start: (λ res 0 maxRes 0
    (with fs FileStream()
      (open-r fs "/mnt/proj/res/unixdict.txt")
      (for w in (read-lines fs)
             where (within (size w) minwLen maxwLen) do
        (append dict w))
    )

    (lout "Main part of task:\n")
    (procGrid "ndeokgelw" "k" true)
    (lout "Number of words: " (size subWords) ";\nword list: " subWords)

    (lout "\n\nOptional part of task:\n")
    (for w in dict where (eq (size w) maxwLen) do
      (for centl in (split (unique (sort (cp w))) "") do
        (if (>= (= res (procGrid (cp w) centl false)) maxRes) (= maxRes res)
          (lout "New max. number: " maxRes ", word: " w ", central letter: " centl)
  ) ) ) )
}


import "io" for File
import "/sort" for Sort, Find
import "/seq" for Lst

var letters = ["d", "e", "e", "g", "k", "l", "n", "o","w"]

var words = File.read("unixdict.txt").split("\n")
// get rid of words under 3 letters or over 9 letters
words = words.where { |w| w.count > 2 && w.count < 10 }.toList
var found = []
for (word in words) {
    if (word.indexOf("k") >= 0) {
        var lets = letters.toList
        var ok = true
        for (c in word) {
            var ix = Find.first(lets, c)
            if (ix == - 1) {
                ok = false
                break
            }
            lets.removeAt(ix)
        }
        if (ok) found.add(word)
    }
}

System.print("The following %(found.count) words are the solutions to the puzzle:")
System.print(found.join("\n"))

// optional extra
var mostFound = 0
var mostWords9 = []
var mostLetters = []
// iterate through all 9 letter words in the dictionary
for (word9 in words.where { |w| w.count == 9 }) {
    letters = word9.toList
    Sort.insertion(letters)
    // get distinct letters
    var distinctLetters = Lst.distinct(letters)
    // place each distinct letter in the middle and see what we can do with the rest
    for (letter in distinctLetters) {
        found = 0
        for (word in words) {
            if (word.indexOf(letter) >= 0) {
                var lets = letters.toList
                var ok = true
                for (c in word) {
                    var ix = Find.first(lets, c)
                    if (ix == - 1) {
                        ok = false
                        break
                    }
                    lets.removeAt(ix)
                }
                if (ok) found = found + 1
            }
        }
        if (found > mostFound) {
            mostFound = found
            mostWords9 = [word9]
            mostLetters = [letter]
        } else if (found == mostFound) {
            mostWords9.add(word9)
            mostLetters.add(letter)
        }
    }
}
System.print("\nMost words found = %(mostFound)")
System.print("Nine letter words producing this total:")
for (i in 0...mostWords9.count) {
    System.print("%(mostWords9[i]) with central letter '%(mostLetters[i])'")
}


string  0;      \use zero-terminated strings
int     I, Set, HasK, HasOther, HasDup, ECnt, Ch;
char    Word(25);
def     LF=$0A, CR=$0D, EOF=$1A;
[FSet(FOpen("unixdict.txt", 0), ^I);
OpenI(3);
repeat  I:= 0;  HasK:= false;  HasOther:= false;
        ECnt:= 0;  Set:= 0;  HasDup:= false;
        loop    [repeat Ch:= ChIn(3) until Ch # CR;     \remove possible CR
                if Ch=LF or Ch=EOF then quit;
                Word(I):= Ch;
                I:= I+1;
                if Ch = ^k then HasK:= true;
                case Ch of ^k,^n,^d,^e,^o,^g,^l,^w: []  \assume all lowercase
                other HasOther:= true;
                if Ch = ^e then ECnt:= ECnt+1
                else    [if Set & 1<<(Ch-^a) then HasDup:= true;
                        Set:= Set ! 1<<(Ch-^a);
                        ];
                ];
        Word(I):= 0;                                    \terminate string
        if I>=3 & HasK & ~HasOther & ~HasDup & ECnt<=2 then
                [Text(0, Word);  CrLf(0);
                ];
until   Ch = EOF;
]


F1::  ;; when user hits the F1 key, do the following
WinGetTitle, window, A  ; get identity of active window into a variable
WinMove, %window%, , 100, 100, 800, 800 ; move window to coordinates, 100, 100
                                        ; and change size to 800 x 800 pixels
sleep, 2000
WinHide, % window    ; hide window
TrayTip, hidden, window is hidden, 2
sleep, 2000
WinShow, % window  ; show window again
loop,
{
  inputbox, name, what was the name of your window?
  if (name = window) ; compare window variables for equality
  {
    msgbox you got it
    break
  }
; else try again
}
WinClose, % window
return


      SWP_NOMOVE = 2
      SWP_NOZORDER = 4
      SW_MAXIMIZE = 3
      SW_MINIMIZE = 6
      SW_RESTORE = 9
      SW_HIDE = 0
      SW_SHOW = 5

      REM Store window handle in a variable:
      myWindowHandle% = @hwnd%

      PRINT "Hiding the window in two seconds..."
      WAIT 200
      SYS "ShowWindow", myWindowHandle%, SW_HIDE
      WAIT 200
      SYS "ShowWindow", myWindowHandle%, SW_SHOW
      PRINT "Windows shown again."

      PRINT "Minimizing the window in two seconds..."
      WAIT 200
      SYS "ShowWindow", myWindowHandle%, SW_MINIMIZE
      WAIT 200
      SYS "ShowWindow", myWindowHandle%, SW_RESTORE
      PRINT "Maximizing the window in two seconds..."
      WAIT 200
      SYS "ShowWindow", myWindowHandle%, SW_MAXIMIZE
      WAIT 200
      SYS "ShowWindow", myWindowHandle%, SW_RESTORE
      PRINT "Now restored to its normal size."

      PRINT "Resizing the window in two seconds..."
      WAIT 200
      SYS "SetWindowPos", myWindowHandle%, 0, 0, 0, 400, 200, \
      \    SWP_NOMOVE OR SWP_NOZORDER

      PRINT "Closing the window in two seconds..."
      WAIT 200
      QUIT


#include<windows.h>
#include<unistd.h>
#include<stdio.h>

const char g_szClassName[] = "weirdWindow";

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd[3];
    MSG Msg;
	int i,x=0,y=0;
	char str[3][100];
	int maxX = GetSystemMetrics(SM_CXSCREEN), maxY = GetSystemMetrics(SM_CYSCREEN);

	char messages[15][180] = {"Welcome to the Rosettacode Window C implementation.",
	"If you can see two blank windows just behind this message box, you are in luck.",
	"Let's get started....",
	"Yes, you will be seeing a lot of me :)",
	"Now to get started with the tasks, the windows here are stored in an array of type HWND, the array is called hwnd (yes, I know it's very innovative.)",
	"Let's compare the windows for equality.",
	"Now let's hide Window 1.",
	"Now let's see Window 1 again.",
	"Let's close Window 2, bye, bye, Number 2 !",
	"Let's minimize Window 1.",
	"Now let's maximize Window 1.",
	"And finally we come to the fun part, watch Window 1 move !",
	"Let's double Window 1 in size for all the good work.",
	"That's all folks ! (You still have to close that window, that was not part of the contract, sue me :D )"};

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

	for(i=0;i<2;i++){

		sprintf(str[i],"Window Number %d",i+1);

		hwnd[i] = CreateWindow(g_szClassName,str[i],WS_OVERLAPPEDWINDOW,i*maxX/2 , 0, maxX/2-10, maxY/2-10,NULL, NULL, hInstance, NULL);

		if(hwnd[i] == NULL)
		{
			MessageBox(NULL, "Window Creation Failed!", "Error!",MB_ICONEXCLAMATION | MB_OK);
			return 0;
		}

		ShowWindow(hwnd[i], nCmdShow);
		UpdateWindow(hwnd[i]);
	}

	for(i=0;i<6;i++){
			MessageBox(NULL, messages[i], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);
	}

	if(hwnd[0]==hwnd[1])
			MessageBox(NULL, "Window 1 and 2 are equal.", "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);
	else
			MessageBox(NULL, "Nope, they are not.", "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	MessageBox(NULL, messages[6], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	ShowWindow(hwnd[0], SW_HIDE);

	MessageBox(NULL, messages[7], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	ShowWindow(hwnd[0], SW_SHOW);

	MessageBox(NULL, messages[8], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	ShowWindow(hwnd[1], SW_HIDE);

	MessageBox(NULL, messages[9], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	ShowWindow(hwnd[0], SW_MINIMIZE);

	MessageBox(NULL, messages[10], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	ShowWindow(hwnd[0], SW_MAXIMIZE);

	MessageBox(NULL, messages[11], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	ShowWindow(hwnd[0], SW_RESTORE);

	while(x!=maxX/2||y!=maxY/2){
		if(x<maxX/2)
			x++;
		if(y<maxY/2)
			y++;

		MoveWindow(hwnd[0],x,y,maxX/2-10, maxY/2-10,0);
		sleep(10);
	}

	MessageBox(NULL, messages[12], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

	MoveWindow(hwnd[0],0,0,maxX, maxY,0);

	MessageBox(NULL, messages[13], "Info",MB_APPLMODAL| MB_ICONINFORMATION | MB_OK);

    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}


sWindow As New String[4]
'________________________
Public Sub Form_Open()

Manipulate

End
'________________________
Public Sub Manipulate()
Dim siDelay As Short = 2

Me.Show
Print "Show"
Wait siDelay

sWindow[0] = Me.Width
sWindow[1] = Me.Height
sWindow[2] = Me.X
sWindow[3] = Me.y

Me.Hide
Print "Hidden"
CompareWindow
Wait siDelay

Me.Show
Print "Show"
CompareWindow
Wait siDelay

Me.Minimized = True
Print "Minimized"
CompareWindow
Wait siDelay

Me.Show
Print "Show"
CompareWindow
Wait siDelay

Me.Maximized = True
Print "Maximized"
CompareWindow
Wait siDelay

Me.Maximized = False
Print "Not Maximized"
CompareWindow
Wait siDelay

Me.Height = 200
Me.Width = 300
Print "Resized"
CompareWindow
Wait siDelay

Me.x = 10
Me.Y = 10
Print "Moved"
CompareWindow
Wait siDelay

Me.Close

End
'________________________
Public Sub CompareWindow()
Dim sNewWindow As New String[4]
Dim siCount As Short
Dim bMatch As Boolean = True

sNewWindow[0] = Me.Width
sNewWindow[1] = Me.Height
sNewWindow[2] = Me.X
sNewWindow[3] = Me.y

For siCount = 0 To 3
  If sWindow[siCount] <> sNewWindow[siCount] Then bMatch = False
Next

If bMatch Then
  Print "Windows identities match the original window size"
Else
  Print "Windows identities DONOT match the original window size"
End If

End


package main

import (
    "github.com/gotk3/gotk3/gtk"
    "log"
    "time"
)

func check(err error, msg string) {
    if err != nil {
        log.Fatal(msg, err)
    }
}

func main() {
    gtk.Init(nil)

    window, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
    check(err, "Unable to create window:")
    window.SetResizable(true)
    window.SetTitle("Window management")
    window.SetBorderWidth(5)
    window.Connect("destroy", func() {
        gtk.MainQuit()
    })

    stackbox, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 10)
    check(err, "Unable to create stack box:")

    bmax, err := gtk.ButtonNewWithLabel("Maximize")
    check(err, "Unable to create maximize button:")
    bmax.Connect("clicked", func() {
        window.Maximize()
    })

    bunmax, err := gtk.ButtonNewWithLabel("Unmaximize")
    check(err, "Unable to create unmaximize button:")
    bunmax.Connect("clicked", func() {
        window.Unmaximize()
    })

    bicon, err := gtk.ButtonNewWithLabel("Iconize")
    check(err, "Unable to create iconize button:")
    bicon.Connect("clicked", func() {
        window.Iconify()
    })

    bdeicon, err := gtk.ButtonNewWithLabel("Deiconize")
    check(err, "Unable to create deiconize button:")
    bdeicon.Connect("clicked", func() {
        window.Deiconify()
    })

    bhide, err := gtk.ButtonNewWithLabel("Hide")
    check(err, "Unable to create hide button:")
    bhide.Connect("clicked", func() {
        // not working on Ubuntu 16.04 but window 'dims' after a few seconds
        window.Hide()
        time.Sleep(10 * time.Second)
        window.Show()
    })

    bshow, err := gtk.ButtonNewWithLabel("Show")
    check(err, "Unable to create show button:")
    bshow.Connect("clicked", func() {
        window.Show()
    })

    bmove, err := gtk.ButtonNewWithLabel("Move")
    check(err, "Unable to create move button:")
    isShifted := false
    bmove.Connect("clicked", func() {
        w, h := window.GetSize()
        if isShifted {
            window.Move(w-10, h-10)
        } else {
            window.Move(w+10, h+10)
        }
        isShifted = !isShifted
    })

    bquit, err := gtk.ButtonNewWithLabel("Quit")
    check(err, "Unable to create quit button:")
    bquit.Connect("clicked", func() {
        window.Destroy()
    })

    stackbox.PackStart(bmax, true, true, 0)
    stackbox.PackStart(bunmax, true, true, 0)
    stackbox.PackStart(bicon, true, true, 0)
    stackbox.PackStart(bdeicon, true, true, 0)
    stackbox.PackStart(bhide, true, true, 0)
    stackbox.PackStart(bshow, true, true, 0)
    stackbox.PackStart(bmove, true, true, 0)
    stackbox.PackStart(bquit, true, true, 0)

    window.Add(stackbox)
    window.ShowAll()
    gtk.Main()
}


CHARACTER title="Rosetta Window_management"
REAL :: w=-333, h=25, x=1, y=0.5 ! pixels < 0,  relative window size 0...1,  script character size > 1

  WINDOW(WINdowhandle=wh, Width=w, Height=h, X=x, Y=y, TItle=title) ! create, on return size/pos VARIABLES are set to script char
  WINDOW(WIN=wh, MINimize)    ! minimize
  WINDOW(WIN=wh, SHowNormal)  ! restore
  WINDOW(WIN=wh, X=31, Y=7+4) !<-- move upper left here (col 31, row 7 + ~4 rows for title, menus, toolbar. Script window in upper left screen)
  WINDOW(WIN=wh, MAXimize)    ! maximize (hides the script window)
  WINDOW(Kill=wh)             ! close
END


link graphics

procedure main()

   Delay := 3000

   W1 := open("Window 1","g","resize=on","size=400,400","pos=100,100","bg=black","fg=red") |
         stop("Unable to open window 1")
   W2 := open("Window 2","g","resize=on","size=400,400","pos=450,450","bg=blue","fg=yellow") |
         stop("Unable to open window 2")
   W3 := open("Window 3","g","resize=on","size=400,400","pos=600,150","bg=orange","fg=black") |
         stop("Unable to open window 3")
   WWrite(W3,"Opened three windows")

   WWrite(W3,"Window 1&2 with rectangles")
   every Wx := W1 | W2 | W3 do
      if Wx ~=== W3 then
         FillRectangle(Wx,50,50,100,100)

   delay(Delay)
   WWrite(W3,"Window 1 rasied")
   Raise(W1)

   delay(Delay)
   WWrite(W3,"Window 2 hidden")
   WAttrib(W2,"canvas=hidden")

   delay(Delay)
   WWrite(W3,"Window 2 maximized")
   WAttrib(W2,"canvas=maximal")
   Raise(W3)

   delay(Delay)
   WWrite(W3,"Window 2 restored & resized")
   WAttrib(W2,"canvas=normal")
   WAttrib(W2,"size=600,600")

   delay(Delay)
   WWrite(W3,"Window 2 moved")
   WAttrib(W2,"posx=700","posy=300")

   delay(Delay)
   WWrite(W3,"Window 2 minimized")
   WAttrib(W2,"canvas=iconic")

   delay(Delay)
   WWrite(W3,"Window 2 restored")
   WAttrib(W2,"canvas=normal")  # restore as maximal, possible bug

   delay(Delay)
   WWrite(W3,"Enter Q or q here to quit")
   WDone(W3)
end


import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class WindowController extends JFrame {
   // Create UI on correct thread
   public static void main( final String[] args ) {
      EventQueue.invokeLater( () -> new WindowController() );
   }

   private JComboBox<ControlledWindow> list;

   // Button class to call the right method
   private class ControlButton extends JButton {
      private ControlButton( final String name ) {
         super(
            new AbstractAction( name ) {
               public void actionPerformed( final ActionEvent e ) {
                  try {
                     WindowController.class.getMethod( "do" + name )
                        .invoke ( WindowController.this );
                  } catch ( final Exception x ) { // poor practice
                     x.printStackTrace();        // also poor practice
                  }
               }
            }
         );
      }
   }

   // UI for controlling windows
   public WindowController() {
      super( "Controller" );

      final JPanel main = new JPanel();
      final JPanel controls = new JPanel();

      setLocationByPlatform( true );
      setResizable( false );
      setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      setLayout( new BorderLayout( 3, 3 ) );
      getRootPane().setBorder( new EmptyBorder( 3, 3, 3, 3 ) );
      add( new JLabel( "Add windows and control them." ), BorderLayout.NORTH );
      main.add( list = new JComboBox<>() );
      add( main, BorderLayout.CENTER );
      controls.setLayout( new GridLayout( 0, 1, 3, 3 ) );
      controls.add( new ControlButton( "Add"      ) );
      controls.add( new ControlButton( "Hide"     ) );
      controls.add( new ControlButton( "Show"     ) );
      controls.add( new ControlButton( "Close"    ) );
      controls.add( new ControlButton( "Maximise" ) );
      controls.add( new ControlButton( "Minimise" ) );
      controls.add( new ControlButton( "Move"     ) );
      controls.add( new ControlButton( "Resize"   ) );
      add( controls, BorderLayout.EAST );
      pack();
      setVisible( true );
   }

   // These are the windows we're controlling, but any JFrame would do
   private static class ControlledWindow extends JFrame {
      private int num;

      public ControlledWindow( final int num ) {
         super( Integer.toString( num ) );
         this.num = num;
         setLocationByPlatform( true );
         getRootPane().setBorder( new EmptyBorder( 3, 3, 3, 3 ) );
         setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
         add( new JLabel( "I am window " + num + ". Use the controller to control me." ) );
         pack();
         setVisible( true );
      }

      public String toString() {
         return "Window " + num;
      }
   }

   // Here comes the useful bit - window control code
   // Everything else was just to allow us to do this!

   public void doAdd() {
      list.addItem( new ControlledWindow( list.getItemCount () + 1 ) );
      pack();
   }

   public void doHide() {
      final JFrame window = getWindow();
      if ( null == window ) {
         return;
      }
      window.setVisible( false );
   }

   public void doShow() {
      final JFrame window = getWindow();
      if ( null == window ) {
         return;
      }
      window.setVisible( true );
   }

   public void doClose() {
      final JFrame window = getWindow();
      if ( null == window ) {
         return;
      }
      window.dispose();
   }

   public void doMinimise() {
      final JFrame window = getWindow();
      if ( null == window ) {
         return;
      }
      window.setState( Frame.ICONIFIED );
   }

   public void doMaximise() {
      final JFrame window = getWindow();
      if ( null == window ) {
         return;
      }
      window.setExtendedState( Frame.MAXIMIZED_BOTH );
   }

   public void doMove() {
      final JFrame window = getWindow();
      if ( null == window ) {
         return;
      }
      final int hPos = getInt( "Horizontal position?" );
      if ( -1 == hPos ) {
         return;
      }
      final int vPos = getInt( "Vertical position?" );
      if ( -1 == vPos ) {
         return;
      }
      window.setLocation ( hPos, vPos );
   }

   public void doResize() {
      final JFrame window = getWindow();
      if ( null == window ) {
         return;
      }
      final int width = getInt( "Width?" );
      if ( -1 == width ) {
         return;
      }
      final int height = getInt( "Height?" );
      if ( -1 == height ) {
         return;
      }
      window.setBounds ( window.getX(), window.getY(), width, height );
   }

   private JFrame getWindow() {
      final JFrame window = ( JFrame ) list.getSelectedItem();
      if ( null == window ) {
         JOptionPane.showMessageDialog( this, "Add a window first" );
      }
      return window;
   }

   private int getInt(final String prompt) {
      final String s = JOptionPane.showInputDialog( prompt );
      if ( null == s ) {
         return -1;
      }
      try {
         return Integer.parseInt( s );
      } catch ( final NumberFormatException x ) {
         JOptionPane.showMessageDialog( this, "Not a number" );
         return -1;
      }
   }
}


using Gtk

function controlwindow(win, lab)
    sleep(4)
    set_gtk_property!(lab, :label, "Hiding...")
    sleep(1)
    println("Hiding widow")
    set_gtk_property!(win, :visible, false)
    sleep(5)
    set_gtk_property!(lab, :label, "Showing...")
    println("Showing window")
    set_gtk_property!(win, :visible, true)
    sleep(5)
    set_gtk_property!(lab, :label, "Resizing...")
    println("Resizing window")
    resize!(win, 300, 300)
    sleep(4)
    set_gtk_property!(lab, :label, "Maximizing...")
    println("Maximizing window")
    sleep(1)
    maximize(win)
    set_gtk_property!(lab, :label, "Closing...")
    sleep(5)
    println("Closing window")
    destroy(win)
    sleep(2)
    exit(0)
end

function runwindow()
    win = GtkWindow("Window Control Test", 500, 30) |> (GtkFrame() |> (vbox = GtkBox(:v)))
    lab = GtkLabel("Window under external control")
    push!(vbox, lab)
    @async(controlwindow(win, lab))

    cond = Condition()
    endit(w) = notify(cond)
    signal_connect(endit, win, :destroy)
    showall(win)
    wait(cond)
end

runwindow()


nb=NotebookCreate[]; (*Create a window and store in a variable*)
nb===nb2 (*test for equality with another window object*)
SetOptions[nb,Visible->False](*Hide*)
SetOptions[nb,Visible->True](*Show*)
NotebookClose[nb] (*Close*)
SetOptions[nb,WindowMargins->{{x,Automatic},{y,Automatic}}](*Move to x,y screen position*)
SetOptions[nb,WindowSize->{100,100}](*Resize*)


import os
import gintro/[glib, gobject, gtk, gio]
from gintro/gdk import processAllUpdates

type MyWindow = ref object of ApplicationWindow
  isShifted: bool

#---------------------------------------------------------------------------------------------------

proc wMaximize(button: Button; window: MyWindow) =
  window.maximize()

proc wUnmaximize(button: Button; window: MyWindow) =
  window.unmaximize()

proc wIconify(button: Button; window: MyWindow) =
  window.iconify()

proc wDeiconify(button: Button; window: MyWindow) =
  window.deiconify()

proc wHide(button: Button; window: MyWindow) =
  window.hide()
  processAllUpdates()
  os.sleep(2000)
  window.show()

proc wShow(button: Button; window: MyWindow) =
  window.show()

proc wMove(button: Button; window: MyWindow) =
  var x, y: int
  window.getPosition(x, y)
  if window.isShifted:
    window.move(x - 10, y - 10)
  else:
    window.move(x + 10, y + 10)
  window.isShifted = not window.isShifted

proc wQuit(button: Button; window: MyWindow) =
  window.destroy()

#---------------------------------------------------------------------------------------------------

proc activate(app: Application) =
  ## Activate the application.

  let window = newApplicationWindow(MyWindow, app)
  window.setTitle("Window management")

  let stackBox = newBox(Orientation.vertical, 10)
  stackBox.setHomogeneous(true)

  let
    bMax = newButton("maximize")
    bUnmax = newButton("unmaximize")
    bIcon = newButton("iconize")
    bDeicon = newButton("deiconize")
    bHide = newButton("hide")
    bShow = newButton("show")
    bMove = newButton("move")
    bQuit = newButton("Quit")

  for button in [bMax, bUnmax, bIcon, bDeicon, bHide, bShow, bMove, bQuit]:
    stackBox.add button

  window.setBorderWidth(5)
  window.add(stackBox)

  discard bMax.connect("clicked", wMaximize, window)
  discard bUnmax.connect("clicked", wUnmaximize, window)
  discard bIcon.connect("clicked", wIconify, window)
  discard bDeicon.connect("clicked", wDeiconify, window)
  discard bHide.connect("clicked", wHide, window)
  discard bShow.connect("clicked", wShow, window)
  discard bMove.connect("clicked", wMove, window)
  discard bQuit.connect("clicked", wQuit, window)

  window.showAll()

#———————————————————————————————————————————————————————————————————————————————————————————————————

let app = newApplication(Application, "Rosetta.Window.Management")
discard app.connect("activate", activate)
discard app.run()


declare
  [QTk] = {Module.link ['x-oz://system/wp/QTk.ozf']}

  %% The messages that can be sent to the windows.
  WindowActions =
  [hide show close
   iconify deiconify
   maximize restore
   set(minsize:minsize(width:400 height:400))
   set(minsize:minsize(width:200 height:200))
   set(geometry:geometry(x:0 y:0))
   set(geometry:geometry(x:500 y:500))
  ]

  %% Two windows, still uninitialized.
  Windows = windows(window1:_
                    window2:_)

  fun {CreateWindow}
     Message = {NewCell WindowActions.1}
     ReceiverName = {NewCell {Arity Windows}.1}
     fun {ButtonText}
        "Send"#"  "#{ValueToString @Message}#"  to  "#@ReceiverName
     end
     Button
     Desc =
     td(title:"Window Management"
        lr(listbox(init:{Arity Windows}
                   glue:nswe
                   tdscrollbar:true
                   actionh:proc {$ W}
                              ReceiverName := {GetSelected W}
                              {Button set(text:{ButtonText})}
                           end
                  )
           listbox(init:{Map WindowActions ValueToString}
                   glue:nswe
                   tdscrollbar:true
                   actionh:proc {$ A}
                              Message := {GetSelected A}
                              {Button set(text:{ButtonText})}
                           end
                  )
           glue:nswe
          )
        button(text:{ButtonText}
               glue:we
               handle:Button
               action:proc {$}
                         {Windows[email protected]ReceiverName @Message}
                      end
              )
       )
     Window = {Extend {QTk.build Desc}}
  in
     {Window show}
     Window
  end

  %% Adds two methods to a toplevel instance.
  %% For maximize and restore we have to interact directly with Tk
  %% because that functionality is not part of the QTk library.
  fun {Extend Toplevel}
     proc {$ A}
        case A of maximize then
           {Tk.send wm(state Toplevel zoomed)}
        [] restore then
           {Tk.send wm(state Toplevel normal)}
        else
           {Toplevel A}
        end
     end
  end

  %% Returns the current entry of a listbox
  %% as an Oz value.
  fun {GetSelected LB}
     Entries = {LB get($)}
     Index = {LB get(firstselection:$)}
  in
     {Compiler.virtualStringToValue {Nth Entries Index}}
  end

  fun {ValueToString V}
     {Value.toVirtualString V 100 100}
  end
in
  {Record.forAll Windows CreateWindow}


#!perl
use strict;
use warnings;
use Tk;

my $mw;
my $win;
my $lab;

# How to open a window.
sub openWin {
	if( $win ) {
		$win->deiconify;
		$win->wm('state', 'normal');
	} else {
		eval { $win->destroy } if $win;
		$win = $mw->Toplevel;
		$win->Label(-text => "This is the window being manipulated")
			->pack(-fill => 'both', -expand => 1);
		$lab->configure(-text => "The window object is:\n$win");
	}
}

# How to close a window
sub closeWin {
	return unless $win;
	$win->destroy;
	$lab->configure(-text => '');
	undef $win;
}

# How to minimize a window
sub minimizeWin {
	return unless $win;
	$win->iconify;
}

# How to maximize a window
sub maximizeWin {
	return unless $win;
	$win->wm('state', 'zoomed');
	eval { $win->wmAttribute(-zoomed => 1) }; # Hack for X11
}

# How to move a window
sub moveWin {
	return unless $win;
	my ($x, $y) = $win->geometry() =~ /\+(\d+)\+(\d+)\z/ or die;
	$_ += 10 for $x, $y;
	$win->geometry("+$x+$y");
}

# How to resize a window
sub resizeWin {
	return unless $win;
	my ($w, $h) = $win->geometry() =~ /^(\d+)x(\d+)/ or die;
	$_ += 10 for $w, $h;
	$win->geometry($w . "x" . $h);
}

$mw = MainWindow->new;
for my $label0 ($mw->Label(-text => 'Window handle:')) {
	$lab = $mw->Label(-text => '');
	$label0->grid($lab);
}

my @binit = ('Open/Restore' => \&openWin, Close => \&closeWin,
	Minimize => \&minimizeWin, Maximize => \&maximizeWin,
	Move => \&moveWin, Resize => \&resizeWin);

while( my ($text, $callback) = splice @binit, 0, 2 ) {
	$mw->Button(-text => $text, -command => $callback)->grid('-');
}

MainLoop();

__END__


-- demo\rosetta\Window_management.exw
include pGUI.e

Ihandle dlg

function doFull(Ihandle /*ih*/)
    IupSetAttribute(dlg,"FULLSCREEN","YES")
    return IUP_DEFAULT
end function

function doMax(Ihandle /*ih*/)
    IupSetAttribute(dlg,"PLACEMENT","MAXIMIZED")
    -- this is a work-around to get the dialog minimised (on win platform)
    IupSetAttribute(dlg,"VISIBLE","YES")
    return IUP_DEFAULT
end function

function doMin(Ihandle /*ih*/)
    IupSetAttribute(dlg,"PLACEMENT","MINIMIZED")
    -- this is a work-around to get the dialog minimised (on win platform)
    IupSetAttribute(dlg,"VISIBLE","YES")
    return IUP_DEFAULT
end function

function doRestore(Ihandle /*ih*/)
    IupSetAttribute(dlg,"OPACITY","255")
    IupSetAttribute(dlg,"FULLSCREEN","NO")
    IupSetAttribute(dlg,"PLACEMENT","NORMAL")
    IupSetAttribute(dlg,"VISIBLE","YES")
    return IUP_DEFAULT
end function

function doDim(Ihandle /*ih*/)
    IupSetAttribute(dlg,"OPACITY","60")
    return IUP_DEFAULT
end function

function doShow(Ihandle /*ih*/)
    IupSetAttribute(dlg,"OPACITY","255")
    return IUP_DEFAULT
end function

function doMove(Ihandle /*ih*/)
    integer {x,y} = IupGetIntInt(dlg,"SCREENPOSITION")
    integer shift = iff(IupGetInt(NULL,"SHIFTKEY")?-10,+10)
    IupShowXY(dlg,x+shift,y+shift)
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()

    Ihandle hbox = IupHbox({IupButton("restore",    Icallback("doRestore")),
                            IupButton("full screen",Icallback("doFull")),
                            IupButton("maximize",   Icallback("doMax")),
                            IupButton("minimize",   Icallback("doMin")),
                            IupButton("dim",        Icallback("doDim")),
                            IupButton("show",       Icallback("doShow")),
                            IupButton("move",       Icallback("doMove"))})
    IupSetAttribute(hbox,"MARGIN", "10x10")
    IupSetAttribute(hbox,"PADDING", "5x5")

    dlg = IupDialog(hbox)
    IupSetAttribute(dlg,"OPACITY","255")

    IupShowXY(dlg,IUP_CENTER,IUP_CENTER)
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure
main()


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program creatFenX1164.s   */
/* link with gcc options  -lX11 -L/usr/lpp/X11/lib */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ ClientMessage, 33

/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szRetourligne: .asciz  "\n"
szMessErreur:  .asciz "Server X11 not found.\n"
szMessErrfen:  .asciz "Error create X11 window.\n"

szLibDW:       .asciz "WM_DELETE_WINDOW"      // message close window

/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss
.align 4
qDisplay:        .skip 8           // Display address
qDefScreen:      .skip 8           // Default screen address
identWin:        .skip 8           // window ident
wmDeleteMessage: .skip 16          // ident close message
stEvent:         .skip 400         // provisional size

buffer:          .skip 500

/**********************************************/
/* -- Code section                            */
/**********************************************/
.text
.global main                   // program entry
main:
    mov x0,#0                  // open server X
    bl XOpenDisplay
    cmp x0,#0
    beq erreur
                               //  Ok return Display address
    ldr x1,qAdrqDisplay
    str x0,[x1]                // store Display address for future use
    mov x28,x0                 // and in register 28
                               // load default screen
    ldr x2,[x0,#264]           // at location 264
    ldr x1,qAdrqDefScreen
    str x2,[x1]                //store default_screen
    mov x2,x0
    ldr x0,[x2,#232]           // screen list

                               //screen areas
    ldr x5,[x0,#+88]           // white pixel
    ldr x3,[x0,#+96]           // black pixel
    ldr x4,[x0,#+56]           // bits par pixel
    ldr x1,[x0,#+16]           // root windows
                               // create window x11
    mov x0,x28                 //display
    mov x2,#0                  // position X
    mov x3,#0                  // position Y
    mov x4,600                 // weight
    mov x5,400                 // height
    mov x6,0                   // bordure ???
    ldr x7,0                   // ?
    ldr x8,qBlanc              // background
    str x8,[sp,-16]!           // argument fot stack
    bl XCreateSimpleWindow
    add sp,sp,16               // for stack alignement
    cmp x0,#0                  // error ?
    beq erreurF
    //mov x3,sp
    ldr x1,qAdridentWin
    str x0,[x1]                // store window ident for future use
    mov x27,x0                 // and in register 27

                               // Correction of window closing error
    mov x0,x28                 // Display address
    ldr x1,qAdrszLibDW         // atom name address
    mov x2,#1                  // False  create atom if not exist
    bl XInternAtom
    cmp x0,#0
    ble erreurF
    ldr x1,qAdrwmDeleteMessage // address message
    str x0,[x1]
    mov x2,x1                  // address atom create
    mov x0,x28                 // display address
    mov x1,x27                 // window ident
    mov x3,#1                  // number of protocoles
    bl XSetWMProtocols
    cmp x0,#0
    ble erreurF

                               // Display window
    mov x1,x27                 // ident window
    mov x0,x28                 // Display address
    bl XMapWindow

1:                             // events loop
    mov x0,x28                 // Display address
    ldr x1,qAdrstEvent         // events structure address
    bl XNextEvent
    ldr x0,qAdrstEvent         // events structure address
    ldr w0,[x0]                // type in 4 fist bytes
    cmp w0,#ClientMessage      // message for close window
    bne 1b                     // no -> loop

    ldr x0,qAdrstEvent         // events structure address
    ldr x1,[x0,56]             // location message code
    ldr x2,qAdrwmDeleteMessage // equal ?
    ldr x2,[x2]
    cmp x1,x2
    bne 1b                     // no loop

    mov x0,0                   // end Ok
    b 100f
erreurF:                       // error create window
    ldr x0,qAdrszMessErrfen
    bl affichageMess
    mov x0,1
    b 100f
erreur:                        // error no server x11 active
    ldr x0,qAdrszMessErreur
    bl affichageMess
    mov x0,1
100:                           // program standard end
    mov x8,EXIT
    svc 0
qBlanc:              .quad 0xF0F0F0F0
qAdrqDisplay:        .quad qDisplay
qAdrqDefScreen:      .quad qDefScreen
qAdridentWin:        .quad identWin
qAdrstEvent:         .quad stEvent
qAdrszMessErrfen:    .quad szMessErrfen
qAdrszMessErreur:    .quad szMessErreur
qAdrwmDeleteMessage: .quad wmDeleteMessage
qAdrszLibDW:         .quad szLibDW
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


$ ersatz/pil +
: (setq
   JFrame         "javax.swing.JFrame"
   MAXIMIZED_BOTH (java (public JFrame 'MAXIMIZED_BOTH))
   ICONIFIED      (java (public JFrame 'ICONIFIED))
   Win            (java JFrame T "Window") )
-> $JFrame

# Compare for equality
: (== Win Win)
-> T

# Set window visible
(java Win 'setLocation 100 100)
(java Win 'setSize 400 300)
(java Win 'setVisible T)

# Hide window
(java Win 'hide)

# Show again
(java Win 'setVisible T)

# Move window
(java Win 'setLocation 200 200)

# Iconify window
(java Win 'setExtendedState
   (| (java (java Win 'getExtendedState)) ICONIFIED) )

# De-conify window
(java Win 'setExtendedState
   (& (java (java Win 'getExtendedState)) (x| (hex "FFFFFFFF") ICONIFIED)) )

# Maximize window
(java Win 'setExtendedState
   (| (java (java Win 'getExtendedState)) MAXIMIZED_BOTH) )

# Close window
(java Win 'dispose)


;- Create a linked list to store created windows.
NewList Windows()
Define i, j, dh, dw, flags, err$, x, y

;- Used sub-procedure to simplify the error handling
Procedure HandleError(Result, Text.s,ErrorLine=0,ExitCode=0)
  If Not Result
    MessageRequester("Error",Text)
    End ExitCode
  EndIf
  ProcedureReturn Result
EndProcedure

;- Window handling procedures
Procedure Minimize(window)
  SetWindowState(window,#PB_Window_Minimize)
EndProcedure

Procedure Normalize(window)
  SetWindowState(window,#PB_Window_Normal)
EndProcedure

;- Get enviroment data
HandleError(ExamineDesktops(),  "Failed to examine you Desktop.")
dh=HandleError(DesktopHeight(0),"Could not retrieve DesktopHight")/3
dw=HandleError(DesktopWidth(0), "Could not retrieve DesktopWidth")/3

;- Now, creating 9 windows
flags=#PB_Window_SystemMenu
err$="Failed to open Window"
For i=0 To 8
  j=HandleError(OpenWindow(#PB_Any,i*10,i*10+30,10,10,Str(i),flags),err$)
  SmartWindowRefresh(j, 1)
  AddElement(Windows())
  Windows()=j
Next i
Delay(1000)

;- Call a sub-routine for each Window stored in the list.
ForEach Windows()
  Minimize(Windows())
Next
Delay(1000)
;- and again
ForEach Windows()
  Normalize(Windows())
Next
Delay(1000)

;- Spread them evenly
ForEach Windows()
  ResizeWindow(Windows(),x*dw,y*dh,dw-15,dh-35)
  x+1
  If x>2
    x=0: y+1
  EndIf
Next
Delay(2000)

End


from tkinter import *
import tkinter.messagebox

def maximise():
	"""get screenwidth and screenheight, and resize window to that size.
	Also move to 0,0"""
	root.geometry("{}x{}+{}+{}".format(root.winfo_screenwidth(), root.winfo_screenheight(), 0, 0))

def minimise():
	"""Iconify window to the taskbar. When reopened, the window is
	unfortunately restored to its original state, NOT its most recent state."""
	root.iconify()

def delete():
	"""create a modal dialog. If answer is "OK", quit the program"""
	if tkinter.messagebox.askokcancel("OK/Cancel","Are you sure?"):
		root.quit()

root = Tk()

mx=Button(root,text="maximise",command=maximise)
mx.grid()
mx.bind(maximise)

mn=Button(root,text="minimise",command=minimise)
mn.grid()
mn.bind(minimise)

#catch exit events, including "X" on title bar.
root.protocol("WM_DELETE_WINDOW",delete)

mainloop()


FILE window;
draw device (window, "X", "600x400");
open (window, "Hello, World!", stand draw channel);
  draw erase (window);
  draw move (window, 0.25, 0.5);
  draw colour (window, 1, 0, 0);
  draw text (window, "c", "c", "hello world");
  draw show (window);
  VOID (read char);
close (window)


/* ARM assembly Raspberry PI  */
/*  program windows1.s        */

/* compile with as         */
/* link with gcc and options -lX11 -L/usr/lpp/X11/lib   */

/********************************************/
/*Constantes                                */
/********************************************/
.equ STDOUT,              1     @ Linux output console
.equ EXIT,                1     @ Linux syscall
.equ WRITE,               4     @ Linux syscall
/* constantes X11 */
.equ KeyPressed,          2
.equ ButtonPress,         4
.equ MotionNotify,        6
.equ EnterNotify,         7
.equ LeaveNotify,         8
.equ Expose,              12
.equ ClientMessage,       33
.equ KeyPressMask,        1
.equ ButtonPressMask,     4
.equ ButtonReleaseMask,   8
.equ ExposureMask,        1<<15
.equ StructureNotifyMask, 1<<17
.equ EnterWindowMask,     1<<4
.equ LeaveWindowMask,     1<<5
.equ ConfigureNotify,     22

/*******************************************/
/* DONNEES INITIALISEES                    */
/*******************************************/
.data
szWindowName:            .asciz "Windows Raspberry"
szRetourligne:           .asciz  "\n"
szMessDebutPgm:          .asciz "Program start. \n"
szMessErreur:            .asciz "Server X not found.\n"
szMessErrfen:            .asciz "Can not create window.\n"
szMessErreurX11:         .asciz "Error call function X11. \n"
szMessErrGc:             .asciz "Can not create graphics context.\n"
szTitreFenRed:           .asciz "Pi"
szTexte1:                .asciz "Hello world."
.equ LGTEXTE1, . - szTexte1
szTexte2:                .asciz "Press q for close window or clic X in system menu."
.equ LGTEXTE2, . - szTexte2
szLibDW: .asciz "WM_DELETE_WINDOW"    @ special label for correct close error

/*************************************************/
szMessErr: .ascii	"Error code hexa : "
sHexa: .space 9,' '
         .ascii "  decimal :  "
sDeci: .space 15,' '
         .asciz "\n"

/*******************************************/
/* DONNEES NON INITIALISEES                    */
/*******************************************/
.bss
.align 4
ptDisplay:          .skip 4      @ pointer display
ptEcranDef:         .skip 4      @ pointer screen default
ptFenetre:          .skip 4      @ pointer window
ptGC:               .skip 4      @ pointer graphic context
key:                .skip 4      @ key code
wmDeleteMessage:    .skip 8      @ ident close message
event:              .skip 400    @ TODO event size ??
PrpNomFenetre:      .skip 100    @ window name proprety
buffer:             .skip 500
iWhite:             .skip 4      @ rgb code for white pixel
iBlack:             .skip 4      @ rgb code for black pixel
/**********************************************/
/* -- Code section                            */
/**********************************************/
.text
.global main

main:                               @ entry of program
    ldr r0,iAdrszMessDebutPgm   @
    bl affichageMess            @ display start message on console linux
    /* attention r6  pointer display*/
    /* attention r8  pointer graphic context   */
    /* attention r9 ident window  */
    /*****************************/
    /*    OPEN SERVER X11        */
    /*****************************/
    mov r0,#0
    bl XOpenDisplay             @ open X server
    cmp r0,#0                   @ error ?
    beq erreurServeur
    ldr r1,iAdrptDisplay
    str r0,[r1]                 @ store display address
    mov r6,r0                   @ and in register r6
    ldr r2,[r0,#+132]           @ load default_screen
    ldr r1,iAdrptEcranDef
    str r2,[r1]                 @ store default_screen
    mov r2,r0
    ldr r0,[r2,#+140]           @ load pointer screen list
    ldr r5,[r0,#+52]            @ load value white pixel
    ldr r4,iAdrWhite            @ and store in memory
    str r5,[r4]
    ldr r3,[r0,#+56]            @ load value black pixel
    ldr r4,iAdrBlack            @ and store in memory
    str r3,[r4]
    ldr r4,[r0,#+28]            @ load bits par pixel
    ldr r1,[r0,#+8]             @ load root windows
    /**************************/
    /* CREATE WINDOW          */
    /**************************/
    mov r0,r6                   @ address display
    mov r2,#0                   @ window position X
    mov r3,#0                   @ window position Y
    mov r8,#0                   @ for stack alignement
    push {r8}
    push {r3}                   @  background  = black pixel
    push {r5}                   @  border = white pixel
    mov r8,#2                   @  border size
    push {r8}
    mov r8,#400                 @ hauteur
    push {r8}
    mov r8,#600                 @ largeur
    push {r8}
    bl XCreateSimpleWindow
    add sp,#24                  @ stack alignement  6 push (4 bytes * 6)
    cmp r0,#0                   @ error ?
    beq erreurF

    ldr r1,iAdrptFenetre
    str r0,[r1]                 @ store window address in memory
    mov r9,r0                   @ and in register r9
    /*****************************/
    /* add window property       */
    /*****************************/
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    ldr r2,iAdrszWindowName     @ window name
    ldr r3,iAdrszTitreFenRed    @ window name reduced
    mov r4,#0
    push {r4}                   @ parameters not use
    push {r4}
    push {r4}
    push {r4}
    bl XSetStandardProperties
    add sp,sp,#16               @ stack alignement for 4 push
    /**************************************/
    /* for correction window close error  */
    /**************************************/
    mov r0,r6                   @ display address
    ldr r1,iAdrszLibDW          @ atom address
    mov r2,#1                   @ False  créate atom if not exists
    bl XInternAtom
    cmp r0,#0                   @ error X11 ?
    ble erreurX11
    ldr r1,iAdrwmDeleteMessage  @ recept address
    str r0,[r1]
    mov r2,r1                   @ return address
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    mov r3,#1                   @ number of protocols
    bl XSetWMProtocols
    cmp r0,#0                   @ error X11 ?
    ble erreurX11
    /**********************************/
    /*  create graphic context        */
    /**********************************/
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    mov r2,#0                   @ not use for simply context
    mov r3,#0
    bl XCreateGC
    cmp r0,#0                   @ error ?
    beq erreurGC
    ldr r1,iAdrptGC
    str r0,[r1]                 @ store address graphic context
    mov r8,r0                   @ and in r8
    /****************************/
    /* modif window background  */
    /****************************/
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    ldr r2,iGris1               @ background color
    bl XSetWindowBackground
    cmp r0,#0                   @ error ?
    ble erreurX11
    /***************************/
    /* OUF!! window display    */
    /***************************/
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    bl XMapWindow
    /****************************/
    /* Write text in the window */
    /****************************/
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    mov r2,r8                   @ address graphic context
    mov r3,#50                  @ position x
    sub sp,#4                   @ stack alignement
    mov r4,#LGTEXTE1  - 1       @ size string
    push {r4}                   @ on the stack
    ldr r4,iAdrszTexte1            @ string address
    push {r4}
    mov r4,#100                 @ position y
    push {r4}
    bl XDrawString
    add sp,sp,#16               @ stack alignement 3 push and 1 stack alignement
    cmp r0,#0                   @ error ?
    blt erreurX11
    /* write text 2 */
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    mov r2,r8                   @ address graphic context
    mov r3,#10                  @ position x
    sub sp,#4                   @ stack alignement
    mov r4,#LGTEXTE2  - 1       @ size string
    push {r4}                   @ on the stack
    ldr r4,iAdrszTexte2            @ string address
    push {r4}
    mov r4,#350                 @ position y
    push {r4}
    bl XDrawString
    add sp,sp,#16               @ stack alignement 3 push and 1 stack alignement
    cmp r0,#0                   @ error ?
    blt erreurX11
    /****************************/
    /* Autorisations            */
    /****************************/
    mov r0,r6                   @ display address
    mov r1,r9                   @ window address
    ldr r2,iFenetreMask         @ autorisation mask
    bl XSelectInput
    cmp r0,#0                   @ error ?
    ble erreurX11
    /****************************/
    /* Events loop              */
    /****************************/
1:
    mov r0,r6                   @ display address
    ldr r1,iAdrevent            @ events address
    bl XNextEvent               @ event ?
    ldr r0,iAdrevent
    ldr r0,[r0]                 @ code event
    cmp r0,#KeyPressed          @ key ?
    bne 2f
    ldr r0,iAdrevent            @ yes read key in buffer
    ldr r1,iAdrbuffer
    mov r2,#255
    ldr r3,iAdrkey
    mov r4,#0
    push {r4}                   @ stack alignement
    push {r4}
    bl XLookupString
    add sp,#8                   @ stack alignement 2 push
    cmp r0,#1                   @ is character key ?
    bne 2f
    ldr r0,iAdrbuffer           @ yes -> load first buffer character
    ldrb r0,[r0]
    cmp r0,#0x71                @ character q for quit
    beq 5f                      @ yes -> end
    b 4f
2:
    /*                                  */
    /* for example  clic mouse button   */
    /************************************/
    cmp r0,#ButtonPress         @ clic mouse buton
    bne 3f
    ldr r0,iAdrevent
    ldr r1,[r0,#+32]            @ position X mouse clic
    ldr r2,[r0,#+36]            @ position Y
    @ etc for eventuel use
    b 4f
3:
    cmp r0,#ClientMessage       @ code for close window within error
    bne 4f
    ldr r0,iAdrevent
    ldr r1,[r0,#+28]            @ code message address
    ldr r2,iAdrwmDeleteMessage  @ equal code window créate ???
    ldr r2,[r2]
    cmp r1,r2
    beq 5f                      @ yes -> end window

4:  @ loop for other event
    b 1b
    /***********************************/
    /* Close window -> free ressources */
    /***********************************/
5:
    mov r0,r6                  @ display address
    ldr r1,iAdrptGC
    ldr r1,[r1]                @ load context graphic address
    bl XFreeGC
    cmp r0,#0
    blt erreurX11
    mov r0,r6                  @ display address
    mov r1,r9                  @ window address
    bl XDestroyWindow
    cmp r0,#0
    blt erreurX11
    mov r0,r6                  @ display address
    bl XCloseDisplay
    cmp r0,#0
    blt erreurX11
    mov r0,#0                  @ return code OK
    b 100f
erreurF:   @ create error window but possible not necessary. Display error by server
    ldr r1,iAdrszMessErrfen
    bl   displayError
    mov r0,#1                  @ return error code
    b 100f
erreurGC:                      @ error create graphic context
    ldr r1,iAdrszMessErrGc
    bl   displayError
    mov r0,#1
    b 100f
erreurX11:    @ erreur X11
    ldr r1,iAdrszMessErreurX11
    bl   displayError
    mov r0,#1
    b 100f
erreurServeur:                 @ error no found X11 server see doc putty and Xming
    ldr r1,iAdrszMessErreur
    bl   displayError
    mov r0,#1
    b 100f

100:                           @ standard end of the program
    mov r7, #EXIT
    svc 0
iFenetreMask:        .int  KeyPressMask|ButtonPressMask|StructureNotifyMask
iGris1:              .int 0xFFA0A0A0
iAdrWhite:           .int iWhite
iAdrBlack:           .int iBlack
iAdrptDisplay:       .int ptDisplay
iAdrptEcranDef:      .int ptEcranDef
iAdrptFenetre:       .int ptFenetre
iAdrptGC:            .int ptGC
iAdrevent:           .int event
iAdrbuffer:          .int buffer
iAdrkey:             .int key
iAdrszLibDW:         .int szLibDW
iAdrszMessDebutPgm:  .int szMessDebutPgm
iAdrszMessErreurX11: .int szMessErreurX11
iAdrszMessErrGc:     .int szMessErrGc
iAdrszMessErreur:    .int szMessErreur
iAdrszMessErrfen:    .int szMessErrfen
iAdrszWindowName:    .int szWindowName
iAdrszTitreFenRed:   .int szTitreFenRed
iAdrszTexte1:        .int szTexte1
iAdrszTexte2:        .int szTexte2
iAdrPrpNomFenetre:   .int PrpNomFenetre
iAdrwmDeleteMessage: .int wmDeleteMessage
/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                   @ save  registres
    mov r2,#0                               @ counter length
1:                                          @ loop length calculation
    ldrb r1,[r0,r2]                         @ read octet start position + index
    cmp r1,#0                               @ if 0 its over
    addne r2,r2,#1                          @ else add 1 in the length
    bne 1b                                  @ and loop
                                            @ so here r2 contains the length of the message
    mov r1,r0                               @ address message in r1
    mov r0,#STDOUT                          @ code to write to the standard output Linux
    mov r7, #WRITE                          @ code call system "write"
    svc #0                                  @ call systeme
    pop {r0,r1,r2,r7,lr}                    @ restaur registers */
    bx lr                                   @ return
/***************************************************/
/*   affichage message d erreur              */
/***************************************************/
/* r0 contains error code  r1 : message address */
displayError:
    push {r0-r2,lr}                         @ save registers
    mov r2,r0                               @ save error code
    mov r0,r1
    bl affichageMess
    mov r0,r2                               @ error code
    ldr r1,iAdrsHexa
    bl conversion16                         @ conversion hexa
    mov r0,r2                               @ error code
    ldr r1,iAdrsDeci                        @ result address
    bl conversion10                         @ conversion decimale
    ldr r0,iAdrszMessErr                    @ display error message
    bl affichageMess
100:
    pop {r0-r2,lr}                          @ restaur registers
    bx lr                                   @ return
iAdrszMessErr:                 .int szMessErr
iAdrsHexa:                     .int sHexa
iAdrsDeci:                     .int sDeci
/******************************************************************/
/*     Converting a register to hexadecimal                      */
/******************************************************************/
/* r0 contains value and r1 address area   */
conversion16:
    push {r1-r4,lr}                                    @ save registers
    mov r2,#28                                         @ start bit position
    mov r4,#0xF0000000                                 @ mask
    mov r3,r0                                          @ save entry value
1:                                                     @ start loop
    and r0,r3,r4                                       @value register and mask
    lsr r0,r2                                          @ move right
    cmp r0,#10                                         @ compare value
    addlt r0,#48                                       @ <10  ->digit
    addge r0,#55                                       @ >10  ->letter A-F
    strb r0,[r1],#1                                    @ store digit on area and + 1 in area address
    lsr r4,#4                                          @ shift mask 4 positions
    subs r2,#4                                         @  counter bits - 4 <= zero  ?
    bge 1b                                             @  no -> loop

100:
    pop {r1-r4,lr}                                     @ restaur registers
    bx lr                                              @return
/******************************************************************/
/*     Converting a register to a decimal unsigned                */
/******************************************************************/
/* r0 contains value and r1 address area   */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes          */
.equ LGZONECAL,   10
conversion10:
    push {r1-r4,lr}                                 @ save registers
    mov r3,r1
    mov r2,#LGZONECAL
1:                                                  @ start loop
    bl divisionpar10U                               @ unsigned  r0 <- dividende. quotient ->r0 reste -> r1
    add r1,#48                                      @ digit
    strb r1,[r3,r2]                                 @ store digit on area
    cmp r0,#0                                       @ stop if quotient = 0
    subne r2,#1                                     @ else previous position
    bne 1b                                          @ and loop
                                                    @ and move digit from left of area
    mov r4,#0
2:
    ldrb r1,[r3,r2]
    strb r1,[r3,r4]
    add r2,#1
    add r4,#1
    cmp r2,#LGZONECAL
    ble 2b
                                                      @ and move spaces in end on area
    mov r0,r4                                         @ result length
    mov r1,#' '                                       @ space
3:
    strb r1,[r3,r4]                                   @ store space in area
    add r4,#1                                         @ next position
    cmp r4,#LGZONECAL
    ble 3b                                            @ loop if r4 <= area size

100:
    pop {r1-r4,lr}                                    @ restaur registres
    bx lr                                             @return

/***************************************************/
/*   division par 10   unsigned                    */
/***************************************************/
/* r0 dividende   */
/* r0 quotient    */
/* r1 remainder   */
divisionpar10U:
    push {r2,r3,r4, lr}
    mov r4,r0                                          @ save value
    ldr r3,iMagicNumber                                @ r3 <- magic_number    raspberry 1 2
    umull r1, r2, r3, r0                               @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
    mov r0, r2, LSR #3                                 @ r2 <- r2 >> shift 3
    add r2,r0,r0, lsl #2                               @ r2 <- r0 * 5
    sub r1,r4,r2, lsl #1                               @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
    pop {r2,r3,r4,lr}
    bx lr                                              @ leave function
iMagicNumber:  	.int 0xCCCCCCCD


#lang racket/gui

(define (say . xs) (printf ">>> ~a\n" (apply ~a xs)) (flush-output))

(define frame (new frame% [label "Demo"] [width 400] [height 400]))
(say "frame = " frame) ; plain value

(say 'Show)     (send frame show #t)      (sleep 1)
(say 'Hide)     (send frame show #f)      (sleep 1)
(say 'Show)     (send frame show #t)      (sleep 1)
(say 'Minimize) (send frame iconize #t)   (sleep 1)
(say 'Restore)  (send frame iconize #f)   (sleep 1)
(say 'Maximize) (send frame maximize #t)  (sleep 1)
(say 'Restore)  (send frame maximize #f)  (sleep 1)
(say 'Move)     (send frame move 100 100) (sleep 1)
(say 'Resize)   (send frame resize 100 100) (sleep 1)
(say 'Close)    (send frame show #f) (sleep 1) ; that's how we close a window


use X11::libxdo;

my $xdo = Xdo.new;

say 'Visible windows:';
printf "Class: %-21s ID#: %10d  pid: %5d  Name: %s\n", $_<class ID pid name>
    for $xdo.get-windows.sort(+*.key)».value;
sleep 2;

my $id = $xdo.get-active-window;

my ($w,  $h ) = $xdo.get-window-size( $id );
my ($wx, $wy) = $xdo.get-window-location( $id );
my ($dw, $dh) = $xdo.get-desktop-dimensions( 0 );

$xdo.move-window( $id, 150, 150 );

$xdo.set-window-size( $id, 350, 350, 0 );

sleep .25;

for flat 1 .. $dw - 350, $dw - 350, {$_ - 1} … 1 -> $mx { #
    my $my = (($mx / $dw * τ).sin * 500).abs.Int;
    $xdo.move-window( $id, $mx, $my );
    $xdo.activate-window($id);
}

sleep .25;

$xdo.move-window( $id, 150, 150 );

my $dx = $dw - 300;
my $dy = $dh - 300;

$xdo.set-window-size( $id, $dx, $dy, 0 );

sleep .25;

my $s = -1;

loop {
    $dx += $s * ($dw / 200).ceiling;
    $dy += $s * ($dh / 200).ceiling;
    $xdo.set-window-size( $id, $dx, $dy, 0 );
    $xdo.activate-window($id);
    sleep .005;
    $s *= -1 if $dy < 200;
    last if $dx >= $dw;
}

sleep .25;

$xdo.set-window-size( $id, $w, $h, 0 );
$xdo.move-window( $id, $wx, $wy );
$xdo.activate-window($id);

sleep .25;

$xdo.minimize($id);
$xdo.activate-window($id);
sleep 1;
$xdo.raise-window($id);
sleep .25;


'--- added a flush to exit cleanly
PRAGMA LDFLAGS `pkg-config --cflags --libs x11`
PRAGMA INCLUDE <X11/Xlib.h>
PRAGMA INCLUDE <X11/Xutil.h>

OPTION PARSE FALSE

'---XLIB is so ugly
ALIAS XNextEvent TO EVENT
ALIAS XOpenDisplay TO DISPLAY
ALIAS DefaultScreen TO SCREEN
ALIAS XCreateSimpleWindow TO CREATE
ALIAS XCloseDisplay TO CLOSE_DISPLAY
ALIAS XSelectInput TO EVENT_TYPE
ALIAS XMapWindow TO MAP_EVENT
ALIAS XFillRectangle TO FILL_RECTANGLE
ALIAS XDrawString TO DRAW_STRING
ALIAS XFlush TO FLUSH

'---pointer to X Display structure
DECLARE d TYPE  Display*

'---pointer to the newly created window
'DECLARE w TYPE WINDOW

'---pointer to the XEvent
DECLARE e TYPE XEvent

DECLARE msg TYPE char*

'--- number of screen to place the window on
DECLARE s TYPE int

  msg = "Hello, World!"

   d = DISPLAY(NULL)
   IF d == NULL THEN
	 EPRINT "Cannot open display" FORMAT "%s%s\n"
	 END
   END IF

   s = SCREEN(d)
   w = CREATE(d, RootWindow(d, s), 10, 10, 100, 100, 1,BlackPixel(d, s), WhitePixel(d, s))

   EVENT_TYPE(d, w, ExposureMask | KeyPressMask)
   MAP_EVENT(d, w)

   WHILE  (1)
	 EVENT(d, &e)
	 IF e.type == Expose THEN
	    FILL_RECTANGLE(d, w, DefaultGC(d, s), 20, 20, 10, 10)
	    DRAW_STRING(d, w, DefaultGC(d, s), 10, 50, msg, strlen(msg))
	 END IF
	 IF e.type == KeyPress THEN
	    BREAK
	 END IF
   WEND
   FLUSH(d)
   CLOSE_DISPLAY(d)


#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
   Display *d;
   Window w;
   XEvent e;
   const char *msg = "Hello, World!";
   int s;

   d = XOpenDisplay(NULL);
   if (d == NULL) {
      fprintf(stderr, "Cannot open display\n");
      exit(1);
   }

   s = DefaultScreen(d);
   w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
                           BlackPixel(d, s), WhitePixel(d, s));
   XSelectInput(d, w, ExposureMask | KeyPressMask);
   XMapWindow(d, w);

   while (1) {
      XNextEvent(d, &e);
      if (e.type == Expose) {
         XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
         XDrawString(d, w, DefaultGC(d, s), 10, 50, msg, strlen(msg));
      }
      if (e.type == KeyPress)
         break;
   }

   XCloseDisplay(d);
   return 0;
}


       identification division.
       program-id. x11-hello.
       installation. cobc -x x11-hello.cob -lX11
       remarks. Use of private data is likely not cross platform.

       data division.
       working-storage section.
       01 msg.
          05 filler            value z"S'up, Earth?".
       01 msg-len              usage binary-long value 12.

       01 x-display            usage pointer.
       01 x-window             usage binary-c-long.

      *> GnuCOBOL does not evaluate C macros, need to peek at opaque
      *> data from Xlib.h
      *> some padding is added, due to this comment in the header
      *> "there is more to this structure, but it is private to Xlib"
       01 x-display-private    based.
          05 x-ext-data        usage pointer sync.
          05 private1          usage pointer.
          05 x-fd              usage binary-long.
          05 private2          usage binary-long.
          05 proto-major-version   usage binary-long.
          05 proto-minor-version   usage binary-long.
          05 vendor            usage pointer sync.
          05 private3          usage pointer.
          05 private4          usage pointer.
          05 private5          usage pointer.
          05 private6          usage binary-long.
          05 allocator         usage program-pointer sync.
          05 byte-order        usage binary-long.
          05 bitmap-unit       usage binary-long.
          05 bitmap-pad        usage binary-long.
          05 bitmap-bit-order  usage binary-long.
          05 nformats          usage binary-long.
          05 screen-format     usage pointer sync.
          05 private8          usage binary-long.
          05 x-release         usage binary-long.
          05 private9          usage pointer sync.
          05 private10         usage pointer sync.
          05 qlen              usage binary-long.
          05 last-request-read usage binary-c-long unsigned sync.
          05 request           usage binary-c-long unsigned sync.
          05 private11         usage pointer sync.
          05 private12         usage pointer.
          05 private13         usage pointer.
          05 private14         usage pointer.
          05 max-request-size  usage binary-long unsigned.
          05 x-db              usage pointer sync.
          05 private15         usage program-pointer sync.
          05 display-name      usage pointer.
          05 default-screen    usage binary-long.
          05 nscreens          usage binary-long.
          05 screens           usage pointer sync.
          05 motion-buffer     usage binary-c-long unsigned.
          05 private16         usage binary-c-long unsigned.
          05 min-keycode       usage binary-long.
          05 max-keycode       usage binary-long.
          05 private17         usage pointer sync.
          05 private18         usage pointer.
          05 private19         usage binary-long.
          05 x-defaults        usage pointer sync.
          05 filler            pic x(256).

       01 x-screen-private     based.
          05 scr-ext-data      usage pointer sync.
          05 display-back      usage pointer.
          05 root              usage binary-c-long.
          05 x-width           usage binary-long.
          05 x-height          usage binary-long.
          05 m-width           usage binary-long.
          05 m-height          usage binary-long.
          05 x-ndepths         usage binary-long.
          05 depths            usage pointer sync.
          05 root-depth        usage binary-long.
          05 root-visual       usage pointer sync.
          05 default-gc        usage pointer.
          05 cmap              usage pointer.
          05 white-pixel       usage binary-c-long unsigned sync.
          05 black-pixel       usage binary-c-long unsigned.
          05 max-maps          usage binary-long.
          05 min-maps          usage binary-long.
          05 backing-store     usage binary-long.
          05 save_unders       usage binary-char.
          05 root-input-mask   usage binary-c-long sync.
          05 filler            pic x(256).

       01 event.
          05 e-type usage      binary-long.
          05 filler            pic x(188).
          05 filler            pic x(256).
       01 Expose               constant as 12.
       01 KeyPress             constant as 2.

      *> ExposureMask or-ed with KeyPressMask, from X.h
       01 event-mask           usage binary-c-long value 32769.

      *> make the box around the message wide enough for the font
       01 x-char-struct.
          05 lbearing          usage binary-short.
          05 rbearing          usage binary-short.
          05 string-width      usage binary-short.
          05 ascent            usage binary-short.
          05 descent           usage binary-short.
          05 attributes        usage binary-short unsigned.
       01 font-direction       usage binary-long.
       01 font-ascent          usage binary-long.
       01 font-descent         usage binary-long.

       01 XGContext            usage binary-c-long.
       01 box-width            usage binary-long.
       01 box-height           usage binary-long.

      *> ***************************************************************
       procedure division.

       call "XOpenDisplay" using by reference null returning x-display
           on exception
               display function module-id " Error: "
                       "no XOpenDisplay linkage, requires libX11"
                  upon syserr
               stop run returning 1
       end-call
       if x-display equal null then
           display function module-id " Error: "
                   "XOpenDisplay returned null" upon syserr
           stop run returning 1
       end-if
       set address of x-display-private to x-display

       if screens equal null then
           display function module-id " Error: "
                   "XOpenDisplay associated screen null" upon syserr
           stop run returning 1
       end-if
       set address of x-screen-private to screens

       call "XCreateSimpleWindow" using
           by value x-display root 10 10 200 50 1
                    black-pixel white-pixel
           returning x-window
       call "XStoreName" using
           by value x-display x-window by reference msg

       call "XSelectInput" using by value x-display x-window event-mask

       call "XMapWindow" using by value x-display x-window

       call "XGContextFromGC" using by value default-gc
           returning XGContext
       call "XQueryTextExtents" using by value x-display XGContext
           by reference msg by value msg-len
           by reference font-direction font-ascent font-descent
           x-char-struct
       compute box-width = string-width + 8
       compute box-height = font-ascent + font-descent + 8

       perform forever
          call "XNextEvent" using by value x-display by reference event
          if e-type equal Expose then
              call "XDrawRectangle" using
                  by value x-display x-window default-gc 5 5
                           box-width box-height
              call "XDrawString" using
                  by value x-display x-window default-gc 10 20
                  by reference msg by value msg-len
          end-if
          if e-type equal KeyPress then exit perform end-if
       end-perform

       call "XCloseDisplay" using by value x-display

       goback.
       end program x11-hello.