Question

I see in the tk source code in the Tkbind.c, TkEvent.c and TkEntry.c that there are a set of pointers, eventPtr, dispPtr, bindPtr, and a few more pointing to different C-structures.

There is eventPtr which stores information relating to which key is pressed. Then the bindPtr takes an appropriate glyph from the hashtable, corresponding to the keySym from eventPtr and stores the result to the structure pointed to by patPtr (pattern pointer).

An example would help, I guess.

So, I press key "A". This is what goes in eventPtr. If I have CAPS LOCK off, then the actual text would be "a" and therefore the corresponding glyph "a" is picked from the hashtable by bindPtr. This "a" is passed onto patPtr.

In case, I want to write arabic, again pressing "A", gives the same keySym in eventPtr. From the hashtable, bindPtr will choose the appropriate glyph of " ش". In arabic the glyphs can be different due to the joining of the letters, even for the same letter. The appropriate glyph is passed onto patPtr.

This is then passed on to the dispPtr. I know (or at least I think) that these pointers to structures are used to form a linked list which is then handed over to the system/platform resources to render the text on the widget.

Am I on the right track so far or ... ? I ultimately, intend to use fribidi (binary or if not the binary then, the dynamic link library with the corresponding header files) to enable tk to handle arabic. If fribidi is not the appropriate choice then I would go for pango/cairo or something further.

thanks ! p.s. I know this question is sort of specific that only Tcl/Tk maintainers/developers could answer. I hope it is the right place to ask this !

Was it helpful?

Solution

This is really out of the scope of Stack Overflow, but let me say that I'm definitely supportive of someone who wants to work on this! I know I lack the specific expertise required (in particular, I wouldn't know what is correct behaviour) and so I can only help those who take this on. If you're such a person, THAT'S GREAT!

On the specific point of event bindings, I'd urge you to try to avoid working with the binding code itself if possible. Typically, the processing of a key that leads to a character being inserted in the widget is delegated to a (Tcl) script that invokes the correct code to insert the character (or character sequence — you can't assume that one key press produces one character). However, if you are merely seeking to augment the code that decides what characters are being inserted by a keypress as well as adding a way to tell the script which direction is associated with the character, that I can support.

The key sequence is inserted via the %A substitution (intercepting the keysyms is typically not advised if at all possible, as it doesn't work well with input method handling) and the content for that is fetched via TkpGetString; the implementation typically caches the string of characters inside an extended field of the event itself (otherwise using %A twice — which is very easily done in a complex binding set — leads to strange failures).

I've no idea how you might get the insertion direction (i.e., which direction to move the cursor in after writing that particular character) but when inserting the substitution, you pick some character that is either totally unused or that is not used for KEY or VIRTUAL events and augment that. Assuming the information is not passed via its own event; if it is done that way, just pass that event through to scripts (you'll definitely want to minimise the amount of work done in C).

For rendering, you'll need to look at the font engine. The source code to the main Unix font engine is in unix/tkUnixRFont.c, which works by delegating the majority of work to the Xft library. (There's also unix/tkUnixFont.c, which uses native X11 APIs, but that's not really encouraged for use; it tends to look ugly on modern displays. Or really on anything made within the past 10 years, especially when text is rotated, as can be done on the canvas.) I'd be not at all surprised if we get this area catastrophically wrong (except perhaps on OSX, and super doubly perhaps on Windows; they both have their own platform-specific rendering engines, but I don't know if we feed text through in large enough chunks to be useful yet).

There might be other places to look too as part of your programme of fixes. The widgets that do text entry are the entry/spinbox, the ttk::entry/ttk::spinbox, the ttk::combobox (I don't know how much that shares with the ttk::entry), the text widget (which is non-trivial code!) and the canvas widget via its text item.


I hope this gives you some info to get started. Once you've got something, even if it's not really working for anything other than a few basic cases, contact anyone on the Tcl Core Team (or, better, our mailing list) and we'll sort out a branch in the Tk source repository for you to work on. I'd really like to see proper bidi support; it's been something that I've known was missing for a long time now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top