1 /*****
2  *       Xnee's Not an Event Emulator
3  *
4  * Xnee enables recording and replaying of X protocol data
5  *
6  *  Copyright (C) 1999-2003, 2009, 2010, 2014 Henrik Sandklef
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 3
11  * of the License, or any later version.
12  *
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Boston,
22  * MA  02110-1301, USA.
23  ****/
24 
25 
26 #ifndef XNEE_XNEE_H
27 #define XNEE_XNEE_H
28 
29 #include <limits.h>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <semaphore.h>
34 
35 #include <sys/utsname.h>
36 
37 
38 #include "libxnee/x11_files.h"
39 
40 #include "libxnee/xnee_internal.h"
41 #include "libxnee/xnee_strings.h"
42 #include "libxnee/xnee_error.h"
43 #include "libxnee/xnee_settings.h"
44 
45 #define  XNEE_CLI       "cnee"
46 #define  XNEE_CLI_UC    "CNEE"
47 
48 typedef int xnee_keymask;
49 
50 /*
51  * Return values
52  */
53 enum return_values
54   {
55     XNEE_OK =           0  ,
56     XNEE_MEMORY_FAULT      ,
57     XNEE_FILE_NOT_FOUND    ,
58     XNEE_TIMED_OUT         ,
59     XNEE_USER_INTR         ,
60     XNEE_SYNCH_FAULT       ,
61     XNEE_WRONG_PARAMS      ,
62     XNEE_NO_REC_EXT        ,
63     XNEE_NO_TEST_EXT       ,
64     XNEE_NO_PROT_CHOOSEN   ,
65     XNEE_NOT_OPEN_DISPLAY  ,
66     XNEE_AMBIGOUS_CMD      ,
67     XNEE_OUT_OF_SYNC       ,
68     XNEE_NOT_SYNCING       ,
69     XNEE_NO_PLUGIN_FILE    ,
70     XNEE_PLUGIN_FILE_ERROR ,
71     XNEE_NO_PROJECT_FILE   ,
72     XNEE_NO_MAIN_DATA      ,
73     XNEE_NO_RECORD_DATA    ,
74     XNEE_NO_REPLAY_DATA    ,
75     XNEE_SYNTAX_ERROR      ,
76     XNEE_UNKNOWN_GRAB_MODE ,
77     XNEE_NO_GRAB_DATA      ,
78     XNEE_GRAB_DATA         ,
79     XNEE_BAD_GRAB_DATA     ,
80     XNEE_BAD_LOG_FILE      ,
81     XNEE_BAD_SPEED         ,
82     XNEE_BAD_RESOLUTION    ,
83     XNEE_BAD_THRESHOLD     ,
84     XNEE_BAD_CONTEXT       ,
85     XNEE_BLANK_LINE        ,
86     XNEE_XOSD_FAILURE      ,
87     XNEE_FEEDBACK_FAILURE  ,
88     XNEE_MODE_NOT_SET      ,
89     XNEE_GRAB_MEM_FAILURE  ,
90     XNEE_RECORD_FAILURE    ,
91     XNEE_DATE_FAILURE      ,
92     XNEE_SCREEN_MISSING    ,
93     XNEE_RANGE_FAILURE     ,
94     XNEE_BAD_OFFSET        ,
95     XNEE_WINDOW_POS_ADJ_ERROR     ,
96     XNEE_MISSING_ARG        ,
97     XNEE_OK_LEAVE          ,
98     XNEE_GRAB_CONFUSION    ,
99     XNEE_PROJECT_SYNTAX_ERROR  ,
100     XNEE_CLI_ERROR         ,
101     XNEE_XINPUT_EXTENSION_FAILURE  ,
102     XNEE_REPLAY_BACKEND_FAILURE    ,
103     XNEE_OVERRIDE_DISPLAY_FAILURE  ,
104     XNEE_LAST_ERROR
105   };
106 
107 
108 
109 enum bool_string_values
110   {
111     XNEE_BOOL_EXPLICIT_FALSE=0,
112     XNEE_BOOL_IMPLICIT_TRUE,
113     XNEE_BOOL_EXPLICIT_TRUE,
114     XNEE_BOOL_ERROR
115   };
116 
117 enum xnee_protocol_data_numbers
118   {
119     XNEE_PROTO_EVENT = 0,
120     XNEE_PROTO_REQUEST  ,
121     XNEE_PROTO_REPLY    ,
122     XNEE_PROTO_ERROR    ,
123     XNEE_PROTO_DUMMY1   ,
124     XNEE_PROTO_DUMMY2   ,
125     XNEE_PROTO_XINPUT_EVENT_MASTER,
126     XNEE_PROTO_XINPUT_EVENT_SLAVE,
127     XNEE_PROTO_LAST
128   };
129 
130 enum xnee_replay_backend
131   {
132     XNEE_REPLAY_XNEE = 0,
133     XNEE_REPLAY_SWINPUT,
134     XNEE_REPLAY_LAST
135   };
136 
137 /**
138  * \brief simply a X error.
139  *
140  */
141 typedef struct {
142   int type;    /*!< Simply an X error. Put in a struct if things are to be added later on  */
143 }xnee_error;
144 
145 /**
146  * \brief simply a X reply.
147  *
148  */
149 typedef struct {
150   int type;      /*!<  Simply an X reply. Put in a struct if things are to be added later on  */
151 }xnee_reply;
152 
153 /**
154  * \brief simply a X request.
155  *
156  */
157 typedef struct {
158   int type;      /*!<  Simply an X requets. Put in a struct if things are to be added later on  */
159 }xnee_request;
160 
161 
162 /**
163  * \brief simply an X event.
164  *
165  */
166 typedef struct {
167   int type ;      /*!< type of Xevent (e.g MotionNotify)*/
168   int x, y ;      /*!< x, y coordinates. These are only used when type is MotionXXX*/
169   int button ;    /*!< x, y coordinates. These are only used when type is Button*/
170   int keycode ;   /*!< x, y coordinates. These are only used when type is Key*/
171   int screen_nr ; /*!< The screen on which the event occured */
172 }xnee_event;
173 
174 typedef struct _xinput_device
175 {
176   char    *name;
177   int      deviceid;
178   int      is_slave;
179   int      masterid;
180   XDevice *device; /* for replay */
181 
182 } xinput_device ;
183 
184 
185 typedef struct _xinput_data
186 {
187   int             xinput_event_base;
188   int             xinput_record_mouse;
189   int             xinput_record_keyboard;
190   int             nr_of_xi_devices;
191   xinput_device   xi_devices[XNEE_NR_OF_XINPUT_DEVICES];
192   int             forced_core_replay;
193   int             recording_enabled;
194 } xinput_data;
195 
196 typedef struct _saved_xinput_event
197 {
198   int  button;
199   int  type;
200   int  x;
201   int  y;
202   int  deviceid;
203   int  detail;
204   Time time;
205 } saved_xinput_event ;
206 
207 
208 /**
209  * \brief an Xinput event.
210  *
211  */
212 typedef struct {
213   int type ;      /*!< type of Xevent (e.g MotionNotify)*/
214   int x, y ;      /*!< x, y coordinates. These are only used when type is MotionXXX*/
215   int button ;
216   int keycode ;
217   int screen_nr ; /*!< The screen on which the event occured */
218   int detail;     /*!< The id of the originating device  */
219   int deviceid;
220   char name[100];
221 }xnee_xinput_event;
222 
223 
224 struct data_description
225 {
226   int   data_nr;
227   char *data_name;
228   char *data_descr;
229 };
230 
231 enum
232   {
233     XNEE_ANY_OPTION,
234     XNEE_GENERAL_OPTION,
235     XNEE_RECORD_OPTION,
236     XNEE_REPLAY_OPTION,
237     XNEE_SYNC_OPTION,
238     XNEE_GRAB_OPTION,
239     XNEE_MISC_OPTION,
240     XNEE_INTERNAL_OPTION,
241     XNEE_OBSOLETE_OPTION,
242     XNEE_RETYPE_OPTION
243   };
244 
245 
246 enum
247   {
248     XNEE_OVERRIDE_DISPLAY_NONE,
249     XNEE_OVERRIDE_DISPLAY_DATA,
250     XNEE_OVERRIDE_DISPLAY_CONTROL
251   };
252 
253 typedef struct
254 {
255   int   key;
256   char *option;
257   char *short_option;
258   char *args;
259   char *description;
260   int   type;
261   int   visible;
262 } xnee_option_t;
263 
264 /*
265 typedef struct
266 {
267   xnee_option_t   **options;
268   int             nr_of_options;
269 } xnee_options_t;
270 */
271 
272 typedef struct
273 {
274   Bool  new_project;
275   char *project_name ;
276   char *project_descr;
277   char *creat_date;
278   char *creat_prog;
279   char *creat_prog_vers;
280   char *last_date;
281   char *last_prog;
282   char *last_prog_vers;
283   char *author_name;
284   char *author_email;
285 } xnee_resource_meta ;
286 
287 
288 /*! \brief Holds information about Record Extension setup
289  *
290  */
291 typedef struct
292 {
293   int	 xtest_version_major ;  /*!< Major version number of XTest */
294   int    xtest_version_minor ;  /*!< Minor version number of XTest */
295   int	 xtest_error_basep   ;  /*!< First error number for this extension*/
296   int    xtest_event_basep   ;  /*!< First event number for this extension*/
297 } xnee_testext_setup;
298 
299 
300 
301 
302 /*! \brief Holds a
303  *
304  */
305 typedef struct
306 {
307   KeyCode         key ;         /*!< key */
308   char           *str;          /*!<  string representation of the key */
309   char           *extra_str;
310 } xnee_action_key;
311 
312 
313 
314 
315 /*! \brief Holds a information about the sync state
316  *
317  */
318 typedef struct
319 {
320   int	 max   ;       /*!< max positive diff  */
321   int    min   ;       /*!< max negative diff  */
322   int    total ;       /*!< total diff  */
323 } xnee_diff;
324 
325 
326 
327 /*! \brief Holds information about keycodes needed to fake a letter press
328  *
329  */
330 typedef struct
331 {
332   KeyCode kc ;       /*!< key to fake */
333   int shift_press ;  /*!< is a SHIT press needed */
334   int alt_press   ;  /*!< is a ALT press needed */
335   int alt_gr_press;  /*!< is a ALT GRAPH press needed */
336   int ctrl_press  ;  /*!< is a CTRL press needed */
337 
338 } old_xnee_key_code;
339 
340 
341 /*! \brief Holds information about keycodes needed to fake a letter press
342  *
343  */
344 typedef struct
345 {
346   KeyCode kc ;       /*!< key to fake */
347   KeyCode mod_keycodes[XNEE_NR_OF_MODIFIERS];
348 } xnee_key_code;
349 
350 
351 
352 
353 /*! \brief Resolution of X server
354  *
355  */
356 typedef struct
357 {
358   int	 x_res ;  /*!< Xserver resoluton:   x */
359   int    y_res ;  /*!< Xserver resoluton:   y */
360 
361 } xnee_res;
362 
363 
364 /*! \brief Data needed for distribution
365  *
366  */
367 typedef struct
368 {
369   xnee_res res      ;  /*!< resolution when replaying */
370   int      is_used  ;  /*!< flag to say if we should
371 			 convert resolution at all */
372   Display  *dpy     ;
373 } xnee_distr;
374 
375 
376 /*! \brief Resolution of X server
377  *
378  */
379 typedef struct
380 {
381   xnee_res record ;  /*!< resolution when recorded   */
382   xnee_res replay ;  /*!< resolution when replaying */
383   int  is_used    ;  /*!< flag to say if we should convert resolution at all */
384   int  x_offset ;    /*!< Xserver offset for X */
385   int  y_offset ;    /*!< Xserver offset for Y */
386 } xnee_resolution_info;
387 
388 
389 
390 /*! \brief time scale settings for Xnee
391  *
392  */
393 typedef struct
394 {
395   int  percent    ;  /*!< percentage of the original time (0-10000)  */
396   int  is_used    ;  /*!< flag to say if we should scale time at all */
397 } xnee_timescale_info;
398 
399 
400 
401 
402 /*! \brief holds replay delay information.
403  *  Xnee chooses at replay/fake-time one of these to
404  *  use as delay.
405  */
406 typedef struct
407 {
408   Time f_delay ;  /*!< time to wait before next event is faked */
409   Time s_delay  ; /*!< time to sleep before next event is faked */
410 } xnee_delay_time;
411 
412 
413 
414 /**
415  * Used for holding data of what we've received (from file)
416  *
417  *  u
418  *  type       Type of event/request/error/reply... eg MotionNotify
419  *  newtime
420  *  oldtime
421  *
422  */
423 typedef struct {
424 
425   union {
426     xnee_event          event ;
427     xnee_request        request ;
428     xnee_reply          reply ;
429     xnee_error          error ;
430     xnee_xinput_event   xievent ;
431   } u ;  /*!< What have we got ... event, request, reply or error  */
432   int type ;     /*!< Type of event/request/error/reply... eg MotionNotify  */
433   Time newtime ; /*!< Time when data (u.type) occured  */
434   Time oldtime ; /*!< Remember when the last data occured*/
435 } xnee_intercept_data;
436 
437 
438 
439 
440 /**
441  * Used for holding scripting data
442  *
443  * x             mouse position's X coord
444  * y             mouse position's Y coord
445  * x_rel         X coord is relative
446  * y_rel         Y coord is relative
447  * button        nr of button to fake
448  * button_state  XNEE_PRESS or XNEE_RELEASE
449  * key           nr of key to fake
450  * key_state     XNEE_PRESS or XNEE_RELEASE
451  * valid         1 if whole struct is valid, else 0
452  * msecs         Nr of msecs to sleep before fakeing
453  * kc            keycode of the key to fake
454  *
455  */
456 typedef struct
457 {
458   /* Mouse */
459   int x ;
460   int y ;
461   int x_rel  ;
462   int y_rel  ;
463   int button ;
464   int button_state ;
465 
466   /* Keyboard */
467   int key    ;
468   int key_state    ;
469 
470   int valid ;
471   int msecs ;
472 
473   int xinput_deviceid ;
474 
475   xnee_key_code kc;
476 
477 } xnee_script_s ;
478 
479 
480 /* *
481  * this typedef should, according to XRecord,
482  * specification be defined in <X11/extensions/record.h>
483  * ... can't find .... errrh?
484  *
485  */
486 typedef union {
487   unsigned char    type ;
488   xEvent           event ;
489   xReq             req   ;
490   xGenericReply    reply ;
491   xError           error ;
492   xConnSetupPrefix setup;
493 } XRecordDatum ;
494 
495 
496 
497 
498 
499 
500 /**
501  * Holds information about the xnee_record session
502  */
503 typedef struct
504 {
505   Bool            first_last     ;  /*!< when true, only first and last motion events are printed */
506   Bool            last_motion    ;  /*!< was the last event a motion event */
507   int             store_mouse_pos;  /*!< shall we save the mouse position before starting recording */
508   Bool            store_window_pos;  /*!< shall we store every new window position   0=don't, 1=only for window pos, 2=window pos and user resuested recording*/
509   unsigned long   server_time    ;  /*!< when the X11 data did occur          */
510   int             x              ;  /*!< last MotionNotify RootX-value        */
511   int             y              ;  /*!< last MotionNotify RootY-value        */
512   int             events_recorded;  /*!< .. to Intercept                      */
513   int             data_recorded  ;  /*!< .. to Intercept                      */
514   int             time_recorded  ;  /*!< .. to Intercept                      */
515   int             events_max     ;  /*!< .. to Intercept                      */
516   int             data_max       ;  /*!< .. to Intercept                      */
517   int             time_max       ;  /*!< .. to Intercept                      */
518   unsigned int    interval       ;  /*!< how many seconds to record           */
519   unsigned int    size           ;  /*!< max size of file                     */
520 
521   int             replayed_events;
522 
523   int data_ranges[XNEE_NR_OF_TYPES] ;  /*!< Count how many data ranges specified */
524 
525   int             interrupt ;
526   int             override_recorded_display;
527 
528 } xnee_record_init_data ;
529 
530 
531 
532 
533 /**
534  *
535  */
536 typedef struct
537 {
538 
539   int     grab         ;   /*!< true if any key     is grabbed */
540   int     grabbed_action ; /*!< set to the action when grabbed */
541 
542   xnee_action_key action_keys[XNEE_GRAB_LAST];
543 
544 } xnee_grab_keys;
545 
546 
547 
548 
549 
550 /**
551  * Holds information about Record Extension setup
552  */
553 typedef struct
554 {
555   /*@null@*/ /*@only@*/   XRecordClientSpec * xids;
556   /*@null@*/ /*@only@*/   XRecordState      * rState;
557   /*@null@*/ /*@only@*/   XRecordRange     ** range_array ;
558 
559   XID		      id ;
560   XRecordContext      rContext;
561   int 	data_flags;
562   int	major_return;
563   int   minor_return ;
564   int   nclients;
565   int   active;
566 } xnee_recordext_setup;
567 
568 
569 typedef struct
570 {
571   unsigned int key_press_delay   ;
572   unsigned int key_release_delay ;
573 } retype_settings ;
574 
575 struct buffer_meta_data
576 {
577   int sum_max  ;
578   /*!< sum of the maximum in the buffer. */
579 
580   int sum_min  ;
581   /*!< sum of the minimum values in the buffer. */
582 
583   int total_diff ;
584   /*!< the total sum of positive values in the buffer  */
585 
586   int cached_max  ;
587   /*!< a cached value of the maximum value in the buffer.
588     (-1 for unknown state) */
589 
590   int cached_min  ;
591   /*!< a cached value of the minimum value in the buffer.
592     (-1 for unknown state) */
593 
594 
595   /* thresholds used during synch */
596   int sum_max_threshold;
597   int sum_min_threshold;
598   int tot_diff_threshold;
599 
600 } ;
601 
602 
603 /**
604  * Holds most information about the Xnee session.
605  *
606  */
607 typedef struct
608 {
609   /*@null@*/ char    *program_name;    /*!< name of the program currently using libxnee */
610   /*@null@*/ char    *out_name    ;    /*!< name of output file (e.g stdout, /tmp/xnee.log*/
611   /*@null@*/ char    *err_name    ;    /*!< name of error file  (e.g stdout, /tmp/xnee.log*/
612   /*@null@*/ char    *rc_name     ;    /*!< name of resource file (e.g netscape.xns, /tmp/xterm.xns*/
613   /*@null@*/ char    *data_name   ;    /*!< name of data file (e.g */
614   /*@null@*/ char    *rt_name     ;    /*!< name of retype file (e.g stdout, /home/user/myfile.txt */
615 
616   /*@null@*/ /*@dependent@*/FILE    *data_file   ;    /*!< data input file descriptor */
617   /*@null@*/ /*@dependent@*/FILE    *out_file    ;    /*!< output file descriptor */
618   /*@null@*/ /*@dependent@*/ FILE    *err_file    ;    /*!< error file descriptor */
619   /*@null@*/ /*@dependent@*/FILE    *rc_file     ;    /*!< resource file descriptor */
620   /*@null@*/ /*@dependent@*/FILE    *rt_file     ;    /*!< retype file descriptor */
621   /*@null@*/ /*@dependent@*/FILE    *buffer_file ;    /*!< verbose buffer printout file descriptor */
622 
623   FILE    *saved_out_file    ;    /*!< output file descriptor */
624   FILE    *saved_err_file    ;    /*!< error file descriptor */
625 
626   char   **app_args    ;
627 
628   Bool     verbose     ;    /*!< true if verbose mode */
629   Bool     buf_verbose ;    /*!< true if verbose mode for buffer printouts */
630   Bool     all_clients ;    /*!< True if recording all clients
631 			      (else Xneee recods only future clients) */
632   Bool     sync        ;    /*!< True if Record used when replaying */
633   Bool     keep_autorepeat ;    /*!< True = use autorepeat */
634   unsigned char  mode  ;    /*!< Xnee's current mode (RECORDER/REPLAY/SYNTAX_CHECK...)  */
635 
636   /*@null@*/ void *plugin_handle  ;        /*!< Handle for the plugin file */
637   /*@null@*/ char *plugin_name    ;        /*!< Name of the plugin file */
638   callback_ptr rec_callback ;   /*!< recording callback function  */
639   callback_ptr rep_callback ;   /*!< replaying callback function  */
640   callback_ptr sync_fun     ;   /*!< synchronisation function     */
641 
642 
643   fprint_fptr buffer_verbose_fp; /*!< pointer to buffer verbose fun */
644   vfprint_fptr verbose_fp;        /*!< pointer to verbose fun */
645   fprint_fptr data_fp   ;        /*!< pointer to xnee protcol print fun */
646 
647   /*@null@*/ /*@observer@*/
648   /*@null@*/ char    * display    ;    /*!< char representation of the Display */
649   /*@null@*/ Display *data        ;    /*!< used for sending recored data between Xnee and Xserver*/
650   /*@null@*/ Display *control     ;    /*!< used for sending info between Xnee and Xserver  */
651   /*@null@*/ Display *fake        ;    /*!< used for faking events  */
652   /*@null@*/ Display *grab        ;    /*!< used for holding the grabbed key/modifier */
653   int first_replayed_event;  /*!< True if the event to replay is the first one.
654 			       Needed to set the start time of the first event to 0 */
655   int recall_recorded_win_pos; /*!< True if Xnee (during replay) shall use the recorded.
656 			            window position*/
657   int     cont         ;     /*!< A simple flag telling Xnee wether to keep
658 			       recording/replaying or to quit. */
659   /*@null@*/ xnee_distr *distr_list ;  /*!< array of displays to distribute events to */
660   size_t     distr_list_size ; /*!< size of array of displays to distribute events to */
661   /*@null@*/    /*@reldef@*/
662 #ifdef XNEE_USE_SEMAPHORES
663   sem_t   *buf_sem     ;    /*!< semaphore to protect the replay buffer */
664 #endif /* XNEE_USE_SEMAPHORES */
665   long first_read_time ;    /*!< server time of the first read from recorded file */
666   int     force_replay ;    /*!< Keep replaying even if we are out of sync .... dangerous */
667 
668   XKeyboardState kbd_orig;  /*!< User keyboard state before Xnee messes is up */
669   int     autorepeat_saved; /*!< Flag indicating if we have a stored keyboard state */
670 
671   /*@only@*/ /*@null@*/
672   xnee_record_init_data    xnee_info ;
673   int             no_reparent_recording ;
674   int             max_nr_of_moves;
675 
676   /*@only@*/ /*@null@*/
677   xnee_recordext_setup     *record_setup;
678 
679   /*@only@*/ /*@null@*/
680   xnee_testext_setup       *replay_setup;
681 
682   int                      data_buffer[4][XNEE_REPLAY_BUFFER_SIZE];
683   struct buffer_meta_data  meta_data;
684   int                      speed_percent;
685   /*@only@*/ /*@null@*/
686   xnee_grab_keys           *grab_keys;
687 
688   int     button_pressed ;
689   int     key_pressed ;
690 
691   xnee_resolution_info   res_info;
692   xnee_resource_meta     xrm;
693 
694   XModifierKeymap *map ;
695 
696   int              in_use;
697 
698   retype_settings  retype;
699 
700   unsigned char   x_version_major;
701   unsigned char   x_version_minor;
702   unsigned char   x_version_minor_sub;
703   char *          x_vendor_name  ;
704 
705 
706   xinput_data xi_data;
707   unsigned char replay_backend;
708 
709 } xnee_data ;
710 
711 
712 
713 
714 
715 
716 /**
717  * Checks if the first argument is equals to any of the other two arguments
718  * @param arg       string to compare
719  * @param long_arg  with this one
720  * @param short_arg and with this one
721  * @return int      1 if arg was equal to any of long_arg or short_arg, else it returns 0
722  */
723 int
724 xnee_check ( const char *arg, const char *long_arg , const char *short_arg );
725 
726 
727 
728 
729 
730 
731 #define xnee_print_obsolete_mess(s) fprintf (stderr, s)
732 
733 
734 int
735 xnee_start(xnee_data *xd);
736 
737 
738 
739 
740 /**
741  * Allocates a new xnee_data structure.
742  * To free the memory, xnee_free_xnee_data can be used.
743  * @return xnee_data * NULL if alloc failed
744  */
745 /*@null@   The implementation of this function is located in xnee_alloc.c*/
746 
747 xnee_data*
748 xnee_new_xnee_data(void);
749 
750 
751 
752 #define DEBUG_XNEE_DATA
753 #ifdef DEBUG_XNEE_DATA
754 void
755 xnee_debug_xnee_data(xnee_data *xd, char *str)                ;
756 #endif
757 
758 
759 #endif /*   XNEE_XNEE_H */
760 
761