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