From 5cbe15a899718a715e5d563b160dc16e3193b2ee Mon Sep 17 00:00:00 2001 From: Akos Horvath Date: Tue, 2 Apr 2024 11:40:51 +0200 Subject: [PATCH] add comments to function prototype declarations --- src/client.h | 87 ++++++++++++++++ src/util.c | 22 +--- src/util.h | 280 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 344 insertions(+), 45 deletions(-) diff --git a/src/client.h b/src/client.h index 6ecad1a..6224bf6 100644 --- a/src/client.h +++ b/src/client.h @@ -49,31 +49,118 @@ struct Client { bool is_pid_set; }; +/** + * Client functions + */ + +/** + * Converts the position of `c` to a `XWindowChanges` structure. + */ XWindowChanges wm_client_to_xwchanges(Client *c); + +/** + * Returns the client associated with `w`. + * Returns NULL if it could not find the client. + */ Client* wm_client_find(Wm* wm, Window w); + +/** + * Initializes a new Client. + */ Client* wm_client_create(Wm *wm, Window w); + void wm_client_handle_window_types(Wm *wm, Client *c, XMapRequestEvent e); + +/** + * Unmaps `c->window` and `c->frame`. + */ void wm_client_hide(Wm *wm, Client *c); + +/** + * Maps `c->window` and `c->frame`. + */ void wm_client_show(Wm* wm, Client *c); + +/** + * Focuses `c`. + */ void wm_client_focus(Wm* wm, Client *c); + +/** + * Focuses the client in the direction `dir`, relative to the current focused + * client. + */ void wm_client_focus_dir(Wm* wm, Client *c, int dir); + +/** + * Swaps the client in the direction `dir`, relative to the current focused + * client. + */ void wm_client_swap_dir(Wm* wm, Client *c, int dir); + +/** + * Frees `c`, and its dynamically allocated fields. + */ void wm_client_free(Wm *wm, Client *c); + +/** + * Destroys the window and frame associated with `c`, frees `c`, and recalculates + * the layout. + */ void wm_client_kill(Wm *wm, Client *c); +/** + * Sets the window property with the atom of `name`, with the value `data`. + */ void wm_client_set_atom(Wm *wm, Client *c, const char *name, const unsigned char *data, Atom type, int nelements); + +/** + * Reads the window poperty with the atom of `name`, and returns the value + * in `atom_ret`, and returns the number of read items in `nitems_ret`. + */ Atom wm_client_get_atom(Wm *wm, Client *c, const char *name, unsigned char **atom_ret, unsigned long *nitems_ret); + +/** + * Finds the client in the direction `dir` relative to `c`. + */ Client* wm_client_get_dir_rel_c(Client *c, int dir); + +/** + * Returns the currently focused client. + */ Client* wm_client_get_focused(Wm* wm); + +/** + * Draws border for client `c`. + */ void wm_client_border(Wm* wm, Client *c); + +/** + * Draws focused border for client `c`. + */ void wm_client_border_focused(Wm* wm, Client *c); + +/** + * Draws borders for all clients in `m`. + */ void wm_monitor_clients_border(Wm* wm, Monitor *m); + +/** + * Returns true if `c` is focused, false if `c` is not focused. + */ bool wm_client_is_focused(Wm* wm, Client *c); +/** + * Draws server-side decorations for `c`. + */ void wm_client_draw_frame(Wm *wm, Client *c); + +/** + * Draws server-side decorations for all clients in `m`. + */ void wm_monitor_draw_all_clients_frame(Wm* wm, Monitor *m); #endif diff --git a/src/util.c b/src/util.c index 58a1a69..fc7a185 100644 --- a/src/util.c +++ b/src/util.c @@ -225,10 +225,8 @@ UIntArray* wm_nonempty_workspaces_to_strptrarray(Wm *wm) return ret; } -json_object* wm_state_to_json_object(Wm *wm, const char *prefixstr) +json_object* wm_state_to_json_object(Wm *wm) { - assert(prefixstr); - json_object *ret = json_object_new_object(); UIntArray *ws_str = wm_nonempty_workspaces_to_strptrarray(wm); @@ -503,14 +501,6 @@ UIntArray* wm_treenode_all_keyroots_index(TreeNode *node) return ret; } -bool wm_nodes_are_equal(TreeNode *node1, TreeNode *node2) -{ - if (node1->type != node2->type) - return false; - - return true; -} - // https://github.com/timtadh/zhang-shasha void wm_treedist(TreeNode *tree1, TreeNode *tree2, size_t i, size_t j, UIntArray *dists, TreeEditDistanceCosts costs) @@ -987,16 +977,6 @@ void wm_tree_to_DOT(TreeNode *root, const char *filename) wm_nodearray_free(all_nodes); } -int wm_get_node_index(TreeNode *parent, unsigned int node_id) -{ - for (size_t i = 0; i < parent->children->size; i++) { - if (node_id == parent->children->nodes[i]->id) - return i; - } - - return -1; -} - void wm_treenode_remove_node(Wm *wm, TreeNode *root, TreeNode *node) { DEBUG_PRINT("%s\n", __func__); diff --git a/src/util.h b/src/util.h index 9db6904..55c2a90 100644 --- a/src/util.h +++ b/src/util.h @@ -77,76 +77,308 @@ typedef struct { UpdateCostFunction update_cost_function; } TreeEditDistanceCosts; +/** + * Functions for NodeArray operations + */ + +/** + * Initializes a new NodeArray. + */ NodeArray* wm_nodearray_new(); -void wm_nodearray_set(NodeArray *arr, size_t index, uint64_t value); + +/** + * Adds `node` to the end of `arr`. If the capacity is lower than the + * new size, it resizes the array. + */ void wm_nodearray_push(NodeArray *arr, TreeNode *node); + +/** + * Removes the last element, and returns it in `ret`. + */ bool wm_nodearray_pop(NodeArray *arr, TreeNode **ret); + +/** + * Removes the first element, and returns it in `ret`. + */ bool wm_nodearray_pop_front(NodeArray *arr, TreeNode **ret); + +/** + * Removes all elements from `arr`, and sets its size to 0. + */ void wm_nodearray_clear(NodeArray *arr); + +/** + * Removes the element at the provided index. Returns true on success, false + * on failure. + */ bool wm_nodearray_remove(NodeArray *arr, size_t index); + +/** + * Frees the array. + */ void wm_nodearray_free(NodeArray *arr); -TreeNode* wm_nodearray_at(NodeArray *arr, size_t index); +/** + * Functions for TreeNode operations + */ + +/** + * Initializes a new TreeNode. + */ TreeNode* wm_treenode_new(NodeType type, TreeNode *parent); -void wm_treenode_free(TreeNode *node); -bool wm_treenode_is_empty(TreeNode *node); -void wm_treenode_split_space(TreeNode *node, Rect *ret1, Rect *ret2); -void wm_treenode_recalculate_space(TreeNode *node); -void wm_treenode_swap(TreeNode *root, TreeNode *node1, TreeNode* node2); -void wm_treenode_add_child(TreeNode *node, TreeNode *child); -TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client); -void wm_treenode_remove_node(Wm *wm, TreeNode *root, TreeNode *node); -int wm_get_node_index(TreeNode *parent, unsigned int node_id); +/** + * Frees `node`, and the `children` NodeArray field. + */ +void wm_treenode_free(TreeNode *node); + +/** + * Returns true if `node` has no children. + */ +bool wm_treenode_is_empty(TreeNode *node); + +/** + * Splits the available space between `ret1` and `ret2`, based on `node->type`. + */ +void wm_treenode_split_space(TreeNode *node, Rect *ret1, Rect *ret2); + +/** + * Asserts `node->children->size == 2`, and calls split_space on first and second + * child. + */ +void wm_treenode_recalculate_space(TreeNode *node); + +/** + * Swaps the clients of the `node1` and `node2`. + */ +void wm_treenode_swap(TreeNode *root, TreeNode *node1, TreeNode* node2); + +/** + * Pushes child to `node->children`, and sets `child->parent` to node. + */ +void wm_treenode_add_child(TreeNode *node, TreeNode *child); + +/** + * Finds `client` in `root`, removes and frees the node associated with it, + * and recalculates layout. + */ +TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client); + +/** + * Finds `node` in `root`, removes and frees it, and recalculates layout. + */ +void wm_treenode_remove_node(Wm *wm, TreeNode *root, TreeNode *node); + +/** + * Converts `tree` to DOT file format. + * Use `dot -Tsvg > output.svg` to convert the DOT file to svg. + */ void wm_tree_to_DOT(TreeNode *root, const char *filename); + +/** + * Converts `type` to a string, and writes it to `buf`. + */ void wm_node_type_to_str(NodeType type, char *buf, size_t bufsize); + +/** + * Finds non empty workspaces, and converts them to JSON strings. + * Return value: `UIntArray` + */ UIntArray* wm_nonempty_workspaces_to_strptrarray(Wm *wm); + +/** + * Converts a string to NodeType. + */ NodeType wm_node_type_from_str(char *buf, size_t bufsize); + +/** + * Converts `node` to a JSON string. + */ char* wm_treenode_to_str(TreeNode *node); + +/** + * Converts `node` to a JSON string, and if DEBUG is defined, prints it to stderr. + */ void wm_treenode_print(TreeNode *node); + +/** + * Parses a `json_object` to a TreeNode. + */ TreeNode* wm_json_obj_to_treenode(struct json_object *jobj); + +/** + * Functions for UIntArray operations + * UIntArray can be used as a generic pointer container, if + * `_Static_assert(sizeof(uint64_t) == sizeof(), "")`. + */ + +/** + * Initializes a new UIntArray. + */ UIntArray* wm_uintarray_new(); + +/** + * Asserts `index < arr->size`, and returns `arr->elements[index]`. + */ uint64_t wm_uintarray_at(UIntArray *arr, size_t index); -void wm_uintarray_set(UIntArray *arr, size_t index, uint64_t value); + +/** + * Adds `node` to the end of `arr`. If the capacity is lower than the + * new size, it resizes the array. + */ void wm_uintarray_push(UIntArray *arr, uint64_t element); + +/** + * Removes the last element, and returns it in `ret`. + */ bool wm_uintarray_pop(UIntArray *arr, uint64_t *ret); + +/** + * Removes the first element, and returns it in `ret`. + */ bool wm_uintarray_pop_front(UIntArray *arr, uint64_t *ret); + +/** + * Removes the element at the provided index. Returns true on success, false + * on failure. + */ bool wm_uintarray_remove(UIntArray *arr, size_t index); + +/** + * Frees the array. + */ void wm_uintarray_free(UIntArray *arr); + +/** + * Returns ((uint64_t**)arr->elements)[i][j]. + */ uint64_t wm_uintarray_2d_index(UIntArray *arr, size_t i, size_t j); +/** + * TreeNode utility functions + */ + +/** + * Find the node associated with the currently focused client, and returns it. + * Returns NULL if no client is focused. + */ TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root); + +/** + * Find the node associated with `client`, and returns it. + * Returns NULL if it could not find `client`. + */ TreeNode* wm_treenode_ptr_find_client_node(TreeNode *root, Client *client); + +/** + * Returns all `NODE_CLIENT` type descendant nodes of `root`. + */ NodeArray* wm_treenode_find_client_nodes(TreeNode *root); + +/** + * Returns the sibling node of `node`. + * Returns NULL on error. + */ TreeNode* wm_treenode_split_get_sibling(TreeNode *node); + +/** + * Returns descendant nodes of `root`. + */ NodeArray* wm_all_nodes_to_array(TreeNode *root); -json_object* wm_state_to_json_object(Wm *wm, const char *prefixstr); + +/** + * Converts all non empty workspace trees to a `json_object`. + */ +json_object* wm_state_to_json_object(Wm *wm); + +/** + * Writes current state encoded as JSON to logfile. + * If logfile exists, and is not empty, appends the state to the JSON object in + * logfile. + */ void wm_log_state(Wm *wm, const char *prefixstr, const char* logfile); -TreeNode* wm_treenode_lmd(TreeNode *node); -NodeArray* wm_treenode_all_lmds(TreeNode *node); -UIntArray* wm_treenode_all_lmds_index(TreeNode *node); -NodeArray* wm_postorder_traversal(TreeNode *tree); -bool wm_is_treenode_keyroot(TreeNode *node, NodeArray *postorder); -NodeArray* wm_treenode_all_keyroots(TreeNode *node); -UIntArray* wm_treenode_all_keyroots_index(TreeNode *node); -bool wm_nodes_are_equal(TreeNode *node1, TreeNode *node2); +/** + * Utility functions for tree edit distance + */ + +/** + * Returns the leftmost descendant of `node`. + */ +TreeNode* wm_treenode_lmd(TreeNode *node); + +/** + * Returns all leftmost descendants of `node`. + */ +NodeArray* wm_treenode_all_lmds(TreeNode *node); + +/** + * Returns all leftmost descendants of `node`, as indexes of a postorder + * traversal array. + */ +UIntArray* wm_treenode_all_lmds_index(TreeNode *node); + +/** + * Returns all nodes of `tree`, in postorder traversal order. + */ +NodeArray* wm_postorder_traversal(TreeNode *tree); + +/** + * Returns true of `node` is a keyroot. + * LR_keyroots(T) = {k | there exists no k’ > k such that l(k)= l(k’)}. + * l = leftmost descendant + */ +bool wm_is_treenode_keyroot(TreeNode *node, NodeArray *postorder); + +/** + * Returns all keyroots of `node`. + */ +NodeArray* wm_treenode_all_keyroots(TreeNode *node); + +/** + * Returns all keyroots of `node`, as indexes of a postorder traversal array. + */ +UIntArray* wm_treenode_all_keyroots_index(TreeNode *node); + + +/** + * Calculates the distance of the subtrees of `tree1` and `tree2`, at indexes + * `i` and `j`. + */ void wm_treedist(TreeNode *tree1, TreeNode *tree2, size_t i, size_t j, UIntArray *dists, TreeEditDistanceCosts costs); +/** + * Calculates the distance of `tree1` and `tree2` using the edit costs `costs`. + */ size_t wm_tree_edit_distance(TreeNode *tree1, TreeNode *tree2, TreeEditDistanceCosts costs); +/** + * Creates the logfile at the provided path. + */ void wm_logfile_init(const char *path); -/* UIntArray */ +/** + * Frees all dynamically allocated fields of the array elements, and frees the + * array. + * Type of `entries`: UIntArray + */ void wm_logentries_free(UIntArray *entries); -/* UIntArray */ +/** + * Parses the JSON objects in the file at path `filename`, and populates a LogEntry* + * array with the parsed values. + * Return type: UIntArray + */ UIntArray* wm_read_log(const char* filename); -/* UIntArray */ +/** + * Calculates the tree edit distance of `log_entries[i]` and `curr_tree`. + * Stores the distance in `log_entries[i]->workspaces[j]->tree->distance`. + * Type of `log_entries`: UIntArray + */ void wm_logentries_calculate_distances(UIntArray *log_entries, TreeNode *curr_tree, UpdateCostFunction update_cost_function);