comparison src/console-msw.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children 11054d720c21
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
1 /* Console functions for mswindows. 1 /* Console functions for mswindows.
2 Copyright (C) 1996, 2000 Ben Wing. 2 Copyright (C) 1996 Ben Wing.
3 3
4 This file is part of XEmacs. 4 This file is part of XEmacs.
5 5
6 XEmacs is free software; you can redistribute it and/or modify it 6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 7 under the terms of the GNU General Public License as published by the
27 */ 27 */
28 28
29 #include <config.h> 29 #include <config.h>
30 #include "lisp.h" 30 #include "lisp.h"
31 31
32 #include "buffer.h"
33 #include "console-msw.h" 32 #include "console-msw.h"
34 #include "events.h" 33
35 #include "opaque.h"
36 34
37 DEFINE_CONSOLE_TYPE (mswindows); 35 DEFINE_CONSOLE_TYPE (mswindows);
38 DEFINE_CONSOLE_TYPE (msprinter);
39 36
40 Lisp_Object Qabortretryignore;
41 Lisp_Object Qapplmodal;
42 Lisp_Object Qdefault_desktop_only;
43 Lisp_Object Qdefbutton1;
44 Lisp_Object Qdefbutton2;
45 Lisp_Object Qdefbutton3;
46 Lisp_Object Qdefbutton4;
47 /* Lisp_Object Qhelp; */
48 Lisp_Object Qiconasterisk;
49 Lisp_Object Qiconexclamation;
50 Lisp_Object Qiconhand;
51 Lisp_Object Qiconinformation;
52 Lisp_Object Qiconquestion;
53 Lisp_Object Qiconstop;
54 /* Lisp_Object Qok; */
55 Lisp_Object Qokcancel;
56 Lisp_Object Qretrycancel;
57 /* Lisp_Object Qright; */
58 Lisp_Object Qrtlreading;
59 Lisp_Object Qservice_notification;
60 Lisp_Object Qsetforeground;
61 Lisp_Object Qsystemmodal;
62 Lisp_Object Qtaskmodal;
63 Lisp_Object Qtopmost;
64 Lisp_Object Qyesno;
65 Lisp_Object Qyesnocancel;
66
67 /* Lisp_Object Qabort; */
68 /* Lisp_Object Qcancel; */
69 /* Lisp_Object Qignore; */
70 /* Lisp_Object Qno; */
71 /* Lisp_Object Qok; */
72 /* Lisp_Object Qretry; */
73 /* Lisp_Object Qyes; */
74
75
76 /************************************************************************/
77 /* mswindows console methods */
78 /************************************************************************/
79 37
80 static int 38 static int
81 mswindows_initially_selected_for_input (struct console *con) 39 mswindows_initially_selected_for_input (struct console *con)
82 { 40 {
83 return 1; 41 return 1;
84 } 42 }
85 43
86 static HWND mswindows_console_hwnd = 0;
87 44
88 #define KLUDGE_BUFSIZE 1024 /* buffer size for console window titles */
89
90 /* Direct from the horse's mouth: Microsoft KB article Q124103 */
91 static HWND
92 GetConsoleHwnd (void)
93 {
94 HWND hwndFound; /* this is what is returned to the caller */
95 char pszNewWindowTitle[KLUDGE_BUFSIZE]; /* contains fabricated WindowTitle */
96 char pszOldWindowTitle[KLUDGE_BUFSIZE]; /* contains original WindowTitle */
97
98 /* fetch current window title */
99
100 GetConsoleTitle(pszOldWindowTitle, KLUDGE_BUFSIZE);
101
102 /* format a "unique" NewWindowTitle */
103
104 wsprintf(pszNewWindowTitle,"%d/%d",
105 GetTickCount(),
106 GetCurrentProcessId());
107
108 /* change current window title */
109
110 SetConsoleTitle(pszNewWindowTitle);
111
112 /* ensure window title has been updated */
113
114 Sleep(40);
115
116 /* look for NewWindowTitle */
117
118 hwndFound=FindWindow(NULL, pszNewWindowTitle);
119
120 /* restore original window title */
121
122 SetConsoleTitle(pszOldWindowTitle);
123
124 return(hwndFound);
125 }
126
127 HWND
128 mswindows_get_console_hwnd (void)
129 {
130 if (!mswindows_console_hwnd)
131 mswindows_console_hwnd = GetConsoleHwnd ();
132 return mswindows_console_hwnd;
133 }
134
135 static int
136 mswindows_ensure_console_allocated (void)
137 {
138 HWND fgwin = GetForegroundWindow ();
139 /* stupid mswin api won't let you create the console window
140 hidden! creating it changes the focus! fuck me! */
141 if (AllocConsole ())
142 {
143 SetForegroundWindow (fgwin);
144 return 1;
145 }
146 return 0;
147 }
148
149 static Lisp_Object
150 mswindows_canonicalize_console_connection (Lisp_Object connection,
151 Error_behavior errb)
152 {
153 /* Do not allow more than one mswindows device, by explicitly
154 requiring that CONNECTION is nil, the only allowed connection in
155 Windows. */
156 if (!NILP (connection))
157 {
158 if (ERRB_EQ (errb, ERROR_ME))
159 signal_simple_error
160 ("Invalid (non-nil) connection for mswindows device/console",
161 connection);
162 else
163 return Qunbound;
164 }
165
166 return Qnil;
167 }
168
169 static Lisp_Object
170 mswindows_canonicalize_device_connection (Lisp_Object connection,
171 Error_behavior errb)
172 {
173 return mswindows_canonicalize_console_connection (connection, errb);
174 }
175
176 void
177 mswindows_hide_console (void)
178 {
179 ShowWindow (mswindows_get_console_hwnd (), SW_HIDE);
180 }
181
182 void
183 mswindows_show_console (void)
184 {
185 HWND hwnd = mswindows_get_console_hwnd ();
186 ShowWindow (hwnd, SW_SHOWNA);
187
188 /* I tried to raise the window to the top without activating
189 it, but this fails. Apparently Windows just doesn't like
190 having the active window not be on top. So instead, we
191 at least put it just below our own window, where part of it
192 will likely be seen. */
193 SetWindowPos (hwnd, GetForegroundWindow (), 0, 0, 0, 0,
194 SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING |
195 SWP_NOACTIVATE);
196 }
197
198 static int mswindows_console_buffered = 0;
199 HANDLE mswindows_console_buffer;
200
201 static void
202 mswindows_ensure_console_buffered (void)
203 {
204 if (!mswindows_console_buffered)
205 {
206 COORD new_size;
207
208 new_size.X = 80;
209 new_size.Y = 1000;
210 mswindows_ensure_console_allocated ();
211 mswindows_console_buffer =
212 CreateConsoleScreenBuffer (GENERIC_WRITE, 0, NULL,
213 CONSOLE_TEXTMODE_BUFFER, NULL);
214 SetConsoleScreenBufferSize (mswindows_console_buffer, new_size);
215 SetConsoleActiveScreenBuffer (mswindows_console_buffer);
216 mswindows_console_buffered = 1;
217 }
218 }
219
220 int mswindows_message_outputted;
221
222 int
223 mswindows_output_console_string (CONST Extbyte *str, Extcount len)
224 {
225 DWORD num_written;
226
227 mswindows_message_outputted = 1;
228 mswindows_ensure_console_buffered ();
229 mswindows_show_console ();
230 return WriteConsole (mswindows_console_buffer, str, len, &num_written, NULL);
231 }
232
233 /* Determine if running on Windows 9x and not NT */
234 int
235 mswindows_windows9x_p (void)
236 {
237 return GetVersion () & 0x80000000;
238 }
239
240
241 #ifdef DEBUG_XEMACS
242
243 /*
244 * Random helper functions for debugging.
245 * Intended for use in the MSVC "Watch" window which doesn't like
246 * the aborts that the error_check_foo() functions can make.
247 */
248 struct lrecord_header *DHEADER (Lisp_Object obj);
249 struct lrecord_header *
250 DHEADER (Lisp_Object obj)
251 {
252 return LRECORDP (obj) ? XRECORD_LHEADER (obj) : NULL;
253 }
254
255 void *DOPAQUE_DATA (Lisp_Object obj);
256 void *
257 DOPAQUE_DATA (Lisp_Object obj)
258 {
259 return OPAQUEP (obj) ? OPAQUE_DATA (XOPAQUE (obj)) : NULL;
260 }
261
262 Lisp_Event *DEVENT (Lisp_Object obj);
263 Lisp_Event *
264 DEVENT (Lisp_Object obj)
265 {
266 return EVENTP (obj) ? XEVENT (obj) : NULL;
267 }
268
269 Lisp_Cons *DCONS (Lisp_Object obj);
270 Lisp_Cons *
271 DCONS (Lisp_Object obj)
272 {
273 return CONSP (obj) ? XCONS (obj) : NULL;
274 }
275
276 Lisp_Cons *DCONSCDR (Lisp_Object obj);
277 Lisp_Cons *
278 DCONSCDR (Lisp_Object obj)
279 {
280 return (CONSP (obj) && CONSP (XCDR (obj))) ? XCONS (XCDR (obj)) : 0;
281 }
282
283 Bufbyte *DSTRING (Lisp_Object obj);
284 Bufbyte *
285 DSTRING (Lisp_Object obj)
286 {
287 return STRINGP (obj) ? XSTRING_DATA (obj) : NULL;
288 }
289
290 Lisp_Vector *DVECTOR (Lisp_Object obj);
291 Lisp_Vector *
292 DVECTOR (Lisp_Object obj)
293 {
294 return VECTORP (obj) ? XVECTOR (obj) : NULL;
295 }
296
297 Lisp_Symbol *DSYMBOL (Lisp_Object obj);
298 Lisp_Symbol *
299 DSYMBOL (Lisp_Object obj)
300 {
301 return SYMBOLP (obj) ? XSYMBOL (obj) : NULL;
302 }
303
304 Bufbyte *DSYMNAME (Lisp_Object obj);
305 Bufbyte *
306 DSYMNAME (Lisp_Object obj)
307 {
308 return SYMBOLP (obj) ? string_data (XSYMBOL (obj)->name) : NULL;
309 }
310
311 #endif /* DEBUG_XEMACS */
312
313 DEFUN ("mswindows-message-box", Fmswindows_message_box, 1, 3, 0, /*
314 Pop up an MS Windows message box.
315 MESSAGE is the string to display. Optional argument FLAG controls
316 what appears in the box and how it behaves; it is a symbol or list of
317 symbols, described below. Second optional argument TITLE controls the
318 title bar; if omitted, a standard title bar will be used, probably
319 displaying "XEmacs".
320
321 Possible flags are
322
323
324 -- To specify the buttons in the message box:
325
326 abortretryignore
327 The message box contains three push buttons: Abort, Retry, and Ignore.
328 ok
329 The message box contains one push button: OK. This is the default.
330 okcancel
331 The message box contains two push buttons: OK and Cancel.
332 retrycancel
333 The message box contains two push buttons: Retry and Cancel.
334 yesno
335 The message box contains two push buttons: Yes and No.
336 yesnocancel
337 The message box contains three push buttons: Yes, No, and Cancel.
338
339
340 -- To display an icon in the message box:
341
342 iconexclamation, iconwarning
343 An exclamation-point icon appears in the message box.
344 iconinformation, iconasterisk
345 An icon consisting of a lowercase letter i in a circle appears in
346 the message box.
347 iconquestion
348 A question-mark icon appears in the message box.
349 iconstop, iconerror, iconhand
350 A stop-sign icon appears in the message box.
351
352
353 -- To indicate the default button:
354
355 defbutton1
356 The first button is the default button. This is the default.
357 defbutton2
358 The second button is the default button.
359 defbutton3
360 The third button is the default button.
361 defbutton4
362 The fourth button is the default button.
363
364
365 -- To indicate the modality of the dialog box:
366
367 applmodal
368 The user must respond to the message box before continuing work in
369 the window identified by the hWnd parameter. However, the user can
370 move to the windows of other applications and work in those windows.
371 Depending on the hierarchy of windows in the application, the user
372 may be able to move to other windows within the application. All
373 child windows of the parent of the message box are automatically
374 disabled, but popup windows are not. This is the default.
375 systemmodal
376 Same as applmodal except that the message box has the WS_EX_TOPMOST
377 style. Use system-modal message boxes to notify the user of serious,
378 potentially damaging errors that require immediate attention (for
379 example, running out of memory). This flag has no effect on the
380 user's ability to interact with windows other than those associated
381 with hWnd.
382 taskmodal
383 Same as applmodal except that all the top-level windows belonging to
384 the current task are disabled if the hWnd parameter is NULL. Use
385 this flag when the calling application or library does not have a
386 window handle available but still needs to prevent input to other
387 windows in the current application without suspending other
388 applications.
389
390
391 In addition, you can specify the following flags:
392
393 default-desktop-only
394 The desktop currently receiving input must be a default desktop;
395 otherwise, the function fails. A default desktop is one an
396 application runs on after the user has logged on.
397 help
398 Adds a Help button to the message box. Choosing the Help button or
399 pressing F1 generates a Help event.
400 right
401 The text is right-justified.
402 rtlreading
403 Displays message and caption text using right-to-left reading order
404 on Hebrew and Arabic systems.
405 setforeground
406 The message box becomes the foreground window. Internally, Windows
407 calls the SetForegroundWindow function for the message box.
408 topmost
409 The message box is created with the WS_EX_TOPMOST window style.
410 service-notification
411 Windows NT only: The caller is a service notifying the user of an
412 event. The function displays a message box on the current active
413 desktop, even if there is no user logged on to the computer. If
414 this flag is set, the hWnd parameter must be NULL. This is so the
415 message box can appear on a desktop other than the desktop
416 corresponding to the hWnd.
417
418
419
420 The return value is one of the following menu-item values returned by
421 the dialog box:
422
423 abort
424 Abort button was selected.
425 cancel
426 Cancel button was selected.
427 ignore
428 Ignore button was selected.
429 no
430 No button was selected.
431 ok
432 OK button was selected.
433 retry
434 Retry button was selected.
435 yes
436 Yes button was selected.
437
438 If a message box has a Cancel button, the function returns the
439 `cancel' value if either the ESC key is pressed or the Cancel button
440 is selected. If the message box has no Cancel button, pressing ESC has
441 no effect. */
442 (message_, flags, title))
443 {
444 Lisp_Object tail;
445 Extbyte *msgout;
446 Extbyte *titleout = 0;
447 UINT sty = 0;
448
449 if (noninteractive)
450 return Qcancel;
451
452 if (!CONSP (flags))
453 {
454 CHECK_SYMBOL (flags);
455 flags = list1 (flags);
456 }
457
458 CHECK_STRING (message_);
459 TO_EXTERNAL_FORMAT (LISP_STRING, message_,
460 C_STRING_ALLOCA, msgout,
461 Qmswindows_tstr);
462
463 if (!NILP (title))
464 {
465 CHECK_STRING (title);
466 TO_EXTERNAL_FORMAT (LISP_STRING, title,
467 C_STRING_ALLOCA, titleout,
468 Qmswindows_tstr);
469 }
470
471 EXTERNAL_LIST_LOOP (tail, flags)
472 {
473 Lisp_Object st = XCAR (tail);
474 CHECK_SYMBOL (st);
475 if (0)
476 ;
477 #define FROB(sym, val) else if (EQ (st, sym)) sty |= val
478 FROB (Qabortretryignore, MB_ABORTRETRYIGNORE);
479 FROB (Qapplmodal, MB_APPLMODAL);
480 FROB (Qdefault_desktop_only, MB_DEFAULT_DESKTOP_ONLY);
481 FROB (Qdefbutton1, MB_DEFBUTTON1);
482 FROB (Qdefbutton2, MB_DEFBUTTON2);
483 FROB (Qdefbutton3, MB_DEFBUTTON3);
484 FROB (Qdefbutton4, MB_DEFBUTTON4);
485 FROB (Qhelp, MB_HELP);
486 FROB (Qiconasterisk, MB_ICONASTERISK);
487 FROB (Qiconexclamation, MB_ICONEXCLAMATION);
488 FROB (Qiconhand, MB_ICONHAND);
489 FROB (Qiconinformation, MB_ICONINFORMATION);
490 FROB (Qiconquestion, MB_ICONQUESTION);
491 FROB (Qiconstop, MB_ICONSTOP);
492 FROB (Qok, MB_OK);
493 FROB (Qokcancel, MB_OKCANCEL);
494 FROB (Qretrycancel, MB_RETRYCANCEL);
495 FROB (Qright, MB_RIGHT);
496 FROB (Qrtlreading, MB_RTLREADING);
497 FROB (Qservice_notification, MB_SERVICE_NOTIFICATION);
498 FROB (Qsetforeground, MB_SETFOREGROUND);
499 FROB (Qsystemmodal, MB_SYSTEMMODAL);
500 FROB (Qtaskmodal, MB_TASKMODAL);
501 FROB (Qtopmost, MB_TOPMOST);
502 FROB (Qyesno, MB_YESNO);
503 FROB (Qyesnocancel, MB_YESNOCANCEL);
504 #undef FROB
505
506 else
507 signal_simple_error ("Unrecognized flag", st);
508 }
509
510 {
511 int retval = MessageBox (NULL, msgout, titleout, sty);
512
513 if (retval == 0)
514 error ("Out of memory when calling `mswindows-message-box'");
515
516 #define FROB(sym, val) if (retval == val) return sym
517 FROB (Qabort, IDABORT);
518 FROB (Qcancel, IDCANCEL);
519 FROB (Qignore, IDIGNORE);
520 FROB (Qno, IDNO);
521 FROB (Qok, IDOK);
522 FROB (Qretry, IDRETRY);
523 FROB (Qyes, IDYES);
524 #undef FROB
525
526 signal_simple_error ("Unknown return value from MessageBox()",
527 make_int (retval));
528 }
529
530 return Qnil;
531 }
532
533 void
534 mswindows_output_last_error (char *frob)
535 {
536 LPVOID lpMsgBuf;
537 int errval = GetLastError();
538
539 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
540 | FORMAT_MESSAGE_FROM_SYSTEM,
541 NULL, errval,
542 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
543 (LPTSTR) &lpMsgBuf,
544 0,
545 NULL);
546 stderr_out ("last error during %s is %d: %s\n",
547 frob, errval, (char*)lpMsgBuf);
548 }
549 45
550 46
551 /************************************************************************/ 47 /************************************************************************/
552 /* initialization */ 48 /* initialization */
553 /************************************************************************/ 49 /************************************************************************/
554 50
555 void 51 void
556 syms_of_console_mswindows (void) 52 syms_of_console_mswindows (void)
557 { 53 {
558 defsymbol (&Qabortretryignore, "abortretryignore");
559 defsymbol (&Qapplmodal, "applmodal");
560 defsymbol (&Qdefault_desktop_only, "default-desktop-only");
561 defsymbol (&Qdefbutton1, "defbutton1");
562 defsymbol (&Qdefbutton2, "defbutton2");
563 defsymbol (&Qdefbutton3, "defbutton3");
564 defsymbol (&Qdefbutton4, "defbutton4");
565 /* defsymbol (&Qhelp, "help"); */
566 defsymbol (&Qiconasterisk, "iconasterisk");
567 defsymbol (&Qiconexclamation, "iconexclamation");
568 defsymbol (&Qiconhand, "iconhand");
569 defsymbol (&Qiconinformation, "iconinformation");
570 defsymbol (&Qiconquestion, "iconquestion");
571 defsymbol (&Qiconstop, "iconstop");
572 /* defsymbol (&Qok, "ok"); */
573 defsymbol (&Qokcancel, "okcancel");
574 defsymbol (&Qretrycancel, "retrycancel");
575 /* defsymbol (&Qright, "right"); */
576 defsymbol (&Qrtlreading, "rtlreading");
577 defsymbol (&Qservice_notification, "service-notification");
578 defsymbol (&Qsetforeground, "setforeground");
579 defsymbol (&Qsystemmodal, "systemmodal");
580 defsymbol (&Qtaskmodal, "taskmodal");
581 defsymbol (&Qtopmost, "topmost");
582 defsymbol (&Qyesno, "yesno");
583 defsymbol (&Qyesnocancel, "yesnocancel");
584
585 /* defsymbol (&Qabort, "abort"); */
586 /* defsymbol (&Qcancel, "cancel"); */
587 /* defsymbol (&Qignore, "ignore"); */
588 /* defsymbol (&Qno, "no"); */
589 /* defsymbol (&Qok, "ok"); */
590 /* defsymbol (&Qretry, "retry"); */
591 /* defsymbol (&Qyes, "yes"); */
592
593 DEFSUBR (Fmswindows_message_box);
594 } 54 }
595 55
596 void 56 void
597 console_type_create_mswindows (void) 57 console_type_create_mswindows (void)
598 { 58 {
601 /* console methods */ 61 /* console methods */
602 /* CONSOLE_HAS_METHOD (mswindows, init_console); */ 62 /* CONSOLE_HAS_METHOD (mswindows, init_console); */
603 /* CONSOLE_HAS_METHOD (mswindows, mark_console); */ 63 /* CONSOLE_HAS_METHOD (mswindows, mark_console); */
604 CONSOLE_HAS_METHOD (mswindows, initially_selected_for_input); 64 CONSOLE_HAS_METHOD (mswindows, initially_selected_for_input);
605 /* CONSOLE_HAS_METHOD (mswindows, delete_console); */ 65 /* CONSOLE_HAS_METHOD (mswindows, delete_console); */
606 CONSOLE_HAS_METHOD (mswindows, canonicalize_console_connection); 66 /* CONSOLE_HAS_METHOD (mswindows, canonicalize_console_connection); */
607 CONSOLE_HAS_METHOD (mswindows, canonicalize_device_connection); 67 /* CONSOLE_HAS_METHOD (mswindows, canonicalize_device_connection); */
608 /* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_console_connection); */ 68 /* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_console_connection); */
609 /* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_device_connection); */ 69 /* CONSOLE_HAS_METHOD (mswindows, semi_canonicalize_device_connection); */
610
611 INITIALIZE_CONSOLE_TYPE (msprinter, "msprinter", "console-msprinter-p");
612 }
613
614 void
615 reinit_console_type_create_mswindows (void)
616 {
617 REINITIALIZE_CONSOLE_TYPE (mswindows);
618 REINITIALIZE_CONSOLE_TYPE (msprinter);
619 } 70 }
620 71
621 void 72 void
622 vars_of_console_mswindows (void) 73 vars_of_console_mswindows (void)
623 { 74 {
624 Fprovide (Qmswindows); 75 Fprovide (Qmswindows);
625 } 76 }
77
78
79 #ifdef DEBUG_XEMACS
80 #include "events.h"
81 #include "opaque.h"
82 /*
83 * Random helper functions for debugging.
84 * Intended for use in the MSVC "Watch" window which doesn't like
85 * the aborts that the error_check_foo() functions can make.
86 */
87 struct lrecord_header *
88 DHEADER (Lisp_Object obj)
89 {
90 return LRECORDP (obj) ? XRECORD_LHEADER (obj) : NULL;
91 }
92
93 void *
94 DOPAQUE_DATA (Lisp_Object obj)
95 {
96 return OPAQUEP (obj) ? OPAQUE_DATA (XOPAQUE (obj)) : NULL;
97 }
98
99 struct Lisp_Event *
100 DEVENT (Lisp_Object obj)
101 {
102 return EVENTP (obj) ? XEVENT (obj) : NULL;
103 }
104
105 struct Lisp_Cons *
106 DCONS (Lisp_Object obj)
107 {
108 return CONSP (obj) ? XCONS (obj) : NULL;
109 }
110
111 struct Lisp_Cons *
112 DCONSCDR (Lisp_Object obj)
113 {
114 return (CONSP (obj) && CONSP (XCDR (obj))) ? XCONS (XCDR (obj)) : 0;
115 }
116
117 Bufbyte *
118 DSTRING (Lisp_Object obj)
119 {
120 return STRINGP (obj) ? XSTRING_DATA (obj) : NULL;
121 }
122
123 struct Lisp_Vector *
124 DVECTOR (Lisp_Object obj)
125 {
126 return VECTORP (obj) ? XVECTOR (obj) : NULL;
127 }
128
129 struct Lisp_Symbol *
130 DSYMBOL (Lisp_Object obj)
131 {
132 return SYMBOLP (obj) ? XSYMBOL (obj) : NULL;
133 }
134
135 Bufbyte *
136 DSYMNAME (Lisp_Object obj)
137 {
138 return SYMBOLP (obj) ? string_data (XSYMBOL (obj)->name) : NULL;
139 }
140
141 #endif