1 /* 2 * Copyright © 2019 Manuel Stoeckl 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial 14 * portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 */ 25 #ifndef WAYPIPE_PARSING_H 26 #define WAYPIPE_PARSING_H 27 28 #include <stdbool.h> 29 #include <stdint.h> 30 31 struct char_window; 32 struct int_window; 33 struct fd_translation_map; 34 struct main_config; 35 36 struct wp_interface; 37 /** An object used by the wayland protocol. Specific types may extend 38 * this struct, using the following data as a header */ 39 struct wp_object { 40 struct wp_object *t_left, *t_right; // inline tree implementation 41 const struct wp_interface *type; // Use to lookup the message handler 42 uint32_t obj_id; 43 bool is_zombie; // object deleted but not yet acknowledged remotely 44 }; 45 struct message_tracker { 46 /* Tree containing all objects that are currently alive or zombie */ 47 struct wp_object *objtree_root; 48 /* sequence number to discriminate between wl_buffer objects; object ids 49 * and pointers are not guaranteed to be unique */ 50 uint64_t buffer_seqno; 51 }; 52 /** Context object, to be passed to the protocol handler functions */ 53 struct context { 54 struct globals *const g; 55 struct message_tracker *const tracker; 56 struct wp_object *obj; 57 bool drop_this_msg; 58 /* If true, running as waypipe client, and interfacing with compositor's 59 * buffers */ 60 const bool on_display_side; 61 /* The transferred message can be rewritten in place, and resized, as 62 * long as there is space available. Setting 'fds_changed' will 63 * prevent the fd zone start from autoincrementing after running 64 * the function, which may be useful when injecting messages with fds */ 65 const int message_available_space; 66 uint32_t *const message; 67 int message_length; 68 bool fds_changed; 69 struct int_window *const fds; 70 }; 71 72 /** Add a protocol object to the list, replacing any preceding object with 73 * the same id. */ 74 void tracker_insert(struct message_tracker *mt, struct wp_object *obj); 75 void tracker_remove(struct message_tracker *mt, struct wp_object *obj); 76 /** Replace an object that is already in the protocol list with a new object 77 * that has the same id; will silently fail if id not present */ 78 void tracker_replace_existing( 79 struct message_tracker *mt, struct wp_object *obj); 80 struct wp_object *tracker_get(struct message_tracker *mt, uint32_t id); 81 82 int init_message_tracker(struct message_tracker *mt); 83 void cleanup_message_tracker(struct message_tracker *mt); 84 85 /** Read message size from header; the 8 bytes beyond data must exist */ 86 int peek_message_size(const void *data); 87 const char *get_nth_packed_string(const char *pack, int n); 88 enum parse_state { PARSE_KNOWN, PARSE_UNKNOWN, PARSE_ERROR }; 89 /** 90 * The return value is false iff the given message should be dropped. 91 * The flag `unidentified_changes` is set to true if the message does 92 * not correspond to a known protocol. 93 * 94 * The message data payload may be modified and increased in size. 95 * 96 * The window `chars` should start at the message start, end 97 * at its end, and indicate remaining space. 98 * The window `fds` should start at the next fd in the queue, ends 99 * with the last. 100 * 101 * The start and end of `chars` will be moved to the new end of the message. 102 * The end of `fds` may be moved if any fds are inserted or discarded. 103 * The start of fds will be moved, depending on how many fds were consumed. 104 */ 105 enum parse_state handle_message(struct globals *g, bool on_display_side, 106 bool from_client, struct char_window *chars, 107 struct int_window *fds); 108 /** 109 * Given a set of messages and fds, parse the messages, and if indicated 110 * by parsing logic, compact the message buffer by removing selected 111 * messages, or edit message contents. 112 * 113 * The `source_bytes` window indicates the range of unread data; it's 114 * zone start point will be advanced. The 'dest_bytes' window indicates 115 * the range of written data; it's zone end point will be advanced. 116 * 117 * The file descriptor queue `fds` will have its start advanced, leaving only 118 * file descriptors that have not yet been read. Further edits may be made 119 * to inject new file descriptors. 120 */ 121 void parse_and_prune_messages(struct globals *g, bool on_display_side, 122 bool from_client, struct char_window *source_bytes, 123 struct char_window *dest_bytes, struct int_window *fds); 124 125 // handlers.c 126 /** Create a new Wayland protocol object of the given type; some types 127 * produce structs extending from wp_object */ 128 struct wp_object *create_wp_object( 129 uint32_t it, const struct wp_interface *type); 130 /** Type-specific destruction routines, also dereferencing linked shadow_fds */ 131 void destroy_wp_object(struct wp_object *object); 132 133 extern const struct wp_interface *the_display_interface; 134 135 #endif // WAYPIPE_PARSING_H 136