ch03.xml revision e9fcaa8a
1<chapter id='data_structures'> 2<title>Data Structures</title> 3 4<para> 5An Xkb keyboard description consists of a variety of data structures, each of 6which describes some aspect of the keyboard. Although each data structure has 7its own peculiarities, there are a number of features common to nearly all Xkb 8structures. This chapter describes these common features and techniques for 9manipulating them. 10</para> 11 12 13<para> 14Many Xkb data structures are interdependent; changing a field in one might 15require changes to others. As an additional complication, some Xkb library 16functions allocate related components as a group to reduce fragmentation and 17allocator overhead. In these cases, simply allocating and freeing fields of Xkb 18structures might corrupt program memory. Creating and destroying such 19structures or keeping them properly synchronized during editing is complicated 20and error prone. 21</para> 22 23 24<para> 25Xkb provides functions and macros to allocate and free all major data 26structures. You should use them instead of allocating and freeing the 27structures yourself. 28</para> 29 30<sect1 id='allocating_xkb_data_structures'> 31<title>Allocating Xkb Data Structures</title> 32 33<para> 34Xkb provides functions, known as allocators, to create and initialize Xkb data 35structures. In most situations, the Xkb functions that read a keyboard 36description from the server call these allocators automatically. As a result, 37you will seldom have to directly allocate or initialize Xkb data structures. 38</para> 39 40 41<para> 42However, if you need to enlarge an existing structure or construct a keyboard 43definition from scratch, you may need to allocate and initialize Xkb data 44structures directly. Each major Xkb data structure has its own unique 45allocator. The allocator functions share common features: allocator functions 46for structures with optional components take as an input argument a mask of 47subcomponents to be allocated. Allocators for data structures containing 48variable-length data take an argument specifying the initial length of the data. 49</para> 50 51 52<para> 53You may call an allocator to change the size of the space allocated for 54variable-length data. When you call an allocator with an existing data 55structure as a parameter, the allocator does not change the data in any of the 56fields, with one exception: variable-length data might be moved. The allocator 57resizes the allocated memory if the current size is too small. This normally 58involves allocating new memory, copying existing data to the newly allocated 59memory, and freeing the original memory. This possible reallocation is 60important to note because local variables pointing into Xkb data structures 61might be invalidated by calls to allocator functions. 62</para> 63 64</sect1> 65<sect1 id='adding_data_and_editing_data_structures'> 66<title>Adding Data and Editing Data Structures</title> 67 68<para> 69You should edit most data structures via the Xkb-supplied helper functions and 70macros, although a few data structures can be edited directly. The helper 71functions and macros make sure everything is initialized and interdependent 72values are properly updated for those Xkb structures that have 73interdependencies. As a general rule, if there is a helper function or macro to 74edit the data structure, use it. For example, increasing the width of a type 75requires you to resize every key that uses that type. This is complicated and 76ugly, which is why there’s an <emphasis> 77XkbResizeKeyType</emphasis> 78 function. 79</para> 80 81 82<para> 83Many Xkb data structures have arrays whose size is reported by two fields. The 84first field, whose name is usually prefixed by <emphasis> 85sz_</emphasis> 86, represents the total number of elements that can be stored in the array. The 87second field, whose name is usually prefixed by <emphasis> 88num_</emphasis> 89, specifies the number of elements currently stored there. These arrays 90typically represent data whose total size cannot always be determined when the 91array is created. In these instances, the usual way to allocate space and add 92data is as follows: 93</para> 94 95<itemizedlist> 96 <listitem> 97 <para> 98Call the allocator function with some arbitrary size, as a hint. 99 </para> 100 </listitem> 101 <listitem> 102 <para> 103For those arrays that have an <emphasis> 104Xkb...Add...</emphasis> 105 function, call it each time you want to add new data to the array. The 106function expands the array if necessary. 107 </para> 108 </listitem> 109</itemizedlist> 110 111<para> 112For example, call: 113</para> 114 115<para> 116XkbAllocGeomShapes(geom,4) 117</para> 118 119<para> 120to say "I’ll need space for four new shapes in this geometry." This makes 121sure that <emphasis> 122sz_shapes</emphasis> 123 - <emphasis> 124num_shapes</emphasis> 125 >= 4, and resizes the shapes array if it isn’t. If this function 126succeeds, you are guaranteed to have space for the number of shapes you need. 127</para> 128 129 130<para> 131When you call an editing function for a structure, you do not need to check for 132space, because the function automatically checks the <emphasis> 133sz_</emphasis> 134 and <emphasis> 135num_</emphasis> 136 fields of the array, resizes the array if necessary, adds the entry to the 137array, and then updates the <emphasis> 138num_</emphasis> 139 field. 140</para> 141 142 143</sect1> 144<sect1 id='making_changes_to_the_servers_keyboard_description'> 145<title>Making Changes to the Server’s Keyboard Description</title> 146 147<para> 148In Xkb, as in the core protocol, the client and server have independent copies 149of the data structures that describe the keyboard. The recommended way to 150change some aspect of the keyboard mapping in the X server is to edit a local 151copy of the Xkb keyboard description and then send only the changes to the X 152server. This method helps eliminate the need to transfer the entire keyboard 153description or even an entire data structure for only minor changes. 154</para> 155 156 157<para> 158To help you keep track of the changes you make to a local copy of the keyboard 159description, Xkb provides separate special <emphasis> 160changes</emphasis> 161 data structures for each major Xkb data structure. These data structures do 162not contain the actual changed values: they only indicate the changes that have 163been made to the structures that actually describe the keyboard. 164</para> 165 166 167<para> 168When you wish to change the keyboard description in the server, you first 169modify a local copy of the keyboard description and then flag the modifications 170in an appropriate changes data structure. When you finish editing the local 171copy of the keyboard description, you pass your modified version of the 172keyboard description and the modified changes data structure to an Xkb 173function. This function uses the modified keyboard description and changes 174structure to pass only the changed information to the server. Note that 175modifying the keyboard description but not setting the appropriate flags in the 176changes data structure causes indeterminate behavior. 177</para> 178 179 180</sect1> 181<sect1 id='tracking_keyboard_changes_in_the_server'> 182<title>Tracking Keyboard Changes in the Server</title> 183 184<para> 185The server reports all changes in its keyboard description to any interested 186clients via special Xkb events. Just as clients use special changes data 187structures to change the keyboard description in the server, the server uses 188special changes data structures to tell a client what changed in the server’s 189keyboard description. 190</para> 191 192 193<para> 194Unlike clients, however, the server does not always pass the new values when it 195reports changes to its copy of the keyboard description. Instead, the server 196only passes a changes data structure when it reports changes to its keyboard 197description. This is done for efficiency reasons — some clients do not always 198need to update their copy of the keyboard description with every report from 199the server. 200</para> 201 202 203<para> 204When your client application receives a report from the server indicating the 205keyboard description has changed, you can determine the set of changes by 206passing the event to an Xkb function that "notes" event information in the 207corresponding changes data structure. These "note changes" functions are 208defined for all major Xkb components, and their names have the form <emphasis> 209XkbNote{Component}Changes</emphasis> 210, where <emphasis> 211Component</emphasis> 212 is the name of a major Xkb component such as <emphasis> 213Map</emphasis> 214 or <emphasis> 215Names</emphasis> 216. When you want to copy these changes from the server into a local copy of the 217keyboard description, use the corresponding <emphasis> 218XkbGet{Component}Changes</emphasis> 219 function<emphasis> 220, </emphasis> 221passing it the changes structure. The function then retrieves only the changed 222structures from the server and copies the modified pieces into the local 223keyboard description. 224</para> 225 226</sect1> 227<sect1 id='freeing_data_structures'> 228<title>Freeing Data Structures</title> 229 230<para> 231For the same reasons you should not directly use <emphasis> 232malloc</emphasis> 233 to allocate Xkb data structures, you should not free Xkb data structures or 234components directly using <emphasis> 235free</emphasis> 236 or <emphasis> 237Xfree</emphasis> 238. Xkb provides functions to free the various data structures and their 239components. Always use the free functions supplied by Xkb. There is no 240guarantee that any particular field can be safely freed by <emphasis> 241free</emphasis> 242 or <emphasis> 243Xfree</emphasis> 244. 245</para> 246</sect1> 247</chapter> 248