20:- module(adv_io_key,[
21
22
23 wait_for_key/0,
24 wait_for_key/1,
25 keyboard_init/0,
26 pprint/2,
27 init_logging/0,
28 stop_logging/0,
29 bug/1,
30 agent_to_input/2,
31 agent_to_output/2,
32 get_overwritten_chars/2,
33 restore_overwritten_chars/1,
34 35 setup_console/1,
36
37 current_error/1,set_error/1]). 38
39
40mutex_create_safe(M):- notrace(catch(mutex_create(M),_,true)).
41
42messages_init:-
43 mutex_create_safe(messages).
44
45flag(N,V):-
46 flag(N,_,V).
47
51post_message(M):-
52 with_mutex(messages,(post_message_int(M),
53 flag(unacked_messages,_,1))),
54 nop(request_screen_update(0,0,1,80)).
55
56post_message(F,L):-
57 atom(A) = AtomStream,
58 format(AtomStream,F,L),post_message(A).
59
60post_message_int(M):-
61 flag(line0,'',M),
62 atom_length(M,L),
63 flag(requested_cursor_row,_,0),
64 flag(requested_cursor_col,_,L),!.
65post_message_int(M):-
66 \+(more_prompt),
67 flag(line0,OL),
68 atom_length(OL,OLL),
69 atom_length(M,ML),
70 OLL+ML=<70,
71 concat_atom([OL,' ',M],NL),
72 flag(line0,_,NL),
73 atom_length(NL,Len),
74 flag(requested_cursor_row,_,0),
75 flag(requested_cursor_col,_,Len),!.
76post_message_int(M):-
77 more_prompt,
78 recordz(messages,M),!.
79post_message_int(M):-
80 flag(more_prompt,_,1),
81 flag(line0,OL),
82 atom_concat(OL,' [More]',NL),
83 flag(line0,_,NL),!,
84 post_message_int(M).
85
86more_prompt:-flag(more_prompt,1).
87
88ack_messages:-flag(unacked_messages,0).
89ack_messages:-
90 with_mutex(messages,(
91 flag(line0,_,''),
92 flag(unacked_messages,_,0),
93 flag(more_prompt,_,0),
94 flag(requested_cursor_row,_,0),
95 flag(requested_cursor_col,_,0),
96 gather_messages(L),
97 (L=[];flag(unacked_messages,_,1),resend_messages(L))
98 )),
99 nop(request_screen_update(0,0,1,80)).
100
101gather_messages([H|T]):-
102 recorded(messages,H,R),
103 erase(R),
104 !,gather_messages(T).
105gather_messages([]).
106
107resend_messages([H|T]):-
108 post_message_int(H),!,resend_messages(T).
109resend_messages([]).
110
170
171:-dynamic key_translate/2. 172
174
177
179
180key_translate(['\014\'],redraw).
181
182key_translate(['\033\','[','A'],up).
183key_translate(['\033\','[','B'],down).
184key_translate(['\033\','[','C'],right).
185key_translate(['\033\','[','D'],left).
186
187key_translate(['\033\','[','5','~'],page_up).
188key_translate(['\033\','[','6','~'],page_down).
189
190key_translate(['\033\',K],meta(K)):-char_type(K,alnum). 191
192keyboard_thread(Buffer):-
193 set_stream(user_input,buffer(none)),
194 get_single_char(Code),char_code(Key,Code),
195 append(Buffer,[Key],NB),
196 !,process_buffer(NB).
197
198process_buffer([]):-!,keyboard_thread([]).
199process_buffer(NB):-
200 key_translate(NNB,_),
201 append(NB,X,NNB),X\=[],
202 !,keyboard_thread(NB).
203process_buffer(NB):-
204 append(NBA,NBB,NB),
205 key_translate(NBA,Key),
207 global_key_hook(Key),
208 !,process_buffer(NBB).
209process_buffer([K|T]):-
210 nop(log_stuff('got key ~w.~n',[K])),global_key_hook(K),!,process_buffer(T).
223keystrokes_thread_name(keystrokes).
224
225global_key_hook(Key):-
226 keystrokes_thread_name(Keystrokes),
227 with_mutex(messages,(
228 nop(more_prompt),(Key=' ',nop(ack_messages);true);
229 nop(ack_messages),thread_send_message(Keystrokes,Key)
230 )),!.
231
232keyboard_init:-
233 keystrokes_thread_name(Keystrokes),
234 (message_queue_property(_, alias(Keystrokes))->true;message_queue_create(Keystrokes)),
235 thread_create(keyboard_thread([]),_,[]).
236
237wait_for_key(Key):-
238 keystrokes_thread_name(Keystrokes),
239 thread_get_message(Keystrokes,Key).
240
241wait_for_key:-wait_for_key(_)