NB. Sets up J as a cold-link DDE server.
NB.
NB. The client sends J sentences for execution. The result is returned.
NB.
NB. Since the link is a cold-link, avoid requesting data from J when
NB. J is likely to be executing - otherwise the request may time out.
NB.
NB. The service name is:  jserver
NB.  	
NB. Any number of topic/items are supported.
NB.
NB. You can invoke J with this file as the initial file specified
NB. in the command line. No other scripts are required.
NB.
NB. The incoming and outgoing messages are displayed.
NB.
NB. Method:
NB.
NB. Load J and run this script
NB.   (you can set up an icon/shortcut to do this)
NB. From the client, issue a ddepoke for any topic and item, with the
NB.   data being an executable J sentence
NB. If data is 'exit', J exits the function
NB. If data is 'off', J terminates
NB. J executes the sentence, and stores the result with topic and item.
NB. If execution fails, result is: 'unable to execute: ',data
NB. Client sends a ddereq for the item, and J responds
NB.
NB. The global FORMAT controls the result. If FORMAT=1, item is stored
NB. as ":item. This is useful for clients such as Word for Windows that
NB. will simply paste in the formatted result.


TAB=: 9{a.
LF=: 10{a.
FF=: 12{a.
CR=: 13{a.
CRLF=: 13 10{a.
EAV=: 255{a.

FORMAT=: 0

delay=: 6!:3
empty=: (i.0 0)"_
erase=: 4!:55
nameclass=: 4!:0
signoff=: 2!:55

wd=: 11!:0

NB. wdhandler
NB. runs in form locale
NB. sets global event data: wdq
NB. runs first found of: form_handler, form_event, form_default,
NB. with temporary global event variables from wdq
wdhandler=: 3 : 0
wdq=: wd 'q'
val=. {:"1 wdq
ndx=. 1 i.~ 3 = 4!:0 [ 3{.val
if. 3>ndx do.
  nms=. {."1 wdq
  (nms)=: val
  fn=. >ndx{val
  try. fn~0
  catch.
    err=. LF,,LF,.}.;._2 [ 13!:12''
    wdinfo 'wdhandler';'error in: ',fn,err
  end.
  4!:55 nms
end.
empty''
)

wdreqd=: 3 : 0
wd 'ddereqd *',clipfmt y.
)

NB. clipfmt
clipfmt=: 3 : 0
NB. format array of rank 0 1 or 2 for clipboard.
NB. columns are separated by TAB, rows by CRLF.
t=. 3!:0 y.
if. 2=t do.
  y=. ,y.,"1 CRLF
elseif. 32<:t do.
  y=. ,&TAB @ ": &.>y.
  y=. ;,&CRLF@}: &.><@;"1 y
elseif. 1 do.
  y=. ;,&CRLF @ ": &.><"1 y.
  y=. '-' (I. y='_') } y
  y=. TAB (I. y=' ') } y
end.
y
)

NB. create display controls:

WPSERVER=: 0 : 0
pc server closeok;pn "J Server";
xywh 4 4 100 10;
cc e0 edit ws_border;
xywh 4 17 160 40;
cc e1 editm ws_border;
pas 4 4;pcenter;
)

NB. functions to write to controls:
write0=: 3 : 0
wd 'set e0 *',y.
)

write1=: 3 : 0
y=. 1 1}. _1 _1}. ": <y.
y=. }.,LF,"1 y
wd 'set e1 *',y
)

NB. jserver
jserver=: 3 : 0

NB. set service name: jserver
try. wd 'reset;ddename jserver;'
catch. end.

NB. set up topic;item;result table:
topitem=: i.0 3

NB. display controls:
wd WPSERVER
wd 'setfont e0 Terminal 9 oem'
wd 'setfont e1 Terminal 9 oem'
wd 'pshow'
)

NB. event handlers:

server_close=: signoff
server_break=: signoff

sys_ddepoke=: 3 : 0
sysdata=: sysdata -. CRLF,TAB
write0 sysdata
if. sysdata -: 'exit' do. return. end.
if. sysdata -: 'off' do.
  delay 1
  signoff ''
end.
try. val=: (3 : sysdata) ''
catch. val=: 'unable to execute: ',sysdata end.
if. FORMAT do. val=: ":val end.
write1 val
topitem=: topitem,systopic;sysitem;<val
)

sys_ddereq=: 3 : 0
ndx=: (}:"1 topitem) i. systopic;sysitem
wdreqd >ndx{({:"1 topitem),<'item not found'
topitem=: topitem #~ ndx ~: i.#topitem
)

jserver''
