#if 0
I rewrote the driver according to good sense, my style,
and discussion.

This is file main.c on Autumn 2011 ubuntu linux release.
The emacs compile command output:

-*- mode: compilation; default-directory: "/tmp/" -*-
Compilation started at Mon Mar 12 20:25:27

make -k CFLAGS=-Wall main.o
cc -Wall   -c -o main.o main.c

Compilation finished at Mon Mar 12 20:25:27
#endif

#include <stdio.h>
#include <stdlib.h>

extern int Query(char *Data, unsigned *Length);

int main(int argc, char *argv[]) {
  char Buffer[1024], *pc;
  unsigned Size = sizeof(Buffer);
  if (!Query(Buffer, &Size))
    fputs("failed to call Query", stdout);
  else
    for (pc = Buffer; Size--; ++pc)
      putchar(*pc);
  putchar('\n');
  return EXIT_SUCCESS;
}


#include <string>
using std::string;

// C++ functions with extern "C" can get called from C.
extern "C" int
Query (char *Data, size_t *Length)
{
   const string Message = "Here am I";

   // Check that Message fits in Data.
   if (*Length < Message.length())
      return false;  // C++ converts bool to int.

   *Length = Message.length();
   Message.copy(Data, *Length);
   return true;
}


       identification division.
       program-id. Query.

       environment division.
       configuration section.
       special-names.
           call-convention 0 is extern.

       repository.
           function all intrinsic.

       data division.
       working-storage section.
       01 query-result.
          05 filler value "Here I am".

       linkage section.
       01 data-reference.
          05 data-buffer   pic x occurs 0 to 8192 times
                                 depending on length-reference.
       01 length-reference usage binary-long.

       procedure division extern using data-reference length-reference.

       if length(query-result) less than or equal to length-reference
                           and length-reference less than 8193 then
           move query-result to data-reference
           move length(query-result) to length-reference
           move 1 to return-code
       end-if

       goback.
       end program Query.


import core.stdc.string;

extern(C) bool query(char *data, size_t *length) pure nothrow {
    immutable text = "Here am I";

    if (*length < text.length) {
        *length = 0; // Also clears length.
        return false;
    } else {
        memcpy(data, text.ptr, text.length);
        *length = text.length;
        return true;
    }
}


function Query(Buffer: PChar; var Size: Int64): LongBool;
const
    Text = 'Hello World!';
begin
    If not Assigned(Buffer) Then
    begin
        Size := 0;
        Result := False;
        Exit;
    end;
    If Size < Length(Text) Then
    begin
        Size := 0;
        Result := False;
        Exit;
    end;

    Size := Length(Text);
    Move(Text[1], Buffer^, Size);
    Result := True;
end;


!-----------------------------------------------------------------------
!Function
!-----------------------------------------------------------------------
function  fortran_query(data, length) result(answer) bind(c, name='Query')
   use, intrinsic  :: iso_c_binding, only: c_char, c_int, c_size_t, c_null_char
   implicit none
   character(len=1,kind=c_char), dimension(length),  intent(inout) ::  data
   integer(c_size_t), intent(inout) :: length
   integer(c_int) :: answer
   answer = 0
   if(length<10) return
   data = transfer("Here I am"//c_null_char, data)
   length = 10_c_size_t
   answer = 1
end function fortran_query


#include <stdio.h>
#include "_cgo_export.h"

void Run()
{
   char     Buffer [1024];
   size_t   Size = sizeof (Buffer);

   if (0 == Query (Buffer, &Size))
   ...


#ifdef __GLASGOW_HASKELL__
#include "Called_stub.h"
extern void __stginit_Called(void);
#endif
#include <stdio.h>
#include <HsFFI.h>

int main (int argc, char * argv [])
{
    char     Buffer [1024];
    size_t   Size = sizeof (Buffer);

    hs_init(&argc, &argv);
#ifdef __GLASGOW_HASKELL__
    hs_add_root(__stginit_Called);
#endif

    if (0 == query_hs (Buffer, &Size))
        {
            printf ("failed to call Query\n");
        }
    else
        {
            char * Ptr = Buffer;
            while (Size-- > 0) putchar (*Ptr++);
            putchar ('\n');
        }

    hs_exit();
    return 0;
}


/* Query.java */
public class Query {
    public static boolean call(byte[] data, int[] length)
	throws java.io.UnsupportedEncodingException
    {
	String message = "Here am I";
	byte[] mb = message.getBytes("utf-8");
	if (length[0] < mb.length)
	    return false;
	length[0] = mb.length;
	System.arraycopy(mb, 0, data, 0, mb.length);
	return true;
    }
}


// Kotlin Native v0.6

import kotlinx.cinterop.*
import platform.posix.*

fun query(data: CPointer<ByteVar>, length: CPointer<size_tVar>): Int {
    val s = "Here am I"
    val strLen = s.length
    val bufferSize = length.pointed.value
    if (strLen > bufferSize) return 0  // buffer not large enough
    for (i in 0 until strLen) data[i] = s[i].toByte()
    length.pointed.value = strLen.signExtend<size_t>()
    return 1
}


Section Header

+ name := QUERY;
- external := `#define main _query_main`;
- external := `#define query Query`;

Section External

- query(buffer : NATIVE_ARRAY[CHARACTER], size : NATIVE_ARRAY[INTEGER]) : INTEGER <- (
  + s : STRING_CONSTANT;
  + len, result : INTEGER;
  s := "Here am I";
  len := s.count;
  (len > size.item(0)).if {
    result := 0;
  } else {
    1.to len do { i : INTEGER;
      buffer.put (s @ i) to (i - 1);
    };
    size.put len to 0;
    result := 1;
  };
  result
);

Section Public

- main <- (
  + buffer : NATIVE_ARRAY[CHARACTER];
  + size : NATIVE_ARRAY[INTEGER];
  query(buffer, size); // need this to pull the query() method
);


:- module query.
:- interface.

:- pred query(string::in, string::out) is det.

:- implementation.

query(_, "Hello, world!").

:- pragma foreign_export("C", query(in, out), "query").

:- pragma foreign_decl("C",
"
#include <string.h>
int Query (char * Data, size_t * Length);
").
:- pragma foreign_code("C",
"
int Query (char *Data, size_t *Length) {
    MR_String input, result;
    MR_allocate_aligned_string_msg(input, *Length, MR_ALLOC_ID);
    memmove(input, Data, *Length);
    query(input, &result);
    *Length = strlen(result);
    memmove(Data, result, *Length);
    return 1;
}
").


proc Query*(data: var array[1024, char], length: var cint): cint {.exportc.} =
  const text = "Here am I"
  if length < text.len:
    return 0

  for i in 0 .. text.high:
    data[i] = text[i]
  length = text.len
  return 1


#include <stdio.h>
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>

extern int Query (char * Data, size_t * Length)
{
   static value * closure_f = NULL;
   if (closure_f == NULL) {
       closure_f = caml_named_value("Query function cb");
   }
   value ret = caml_callback(*closure_f, Val_unit);
   *Length = Int_val(Field(ret, 1));
   strncpy(Data, String_val(Field(ret, 0)), *Length);
   return 1;
}

int main (int argc, char * argv [])
{
   char     Buffer [1024];
   unsigned Size = 0;

   caml_main(argv);  /* added from the original main */

   if (0 == Query (Buffer, &Size))
   {
      printf ("failed to call Query\n");
   }
   else
   {
      char * Ptr = Buffer;
      printf("size: %d\n", Size);
      while (Size-- > 0) putchar (*Ptr++);
      putchar ('\n');
   }
}


#include <extensions/embed.h>

#define min(x,y) (x < y ? x : y)

extern unsigned char repl[];
int Query(char *Data, size_t *Length) {
	ol_t ol;
	embed_new(&ol, repl, 0);

	word s = embed_eval(&ol, new_string(&ol,
		"(define sample \"Here am I\")"
		"sample"
	), 0);
	if (!is_string(s))
		goto fail;

	int i = *Length = min(string_length(s), *Length);

	memcpy(Data, string_value(s), i);
	*Length = i;

	OL_free(ol.vm);
	return 1;
fail:
	OL_free(ol.vm);
	return 0;
}


without js -- (peek/poke, call_back)
constant Here_am_I = "Here am I"
function Query(atom pData, pLength)
    integer len = peekNS(pLength,machine_word(),0)
    if poke_string(pData,len,Here_am_I) then
        return 0
    end if
    pokeN(pLength,length(Here_am_I)+1,machine_word())
    return 1
end function
constant Query_cb = call_back(Query)


(let (Str "Here am I"  Len (format (opt)))  # Get length from command line
   (unless (>= (size Str) Len)              # Check buffer size
      (prinl Str) ) )                       # Return string if OK


# store this in file rc_embed.py
# store this in file rc_embed.py
def query(buffer_length):
    message = b'Here am I'
    L = len(message)
    return message[0:L*(L <= buffer_length)]


typedef int strfun (char * Data, size_t * Length);
strfun *Query = NULL;


#!/usr/bin/env raku

sub MAIN (Int :l(:len(:$length))) {
   my Str $String = "Here am I";
   $*OUT.print: $String if $String.codes ≤ $length
}


# query.rb
require 'fiddle'

# Look for a C variable named QueryPointer.
# Raise an error if it is missing.
c_var = Fiddle.dlopen(nil)['QueryPointer']

int = Fiddle::TYPE_INT
voidp = Fiddle::TYPE_VOIDP
sz_voidp = Fiddle::SIZEOF_VOIDP

# Implement the C function
#   int Query(void *data, size_t *length)
# in Ruby code.  Store it in a global constant in Ruby (named Query)
# to protect it from Ruby's garbage collector.
#
Query = Fiddle::Closure::BlockCaller
          .new(int, [voidp, voidp]) do |datap, lengthp|
  message = "Here am I"

  # We got datap and lengthp as Fiddle::Pointer objects.
  # Read length, assuming sizeof(size_t) == sizeof(void *).
  length = lengthp[0, sz_voidp].unpack('J').first

  # Does the message fit in length bytes?
  if length < message.bytesize
    0  # failure
  else
    length = message.bytesize
    datap[0, length] = message  # Copy the message.
    lengthp[0, sz_voidp] = [length].pack('J')  # Update the length.
    1  # success
  end
end

# Set the C variable to our Query.
Fiddle::Pointer.new(c_var)[0, sz_voidp] = [Query.to_i].pack('J')


//! In order to run this task, you will need to compile the C program locating in the task linked
//! above. The C program will need to be linked with the library produced by this file.
//!
//! 1. Compile this library:
//!
//!     ```bash
//!     $ cargo build --release
//!     ```
//!
//! 2. Copy the C program into query.c.
//! 3. Compile and link the C program with the produced library:
//!
//!     ```bash
//!     $ LD_LIBRARY_PATH=/path/to/library gcc query.c -o query -Wall -Werror libquery
//!     ```
//! 4. Run the resulting binary.
//!
//!     ```bash
//!     $ LD_LIBRARY_PATH=/path/to/library ./query
//!     Here am I
//!     ```

#![crate_type = "cdylib"]

extern crate libc;

use std::ffi::CString;

use libc::{c_char, c_int, size_t};

#[no_mangle]
#[allow(non_snake_case)]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn Query(data: *mut c_char, length: *mut size_t) -> c_int {
    let string = "Here am I";
    if *length + 1 < string.len() {
        0
    } else {
        let c_string = CString::new(string).unwrap();
        libc::strcpy(data, c_string.as_ptr());
        *length = string.len();
        1
    }
}


/* Query.scala */
object Query {
  def call(data: Array[Byte], length: Array[Int]): Boolean = {
    val message = "Here am I"
    val mb = message.getBytes("utf-8")
    if (length(0) >= mb.length) {
      length(0) = mb.length
      System.arraycopy(mb, 0, data, 0, mb.length)
      true
    } else false
  }
}


int Query (char * Data, size_t * Length) {
    Tcl_Obj *arguments[2];
    int code;

    arguments[0] = Tcl_NewStringObj("Query", -1); /* -1 for "use up to zero byte" */
    arguments[1] = Tcl_NewStringObj(Data, Length);
    Tcl_IncrRefCount(arguments[0]);
    Tcl_IncrRefCount(arguments[1]);
    if (Tcl_EvalObjv(interp, 2, arguments, 0) != TCL_OK) {
        /* Was an error or other exception; report here... */
        Tcl_DecrRefCount(arguments[0]);
        Tcl_DecrRefCount(arguments[1]);
        return 0;
    }
    Tcl_DecrRefCount(arguments[0]);
    Tcl_DecrRefCount(arguments[1]);
    if (Tcl_GetObjResult(NULL, Tcl_GetObjResult(interp), &code) != TCL_OK) {
        /* Not an integer result */
        return 0;
    }
    return code;
}


#include <stdio.h>

int query(int (*callback)(char *, size_t *))
{
  char buffer[1024];
  size_t size = sizeof buffer;

  if (callback(buffer, &size) == 0) {
    puts("query: callback failed");
  } else {
    char *ptr = buffer;

    while (size-- > 0)
      putchar (*ptr++);
    putchar('\n');
  }
}


/* query.wren */

class RCQuery {
    // Both arguments are lists as we need pass by reference here
    static query(Data, Length) {
        var s = "Here am I"
        var sc = s.count
        if (sc > Length[0]) return 0 // buffer too small
        for (i in 0...sc) Data[i] = s[i].bytes[0]
        Length[0] = sc
        return 1
    }
}


option casemap:none

strlen  proto :qword
strncpy proto :qword, :qword, :dword

Query   proto :qword, :qword

.data
szstr     db "Here am I",0

.code
Query proc Data:qword, len:qword
  local d:qword, l:qword, s:dword

  mov d, Data
  mov l, len
  invoke strlen, addr szstr
  .if rax <= l
    mov s, eax
    invoke strncpy, d, addr szstr, s
    mov eax, s
    mov rax, l
    mov dword ptr [rax], ecx
    mov rax, 1
    ret
  .endif
  mov rax, 0
  ret
Query endp
end


const std = @import("std");

export fn Query(Data: [*c]u8, Length: *usize) callconv(.C) c_int {
    const value = "Here I am";

    if (Length.* >= value.len) {
        @memcpy(@ptrCast([*]u8, Data), value, value.len);
        Length.* = value.len;
        return 1;
    }

    return 0;
}


// query.c
// export zklRoot=/home/ZKL
// clang query.c -I $zklRoot/VM -L $zklRoot/Lib -lzkl -pthread -lncurses -o query
// LD_LIBRARY_PATH=$zklRoot/Lib ./query

#include <stdio.h>
#include <string.h>

#include "zklObject.h"
#include "zklImports.h"
#include "zklClass.h"
#include "zklFcn.h"
#include "zklString.h"

int query(char *buf, size_t *sz)
{
   Instance *r;
   pVM       vm;
   MLIST(mlist,10);

   // Bad practice: not protecting things from the garbage collector

   // build the call parameters: ("query.zkl",False,False,True)
   mlistBuild(mlist,stringCreate("query.zkl",I_OWNED,NoVM),
              BoolFalse,BoolFalse,BoolTrue,ZNIL);
   // Import is in the Vault, a store of useful stuff
   // We want to call TheVault.Import.import("query.zkl",False,False,True)
   //    which will load/compile/run query.zkl
   r = fcnRunith("Import","import",(Instance *)mlist,NoVM);
   // query.zkl is a class with a var that has the query result
   r = classFindVar(r,"query",0,NoVM);  // -->the var contents
   strcpy(buf,stringText(r));     // decode the string into a char *
   *sz = strlen(buf);   // screw overflow checking
   return 1;
}

int main(int argc, char* argv[])
{
   char   buf[100];
   size_t sz = sizeof(buf);

   zklConstruct(argc,argv);	// initialize the zkl shared library
   query(buf,&sz);
   printf("Query() --> \"%s\"\n",buf);

   return 0;
}


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program inputWin64.s   */

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

.equ YPOSTEXTINPUT,   18
.equ LGBUFFER,        50
.equ FONTSIZE,        6
/* constantes X11 */
.equ KeyPressed,    2
.equ ButtonPress, 4
.equ ButtonPress,   4
.equ EnterNotify,   7
.equ LeaveNotify,   8
.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 CWBorderWidth, 1<<4

/* structures descriptions are in end oh this program */

/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szRetourligne:      .asciz  "\n"
szMessErreur:       .asciz "Server X11 not found.\n"
szMessErrfen:       .asciz "Error create X11 window.\n"
szMessErrGC:        .asciz "Error create Graphic Context.\n"
szMessErrButton:    .asciz "Error create button.\n"
szMessErrButtonGC:  .asciz "Error create button Graphic Context.\n"
szMessErrInput:     .asciz "Error create input window.\n"
szMessErrInputGC:   .asciz "Error create input Graphic Context.\n"
//szMessGoodBye:      .asciz "There have been no clicks yet"
szCursor:           .asciz "_"
szTextButton:       .asciz "PUSH"
szMessResult:       .asciz "Text : @ Value @    "
szLibText:          .asciz "Text :"
szLibValue:         .asciz "Value : "

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
qCounterClic:    .skip 8           // counter clic button
//qLongTexte:      .skip 8
//ptZoneS:         .skip 8           // pointeur zone saisie
ptMessage:       .skip 8           // final message pointer
sZoneConv:       .skip 24
wmDeleteMessage: .skip 16          // ident close message
stEvent:         .skip 400         // provisional size

stButton:        .skip BT_fin
buffer:          .skip 500
stInputText:     .skip Input_fin
stInputValue:    .skip Input_fin
stWindowChge:    .skip XWCH_fin
sSaisieCar:      .skip LGBUFFER
sTexteSaisi:     .skip LGBUFFER
sValueSaisi:     .skip LGBUFFER
key:             .skip 4              // code touche
/**********************************************/
/* -- Code section                            */
/**********************************************/
.text
.global main                   // program entry
main:                          // INFO: 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

    ldr x2,[x28,Disp_default_screen] // load default screen
    ldr x1,qAdrqDefScreen
    str x2,[x1]                      //store default_screen
    mov x2,x28
    ldr x0,[x2,Disp_screens]         // screen list
                                     //screen areas
    ldr x5,[x0,Screen_white_pixel]   // white pixel
    ldr x3,[x0,Screen_black_pixel]   // black pixel
    ldr x4,[x0,Screen_root_depth]    // bits par pixel
    ldr x1,[x0,Screen_root]          // 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
    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
                               // authorization of seizures
    mov x0,x28                 // display address
    mov x1,x27                 // window ident
    ldr x2,qFenetreMask        // mask
    bl XSelectInput
    cmp x0,#0
    ble 99f
                               // create Graphic Context
    mov x0,x28                 // display address
    mov x1,x27                 // window ident
    bl createGC                // GC address -> x26
    cbz x0,erreurF
                               // create Graphic Context 1
    mov x0,x28                 // display address
    mov x1,x27                 // window ident
    bl createGC1                // GC address -> x25
    cbz x0,erreurF
                               // Display window
    mov x1,x27                 // ident window
    mov x0,x28                 // Display address
    bl XMapWindow

    ldr x0,qAdrszLibText
    mov x1,x27
    mov x2,5
    mov x3,70
    bl displayText
    ldr x0,qAdrszLibValue
    mov x1,x27
    mov x2,280
    mov x3,70
    bl displayText
    bl createButton            // create button on screen

    bl createInputText         // create input text window

    bl createInputValue        // create input value window

1:                             // events loop
    bl traitEvents
                               // other events
    cbz x0,1b                  // and loop
   //TODO: close ??
    mov x0,0                   // end Ok
    b 100f
    //TODO: close ??

3:
    ldr x0,qAdrstEvent         // events structure address
    bl evtButtonMouse
    b 1b

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
//qAdrszMessGoodBye:   .quad szMessGoodBye
qAdrszLibText:       .quad szLibText
qAdrszLibValue:      .quad szLibValue
qFenetreMask:        .quad  KeyPressMask|ButtonPressMask|StructureNotifyMask|ExposureMask|EnterWindowMask
/********************************************************************/
/*   Events                                                       ***/
/********************************************************************/
traitEvents:                   // INFO: traitEvents
    stp x20,lr,[sp,-16]!       // save  registers
    mov x0,x28                 // Display address
    ldr x1,qAdrstEvent         // events structure address
    bl XNextEvent
    ldr x0,qAdrstEvent         // events structure address
    ldr x1,[x0,#XAny_window]   // what window ?
    cmp x1,x27                 // main window ?
    bne 1f
    bl evtMainWindow           // yes
    b 100f
1:
    ldr x10,qAdrstInputText    // input text window ?
    ldr x11,[x10,Input_adresse]
    cmp x1,x11
    bne 2f
    bl evtInputWindowText
    mov x0,0                   // other events
    b 100f
2:
    ldr x10,qAdrstInputValue   // input value window
    ldr x11,[x10,Input_adresse]
    cmp x1,x11
    bne 3f
    bl evtInputWindowValue
    mov x0,0                   // other events
    b 100f
3:
    ldr x10,[x0,XAny_window]   //  window of event
    ldr x11,qAdrstButton       // load button ident
    ldr x12,[x11,BT_adresse]
    cmp x10,x12                // equal ?
    bne 4f                     // no
    bl evtButton
    mov x0,0                   // other events
    b 100f
4:                             // other windows
    mov x0,0                   // other events
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
/******************************************************************/
/*     main windows events                                     */
/******************************************************************/
/* x0 contains the events */
/* x1 contains the ident Window */
/* x0 return 0 if continue , 1 if program end   */
evtMainWindow:                 // INFO: evtMainWindow
    stp x20,lr,[sp,-16]!       // save  registers
    ldr w0,[x0]                // type in 4 first bytes
    cmp w0,#ClientMessage      // message for close window
    beq 2f                     // yes -> end
    mov x0,0                   // other events
    b 100f                     // and loop
2:
    ldr x0,qAdrstEvent         // events structure address
    ldr x1,[x0,56]             // location message code
    ldr x2,qAdrwmDeleteMessage // equal ?
    ldr x2,[x2]
    mov x0,0
    cmp x1,x2
    bne 100f                   // no loop
    mov x0,1                   // end program
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
/******************************************************************/
/*     input text windows events                                  */
/******************************************************************/
/* x0 contains the events */
/* x1 contains the ident Window */
evtButton:                     // INFO: evtButton
    stp x20,lr,[sp,-16]!       // save  registers
    ldr x10,[x0,#XAny_type]
    cmp x10,ButtonPress
    bne 1f
    bl evtButtonMouse
    b 100f
1:
    cmp x10,#EnterNotify      // mouse is on the button
    bne 2f
    ldr x3,qAdrstWindowChge    // and change window border
    mov x2,3
    str x2,[x3,#XWCH_border_width]
    mov x0,x28                // display
    ldr x2,qFenSMask
    bl XConfigureWindow
    b 100f
2:
    cmp x10,#LeaveNotify      // mouse is off the button
    bne 3f
    ldr x3,qAdrstWindowChge    // and change window border
    mov x2,1
    str x2,[x3,#XWCH_border_width]
    mov x0,x28                // display
    ldr x2,qFenSMask
    bl XConfigureWindow
    b 100f
3:                             // other event
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
/******************************************************************/
/*     input text windows events                                  */
/******************************************************************/
/* x0 contains the events */
/* x1 contains the ident Window */
evtInputWindowText:            // INFO: evtInputWindowText
    stp x20,lr,[sp,-16]!       // save  registers
    ldr x10,[x0,#XAny_type]
    mov x20,x1
    cmp x10,#KeyPressed        // key character ?
    bne 2f
                               // x0 events x1 window ident
    ldr x2,qAdrstInputText
    bl traitImput
    b 100f
2:
    cmp x10,#EnterNotify      // mouse is on the window
    bne 3f
    ldr x0,qAdrstInputText    // display text and cursor
    bl displayInput
    mov x1,x20
    ldr x3,qAdrstWindowChge   // and change window border
    mov x2,3
    str x2,[x3,#XWCH_border_width]
    mov x0,x28                // display
    ldr x2,qFenSMask
    bl XConfigureWindow
    b 100f
3:
    cmp x10,#LeaveNotify      // the mouse is out the window
    bne 4f
    ldr x0,qAdrszCursor       // erase the cursor
    ldr x2,qAdrstInputText
    ldr x2,[x2,Input_cursor]
    mov x10,FONTSIZE
    mul x2,x2,x10
    mov x3,YPOSTEXTINPUT
    bl eraseText1
    mov x1,x20
    ldr x3,qAdrstWindowChge    // and chane window border
    mov x2,1
    str x2,[x3,#XWCH_border_width]
    mov x0,x28                 // display
    ldr x2,qFenSMask
    bl XConfigureWindow
    b 100f
4:                             // other event
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
qFenSMask:   .quad  CWBorderWidth
qAdrstWindowChge:   .quad stWindowChge
/******************************************************************/
/*     input text windows events                                  */
/******************************************************************/
/* x0 contains the events */
/* x1 contains the ident Window */
evtInputWindowValue:           // INFO: evtInputWindowValue
    stp x20,lr,[sp,-16]!       // save  registers
    ldr x10,[x0,#XAny_type]
    mov x20,x1
    cmp x10,#KeyPressed        // cas d'une touche
    bne 2f
                               // x0 events x1 window ident
    ldr x2,qAdrstInputValue
    bl traitImput
    b 100f
2:
    cmp x10,#EnterNotify       // mouse is on the window
    bne 3f
    ldr x0,qAdrstInputValue    // display text and cursor
    bl displayInput
    mov x1,x20
    ldr x3,qAdrstWindowChge    // and change window border
    mov x2,3
    str x2,[x3,#XWCH_border_width]
    mov x0,x28                 // display
    ldr x2,qFenSMask
    bl XConfigureWindow
    b 100f
3:
    cmp x10,#LeaveNotify       // the mouse is out the window
    bne 4f
    ldr x0,qAdrszCursor        // erase the cursor
    ldr x2,qAdrstInputValue
    ldr x2,[x2,Input_cursor]
    mov x10,FONTSIZE
    mul x2,x2,x10
    mov x3,YPOSTEXTINPUT
    bl eraseText1
    mov x1,x20
    ldr x3,qAdrstWindowChge    // and chane window border
    mov x2,1
    str x2,[x3,#XWCH_border_width]
    mov x0,x28                 // display
    ldr x2,qFenSMask
    bl XConfigureWindow
    b 100f
4:                             // other event
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30

/******************************************************************/
/*     traitement Key pressed                                     */
/******************************************************************/
/* x0 contains the event */
/* x1 contains the ident Window */
/* x2 contains address structure window*/
traitImput:                    // INFO: traitImput
    stp x20,lr,[sp,-16]!       // save  registers
    mov x20,x2                 // save structure address
    mov x21,x1                 // save ident window
    ldr x1,qAdrsSaisieCar      // character input buffer
    mov x2,#4                  // buffer lenght
    ldr x3,qAdrkey             // code character
    mov x4,0                   // Specifies or returns the XComposeStatus structure or NULL.
    bl XLookupString
    cmp x0,#1                  // character key ?
    bne 1f
    ldr x0,qAdrsSaisieCar      // input character area
    ldrb w22,[x0]              // load byte
    cmp x22,#13                // enter ?
    beq 1f
    ldr x0,[x20,Input_text]    // erase input area
    mov x1,x21
    mov x2,0
    mov x3,YPOSTEXTINPUT
    bl eraseText1
    ldr x0,qAdrszCursor
    ldr x2,[x20,Input_cursor]  // erase cursor
    mov x1,x21
    mov x10,FONTSIZE           // Font size
    mul x2,x2,x10
    mov x3,YPOSTEXTINPUT
    bl eraseText1
    ldr x13,[x20,Input_text]
    cmp x22,#8                  // back
    beq back
    // voir autre touche
    ldr x4,[x20,Input_cursor]   //
    strb w22,[x13,x4]           // store input character at text end
    add x4,x4,1
    str x4,[x20,Input_cursor]   // maj cursor location
    b suiteaff
back:
    ldr x4,[x20,Input_cursor]   // text size
    sub x4,x4,#1
    str x4,[x20,Input_cursor]   // maj cursor location
suiteaff:
    strb wzr,[x13,x4]           // zero -> text end
    mov x0,x20
    bl displayInput
    b 100f
1:                              // other key
   mov x0,x28
   mov x1,#50
   bl XBell                     // sound on

100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
qAdrsSaisieCar:            .quad sSaisieCar
qAdrkey:                   .quad key
qAdrsTexteSaisi:           .quad sTexteSaisi
/******************************************************************/
/*     create Graphic Context                                     */
/******************************************************************/
/* x0 contains the Display address */
/* x1 contains the ident Window */
createGC:                      // INFO: createGC
    stp x20,lr,[sp,-16]!       // save  registers
    mov x20,x0                 // save display address
    mov x2,#0
    mov x3,#0
    bl XCreateGC
    cbz x0,99f
    mov x26,x0                 // save GC
    mov x0,x20                 // display address
    mov x1,x26
    ldr x2,qRed                // code RGB color
    bl XSetForeground
    cbz x0,99f
    mov x0,x26                 // return GC
    b 100f
99:
    ldr x0,qAdrszMessErrGC
    bl affichageMess
    mov x0,0
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
qAdrszMessErrGC:             .quad szMessErrGC
qRed:                        .quad 0xFF0000
qGreen:                      .quad 0xFF00
qBlue:                       .quad 0xFF
qBlack:                      .quad 0x0
/******************************************************************/
/*     create Graphic Context 1                                    */
/******************************************************************/
/* x0 contains the Display address */
/* x1 contains the ident Window */
createGC1:                     // INFO: createGC1
    stp x20,lr,[sp,-16]!       // save  registers
    mov x20,x0                 // save display address
    mov x2,#0
    mov x3,#0
    bl XCreateGC
    cbz x0,99f
    mov x25,x0                 // save GC
    mov x0,x20                 // display address
    mov x1,x25
    ldr x2,qBlanc              // code RGB color
    bl XSetForeground
    cbz x0,99f
    mov x0,x25                 // return GC1
    b 100f
99:
    ldr x0,qAdrszMessErrGC
    bl affichageMess
    mov x0,0
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
/******************************************************************/
/*     create button on screen                                     */
/******************************************************************/
createButton:                  // INFO: createButton
    stp x21,lr,[sp,-16]!       // save  registers
                               // create button window
    mov x0,x28                 // display address
    mov x1,x27                 // ident window
    mov x2,500                 // X position
    mov x3,50                  // Y position
    mov x4,60                  // weight
    mov x5,30                  // height
    mov x6,1                   // border
    ldr x7,qBlack
    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 99f
    ldr x21,qAdrstButton
    str x0,[x21,BT_adresse]    // save ident button
    str xzr,[x21,BT_cbdata]    // for next use

                              // autorisation des saisies
    mov x0,x28                // display address
    ldr x1,[x21,BT_adresse]   // button address
    ldr x2,qButtonMask        // mask
    bl XSelectInput
                              // create Graphic Contexte of button
    mov x0,x28                // display address
    ldr x1,[x21,BT_adresse]   // button ident
    mov x2,#0
    mov x3,#0
    bl XCreateGC
    cmp x0,#0
    beq 98f
    str x0,[x21,BT_GC]        // store GC
                              // display button
    mov x0,x28                // display address
    ldr x1,[x21,BT_adresse]   // button address
    bl XMapWindow
    ldr x0,qAdrszTextButton   // text address
    ldr x1,[x21,BT_adresse]   // ident button
    mov x2,#18                 // position x
    mov x3,#18                // position y
    bl displayText

    b 100f
98:
    ldr x0,qAdrszMessErrButtonGC
    bl affichageMess
    b 100f
99:
    ldr x0,qAdrszMessErrButton
    bl affichageMess
100:
    ldp x1,lr,[sp],16      // restaur  2 registers
    ret                    // return to address lr x30
qAdrstButton:           .quad stButton
qAdrszTextButton:       .quad szTextButton
qAdrszMessErrButtonGC:  .quad szMessErrButtonGC
qAdrszMessErrButton:    .quad szMessErrButton
qButtonMask:            .quad  ButtonPressMask|ButtonReleaseMask|StructureNotifyMask|ExposureMask|LeaveWindowMask|EnterWindowMask
/******************************************************************/
/*     create window input text                                     */
/******************************************************************/
createInputText:                 // INFO: createInputText
    stp x21,lr,[sp,-16]!         // save  registers
                                 // create button window
    mov x0,x28                   // display address
    mov x1,x27                   // ident window
    mov x2,50                    // X position
    mov x3,50                    // Y position
    mov x4,200                   // weight
    mov x5,30                    // height
    mov x6,1                     // border
    ldr x7,qBlack
    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 99f
    ldr x21,qAdrstInputText
    str x0,[x21,Input_adresse]   // save ident button

                                 // autorisation des saisies
    mov x0,x28                   // display address
    ldr x1,[x21,Input_adresse]   // button address
    ldr x2,qInputMask            // mask
    bl XSelectInput
                                 // create Graphic Contexte of button
    mov x0,x28                   // display address
    ldr x1,[x21,Input_adresse]   // button ident
    mov x2,#0
    mov x3,#0
    bl XCreateGC
    cmp x0,#0
    beq 98f
    str x0,[x21,Input_GC]        // store GC
                                 // display button
    mov x0,x28                   // display address
    ldr x1,[x21,Input_adresse]   // button address
    bl XMapWindow

    ldr x6,qAdrsTexteSaisi

    str x6,[x21,Input_text]
    str xzr,[x21,Input_cursor]

    b 100f
98:
    ldr x0,qAdrszMessErrInputGC
    bl affichageMess
    b 100f
99:
    ldr x0,qAdrszMessErrInput
    bl affichageMess
100:
    ldp x1,lr,[sp],16      // restaur  2 registers
    ret                    // return to address lr x30
qAdrstInputText:           .quad stInputText
qAdrszMessErrInputGC:  .quad szMessErrInputGC
qAdrszMessErrInput:    .quad szMessErrInput
qInputMask:            .quad  KeyPressMask|StructureNotifyMask|ExposureMask|LeaveWindowMask|EnterWindowMask
/******************************************************************/
/*     create window input text                                     */
/******************************************************************/
createInputValue:                // INFO: createInputValue
    stp x21,lr,[sp,-16]!         // save  registers
                                 // create  window
    mov x0,x28                   // display address
    mov x1,x27                   // ident main window
    mov x2,340                    // X position
    mov x3,50                    // Y position
    mov x4,50                   // weight
    mov x5,30                    // height
    mov x6,1                     // border
    ldr x7,qBlack
    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 99f
    ldr x21,qAdrstInputValue
    str x0,[x21,Input_adresse]   // save ident button

                                 // autorisation des saisies
    mov x0,x28                   // display address
    ldr x1,[x21,Input_adresse]   // button address
    ldr x2,qInputMask            // mask
    bl XSelectInput
                                 // create Graphic Contexte of button
    mov x0,x28                   // display address
    ldr x1,[x21,Input_adresse]   // button ident
    mov x2,#0
    mov x3,#0
    bl XCreateGC
    cmp x0,#0
    beq 98f
    str x0,[x21,Input_GC]        // store GC
                                 // display button
    mov x0,x28                   // display address
    ldr x1,[x21,Input_adresse]   // button address
    bl XMapWindow

    ldr x6,qAdrsValueSaisi

    str x6,[x21,Input_text]
    str xzr,[x21,Input_cursor]

    b 100f
98:
    ldr x0,qAdrszMessErrInputGC
    bl affichageMess
    b 100f
99:
    ldr x0,qAdrszMessErrInput
    bl affichageMess
100:
    ldp x1,lr,[sp],16      // restaur  2 registers
    ret                    // return to address lr x30
qAdrstInputValue:       .quad stInputValue
qAdrsValueSaisi:       .quad sValueSaisi
/******************************************************************/
/*     display text on screen                                     */
/******************************************************************/
/* x0 contains the address of text */
/* x1 contains ident window */
/* x2 position X */
/* x3 position Y */
displayText:               // INFO: displayText
    stp x1,lr,[sp,-16]!    // save  registers
    mov x5,x0              // text address
    mov x6,0               // text size
1:                         // loop compute text size
    ldrb w10,[x5,x6]       // load text byte
    cbz x10,2f             // zero -> end
    add x6,x6,1            // increment size
    b 1b                   // and loop
2:
    mov x0,x28             // display address
    mov x4,x3              // position y
    mov x3,x2              // position x
    mov x2,x26             // GC address

    bl XDrawString
100:
    ldp x1,lr,[sp],16      // restaur  2 registers
    ret                    // return to address lr x30
/******************************************************************/
/*     erase text on screen                                     */
/******************************************************************/
/* x0 contains the address of text */
/* x1 window ident */
/* x2 position x */
/* x3 position y */
eraseText1:                // INFO: eraseText1
    stp x1,lr,[sp,-16]!    // save  registers
    mov x5,x0              // text address
    mov x6,0               // text size
1:                         // loop compute text size
    ldrb w10,[x5,x6]       // load text byte
    cbz x10,2f             // zero -> end
    add x6,x6,1            // increment size
    b 1b                   // and loop
2:
    mov x0,x28             // display address
    mov x4,x3
    mov x3,x2
    mov x2,x25             // GC1 address
    bl XDrawString
100:
    ldp x1,lr,[sp],16      // restaur  2 registers
    ret                    // return to address lr x30
/******************************************************************/
/*     events clic mouse button                                      */
/******************************************************************/
/* x0 contains the address of event */
evtButtonMouse:                 // INFO: evtButtonMouse
    stp x20,lr,[sp,-16]!         // save  registers
    ldr x10,[x0,XBE_window]     //  windows of event
    ldr x11,qAdrstButton        // load button ident
    ldr x12,[x11,BT_adresse]
    cmp x10,x12                 // equal ?
    bne 100f                    // no
    ldr x20,qAdrptMessage       // first entry
    ldr x0,[x20]
    cbz x0,1f
    mov x1,x27
    mov x2,50
    mov x3,200
    bl eraseText1                // yes erase the text
1:
    ldr x1,qAdrstInputText       // input text
    ldr x1,[x1,Input_text]
    ldrb w2,[x1]
    cbz w2,100f                 // no input text
    ldr x0,qAdrszMessResult
    bl strInsertAtCharInc       // insert text at @ character
    mov x5,x0
    ldr x1,qAdrstInputValue          // input text
    ldr x0,[x1,Input_text]
    bl conversionAtoD           // conversion value to decimal
                                // x0 contains the input value

    ldr x1,qAdrsZoneConv        // and decimal conversion
    bl conversion10
    mov x0,x5
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc       // and insert result at @ character
    str x0,[x20]                // save message address
    mov x1,x27
    mov x2,50
    mov x3,200
    bl displayText              // and display new text

100:
    ldp x20,lr,[sp],16           // restaur  2 registers
    ret                         // return to address lr x30
qAdrqCounterClic:         .quad qCounterClic
qAdrsZoneConv:            .quad sZoneConv
qAdrszMessResult:         .quad szMessResult
qAdrptMessage:            .quad ptMessage

/******************************************************************/
/*     display input area                                       */
/******************************************************************/
/* x0 contains area structure    */
displayInput:                   // INFO: displayInput
    stp x1,lr,[sp,-16]!         // save  registers
    mov x10,x0                  // save structure
    ldr x0,[x10,Input_text]     //  text
    ldr x6,[x10,Input_cursor]   // position curseur
    cbz x6,1f                   // if zero no text
    mov x0,x28                  // display address
    ldr x1,[x10,Input_adresse]  // ident window
    ldr x2,[x10,Input_GC]       // GC address
    mov x3,0                    // position x
    mov x4,YPOSTEXTINPUT        // position y
    ldr x5,[x10,Input_text]     //  text
    bl XDrawString
1:                              // display cursor
    mov x0,x28                  // Display address
    ldr x1,[x10,Input_adresse]  // ident window
    ldr x2,[x10,Input_GC]       // GC address
    ldr x3,[x10,Input_cursor]   // position x
    mov x10,FONTSIZE
    mul x3,x3,x10
    mov x4,YPOSTEXTINPUT        // position y
    ldr x5,qAdrszCursor         // cursor text
    mov x6,1                    // length
    bl XDrawString
100:
    ldp x1,lr,[sp],16           // restaur  2 registers
    ret                         // return to address lr x30
qAdrszCursor:            .quad szCursor
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
/*******************************************/
/* Structures                              */
/********************************************/
/*************************************************/
/* INFO: Structures  */
/*********************************************/
/* Display définition         */
    .struct  0
Disp_ext_data:                   /* hook for extension to hang data */
    .struct  Disp_ext_data + 8
Disp_private1:
    .struct  Disp_private1 + 8
Disp_fd:                        /* Network socket. */
    .struct  Disp_fd + 4
Disp_private2:
    .struct  Disp_private2 + 4
Disp_proto_major_version:       /* major version of server's X protocol */
    .struct  Disp_proto_major_version + 4
Disp_proto_minor_version:       /* minor version of servers X protocol */
    .struct  Disp_proto_minor_version + 4
Disp_vendor:                    /* vendor of the server hardware  OK*/
    .struct  Disp_vendor + 8
Disp_private3:
    .struct  Disp_private3 + 8
Disp_private8:
    .struct  Disp_private8 + 8
Disp_private5:
    .struct  Disp_private5 + 8
Disp_private6:
    .struct  Disp_private6 + 8
Disp_resource_alloc:
    .struct  Disp_resource_alloc + 8
Disp_byte_order:                 /* screen byte order, LSBFirst, MSBFirst */
    .struct  Disp_byte_order+ 4
Disp_bitmap_unit:                /* padding and data requirements */
    .struct  Disp_bitmap_unit + 4
Disp_bitmap_pad:                 /* padding requirements on bitmaps */
    .struct  Disp_bitmap_pad + 4
Disp_bitmap_bit_order:           /* LeastSignificant or MostSignificant */
    .struct  Disp_bitmap_bit_order + 4
Disp_nformats:                   /* number of pixmap formats in list */
    .struct  Disp_nformats + 8
Disp_pixmap_format:              /* pixmap format list */
    .struct  Disp_pixmap_format + 8
Disp_private28:
    .struct  Disp_private28 + 4
Disp_release:                    /* release of the server */
    .struct  Disp_release + 4
Disp_private9:
    .struct  Disp_private9 + 8
Disp_private10:
    .struct  Disp_private10 + 8
Disp_qlen:                       /* Length of input event queue */
    .struct  Disp_qlen + 8       /* correction dec19 */
Disp_last_request_read:          /* seq number of last event read */
    .struct  Disp_last_request_read + 8
Disp_request:                    /* sequence number of last request. */
    .struct  Disp_request + 8
Disp_private11:
    .struct  Disp_private11 + 8
Disp_private12:
    .struct  Disp_private12 + 8
Disp_private13:
    .struct  Disp_private13 + 8
Disp_private14:
    .struct  Disp_private14 + 8     /* correction Vim */
Disp_max_request_size:            /* maximum number 32 bit words in request*/
    .struct  Disp_max_request_size + 8
Disp_db:
    .struct  Disp_db + 8          /* correction Vim */
Disp_private15:
    .struct  Disp_private15 + 8   /* correction Vim */
Disp_display_name:                /* "host:display" string used on this connect*/
    .struct  Disp_display_name + 8
Disp_default_screen:              /* default screen for operations */
    .struct  Disp_default_screen + 4
Disp_nscreens:                    /* number of screens on this server*/
    .struct  Disp_nscreens + 4
Disp_screens:                     /* pointer to list of screens */
    .struct  Disp_screens + 8
Disp_motion_buffer:               /* size of motion buffer */
    .struct  Disp_motion_buffer + 8
Disp_private16:
    .struct  Disp_private16 + 8
Disp_min_keycode:                 /* minimum defined keycode */
    .struct  Disp_min_keycode + 4
Disp_max_keycode:                 /* maximum defined keycode */
    .struct  Disp_max_keycode + 4
Disp_private17:
    .struct  Disp_private17 + 8
Disp_private18:
    .struct  Disp_private18 + 8
Disp_private19:
    .struct  Disp_private19 + 8
Disp_xdefaults:                   /* contents of defaults from server */
    .struct  Disp_xdefaults + 8
Disp_fin:
/*****************************************/
/* Screen définition                     */
    .struct  0
Screen_ext_data:     /* hook for extension to hang data */
    .struct  Screen_ext_data + 8
Screen_Xdisplay:     /* back pointer to display structure */
    .struct  Screen_Xdisplay + 8
Screen_root:         /* Root window id. */
    .struct  Screen_root + 8
Screen_width:
    .struct  Screen_width + 4
Screen_height:
    .struct  Screen_height + 4
Screen_mwidth:     /* width and height of  in millimeters */
    .struct  Screen_mwidth + 4
Screen_mheight:
    .struct  Screen_mheight + 4
Screen_ndepths:      /* number of depths possible */
    .struct  Screen_ndepths + 8
Screen_depths:     /* list of allowable depths on the screen */
    .struct  Screen_depths + 8
Screen_root_depth:       /* bits per pixel */
    .struct  Screen_root_depth + 8
Screen_root_visual:     /* root visual */
    .struct  Screen_root_visual + 8
Screen_default_gc:     /* GC for the root root visual */
    .struct  Screen_default_gc + 8
Screen_cmap:     /* default color map */
    .struct  Screen_cmap + 8
Screen_white_pixel:
    .struct  Screen_white_pixel + 8
Screen_black_pixel:
    .struct  Screen_black_pixel + 8
Screen_max_maps:     /* max and min color maps */
    .struct  Screen_max_maps + 4
Screen_min_maps:
    .struct  Screen_min_maps + 4
Screen_backing_store:     /* Never, WhenMapped, Always */
    .struct  Screen_backing_store + 8
Screen_save_unders:
    .struct  Screen_save_unders + 8
Screen_root_input_mask:     /* initial root input mask */
    .struct  Screen_root_input_mask + 8
Screen_fin:
/**********************************************/
/* Button structure */
    .struct  0
BT_cbdata:
    .struct BT_cbdata  + 8
BT_adresse:
    .struct BT_adresse + 8
BT_GC:
    .struct BT_GC + 8
BT_Font:
    .struct BT_Font + 8
BT_fin:
/****************************************/
/* Input text structure */
    .struct  0

Input_adresse:
    .struct Input_adresse + 8
Input_GC:
    .struct Input_GC + 8
Input_text:
    .struct Input_text + 8
Input_cursor:
    .struct Input_cursor + 8
Input_Font:
    .struct Input_Font + 8
Input_fin:
/***************************************************/
/* structure XButtonEvent    */
    .struct  0
XBE_type:                          //event type
    .struct XBE_type + 8
XBE_serial:                       // No  last request processed  server */
    .struct XBE_serial + 8
XBE_send_event:                   // true if this came from a SendEvent request */
    .struct XBE_send_event + 8
XBE_display:                      // Display the event was read from
    .struct XBE_display + 8
XBE_window:                       // "event" window it is reported relative to
    .struct XBE_window + 8
XBE_root:                         // root window that the event occurred on
    .struct XBE_root + 8
XBE_subwindow:                    // child window
    .struct XBE_subwindow + 8
XBE_time:                         // milliseconds
    .struct XBE_time + 8
XBE_x:                            // pointer x, y coordinates in event window
    .struct XBE_x + 8
XBE_y:
    .struct XBE_y + 8
XBE_x_root:                       // coordinates relative to root
    .struct XBE_x_root + 8
XBE_y_root:
    .struct XBE_y_root + 8
XBE_state:                        // key or button mask
    .struct XBE_state + 8
XBE_button:                       // detail
    .struct XBE_button + 8
XBE_same_screen:                  // same screen flag
    .struct XBE_same_screen + 8
XBE_fin:
/***************************************************/
/* structure XAnyEvent */
    .struct  0
XAny_type:
    .struct XAny_type + 8
XAny_serial:
    .struct XAny_serial + 8   /* # of last request processed by server */
XAny_send_event:
    .struct XAny_send_event + 8    /* true if this came from a SendEvent request */
XAny_display:
    .struct XAny_display + 8  /* Display the event was read from */
XAny_window:
    .struct XAny_window + 8     /* window on which event was requested in event mask */
Xany_fin:
/****************************************/
/* structure de type   XWindowChanges   */
    .struct  0
XWCH_x:
    .struct XWCH_x + 4
XWCH_y:
    .struct XWCH_y + 4
XWCH_width:
    .struct XWCH_width + 4
XWCH_height:
    .struct XWCH_height + 4
XWCH_border_width:
    .struct XWCH_border_width + 4
XWCH_sibling:
    .struct XWCH_sibling + 4
XWCH_stack_mode:
    .struct XWCH_stack_mode + 4
XWCH_fin:


with Gtk.Button;  use Gtk.Button;
with Gtk.GEntry;  use Gtk.GEntry;
with Gtk.Label;   use Gtk.Label;
with Gtk.Window;  use Gtk.Window;
with Gtk.Widget;  use Gtk.Widget;
with Gtk.Table;   use Gtk.Table;

with Gtk.Handlers;
with Gtk.Main;

procedure Graphic_Input is
   Window  : Gtk_Window;
   Grid    : Gtk_Tnetable;
   Label   : Gtk_Label;
   Message : Gtk_Label;
   Edit    : Gtk_GEntry;
   Button  : Gtk_Button;

   package Handlers is new Gtk.Handlers.Callback (Gtk_Widget_Record);
   package Return_Handlers is
      new Gtk.Handlers.Return_Callback (Gtk_Widget_Record, Boolean);

   function Delete_Event (Widget : access Gtk_Widget_Record'Class)
      return Boolean is
   begin
      return False;
   end Delete_Event;

   procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
   begin
      Gtk.Main.Main_Quit;
   end Destroy;

   procedure Clicked (Widget : access Gtk_Widget_Record'Class) is
   begin
      if Get_Text (Label) = "Enter integer:" then
         Set_Text (Message, "Entered:" & Integer'Image (Integer'Value (Get_Text (Edit))));
         Set_Sensitive (Button, False);
      else
         Set_Text (Message, "Entered:" & Get_Text (Edit));
         Set_Text (Label, "Enter integer:");
      end if;
   exception
      when Constraint_Error =>
         Set_Text (Message, "Error integer input");
   end Clicked;

begin
   Gtk.Main.Init;
   Gtk.Window.Gtk_New (Window);
   Gtk_New (Grid, 2, 3, False);
   Add (Window, Grid);
   Gtk_New (Label, "Enter string:");
   Attach (Grid, Label, 0, 1, 0, 1);
   Gtk_New (Edit);
   Attach (Grid, Edit, 1, 2, 0, 1);
   Gtk_New (Button, "OK");
   Attach (Grid, Button, 2, 3, 0, 1);
   Gtk_New (Message);
   Attach (Grid, Message, 0, 3, 1, 2);
   Return_Handlers.Connect
   (  Window,
      "delete_event",
      Return_Handlers.To_Marshaller (Delete_Event'Access)
   );
   Handlers.Connect
   (  Window,
      "destroy",
      Handlers.To_Marshaller (Destroy'Access)
   );
   Handlers.Connect
   (  Button,
      "clicked",
      Handlers.To_Marshaller (Clicked'Access)
   );
   Show_All (Grid);
   Show (Window);

   Gtk.Main.Main;
end Graphic_Input;


set input to text returned of (display dialog "Enter text:" default answer "")


InputBox, String, Input, Enter a string:
InputBox, Int, Input, Enter an int:
Msgbox, You entered "%String%" and "%Int%"


OPTION GUI TRUE
PRAGMA GUI gtk3

DECLARE text TYPE STRING
DECLARE data TYPE FLOATING

gui = GUIDEFINE(" \
    { type=WINDOW name=window callback=delete-event title=\"Rosetta Code\" width-request=300 } \
    { type=BOX name=box parent=window orientation=GTK_ORIENTATION_VERTICAL } \
    { type=ENTRY name=entry parent=box margin=4 callback=activate } \
    { type=SPIN_BUTTON name=spin parent=box margin=4 numeric=TRUE } \
    { type=BUTTON_BOX name=bbox parent=box } \
    { type=BUTTON name=button parent=bbox margin=4 callback=clicked label=\"Exit\" }")

CALL GUISET(gui, "spin", "adjustment", gtk_adjustment_new(75000, 0, 100000, 1, 1, 0))

REPEAT
    event$ = GUIEVENT$(gui)
UNTIL event$ = "button" OR event$ = "window"

CALL GUIGET(gui, "entry", "text", &text)
PRINT text FORMAT "Entered: %s\n"

CALL GUIGET(gui, "spin", "value", &data)
PRINT data FORMAT "Entered: %g\n"


      INSTALL @lib$+"WINLIB2"
      INSTALL @lib$+"WINLIB5"
      ES_NUMBER = 8192

      form% = FN_newdialog("Rosetta Code", 100, 100, 100, 64, 8, 1000)
      PROC_static(form%, "String:", 100, 8, 8, 30, 14, 0)
      PROC_editbox(form%, "Example", 101, 40, 6, 52, 14, 0)
      PROC_static(form%, "Number:", 102, 8, 26, 30, 14, 0)
      PROC_editbox(form%, "75000", 103, 40, 24, 52, 14, ES_NUMBER)
      PROC_pushbutton(form%, "Read", FN_setproc(PROCread), 30, 43, 40, 16, 0)
      PROC_showdialog(form%)

      REPEAT
        WAIT 1
      UNTIL !form% = 0
      QUIT

      DEF PROCread
      LOCAL buffer%, number%
      DIM buffer% LOCAL 255
      SYS "GetDlgItemText", !form%, 101, buffer%, 255
      SYS "GetDlgItemInt", !form%, 103, 0, 1 TO number%
      PRINT "String = """ $$buffer% """"
      PRINT "Number = " ; number%
      ENDPROC


#include <gtk/gtk.h>

void ok_hit(GtkButton *o, GtkWidget **w)
{
  GtkMessageDialog *msg;

  gdouble v = gtk_spin_button_get_value((GtkSpinButton *)w[1]);
  const gchar *c = gtk_entry_get_text((GtkEntry *)w[0]);

  msg = (GtkMessageDialog *)
    gtk_message_dialog_new(NULL,
			   GTK_DIALOG_MODAL,
			   (v==75000) ? GTK_MESSAGE_INFO : GTK_MESSAGE_ERROR,
			   GTK_BUTTONS_OK,
			   "You wrote '%s' and selected the number %d%s",
			   c, (gint)v,
			   (v==75000) ? "" : " which is wrong (75000 expected)!");
  gtk_widget_show_all(GTK_WIDGET(msg));
  (void)gtk_dialog_run(GTK_DIALOG(msg));
  gtk_widget_destroy(GTK_WIDGET(msg));
  if ( v==75000 ) gtk_main_quit();
}

int main(int argc, char **argv)
{
  GtkWindow *win;
  GtkEntry *entry;
  GtkSpinButton *spin;
  GtkButton *okbutton;
  GtkLabel *entry_l, *spin_l;
  GtkHBox *hbox[2];
  GtkVBox *vbox;
  GtkWidget *widgs[2];

  gtk_init(&argc, &argv);

  win = (GtkWindow *)gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(win, "Insert values");

  entry_l = (GtkLabel *)gtk_label_new("Insert a string");
  spin_l =  (GtkLabel *)gtk_label_new("Insert 75000");

  entry = (GtkEntry *)gtk_entry_new();
  spin = (GtkSpinButton *)gtk_spin_button_new_with_range(0, 80000, 1);

  widgs[0] = GTK_WIDGET(entry);
  widgs[1] = GTK_WIDGET(spin);

  okbutton = (GtkButton *)gtk_button_new_with_label("Ok");

  hbox[0] = (GtkHBox *)gtk_hbox_new(FALSE, 1);
  hbox[1] = (GtkHBox *)gtk_hbox_new(FALSE, 1);

  vbox = (GtkVBox *)gtk_vbox_new(TRUE, 1);

  gtk_container_add(GTK_CONTAINER(hbox[0]), GTK_WIDGET(entry_l));
  gtk_container_add(GTK_CONTAINER(hbox[0]), GTK_WIDGET(entry));
  gtk_container_add(GTK_CONTAINER(hbox[1]), GTK_WIDGET(spin_l));
  gtk_container_add(GTK_CONTAINER(hbox[1]), GTK_WIDGET(spin));

  gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(hbox[0]));
  gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(hbox[1]));
  gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(okbutton));

  gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(vbox));

  g_signal_connect(G_OBJECT(win), "delete-event", (GCallback)gtk_main_quit, NULL);
  g_signal_connect(G_OBJECT(okbutton), "clicked", (GCallback)ok_hit, widgs);

  gtk_widget_show_all(GTK_WIDGET(win));
  gtk_main();

  return 0;
}


(import 'javax.swing.JOptionPane)
(let [number (-> "Enter an Integer"
                 JOptionPane/showInputDialog
                 Integer/parseInt)
      string (JOptionPane/showInputDialog "Enter a String")]
  [number string])


(capi:prompt-for-string "Enter a string:")


import 'package:flutter/material.dart';

main() => runApp( OutputLabel() );

class OutputLabel extends StatefulWidget {
  @override
  _OutputLabelState createState() => _OutputLabelState();
}

class _OutputLabelState extends State<OutputLabel> {
  String output = "output"; // This will be displayed in an output text field

  TextEditingController _stringInputController = TextEditingController(); // Allows us to get the text from a text field
  TextEditingController _numberInputController = TextEditingController();

  @override
  Widget build( BuildContext context ) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, // Disable debug banner in top right
      home: Scaffold ( // Scaffold provides a layout for the app
        body: Center ( // Everything in the center widget will be centered
          child: Column ( // All the widgets will be in a column
            children: <Widget> [
              SizedBox( height: 25 ), // Space between top and text field

              TextField ( // String input Text Field
                controller: _stringInputController, // Add input controller so we can grab text
                textAlign: TextAlign.center, // Center text
                decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Enter a string...'), // Border and default text
              ), // end TextField

              SizedBox( height: 10 ), // Space between text fields

              TextField ( // Number input Text Field
                controller: _numberInputController, // Add input controller so we can grab text
                textAlign: TextAlign.center, // Center text
                decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Enter 75000'), // Border and default text
              ), // end TextField

              FlatButton ( // Submit Button
                child: Text('Submit Data'), // Button Text
                color: Colors.blue[400] // button color
                onPressed: () { // On pressed Callback for button
                  setState( () {
                    output = ''; // Reset output

                    int number; // Int to store number in

                    var stringInput = _stringInputController.text ?? ''; // Get the input from the first field, if it is null set it to an empty string

                    var numberString = _numberInputController.text ?? ''; // Get the input from the second field, if it is null set it to an empty string

                    if ( stringInput == '')  { // If first field is empty
                      output = 'Please enter something in field 1\n';
                      return;
                    }

                    if (_numberInputController.text == '') { // If second field is empty
                      output += 'Please enter something in field 2';
                      return;
                    } else { // If we got an input in the second field

                      try {
                        number = int.parse( numberString ); // Parse numberString into an int

                        if ( number == 75000 )
                          output = 'text output: $stringInput\nnumber: $number'; // Grabs the text from the input controllers and changes the string
                        else
                          output = '$number is not 75000!';

                      } on FormatException { // If a number is not entered in second field
                          output = '$numberString is not a number!';
                      }

                    }

                  });
                }
              ), // End FlatButton

              Text( output ) // displays output

            ]
          )
        )
      )
    );
  }
}


program UserInputGraphical;

{$APPTYPE CONSOLE}

uses SysUtils, Dialogs;

var
  s: string;
  lStringValue: string;
  lIntegerValue: Integer;
begin
  lStringValue := InputBox('User input/Graphical', 'Enter a string', '');

  repeat
    s := InputBox('User input/Graphical', 'Enter the number 75000', '75000');
    lIntegerValue := StrToIntDef(s, 0);
    if lIntegerValue <> 75000 then
      ShowMessage('Invalid entry: ' + s);
  until lIntegerValue = 75000;
end.


s = input["Enter a string: "]
i = parseInt[input["Enter an integer: "]]


hTextBox As TextBox
hValueBox As ValueBox
hLabel As Label

Public Sub Form_Open()

With Me
  .Height = 100
  .Width = 300
  .padding = 5
  .Arrangement = Arrange.Vertical
  .Title = "User input/Graphical"
End With

hTextBox = New TextBox(Me) As "TextBox1"
hTextBox.Expand = True

hValueBox = New ValueBox(Me) As "ValueBox1"
hValueBox.Expand = True

hLabel = New Label(Me)
hLabel.expand = True

End

Public Sub TextBox1_Change()

hLabel.text = hTextBox.Text & " - " & Str(hValueBox.value)

End

Public Sub valueBox1_Change()

TextBox1_Change

End


package main

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

func validateInput(window *gtk.Window, str1, str2 string) bool {
    n, err := strconv.ParseFloat(str2, 64)
    if len(str1) == 0 || err != nil || n != 75000 {
        dialog := gtk.MessageDialogNew(
            window,
            gtk.DIALOG_MODAL,
            gtk.MESSAGE_ERROR,
            gtk.BUTTONS_OK,
            "Invalid input",
        )
        dialog.Run()
        dialog.Destroy()
        return false
    }
    return true
}

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

func main() {
    rand.Seed(time.Now().UnixNano())
    gtk.Init(nil)

    window, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
    check(err, "Unable to create window:")
    window.SetTitle("Rosetta Code")
    window.SetPosition(gtk.WIN_POS_CENTER)
    window.Connect("destroy", func() {
        gtk.MainQuit()
    })

    vbox, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 1)
    check(err, "Unable to create vertical box:")
    vbox.SetBorderWidth(1)

    hbox1, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 1)
    check(err, "Unable to create first horizontal box:")

    hbox2, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 1)
    check(err, "Unable to create second horizontal box:")

    label, err := gtk.LabelNew("Enter a string and the number 75000   \n")
    check(err, "Unable to create label:")

    sel, err := gtk.LabelNew("String:      ")
    check(err, "Unable to create string entry label:")

    nel, err := gtk.LabelNew("Number: ")
    check(err, "Unable to create number entry label:")

    se, err := gtk.EntryNew()
    check(err, "Unable to create string entry:")

    ne, err := gtk.EntryNew()
    check(err, "Unable to create number entry:")

    hbox1.PackStart(sel, false, false, 2)
    hbox1.PackStart(se, false, false, 2)

    hbox2.PackStart(nel, false, false, 2)
    hbox2.PackStart(ne, false, false, 2)

    // button to accept
    ab, err := gtk.ButtonNewWithLabel("Accept")
    check(err, "Unable to create accept button:")
    ab.Connect("clicked", func() {
        // read and validate the entered values
        str1, _ := se.GetText()
        str2, _ := ne.GetText()
        if validateInput(window, str1, str2) {
            window.Destroy() // close window if input is OK
        }
    })

    vbox.Add(label)
    vbox.Add(hbox1)
    vbox.Add(hbox2)
    vbox.Add(ab)
    window.Add(vbox)

    window.ShowAll()
    gtk.Main()
}


import javax.swing.JOptionPane

def number = JOptionPane.showInputDialog ("Enter an Integer") as Integer
def string = JOptionPane.showInputDialog ("Enter a String")

assert number instanceof Integer
assert string instanceof String


import Graphics.UI.Gtk
import Control.Monad

main = do
  initGUI

  window <- windowNew
  set window [windowTitle := "Graphical user input", containerBorderWidth := 10]

  vb <- vBoxNew False 0
  containerAdd window vb

  hb1 <- hBoxNew False 0
  boxPackStart vb hb1 PackNatural 0
  hb2 <- hBoxNew False 0
  boxPackStart vb hb2 PackNatural 0

  lab1 <- labelNew (Just "Enter number 75000")
  boxPackStart hb1 lab1 PackNatural 0
  nrfield <- entryNew
  entrySetText nrfield "75000"
  boxPackStart hb1 nrfield PackNatural 5

  strfield <- entryNew
  boxPackEnd hb2 strfield PackNatural 5
  lab2 <- labelNew (Just "Enter a text")
  boxPackEnd hb2 lab2 PackNatural 0

  accbox    <- hBoxNew False 0
  boxPackStart vb accbox PackNatural 5
  im <- imageNewFromStock stockApply IconSizeButton
  acceptButton <- buttonNewWithLabel "Accept"
  buttonSetImage acceptButton im
  boxPackStart accbox acceptButton PackRepel 0

  txtstack <- statusbarNew
  boxPackStart vb txtstack PackNatural 0
  id <- statusbarGetContextId txtstack "Line"

  widgetShowAll window

  onEntryActivate nrfield (showStat nrfield txtstack id)
  onEntryActivate strfield (showStat strfield txtstack id)

  onPressed acceptButton $ do
    g <- entryGetText nrfield
    if g=="75000" then
      widgetDestroy window
     else do
       msgid <- statusbarPush txtstack id "You didn't enter 75000. Try again"
       return ()

  onDestroy window mainQuit
  mainGUI

showStat :: Entry -> Statusbar -> ContextId -> IO ()
showStat fld stk id = do
    txt <- entryGetText fld
    let mesg = "You entered \"" ++ txt ++ "\""
    msgid <- statusbarPush stk id mesg
    return ()


CHARACTER string*100

DLG(Edit=string, Edit=num_value, Button='&OK', TItle='Enter 75000 for num_value')
WRITE(Messagebox, Name) "You entered", string, num_value


procedure main()
WOpen("size=800,800") | stop("Unable to open window")
WWrite("Enter a string:")
s := WRead()
WWrite("You entered ",image(s))
WWrite("Enter the integer 75000:")
i := WRead()
if i := integer(i) then
   WWrite("You entered: ",i)
else
   WWrite(image(i)," isn't an integer")
WDone()
end

link graphics


SIMPLEGUI=: noun define
pc simpleGui;
cc IntegerLabel static;cn "Enter the integer 75000";
cc integer edit;
cc TextLabel static;cn "Enter text";
cc text edit;
cc accept button;cn "Accept";
pshow;
)

simpleGui_run=: wd bind SIMPLEGUI
simpleGui_close=: wd bind 'pclose'
simpleGui_cancel=: simpleGui_close

simpleGui_accept_button=: verb define
  ttxt=. text
  tint=. _". integer
  if. tint ~: 75000 do.
    wdinfo 'Integer entered was not 75000.'
  else.
    simpleGui_close ''
   'simpleGui_text simpleGui_integer'=: ttxt;tint
  end.
)

simpleGui_run''


import javax.swing.*;

public class GetInputSwing {
    public static void main(String[] args) throws Exception {
        int number = Integer.parseInt(
                JOptionPane.showInputDialog ("Enter an Integer"));
        String string = JOptionPane.showInputDialog ("Enter a String");
    }
}


var str = prompt("Enter a string");
var value = 0;
while (value != 75000) {
    value = parseInt( prompt("Enter the number 75000") );
}


using Gtk

function twoentrywindow()
    txt = "Enter Text Here"
    txtchanged = false

    win = GtkWindow("Keypress Test", 500, 100) |> (GtkFrame() |> (vbox = GtkBox(:v)))
    lab = GtkLabel("Enter some text in the first box and 7500 into the second box.")
    txtent = GtkEntry()
    set_gtk_property!(txtent,:text,"Enter Some Text Here")
    nument = GtkEntry()
    set_gtk_property!(nument,:text,"Enter the number seventy-five thousand here")
    push!(vbox, lab, txtent, nument)

    function keycall(w, event)
        strtxt = get_gtk_property(txtent, :text, String)
        numtxt = get_gtk_property(nument, :text, String)
        if strtxt != txt && occursin("75000", numtxt)
            set_gtk_property!(lab, :label, "You have accomplished the task.")
        end
    end
    signal_connect(keycall, win, "key-press-event")

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

twoentrywindow()


// version 1.1

import javax.swing.JOptionPane

fun main(args: Array<String>) {
    do {
        val number = JOptionPane.showInputDialog("Enter 75000").toInt()
    } while (number != 75000)
}


'   [RC] User input/graphical

    '   Typical LB graphical input/output example.This shows how LB takes user input.
    '   You'd usually do more validating of input.

    nomainwin   '   No console window needed.

    textbox#w.tb1, 100, 20, 200, 30
    textbox#w.tb2, 100, 60, 200, 30
    textbox#w.tb3, 100,160, 200, 30

    statictext #w.st1, "String  =", 10, 30, 90, 30
    statictext #w.st2, "Integer =", 10, 70, 90, 30

    button #w.b1, "Read and Show", [buttonClicked], LR, 180,  70

    WindowWidth  =360
    WindowHeight =240
    UpperLeftX   = 40
    UpperLeftY   = 40

    open "User input of integer & string" for window as #w

    #w "trapclose [quit]"       '   Clean exit routine.
    #w.tb1 "!font courier 12"
    #w.tb2 "!font courier 12"
    #w.tb3 "!font courier 12 bold"
    #w.st1 "!font courier 12"
    #w.st2 "!font courier 12"

    #w.tb1 "Change this string."
    #w.tb2 "Enter an integer here."
    #w.tb3 "Display will be here."

    #w.tb1 "!selectall"

    wait

  [buttonClicked]   '   Button-clicked routine collects data
    #w.tb1 "!contents? in1$"
    #w.tb2 "!contents? in2$"
    #w.tb3 in1$; "   "; int( val( in2$))
    wait

  [quit]
    close #w
    end


Module CheckIt {
      Def aName$="No Name", Num$
      \\ we open a new stack, and hold old
      Stack New {
            If Ask$("Give your name:",,,,,aName$)="OK" Then Read aName$
            If Ask$("Give a Number: (75000)",,,,,"")="OK" Then Read Num$
            if  Num$<>"75000" or aName$="" Then loop
      }
      \ now old stack came back
      Print Num$, aName$
      Print Letter$    \\ Letter$ pop a string from stack
}
CheckIt "Thank You"


str = InputString["Input a string"]; nb =
 InputString["Input a number"]; Print[str, " " , [email protected]]


import Nanoquery.Util.Windows

// a function to handle the main window closing
def finish(caller, event)
	exit
end

// create a window
w = new(Window, "Input").setTitle("Input")
w.setSize(320, 190)
w.setHandler(w.closing, finish)

// create two labels to go next to the input boxes
stringlabel = new(Label).setParent(w)
intlabel    = new(Label).setParent(w)

stringlabel.setText("String: "); stringlabel.setPosition(20, 25)
intlabel.setText("Integer: "); intlabel.setPosition(20, 75)

// create two textboxes for input
stringbox = new(Textbox).setParent(w)
intbox    = new(Textbox).setParent(w)

stringbox.setPosition(100, 20); stringbox.setWidth(200); stringbox.setHeight(30)
intbox.setPosition(100, 70); intbox.setWidth(200); intbox.setHeight(30)

// a function that handles when the 'done' button is clicked
def done_clicked(caller, event)
	global stringbox
	global intbox
	global w

	s = stringbox.getText()
	i = intbox.getText()

	try
		if int(i) = 75000
			println "String:  " + s
			println "Integer: " + i
			exit
		else
			w.showMessageBox("Please enter 75000 for the integer value")
		end
	catch
		w.showMessageBox("Please enter 75000 for the integer value")
	end
end

// create the 'done' button
done = new(Button).setParent(w)

done.setText("Done"); done.setPosition(250,120)
done.setHandler(done.clicked, done_clicked)

// display the window
w.show()


/* NetRexx */
options replace format comments java crossref symbols nobinary
import javax.swing.JOptionPane

unumber = 0
ustring = ''

do
  unumber = Integer.parseInt(JOptionPane.showInputDialog("Enter an Integer"))
  ustring = JOptionPane.showInputDialog("Enter a String")
catch ex = Exception
  ex.printStackTrace
end

unumber = unumber * 1.0 -- just to prove unumber is really a number
say 'Number:' unumber.right(10)', String:' ustring

return


; file:   input-gui.lsp
; url:    http://rosettacode.org/wiki/User_input/Graphical
; author: oofoe 2012-02-02

; Colours
(setq  ok '(.8 1 .8)  fail '(1 .5 .5))

; Load library and initialize GUI server:
(load (append (env "NEWLISPDIR") "/guiserver.lsp"))
(gs:init)

; Validation Callback

; There is a bug in the "gs:get-text" function that causes it to fail
; silently if the text field is empty. Therfore, I set the field
; background to red first and only clear it if the field returns
; correctly.
(define (validate)
  (gs:set-color 'string fail)
  (if (not (empty? (gs:get-text 'string)))
      (gs:set-color 'string ok))

  (gs:set-color 'number fail)
  (if (= 75000 (int (gs:get-text 'number)))
      (gs:set-color 'number ok))
  )

; Create main window frame and set layout.
(gs:frame 'main 100 100 256 128 "User Input/Graphical")
(gs:set-flow-layout 'main "left" 4 4)

; Create and add widgets.
(gs:label 'instructions "Please enter a string and the number 75000:")
(gs:text-field 'string 'validate 32)
(gs:text-field 'number 'validate 8)
(gs:button 'check 'validate "validate...")
(gs:add-to 'main 'instructions 'string 'number 'check)

; Show main window.
(gs:set-visible 'main true)

; Start event loop.
(gs:listen)

; No (exit) needed -- guiserver kills program on window close.


import strutils
import gintro/[glib, gobject, gtk, gio]

type MainWindow = ref object of ApplicationWindow
  strEntry: Entry
  intEntry: SpinButton

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

proc displayValues(strval: string; intval: int) =
  ## Display a dialog window with the values entered by the user.

  let dialog = newDialog()
  dialog.setModal(true)
  let label1 = newLabel(" String value is “$1”.".format(strval))
  label1.setHalign(Align.start)
  dialog.contentArea.packStart(label1, true, true, 5)
  let msg = " Integer value is $1 which is ".format(intval) &
            (if intval == 75000: "right. " else: "wrong (expected 75000). ")
  let label2 = newLabel(msg)
  dialog.contentArea.packStart(label2, true, true, 5)
  discard dialog.addButton("OK", ord(ResponseType.ok))
  dialog.showAll()
  discard dialog.run()
  dialog.destroy()

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

proc onOk(button: Button; window: MainWindow) =
  ## Callback executed when the OK button has been clicked.
  let strval = window.strEntry.text()
  let intval = window.intEntry.value().toInt
  displayValues(strval, intval)
  if intval == 75_000:
    window.destroy()

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

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

  let window = newApplicationWindow(MainWindow, app)
  window.setTitle("User input")

  let content = newBox(Orientation.vertical, 10)
  content.setHomogeneous(true)
  let grid = newGrid()
  grid.setColumnSpacing(30)
  let bbox = newButtonBox(Orientation.horizontal)
  bbox.setLayout(ButtonBoxStyle.spread)

  let strLabel = newLabel("Enter some text")
  strLabel.setHalign(Align.start)
  window.strEntry = newEntry()
  grid.attach(strLabel, 0, 0, 1, 1)
  grid.attach(window.strEntry, 1, 0, 1, 1)

  let intLabel = newLabel("Enter 75000")
  intLabel.setHalign(Align.start)
  window.intEntry = newSpinButtonWithRange(0, 80_000, 1)
  grid.attach(intLabel, 0, 1, 1, 1)
  grid.attach(window.intEntry, 1, 1, 1, 1)

  let btnOk = newButton("OK")

  bbox.add(btnOk)

  content.packStart(grid, true, true, 0)
  content.packEnd(bbox, true, true, 0)

  window.setBorderWidth(5)
  window.add(content)

  discard btnOk.connect("clicked", onOk, window)

  window.showAll()

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

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


functor
import
   Application
   QTk at 'x-oz://system/wp/QTk.ozf'
   System
define
   Number NumberWidget
   Text
   StatusLabel
   WindowClosed
   GUI = td(action:OnClose
	    return:WindowClosed
	    lr(label(text:"Enter some text:" width:20)
	       entry(return:Text glue:ew)
	      glue:ew)
	    lr(label(text:"Enter a number:" width:20)
	       numberentry(max:100000 return:Number handle:NumberWidget)
	       label(handle:StatusLabel width:20)
	       glue:ew
	      )
	    button(text:"Ok" glue:ew
		   action:OnClose
		  )
	   )
   proc {OnClose}
      if {NumberWidget get($)} \= 75000 then
	 {StatusLabel set(text:"Invalid value")}
      else
	 {Window close}
      end
   end
   Window = {QTk.build GUI}
   {Window show}
   {Wait WindowClosed}
   {System.showInfo "You entered; "#Text#", "#Number}
   {Application.exit 0}
end


use Wx;

package MyApp;
use base 'Wx::App';
use Wx qw(wxHORIZONTAL wxVERTICAL wxALL wxALIGN_CENTER);
use Wx::Event 'EVT_BUTTON';

our ($frame, $text_input, $integer_input);

sub OnInit
   {$frame = new Wx::Frame
       (undef, -1, 'Input window', [-1, -1], [250, 150]);

    my $panel = new Wx::Panel($frame, -1);
    $text_input = new Wx::TextCtrl($panel, -1, '');
    $integer_input = new Wx::SpinCtrl
       ($panel, -1, '', [-1, -1], [-1, -1],
        0, 0, 100_000);

    my $okay_button = new Wx::Button($panel, -1, 'OK');
    EVT_BUTTON($frame, $okay_button, \&OnQuit);

    my $sizer = new Wx::BoxSizer(wxVERTICAL);
    $sizer->Add($_, 0, wxALL | wxALIGN_CENTER, 5)
        foreach $text_input, $integer_input, $okay_button;
    $panel->SetSizer($sizer);

    $frame->Show(1);}

sub OnQuit
   {print 'String: ', $text_input->GetValue, "\n";
    print 'Integer: ', $integer_input->GetValue, "\n";
    $frame->Close;}

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

package main;

MyApp->new->MainLoop;


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

Ihandle dlg, label1, input1, label2, input2, OK, Cancel

function ok_cb(Ihandle self)
    if self=OK then
        string in1 = IupGetAttribute(input1,"VALUE")
        integer in2 = IupGetInt(input2,"VALUE")
        string msg = sprintf(`"%s" and %d`,{in1,in2})
        IupMessage("You entered",msg)
        -- (return IUP_CONTINUE if unhappy with input)
    end if
    return IUP_CLOSE
end function

IupOpen()
label1 = IupLabel("Please enter a string")
input1 = IupText(`VALUE="a string", EXPAND=HORIZONTAL`)
label2 = IupLabel("and the number 75000")
input2 = IupText("VALUE=75000, EXPAND=HORIZONTAL, MASK="&IUP_MASK_INT)
OK     = IupButton("OK", "ACTION", Icallback("ok_cb"))
Cancel = IupButton("Cancel", "ACTION", Icallback("ok_cb"))
sequence buttons = {IupFill(),OK,Cancel,IupFill()}
Ihandle strbox = IupHbox({label1,input1},"ALIGNMENT=ACENTER, PADDING=5"),
        numbox = IupHbox({label2,input2},"ALIGNMENT=ACENTER, PADDING=5"),
        btnbox = IupHbox(buttons,"PADDING=40"),
        vbox = IupVbox({strbox, numbox, btnbox}, "MARGIN=5x5")
if platform()!=JS then
    IupSetAttribute(btnbox,"NORMALIZESIZE","BOTH")
    IupSetAttribute(vbox,"GAP","5")
end if
dlg = IupDialog(vbox, `TITLE="User Input/Graphical"`)
IupShow(dlg)
if platform()!=JS then
    IupMainLoop()
    IupClose()
end if


(and
   (call 'sh "-c"
      (pack
         "dialog \
            --inputbox 'Input a string' 8 60 \
            --inputbox 'Input a number' 8 20 \
            2>"
         (tmp "dlg") ) )
   (split (in (tmp "dlg") (line)) "^I")
   (cons (pack (car @)) (format (cadr @))) )


FUNCTION PBMAIN () AS LONG
    result$ = INPUTBOX$("Enter a string.")
    MSGBOX result$
    DO
        'This assumes that 75000 is the ONLY valid input.
        result$ = INPUTBOX$("Enter the number 75000.")
        IF VAL(result$) <> 75000 THEN
            MSGBOX "You need to enter 75000!"
        ELSE
            MSGBOX "You entered the right number."
            EXIT DO
        END IF
    LOOP
END FUNCTION


#region Define the Windows Form
[Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$Form1 = New-Object System.Windows.Forms.Form
$label1 = New-Object System.Windows.Forms.Label
$label2 = New-Object System.Windows.Forms.Label
$txtInputText = New-Object System.Windows.Forms.TextBox
$txtInputNumber = New-Object System.Windows.Forms.TextBox
$btnAccept = New-Object System.Windows.Forms.Button
$label3 = New-Object System.Windows.Forms.Label
$btnCancel = New-Object System.Windows.Forms.Button
$SuspendLayout
#
# label1
#
$label1.AutoSize = $true
$label1.Location = New-Object System.Drawing.Point(23, 36)
$label1.Name = "label1"
$label1.Size = New-Object System.Drawing.Size(34, 13)
$label1.TabIndex = 0
$label1.Text = "String"
#
# label2
#
$label2.AutoSize = $true
$label2.Location = New-Object System.Drawing.Point(13, 62)
$label2.Name = "label2"
$label2.Size = New-Object System.Drawing.Size(44, 13)
$label2.TabIndex = 1
$label2.Text = "Number"
#
# txtInputText
#
$txtInputText.Location = New-Object System.Drawing.Point(63, 33)
$txtInputText.Name = "txtInputText"
$txtInputText.Size = New-Object System.Drawing.Size(100, 20)
$txtInputText.TabIndex = 0
#
# txtInputNumber
#
$txtInputNumber.Location = New-Object System.Drawing.Point(63, 59)
$txtInputNumber.Name = "txtInputNumber"
$txtInputNumber.Size = New-Object System.Drawing.Size(100, 20)
$txtInputNumber.TabIndex = 1
$txtInputNumber.Text = "75000"
#
# btnAccept
#
$btnAccept.DialogResult = [System.Windows.Forms.DialogResult]::OK
$btnAccept.Location = New-Object System.Drawing.Point(16, 94)
$btnAccept.Name = "btnAccept"
$btnAccept.Size = New-Object System.Drawing.Size(75, 23)
$btnAccept.TabIndex = 2
$btnAccept.Text = "Accept"
$btnAccept.UseVisualStyleBackColor = $true
$btnAccept.add_Click({$rc="Accept"; $Form1.Close()})
#
# label3
#
$label3.AutoSize = $true
$label3.Location = New-Object System.Drawing.Point(13, 9)
$label3.Name = "label3"
$label3.Size = New-Object System.Drawing.Size(173, 13)
$label3.TabIndex = 5
$label3.Text = "Please input a string and a number:"
#
# btnCancel
#
$btnCancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$btnCancel.Location = New-Object System.Drawing.Point(97, 94)
$btnCancel.Name = "btnCancel"
$btnCancel.Size = New-Object System.Drawing.Size(75, 23)
$btnCancel.TabIndex = 3
$btnCancel.Text = "Cancel"
$btnCancel.UseVisualStyleBackColor = $true
#
# Form1
#
$Form1.AcceptButton = $btnAccept
$Form1.CancelButton = $btnCancel
$Form1.ClientSize = New-Object System.Drawing.Size(196, 129)
$Form1.ControlBox = $false
$Form1.Controls.Add($btnCancel)
$Form1.Controls.Add($label3)
$Form1.Controls.Add($btnAccept)
$Form1.Controls.Add($txtInputNumber)
$Form1.Controls.Add($txtInputText)
$Form1.Controls.Add($label2)
$Form1.Controls.Add($label1)
$Form1.Name = "Form1"
$Form1.Text = "RosettaCode"

#endregion Define the Windows Form

### Show the input form
$f = $Form1.ShowDialog()
if ( $f -eq [System.Windows.Forms.DialogResult]::Cancel ) { "User selected Cancel" }
else { "User entered `"{0}`" for the text and {1} for the number" -f $txtInputText.Text, $txtInputNumber.Text }


import javax.swing.JOptionPane;

int number = int(JOptionPane.showInputDialog ("Enter an Integer"));
println(number);

String string = JOptionPane.showInputDialog ("Enter a String");
println(string);


string$=InputRequester("Some Title","Enter a string","")
variable=Val(InputRequester("Some other Title","Enter a Number","75000"))


import Tkinter,tkSimpleDialog

root = Tkinter.Tk()
root.withdraw()

number = tkSimpleDialog.askinteger("Integer", "Enter a Number")
string = tkSimpleDialog.askstring("String", "Enter a String")


$ \
import tkinter
import tkinter.simpledialog as tks

root = tkinter.Tk()
root.withdraw()

to_stack(tks.askinteger("Integer", "Enter a Number"))
string_to_stack(tks.askstring("String", "Enter a String"))

 \ python

swap echo cr echo$


library(gWidgets)
options(guiToolkit="RGtk2") ## using gWidgtsRGtk2

w <- gwindow("Enter a string and a number")
lyt <- glayout(cont=w)
lyt[1,1] <- "Enter a string"
lyt[1,2] <- gedit("", cont=lyt)
lyt[2,1] <- "Enter 75000"
lyt[2,2] <- gedit("", cont=lyt)
lyt[3,2] <- gbutton("validate", cont=lyt, handler=function(h,...) {
  txt <- svalue(lyt[1,2])
  x <- svalue(lyt[2,2])
  x <- gsub(",", "", x)
  x <- as.integer(x)

  if(nchar(txt) > 0 && x == 75000)
    gmessage("Congratulations, you followed directions", parent=w)
  else
    gmessage("You failed this simple task", parent=w)
})


#lang racket
(require racket/gui)

(define str (get-text-from-user "Hi" "Enter a string"))
(message-box "Hi" (format "You entered: ~a" str))

(define n (get-text-from-user "Hi" "Enter a number"))
(message-box "Hi" (format "You entered: ~a"
                          (or (string->number n) "bogus text")))


use GTK::Simple;
use GTK::Simple::App;

my GTK::Simple::App $app .= new( title => 'User Interaction' );

$app.border-width = 20;

$app.set-content(
    GTK::Simple::VBox.new(
        my $        = GTK::Simple::Label.new( text => 'Enter a string.' ),
        my $str     = GTK::Simple::Entry.new,
        my $string  = GTK::Simple::Label.new,
        my $        = GTK::Simple::Label.new( text => 'Enter the number 75000' ),
        my $val     = GTK::Simple::Entry.new,
        my $correct = GTK::Simple::Label.new,
    )
);

$str.changed.tap: {
    $string.text = "You entered: { $str.text }"
}

$val.changed.tap: {
    $correct.text = "That's { 'not' unless $val.text ~~ / ^^ <ws> 75000 <ws> $$ / } 75000!"
}

$app.run;


import vis::Render;
import vis::Figure;

public void UserInput2(){
	integer = "";
	string = "";
	row1 = [text("Enter a string  "),
			textfield("",void(str s){string = s;}),
			text(str(){return " This input box will give a string by definition.\n You entered <string>";})];
	row2 = [text("Enter 75000"),
			textfield("",void(str v){integer = v;}),
			text(str(){return " <integer == "75000" ? "Correct" : "Wrong">";})];
	render(grid([row1, row2]));
}


rebol [
	Title: "Graphical User Input"
	URL: http://rosettacode.org/wiki/User_Input_-_graphical
]

; Simple GUI's can be defined with 'layout', a special purpose dialect
; for specifying interfaces. In this case, I describe a gradient
; background with an instruction label, followed by the input fields
; and a validation button. It's possible to check dynamically as the
; user types but I wanted to keep this example as clear as possible.

view layout [

; You can define new widget styles. Here I create a padded label style
; (so that everything will line up) and a simple indicator light to
; show if there's a problem with an input field.

	style label vtext 60 "unlabeled"
	style indicator box maroon 24x24

	backdrop effect [gradient 0x1 black coal]

	vtext "Please enter a string, and the number 75000:"

; By default, GUI widgets are arranged top down. The 'across' word
; starts stacking widgets from left to right. 'return' starts a new
; line -- just like on a typewriter!

	across

; Notice I'm using my new label and indicator styles here. Widgets
; that I need to access later (the input field and the indicator) are
; assigned to variables.

	label "string:"  s: field 240  si: indicator  return

	label "number:"  n: field 50   ni: indicator  return

	pad 66
	button "validate" [

; The user may have entered bogus values, so I reset the indicators:

		si/color: ni/color: maroon

; Now I check to see if the values are correct. For the string, I just
; care that there is one. For the integer, I make sure that it
; evaluates to an integer and that it's value is 75000. Because I've
; already set the indicator colour, I don't care the integer
; conversion raises an error or not, so I ignore it if anything goes
; wrong.

		if 0 < length? get-face s [si/color: green]
		error? try [if 75000 = to-integer get-face n [ni/color: green]]

		show [si ni] ; Repainting multiple objects at once.
	]
]


/*REXX pgm prompts (using the OS GUI) for a string & then prompts for a specific number.*/
#= 75000                                         /*the number that   must be   entered. */
x=
N=
     do while x=' ';       say                   /*string can't be blanks or null string*/
     say 'Please enter a string: '
     parse pull x
     if x=''  then say '***error***  No string entered.'
     end   /*while x···*/

     do while N\=#;        say                   /*the number (below) may be ill formed.*/
     say 'Please enter the number:'   #
     parse pull N
     if datatype(N, 'N')  then N= N / 1          /*normalize the number:  007  4.0  +2  */
     if N\=#  then say '***error***  The number is not correct: '   N.
     end   /*while N···*/
say
say 'The string entered is:'  x                  /*echo the values  (string and number. */
say 'The number entered is:'  N                  /*stick a fork in it,  we're all done. */


Load "guilib.ring"

MyApp = New qApp {
                 num = 0
                 win1 = new qWidget() {
                        setwindowtitle("Hello World")
                        setGeometry(100,100,370,250)

                        btn1 = new qpushbutton(win1) {
                               setGeometry(130,200,100,30)
                               settext("Validate")
                               setclickevent("Validate()")}

                        lineedit1 = new qlineedit(win1) {
                                    setGeometry(10,100,250,30)
                                    settext("")}

                        lineedit2 = new qlineedit(win1) {
                                    setGeometry(10,150,50,30)
                                    settext("0")}

                        label1 = new qLabel(win1) {
                                 setGeometry(270,100,50,30)
		                 setText("")}

                        label2 = new qLabel(win1) {
                                 setGeometry(70,150,50,30)
		                 setText("")}

                        label3 = new qLabel(win1) {
                                 setGeometry(10,50,250,30)
		                 setText("Please enter a string, and the number 75000 :")}
                 show()}
                 exec()}

func Validate
     lineedit1{temp1 = text()}
     num1 = isdigit(temp1)
     if num1 = 0 label1{settext("OK")} else label1{settext("NOT OK")} ok

     lineedit2{temp2 = text()}
     num2 = number(temp2)
     if num2 = 75000 label2{settext("OK")} else label2{settext("NOT OK")} ok


require 'tk'

def main
  root = TkRoot.new
  l1 = TkLabel.new(root, "text" => "input a string")
  e1 = TkEntry.new(root)
  l2 = TkLabel.new(root, "text" => "input the number 75000")
  e2 = TkEntry.new(root) do
    validate "focusout"
    validatecommand lambda {e2.value.to_i == 75_000}
    invalidcommand  lambda {focus_number_entry(e2)}
  end
  ok = TkButton.new(root) do
    text "OK"
    command lambda {validate_input(e1, e2)}
  end
  Tk.grid(l1, e1)
  Tk.grid(l2, e2)
  Tk.grid("x",ok, "sticky" => "w")
  Tk.mainloop
end

def validate_input(text_entry, number_entry)
  if number_entry.value.to_i != 75_000
    focus_number_entry(number_entry)
  else
    puts %Q{You entered: "#{text_entry.value}" and "#{number_entry.value}"}
    root.destroy
  end
end

def focus_number_entry(widget)
  widget \
    .configure("background" => "red", "foreground" => "white") \
    .selection_range(0, "end") \
    .focus
end

main


html "

Please input a string and a number

String	<input type=text   name=str size=18>

Number	<input type=number name=num size=18 value=75000>

"

button #go, "Accept", [go]
button #ex, "Exit",   [ex]

html "

"
Wait

[go]
print #request get$("str")
print val(#request get$("num"))
wait

[ex]
end


import swing.Dialog.{Message, showInput}
import scala.swing.Swing

object UserInput extends App {
  def responce = showInput(null,
    "Complete the sentence:\n\"Green eggs and...\"",
    "Customized Dialog",
    Message.Plain,
    Swing.EmptyIcon,
    Nil, "ham")
  println(responce)
}