create new tag
, view all tags




  • Reread the first 20 or so pages of the "Definition of the Porting Layer for the X .v11 Sample Server". There are an awful lot of clues there! Looks like I want to target making any changes in the DIX layer (device independent layer), somewhere around the function:

void DevicePtr->processInputProc(pEvent, device, count)

This function is called by procedures in the DDX layer each time an event should be delivered to the X server, and can be called as many times as necessary to deliver as many events as should be delivered. I don't want to make the change in the DDX layer — I may want to make my change near this function. Monitor for keypresses (down and up), watch for the special ones (what kind of data structure should they be in, how searched (and how edited by the user)). When one of the special keystrokes is found, maybe call this same function multiple times (twice for each keystroke in the keyboard macro) from the DIX layer (as I want this to be device independent code, not device dependent code). Am I ready to look in the code to find this function and look around? Well why not, if I find I'm not ready, I just back up a few steps.

It's interesting, I read this same document maybe a week ago, but didn't know enough to recognize that maybe it contained as many clues as it seems to — now it looks like it might be the main document I needed to find. How to know which document that is in advance?? (Of course, IIRC, somebody did refer me to this document.)

Some things to beware of:

  • Don't interfere with the special keystrokes that control the X server (like <ctrl><alt>7lt;backspace> (or +, or whatever).
  • What does auto repeat mean to this routine? (Maybe, as sort of a safety check, I don't want to expand an auto repeated special key?)
  • Watch the timing issues -- maybe if this code slows things down to much, I will need to be able to disable it on an application by application basis

  • Aside: I probably want to allow all modifier keys (and all combinations of modifier keys??) to be the prefix for a special key. Not that I think I'll ever define that many macros, but more based on my experience with Microsoft Word, especially Word97. They defined some macros with most of the common combinations of <ctrl>, <alt>, and <shift>. So, I could try to:
  • define my macros in the blanks of what they hadn't used (a real pain to remember)
  • reassign their macro keys to give myself an "open" "namespace" (a real pain anytime I had to use an unmodified version of Word, or somebody else used my machine)
  • choose an unused modifier key combination, no matter how painful (I chose <ctrl> <alt><shift>) so I could have a virgin "namespace" — I tended to do the <ctrl> <alt><shift> and pick macro keys on the right hand side of the keyboard).
  • Also, I want the ability to define at least two key macros. I suppose I could consider longer strings, and might, but two sounds like it should be sufficient in quantity
— longer strings might be more mnemonic.

Just one more afterthought, I will start searching for the function:

void DevicePtr->processInputProc(pEvent, device, count)


  • I may have to learn more about how a function pointer works to call a function (otherwise I may have trouble finding the places the function is called from)
  • However, it may be more important to review the "server's dispatch loop" and functions like:
    • int WriteToClient(who, n, buf)
    • void ProcessInputEvents() *
  • The xEvent variant that is relevant is the keyButtonPointer variant, which includes the following fields:

type &mdash; KeyPress, KeyRelease, ButtonPress, ButtonRelease, or MotionNotify
detail &mdash; for KeyPress or KeyRelease, this should be the key number &mdash; otherwise unused
time &mdash; 32 bit timestamp in milliseconds (arbitrary "origin") (the DDX layer is responsible for this &mdash; if I "synthesize" events in the DIX layer, will have to deal with this somehow.  (Increment by a millisecond per keystroke?  What happens if some of these synthesized events then end up "behind" some other real events?  Maybe don't increment &mdash; can there be a whole bunch of events with the same timestamp without causing problems?  How about any affect on the repeat keys?  Or any key debounce logic (although I'd expect that was already dealt with at a much lower level, like maybe the keyboard controller?)
rootX &mdash; x coordinate of cursor
rootY &mdash; y coordinate of cursor

Do those last two have to change as typing continues? I wouldn't think so, but maybe I'm wrong — I'm thinking that the coordinates really refer to what I sometimes call the mouse pointer, not to the "text insertion point". If they did refer to the text insertion point, they might have to move (change), but that sounds very complicated — the amount to move would depend on the font size, etc., etc., and since this is an input event I don't see how that would be known.

Do I need to worry about a situation where a very long keyboard macro ties up the system and blocks other productive work? I'm trying to convince myself that I don't:

  • Even though I've joked about a macro that inserts the Bible into the current application / file, I don't really expect to do that
  • The user of a macro should not be surprised if he generates a macro the size of the Bible if it ties up his system for some period of time. (He should consider how long he and the system would be tied up if he was typing in the Bible.)

Still there may be things to consider (especially if the system has any chance of being used in a real time control situation (although in that case, I'd hope any upper layer like X would be fully interruptible and interrupted by lower layers of the OS to properly handle the real time situation. And such interruption should be transparent to X, it's probably ususally fine for X to go back to transcribing the Bible (if that's what it was doing) — ahh, except for cases where real time input from the operator became required — maybe, in that case (which I don't think is relevant), there should be a mechanism to kill the macro expansion and allow keyboard input.

What else should I worry (or not worry) about? Don't know, maybe I'll do some searching for some of the things I mention above:

  • void DevicePtr->processInputProc(pEvent, device, count)
  • "server's dispatch loop"
  • int WriteToClient(who, n, buf)
  • void ProcessInputEvents()

Oh, before I go, maybe I need to dig into keyboard mapping and keycodes: "array of sets of keysyms for each key, that is of the length maxkeycode - minkeycode +1. Each element of the array is a list of codes for symbols that are on that key. ... no limit to the number of symbols that can be on a key."


  • Is "codes for symbols" == "keysyms"?
  • Is "list" == "set"?
  • Is the last statement referring to the number of modifiers that can be applied to a key?
  • The array is one dimensional only, the other dimension (set) is a list?? (Or is possibly implementation dependent?)
  • (Will I remember later what I'm driving at??) wink

In any event, I still think that this keyboard macro facility will work at the level of inserting additional keypresses and keyreleases with associated numerical keycodes, and something downstream will translate into keysyms for the application (or whoever needs the keysyms). This does mean that the macro will have to record and insert events on the modifier keys as well!!

_That may mean more storage space than some other approach (storing an ASCII string, but that doesn't seem to be in the realm of likelihood anyway, and it may be not much longer than storing a string of keysyms), but means that the macros can be recorded as keyboard events — if I want an upper case A in the macro, I will press <shift>, A, release the A, and then release the <shift> (or possibly the first two and last two at almost the same time), and that is what needs to be recorded in the macro. If I "generate" a macro in an editor, for example, by typing in a series of keystrokes (of the form keypress shift (i.e., keycode xxx), keypress a (keycode yyy), keyrelease a (keycode yyy), keyrelease shift (keycode xxx)) that will be more painful (more keystrokes) than some other possible approach but I think it's the appropriate approach, and I might provide a method to make input easier if I do create a macro editor. (Like simply record the keystrokes.)

What about situations like:

  • Recording a keyboard macro for (in) English and playing it back on a German "keyboard" (or, really I guess, German keymapping)? I think the macro will produce garbage, and I think that should be considered the appropriate behavior.

  • Are their situations where an Xserver will be working with multiple clients, some of whom are using a different keymapping resulting in a problem similar to above? Well, I suppose so — simplest example is if an Xserver is serving a German and an English (localized) X client. What should the behavior be? Interesting question! My first thought is that the user should deal with this — he might record some macros that are appropriate for the English application and others that are appropriate for the German application, he should take care to play them back only in the appropriate application — if he doesn't he gets garbage, and that should be considered the appropriate behavior.

  • Can I think of applications all in English where one might have different keymapping that another? Not sure, one possible example is an application that can do it's own keyboard macros (nedit, many others). First of all, the two facilities should not be considered to interfere with each other — in the case of nedit, one could define a keyboard macro in nedit or in the X server, and both facilities will work. If the X keyboard macros passes some keystrokes on to the nedit application that trigger macro expansion at the nedit level, that's just the way life is and the user must be responsible to deal with the situation.

  • (That wasn't quite the previous question, though, repeating:) Can I think of applications all in English where one might have different keymapping that another? Not offhand, but if I did, I think I'd make the same response — the user must take responsibility, and keep separate macros to be used with one application or the other (and not "cross utilize" them), or something similar.

Ok, it's all very well and good to say the user must take responsibility to play back macros only in the appropriate applications, but don't you (me) occasionally press the wrong keys, and won't you get very upset if doing that causes some major deletion? Yes. Is there anything that can be done about that? Well, we can think about it. Maybe, like some other operator tools, the user must train himself (I must train myself) to not include key sequences in macros that are likely to cause deletions or be command shortcuts. (Like <alt>f,x.) Then it gets worse when you go cross language — an innocent looking macro in German might indeed invoke the same keycodes as <alt>f,x. Maybe at the cross language "level" there could be a check of some sort — record the keymap that a macro was redorded in and only allow playback in an application with the same keymap?? But, then it sounds like we need information from the client. (Who is keeper of the keymap?). Not sure that it can be done, or how easy it might be to do, but I'll try to keep it in mind as I go through this stuff.


  • () RandyKramer - 28 Apr 2003
  • If you edit this page: add your name here; move this to the next line; and if you've used a comment marker (your initials in parenthesis), include it before your WikiName.

Page Ratings

Edit | Attach | Watch | Print version | History: r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r3 - 2003-04-28 - RandyKramer
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by PerlCopyright 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding WikiLearn? WebBottomBar">Send feedback
See TWiki's New Look