Mercurial > hg > xemacs-beta
annotate src/tooltalk.c @ 4834:b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Tue, 12 Jan 2010 01:38:04 -0600 |
parents | facf3239ba30 |
children | a98ca4640147 |
rev | line source |
---|---|
428 | 1 /* Tooltalk support for Emacs. |
2 Copyright (C) 1993, 1994 Sun Microsystems, Inc. | |
3 Copyright (C) 1995 Free Software Foundation, Inc. | |
853 | 4 Copyright (C) 2002 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Not in FSF. */ | |
24 | |
25 /* Written by John Rose <john.rose@eng.sun.com>. | |
26 Heavily modified and cleaned up by Ben Wing <ben@xemacs.org>. */ | |
27 | |
28 #include <config.h> | |
29 #include "lisp.h" | |
30 | |
31 #include <X11/Xlib.h> | |
32 | |
33 #include "buffer.h" | |
34 #include "elhash.h" | |
35 #include "process.h" | |
36 #include "tooltalk.h" | |
442 | 37 #include "syssignal.h" |
428 | 38 |
39 Lisp_Object Vtooltalk_fd; | |
40 | |
41 #ifdef TT_DEBUG | |
42 static FILE *tooltalk_log_file; | |
43 #endif | |
44 | |
45 static Lisp_Object | |
46 Vtooltalk_message_handler_hook, | |
47 Vtooltalk_pattern_handler_hook, | |
48 Vtooltalk_unprocessed_message_hook; | |
49 | |
50 static Lisp_Object | |
51 Qtooltalk_message_handler_hook, | |
52 Qtooltalk_pattern_handler_hook, | |
53 Qtooltalk_unprocessed_message_hook; | |
54 | |
55 static Lisp_Object | |
56 Qreceive_tooltalk_message, | |
57 Qtt_address, | |
58 Qtt_args_count, | |
59 Qtt_arg_bval, | |
60 Qtt_arg_ival, | |
61 Qtt_arg_mode, | |
62 Qtt_arg_type, | |
63 Qtt_arg_val, | |
64 Qtt_class, | |
65 Qtt_category, | |
66 Qtt_disposition, | |
67 Qtt_file, | |
68 Qtt_gid, | |
69 Qtt_handler, | |
70 Qtt_handler_ptype, | |
71 Qtt_object, | |
72 Qtt_op, | |
73 Qtt_opnum, | |
74 Qtt_otype, | |
75 Qtt_scope, | |
76 Qtt_sender, | |
77 Qtt_sender_ptype, | |
78 Qtt_session, | |
79 Qtt_state, | |
80 Qtt_status, | |
81 Qtt_status_string, | |
82 Qtt_uid, | |
83 Qtt_callback, | |
84 Qtt_plist, | |
85 Qtt_prop, | |
86 | |
87 Qtt_reject, /* return-tooltalk-message */ | |
88 Qtt_reply, | |
89 Qtt_fail, | |
90 | |
91 Q_TT_MODE_UNDEFINED, /* enum Tt_mode */ | |
92 Q_TT_IN, | |
93 Q_TT_OUT, | |
94 Q_TT_INOUT, | |
95 Q_TT_MODE_LAST, | |
96 | |
97 Q_TT_SCOPE_NONE, /* enum Tt_scope */ | |
98 Q_TT_SESSION, | |
99 Q_TT_FILE, | |
100 Q_TT_BOTH, | |
101 Q_TT_FILE_IN_SESSION, | |
102 | |
103 Q_TT_CLASS_UNDEFINED, /* enum Tt_class */ | |
104 Q_TT_NOTICE, | |
105 Q_TT_REQUEST, | |
106 Q_TT_CLASS_LAST, | |
107 | |
108 Q_TT_CATEGORY_UNDEFINED, /* enum Tt_category */ | |
109 Q_TT_OBSERVE, | |
110 Q_TT_HANDLE, | |
111 Q_TT_CATEGORY_LAST, | |
112 | |
113 Q_TT_PROCEDURE, /* typedef enum Tt_address */ | |
114 Q_TT_OBJECT, | |
115 Q_TT_HANDLER, | |
116 Q_TT_OTYPE, | |
117 Q_TT_ADDRESS_LAST, | |
118 | |
119 Q_TT_CREATED, /* enum Tt_state */ | |
120 Q_TT_SENT, | |
121 Q_TT_HANDLED, | |
122 Q_TT_FAILED, | |
123 Q_TT_QUEUED, | |
124 Q_TT_STARTED, | |
125 Q_TT_REJECTED, | |
126 Q_TT_STATE_LAST, | |
127 | |
128 Q_TT_DISCARD, /* enum Tt_disposition */ | |
129 Q_TT_QUEUE, | |
130 Q_TT_START; | |
131 | |
132 static Lisp_Object Tooltalk_Message_plist_str, Tooltalk_Pattern_plist_str; | |
133 | |
134 Lisp_Object Qtooltalk_error; | |
135 | |
136 /* Used to GCPRO tooltalk message and pattern objects while | |
137 they're sitting inside of some active tooltalk message or pattern. | |
138 There may not be any other pointers to these objects. */ | |
139 Lisp_Object Vtooltalk_message_gcpro, Vtooltalk_pattern_gcpro; | |
140 | |
141 | |
142 /* */ | |
143 /* machinery for tooltalk-message type */ | |
144 /* */ | |
145 | |
146 Lisp_Object Qtooltalk_messagep; | |
147 | |
148 struct Lisp_Tooltalk_Message | |
149 { | |
3017 | 150 struct LCRECORD_HEADER header; |
428 | 151 Lisp_Object plist_sym, callback; |
152 Tt_message m; | |
153 }; | |
154 | |
1204 | 155 static const struct memory_description tooltalk_message_description [] = { |
934 | 156 { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Message, callback) }, |
157 { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Message, plist_sym) }, | |
158 { XD_END } | |
159 }; | |
160 | |
428 | 161 static Lisp_Object |
162 mark_tooltalk_message (Lisp_Object obj) | |
163 { | |
164 mark_object (XTOOLTALK_MESSAGE (obj)->callback); | |
165 return XTOOLTALK_MESSAGE (obj)->plist_sym; | |
166 } | |
167 | |
168 static void | |
169 print_tooltalk_message (Lisp_Object obj, Lisp_Object printcharfun, | |
2286 | 170 int UNUSED (escapeflag)) |
428 | 171 { |
440 | 172 Lisp_Tooltalk_Message *p = XTOOLTALK_MESSAGE (obj); |
428 | 173 |
174 if (print_readably) | |
563 | 175 printing_unreadable_object ("#<tooltalk_message 0x%x>", |
176 p->header.uid); | |
428 | 177 |
800 | 178 write_fmt_string (printcharfun, "#<tooltalk_message id:0x%lx 0x%x>", |
179 (long) (p->m), p->header.uid); | |
428 | 180 } |
181 | |
934 | 182 DEFINE_LRECORD_IMPLEMENTATION ("tooltalk-message", tooltalk_message, |
960 | 183 0, /*dumpable-flag*/ |
934 | 184 mark_tooltalk_message, print_tooltalk_message, |
185 0, 0, 0, | |
186 tooltalk_message_description, | |
187 Lisp_Tooltalk_Message); | |
428 | 188 |
189 static Lisp_Object | |
190 make_tooltalk_message (Tt_message m) | |
191 { | |
192 Lisp_Object val; | |
440 | 193 Lisp_Tooltalk_Message *msg = |
3017 | 194 ALLOC_LCRECORD_TYPE (Lisp_Tooltalk_Message, &lrecord_tooltalk_message); |
428 | 195 |
196 msg->m = m; | |
197 msg->callback = Qnil; | |
198 msg->plist_sym = Fmake_symbol (Tooltalk_Message_plist_str); | |
793 | 199 return wrap_tooltalk_message (msg); |
428 | 200 } |
201 | |
202 Tt_message | |
203 unbox_tooltalk_message (Lisp_Object msg) | |
204 { | |
205 CHECK_TOOLTALK_MESSAGE (msg); | |
206 return XTOOLTALK_MESSAGE (msg)->m; | |
207 } | |
208 | |
209 DEFUN ("tooltalk-message-p", Ftooltalk_message_p, 1, 1, 0, /* | |
210 Return non-nil if OBJECT is a tooltalk message. | |
211 */ | |
212 (object)) | |
213 { | |
214 return TOOLTALK_MESSAGEP (object) ? Qt : Qnil; | |
215 } | |
216 | |
217 | |
218 | |
219 | |
220 /* */ | |
221 /* machinery for tooltalk-pattern type */ | |
222 /* */ | |
223 | |
224 Lisp_Object Qtooltalk_patternp; | |
225 | |
226 struct Lisp_Tooltalk_Pattern | |
227 { | |
3017 | 228 struct LCRECORD_HEADER header; |
428 | 229 Lisp_Object plist_sym, callback; |
230 Tt_pattern p; | |
231 }; | |
232 | |
1204 | 233 static const struct memory_description tooltalk_pattern_description [] = { |
934 | 234 { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Pattern, callback) }, |
235 { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Pattern, plist_sym) }, | |
236 { XD_END } | |
237 }; | |
238 | |
428 | 239 static Lisp_Object |
240 mark_tooltalk_pattern (Lisp_Object obj) | |
241 { | |
242 mark_object (XTOOLTALK_PATTERN (obj)->callback); | |
243 return XTOOLTALK_PATTERN (obj)->plist_sym; | |
244 } | |
245 | |
246 static void | |
247 print_tooltalk_pattern (Lisp_Object obj, Lisp_Object printcharfun, | |
2286 | 248 int UNUSED (escapeflag)) |
428 | 249 { |
440 | 250 Lisp_Tooltalk_Pattern *p = XTOOLTALK_PATTERN (obj); |
428 | 251 |
252 if (print_readably) | |
563 | 253 printing_unreadable_object ("#<tooltalk_pattern 0x%x>", |
254 p->header.uid); | |
428 | 255 |
800 | 256 write_fmt_string (printcharfun, "#<tooltalk_pattern id:0x%lx 0x%x>", |
257 (long) (p->p), p->header.uid); | |
428 | 258 } |
259 | |
934 | 260 DEFINE_LRECORD_IMPLEMENTATION ("tooltalk-pattern", tooltalk_pattern, |
960 | 261 0, /*dumpable-flag*/ |
934 | 262 mark_tooltalk_pattern, print_tooltalk_pattern, |
263 0, 0, 0, | |
264 tooltalk_pattern_description, | |
265 Lisp_Tooltalk_Pattern); | |
428 | 266 |
267 static Lisp_Object | |
268 make_tooltalk_pattern (Tt_pattern p) | |
269 { | |
440 | 270 Lisp_Tooltalk_Pattern *pat = |
3017 | 271 ALLOC_LCRECORD_TYPE (Lisp_Tooltalk_Pattern, &lrecord_tooltalk_pattern); |
428 | 272 Lisp_Object val; |
273 | |
274 pat->p = p; | |
275 pat->callback = Qnil; | |
276 pat->plist_sym = Fmake_symbol (Tooltalk_Pattern_plist_str); | |
277 | |
793 | 278 return wrap_tooltalk_pattern (pat); |
428 | 279 } |
280 | |
281 static Tt_pattern | |
282 unbox_tooltalk_pattern (Lisp_Object pattern) | |
283 { | |
284 CHECK_TOOLTALK_PATTERN (pattern); | |
285 return XTOOLTALK_PATTERN (pattern)->p; | |
286 } | |
287 | |
288 DEFUN ("tooltalk-pattern-p", Ftooltalk_pattern_p, 1, 1, 0, /* | |
289 Return non-nil if OBJECT is a tooltalk pattern. | |
290 */ | |
291 (object)) | |
292 { | |
293 return TOOLTALK_PATTERNP (object) ? Qt : Qnil; | |
294 } | |
295 | |
296 | |
297 | |
298 | |
299 static int | |
300 tooltalk_constant_value (Lisp_Object s) | |
301 { | |
302 if (INTP (s)) | |
303 return XINT (s); | |
304 else if (SYMBOLP (s)) | |
305 return XINT (XSYMBOL (s)->value); | |
306 else | |
307 return 0; /* should never occur */ | |
308 } | |
309 | |
310 static void | |
311 check_status (Tt_status st) | |
312 { | |
313 if (tt_is_err (st)) | |
563 | 314 { |
867 | 315 CIbyte *err; |
563 | 316 |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
317 EXTERNAL_TO_C_STRING (tt_status_message (st), err, Qtooltalk_encoding); |
563 | 318 signal_error (Qtooltalk_error, err, Qunbound); |
319 } | |
428 | 320 } |
321 | |
322 DEFUN ("receive-tooltalk-message", Freceive_tooltalk_message, 0, 2, 0, /* | |
323 Run tt_message_receive(). | |
324 This function is the process handler for the ToolTalk connection process. | |
325 */ | |
2286 | 326 (UNUSED (ignore1), UNUSED (ignore2))) |
428 | 327 { |
328 /* This function can GC */ | |
329 Tt_message mess = tt_message_receive (); | |
330 Lisp_Object message_ = make_tooltalk_message (mess); | |
331 struct gcpro gcpro1; | |
332 | |
333 GCPRO1 (message_); | |
334 if (mess != NULL && !NILP (Vtooltalk_unprocessed_message_hook)) | |
335 va_run_hook_with_args (Qtooltalk_unprocessed_message_hook, 1, message_); | |
336 UNGCPRO; | |
337 | |
338 /* see comment in event-stream.c about this return value. */ | |
339 return Qzero; | |
340 } | |
341 | |
342 static Tt_callback_action | |
343 tooltalk_message_callback (Tt_message m, Tt_pattern p) | |
344 { | |
345 /* This function can GC */ | |
346 Lisp_Object cb; | |
347 Lisp_Object message_; | |
348 Lisp_Object pattern; | |
349 struct gcpro gcpro1, gcpro2; | |
350 | |
351 #ifdef TT_DEBUG | |
352 int i, j; | |
353 | |
354 fprintf (tooltalk_log_file, "message_cb: %d\n", m); | |
355 fprintf (tooltalk_log_file, "op: %s (", tt_message_op (m)); | |
356 for (j = tt_message_args_count (m), i = 0; i < j; i++) { | |
357 fprintf (tooltalk_log_file, "%s \"%s\"", tt_message_arg_type (m, i), | |
358 tt_message_arg_val (m, i)); | |
359 fprintf (tooltalk_log_file, "%s", i == j-1 ? ")" : ", "); | |
360 } | |
361 fprintf (tooltalk_log_file, "\n\n"); | |
362 fflush (tooltalk_log_file); | |
363 #endif | |
364 | |
826 | 365 message_ = VOID_TO_LISP (tt_message_user (m, TOOLTALK_MESSAGE_KEY)); |
428 | 366 pattern = make_tooltalk_pattern (p); |
367 cb = XTOOLTALK_MESSAGE (message_)->callback; | |
368 GCPRO2 (message_, pattern); | |
369 if (!NILP (Vtooltalk_message_handler_hook)) | |
370 va_run_hook_with_args (Qtooltalk_message_handler_hook, 2, | |
371 message_, pattern); | |
372 | |
373 if ((SYMBOLP (cb) && EQ (Qt, Ffboundp (cb))) || | |
374 (CONSP (cb) && EQ (Qlambda, Fcar (cb)) && | |
375 !NILP (Flistp (Fcar (Fcdr (cb)))))) | |
376 call2 (cb, message_, pattern); | |
377 UNGCPRO; | |
378 | |
379 tt_message_destroy (m); | |
380 Fremhash (message_, Vtooltalk_message_gcpro); | |
381 | |
382 return TT_CALLBACK_PROCESSED; | |
383 } | |
384 | |
385 static Tt_callback_action | |
386 tooltalk_pattern_callback (Tt_message m, Tt_pattern p) | |
387 { | |
388 /* This function can GC */ | |
389 Lisp_Object cb; | |
390 Lisp_Object message_; | |
391 Lisp_Object pattern; | |
392 struct gcpro gcpro1, gcpro2; | |
393 | |
394 #ifdef TT_DEBUG | |
395 int i, j; | |
396 | |
397 fprintf (tooltalk_log_file, "pattern_cb: %d\n", m); | |
398 fprintf (tooltalk_log_file, "op: %s (", tt_message_op (m)); | |
399 for (j = tt_message_args_count (m), i = 0; i < j; i++) { | |
400 fprintf (tooltalk_log_file, "%s \"%s\"", tt_message_arg_type (m, i), | |
401 tt_message_arg_val (m, i)); | |
402 fprintf (tooltalk_log_file, "%s", i == j-1 ? ")" : ", "); | |
403 } | |
404 fprintf (tooltalk_log_file, "\n\n"); | |
405 fflush (tooltalk_log_file); | |
406 #endif | |
407 | |
408 message_ = make_tooltalk_message (m); | |
826 | 409 pattern = VOID_TO_LISP (tt_pattern_user (p, TOOLTALK_PATTERN_KEY)); |
428 | 410 cb = XTOOLTALK_PATTERN (pattern)->callback; |
411 GCPRO2 (message_, pattern); | |
412 if (!NILP (Vtooltalk_pattern_handler_hook)) | |
413 va_run_hook_with_args (Qtooltalk_pattern_handler_hook, 2, | |
414 message_, pattern); | |
415 | |
416 if (SYMBOLP (cb) && EQ (Qt, Ffboundp (cb))) | |
417 call2 (cb, message_, pattern); | |
418 UNGCPRO; | |
419 | |
420 tt_message_destroy (m); | |
421 return TT_CALLBACK_PROCESSED; | |
422 } | |
423 | |
424 static Lisp_Object | |
425 tt_mode_symbol (Tt_mode n) | |
426 { | |
427 switch (n) | |
428 { | |
429 case TT_MODE_UNDEFINED: return Q_TT_MODE_UNDEFINED; | |
430 case TT_IN: return Q_TT_IN; | |
431 case TT_OUT: return Q_TT_OUT; | |
432 case TT_INOUT: return Q_TT_INOUT; | |
433 case TT_MODE_LAST: return Q_TT_MODE_LAST; | |
434 default: return Qnil; | |
435 } | |
436 } | |
437 | |
438 static Lisp_Object | |
439 tt_scope_symbol (Tt_scope n) | |
440 { | |
441 switch (n) | |
442 { | |
443 case TT_SCOPE_NONE: return Q_TT_SCOPE_NONE; | |
444 case TT_SESSION: return Q_TT_SESSION; | |
445 case TT_FILE: return Q_TT_FILE; | |
446 case TT_BOTH: return Q_TT_BOTH; | |
447 case TT_FILE_IN_SESSION: return Q_TT_FILE_IN_SESSION; | |
448 default: return Qnil; | |
449 } | |
450 } | |
451 | |
452 | |
453 static Lisp_Object | |
454 tt_class_symbol (Tt_class n) | |
455 { | |
456 switch (n) | |
457 { | |
458 case TT_CLASS_UNDEFINED: return Q_TT_CLASS_UNDEFINED; | |
459 case TT_NOTICE: return Q_TT_NOTICE; | |
460 case TT_REQUEST: return Q_TT_REQUEST; | |
461 case TT_CLASS_LAST: return Q_TT_CLASS_LAST; | |
462 default: return Qnil; | |
463 } | |
464 } | |
465 | |
466 /* | |
467 * This is not being used. Is that a mistake or is this function | |
468 * simply not necessary? | |
469 */ | |
470 #if 0 | |
471 static Lisp_Object | |
472 tt_category_symbol (Tt_category n) | |
473 { | |
474 switch (n) | |
475 { | |
476 case TT_CATEGORY_UNDEFINED: return Q_TT_CATEGORY_UNDEFINED; | |
477 case TT_OBSERVE: return Q_TT_OBSERVE; | |
478 case TT_HANDLE: return Q_TT_HANDLE; | |
479 case TT_CATEGORY_LAST: return Q_TT_CATEGORY_LAST; | |
480 default: return Qnil; | |
481 } | |
482 } | |
483 #endif /* 0 */ | |
484 | |
485 static Lisp_Object | |
486 tt_address_symbol (Tt_address n) | |
487 { | |
488 switch (n) | |
489 { | |
490 case TT_PROCEDURE: return Q_TT_PROCEDURE; | |
491 case TT_OBJECT: return Q_TT_OBJECT; | |
492 case TT_HANDLER: return Q_TT_HANDLER; | |
493 case TT_OTYPE: return Q_TT_OTYPE; | |
494 case TT_ADDRESS_LAST: return Q_TT_ADDRESS_LAST; | |
495 default: return Qnil; | |
496 } | |
497 } | |
498 | |
499 static Lisp_Object | |
500 tt_state_symbol (Tt_state n) | |
501 { | |
502 switch (n) | |
503 { | |
504 case TT_CREATED: return Q_TT_CREATED; | |
505 case TT_SENT: return Q_TT_SENT; | |
506 case TT_HANDLED: return Q_TT_HANDLED; | |
507 case TT_FAILED: return Q_TT_FAILED; | |
508 case TT_QUEUED: return Q_TT_QUEUED; | |
509 case TT_STARTED: return Q_TT_STARTED; | |
510 case TT_REJECTED: return Q_TT_REJECTED; | |
511 case TT_STATE_LAST: return Q_TT_STATE_LAST; | |
512 default: return Qnil; | |
513 } | |
514 } | |
515 | |
516 static Lisp_Object | |
771 | 517 tt_build_c_string (char *s) |
428 | 518 { |
519 return build_string (s ? s : ""); | |
520 } | |
521 | |
522 static Lisp_Object | |
523 tt_opnum_string (int n) | |
524 { | |
525 char buf[32]; | |
526 | |
527 sprintf (buf, "%u", n); | |
528 return build_string (buf); | |
529 } | |
530 | |
531 static Lisp_Object | |
532 tt_message_arg_ival_string (Tt_message m, int n) | |
533 { | |
603 | 534 char buf[DECIMAL_PRINT_SIZE (long)]; |
428 | 535 int value; |
536 | |
537 check_status (tt_message_arg_ival (m, n, &value)); | |
538 long_to_string (buf, value); | |
539 return build_string (buf); | |
540 } | |
541 | |
542 static Lisp_Object | |
543 tt_message_arg_bval_vector (Tt_message m, int n) | |
544 { | |
545 /* !!#### This function has not been Mule-ized */ | |
867 | 546 Ibyte *value; |
428 | 547 int len = 0; |
548 | |
549 check_status (tt_message_arg_bval (m, n, &value, &len)); | |
550 | |
551 return make_string (value, len); | |
552 } | |
553 | |
554 DEFUN ("get-tooltalk-message-attribute", Fget_tooltalk_message_attribute, | |
555 2, 3, 0, /* | |
556 Return the indicated Tooltalk message attribute. Attributes are | |
557 identified by symbols with the same name (underscores and all) as the | |
558 suffix of the Tooltalk tt_message_<attribute> function that extracts the value. | |
559 String attribute values are copied, enumerated type values (except disposition) | |
3025 | 560 are converted to symbols - e.g. TT_HANDLER is `TT_HANDLER', uid and gid are |
428 | 561 represented by fixnums (small integers), opnum is converted to a string, |
562 and disposition is converted to a fixnum. We convert opnum (a C int) to a | |
563 string, e.g. 123 => "123" because there's no guarantee that opnums will fit | |
564 within the range of Lisp integers. | |
565 | |
3025 | 566 Use the `plist' attribute instead of the C API `user' attribute |
428 | 567 for user defined message data. To retrieve the value of a message property |
568 specify the indicator for argn. For example to get the value of a property | |
3025 | 569 called `rflag', use |
428 | 570 (get-tooltalk-message-attribute message 'plist 'rflag) |
571 | |
3025 | 572 To get the value of a message argument use one of the `arg_val' (strings), |
573 `arg_ival' (integers), or `arg_bval' (strings with embedded nulls), attributes. | |
428 | 574 For example to get the integer value of the third argument: |
575 | |
576 (get-tooltalk-message-attribute message 'arg_ival 2) | |
577 | |
578 As you can see, argument numbers are zero based. The type of each argument | |
3025 | 579 can be retrieved with the `arg_type' attribute; however, Tooltalk doesn't |
580 define any semantics for the string value of `arg_type'. Conventionally | |
428 | 581 "string" is used for strings and "int" for 32 bit integers. Note that |
582 Emacs Lisp stores the lengths of strings explicitly (unlike C) so treating the | |
3025 | 583 value returned by `arg_bval' like a string is fine. |
428 | 584 */ |
585 (message_, attribute, argn)) | |
586 { | |
587 Tt_message m = unbox_tooltalk_message (message_); | |
588 int n = 0; | |
589 | |
590 CHECK_SYMBOL (attribute); | |
591 if (EQ (attribute, (Qtt_arg_bval)) || | |
592 EQ (attribute, (Qtt_arg_ival)) || | |
593 EQ (attribute, (Qtt_arg_mode)) || | |
594 EQ (attribute, (Qtt_arg_type)) || | |
595 EQ (attribute, (Qtt_arg_val))) | |
596 { | |
597 CHECK_INT (argn); | |
598 n = XINT (argn); | |
599 } | |
600 | |
601 if (!VALID_TOOLTALK_MESSAGEP (m)) | |
602 return Qnil; | |
603 | |
604 else if (EQ (attribute, Qtt_arg_bval)) | |
605 return tt_message_arg_bval_vector (m, n); | |
606 | |
607 else if (EQ (attribute, Qtt_arg_ival)) | |
608 return tt_message_arg_ival_string (m, n); | |
609 | |
610 else if (EQ (attribute, Qtt_arg_mode)) | |
611 return tt_mode_symbol (tt_message_arg_mode (m, n)); | |
612 | |
613 else if (EQ (attribute, Qtt_arg_type)) | |
771 | 614 return tt_build_c_string (tt_message_arg_type (m, n)); |
428 | 615 |
616 else if (EQ (attribute, Qtt_arg_val)) | |
617 return tt_message_arg_bval_vector (m, n); | |
618 | |
619 else if (EQ (attribute, Qtt_args_count)) | |
620 return make_int (tt_message_args_count (m)); | |
621 | |
622 else if (EQ (attribute, Qtt_address)) | |
623 return tt_address_symbol (tt_message_address (m)); | |
624 | |
625 else if (EQ (attribute, Qtt_class)) | |
626 return tt_class_symbol (tt_message_class (m)); | |
627 | |
628 else if (EQ (attribute, Qtt_disposition)) | |
629 return make_int (tt_message_disposition (m)); | |
630 | |
631 else if (EQ (attribute, Qtt_file)) | |
771 | 632 return tt_build_c_string (tt_message_file (m)); |
428 | 633 |
634 else if (EQ (attribute, Qtt_gid)) | |
635 return make_int (tt_message_gid (m)); | |
636 | |
637 else if (EQ (attribute, Qtt_handler)) | |
771 | 638 return tt_build_c_string (tt_message_handler (m)); |
428 | 639 |
640 else if (EQ (attribute, Qtt_handler_ptype)) | |
771 | 641 return tt_build_c_string (tt_message_handler_ptype (m)); |
428 | 642 |
643 else if (EQ (attribute, Qtt_object)) | |
771 | 644 return tt_build_c_string (tt_message_object (m)); |
428 | 645 |
646 else if (EQ (attribute, Qtt_op)) | |
771 | 647 return tt_build_c_string (tt_message_op (m)); |
428 | 648 |
649 else if (EQ (attribute, Qtt_opnum)) | |
650 return tt_opnum_string (tt_message_opnum (m)); | |
651 | |
652 else if (EQ (attribute, Qtt_otype)) | |
771 | 653 return tt_build_c_string (tt_message_otype (m)); |
428 | 654 |
655 else if (EQ (attribute, Qtt_scope)) | |
656 return tt_scope_symbol (tt_message_scope (m)); | |
657 | |
658 else if (EQ (attribute, Qtt_sender)) | |
771 | 659 return tt_build_c_string (tt_message_sender (m)); |
428 | 660 |
661 else if (EQ (attribute, Qtt_sender_ptype)) | |
771 | 662 return tt_build_c_string (tt_message_sender_ptype (m)); |
428 | 663 |
664 else if (EQ (attribute, Qtt_session)) | |
771 | 665 return tt_build_c_string (tt_message_session (m)); |
428 | 666 |
667 else if (EQ (attribute, Qtt_state)) | |
668 return tt_state_symbol (tt_message_state (m)); | |
669 | |
670 else if (EQ (attribute, Qtt_status)) | |
671 return make_int (tt_message_status (m)); | |
672 | |
673 else if (EQ (attribute, Qtt_status_string)) | |
771 | 674 return tt_build_c_string (tt_message_status_string (m)); |
428 | 675 |
676 else if (EQ (attribute, Qtt_uid)) | |
677 return make_int (tt_message_uid (m)); | |
678 | |
679 else if (EQ (attribute, Qtt_callback)) | |
680 return XTOOLTALK_MESSAGE (message_)->callback; | |
681 | |
682 else if (EQ (attribute, Qtt_prop)) | |
683 return Fget (XTOOLTALK_MESSAGE (message_)->plist_sym, argn, Qnil); | |
684 | |
685 else if (EQ (attribute, Qtt_plist)) | |
686 return Fcopy_sequence (Fsymbol_plist | |
687 (XTOOLTALK_MESSAGE (message_)->plist_sym)); | |
688 | |
689 else | |
563 | 690 invalid_constant ("Invalid value for `get-tooltalk-message-attribute'", |
428 | 691 attribute); |
692 | |
693 return Qnil; | |
694 } | |
695 | |
696 DEFUN ("set-tooltalk-message-attribute", Fset_tooltalk_message_attribute, | |
697 3, 4, 0, /* | |
698 Initialize one Tooltalk message attribute. | |
699 | |
700 Attribute names and values are the same as for | |
701 `get-tooltalk-message-attribute'. A property list is provided for user | |
3025 | 702 data (instead of the `user' message attribute); see |
428 | 703 `get-tooltalk-message-attribute'. |
704 | |
705 The value of callback should be the name of a function of one argument. | |
706 It will be applied to the message and matching pattern each time the state of the | |
707 message changes. This is usually used to notice when the messages state has | |
708 changed to TT_HANDLED (or TT_FAILED), so that reply argument values | |
709 can be used. | |
710 | |
3025 | 711 If one of the argument attributes is specified, `arg_val', `arg_ival', or |
712 `arg_bval' then argn must be the number of an already created argument. | |
428 | 713 New arguments can be added to a message with add-tooltalk-message-arg. |
714 */ | |
715 (value, message_, attribute, argn)) | |
716 { | |
717 Tt_message m = unbox_tooltalk_message (message_); | |
718 int n = 0; | |
440 | 719 Tt_status (*fun_str) (Tt_message, const char *) = 0; |
428 | 720 |
721 CHECK_SYMBOL (attribute); | |
440 | 722 |
428 | 723 if (EQ (attribute, (Qtt_arg_bval)) || |
724 EQ (attribute, (Qtt_arg_ival)) || | |
725 EQ (attribute, (Qtt_arg_val))) | |
726 { | |
727 CHECK_INT (argn); | |
728 n = XINT (argn); | |
729 } | |
730 | |
731 if (!VALID_TOOLTALK_MESSAGEP (m)) | |
732 return Qnil; | |
733 | |
440 | 734 if (EQ (attribute, Qtt_address)) |
428 | 735 { |
736 CHECK_TOOLTALK_CONSTANT (value); | |
737 tt_message_address_set (m, (Tt_address) tooltalk_constant_value (value)); | |
738 } | |
739 else if (EQ (attribute, Qtt_class)) | |
740 { | |
741 CHECK_TOOLTALK_CONSTANT (value); | |
742 tt_message_class_set (m, (Tt_class) tooltalk_constant_value (value)); | |
743 } | |
744 else if (EQ (attribute, Qtt_disposition)) | |
745 { | |
746 CHECK_TOOLTALK_CONSTANT (value); | |
747 tt_message_disposition_set (m, ((Tt_disposition) | |
748 tooltalk_constant_value (value))); | |
749 } | |
750 else if (EQ (attribute, Qtt_scope)) | |
751 { | |
752 CHECK_TOOLTALK_CONSTANT (value); | |
753 tt_message_scope_set (m, (Tt_scope) tooltalk_constant_value (value)); | |
754 } | |
440 | 755 else if (EQ (attribute, Qtt_file)) |
756 fun_str = tt_message_file_set; | |
757 else if (EQ (attribute, Qtt_handler_ptype)) | |
758 fun_str = tt_message_handler_ptype_set; | |
759 else if (EQ (attribute, Qtt_handler)) | |
760 fun_str = tt_message_handler_set; | |
761 else if (EQ (attribute, Qtt_object)) | |
762 fun_str = tt_message_object_set; | |
763 else if (EQ (attribute, Qtt_op)) | |
764 fun_str = tt_message_op_set; | |
765 else if (EQ (attribute, Qtt_otype)) | |
766 fun_str = tt_message_otype_set; | |
428 | 767 else if (EQ (attribute, Qtt_sender_ptype)) |
440 | 768 fun_str = tt_message_sender_ptype_set; |
428 | 769 else if (EQ (attribute, Qtt_session)) |
440 | 770 fun_str = tt_message_session_set; |
771 else if (EQ (attribute, Qtt_status_string)) | |
772 fun_str = tt_message_status_string_set; | |
428 | 773 else if (EQ (attribute, Qtt_arg_bval)) |
774 { | |
775 Extbyte *value_ext; | |
665 | 776 Bytecount value_ext_len; |
428 | 777 CHECK_STRING (value); |
440 | 778 TO_EXTERNAL_FORMAT (LISP_STRING, value, |
779 ALLOCA, (value_ext, value_ext_len), | |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
780 Qtooltalk_encoding); |
444 | 781 tt_message_arg_bval_set (m, n, (unsigned char *) value_ext, value_ext_len); |
428 | 782 } |
783 else if (EQ (attribute, Qtt_arg_ival)) | |
784 { | |
785 CHECK_INT (value); | |
786 tt_message_arg_ival_set (m, n, XINT (value)); | |
787 } | |
788 else if (EQ (attribute, Qtt_arg_val)) | |
789 { | |
442 | 790 const char *value_ext; |
428 | 791 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
792 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 793 tt_message_arg_val_set (m, n, value_ext); |
794 } | |
795 else if (EQ (attribute, Qtt_status)) | |
796 { | |
797 CHECK_INT (value); | |
798 tt_message_status_set (m, XINT (value)); | |
799 } | |
800 else if (EQ (attribute, Qtt_callback)) | |
801 { | |
802 CHECK_SYMBOL (value); | |
803 XTOOLTALK_MESSAGE (message_)->callback = value; | |
804 } | |
805 else if (EQ (attribute, Qtt_prop)) | |
806 { | |
807 return Fput (XTOOLTALK_MESSAGE (message_)->plist_sym, argn, value); | |
808 } | |
809 else | |
563 | 810 invalid_constant ("Invalid value for `set-tooltalk-message-attribute'", |
428 | 811 attribute); |
440 | 812 |
813 if (fun_str) | |
814 { | |
442 | 815 const char *value_ext; |
440 | 816 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
817 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
440 | 818 (*fun_str) (m, value_ext); |
819 } | |
820 | |
428 | 821 return Qnil; |
822 } | |
823 | |
824 DEFUN ("return-tooltalk-message", Freturn_tooltalk_message, 1, 2, 0, /* | |
825 Send a reply to this message. The second argument can be | |
3025 | 826 `reply', `reject' or `fail'; the default is `reply'. Before sending |
428 | 827 a reply all message arguments whose mode is TT_INOUT or TT_OUT should |
828 have been filled in - see set-tooltalk-message-attribute. | |
829 */ | |
830 (message_, mode)) | |
831 { | |
832 Tt_message m = unbox_tooltalk_message (message_); | |
833 | |
834 if (NILP (mode)) | |
835 mode = Qtt_reply; | |
836 else | |
837 CHECK_SYMBOL (mode); | |
838 | |
839 if (!VALID_TOOLTALK_MESSAGEP (m)) | |
840 return Qnil; | |
841 else if (EQ (mode, Qtt_reply)) | |
842 tt_message_reply (m); | |
843 else if (EQ (mode, Qtt_reject)) | |
844 tt_message_reject (m); | |
845 else if (EQ (mode, Qtt_fail)) | |
846 tt_message_fail (m); | |
847 | |
848 return Qnil; | |
849 } | |
850 | |
851 DEFUN ("create-tooltalk-message", Fcreate_tooltalk_message, 0, 1, 0, /* | |
852 Create a new tooltalk message. | |
853 The messages session attribute is initialized to the default session. | |
854 Other attributes can be initialized with `set-tooltalk-message-attribute'. | |
855 `make-tooltalk-message' is the preferred to create and initialize a message. | |
856 | |
857 Optional arg NO-CALLBACK says don't add a C-level callback at all. | |
858 Normally don't do that; just don't specify the Lisp callback when | |
859 calling `make-tooltalk-message'. | |
860 */ | |
861 (no_callback)) | |
862 { | |
863 Tt_message m = tt_message_create (); | |
864 Lisp_Object message_ = make_tooltalk_message (m); | |
865 if (NILP (no_callback)) | |
866 { | |
867 tt_message_callback_add (m, tooltalk_message_callback); | |
868 } | |
869 tt_message_session_set (m, tt_default_session ()); | |
870 tt_message_user_set (m, TOOLTALK_MESSAGE_KEY, LISP_TO_VOID (message_)); | |
871 return message_; | |
872 } | |
873 | |
874 DEFUN ("destroy-tooltalk-message", Fdestroy_tooltalk_message, 1, 1, 0, /* | |
875 Apply tt_message_destroy() to the message. | |
876 It's not necessary to destroy messages after they've been processed by | |
877 a message or pattern callback; the Lisp/Tooltalk callback machinery does | |
878 this for you. | |
879 */ | |
880 (message_)) | |
881 { | |
882 Tt_message m = unbox_tooltalk_message (message_); | |
883 | |
884 if (VALID_TOOLTALK_MESSAGEP (m)) | |
885 /* #### Should we call Fremhash() here? It seems that | |
886 a common paradigm is | |
887 | |
888 (send-tooltalk-message) | |
889 (destroy-tooltalk-message) | |
890 | |
891 which would imply that destroying a sent ToolTalk message | |
892 doesn't actually destroy it; when a response is sent back, | |
893 the callback for the message will still be called. | |
894 | |
895 But then maybe not: Maybe it really does destroy it, | |
896 and the reason for that paradigm is that the author | |
897 of `send-tooltalk-message' didn't really know what he | |
898 was talking about when he said that it's a good idea | |
899 to call `destroy-tooltalk-message' after sending it. */ | |
900 tt_message_destroy (m); | |
901 | |
902 return Qnil; | |
903 } | |
904 | |
905 | |
906 DEFUN ("add-tooltalk-message-arg", Fadd_tooltalk_message_arg, 3, 4, 0, /* | |
907 Append one new argument to the message. | |
908 MODE must be one of TT_IN, TT_INOUT, or TT_OUT; VTYPE must be a string; | |
909 and VALUE can be a string or an integer. Tooltalk doesn't | |
910 define any semantics for VTYPE, so only the participants in the | |
911 protocol you're using need to agree what types mean (if anything). | |
912 Conventionally "string" is used for strings and "int" for 32 bit integers. | |
913 Arguments can initialized by providing a value or with | |
914 `set-tooltalk-message-attribute'. The latter is necessary if you | |
915 want to initialize the argument with a string that can contain | |
3025 | 916 embedded nulls (use `arg_bval'). |
428 | 917 */ |
918 (message_, mode, vtype, value)) | |
919 { | |
920 Tt_message m = unbox_tooltalk_message (message_); | |
921 Tt_mode n; | |
922 | |
923 CHECK_STRING (vtype); | |
924 CHECK_TOOLTALK_CONSTANT (mode); | |
925 | |
926 n = (Tt_mode) tooltalk_constant_value (mode); | |
927 | |
928 if (!VALID_TOOLTALK_MESSAGEP (m)) | |
929 return Qnil; | |
930 { | |
442 | 931 const char *vtype_ext; |
428 | 932 |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
933 LISP_STRING_TO_EXTERNAL (vtype, vtype_ext, Qtooltalk_encoding); |
428 | 934 if (NILP (value)) |
935 tt_message_arg_add (m, n, vtype_ext, NULL); | |
936 else if (STRINGP (value)) | |
937 { | |
442 | 938 const char *value_ext; |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
939 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 940 tt_message_arg_add (m, n, vtype_ext, value_ext); |
941 } | |
942 else if (INTP (value)) | |
943 tt_message_iarg_add (m, n, vtype_ext, XINT (value)); | |
944 } | |
945 | |
946 return Qnil; | |
947 } | |
948 | |
949 DEFUN ("send-tooltalk-message", Fsend_tooltalk_message, 1, 1, 0, /* | |
950 Send the message on its way. | |
951 Once the message has been sent it's almost always a good idea to get rid of | |
952 it with `destroy-tooltalk-message'. | |
953 */ | |
954 (message_)) | |
955 { | |
956 Tt_message m = unbox_tooltalk_message (message_); | |
957 | |
958 if (VALID_TOOLTALK_MESSAGEP (m)) | |
959 { | |
960 tt_message_send (m); | |
961 Fputhash (message_, Qnil, Vtooltalk_message_gcpro); | |
962 } | |
963 | |
964 return Qnil; | |
965 } | |
966 | |
967 DEFUN ("create-tooltalk-pattern", Fcreate_tooltalk_pattern, 0, 0, 0, /* | |
968 Create a new Tooltalk pattern. | |
969 Its session attribute is initialized to be the default session. | |
970 */ | |
971 ()) | |
972 { | |
973 Tt_pattern p = tt_pattern_create (); | |
974 Lisp_Object pattern = make_tooltalk_pattern (p); | |
975 | |
976 tt_pattern_callback_add (p, tooltalk_pattern_callback); | |
977 tt_pattern_session_add (p, tt_default_session ()); | |
978 tt_pattern_user_set (p, TOOLTALK_PATTERN_KEY, LISP_TO_VOID (pattern)); | |
979 | |
980 return pattern; | |
981 } | |
982 | |
983 | |
984 DEFUN ("destroy-tooltalk-pattern", Fdestroy_tooltalk_pattern, 1, 1, 0, /* | |
985 Apply tt_pattern_destroy() to the pattern. | |
986 This effectively unregisters the pattern. | |
987 */ | |
988 (pattern)) | |
989 { | |
990 Tt_pattern p = unbox_tooltalk_pattern (pattern); | |
991 | |
992 if (VALID_TOOLTALK_PATTERNP (p)) | |
993 { | |
994 tt_pattern_destroy (p); | |
995 Fremhash (pattern, Vtooltalk_pattern_gcpro); | |
996 } | |
997 | |
998 return Qnil; | |
999 } | |
1000 | |
1001 | |
1002 DEFUN ("add-tooltalk-pattern-attribute", Fadd_tooltalk_pattern_attribute, 3, 3, 0, /* | |
1003 Add one value to the indicated pattern attribute. | |
3025 | 1004 All Tooltalk pattern attributes are supported except `user'. The names |
428 | 1005 of attributes are the same as the Tooltalk accessors used to set them |
1006 less the "tooltalk_pattern_" prefix and the "_add" ... | |
1007 */ | |
1008 (value, pattern, attribute)) | |
1009 { | |
1010 Tt_pattern p = unbox_tooltalk_pattern (pattern); | |
1011 | |
1012 CHECK_SYMBOL (attribute); | |
1013 | |
1014 if (!VALID_TOOLTALK_PATTERNP (p)) | |
1015 return Qnil; | |
1016 | |
1017 else if (EQ (attribute, Qtt_category)) | |
1018 { | |
1019 CHECK_TOOLTALK_CONSTANT (value); | |
1020 tt_pattern_category_set (p, ((Tt_category) | |
1021 tooltalk_constant_value (value))); | |
1022 } | |
1023 else if (EQ (attribute, Qtt_address)) | |
1024 { | |
1025 CHECK_TOOLTALK_CONSTANT (value); | |
1026 tt_pattern_address_add (p, ((Tt_address) | |
1027 tooltalk_constant_value (value))); | |
1028 } | |
1029 else if (EQ (attribute, Qtt_class)) | |
1030 { | |
1031 CHECK_TOOLTALK_CONSTANT (value); | |
1032 tt_pattern_class_add (p, (Tt_class) tooltalk_constant_value (value)); | |
1033 } | |
1034 else if (EQ (attribute, Qtt_disposition)) | |
1035 { | |
1036 CHECK_TOOLTALK_CONSTANT (value); | |
1037 tt_pattern_disposition_add (p, ((Tt_disposition) | |
1038 tooltalk_constant_value (value))); | |
1039 } | |
1040 else if (EQ (attribute, Qtt_file)) | |
1041 { | |
442 | 1042 const char *value_ext; |
428 | 1043 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1044 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1045 tt_pattern_file_add (p, value_ext); |
1046 } | |
1047 else if (EQ (attribute, Qtt_object)) | |
1048 { | |
442 | 1049 const char *value_ext; |
428 | 1050 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1051 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1052 tt_pattern_object_add (p, value_ext); |
1053 } | |
1054 else if (EQ (attribute, Qtt_op)) | |
1055 { | |
442 | 1056 const char *value_ext; |
428 | 1057 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1058 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1059 tt_pattern_op_add (p, value_ext); |
1060 } | |
1061 else if (EQ (attribute, Qtt_otype)) | |
1062 { | |
442 | 1063 const char *value_ext; |
428 | 1064 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1065 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1066 tt_pattern_otype_add (p, value_ext); |
1067 } | |
1068 else if (EQ (attribute, Qtt_scope)) | |
1069 { | |
1070 CHECK_TOOLTALK_CONSTANT (value); | |
1071 tt_pattern_scope_add (p, (Tt_scope) tooltalk_constant_value (value)); | |
1072 } | |
1073 else if (EQ (attribute, Qtt_sender)) | |
1074 { | |
442 | 1075 const char *value_ext; |
428 | 1076 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1077 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1078 tt_pattern_sender_add (p, value_ext); |
1079 } | |
1080 else if (EQ (attribute, Qtt_sender_ptype)) | |
1081 { | |
442 | 1082 const char *value_ext; |
428 | 1083 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1084 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1085 tt_pattern_sender_ptype_add (p, value_ext); |
1086 } | |
1087 else if (EQ (attribute, Qtt_session)) | |
1088 { | |
442 | 1089 const char *value_ext; |
428 | 1090 CHECK_STRING (value); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1091 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1092 tt_pattern_session_add (p, value_ext); |
1093 } | |
1094 else if (EQ (attribute, Qtt_state)) | |
1095 { | |
1096 CHECK_TOOLTALK_CONSTANT (value); | |
1097 tt_pattern_state_add (p, (Tt_state) tooltalk_constant_value (value)); | |
1098 } | |
1099 else if (EQ (attribute, Qtt_callback)) | |
1100 { | |
1101 CHECK_SYMBOL (value); | |
1102 XTOOLTALK_PATTERN (pattern)->callback = value; | |
1103 } | |
1104 | |
1105 return Qnil; | |
1106 } | |
1107 | |
1108 | |
1109 DEFUN ("add-tooltalk-pattern-arg", Fadd_tooltalk_pattern_arg, 3, 4, 0, /* | |
1110 Add one fully specified argument to a tooltalk pattern. | |
1111 Mode must be one of TT_IN, TT_INOUT, or TT_OUT, type must be a string. | |
1112 Value can be an integer, string or nil. If value is an integer then | |
1113 an integer argument (tt_pattern_iarg_add) added otherwise a string argument | |
1114 is added. At present there's no way to add a binary data argument. | |
1115 */ | |
1116 (pattern, mode, vtype, value)) | |
1117 { | |
1118 Tt_pattern p = unbox_tooltalk_pattern (pattern); | |
1119 Tt_mode n; | |
1120 | |
1121 CHECK_STRING (vtype); | |
1122 CHECK_TOOLTALK_CONSTANT (mode); | |
1123 | |
1124 n = (Tt_mode) tooltalk_constant_value (mode); | |
1125 | |
1126 if (!VALID_TOOLTALK_PATTERNP (p)) | |
1127 return Qnil; | |
1128 | |
1129 { | |
442 | 1130 const char *vtype_ext; |
428 | 1131 |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1132 LISP_STRING_TO_EXTERNAL (vtype, vtype_ext, Qtooltalk_encoding); |
428 | 1133 if (NILP (value)) |
1134 tt_pattern_arg_add (p, n, vtype_ext, NULL); | |
1135 else if (STRINGP (value)) | |
1136 { | |
442 | 1137 const char *value_ext; |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1138 LISP_STRING_TO_EXTERNAL (value, value_ext, Qtooltalk_encoding); |
428 | 1139 tt_pattern_arg_add (p, n, vtype_ext, value_ext); |
1140 } | |
1141 else if (INTP (value)) | |
1142 tt_pattern_iarg_add (p, n, vtype_ext, XINT (value)); | |
1143 } | |
1144 | |
1145 return Qnil; | |
1146 } | |
1147 | |
1148 | |
1149 DEFUN ("register-tooltalk-pattern", Fregister_tooltalk_pattern, 1, 1, 0, /* | |
1150 Emacs will begin receiving messages that match this pattern. | |
1151 */ | |
1152 (pattern)) | |
1153 { | |
1154 Tt_pattern p = unbox_tooltalk_pattern (pattern); | |
1155 | |
1156 if (VALID_TOOLTALK_PATTERNP (p) && tt_pattern_register (p) == TT_OK) | |
1157 { | |
1158 Fputhash (pattern, Qnil, Vtooltalk_pattern_gcpro); | |
1159 return Qt; | |
1160 } | |
1161 else | |
1162 return Qnil; | |
1163 } | |
1164 | |
1165 | |
1166 DEFUN ("unregister-tooltalk-pattern", Funregister_tooltalk_pattern, 1, 1, 0, /* | |
1167 Emacs will stop receiving messages that match this pattern. | |
1168 */ | |
1169 (pattern)) | |
1170 { | |
1171 Tt_pattern p = unbox_tooltalk_pattern (pattern); | |
1172 | |
1173 if (VALID_TOOLTALK_PATTERNP (p)) | |
1174 { | |
1175 tt_pattern_unregister (p); | |
1176 Fremhash (pattern, Vtooltalk_pattern_gcpro); | |
1177 } | |
1178 | |
1179 return Qnil; | |
1180 } | |
1181 | |
1182 | |
1183 DEFUN ("tooltalk-pattern-prop-get", Ftooltalk_pattern_prop_get, 2, 2, 0, /* | |
1184 Return the value of PROPERTY in tooltalk pattern PATTERN. | |
1185 This is the last value set with `tooltalk-pattern-prop-set'. | |
1186 */ | |
1187 (pattern, property)) | |
1188 { | |
1189 CHECK_TOOLTALK_PATTERN (pattern); | |
1190 return Fget (XTOOLTALK_PATTERN (pattern)->plist_sym, property, Qnil); | |
1191 } | |
1192 | |
1193 | |
1194 DEFUN ("tooltalk-pattern-prop-set", Ftooltalk_pattern_prop_set, 3, 3, 0, /* | |
1195 Set the value of PROPERTY to VALUE in tooltalk pattern PATTERN. | |
1196 It can be retrieved with `tooltalk-pattern-prop-get'. | |
1197 */ | |
1198 (pattern, property, value)) | |
1199 { | |
1200 CHECK_TOOLTALK_PATTERN (pattern); | |
1201 return Fput (XTOOLTALK_PATTERN (pattern)->plist_sym, property, value); | |
1202 } | |
1203 | |
1204 | |
1205 DEFUN ("tooltalk-pattern-plist-get", Ftooltalk_pattern_plist_get, 1, 1, 0, /* | |
1206 Return the a list of all the properties currently set in PATTERN. | |
1207 */ | |
1208 (pattern)) | |
1209 { | |
1210 CHECK_TOOLTALK_PATTERN (pattern); | |
1211 return | |
1212 Fcopy_sequence (Fsymbol_plist (XTOOLTALK_PATTERN (pattern)->plist_sym)); | |
1213 } | |
1214 | |
1215 DEFUN ("tooltalk-default-procid", Ftooltalk_default_procid, 0, 0, 0, /* | |
1216 Return current default process identifier for your process. | |
1217 */ | |
1218 ()) | |
1219 { | |
1220 char *procid = tt_default_procid (); | |
1221 return procid ? build_string (procid) : Qnil; | |
1222 } | |
1223 | |
1224 DEFUN ("tooltalk-default-session", Ftooltalk_default_session, 0, 0, 0, /* | |
1225 Return current default session identifier for the current default procid. | |
1226 */ | |
1227 ()) | |
1228 { | |
1229 char *session = tt_default_session (); | |
1230 return session ? build_string (session) : Qnil; | |
1231 } | |
1232 | |
1233 static void | |
1234 init_tooltalk (void) | |
1235 { | |
1236 /* This function can GC */ | |
1237 char *retval; | |
1238 Lisp_Object lp; | |
1239 Lisp_Object fil; | |
1240 | |
1241 | |
440 | 1242 /* tt_open() messes with our signal handler flags (at least when no |
1243 ttsessions is running on the machine), therefore we save the | |
428 | 1244 actions and restore them after the call */ |
1245 #ifdef HAVE_SIGPROCMASK | |
1246 { | |
1247 struct sigaction ActSIGQUIT; | |
1248 struct sigaction ActSIGINT; | |
1249 struct sigaction ActSIGCHLD; | |
1250 sigaction (SIGQUIT, NULL, &ActSIGQUIT); | |
1251 sigaction (SIGINT, NULL, &ActSIGINT); | |
1252 sigaction (SIGCHLD, NULL, &ActSIGCHLD); | |
1253 #endif | |
1254 retval = tt_open (); | |
1255 #ifdef HAVE_SIGPROCMASK | |
1256 sigaction (SIGQUIT, &ActSIGQUIT, NULL); | |
1257 sigaction (SIGINT, &ActSIGINT, NULL); | |
1258 sigaction (SIGCHLD, &ActSIGCHLD, NULL); | |
1259 } | |
1260 #endif | |
1261 | |
1262 | |
1263 if (tt_ptr_error (retval) != TT_OK) | |
1264 return; | |
1265 | |
1266 Vtooltalk_fd = make_int (tt_fd ()); | |
1267 | |
1268 tt_session_join (tt_default_session ()); | |
1269 | |
1270 lp = connect_to_file_descriptor (build_string ("tooltalk"), Qnil, | |
1271 Vtooltalk_fd, Vtooltalk_fd); | |
1272 if (!NILP (lp)) | |
1273 { | |
1274 /* Don't ask the user for confirmation when exiting Emacs */ | |
1275 Fprocess_kill_without_query (lp, Qnil); | |
2834 | 1276 fil = GET_DEFUN_LISP_OBJECT (Freceive_tooltalk_message); |
853 | 1277 set_process_filter (lp, fil, 1, 0); |
428 | 1278 } |
1279 else | |
1280 { | |
1281 tt_close (); | |
1282 Vtooltalk_fd = Qnil; | |
1283 return; | |
1284 } | |
1285 | |
1286 #if defined (SOLARIS2) | |
1287 /* Apparently the tt_message_send_on_exit() function does not exist | |
1288 under SunOS 4.x or IRIX 5 or various other non-Solaris-2 systems. | |
1289 No big deal if we don't do the following under those systems. */ | |
1290 { | |
1291 Tt_message exit_msg = tt_message_create (); | |
1292 | |
1293 tt_message_op_set (exit_msg, "emacs-aborted"); | |
1294 tt_message_scope_set (exit_msg, TT_SESSION); | |
1295 tt_message_class_set (exit_msg, TT_NOTICE); | |
1296 tt_message_send_on_exit (exit_msg); | |
1297 tt_message_destroy (exit_msg); | |
1298 } | |
1299 #endif | |
1300 } | |
1301 | |
1302 DEFUN ("tooltalk-open-connection", Ftooltalk_open_connection, 0, 0, 0, /* | |
1303 Opens a connection to the ToolTalk server. | |
1304 Returns t if successful, nil otherwise. | |
1305 */ | |
1306 ()) | |
1307 { | |
1308 if (!NILP (Vtooltalk_fd)) | |
563 | 1309 signal_error (Qio_error, "Already connected to ToolTalk", Qunbound); |
428 | 1310 if (noninteractive) |
563 | 1311 signal_error (Qio_error, "Can't connect to ToolTalk in batch mode", Qunbound); |
428 | 1312 init_tooltalk (); |
1313 return NILP (Vtooltalk_fd) ? Qnil : Qt; | |
1314 } | |
1315 | |
1316 | |
1317 void | |
1318 syms_of_tooltalk (void) | |
1319 { | |
442 | 1320 INIT_LRECORD_IMPLEMENTATION (tooltalk_message); |
1321 INIT_LRECORD_IMPLEMENTATION (tooltalk_pattern); | |
1322 | |
563 | 1323 DEFSYMBOL_MULTIWORD_PREDICATE (Qtooltalk_messagep); |
428 | 1324 DEFSUBR (Ftooltalk_message_p); |
563 | 1325 DEFSYMBOL_MULTIWORD_PREDICATE (Qtooltalk_patternp); |
428 | 1326 DEFSUBR (Ftooltalk_pattern_p); |
563 | 1327 DEFSYMBOL (Qtooltalk_message_handler_hook); |
1328 DEFSYMBOL (Qtooltalk_pattern_handler_hook); | |
1329 DEFSYMBOL (Qtooltalk_unprocessed_message_hook); | |
428 | 1330 |
1331 DEFSUBR (Freceive_tooltalk_message); | |
1332 DEFSUBR (Fcreate_tooltalk_message); | |
1333 DEFSUBR (Fdestroy_tooltalk_message); | |
1334 DEFSUBR (Fadd_tooltalk_message_arg); | |
1335 DEFSUBR (Fget_tooltalk_message_attribute); | |
1336 DEFSUBR (Fset_tooltalk_message_attribute); | |
1337 DEFSUBR (Fsend_tooltalk_message); | |
1338 DEFSUBR (Freturn_tooltalk_message); | |
1339 DEFSUBR (Fcreate_tooltalk_pattern); | |
1340 DEFSUBR (Fdestroy_tooltalk_pattern); | |
1341 DEFSUBR (Fadd_tooltalk_pattern_attribute); | |
1342 DEFSUBR (Fadd_tooltalk_pattern_arg); | |
1343 DEFSUBR (Fregister_tooltalk_pattern); | |
1344 DEFSUBR (Funregister_tooltalk_pattern); | |
1345 DEFSUBR (Ftooltalk_pattern_plist_get); | |
1346 DEFSUBR (Ftooltalk_pattern_prop_set); | |
1347 DEFSUBR (Ftooltalk_pattern_prop_get); | |
1348 DEFSUBR (Ftooltalk_default_procid); | |
1349 DEFSUBR (Ftooltalk_default_session); | |
1350 DEFSUBR (Ftooltalk_open_connection); | |
1351 | |
563 | 1352 DEFSYMBOL (Qreceive_tooltalk_message); |
428 | 1353 defsymbol (&Qtt_address, "address"); |
1354 defsymbol (&Qtt_args_count, "args_count"); | |
1355 defsymbol (&Qtt_arg_bval, "arg_bval"); | |
1356 defsymbol (&Qtt_arg_ival, "arg_ival"); | |
1357 defsymbol (&Qtt_arg_mode, "arg_mode"); | |
1358 defsymbol (&Qtt_arg_type, "arg_type"); | |
1359 defsymbol (&Qtt_arg_val, "arg_val"); | |
1360 defsymbol (&Qtt_class, "class"); | |
1361 defsymbol (&Qtt_category, "category"); | |
1362 defsymbol (&Qtt_disposition, "disposition"); | |
1363 defsymbol (&Qtt_file, "file"); | |
1364 defsymbol (&Qtt_gid, "gid"); | |
1365 defsymbol (&Qtt_handler, "handler"); | |
1366 defsymbol (&Qtt_handler_ptype, "handler_ptype"); | |
1367 defsymbol (&Qtt_object, "object"); | |
1368 defsymbol (&Qtt_op, "op"); | |
1369 defsymbol (&Qtt_opnum, "opnum"); | |
1370 defsymbol (&Qtt_otype, "otype"); | |
1371 defsymbol (&Qtt_scope, "scope"); | |
1372 defsymbol (&Qtt_sender, "sender"); | |
1373 defsymbol (&Qtt_sender_ptype, "sender_ptype"); | |
1374 defsymbol (&Qtt_session, "session"); | |
1375 defsymbol (&Qtt_state, "state"); | |
1376 defsymbol (&Qtt_status, "status"); | |
1377 defsymbol (&Qtt_status_string, "status_string"); | |
1378 defsymbol (&Qtt_uid, "uid"); | |
1379 defsymbol (&Qtt_callback, "callback"); | |
1380 defsymbol (&Qtt_prop, "prop"); | |
1381 defsymbol (&Qtt_plist, "plist"); | |
1382 defsymbol (&Qtt_reject, "reject"); | |
1383 defsymbol (&Qtt_reply, "reply"); | |
1384 defsymbol (&Qtt_fail, "fail"); | |
1385 | |
442 | 1386 DEFERROR (Qtooltalk_error, "ToolTalk error", Qio_error); |
428 | 1387 } |
1388 | |
1389 void | |
1390 vars_of_tooltalk (void) | |
1391 { | |
1392 Fprovide (intern ("tooltalk")); | |
1393 | |
1394 DEFVAR_LISP ("tooltalk-fd", &Vtooltalk_fd /* | |
1395 File descriptor returned by tt_initialize; nil if not connected to ToolTalk. | |
1396 */ ); | |
1397 Vtooltalk_fd = Qnil; | |
1398 | |
1399 DEFVAR_LISP ("tooltalk-message-handler-hook", | |
1400 &Vtooltalk_message_handler_hook /* | |
1401 List of functions to be applied to each ToolTalk message reply received. | |
1402 This will always occur as a result of our sending a request message. | |
1403 Functions will be called with two arguments, the message and the | |
1404 corresponding pattern. This hook will not be called if the request | |
1405 message was created without a C-level callback function (see | |
1406 `tooltalk-unprocessed-message-hook'). | |
1407 */ ); | |
1408 Vtooltalk_message_handler_hook = Qnil; | |
1409 | |
1410 DEFVAR_LISP ("tooltalk-pattern-handler-hook", | |
1411 &Vtooltalk_pattern_handler_hook /* | |
1412 List of functions to be applied to each pattern-matching ToolTalk message. | |
1413 This is all messages except those handled by `tooltalk-message-handler-hook'. | |
1414 Functions will be called with two arguments, the message and the | |
1415 corresponding pattern. | |
1416 */ ); | |
1417 Vtooltalk_pattern_handler_hook = Qnil; | |
1418 | |
1419 DEFVAR_LISP ("tooltalk-unprocessed-message-hook", | |
1420 &Vtooltalk_unprocessed_message_hook /* | |
1421 List of functions to be applied to each unprocessed ToolTalk message. | |
1422 Unprocessed messages are messages that didn't match any patterns. | |
1423 */ ); | |
1424 Vtooltalk_unprocessed_message_hook = Qnil; | |
1425 | |
771 | 1426 Tooltalk_Message_plist_str = build_msg_string ("Tooltalk Message plist"); |
1427 Tooltalk_Pattern_plist_str = build_msg_string ("Tooltalk Pattern plist"); | |
428 | 1428 |
1429 staticpro(&Tooltalk_Message_plist_str); | |
1430 staticpro(&Tooltalk_Pattern_plist_str); | |
1431 | |
1432 #define MAKE_CONSTANT(name) do { \ | |
1433 defsymbol (&Q_ ## name, #name); \ | |
1434 Fset (Q_ ## name, make_int (name)); \ | |
1435 } while (0) | |
1436 | |
1437 MAKE_CONSTANT (TT_MODE_UNDEFINED); | |
1438 MAKE_CONSTANT (TT_IN); | |
1439 MAKE_CONSTANT (TT_OUT); | |
1440 MAKE_CONSTANT (TT_INOUT); | |
1441 MAKE_CONSTANT (TT_MODE_LAST); | |
1442 | |
1443 MAKE_CONSTANT (TT_SCOPE_NONE); | |
1444 MAKE_CONSTANT (TT_SESSION); | |
1445 MAKE_CONSTANT (TT_FILE); | |
1446 MAKE_CONSTANT (TT_BOTH); | |
1447 MAKE_CONSTANT (TT_FILE_IN_SESSION); | |
1448 | |
1449 MAKE_CONSTANT (TT_CLASS_UNDEFINED); | |
1450 MAKE_CONSTANT (TT_NOTICE); | |
1451 MAKE_CONSTANT (TT_REQUEST); | |
1452 MAKE_CONSTANT (TT_CLASS_LAST); | |
1453 | |
1454 MAKE_CONSTANT (TT_CATEGORY_UNDEFINED); | |
1455 MAKE_CONSTANT (TT_OBSERVE); | |
1456 MAKE_CONSTANT (TT_HANDLE); | |
1457 MAKE_CONSTANT (TT_CATEGORY_LAST); | |
1458 | |
1459 MAKE_CONSTANT (TT_PROCEDURE); | |
1460 MAKE_CONSTANT (TT_OBJECT); | |
1461 MAKE_CONSTANT (TT_HANDLER); | |
1462 MAKE_CONSTANT (TT_OTYPE); | |
1463 MAKE_CONSTANT (TT_ADDRESS_LAST); | |
1464 | |
1465 MAKE_CONSTANT (TT_CREATED); | |
1466 MAKE_CONSTANT (TT_SENT); | |
1467 MAKE_CONSTANT (TT_HANDLED); | |
1468 MAKE_CONSTANT (TT_FAILED); | |
1469 MAKE_CONSTANT (TT_QUEUED); | |
1470 MAKE_CONSTANT (TT_STARTED); | |
1471 MAKE_CONSTANT (TT_REJECTED); | |
1472 MAKE_CONSTANT (TT_STATE_LAST); | |
1473 | |
1474 MAKE_CONSTANT (TT_DISCARD); | |
1475 MAKE_CONSTANT (TT_QUEUE); | |
1476 MAKE_CONSTANT (TT_START); | |
1477 | |
1478 #undef MAKE_CONSTANT | |
1479 | |
1480 staticpro (&Vtooltalk_message_gcpro); | |
1481 staticpro (&Vtooltalk_pattern_gcpro); | |
1482 Vtooltalk_message_gcpro = | |
1483 make_lisp_hash_table (10, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); | |
1484 Vtooltalk_pattern_gcpro = | |
1485 make_lisp_hash_table (10, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); | |
1486 } |