REM Simulated iconbar mouse click
REM Syntax:
REM Click <application name> [-select] [-menu] [-adjust] [-wait] [-force]
REM <application name>  Name as known to task manager
REM -select -menu -adjust  Mouse clicks to simulate, at least one and in that order
REM -wait  Wait until application has started
REM -force Force simulated mouse click on current icon, if it belongs to the application

ON ERROR PROCerror

END = &A700

DIM block% 256, messages 8

messages!0 = &400C2
messages!4 = 0
SYS "Wimp_Initialise", 310, &4B534154, "Click", messages TO wimp%, thisTask%
IF wimp% < 310 ERROR 0, "RiscOS 3.10 or higher required"

SYS "OS_GetEnv" TO string
string$ = FNstring_c(string)
i = INSTR(string$, """")
i = INSTR(string$, """", i+1)
string$ = FNstring_strip(MID$(string$, i+1))

REM find the task name
i = 1
task$ = FNstring_commandItem(string$, i)

REM find the button to simulate
select% = INSTR(string$, "-select") <> 0
menu%   = INSTR(string$, "-menu")   <> 0
adjust% = INSTR(string$, "-adjust") <> 0

IF NOT(select% OR menu% OR adjust%) ERROR 0, "Button not specified"

wait%  = INSTR(string$, "-wait")  <> 0
force% = INSTR(string$, "-force") <> 0

maskNoTask% = %11100000110001
maskTaskFound% = %11100011100000110000

task% = FNfindTask(task$)

IF task% = -1 THEN
  IF NOT wait% ERROR 0, "Task not running"
  mask% = maskNoTask%
  icon% = -1
ELSE
  IF force% THEN
    icon% = FNreadCurrentIcon(task%)
  ELSE
    icon% = FNscanIconBar(task%)
  ENDIF
  PROCmakeClick(task%, icon%, select%, menu%, adjust%)
  mask% = maskTaskFound%
ENDIF

REPEAT
  SYS "Wimp_Poll", mask%, block% TO event
  CASE event OF
  WHEN 0: REM null
    IF icon% = -1 THEN
      IF force% THEN
        icon% = FNreadCurrentIcon(task%)
      ELSE
        icon% = FNscanIconBar(task%)
      ENDIF
    ELSE
      PROCmakeClick(task%, icon%, select%, menu%, adjust%)
    ENDIF
    IF NOT(select% OR menu% OR adjust%) END
  WHEN 17, 18, 19:
    CASE block%!16 OF
    WHEN &400C2: REM task starting
      IF task$ = FNstring_c(block%+28) THEN
        task% = block%!4
        mask% = maskTaskFound%
      ENDIF
    WHEN 0:
      END
    ENDCASE
  ENDCASE
UNTIL FALSE

DEF PROCmakeClick(task%, icon%, RETURN select%, RETURN menu%, RETURN adjust%)
LOCAL b%
IF select% THEN
  b% = 4
  select% = FALSE
ELSE
  IF menu% THEN
    b% = 2
    menu% = FALSE
  ELSE
    IF adjust% THEN b% = 1: adjust% = FALSE
  ENDIF
ENDIF
IF b% = 0 ENDPROC

block%!0 = -2
block%!4 = icon%
SYS "Wimp_GetIconState",, block%

block%!0  = (block%!8 + block%!16) >> 1
block%!4  = (block%!12 + block%!20) >> 1
block%!8  = b%
block%!12 = -2
block%!16 = icon%

SYS "Wimp_SendMessage", 6, block%, -2, icon%
ENDPROC

DEF FNwhoOwnsIt(window%, icon%)
LOCAL task%
block%!0 = 16
block%!4 =  0
block%!8 =  0
block%!12 = 0
SYS "Wimp_SendMessage", 19, block%, window%, icon% TO ,,task%
= task%

DEF FNreadCurrentIcon(task%)
REM 25/02/2003
LOCAL icon%
icon% = -1
SYS "Wimp_GetPointerInfo", ,block%
icon% = block%!16
IF task% = FNwhoOwnsIt(-2, icon%) THEN = icon%
= -1

DEF FNscanIconBar(task%)
LOCAL flag%, icon%, nIcons%
flag% = TRUE
icon% = -1
block%!0 = -2
SYS "Wimp_GetWindowInfo", ,block%+1
nIcons% = block%!88
FOR icon% = 0 TO nIcons%
  IF task% = FNwhoOwnsIt(-2, icon%) THEN = icon%
NEXT
= -1

DEF FNstring_c(p%)
REM 1.0 16/6/91
REM return control terminated string pointed to by p% and update p% to point to next charactor after control
LOCAL a$
WHILE ?p% > 31
  a$ = a$ + CHR$ ?p%
  p% += 1
ENDWHILE
p% += 1
= a$

DEF FNfindTask(task$)
LOCAL p%
p% = 0
REPEAT
  SYS "TaskManager_EnumerateTasks", p%, block%, 16 TO p%
  IF FNstring_c(block%!4) = task$ THEN  = block%!0
UNTIL p% < 0
= -1

DEF FNstring_strip(a$)
REM 1.0 16/6/91
WHILE LEFT$(a$,1)=" "
   a$=MID$(a$,2)
   ENDWHILE
WHILE RIGHT$(a$,1)=" "
   a$=LEFT$(a$,LEN a$-1)
   ENDWHILE
=a$

DEF FNstring_commandItem(string$, RETURN i)
LOCAL item$, j
i = FNstring_skip(string$, " ", i)
IF MID$(string$, i, 1) = """" THEN
  j = INSTR(string$, """", i+1)
  WHILE MID$(string$, j+1, 1) = """"
    j = INSTR(string$, """", j+2)
  ENDWHILE
  IF j = 0 ERROR 0, "Mismatched quotes"
  item$ = MID$(string$, i+1, j-i-1)
  i = j+1
ELSE
  item$ = FNstring_token(string$, " ", i)
ENDIF
= item$

DEF FNstring_skip(string$, skip$, from%)
WHILE MID$(string$, from%, 1) = skip$
  from% += 1
ENDWHILE
= from%

DEF FNstring_token(string$, token$, RETURN i%)
REM 2/3/93
LOCAL p%, a$
IF i% = -1 THEN =""
IF i% = 0 THEN i% = 1
p% = INSTR(string$, token$, i%)
IF p% = 0 THEN
  a$ = MID$(string$, i%)
  i% = -1
ELSE
  a$ = MID$(string$, i%, p%-i%)
  i% = p% + 1
ENDIF
= FNstring_strip(a$)

DEF PROCerror
ON ERROR PRINT "Click: "; REPORT$; " at line "; ERL/10: END
block%!0 = ERR
$(block%+4) = REPORT$ +  " at line " + STR$(ERL/10)
SYS "Wimp_ReportError", block%, 1, "Click"
END
