| @@ -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). |