## 27.1 Tickles

Tickles are Oz values used to communicate with the graphics engine. The graphics engine receives and executes tickles. The graphics engine is implemented in Tcl/Tk (see [Ous94]). In order to execute tickles the graphics engine first translates tickles into strings. This section defines tickles, defines how tickles are translated into strings, and presents the Oz procedures to send tickles.

### 27.1.1 Syntax

The set of tickles contains virtual strings, boolean values, and so-called tickle-objects. A tickle-object is an object which is created from a class the Tk module provides for (all classes but `Tk.listener`). Roughly spoken, the set of tickles is closed under record construction, where only records are allowed which do not contain names as features or as label. Proper records with the labels `v`, `b`, `#`, and `|` are special cases. Examples for tickles can be found in Section 3.2 of ``Window Programming in Mozart''.

  `fun {IsTcl X}
  {IsBool X} orelse {IsUnit X} orelse
  {IsVirtualString X} orelse
  {IsTclObject X} orelse
  {IsRecord X} andthen
  {Not {Some {Arity X} IsName}} andthen
  {Not {IsName {Label X}}} andthen
  case {Label X}
  of v then {Arity X}==[1] andthen {IsVirtualString X.1}
  [] b then {Arity X}==[1] andthen {All X.1 IsTcl}
  [] c then {Arity X}==[1 2 3] andthen
  {All X fun {$ I} I>=0 andthen I<=255 end}
  [] '#' then false
  [] '|' then false
  else {Record.all X IsTcl}
  end
  end`

Figure 27.1: Procedure `IsTcl` tests whether a value is tickle.

The exact definition of a tickle is given by the procedure `IsTcl` which is shown in Figure 27.1. The procedure `IsTcl` returns `true`, if and only if `X` is a tickle. Otherwise `false` is returned. The procedure `IsTclObject` tests whether an object is a tickle-object. Note that records which have the labels `#` and `|` are treated as virtual strings. Note that `IsTcl` and the following procedures serve as specification, the graphics engine itself employs well optimized routines instead.

### 27.1.2 Translation to Virtual Strings

The translation of a tickle into a virtual string that then by the graphics agent is interpreted as a tcl command is shown in Figure 27.2. The used help routines are shown in Figure 27.3.

  `local
  fun {FieldToV AI Tcl}
  if {IsInt AI} then '' else '-'#{Quote AI}#' ' end # {TclToV Tcl}
  end
  fun {RecordToV R AIs}
  {FoldR AIs fun {$ AI V}
  {FieldToV AI R.AI} # ' ' # V
  end ''}
  end
  in
  fun {TclToV Tcl}
  if {IsBool Tcl} then case Tcl then 0 else 1 end
  elseif {IsUnit Tcl} then ''
  elseif {IsVirtualString Tcl} then {Quote Tcl}
  elseif {IsTclObject Tcl} then {TclObjectToV Tcl}
  else
  case {Label Tcl}
  of o then {RecordToV Tcl {Arity Tcl}}
  [] p then AI|AIs={Arity Tcl} in
  '{'#{FieldToV AI Tcl.AI}#'.'#{RecordToV Tcl AIs}#'}'
  [] b then {FoldR Tcl.1 fun {$ Tcl V}
  {TclToV Tcl}#' '#V
  end ''}
  [] c then '#'#{Hex Tcl.1}#{Hex Tcl.2}#{Hex Tcl.3}
  [] v then Tcl.1
  [] s then '"'#{RecordToV Tcl {Arity Tcl}}#'"'
  [] l then '['#{RecordToV Tcl {Arity Tcl}}#']'
  [] q then '{'#{RecordToV Tcl {Arity Tcl}}#'}'
  else {Quote {Label Tcl}}#' '#{RecordToV Tcl {Arity Tcl}}
  end
  end
  end
  end`

Figure 27.2: Procedure `TclToV` translates a tickle into a virtual string.

<Definition of Octal>=
  `fun {Octal I}
  [&\\ (I div 64 + &0) ((I mod 64) div 8 + &0) (I mod 8 + &0)]
  end`

<Definition of Quote>=
  `fun {Quote V}
  case {VirtualString.toString V} of nil then "\"\""
  [] S then
  {FoldR S fun {$ I Ir}
  if {Member I "{}[]\\$\";"} then &\\|I|Ir
  elseif I<33 orelse I>127 then {Append {Octal I} Ir}
  else I|Ir
  end
  end nil}
  end
  end`

<Definition of Hex>=
  `local
  fun {HexDigit I}
  I + if I>9 then &a-10 else &0 end
  end
  in
  fun {Hex I}
  [{HexDigit I div 16} {HexDigit I mod 16}]
  end
  end`

Figure 27.3: Help routines to translate a tickle into a virtual string.

### 27.1.3 Sending Tickles

Tickles can be send to the graphics engine with the following procedures. The graphics engine processes tickles in batches: it reads a batch of tickles and executes it. If no further batch can be read currently, it updates the graphics. After having updated the graphics, it checks whether user events are to be processed.

The Oz procedures to send tickles are asynchronous and preserve order: all tickles are processed in the same order they are send in. However, after the procedure has been executed, the graphics engine might not yet have executed the tickle.

`send`

  > > `{Tk.send` `+Tcl``}`

  Sends `+Tcl` to the graphics engine.

`batch`

  > > `{Tk.batch` `+TclS``}`

  Sends a list of list of tickles `+TclS` to the graphics engine. It is guaranteed that the graphics engine processes all tickles in `TclS` in a single batch.

### 27.1.4 Sending Tickles and Returning Values

In the same way as sending tickles to graphics engine, the engine can asynchronously send back return values which are strings. The following procedures send tickles and return the values returned by executing the tickles by the graphics engine.

`returnString`

  > > `{Tk.returnString` `+Tcl``` `?S``}`

  Returns the result of sending and executing `+Tcl` as string.

`return`

  > > `{Tk.return` `+Tcl``` `?S``}`

  Shortcut for `Tk.returnString`.

`returnAtom`

  > > `{Tk.returnAtom` `+Tcl``` `?A``}`

  Returns the result of sending and executing `+Tcl` as string.

`returnInt`

  > > `{Tk.returnInt` `+Tcl``` `?IB``}`

  Returns the result of sending and executing `+Tcl` as integer. If the result does not describe a number `false` is returned.

`returnFloat`

  > > `{Tk.returnFloat` `+Tcl``` `?FB``}`

  Returns the result of sending and executing `+Tcl` as float. If the result does not describe a number `false` is returned.

`returnListString`

  > > `{Tk.returnListString` `+Tcl``` `?Ss``}`

  Returns the result of sending and executing `+Tcl` as list of strings.

`returnList`

  > > `{Tk.returnList` `+Tcl``` `?Ss``}`

  Shortcut for `Tk.returnListString`.

`returnListAtom`

  > > `{Tk.returnListAtom` `+Tcl``` `?ABs``}`

  Returns the result of sending and executing `+Tcl` as list of atoms. If elements of the list do not form valid atoms, the list contains the element `false` instead.

`returnListInt`

  > > `{Tk.returnListInt` `+Tcl``` `?IBs``}`

  Returns the result of sending and executing `+Tcl` as list of integers. If elements of the list do not form valid numbers, the list contains the element `false` instead.

`returnListFloat`

  > > `{Tk.returnListFloat` `+Tcl``` `?FBs``}`

  Returns the result of sending and executing `+Tcl` as list of integers. If elements of the list do not form valid numbers, the list contains the element `false` instead.