| @@ -0,0 +1,90 @@ |
| | 1 | Notes on the Tk implementation. |
| | 2 | |
| | 3 | General |
| | 4 | |
| | 5 | TkTop represents a top-level window. |
| | 6 | It holds pointers to the widgets created in that |
| | 7 | window: |
| | 8 | windows gives a list of all windows (this includes "." and any menu widgets) |
| | 9 | root the list of all widgets, whether packed or not. |
| | 10 | |
| | 11 | Each Tk widget holds pointers to the widgets packed inside it, its slaves. |
| | 12 | Widgets that do their own child widget management (canvas |
| | 13 | and text) do not use the slaves list, but store pointers |
| | 14 | to them in their own data structures. |
| | 15 | |
| | 16 | Each Tk widget, w, holds a pointer to the widget it's packed or stored inside. |
| | 17 | |
| | 18 | w->master |
| | 19 | if it's packed or stored in a grid |
| | 20 | w->parent |
| | 21 | if it's a child widget of a canvas or text widget. |
| | 22 | |
| | 23 | A widget type is operated on through functions referred to in its TkMethod structure, |
| | 24 | defined in that widget type's source file, and pointed to by the |
| | 25 | method dispatch table, tkmethod, defined in xdata.c. |
| | 26 | |
| | 27 | utils.c contains the master table holding the built-in commands |
| | 28 | (e.g. widget creation, focus, grab, etc) with their |
| | 29 | associated functions. |
| | 30 | |
| | 31 | xdata.c holds the method table (tkmethod) mapping from |
| | 32 | widget type to the method functions supported by individual widgets. |
| | 33 | |
| | 34 | |
| | 35 | |
| | 36 | Coordinates: |
| | 37 | |
| | 38 | A widget requests a particular size allocation |
| | 39 | by setting its req.width and req.height fields. |
| | 40 | The packer (or its parent) determines the actual |
| | 41 | size allocation, and position and sets act.x, act.y, act.width |
| | 42 | and act.height appropriately. |
| | 43 | |
| | 44 | The requested width and height do not include the |
| | 45 | borderwidth, which is factored in additionally. |
| | 46 | |
| | 47 | Coordinates as delivered by the %x and %y verbs provided |
| | 48 | by bind(9) are relative to the top left of the widget, |
| | 49 | inside its border. I'll call this the "widget's coordinate system". |
| | 50 | |
| | 51 | The draw method of each widget type is provided with |
| | 52 | an "origin" argument. |
| | 53 | |
| | 54 | (origin.x + act.x + borderwidth, origin.y + act.y + borderwidth) |
| | 55 | |
| | 56 | gives the screen coordinate of (0, 0) in the widget coordinate |
| | 57 | system. |
| | 58 | |
| | 59 | |
| | 60 | Dirtiness |
| | 61 | |
| | 62 | Each widget has a "dirty" rectangle, the bounding |
| | 63 | box of any changes that it needs to make visible. |
| | 64 | This is in the widget's coordinate system. |
| | 65 | |
| | 66 | A widget does not have to update everything in |
| | 67 | the dirty rectangle, unless the Tkrefresh flag |
| | 68 | is set, in which case it must. |
| | 69 | |
| | 70 | A widget never has to draw anything outside of its dirty |
| | 71 | rectangle. |
| | 72 | |
| | 73 | Locking |
| | 74 | |
| | 75 | Mostly, Tk is non-reentrant because the interpreter is held |
| | 76 | when a call to, e.g. Tk_cmd, is made. |
| | 77 | |
| | 78 | However, when the display is remote, any access of the display |
| | 79 | (drawing, stringsize, etc) can do a release() and therefore |
| | 80 | let another thread access tk. |
| | 81 | |
| | 82 | The drawing code itself locks the display, so code invoked |
| | 83 | from within a widgets draw() method is guaranteed |
| | 84 | non-reentrant. |
| | 85 | |
| | 86 | If access to the draw device is required during code executed |
| | 87 | in a non-drawing context (e.g. to calculate the size of a |
| | 88 | string), care must be taken to lock the draw device |
| | 89 | appropriately. Tk provides some convenience functions to do |
| | 90 | this (e.g. tkstringsize). |