r511 - in trunk/src/target/OM-2007/applications: . openmoko-keyboard openmoko-keyboard/examples openmoko-keyboard/examples/.deps openmoko-keyboard/layouts openmoko-keyboard/src

caowai_song at gta01.hmw-consulting.de caowai_song at gta01.hmw-consulting.de
Mon Jan 8 03:24:03 CET 2007


Author: caowai_song
Date: 2007-01-08 03:22:58 +0100 (Mon, 08 Jan 2007)
New Revision: 511

Added:
   trunk/src/target/OM-2007/applications/openmoko-keyboard/
   trunk/src/target/OM-2007/applications/openmoko-keyboard/AUTHORS
   trunk/src/target/OM-2007/applications/openmoko-keyboard/COPYING
   trunk/src/target/OM-2007/applications/openmoko-keyboard/ChangeLog
   trunk/src/target/OM-2007/applications/openmoko-keyboard/INSTALL
   trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.am
   trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.in
   trunk/src/target/OM-2007/applications/openmoko-keyboard/NEWS
   trunk/src/target/OM-2007/applications/openmoko-keyboard/README
   trunk/src/target/OM-2007/applications/openmoko-keyboard/autogen.sh
   trunk/src/target/OM-2007/applications/openmoko-keyboard/configure.ac
   trunk/src/target/OM-2007/applications/openmoko-keyboard/doc/
   trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/
   trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/.deps/
   trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/.deps/matchbox-keyboard-gtk-embed.Po
   trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/Makefile.am
   trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/matchbox-keyboard-gtk-embed.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/Makefile.am
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-dvorak.xml
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-extended.xml
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-fi.xml
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-numpad.xml
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-ru.xml
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-us.xml
   trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard.xml
   trunk/src/target/OM-2007/applications/openmoko-keyboard/matchbox-keyboard.desktop
   trunk/src/target/OM-2007/applications/openmoko-keyboard/matchbox-keyboard.png
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/Makefile.am
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/config-parser.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-defs.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-image.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-key.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-layout.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-row.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.h
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.h
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-xembed.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.h
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.c
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.h
   trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util.c
Log:
This is a copy of the matchbox-keyboard. 

The interface of the matchbox-keyboard is simple, and don't suit the 
style of the openmoko. I'd like to change the display mode of it.



Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/AUTHORS
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/AUTHORS	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/AUTHORS	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,2 @@
+Matthew Allum <mallum at o-hand.com>  ( Most stuff )
+Tuukka Pasanen <tuukka.pasanen at ilmi.fi> ( Cairo work, initial -xid work )

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/COPYING
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/COPYING	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/COPYING	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/ChangeLog
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/ChangeLog	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/ChangeLog	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,515 @@
+2006-07-20  Matthew Allum  <mallum at openedhand.com>
+
+	* layouts/keyboard-ru.xml:
+	* src/config-parser.c: (config_handle_key_subtag),
+	(config_handle_layout_tag), (config_xml_start_cb),
+	(mb_kbd_config_load):
+	Apply patches from Paul Sokolovsky for Russian layout
+	improvements and more error messages from config parser.
+
+2006-05-22  Matthew Allum  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kdb_ui_unit_key_size):
+	Dont include keys with set width in min key size calc.
+
+2006-05-16  Matthew Allum  <mallum at openedhand.com>
+
+	* README:
+	Add some notes on setting images on key faces.
+
+2006-05-16  Matthew Allum  <mallum at openedhand.com>
+
+	* src/config-parser.c: (config_handle_key_subtag):
+	Try and load relative image filenaes
+	* src/matchbox-keyboard-image.c: (png_file_load),
+	(mb_kbd_image_new):
+	Force an alpha channel into PNG images without one.
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_min_key_size),
+	(mb_kbd_ui_allocate_ui_layout):
+	Fix a layout issue in mb_kbd_ui_min_key_size() lieing.
+
+2006-05-15  Matthew Allum  <mallum at openedhand.com>
+
+	* configure.ac:
+	* layouts/keyboard.xml:
+	* src/Makefile.am:
+	* src/config-parser.c: (config_handle_key_subtag):
+	* src/matchbox-keyboard-image.c:
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_set_image_face):
+	* src/matchbox-keyboard-ui-xft-backend.c:
+	(mb_kbd_ui_xft_redraw_key):
+	* src/matchbox-keyboard-ui.c: (mb_kdb_ui_unit_key_size),
+	(mb_kbd_ui_min_key_size):
+	* src/matchbox-keyboard.h:
+	Add initial support for defineable PNG images on keys.
+	Keys with images sizing a little borked atm.
+
+2006-03-31  Matthew Allum  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_event_loop):
+	Add some basic gesture support.
+
+2006-03-15  Matthew Allum  <mallum at openedhand.com>
+
+	* layouts/keyboard-ru.xml:
+	Fix broken XML
+
+2006-03-02  Matthew Allum  <mallum at openedhand.com>
+
+	* layouts/Makefile.am:
+	* layouts/keyboard-us.xml:
+	Add US layout from Matt Reimer
+
+2006-02-28  Matthew Allum  <mallum at openedhand.com>
+
+	* src/config-parser.c: (config_load_file):
+	Use ~/.matchbox not ~/matchbox
+
+2006-02-28  Matthew Allum  <mallum at openedhand.com>
+
+	* configure.ac:
+	Make version 0.1. Make cairo usage explicit.
+
+	* layouts/Makefile.am:
+	* layouts/keyboard-numpad.xml:
+	New Layout.
+
+	* src/matchbox-keyboard-ui-xft-backend.c:
+	(mb_kbd_ui_xft_redraw_key):
+	* src/matchbox-keyboard-ui.c: (mb_kdb_ui_unit_key_size),
+	(mb_kbd_ui_allocate_ui_layout), (mb_kbd_ui_handle_configure),
+	(mb_kbd_ui_event_loop):
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	Fixups for layout on small screens and improvements for high
+	DPI layouts.
+
+
+2005-10-27  Matthew Allum  <mallum at openedhand.com>
+
+	* README:
+	Update with current info
+	* src/config-parser.c: (mb_kbd_config_load):
+	* src/matchbox-keyboard-ui.c: (mb_kdb_ui_unit_key_size),
+	(mb_kbd_ui_min_key_size), (mb_kbd_ui_allocate_ui_layout),
+	(mb_kbd_ui_resize), (mb_kbd_ui_realize):
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	Minor cleanups. Improve cmd line option parsing and add
+	a usage() func. 
+
+2005-10-26  Matthew Allum  <mallum at openedhand.com>
+
+	* examples/Makefile.am:
+	* examples/matchbox-keyboard-embbed.c:
+	Rename matchbox-keyboard-embbed.c
+
+2005-10-26  Matthew Allum  <mallum at openedhand.com>
+
+	* AUTHORS:
+	Populate. 	
+	* Makefile.am:
+	* configure.ac:
+	* src/Makefile.am:
+	Fix cairo build issues, 
+
+	* src/matchbox-keyboard-xembed.c:
+	Add XEMBED support for embedding keyboard in other apps.
+	
+	* examples/Makefile.am:
+	* examples/matchbox-keyboard-embbed.c:
+	Add example embedding app
+
+	* src/config-parser.c: (config_str_to_keysym),
+	(config_str_to_modtype), (config_xml_start_cb):
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_get_extended),
+	(mb_kbd_key_set_row), (mb_kdb_key_has_state),
+	(mb_kbd_key_set_glyph_face), (mb_kbd_key_get_glyph_face),
+	(mb_kbd_key_set_image_face), (mb_kbd_key_set_char_action),
+	(mb_kbd_key_press):
+	* src/matchbox-keyboard-layout.c:
+	* src/matchbox-keyboard-row.c:
+	* src/matchbox-keyboard-ui-cairo-backend.c:
+	(mb_kbd_ui_cairo_text_extents), (mb_kbd_ui_cairo_load_font),
+	(mb_kbd_ui_cairo_redraw_key), (mb_kbd_ui_cairo_pre_redraw),
+	(mb_kbd_ui_cairo_resources_create), (mb_kbd_ui_cairo_resize),
+	(mb_kbd_ui_cairo_init):
+	* src/matchbox-keyboard-ui-cairo-backend.h:
+	* src/matchbox-keyboard-ui-xft-backend.c:
+	(mb_kbd_ui_xft_text_extents), (mb_kbd_ui_xft_redraw_key),
+	(mb_kbd_ui_xft_resources_create), (mb_kbd_ui_xft_resize),
+	(mb_kbd_ui_xft_init):
+	* src/matchbox-keyboard-ui-xft-backend.h:
+	* src/matchbox-keyboard-ui.c: (get_current_window_manager_name),
+	(get_desktop_area), (get_xevent_timed),
+	(mb_kbd_ui_send_keysym_press), (mb_kbd_ui_send_release),
+	(mb_kdb_ui_unit_key_size), (mb_kbd_ui_min_key_size),
+	(mb_kbd_ui_redraw_row), (mb_kbd_ui_swap_buffers),
+	(mb_kbd_ui_redraw), (mb_kbd_ui_resources_create),
+	(mb_kbd_ui_resize), (mb_kbd_ui_event_loop), (mb_kbd_ui_realize),
+	(mb_kbd_ui_init):
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	* src/matchbox-keyboard.h:
+	* src/util.c: (util_utf8_char_cnt), (util_file_readable):
+	Fix GCC 4 Warnings.
+	Add License to all files.
+	Improve buggy cairo backend and add gradient keys 
+
+2005-10-21  Matthew Allum  <mallum at openedhand.com>
+
+	* configure.ac:
+	* src/Makefile.am:
+	* src/matchbox-keyboard-ui-cairo-backend.c:
+	* src/matchbox-keyboard-ui-cairo-backend.h:
+	* src/matchbox-keyboard-ui-xft-backend.c:
+	* src/matchbox-keyboard-ui-xft-backend.h:
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_resources_create):
+	* src/matchbox-keyboard.h:
+	Break out rendering backend and add optional initial cairo
+	based rendering backend ( based on patch from Tuukka Pasanen )
+
+	* layouts/Makefile.am:
+	* layouts/keyboard-fi.xml:
+	Add finish layout via  Tuukka Pasanen
+
+2005-10-10  Matthew Allum  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_event_loop):
+	Handle 'stuck' key case ( hopefully ) when release X event is 
+	missed.	
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	Qucik hacks to look better on small displays.
+
+2005-10-10  mallum,,,  <mallum at openedhand.com>
+
+	reviewed by: <delete if not using a buddy>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_event_loop):
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+
+2005-10-04  mallum  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	Make initial point size smaller to kbd fitting on large DPI's.
+
+2005-09-15  mallum,,,  <mallum at openedhand.com>
+
+	* layouts/keyboard.xml:
+	Minor fixes via Michal Ludvig
+
+2005-09-15  mallum,,,  <mallum at openedhand.com>
+
+	reviewed by: <delete if not using a buddy>
+
+	* layouts/keyboard.xml:
+
+2005-09-15  mallum,,,  <mallum at openedhand.com>
+
+	reviewed by: <delete if not using a buddy>
+
+	* layouts/keyboard.xml:
+
+2005-09-01  mallum,,,  <mallum at openedhand.com>
+
+	* layouts/Makefile.am:
+	* layouts/keyboard-ru.xml:
+	Add Russian layout from Stanislav Bogatyrev
+
+2005-06-20  mallum,,,  <mallum at openedhand.com>
+
+	* layouts/Makefile.am:
+	* layouts/keyboard-dvorak.xml:
+	Add dvorak from Leon Matthews.
+
+2005-05-17  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_resources_create):
+	Add SKIP_PAGER hint.
+
+2005-05-10  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_resources_create):
+	Attempt to better support metacity.
+
+2005-05-02  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (want_extended),
+	(mb_kbd_ui_resources_create), (mb_kbd_ui_resize),
+	(mb_kbd_ui_handle_configure), (mb_kbd_ui_event_loop),
+	(mb_kbd_ui_load_font), (mb_kbd_ui_init), (mb_kbd_ui_display_width),
+	(mb_kbd_ui_display_height), (mb_kbd_ui_realize):
+	* src/matchbox-keyboard.c:
+	* src/matchbox-keyboard.h:
+	Clean up warnings
+	Implement key repeat
+
+2005-04-27  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_resize),
+	(mb_kbd_ui_events_iteration):
+	Handle MappingNotify events
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	Make keys slightly bigger for small ( 240x320 ) displays.
+
+2005-04-27  mallum,,,  <mallum at openedhand.com>
+
+	* layouts/keyboard.xml:
+	Swicth shift state for ; key
+
+2005-04-27  mallum,,,  <mallum at openedhand.com>
+
+
+	* layouts/keyboard.xml:
+	New layout with extended keys.
+
+	* src/config-parser.c: (config_handle_key_tag):
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_get_extra_width_pad):
+	* src/matchbox-keyboard-row.c: (mb_kbd_row_height),
+	(mb_kbd_row_width), (mb_kbd_row_base_width):
+	* src/matchbox-keyboard-ui.c: (get_desktop_area),
+	(mb_kbd_ui_send_keysym_press), (mb_kbd_ui_send_release),
+	(mb_kdb_ui_unit_key_size), (mb_kbd_ui_min_key_size),
+	(mb_kbd_ui_allocate_ui_layout), (mb_kbd_ui_redraw_key),
+	(mb_kbd_ui_redraw_row), (mb_kbd_ui_resources_create),
+	(mb_kbd_ui_resize), (mb_kbd_ui_handle_configure),
+	(mb_kbd_ui_events_iteration), (mb_kbd_ui_load_font),
+	(mb_kbd_ui_init), (mb_kbd_ui_display_width),
+	(mb_kbd_ui_display_height), (mb_kbd_ui_realize):
+	* src/matchbox-keyboard.c: (mb_kbd_locate_key),
+	(mb_kbd_get_held_key):
+	* src/matchbox-keyboard.h:
+	Make keyboard 'adapt' with extended keys to screen rotation
+	and screen orientation.
+
+2005-04-26  mallum,,,  <mallum at openedhand.com>
+
+	* configure.ac:
+	* data/Makefile.am:
+	* data/keyboard-extended.xml:
+	* data/keyboard.xml:
+	Rename data -> layouts
+	* Makefile.am:
+	* matchbox-keyboard.desktop:
+        * matchbox-keyboard.png
+	Add a icon and .desktop file
+
+2005-04-26  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_resources_create):
+	Fix taskbar skip hint
+
+2005-04-26  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (get_current_window_manager_name),
+	(mb_kbd_ui_redraw), (mb_kbd_ui_show), (mb_kbd_ui_resources_create),
+	(mb_kbd_ui_resize):
+	Try to avoid ugly flash ( caused by repaint/resize ) on startup.
+	Also probably speeds up startup a little.
+
+2005-04-26  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c:
+	* src/matchbox-keyboard.h:
+	* src/util-list.c: (util_list_append):
+	* src/util.c:
+	Clean up some compiler warnings.
+
+2005-04-26  mallum,,,  <mallum at openedhand.com>
+
+	* README:
+	Small update on Todo.
+	* configure.ac:
+	Fix a minor snafu
+
+2005-04-26  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_resources_create):
+        Make key faces darker to increase visibility on Ipaq.
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	Make small font smaller to fit Ipaq display
+
+2005-04-24  mallum,,,  <mallum at openedhand.com>
+
+	* README:
+        Write one.
+	* configure.ac:
+	* data/keyboard.xml:
+	* src/config-parser.c: (config_load_file):
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_redraw),
+	(mb_kbd_ui_resources_create), (mb_kbd_ui_resize):
+	* src/matchbox-keyboard.h:
+	Various minor tweaks. 
+
+2005-04-21  mallum,,,  <mallum at openedhand.com>
+
+	* configure.ac:
+	Remove unneeded libmb dep check
+
+2005-04-21  mallum,,,  <mallum at openedhand.com>
+
+
+	* Makefile.am:
+	* configure.ac:
+	* data/Makefile.am:
+	* data/keyboard-extended.xml:
+	* data/keyboard.xml:
+	* src/Makefile.am:
+	* src/config.xml:
+	Sort out keyboard configs so they actually get installed.
+	* src/config-parser.c: (config_handle_key_tag),
+	(config_xml_start_cb), (mb_kbd_config_load):
+	and then loaded
+	* src/matchbox-keyboard-row.c: (mb_kbd_row_base_width):
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_allocate_ui_layout),
+	(mb_kbd_ui_resources_create), (mb_kbd_ui_resize),
+	(mb_kbd_ui_events_iteration), (mb_kbd_ui_load_font),
+	(mb_kbd_ui_init):
+	* src/matchbox-keyboard.c: (mb_kbd_new):
+	* src/matchbox-keyboard.h:
+	Fix layout resizing code. Make defaults dependant on display size.
+	* src/util.c: (util_utf8_char_cnt):
+	remove random printf
+
+2005-04-20  mallum,,,  <mallum at openedhand.com>
+
+	* src/config.xml:
+	Improve layout some more with experimentation
+	* src/matchbox-keyboard-key.c:
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_allocate_ui_layout):
+	Fix some layout bugs - making 'fill' work.
+
+2005-04-19  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_press),
+	(mb_kbd_key_release):
+	* src/matchbox-keyboard-ui.c: (alloc_color),
+	(mb_kbd_ui_redraw_key), (mb_kbd_ui_redraw_row),
+	(mb_kbd_ui_swap_buffers), (mb_kbd_ui_redraw), (mb_kbd_ui_show),
+	(mb_kbd_ui_resources_create):
+	* src/matchbox-keyboard.c: (mb_kbd_add_state):
+	* src/matchbox-keyboard.h:
+	Fix caps handling and modifier toggling. 
+	Add a chunk of WM handling and 'co-operation'.
+
+2005-04-18  mallum,,,  <mallum at openedhand.com>
+
+	* src/config-parser.c: (config_str_to_modtype),
+	(config_handle_key_subtag):
+	* src/config.xml:
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_is_blank),
+	(mb_kbd_key_height), (mb_kbd_key_get_modifer_action),
+	(mb_kbd_key_get_face_type), (mb_kbd_key_get_action_type),
+	(mb_kbd_key_press):
+	* src/matchbox-keyboard-row.c: (mb_kbd_row_width):
+	* src/matchbox-keyboard-ui.c: (alloc_color),
+	(mb_kbd_ui_send_press), (mb_kbd_ui_send_keysym_press),
+	(mb_kbd_ui_redraw_key), (mb_kbd_ui_redraw_row), (mb_kbd_ui_redraw),
+	(mb_kbd_ui_show), (mb_kbd_ui_resources_create), (mb_kbd_ui_resize),
+	(mb_kbd_ui_events_iteration), (mb_kbd_ui_load_font),
+	(mb_kbd_ui_init):
+	* src/matchbox-keyboard.c: (mb_kbd_new), (mb_kbd_add_state),
+	(mb_kbd_locate_key), (mb_kbd_add_layout),
+	(mb_kbd_get_selected_layout):
+	* src/matchbox-keyboard.h:
+	* src/util-list.c:
+	Implement more state handling.
+	Handle window resizes.
+
+2005-04-18  mallum,,,  <mallum at openedhand.com>
+
+	* src/config-parser.c: (config_handle_key_subtag):
+	* src/config.xml:
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_set_keysym_action),
+	(mb_kbd_key_get_keysym_action), (mb_kbd_key_press):
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_redraw_key):
+	* src/matchbox-keyboard.c: (mb_kbd_keys_margin):
+	* src/matchbox-keyboard.h:
+	Initial code for handling 'modifiers'
+
+2005-04-17  mallum,,,  <mallum at openedhand.com>
+
+	* src/matchbox-keyboard-ui.c: (text_extents),
+	(mb_kbd_ui_allocate_ui_layout), (mb_kbd_ui_redraw_key),
+	(mb_kbd_ui_redraw_row), (mb_kbd_ui_swap_buffers),
+	(mb_kbd_ui_redraw), (mb_kbd_ui_show), (mb_kbd_ui_resources_create),
+	(mb_kbd_ui_events_iteration), (mb_kbd_ui_init):
+	Make keys look a little nicer
+
+2005-04-17  mallum,,,  <mallum at openedhand.com>
+
+	* src/config-parser.c: (config_handle_row_tag),
+	(config_handle_key_tag), (config_xml_start_cb):
+	* src/config.xml:
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_new),
+	(mb_kbd_key_set_geometry), (mb_kbd_key_abs_x), (mb_kbd_key_abs_y),
+	(mb_kbd_key_x), (mb_kbd_key_y), (mb_kbd_key_width),
+	(mb_kbd_key_height), (mb_kbd_key_set_row), (mb_kdb_key_has_state),
+	(mb_kbd_key_set_glyph_face), (mb_kbd_key_get_glyph_face),
+	(mb_kbd_key_set_image_face), (mb_kbd_key_set_char_action),
+	(mb_kbd_key_get_char_action), (mb_kbd_key_set_keysym_action),
+	(mb_kbd_key_get_keysym_action), (mb_kbd_key_set_modifer_action),
+	(mb_kbd_key_get_face_type), (mb_kbd_key_get_action_type),
+	(mb_kbd_key_press):
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_send_press),
+	(mb_kdb_ui_unit_key_size), (mb_kbd_ui_min_key_size),
+	(mb_kbd_ui_allocate_ui_layout), (mb_kbd_ui_redraw_key):
+	* src/matchbox-keyboard.c: (mb_kbd_locate_key):
+	* src/matchbox-keyboard.h:
+	Layout engine improvements
+
+2005-04-13  mallum,,,  <mallum at openedhand.com>
+
+	reviewed by: <delete if not using a buddy>
+
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_press):
+	* src/matchbox-keyboard-ui.c: (text_extents),
+	(mb_kbd_ui_send_press), (mb_kbd_ui_events_iteration):
+	* src/matchbox-keyboard.c: (mb_kbd_locate_key):
+	* src/matchbox-keyboard.h:
+	Fix locate_key(). Handle press/release cycle better 
+
+2005-04-13  mallum,,,  <mallum at openedhand.com>
+
+	* src/config.xml:
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_new),
+	(mb_kbd_key_height), (mb_kbd_key_set_row), (mb_kdb_key_has_state),
+	(mb_kbd_key_set_glyph_face), (mb_kbd_key_get_glyph_face),
+	(mb_kbd_key_set_image_face), (mb_kbd_key_set_char_action),
+	(mb_kbd_key_get_char_action), (mb_kbd_key_set_keysym_action),
+	(mb_kbd_key_set_modifer_action), (mb_kbd_key_get_face_type),
+	(mb_kbd_key_get_action_type):
+	* src/matchbox-keyboard-row.c: (mb_kbd_row_new):
+	* src/matchbox-keyboard-ui.c: (mb_kbd_ui_send_press),
+	(mb_kdb_ui_unit_key_size), (mb_kbd_ui_allocate_ui_layout),
+	(mb_kbd_ui_redraw_key), (mb_kbd_ui_redraw_row),
+	(mb_kbd_ui_swap_buffers), (mb_kbd_ui_redraw), (mb_kbd_ui_show),
+	(mb_kbd_ui_resources_create), (mb_kbd_ui_events_iteration),
+	(mb_kbd_ui_init):
+	* src/matchbox-keyboard.c: (mb_kbd_new), (mb_kbd_col_spacing),
+	(mb_kbd_keys_border), (mb_kbd_keys_pad), (mb_kbd_keys_margin),
+	(mb_kbd_locate_key), (mb_kbd_add_layout),
+	(mb_kbd_get_selected_layout):
+	* src/matchbox-keyboard.h:
+	* src/util-list.c: (util_list_alloc_item):
+	* src/util.c: (util_fatal_error):
+	Initial UI drawing code
+
+2005-04-10  mallum,,,  <mallum at openedhand.com>
+
+	* configure.ac:
+	Bring in Xft
+	* src/config-parser.c: (config_handle_key_subtag),
+	(config_handle_layout_tag), (config_handle_row_tag),
+	(config_handle_key_tag), (config_xml_start_cb):
+	* src/config.xml:
+	* src/matchbox-keyboard-key.c: (mb_kbd_key_set_glyph_face),
+	(mb_kbd_key_get_glyph_face), (mb_kbd_key_set_image_face),
+	(mb_kbd_key_set_modifer_action), (mb_kbd_key_get_face_type),
+	(mb_kbd_key_get_action_type):
+	* src/matchbox-keyboard-layout.c: (mb_kbd_layout_append_row):
+	* src/matchbox-keyboard-row.c:
+	* src/matchbox-keyboard-ui.c: (mb_kdb_ui_unit_key_size),
+	(mb_kbd_ui_allocate_ui_layout), (mb_kbd_ui_init):
+	* src/matchbox-keyboard.c: (mb_kbd_new), (mb_kbd_add_layout):
+	* src/matchbox-keyboard.h:
+	* src/util-list.c:
+	* src/util.c: (util_fatal_error):
+	Various fixes and improvements. Too many to list

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/INSTALL
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/INSTALL	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/INSTALL	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.am
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.am	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.am	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,17 @@
+SUBDIRS = src layouts
+
+if WANT_EXAMPLES
+SUBDIRS += examples
+endif
+
+EXTRA_DIST = matchbox-keyboard.desktop matchbox-keyboard.png
+
+desktopdir = $(datadir)/applications/inputmethods
+desktop_DATA = matchbox-keyboard.desktop
+
+pixmapsdir = $(datadir)/pixmaps/
+pixmaps_DATA = matchbox-keyboard.png
+
+
+snapshot:
+	$(MAKE) dist distdir=$(PACKAGE)-snap`date +"%Y%m%d"`

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.in
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.in	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/Makefile.in	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,653 @@
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ at WANT_EXAMPLES_TRUE@am__append_1 = examples
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
+	$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
+	depcomp install-sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-exec-recursive install-info-recursive \
+	install-recursive installcheck-recursive installdirs-recursive \
+	pdf-recursive ps-recursive uninstall-info-recursive \
+	uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(pixmapsdir)"
+desktopDATA_INSTALL = $(INSTALL_DATA)
+pixmapsDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(desktop_DATA) $(pixmaps_DATA)
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = src layouts examples
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXPAT_CFLAGS = @EXPAT_CFLAGS@
+EXPAT_LIBS = @EXPAT_LIBS@
+FAKEKEY_CFLAGS = @FAKEKEY_CFLAGS@
+FAKEKEY_LIBS = @FAKEKEY_LIBS@
+GTK2_CFLAGS = @GTK2_CFLAGS@
+GTK2_LIBS = @GTK2_LIBS@
+HAVE_EXPAT = @HAVE_EXPAT@
+HAVE_XMLPARSE_H = @HAVE_XMLPARSE_H@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_CFLAGS = @PNG_CFLAGS@
+PNG_LIBS = @PNG_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WANT_CAIRO_FALSE = @WANT_CAIRO_FALSE@
+WANT_CAIRO_TRUE = @WANT_CAIRO_TRUE@
+WANT_EXAMPLES_FALSE = @WANT_EXAMPLES_FALSE@
+WANT_EXAMPLES_TRUE = @WANT_EXAMPLES_TRUE@
+XFT_CFLAGS = @XFT_CFLAGS@
+XFT_LIBS = @XFT_LIBS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+SUBDIRS = src layouts $(am__append_1)
+EXTRA_DIST = matchbox-keyboard.desktop matchbox-keyboard.png
+desktopdir = $(datadir)/applications/inputmethods
+desktop_DATA = matchbox-keyboard.desktop
+pixmapsdir = $(datadir)/pixmaps/
+pixmaps_DATA = matchbox-keyboard.png
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh:
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+	      cd $(srcdir) && $(AUTOMAKE) --gnu  \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	cd $(top_srcdir) && $(AUTOHEADER)
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+uninstall-info-am:
+install-desktopDATA: $(desktop_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(desktopdir)" || $(mkdir_p) "$(DESTDIR)$(desktopdir)"
+	@list='$(desktop_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(desktopDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(desktopdir)/$$f'"; \
+	  $(desktopDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(desktopdir)/$$f"; \
+	done
+
+uninstall-desktopDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(desktop_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(desktopdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(desktopdir)/$$f"; \
+	done
+install-pixmapsDATA: $(pixmaps_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pixmapsdir)" || $(mkdir_p) "$(DESTDIR)$(pixmapsdir)"
+	@list='$(pixmaps_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(pixmapsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pixmapsdir)/$$f'"; \
+	  $(pixmapsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pixmapsdir)/$$f"; \
+	done
+
+uninstall-pixmapsDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pixmaps_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(pixmapsdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(pixmapsdir)/$$f"; \
+	done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	mkdir $(distdir)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+	list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(mkdir_p) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	    distdir=`$(am__cd) $(distdir) && pwd`; \
+	    top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+	    (cd $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$top_distdir" \
+	        distdir="$$distdir/$$subdir" \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r $(distdir)
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && cd $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+	@cd $(distuninstallcheck_dir) \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(DATA) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(pixmapsdir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-desktopDATA install-pixmapsDATA
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-desktopDATA uninstall-info-am \
+	uninstall-pixmapsDATA
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+	check-am clean clean-generic clean-recursive ctags \
+	ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
+	dist-tarZ dist-zip distcheck distclean distclean-generic \
+	distclean-hdr distclean-recursive distclean-tags \
+	distcleancheck distdir distuninstallcheck dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-desktopDATA install-exec \
+	install-exec-am install-info install-info-am install-man \
+	install-pixmapsDATA install-strip installcheck installcheck-am \
+	installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic maintainer-clean-recursive \
+	mostlyclean mostlyclean-generic mostlyclean-recursive pdf \
+	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+	uninstall-desktopDATA uninstall-info-am uninstall-pixmapsDATA
+
+
+snapshot:
+	$(MAKE) dist distdir=$(PACKAGE)-snap`date +"%Y%m%d"`
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/NEWS
===================================================================

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/README
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/README	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/README	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,218 @@
+                           Matchbox-Keyboard README
+                           ========================
+
+Introduction
+===
+
+Matchbox-keyboard is an on screen 'virtual' or 'software' keyboard. It
+will hopefully work well on various touchscreen devices from mobile
+phones to tablet PCs running X Windows.
+
+It aims to 'just work' supporting localised, easy to write XML layout
+configuration files.
+
+Its made available under the GPL.
+
+
+Rational
+===
+
+I wrote 'xkbd' a few years back which tried to do the same thing. It
+was the first xlib app I wrote and the first bit of C Id coded in
+quite a few years. It was a mess but basically worked, though with
+a few problems.
+
+matchbox-keyboard is my much promised rewrite. The code is cleaner 
+and it hopefully addresses much of the previous short comings of xkbd.
+
+
+Building
+===
+
+Do the usual autotool jig of ./configure, make, make install. ( If
+building from SVN you'll need to run ./autogen.sh before this).
+
+matchbox-keyboard needs xlibs, xft, libfakekey and expat to build -
+The configure script will detect these. Also optionally there is
+experimental cairo support for rendering the keys and example
+embeddeding code.
+
+
+Running
+===
+
+Do;
+
+  matchbox-keyboard [Options..] [optional variant name]
+
+and start typing. The config file will be selected based on locale
+setting and supplied variant name. The onlu current option is -xid,
+used for embedding ( see below ).
+
+The following Environmental Variables are also used, if set;
+
+ * MB_KBD_CONFIG
+ 
+   Set to full path of a alternate layout file to use overriding any other
+   selection mechanisms.
+
+ * MB_KBD_VARIANT
+
+   Same as the first argument to binary. If both set argument overrides.
+
+ * LANG, MB_KBD_LANG 
+
+   The value up to the first '.' ( i.e en_GB ) is used to build up 
+   the config file name based on locale. MB_KBD_LANG can be used to
+   override the systems LANG var ( E.g, for the case of a Dutch person
+   wanting a Dutch keyboard but an English locale - or the other way 
+   round ).
+
+Embedding
+===
+
+You can embed matchbox-keyboard into other applications with toolkits
+that support the XEMBED protocol ( GTK2 for example ). 
+
+See examples/matchbox-keyboard-gtk-embed.c for how its done. 
+
+Making your own keyboard layouts
+===
+
+Keyboard layout files are UTF8 XML files ( Make sure they are saved
+with this encoding! ). They are loaded from the directory
+$PREFIX/share/matchbox-keyboard and are named in the format
+keyboard[-locale][-variant].xml. This can be overridden by setting
+MB_KBD_CONFIG environment variable to a valid config file path or by
+creating $HOME/.matchbox/keyboard.xml.
+
+The basic layout of the file looks like;
+
+    <keyboard>
+
+    <options>
+    </options>
+
+    <layout>
+      <row>
+        <key ...>
+	  <default .. >
+	  <shifted .. >
+	  <mod1 .. >
+          ....
+	<key>
+        .... more keys ...
+	<space width="1000" />
+      </row>
+      <row>
+      ...
+      </row>
+    </layout>
+
+    </keyboard>
+
+A number of layouts can be defined ( though currently only 1 is
+supported ) each with any number of rows of keys, defining the
+keyboard from top to bottom.
+
+The most important tag to know about is the <key> tag and its
+children. A key tag can optionally have the following attributes;
+
+  * obey-caps=true|false ( defaults to false if not declared )
+
+  Specifies if the key obeys the Caps Lock key - Its shifted state
+  is shown when the Caps key is held.
+
+  * width=1000th's of a 'base' key width.
+
+  Override the automatically calculated key width in 1000th's of 
+  a base key width ( The average width of a key with a single glyph ).
+
+  * fill=true|false ( defaults to false )
+
+  If set, the keys width is set to fill all available free space. 
+
+  * extended=true|false ( defaults to false )
+
+  Keys set with this extended attribute set to true will *only*
+  be shown if the display is landscape, rather than portrait.
+  The rational for this is to better adapt to screen rotations.
+  ( Note: the <space> tag can also use this. )
+  
+
+The <key> then has sub tags specifies the appearance and action for
+the five possible key states; <default>,<shifted>,<mod1>,<mod2>,<mod3>.
+
+There are two possible attributes for each of these state tags;
+
+  * display=UTF8 String|image:<filename>
+
+  Sets what is displayed on the key face for the particular case.
+  If this is not set the key will be blank.
+
+  Prefixing the string with 'image:' and then a filename to a valid
+  PNG image will cause that image to be used on that key face. The
+  filename can be abosolute or relative to
+  $PREFIX/share/matchbox-keyboard or ~/.matchbox.
+
+  * action=action string.
+
+  The specifies the action of the key. For most (all?) single glyph keys
+  the action is deduced automatically. For 'special' function keys, it
+  can be set to any of the following. 
+
+    backspace, tab, linefeed, clear, return, pause, scrolllock,
+    sysreq, escape, delete, home, left, up, right, down, prior,
+    pageup, next, pagedown, end, begin, space, f1, f2, f3, f4, f5, f6,
+    f7, f8, f9, f10, f11, f12
+
+  By prefixing the value with 'xkeysym:', a a xkeysym can be defined to
+  be 'pressed' as the action.
+  
+  If the key is a 'modifier' key, the action value is prefixed with 
+  'modifier:' and then one of the following;
+
+  Shift, Alt, Ctrl, mod1, mod2, mod3, Caps
+
+
+Rows can also contain a <space> tags which denote blank space. They
+simply take a width attribute specifying the base in 1000th's of a base
+key width.
+
+See the various keyboard.xml files included in the distribution for
+example setups.
+
+
+Misc Notes
+===
+
+ * matchbox-keyboard attempts to detect the window manager and set up its
+   window 'hints' based on that. This is experimental, YMMV.
+
+   matchbox-keyboard never wants to get keyboard focus itself, if the
+   window manager gives it focus ( matchbox-keyboard requests the 
+   w-m doesn't ), it wont work. 
+
+ * It shouldn't't be too hard to make the keyboard use GTK or another toolkit
+   ( possibly even Non X11 ) just by hacking matchbox-keyboard-ui.c . 
+   ( If you do either of these, please send patches ). 
+
+
+Todo
+===
+
+ * Fix layout engine on small on displays.
+
+ * Images on keys
+
+ Only text on key faces is currently supported. Probably do this via XRender
+ and libPNG ( or just cairo for cairo backend ).
+
+ * Themeing.
+
+ Needs thought... 
+
+
+
+Matthew Allum 2005.
+<mallum at openedhand.com>

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/autogen.sh
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/autogen.sh	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/autogen.sh	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,3 @@
+#! /bin/sh
+autoreconf -v --install || exit 1
+./configure --enable-maintainer-mode "$@"


Property changes on: trunk/src/target/OM-2007/applications/openmoko-keyboard/autogen.sh
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/configure.ac
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/configure.ac	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/configure.ac	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,230 @@
+AC_PREREQ(2.53)
+AC_INIT([matchbox-keyboard], 0.1, [mallum at handhelds.org])
+AC_CONFIG_SRCDIR([src/matchbox-keyboard.c])
+
+AM_INIT_AUTOMAKE()
+AM_MAINTAINER_MODE
+AM_CONFIG_HEADER(config.h)
+
+# Checks for programs.
+AC_GNU_SOURCE
+AC_PROG_CC
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_PID_T
+AC_HEADER_TIME
+
+# Checks for library functions.
+AC_FUNC_ALLOCA
+AC_FUNC_CLOSEDIR_VOID
+AC_FUNC_FORK
+AC_FUNC_SELECT_ARGTYPES
+AC_TYPE_SIGNAL
+AC_FUNC_STAT
+
+AC_ARG_ENABLE(cairo,
+  [  --enable-cairo    enable experimental Cairo support [default=no]],
+   		enable_cairo=$enableval, 
+		enable_cairo=no)	    
+
+AC_ARG_ENABLE(examples,
+  [  --enable-examples  Build embedding examples ( requires GTK ) [default=no]],
+   		enable_examples=$enableval, 
+		enable_examples=no)
+ 
+AC_ARG_ENABLE(debug,
+  [  --enable-debug    enable debug ( verbose ) build],
+     enable_debug=$enableval, enable_debug=no )
+
+AC_ARG_WITH(expat-includes,    
+  [  --with-expat-includes=DIR     Use Expat includes in DIR], 
+	   expat_includes=$withval, expat_includes=yes)
+
+AC_ARG_WITH(expat-lib,         
+  [  --with-expat-lib=DIR          Use Expat library in DIR], 
+	   expat_lib=$withval, expat_lib=yes)
+
+PKG_CHECK_MODULES(FAKEKEY, libfakekey,,
+	         AC_MSG_ERROR([*** You need to install libfakekey from MB SVN  ***]))
+
+if test x$enable_cairo = xyes; then
+   PKG_CHECK_MODULES(CAIRO, cairo,, [enable_cairo="no"])
+fi
+
+if test x$enable_cairo = xno; then
+PKG_CHECK_MODULES(XFT, xft,,
+	         AC_MSG_ERROR([*** Required xft Librarys not found ***]))
+fi
+
+AM_CONDITIONAL(WANT_CAIRO, test x$enable_cairo = xyes)
+
+if test x$enable_cairo = xyes; then
+   AC_DEFINE_UNQUOTED(WANT_CAIRO, 1, [Use Cairo to paint libs])
+fi
+
+if test x$enable_examples = xyes; then
+   PKG_CHECK_MODULES(GTK2, gtk+-2.0,, [enable_examples="no"])
+fi
+
+AM_CONDITIONAL(WANT_EXAMPLES, test x$enable_examples = xyes)
+
+dnl ------ Expat ------------------------------------------------------------
+
+  case "$expat_includes" in
+    yes|no)
+	EXPAT_CFLAGS=""
+	;;
+    *)
+	EXPAT_CFLAGS="-I$expat_includes"
+	;;
+  esac
+	
+  case "$expat_lib" in
+    yes)
+
+	case "$expat" in
+	  yes)
+		EXPAT_LIBS="-lexpat"
+		;;
+	    *)
+		EXPAT_LIBS="-L$expat/lib -lexpat"
+		;;
+	esac
+
+	;;
+   no)
+	;;
+   *)
+	EXPAT_LIBS="-L$expat_lib -lexpat"
+	;;
+   esac
+
+   expatsaved_CPPFLAGS="$CPPFLAGS"
+   CPPFLAGS="$CPPFLAGS $EXPAT_CFLAGS"
+   expatsaved_LIBS="$LIBS"
+   LIBS="$LIBS $EXPAT_LIBS"
+
+   AC_CHECK_HEADER(expat.h)
+   case "$ac_cv_header_expat_h" in
+     no)
+	 AC_CHECK_HEADER(xmlparse.h)
+
+	 case "$ac_cv_header_xmlparse_h" in
+	   no)
+		have_expat_header=no;
+		;;
+	   yes)
+		HAVE_XMLPARSE_H=1
+		AC_SUBST(HAVE_XMLPARSE_H)
+		AC_DEFINE_UNQUOTED(HAVE_XMLPARSE_H,$HAVE_XMLPARSE_H,
+				       [Use xmlparse.h instead of expat.h])
+		have_expat_header=yes
+	        ;;
+	 esac
+	 ;;
+     yes)
+	 have_expat_header=yes
+	;;
+   esac
+	
+   case "$have_expat_header" in
+     no)
+	expat=no
+	;;
+     yes)
+	AC_CHECK_FUNCS(XML_ParserCreate)
+
+	case "$ac_cv_func_XML_ParserCreate" in
+          no)
+	  	expat=no
+		;;
+	  yes)
+		HAVE_EXPAT=1
+		AC_SUBST(HAVE_EXPAT)
+		AC_DEFINE_UNQUOTED(HAVE_EXPAT,$HAVE_EXPAT,
+		[Found a useable expat library])
+		;;
+	esac
+	;;
+   esac
+	
+   CPPFLAGS="$saved_CPPFLAGS"
+   LIBS="$saved_LIBS"
+
+   if test x$expat = xno; then
+      AC_MSG_ERROR([cannot find expat library])
+   fi
+
+dnl ------ Check for PNG ---------------------------------------------------
+
+AC_MSG_CHECKING(for libpng12)
+
+if $PKG_CONFIG --exists libpng12; then
+        AC_MSG_RESULT(yes)
+        PNG_LIBS=`$PKG_CONFIG --libs libpng12`
+        PNG_CFLAGS=`$PKG_CONFIG --cflags libpng12`
+else
+        AC_MSG_RESULT(no)
+        AC_CHECK_LIB([png], [png_create_read_struct],
+                      [have_png="yes"], [have_png="no"])
+
+        if test x$have_png=xyes && test x$have_png_h=xyes; then
+            PNG_LIBS="-lpng -lz"
+        else
+            AC_MSG_ERROR([*** Cannot find libpng12 ****])
+        fi
+fi
+
+
+dnl ------ Debug Build ------------------------------------------------------
+
+if test x$enable_debug = xyes; then
+   AC_DEFINE_UNQUOTED(WANT_DEBUG, 1, [Make a debug (Verbose) Build])
+fi
+
+
+dnl ------ GCC flags --------------------------------------------------------
+
+if test "x$GCC" = "xyes"; then
+        GCC_WARNINGS="-g -Wall -fno-strict-aliasing"
+        FAKEKEY_CFLAGS="$GCC_WARNINGS $FAKEKEY_CFLAGS"
+fi
+
+
+dnl ------ Substitute in found libs, clags to Makefiles etc -----------------
+
+AC_SUBST(FAKEKEY_CFLAGS)
+AC_SUBST(FAKEKEY_LIBS)
+
+AC_SUBST(XFT_CFLAGS)
+AC_SUBST(XFT_LIBS)
+
+AC_SUBST(EXPAT_LIBS)
+AC_SUBST(EXPAT_CFLAGS)
+
+AC_SUBST(PNG_LIBS)
+AC_SUBST(PNG_CFLAGS)
+
+AC_OUTPUT([
+Makefile
+src/Makefile  
+layouts/Makefile
+examples/Makefile
+])
+
+dnl ==========================================================================
+echo "
+                    Matchbox-keyboard $VERSION
+                  =========================
+
+            prefix:                       ${prefix}
+            source code location:         ${srcdir}
+            compiler:                     ${CC} 
+
+            Building with Debug:          ${enable_debug}
+            Building with Cairo:          ${enable_cairo}
+            Building Examples:            ${enable_examples}
+"
\ No newline at end of file

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/.deps/matchbox-keyboard-gtk-embed.Po
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/.deps/matchbox-keyboard-gtk-embed.Po	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/.deps/matchbox-keyboard-gtk-embed.Po	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1 @@
+# dummy

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/Makefile.am
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/Makefile.am	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/Makefile.am	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,8 @@
+PREFIXDIR  = $(prefix)
+
+INCLUDES = -DAPPDIR=\"$(top_builddir)/src\" $(GTK2_CFLAGS)
+
+noinst_PROGRAMS = matchbox-keyboard-gtk-embed
+
+matchbox_keyboard_gtk_embed_SOURCES=matchbox-keyboard-gtk-embed.c
+matchbox_keyboard_gtk_embed_LDADD=$(GTK2_LIBS)
\ No newline at end of file

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/matchbox-keyboard-gtk-embed.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/matchbox-keyboard-gtk-embed.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/examples/matchbox-keyboard-gtk-embed.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,153 @@
+#include <gtk/gtk.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+GtkWidget *m_layout;
+static const char *m_kbd_path = "/usr/local/bin/matchbox-keyboard";
+static const char *m_kbd_str;
+static guint m_kbd_xid;
+static guint m_kbd_pid;
+
+void
+cleanup_children(int s)
+{
+  kill(-getpid(), 15);  /* kill every one in our process group  */
+  exit(0);
+}
+
+void 
+install_signal_handlers(void)
+{
+  signal (SIGCHLD, SIG_IGN);  /* kernel can deal with zombies  */
+  signal (SIGINT, cleanup_children);
+  signal (SIGQUIT, cleanup_children);
+  signal (SIGTERM, cleanup_children);
+}
+
+unsigned long
+launch_keyboard(void)
+{
+  int    i = 0, fd[2];
+  int    stdout_pipe[2];
+  int    stdin_pipe[2];
+  char   buf[256], c;
+  size_t n;
+
+  unsigned long result;
+
+  printf("Launching keyboard from: %s\r\n",m_kbd_path);
+
+  pipe (stdout_pipe);
+  pipe (stdin_pipe);
+
+  switch (fork ())
+    {
+    case 0:
+      {
+	/* Close the Child process' STDOUT */
+	close(1);
+	dup(stdout_pipe[1]);
+	close(stdout_pipe[0]);
+	close(stdout_pipe[1]);
+	
+	execlp ("/bin/sh", "sh", "-c", "matchbox-keyboard --xid", NULL);
+      }
+    case -1:
+      perror ("### Failed to launch 'matchbox-keyboard --xid', is it installed? ### ");
+      exit(1);
+    }
+
+  /* Parent */
+
+  /* Close the write end of STDOUT */
+  close(stdout_pipe[1]);
+
+  /* FIXME: This could be a little safer... */
+  do 
+    {
+      n = read(stdout_pipe[0], &c, 1);
+      if (n == 0 || c == '\n')
+	break;
+      buf[i++] = c;
+    } 
+  while (i < 256);
+
+  buf[i] = '\0';
+  result = atol (buf);
+
+  close(stdout_pipe[0]);
+
+  return result;
+}
+
+
+void widget_destroy( GtkWidget *widget,
+                     gpointer   data )
+{
+   gtk_widget_destroy(widget);
+   gtk_widget_destroy(m_layout);
+   gtk_main_quit ();
+}
+
+
+int main(int argc, char **argv)
+{
+  GtkWidget *window, *button, *textview, *vbox;
+  GtkWidget *socket, *plug, *socket_box;
+
+  unsigned long     kb_xid;
+
+  gtk_init (&argc, &argv);
+
+  install_signal_handlers();
+
+  kb_xid = launch_keyboard();
+
+  if (!kb_xid)
+    {
+      perror ("### 'matchbox-keyboard --xid', failed to return valid window ID. ### ");
+      exit(-1);
+    }
+
+  /* Window */
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
+  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+  g_signal_connect (G_OBJECT (window), "destroy",
+		    G_CALLBACK (widget_destroy), NULL);
+
+  /* Container and textview */
+
+  vbox = gtk_vbox_new(FALSE, 5);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  
+  textview = gtk_text_view_new();
+  gtk_box_pack_start (GTK_BOX(vbox), textview, TRUE, TRUE, 2);
+
+  /* Socket ( XEMBED ) stuff */
+
+  socket_box = gtk_event_box_new ();
+  gtk_widget_show (socket_box);
+  
+  socket = gtk_socket_new ();
+
+  gtk_container_add (GTK_CONTAINER (socket_box), socket);
+  gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(socket_box), TRUE, TRUE, 0);
+  gtk_socket_add_id(GTK_SOCKET(socket), kb_xid); 
+
+  /* FIXME: handle "plug-added" & "plug-removed" signals for socket */
+
+  gtk_widget_show_all (window);
+
+  gtk_main ();
+
+  return 0;
+}
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/Makefile.am
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/Makefile.am	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/Makefile.am	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,6 @@
+keyboardsdir = $(datadir)/matchbox-keyboard
+keyboards_DATA = keyboard.xml keyboard-extended.xml keyboard-dvorak.xml \
+		 keyboard-us.xml keyboard-ru.xml keyboard-fi.xml        \
+                 keyboard-numpad.xml
+
+EXTRA_DIST = $(keyboards_DATA)
\ No newline at end of file

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-dvorak.xml
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-dvorak.xml	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-dvorak.xml	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<keyboard>
+
+<options>
+	<!-- not yet implemented -->
+</options>
+
+<layout id="dvorak keyboard">
+
+<!--
+matchbox-keyboard implementation of the 'common' Dvorak keyboard layout.
+Contributed by Leon Matthews http://www.lost.co.nz/
+-->
+
+<!-- Top Row -->
+<row>
+	<space width="500" extended="true"/>
+	<key fill="true">
+		<default display="Esc" action="escape" />
+	</key>
+	<key>
+		<default display="`" />
+		<shifted display="~" />
+	</key>
+	<key>
+		<default display="1" />
+		<shifted display="!" />
+	</key>
+	<key>
+		<default display="2" />
+		<shifted display='@' />
+		<mod1 display="½" />
+	</key>
+	<key>
+		<default display="3" />
+		<shifted display="#" />
+		<mod1 display="¾" />
+	</key>
+	<key>
+		<default display="4" />
+		<shifted display="$" />
+	</key>
+	<key>
+		<default display="5" />
+		<shifted display="%" />
+	</key>
+	<key>
+		<default display="6" />
+		<shifted display="^" />
+	</key>
+	<key>
+		<default display="7" />
+		<shifted display="&amp;" />
+	</key>
+	<key>
+		<default display="8" />
+		<shifted display="*" />
+	</key>
+	<key>
+		<default display="9" />
+		<shifted display="(" />
+	</key>
+	<key>
+		<default display="0" />
+		<shifted display=")" />
+	</key>
+	<key>
+		<default display="{" />
+		<shifted display="[" />
+	</key>
+	<key>
+		<default display="}" />
+		<shifted display="]" />
+	</key>
+	<key fill="true">
+		<default display="Bksp" action="backspace"/>
+	</key>
+	<space width="500" extended="true"/>
+	<key width="4000"  extended="true">
+		<default display="Home" action="home"/>
+	</key>
+	<key width="4000"  extended="true">
+		<default display="PgUp" action="pageup"/>
+	</key>
+	<space width="500" extended="true"/>
+</row>
+
+<!-- Second Row -->
+<row>
+	<space width="500" extended="true"/>
+	<key fill="true">
+		<default display="Tab" action="tab"/>
+	</key>
+	<key>
+		<default display="'" />
+		<shifted display='"' />
+	</key>
+	<key>
+		<default display="," />
+		<shifted display="&lt;" />
+	</key>
+	<key>
+		<default display="." />
+		<shifted display="&gt;" />
+	</key>
+	<key obey-caps='true'>
+		<default display="p" />
+		<shifted display="P" />
+	</key>
+	<key obey-caps='true'>
+		<default display="y" />
+		<shifted display="Y" />
+	</key>
+	<key obey-caps='true'>
+		<default display="f" />
+		<shifted display="F" />
+	</key>
+	<key obey-caps='true'>
+		<default display="g" />
+		<shifted display="G" />
+	</key>
+	<key obey-caps='true'>
+		<default display="c" />
+		<shifted display="C" />
+	</key>
+	<key obey-caps='true'>
+		<default display="r" />
+		<shifted display="R" />
+	</key>
+	<key obey-caps='true'>
+		<default display="l" />
+		<shifted display="L" />
+	</key>
+	<key>
+		<default display="?" />
+		<shifted display="/" />
+	</key>
+	<key>
+		<default display="=" />
+		<shifted display="+" />
+	</key>
+	<key fill="true">
+		<default display="\" />
+		<shifted display="|" />
+	</key>
+	<space width="500" extended="true"/>
+	<key width="4000"  extended="true">
+		<default display="End" action="end"/>
+	</key>
+	<key width="4000"  extended="true">
+		<default display="PgDn" action="pagedown"/>
+	</key>
+	<space width="500" extended="true"/>
+</row>
+
+<!-- Third row -->
+<row>
+	<space width="500" extended="true"/>
+	<key fill="true">
+		<default display="Caps" action="modifier:caps"/>
+	</key>
+	<key obey-caps='true'>
+		<default display="a" />
+		<shifted display="A" />
+	</key>
+	<key obey-caps='true'>
+		<default display="o" />
+		<shifted display="O" />
+	</key>
+	<key obey-caps='true'>
+		<mod1 display="ë" />
+		<default    display="e" />
+		<shifted display="E" />
+	</key>
+	<key obey-caps='true'>
+		<default display="u" />
+		<shifted display="U" />
+	</key>
+	<key obey-caps='true'>
+		<default display="i" />
+		<shifted display="I" />
+	</key>
+	<key obey-caps='true'>
+		<default display="d" />
+		<shifted display="D" />
+	</key>
+	<key obey-caps='true'>
+		<default display="h" />
+		<shifted display="H" />
+	</key>
+	<key obey-caps='true'>
+		<default display="t" />
+		<shifted display="T" />
+	</key>
+	<key obey-caps='true'>
+		<default display="n" />
+		<shifted display="N" />
+	</key>
+	<key obey-caps='true'>
+		<default display="s" />
+		<shifted display="S" />
+	</key>
+	<key>
+		<default display="-" />
+		<shifted display="_" />
+	</key>
+	<key fill="true">
+		<default display="Ret" action="return"/>
+	</key>
+	<space width="500" extended="true"/>
+	<space width="4000" extended="true" />
+	<space width="4000" extended="true" />
+	<space width="500" extended="true"/>
+</row>
+
+<!-- Fourth Row -->
+<row>
+	<space width="500" extended="true"/>
+	<key fill="true">
+		<default display="Shift" action="modifier:shift"/>
+	</key>
+	<key>
+		<default display=";" />
+		<shifted display=":" />
+	</key>
+	<key obey-caps='true'>
+		<default display="q" />
+		<shifted display="Q" />
+	</key>
+	<key obey-caps='true'>
+		<default display="j" />
+		<shifted display="J" />
+	</key>
+	<key obey-caps='true'>
+		<default display="k" />
+		<shifted display="K" />
+	</key>
+	<key obey-caps='true'>
+		<default display="x" />
+		<shifted display="X" />
+	</key>
+	<key obey-caps='true'>
+		<default display="b" />
+		<shifted display="B" />
+	</key>
+	<key obey-caps='true'>
+		<default display="m" />
+		<shifted display="M" />
+	</key>
+	<key obey-caps='true'>
+		<default display="w" />
+		<shifted display="W" />
+	</key>
+	<key obey-caps='true'>
+		<default display="v" />
+		<shifted display="V" />
+	</key>
+	<key obey-caps='true'>
+		<default display="z" />
+		<shifted display="Z" />
+	</key>
+	<key fill="true">
+		<default display="Shift" action="modifier:shift"/>
+	</key>
+	<space width="500" extended="true"/>
+	<space width="4000"  extended="true" />
+	<space width="4000"  extended="true" />
+	<space width="500" extended="true"/>
+</row>
+
+<!-- Bottom Row -->
+<row>
+	<space width="500" extended="true"/>
+	<key>
+		<default display="äëö" action="modifier:mod1"/>
+	</key>
+	<key fill="true">
+		<default display="Ctrl" action="modifier:ctrl"/>
+	</key>
+	<key>
+		<default display="Alt" action="modifier:alt"/>
+	</key>
+	<key width="12000">
+		<default display=" " action="space" />
+	</key>
+	<key>
+		<default display="^" action="up" />
+	</key>
+	<key>
+		<default display="V" action="down" />
+	</key>
+	<key>
+		<default display="&lt;" action="left" />
+	</key>
+	<key>
+		<default display="&gt;" action="right" />
+	</key>
+	<space width="500" extended="true"/>
+	<space width="4000"  extended="true" />
+	<space width="4000"  extended="true" />
+	<space width="500" extended="true"/>
+</row>
+
+</layout>
+
+</keyboard>

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-extended.xml
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-extended.xml	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-extended.xml	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,348 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<keyboard>
+
+<options>
+<!--
+   <font prefered-size=''>
+   <size fixed='100x100'>
+   <padding>
+-->
+</options>
+
+<layout id="name">
+
+<!--
+  <row>
+     <key>
+	  <default display="ヂ" />                
+    </key>
+    <key>
+	  <default display="Ӫ" />                
+    </key>
+    <key width="1500">
+	  <default display="Ω" />                
+    </key>
+    <space width="1500" />
+    <key fill="true">
+	  <default display="⠿" />                
+    </key>
+  </row>
+-->
+
+  <row>
+    <key fill="true">
+	  <default display="Esc" action="escape" />
+    </key>
+    <key>
+	  <default display="`" />
+    </key>
+    <key>
+	  <default display="1" />                
+	  <shifted display="!" />
+    </key>
+    <key>
+	  <default display="2" />                
+	  <shifted display='"' />
+    </key>
+    <key>
+	  <default display="3" />
+	  <shifted display="" />                
+    </key>
+    <key>
+	  <default display="4" />
+	  <shifted display="$" />                
+    </key>
+    <key>
+	  <default display="5" />
+	  <shifted display="%" />                
+    </key>
+    <key>
+	  <default display="6" />
+	  <shifted display="^" />                
+    </key>
+    <key>
+	  <default display="7" />
+	  <shifted display="&amp;" />                
+    </key>
+    <key>
+	  <default display="8" />
+	  <shifted display="*" />                
+    </key>
+    <key>
+	  <default display="9" />
+	  <shifted display="(" />                
+    </key>
+    <key>
+	  <default display="0" />
+	  <shifted display=")" />                
+    </key>
+    <key>
+	  <default display="-" />
+	  <shifted display="_" />                
+    </key>
+    <key>
+	  <default display="=" />
+	  <shifted display="+" />                
+    </key>
+
+    <key fill="true">
+	  <default display="Bksp" action="backspace"/>
+    </key>
+
+    <space width="500" />
+
+    <key width="4000">
+	  <default display="Home" />
+    </key>
+    <key width="4000">
+	  <default display="PgUp" />
+    </key>
+
+
+  </row>
+
+  <row>
+    <key fill="true">
+	  <default display="Tab" action="tab"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="q" />                
+	  <shifted display="Q" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="w" />                
+	  <shifted display="W" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="e" />                
+	  <shifted display="E" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="r" />                
+	  <shifted display="R" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="t" />                
+	  <shifted display="T" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="y" />                
+	  <shifted display="Y" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="u" />                
+	  <shifted display="U" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="i" />                
+	  <shifted display="I" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="o" />                
+	  <shifted display="O" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="p" />                
+	  <shifted display="P" />
+    </key>
+    <key>
+	  <default display="{" />                
+	  <shifted display="[" />
+    </key>
+    <key>
+	  <default display="}" />                
+	  <shifted display="]" />
+    </key>
+    <key fill="true">
+	  <default display="\" />                
+	  <shifted display="|" />
+    </key>
+
+    <space width="500" />
+
+    <key width="4000">
+	  <default display="End" />
+    </key>
+    <key width="4000">
+	  <default display="PgDn" />
+    </key>
+
+
+  </row>
+  <row>
+    <key fill="true">
+	  <default display="Caps" action="modifier:caps"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="a" />                
+	  <shifted display="A" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="s" />                
+	  <shifted display="S" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="d" />                
+	  <shifted display="D" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="f" />                
+	  <shifted display="F" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="g" />                
+	  <shifted display="G" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="h" />                
+	  <shifted display="H" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="j" />                
+	  <shifted display="J" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="k" />                
+	  <shifted display="K" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="l" />                
+	  <shifted display="L" />
+    </key>
+    <key>
+	  <default display=":" />                
+	  <shifted display=";" />
+    </key>
+    <key>
+	  <default display="#" />                
+	  <shifted display="~" />
+    </key>
+    <key fill="true">
+	  <default display="Ret" action="return"/>
+    </key>
+
+    <space width="500" />
+
+    <key width="4000">
+	  <default display="Del" />
+    </key>
+    <key width="4000">
+	  <default display="XXX" />
+    </key>
+
+
+  </row>
+  <row>
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="z" />                
+	  <shifted display="Z" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="x" />                
+	  <shifted display="X" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="c" />                
+	  <shifted display="C" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="v" />                
+	  <shifted display="V" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="b" />                
+	  <shifted display="B" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="n" />                
+	  <shifted display="N" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="m" />                
+	  <shifted display="M" />
+    </key>
+
+    <key>
+	  <default display="." />                
+	  <shifted display="&lt;" />
+    </key>
+    <key>
+	  <default display="." />                
+	  <shifted display="&gt;" />
+    </key>
+    <key>
+	  <default display="?" />                
+	  <shifted display="/" />
+    </key>
+
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <space width="500" />
+
+    <key width="4000">
+	  <default display="Inst" />
+    </key>
+    <key width="4000">
+	  <default display="Pase" />
+    </key>
+
+
+ </row>
+  <row>
+    <key>
+	  <default display="aeo" action="modifier:mod1"/>                
+    </key>
+
+    <key>
+	  <default display="Ctrl" action="modifier:ctrl"/>                
+    </key>
+
+    <key>
+	  <default display="Alt" action="modifier:alt"/>                
+    </key>
+
+
+    <key width="14000">
+	  <default display=" " action="space" />                
+    </key>
+
+    <key>
+	  <default display="@" />                
+	  <shifted display="'" />
+    </key>
+
+    <key>
+	  <default display="^" action="up" />                
+    </key>
+    <key>
+	  <default display="^" action="down" />                
+    </key>
+    <key>
+	  <default display="&lt;" action="left" />                
+    </key>
+    <key>
+	  <default display="&gt;" action="right" />                
+    </key>
+
+    <space width="8500" />
+
+</row>
+
+</layout>
+
+
+</keyboard>

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-fi.xml
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-fi.xml	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-fi.xml	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,376 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<keyboard>
+
+<options>
+<!-- not yet implemented -->
+</options>
+
+<layout id="defualt keyboard">
+
+<!--
+  <row>
+     <key>
+	  <default display="ヂ" />
+    </key>
+    <key>
+	  <default display="Óª" />
+    </key>
+    <key width="1500">
+	  <default display="Ω" />
+    </key>
+    <space width="1500" />
+    <key fill="true">
+	  <default display="â ¿" />
+    </key>
+  </row>
+-->
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Esc" action="escape" />
+    </key>
+    <key>
+	  <default display="§" />
+	  <shifted display="½" />
+    </key>
+    <key>
+	  <default display="1" />
+	  <shifted display="!" />
+    </key>
+    <key>
+	  <default display="2" />
+	  <shifted display='"' />
+	  <mod1 display='@' />
+    </key>
+    <key>
+	  <default display="3" />
+	  <shifted display="#" />
+	  <mod1 display="£" />
+    </key>
+    <key>
+	  <default display="4" />
+	  <default display="¤" />
+	  <mod1 display="$" />
+    </key>
+    <key>
+	  <default display="5" />
+	  <shifted display="%" />
+    </key>
+    <key>
+	  <default display="6" />
+	  <shifted display="&amp;" />
+    </key>
+    <key>
+	  <default display="7" />
+	  <shifted display="/" />
+	  <mod1 display='{' />
+    </key>
+    <key>
+	  <default display="8" />
+	  <shifted display="(" />
+	  <mod1 display='[' />
+    </key>
+    <key>
+	  <default display="9" />
+	  <shifted display=")" />
+	  <mod1 display=']' />
+    </key>
+    <key>
+	  <default display="0" />
+	  <shifted display="=" />
+	  <mod1 display='}' />
+    </key>
+    <key>
+	  <default display="+" />
+	  <shifted display="?" />
+	  <mod1 display="\" />
+    </key>
+    <key>
+	  <default display="'" />
+	  <shifted display="*" />
+    </key>
+
+    <key fill="true">
+	  <default display="Bksp" action="backspace"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="Home" action="home"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgUp" action="pageup"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Tab" action="tab"/>
+    </key>
+    <key obey-caps='true'>
+	  <default display="q" />
+	  <shifted display="Q" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="w" />
+	  <shifted display="W" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="e" />
+	  <shifted display="E" />
+	  <mod1 display="€" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="r" />
+	  <shifted display="R" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="t" />
+	  <shifted display="T" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="y" />
+	  <shifted display="Y" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="u" />
+	  <shifted display="U" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="i" />
+	  <shifted display="I" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="o" />
+	  <shifted display="O" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="p" />
+	  <shifted display="P" />
+    </key>
+    <key>
+	  <default display="å" />
+	  <shifted display="Å" />
+    </key>
+    <key>
+	  <default display="~" />
+	  <shifted display="^" />
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="End" action="end"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgDn" action="pagedown"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Caps" action="modifier:caps"/>
+    </key>
+    <key obey-caps='true'>
+	  <default display="a" />
+	  <shifted display="A" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="s" />
+	  <shifted display="S" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="d" />
+	  <shifted display="D" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="f" />
+	  <shifted display="F" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="g" />
+	  <shifted display="G" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="h" />
+	  <shifted display="H" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="j" />
+	  <shifted display="J" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="k" />
+	  <shifted display="K" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="l" />
+	  <shifted display="L" />
+    </key>
+    <key>
+	  <default display="Ö" />
+	  <shifted display="ö" />
+    </key>
+    <key>
+	  <default display="ä" />
+	  <shifted display="Ä" />
+    </key>
+    <key fill="true">
+	  <default display="Ret" action="return"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>
+    </key>
+
+    <key>
+	  <default display="&lt;" />
+	  <shifted display="&gt;" />
+	  <mod1 display="|" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="z" />
+	  <shifted display="Z" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="x" />
+	  <shifted display="X" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="c" />
+	  <shifted display="C" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="v" />
+	  <shifted display="V" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="b" />
+	  <shifted display="B" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="n" />
+	  <shifted display="N" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="m" />
+	  <shifted display="M" />
+	  <mod1 display="µ" />
+    </key>
+
+    <key>
+	  <default display="," />
+	  <shifted display=":" />
+    </key>
+    <key>
+	  <default display="." />
+	  <shifted display=":" />
+    </key>
+    <key>
+	  <default display="-" />
+	  <shifted display="_" />
+    </key>
+
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+
+ </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+
+    <key fill="true">
+	  <default display="Ctrl" action="modifier:ctrl"/>
+    </key>
+
+    <key>
+	  <default display="Alt" action="modifier:alt"/>
+    </key>
+
+
+    <key width="12000">
+	  <default display=" " action="space" />
+    </key>
+
+    <key>
+	  <default display="ALT GR" action="modifier:mod1"/>
+    </key>
+
+
+    <key>
+	  <default display="UP" action="up" />
+    </key>
+    <key>
+	  <default display="DOWN" action="down" />
+    </key>
+    <key>
+	  <default display="LEFT" action="left" />
+    </key>
+    <key>
+	  <default display="RIGHT" action="right" />
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+</row>
+
+</layout>
+
+
+</keyboard>
\ No newline at end of file

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-numpad.xml
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-numpad.xml	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-numpad.xml	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<keyboard>
+
+<options>
+<!-- not yet implemented -->
+</options>
+
+<layout id="defualt keyboard">
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key>
+	  <default display="9" />                
+    </key>
+    <key>
+	  <default display="8" />                
+    </key>
+    <key>
+	  <default display="7" />
+    </key>
+
+  </row>
+  <row>
+    <space width="500" extended="true"/>
+    <key>
+	  <default display="6" />
+    </key>
+    <key>
+	  <default display="5" />
+    </key>
+    <key>
+	  <default display="4" />
+    </key>
+  </row>
+  <row>
+    <space width="500" extended="true"/>
+    <key>
+	  <default display="3" />
+    </key>
+
+    <key>
+	  <default display="2" />
+    </key>
+    <key>
+	  <default display="1" />
+    </key>
+  </row>
+  <row>
+    <space width="500" extended="true"/>
+    <key>
+	  <default display="0" />
+    </key>
+  </row>
+
+</layout>
+
+
+</keyboard>
\ No newline at end of file

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-ru.xml
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-ru.xml	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-ru.xml	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,355 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<keyboard>
+
+<options>
+  
+</options>
+
+<layout id="RUS">
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Esc" action="escape" />
+    </key>
+    <key>
+	  <default display="`" />
+    </key>
+    <key>
+	  <default display="1" />                
+	  <shifted display="!" />
+    </key>
+    <key>
+	  <default display="2" />                
+	  <shifted display='"' />
+<!-- " -->
+
+          <mod1    display="½" />
+    </key>
+    <key>
+	  <default display="3" />
+	  <shifted display="£" />
+          <mod1    display="¾" />               
+    </key>
+    <key>
+	  <default display="4" />
+	  <shifted display="$" />                
+    </key>
+    <key>
+	  <default display="5" />
+	  <shifted display="%" />                
+    </key>
+    <key>
+	  <default display="6" />
+	  <shifted display="^" />                
+    </key>
+    <key>
+	  <default display="7" />
+	  <shifted display="&amp;" />                
+    </key>
+    <key>
+	  <default display="8" />
+	  <shifted display="*" />                
+    </key>
+    <key>
+	  <default display="9" />
+	  <shifted display="(" />                
+    </key>
+    <key>
+	  <default display="0" />
+	  <shifted display=")" />                
+    </key>
+    <key>
+	  <default display="-" />
+	  <shifted display="_" />                
+    </key>
+    <key>
+	  <default display="=" />
+	  <shifted display="+" />                
+    </key>
+
+    <key fill="true">
+	  <default display="Bksp" action="backspace"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="Home" action="home"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgUp" action="pageup"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Tab" action="tab"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="й" />                
+	  <shifted display="Й" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="ц" />                
+	  <shifted display="Ц" />
+    </key>
+    <key obey-caps='true'>
+	  <default    display="у" />                
+	  <shifted display="У" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="к" />                
+	  <shifted display="К" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="е" />                
+	  <shifted display="Е" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="н" />                
+	  <shifted display="Н" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="г" />                
+	  <shifted display="Г" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="ш" />                
+	  <shifted display="Ш" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="щ" />                
+	  <shifted display="Щ" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="з" />                
+	  <shifted display="З" />
+    </key>
+    <key>
+	  <default display="х" />                
+	  <shifted display="Х" />
+    </key>
+    <key>
+	  <default display="ъ" />                
+	  <shifted display="Ъ" />
+    </key>
+    <key fill="true">
+	  <default display="\" />                
+	  <shifted display="|" />
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="End" action="end"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgDn" action="pagedown"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Caps" action="modifier:caps"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="ф" />                
+	  <shifted display="Ф" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="ы" />                
+	  <shifted display="Ы" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="в" />                
+	  <shifted display="В" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="а" />                
+	  <shifted display="А" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="п" />                
+	  <shifted display="П" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="р" />                
+	  <shifted display="Р" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="о" />                
+	  <shifted display="О" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="л" />                
+	  <shifted display="Л" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="д" />                
+	  <shifted display="Д" />
+    </key>
+    <key>
+	  <default display="ж" />                
+	  <shifted display="Ж" />
+    </key>
+    <key>
+	  <default display="э" />                
+	  <shifted display="Э" />
+    </key>
+    <key fill="true">
+	  <default display="Ret" action="return"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="я" />                
+	  <shifted display="Я" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="ч" />                
+	  <shifted display="Ч" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="с" />                
+	  <shifted display="С" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="м" />                
+	  <shifted display="М" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="и" />                
+	  <shifted display="И" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="т" />                
+	  <shifted display="Т" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="ь" />                
+	  <shifted display="Ь" />
+    </key>
+
+    <key>
+	  <default display="б" />                
+	  <shifted display="Б" />
+    </key>
+    <key>
+	  <default display="ю" />                
+	  <shifted display="Ю" />
+    </key>
+    <key>
+	  <default display="?" />                
+	  <shifted display="/" />
+    </key>
+
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+
+ </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key>
+	  <default display="äëö" action="modifier:mod1"/>                
+    </key>
+    <key>
+	  <default display="EN" action="modifier:mod2"/>                
+    </key>
+
+    <key fill="true">
+	  <default display="Ctrl" action="modifier:ctrl"/>                
+    </key>
+
+    <key>
+	  <default display="Alt" action="modifier:alt"/>                
+    </key>
+
+
+    <key width="12000">
+	  <default display=" " action="space" />                
+    </key>
+
+    <key>
+	  <default display="@" />                
+	  <shifted display="'" />
+    </key>
+
+    <key>
+	  <default display="^" action="up" />                
+    </key>
+    <key>
+	  <default display="V" action="down" />                
+    </key>
+    <key>
+	  <default display="&lt;" action="left" />                
+    </key>
+    <key>
+	  <default display="&gt;" action="right" />                
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+</row>
+
+</layout>
+
+</keyboard>
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-us.xml
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-us.xml	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard-us.xml	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<keyboard>
+
+<!--
+
+ US keyboard layout by Matt Reimer <mreimer at vpop.net>
+
+-->
+
+<options>
+<!-- not yet implemented -->
+</options>
+
+<layout id="default keyboard">
+
+<!--
+  <row>
+     <key>
+	  <default display="ヂ" />                
+    </key>
+    <key>
+	  <default display="Ӫ" />                
+    </key>
+    <key width="1500">
+	  <default display="Ω" />                
+    </key>
+    <space width="1500" />
+    <key fill="true">
+	  <default display="⠿" />                
+    </key>
+  </row>
+-->
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Esc" action="escape" />
+    </key>
+    <key>
+	  <default display="`" />
+	  <shifted display="~" />
+    </key>
+    <key>
+	  <default display="1" />                
+	  <shifted display="!" />
+    </key>
+    <key>
+	  <default display="2" />                
+	  <shifted display='@' />
+          <mod1    display="½" />
+    </key>
+    <key>
+	  <default display="3" />
+	  <shifted display="#" />
+          <mod1    display="¾" />               
+    </key>
+    <key>
+	  <default display="4" />
+	  <shifted display="$" />                
+    </key>
+    <key>
+	  <default display="5" />
+	  <shifted display="%" />                
+    </key>
+    <key>
+	  <default display="6" />
+	  <shifted display="^" />                
+    </key>
+    <key>
+	  <default display="7" />
+	  <shifted display="&amp;" />                
+    </key>
+    <key>
+	  <default display="8" />
+	  <shifted display="*" />                
+    </key>
+    <key>
+	  <default display="9" />
+	  <shifted display="(" />                
+    </key>
+    <key>
+	  <default display="0" />
+	  <shifted display=")" />                
+    </key>
+    <key>
+	  <default display="-" />
+	  <shifted display="_" />                
+    </key>
+    <key>
+	  <default display="=" />
+	  <shifted display="+" />                
+    </key>
+
+    <key fill="true">
+	  <default display="Bksp" action="backspace"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="Home" action="home"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgUp" action="pageup"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Tab" action="tab"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="q" />                
+	  <shifted display="Q" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="w" />                
+	  <shifted display="W" />
+    </key>
+    <key obey-caps='true'>
+	  <mod1 display="ë" />
+	  <default    display="e" />                
+	  <shifted display="E" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="r" />                
+	  <shifted display="R" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="t" />                
+	  <shifted display="T" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="y" />                
+	  <shifted display="Y" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="u" />                
+	  <shifted display="U" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="i" />                
+	  <shifted display="I" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="o" />                
+	  <shifted display="O" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="p" />                
+	  <shifted display="P" />
+    </key>
+    <key>
+	  <default display="[" />                
+	  <shifted display="{" />
+    </key>
+    <key>
+	  <default display="]" />                
+	  <shifted display="}" />
+    </key>
+    <key fill="true">
+	  <default display="\" />                
+	  <shifted display="|" />
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="End" action="end"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgDn" action="pagedown"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Caps" action="modifier:caps"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="a" />                
+	  <shifted display="A" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="s" />                
+	  <shifted display="S" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="d" />                
+	  <shifted display="D" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="f" />                
+	  <shifted display="F" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="g" />                
+	  <shifted display="G" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="h" />                
+	  <shifted display="H" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="j" />                
+	  <shifted display="J" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="k" />                
+	  <shifted display="K" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="l" />                
+	  <shifted display="L" />
+    </key>
+    <key>
+	  <default display=";" />                
+	  <shifted display=":" />
+    </key>
+    <key>
+	  <default display="'" />                
+	  <shifted display='"' />
+    </key>
+    <key fill="true">
+	  <default display="Ret" action="return"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="z" />                
+	  <shifted display="Z" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="x" />                
+	  <shifted display="X" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="c" />                
+	  <shifted display="C" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="v" />                
+	  <shifted display="V" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="b" />                
+	  <shifted display="B" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="n" />                
+	  <shifted display="N" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="m" />                
+	  <shifted display="M" />
+    </key>
+
+    <key>
+	  <default display="," />                
+	  <shifted display="&lt;" />
+    </key>
+    <key>
+	  <default display="." />                
+	  <shifted display="&gt;" />
+    </key>
+    <key>
+	  <default display="/" />                
+	  <shifted display="?" />
+    </key>
+
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+
+ </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key>
+	  <default display="äëö" action="modifier:mod1"/>                
+    </key>
+
+    <key fill="true">
+	  <default display="Ctrl" action="modifier:ctrl"/>                
+    </key>
+
+    <key>
+	  <default display="Alt" action="modifier:alt"/>                
+    </key>
+
+
+    <key width="12000">
+	  <default display=" " action="space" />                
+    </key>
+
+    <key>
+	  <default display="^" action="up" />                
+    </key>
+    <key>
+	  <default display="V" action="down" />                
+    </key>
+    <key>
+	  <default display="&lt;" action="left" />                
+    </key>
+    <key>
+	  <default display="&gt;" action="right" />                
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+</row>
+
+</layout>
+
+
+</keyboard>

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard.xml
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard.xml	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/layouts/keyboard.xml	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<keyboard>
+
+<options>
+<!-- not yet implemented -->
+</options>
+
+<layout id="defualt keyboard">
+
+<!--
+  <row>
+     <key>
+	  <default display="ヂ" />                
+    </key>
+    <key>
+	  <default display="Ӫ" />                
+    </key>
+    <key width="1500">
+	  <default display="Ω" />                
+    </key>
+    <space width="1500" />
+    <key fill="true">
+	  <default display="⠿" />                
+    </key>
+  </row>
+-->
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Esc" action="escape" />
+    </key>
+<!--
+    <key>
+      <default display="image:/usr/share/pixmaps/sync_icon.png" action="a"/>
+    </key>  
+-->
+    <key>
+	  <default display="`" />
+    </key>
+    <key>
+	  <default display="1" />                
+	  <shifted display="!" />
+    </key>
+    <key>
+	  <default display="2" />                
+	  <shifted display='"' />
+          <mod1    display="½" />
+    </key>
+    <key>
+	  <default display="3" />
+	  <shifted display="£" />
+          <mod1    display="¾" />               
+    </key>
+    <key>
+	  <default display="4" />
+	  <shifted display="$" />                
+    </key>
+    <key>
+	  <default display="5" />
+	  <shifted display="%" />                
+    </key>
+    <key>
+	  <default display="6" />
+	  <shifted display="^" />                
+    </key>
+    <key>
+	  <default display="7" />
+	  <shifted display="&amp;" />                
+    </key>
+    <key>
+	  <default display="8" />
+	  <shifted display="*" />                
+    </key>
+    <key>
+	  <default display="9" />
+	  <shifted display="(" />                
+    </key>
+    <key>
+	  <default display="0" />
+	  <shifted display=")" />                
+    </key>
+    <key>
+	  <default display="-" />
+	  <shifted display="_" />                
+    </key>
+    <key>
+	  <default display="=" />
+	  <shifted display="+" />                
+    </key>
+
+    <key fill="true">
+	  <default display="Bksp" action="backspace"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="Home" action="home"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgUp" action="pageup"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Tab" action="tab"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="q" />                
+	  <shifted display="Q" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="w" />                
+	  <shifted display="W" />
+    </key>
+    <key obey-caps='true'>
+	  <mod1 display="ë" />
+	  <default    display="e" />                
+	  <shifted display="E" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="r" />                
+	  <shifted display="R" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="t" />                
+	  <shifted display="T" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="y" />                
+	  <shifted display="Y" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="u" />                
+	  <shifted display="U" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="i" />                
+	  <shifted display="I" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="o" />                
+	  <shifted display="O" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="p" />                
+	  <shifted display="P" />
+    </key>
+    <key>
+	  <default display="{" />                
+	  <shifted display="[" />
+    </key>
+    <key>
+	  <default display="}" />                
+	  <shifted display="]" />
+    </key>
+    <key fill="true">
+	  <default display="\" />                
+	  <shifted display="|" />
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <key width="4000"  extended="true">
+	  <default display="End" action="end"/>
+    </key>
+    <key width="4000"  extended="true">
+	  <default display="PgDn" action="pagedown"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Caps" action="modifier:caps"/>                
+    </key>
+    <key obey-caps='true'>
+	  <default display="a" />                
+	  <shifted display="A" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="s" />                
+	  <shifted display="S" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="d" />                
+	  <shifted display="D" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="f" />                
+	  <shifted display="F" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="g" />                
+	  <shifted display="G" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="h" />                
+	  <shifted display="H" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="j" />                
+	  <shifted display="J" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="k" />                
+	  <shifted display="K" />
+    </key>
+    <key obey-caps='true'>
+	  <default display="l" />                
+	  <shifted display="L" />
+    </key>
+    <key>
+	  <default display=";" />                
+	  <shifted display=":" />
+    </key>
+    <key>
+	  <default display="#" />                
+	  <shifted display="~" />
+    </key>
+    <key fill="true">
+	  <default display="Ret" action="return"/>
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+  </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="z" />                
+	  <shifted display="Z" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="x" />                
+	  <shifted display="X" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="c" />                
+	  <shifted display="C" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="v" />                
+	  <shifted display="V" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="b" />                
+	  <shifted display="B" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="n" />                
+	  <shifted display="N" />
+    </key>
+
+    <key obey-caps='true'>
+	  <default display="m" />                
+	  <shifted display="M" />
+    </key>
+
+    <key>
+	  <default display="," />                
+	  <shifted display="&lt;" />
+    </key>
+    <key>
+	  <default display="." />                
+	  <shifted display="&gt;" />
+    </key>
+    <key>
+	  <default display="/" />                
+	  <shifted display="?" />
+    </key>
+
+
+    <key fill="true">
+	  <default display="Shift" action="modifier:shift"/>                
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+
+
+ </row>
+  <row>
+
+    <space width="500" extended="true"/>
+
+    <key>
+	  <default display="äëö" action="modifier:mod1"/>                
+    </key>
+
+    <key fill="true">
+	  <default display="Ctrl" action="modifier:ctrl"/>                
+    </key>
+
+    <key>
+	  <default display="Alt" action="modifier:alt"/>                
+    </key>
+
+
+    <key width="12000">
+	  <default display=" " action="space" />                
+    </key>
+
+    <key>
+	  <default display="@" />                
+	  <shifted display="'" />
+    </key>
+
+    <key>
+	  <default display="^" action="up" />                
+    </key>
+    <key>
+	  <default display="V" action="down" />                
+    </key>
+    <key>
+	  <default display="&lt;" action="left" />                
+    </key>
+    <key>
+	  <default display="&gt;" action="right" />                
+    </key>
+
+    <space width="500" extended="true"/>
+
+    <space width="4000"  extended="true" />
+
+    <space width="4000"  extended="true" />
+
+    <space width="500" extended="true"/>
+
+</row>
+
+</layout>
+
+
+</keyboard>

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/matchbox-keyboard.desktop
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/matchbox-keyboard.desktop	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/matchbox-keyboard.desktop	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Name=Keyboard
+Comment=Virtual Keyboard
+Exec=matchbox-keyboard
+Type=Application
+Icon=matchbox-keyboard.png
+Categories=Panel;Utility;MB
+X-MB-INPUT-MECHANSIM=True

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/matchbox-keyboard.png
===================================================================
(Binary files differ)


Property changes on: trunk/src/target/OM-2007/applications/openmoko-keyboard/matchbox-keyboard.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/Makefile.am
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/Makefile.am	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/Makefile.am	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,33 @@
+PREFIXDIR  = $(prefix)
+PKGDATADIR = $(datadir)/matchbox-keyboard
+DATADIR    = $(datadir)
+
+if WANT_CAIRO
+CAIRO_BACKEND_C =                                                     \
+	matchbox-keyboard-ui-cairo-backend.c                          \
+        matchbox-keyboard-ui-cairo-backend.h
+else
+XFT_BACKEND_C =                                                       \
+	matchbox-keyboard-ui-xft-backend.c                            \
+        matchbox-keyboard-ui-xft-backend.h
+endif
+
+INCLUDES = -DDATADIR=\"$(DATADIR)\" -DPKGDATADIR=\"$(PKGDATADIR)\" -DPREFIX=\"$(PREFIXDIR)\" $(FAKEKEY_CFLAGS) $(XFT_CFLAGS) $(EXPAT_CFLAGS) $(CAIRO_CFLAGS) $(PNG_CFLAGS)
+
+bin_PROGRAMS = matchbox-keyboard
+
+matchbox_keyboard_LDADD = $(FAKEKEY_LIBS) $(XFT_LIBS) $(EXPAT_LIBS) $(CAIRO_LIBS) $(PNG_LIBS)
+
+matchbox_keyboard_SOURCES =                                          \
+	matchbox-keyboard.c matchbox-keyboard.h                      \
+	matchbox-keyboard-image.c                                    \
+	matchbox-keyboard-layout.c                                   \
+        matchbox-keyboard-row.c                                      \
+        matchbox-keyboard-key.c                                      \
+        matchbox-keyboard-ui.c                                       \
+        matchbox-keyboard-xembed.c                                   \
+        config-parser.c                                              \
+	util-list.c                                                  \
+        util.c                                                       \
+	$(XFT_BACKEND_C) $(CAIRO_BACKEND_C)
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/config-parser.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/config-parser.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/config-parser.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,611 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+/* 
+    <keyboard>
+
+    <options>
+       <font prefered-size=''>
+       <size fixed='100x100'>
+       <padding>
+    </options>
+
+    <layout id="name">
+      <row>
+        <key id="optional-id" obey-caps='true|false'
+	     width="1000"   // 1/1000's of a unit key size
+	     fill="true"    // Set width to available space
+	     
+             >
+	  <default
+	     display="a"                
+	     display="image:" 
+	     action="utf8char"     // optional, action defaults to this    
+	     action="string"       // from lookup below
+	     action="modifier:Shift|Alt|ctrl|mod1|mod2|mod3|caps"
+	     action="xkeysym:XK_BLAH"
+	  <shifted 
+	     ...... >
+	  <mod1
+	     ...... >
+	     
+	/>
+        <key ... />
+	<key ... />
+	<space width="1000"
+      </row>
+    </layout>
+
+
+    </keyboard>
+*/
+
+struct _keysymlookup
+{
+  KeySym keysym;   char *name;  
+} 
+MBKeyboardKeysymLookup[] =
+{
+ { XK_BackSpace,   "backspace" },
+ { XK_Tab,	   "tab"       },
+ { XK_Linefeed,    "linefeed"  },
+ { XK_Clear,       "clear"     },	
+ { XK_Return,      "return"    },
+ { XK_Pause,       "pause" },	
+ { XK_Scroll_Lock, "scrolllock" },	
+ { XK_Sys_Req,     "sysreq" },
+ { XK_Escape,      "escape" },	
+ { XK_Delete,      "delete" },	
+ { XK_Home,        "home" },
+ { XK_Left,        "left" },
+ { XK_Up,          "up"   },
+ { XK_Right,       "right" },
+ { XK_Down,        "down"  },
+ { XK_Prior,       "prior" },		
+ { XK_Page_Up,     "pageup" },	
+ { XK_Next,        "next"   },
+ { XK_Page_Down,   "pagedown" },
+ { XK_End,         "end" },
+ { XK_Begin,	   "begin" },
+ { XK_space,        "space" },
+ { XK_F1,          "f1" },
+ { XK_F2,          "f2" },
+ { XK_F3,          "f3" },
+ { XK_F4,          "f4" },
+ { XK_F5,          "f5" },
+ { XK_F6,          "f6" },
+ { XK_F7,          "f7" },
+ { XK_F8,          "f8" },
+ { XK_F9,          "f9" },
+ { XK_F10,         "f10" },
+ { XK_F11,         "f11" },
+ { XK_F12,         "f12" }
+};
+
+struct _modlookup
+{
+  char *name; MBKeyboardKeyModType type;
+}
+ModLookup[] =
+{
+  { "shift",   MBKeyboardKeyModShift },
+  { "alt",     MBKeyboardKeyModAlt },
+  { "ctrl",    MBKeyboardKeyModControl },
+  { "control", MBKeyboardKeyModControl },
+  { "mod1",    MBKeyboardKeyModMod1 },
+  { "mod2",    MBKeyboardKeyModMod2 },
+  { "mod3",    MBKeyboardKeyModMod3 },
+  { "caps",    MBKeyboardKeyModCaps }
+};
+
+typedef struct MBKeyboardConfigState
+{
+  MBKeyboard       *keyboard;
+  MBKeyboardLayout *current_layout;
+  MBKeyboardRow    *current_row;
+  MBKeyboardKey    *current_key;
+  Bool              error;
+  char             *error_msg;
+  int               error_lineno;
+  XML_Parser        parser;
+}
+MBKeyboardConfigState;
+
+void 
+set_error(MBKeyboardConfigState *state, char *msg)
+{
+  state->error = True;
+  state->error_lineno = XML_GetCurrentLineNumber(state->parser);
+  state->error_msg = msg;
+}
+
+KeySym
+config_str_to_keysym(const char* str)
+{
+  int i;
+
+  DBG("checking %s", str);
+
+  for (i=0; i<sizeof(MBKeyboardKeysymLookup)/sizeof(struct _keysymlookup); i++)
+    if (streq(str, MBKeyboardKeysymLookup[i].name))
+      return MBKeyboardKeysymLookup[i].keysym;
+
+  DBG("didnt find it %s", str);
+
+  return 0;
+}
+
+MBKeyboardKeyModType
+config_str_to_modtype(const char* str)
+{
+  int i;
+
+  for (i=0; i<sizeof(ModLookup)/sizeof(struct _modlookup); i++)
+    {
+      DBG("checking '%s' vs '%s'", str, ModLookup[i].name);
+      if (streq(str, ModLookup[i].name))
+	return ModLookup[i].type;
+    }
+
+  return 0;
+}
+
+
+static char* 
+config_load_file(MBKeyboard *kbd, char *variant_in)
+{
+  struct stat    stat_info;
+  FILE*          fp;
+  char          *result;
+  char          *country  = NULL;  
+  char          *variant  = NULL;
+  char          *lang     = NULL;
+  int            n = 0, i = 0;
+  char           path[1024]; 	/* XXX MAXPATHLEN */
+
+  /* keyboard[-country][-variant].xml */
+
+  /* This is an overide mainly for people developing keyboard layouts  */
+
+  if (getenv("MB_KBD_CONFIG"))
+    {
+      snprintf(path, 1024, "%s", getenv("MB_KBD_CONFIG"));
+
+      DBG("checking %s\n", path);
+
+      if (util_file_readable(path))
+	goto load;
+
+      return NULL;
+    }
+
+  lang = getenv("MB_KBD_LANG");
+
+  if (lang == NULL)
+    lang = getenv("LANG");
+
+  if (lang)
+    {
+      n = strlen(lang) + 2;
+
+      country = alloca(n);
+
+      snprintf(country, n, "-%s", lang);
+
+      /* strip anything after first '.' */
+      while(country[i] != '\0')
+	if (country[i] == '.')
+	  country[i] = '\0';
+	else
+	  i++;
+    }
+
+  if (variant_in)
+    {
+      n = strlen(variant_in) + 2;
+      variant = alloca(n);
+      snprintf(variant, n, "-%s", variant_in);
+    }
+
+  if (getenv("HOME"))
+    {
+      snprintf(path, 1024, "%s/.matchbox/keyboard.xml", getenv("HOME"));
+
+      DBG("checking %s\n", path);
+
+      if (util_file_readable(path))
+	goto load;
+    }
+
+  /* Hmmm :/ */
+ 
+  snprintf(path, 1024, PKGDATADIR "/keyboard%s%s.xml",
+	   country == NULL ? "" : country,
+	   variant == NULL ? "" : variant);
+
+  DBG("checking %s\n", path);
+  
+  if (util_file_readable(path))
+    goto load;
+
+  snprintf(path, 1024, PKGDATADIR "/keyboard%s.xml",
+	   variant == NULL ? "" : variant);
+
+  DBG("checking %s\n", path);
+
+  if (util_file_readable(path))
+    goto load;
+
+  snprintf(path, 1024, PKGDATADIR "/keyboard%s.xml",
+	   country == NULL ? "" : country);
+
+  DBG("checking %s\n", path);
+
+  if (util_file_readable(path))
+    goto load;
+
+  snprintf(path, 1024, PKGDATADIR "/keyboard.xml");
+  
+  DBG("checking %s\n", path);
+
+  if (!util_file_readable(path))
+    return NULL;
+
+ load:
+
+  if (stat(path, &stat_info)) 
+    return NULL;
+
+  if ((fp = fopen(path, "rb")) == NULL) 
+    return NULL;
+
+  DBG("loading %s\n", path);
+
+  kbd->config_file = strdup(path);
+
+  result = malloc(stat_info.st_size + 1);
+
+  n = fread(result, 1, stat_info.st_size, fp);
+
+  if (n >= 0) result[n] = '\0';
+  
+  fclose(fp);
+
+  return result;
+}
+
+static const char *
+attr_get_val (char *key, const char **attr)
+{
+  int i = 0;
+  
+  while (attr[i] != NULL)
+    {
+      if (!strcmp(attr[i], key))
+	return attr[i+1];
+      i += 2;
+    }
+  
+  return NULL;
+}
+
+
+static void
+config_handle_key_subtag(MBKeyboardConfigState *state,
+			 const char            *tag,
+			 const char           **attr)
+{
+  MBKeyboardKeyStateType keystate;
+  const char            *val;
+  KeySym                 found_keysym;
+
+  /* TODO: Fix below with a lookup table 
+   */
+  if (streq(tag, "normal") || streq(tag, "default"))
+    {
+      keystate = MBKeyboardKeyStateNormal;
+    }
+  else if (streq(tag, "shifted"))
+    {
+      keystate = MBKeyboardKeyStateShifted;
+    }
+  else if (streq(tag, "mod1"))
+    {
+      keystate = MBKeyboardKeyStateMod1;
+    }
+  else if (streq(tag, "mod2"))
+    {
+      keystate = MBKeyboardKeyStateMod2;
+    }
+  else if (streq(tag, "mod3"))
+    {
+      keystate = MBKeyboardKeyStateMod3;
+    }
+  else
+    {
+      set_error(state, "Unknown key subtag");
+      return;
+    }
+
+  if ((val = attr_get_val("display", attr)) == NULL)
+    {
+      set_error(state, "Attribute 'display' is required");
+      return;
+    }
+
+  if (!strncmp(val, "image:", 6))
+    {
+      MBKeyboardImage *img;
+
+
+      if (val[6] != '/')
+	{
+	  /* Relative, rather than absolute path, try pkddatadir and home */
+	  char buf[512];
+	  snprintf(buf, 512, "%s/%s", PKGDATADIR, &val[6]);
+
+	  if (!util_file_readable(buf))
+	    snprintf(buf, 512, "%s/.matchbox/%s", getenv("HOME"), &val[6]);
+
+	  img = mb_kbd_image_new (state->keyboard, buf);
+	}
+      else
+	img = mb_kbd_image_new (state->keyboard, &val[6]);
+
+      if (!img)
+	{
+	  fprintf(stderr, "matchbox-keyboard: Failed to load '%s'\n", &val[6]);
+	  state->error = True;
+	  return;
+	}
+      mb_kbd_key_set_image_face(state->current_key, keystate, img);
+    }
+  else
+    {
+      mb_kbd_key_set_glyph_face(state->current_key, keystate, 
+				attr_get_val("display", attr));
+    }
+
+  if ((val = attr_get_val("action", attr)) != NULL)
+    {
+      /*
+	     action="utf8char"     // optional, action defulats to this    
+	     action="modifier:Shift|Alt|ctrl|mod1|mod2|mod3|caps"
+	     action="xkeysym:XK_BLAH"
+	     action="control:">    // return etc - not needed use lookup 
+      */
+
+      if (!strncmp(val, "modifier:", 9))
+	{
+	  MBKeyboardKeyModType found_type;
+
+	  DBG("checking '%s'", &val[9]);
+
+	  found_type = config_str_to_modtype(&val[9]);
+
+	  if (found_type)
+	    {
+	      mb_kbd_key_set_modifer_action(state->current_key,
+					    keystate,
+					    found_type);
+	    }
+	  else
+	    {
+              set_error(state, "Unknown modifier");
+	      return;
+	    }
+	  
+	}
+      else if (!strncmp(val, "xkeysym:", 8))
+	{
+	  DBG("Checking %s\n", &val[8]);
+
+	  found_keysym = XStringToKeysym(&val[8]);
+
+	  if (found_keysym)
+	    {
+	      mb_kbd_key_set_keysym_action(state->current_key, 
+					   keystate,
+					   found_keysym);
+	    }
+	  else 
+	    {
+	      /* Should this error really be terminal */
+              set_error(state, "Unknown keysym");
+	      return;
+	    }
+	}
+      else
+	{
+	  /* Its just 'regular' key  */
+
+	  if (strlen(val) > 1  	/* match backspace, return etc */
+	      && ((found_keysym  = config_str_to_keysym(val)) != 0))
+	    {
+	      mb_kbd_key_set_keysym_action(state->current_key, 
+					   keystate,
+					   found_keysym);
+	    }
+	  else
+	    {
+	      /* XXX We should actually check its a single UTF8 Char here */
+	      mb_kbd_key_set_char_action(state->current_key, 
+					 keystate, val);
+	    }
+	}
+    }
+  else /* fallback to reusing whats displayed  */
+    {
+
+      /* display could be an image in which case we should throw an error 
+       * or summin.
+      */
+
+      mb_kbd_key_set_char_action(state->current_key, 
+				 keystate, 
+				 attr_get_val("display", attr));
+    }
+
+}
+
+static void
+config_handle_layout_tag(MBKeyboardConfigState *state, const char **attr)
+{
+  const char            *val;
+
+  if ((val = attr_get_val("id", attr)) == NULL)
+    {
+      set_error(state, "Attribute 'id' is required");
+      return;
+    }
+
+  state->current_layout = mb_kbd_layout_new(state->keyboard, val);
+
+  mb_kbd_add_layout(state->keyboard, state->current_layout);
+}
+
+static void
+config_handle_row_tag(MBKeyboardConfigState *state, const char **attr)
+{
+  state->current_row = mb_kbd_row_new(state->keyboard);
+  mb_kbd_layout_append_row(state->current_layout, state->current_row);
+}
+
+static void
+config_handle_key_tag(MBKeyboardConfigState *state, const char **attr)
+{
+  const char *val;
+  DBG("got key");
+
+  state->current_key = mb_kbd_key_new(state->keyboard);
+
+  if ((val = attr_get_val("obey-caps", attr)) != NULL)
+    {
+      if (strcaseeq(val, "true"))
+	mb_kbd_key_set_obey_caps(state->current_key, True);
+    }
+
+  if ((val = attr_get_val("extended", attr)) != NULL)
+    {
+      if (strcaseeq(val, "true"))
+	mb_kbd_key_set_extended(state->current_key, True);
+    }
+
+  if ((val = attr_get_val("width", attr)) != NULL)
+    {
+      if (atoi(val) > 0)
+	mb_kbd_key_set_req_uwidth(state->current_key, atoi(val));
+    }
+
+  if ((val = attr_get_val("fill", attr)) != NULL)
+    {
+      if (strcaseeq(val, "true"))
+	mb_kbd_key_set_fill(state->current_key, True);
+    }
+
+  mb_kbd_row_append_key(state->current_row, state->current_key);
+}
+
+static void 
+config_xml_start_cb(void *data, const char *tag, const char **attr)
+{
+  MBKeyboardConfigState *state = (MBKeyboardConfigState *)data;
+
+  if (streq(tag, "layout"))
+    {
+      config_handle_layout_tag(state, attr);
+    }
+  else if (streq(tag, "row"))
+    {
+      config_handle_row_tag(state, attr);
+    }
+  else if (streq(tag, "key"))
+    {
+      config_handle_key_tag(state, attr);
+    }
+  else  if (streq(tag, "space"))
+    {
+      config_handle_key_tag(state, attr);
+      mb_kbd_key_set_blank(state->current_key, True);
+    }
+  else if (streq(tag, "normal") 
+	   || streq(tag, "default")
+	   || streq(tag, "shifted")
+	   || streq(tag, "mod1")
+	   || streq(tag, "mod2")
+	   || streq(tag, "mod3"))
+    {
+      config_handle_key_subtag(state, tag, attr);
+    }
+
+  if (state->error)
+    {
+      fprintf(stderr, "matchbox-keyboard:%s:%d: %s\n", state->keyboard->config_file, 
+                                              state->error_lineno, state->error_msg);
+      util_fatal_error("Error parsing\n");
+    }
+}
+
+
+int
+mb_kbd_config_load(MBKeyboard *kbd, char *variant)
+{
+  char                  *data;
+  XML_Parser             p;
+  MBKeyboardConfigState *state;
+
+  if ((data = config_load_file(kbd, variant)) == NULL)
+    util_fatal_error("Couldn't find a keyboard config file\n");
+
+  p = XML_ParserCreate(NULL);
+
+  if (!p) 
+    util_fatal_error("Couldn't allocate memory for XML parser\n");
+
+  if (variant && !strstr(kbd->config_file, variant))
+    fprintf(stderr, 
+	    "matchbox-keyboard: *Warning* Unable to locate variant: %s\n"
+	    "                   falling back to %s\n",
+	    variant, kbd->config_file);
+
+  state = util_malloc0(sizeof(MBKeyboardConfigState));
+
+  state->keyboard = kbd;
+  state->parser = p;
+
+  XML_SetElementHandler(p, config_xml_start_cb, NULL);
+
+  /* XML_SetCharacterDataHandler(p, chars); */
+
+  XML_SetUserData(p, (void *)state);
+
+  if (! XML_Parse(p, data, strlen(data), 1)) {
+    fprintf(stderr, 
+	    "matchbox-keyboard:%s:%d: XML Parse error:%s\n",
+	    kbd->config_file,
+	    XML_GetCurrentLineNumber(p),
+	    XML_ErrorString(XML_GetErrorCode(p)));
+    util_fatal_error("XML Parse failed.\n");
+  }
+
+  return 1;
+}
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-defs.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-defs.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-defs.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1 @@
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-image.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-image.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-image.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,242 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+struct MBKeyboardImage
+{
+  MBKeyboard            *kbd;
+  int                    width, height;
+  Pixmap                 xdraw;
+  Picture                xpic;
+};
+
+static unsigned char* 
+png_file_load (const char *file, 
+	       int        *width, 
+	       int        *height)
+{
+  FILE *fd;
+  unsigned char *data;
+  unsigned char header[8];
+  int  bit_depth, color_type;
+
+  png_uint_32  png_width, png_height, i, rowbytes;
+  png_structp png_ptr;
+  png_infop info_ptr;
+  png_bytep *row_pointers;
+
+  if ((fd = fopen( file, "rb" )) == NULL) return NULL;
+
+  fread( header, 1, 8, fd );
+  if ( ! png_check_sig( header, 8 ) ) 
+    {
+      fclose(fd);
+      return NULL;
+    }
+
+  png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+  if ( ! png_ptr ) {
+    fclose(fd);
+    return NULL;
+  }
+
+  info_ptr = png_create_info_struct(png_ptr);
+  if ( ! info_ptr ) {
+    png_destroy_read_struct( &png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+    fclose(fd);
+    return NULL;
+  }
+
+  if ( setjmp( png_ptr->jmpbuf ) ) {
+    png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
+    fclose(fd);
+    return NULL;
+  }
+
+  png_init_io( png_ptr, fd );
+  png_set_sig_bytes( png_ptr, 8);
+  png_read_info( png_ptr, info_ptr);
+  png_get_IHDR( png_ptr, info_ptr, &png_width, &png_height, &bit_depth, 
+		&color_type, NULL, NULL, NULL);
+  *width = (int) png_width;
+  *height = (int) png_height;
+
+  if ( bit_depth == 16 )
+    png_set_strip_16(png_ptr);
+
+  if (bit_depth < 8)
+    png_set_packing(png_ptr);
+
+  if (( color_type == PNG_COLOR_TYPE_GRAY ) ||
+            ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ))
+    png_set_gray_to_rgb(png_ptr);
+
+  /* Add alpha */
+  if (( color_type == PNG_COLOR_TYPE_GRAY ) ||
+      ( color_type == PNG_COLOR_TYPE_RGB ))
+    png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); /* req 1.2.7 */
+
+  if (( color_type == PNG_COLOR_TYPE_PALETTE )||
+      ( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS )))
+    png_set_expand(png_ptr);
+
+  png_read_update_info( png_ptr, info_ptr);
+
+  /* allocate space for data and row pointers */
+  rowbytes = png_get_rowbytes( png_ptr, info_ptr);
+  data = (unsigned char *) malloc( (rowbytes*(*height + 1)));
+  row_pointers = (png_bytep *) malloc( (*height)*sizeof(png_bytep));
+
+  if (( data == NULL )||( row_pointers == NULL )) {
+    png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
+    free(data);
+    free(row_pointers);
+    return NULL;
+  }
+
+  for ( i = 0;  i < *height; i++ )
+    row_pointers[i] = data + i*rowbytes;
+
+  png_read_image( png_ptr, row_pointers );
+  png_read_end( png_ptr, NULL);
+
+  free(row_pointers);
+  png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
+  fclose(fd);
+
+  return data;
+}
+
+MBKeyboardImage*
+mb_kbd_image_new (MBKeyboard *kbd, const char *filename)
+{
+  MBKeyboardUI            *ui;
+  MBKeyboardImage         *img;
+  unsigned char           *data, *p;
+  int                      width, height, x, y;
+  XRenderPictFormat       *ren_fmt;
+  XRenderPictureAttributes ren_attr;
+  GC                       gc;
+  XImage                  *ximg;
+
+  ui = kbd->ui;
+  
+  data = png_file_load (filename, &width, &height);
+
+  if (data == NULL || width == 0 || height == 0)
+    {
+      if (data) free(data);
+      return NULL;
+    }
+
+  img = util_malloc0(sizeof(MBKeyboardImage));
+
+  img->width  = width;
+  img->height = height;
+
+  ren_fmt = XRenderFindStandardFormat(mb_kbd_ui_x_display(ui), 
+				      PictStandardARGB32);
+  img->xdraw = XCreatePixmap(mb_kbd_ui_x_display(ui), 
+			     mb_kbd_ui_x_win_root(ui),
+			     width, height, 
+			     ren_fmt->depth);
+
+  XSync(mb_kbd_ui_x_display(ui), False);
+
+  ren_attr.dither          = True;
+  ren_attr.component_alpha = True;
+  ren_attr.repeat          = False;
+
+  img->xpic = XRenderCreatePicture(mb_kbd_ui_x_display(ui), 
+				   img->xdraw, 
+				   ren_fmt, 
+				   CPRepeat|CPDither|CPComponentAlpha, 
+				   &ren_attr);
+
+  gc = XCreateGC(mb_kbd_ui_x_display(ui), img->xdraw, 0, NULL);
+
+  ximg = XCreateImage(mb_kbd_ui_x_display(ui), 
+		      DefaultVisual(mb_kbd_ui_x_display(ui), 
+				    mb_kbd_ui_x_screen(ui)), 
+		      ren_fmt->depth, 
+		      ZPixmap, 
+		      0, 
+		      NULL, 
+		      width, 
+		      height, 
+		      32, 
+		      0);
+  
+  ximg->data = malloc(ximg->bytes_per_line * ximg->height);
+
+  p = data;
+
+  for (y = 0; y < height; y++)
+    for (x = 0; x < width; x++)
+      {
+	unsigned char a, r, g, b;
+	r = *p++; g = *p++; b = *p++; a = *p++; 
+	r = (r * (a + 1)) / 256; /* premult */
+	g = (g * (a + 1)) / 256;
+	b = (b * (a + 1)) / 256;
+	XPutPixel(ximg, x, y, (a << 24) | (r << 16) | (g << 8) | b);
+      }
+
+  XPutImage(mb_kbd_ui_x_display(ui), 
+	    img->xdraw, 
+	    gc, 
+	    ximg, 
+	    0, 0, 0, 0, width, height);
+
+  free(ximg->data);
+  ximg->data = NULL;
+  XDestroyImage(ximg);
+  XFreeGC (mb_kbd_ui_x_display(ui), gc);
+
+  free(data);
+
+  return img;
+}
+
+int
+mb_kbd_image_width (MBKeyboardImage *img)
+{
+  return img->width;
+}
+
+int
+mb_kbd_image_height (MBKeyboardImage *img)
+{
+  return img->height;
+}
+
+Picture
+mb_kbd_image_render_picture (MBKeyboardImage *img)
+{
+  return img->xpic;
+}
+
+void
+mb_kbd_image_destroy (MBKeyboardImage *img)
+{
+  /* ... */
+}
+
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-key.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-key.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-key.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,655 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+#define MBKB_N_KEY_STATES 5
+
+typedef struct MBKeyboardKeyFace
+{
+  MBKeyboardKeyFaceType  type;
+
+  union
+  {
+    MBKeyboardImage *image;
+    char            *str;
+  } u;
+} 
+MBKeyboardKeyFace;
+
+typedef struct MBKeyboardKeyAction
+{
+  MBKeyboardKeyActionType  type;
+  union 
+  {
+    char                  *glyph;
+    KeySym                 keysym;
+    MBKeyboardKeyModType   type;
+  } u;
+} 
+MBKeyboardKeyAction;
+
+
+/* A key can have 5 different 'states' */
+
+typedef struct MBKeyboardKeyState
+{
+  MBKeyboardKeyAction action;
+  MBKeyboardKeyFace   face;
+
+} MBKeyboardKeyState;
+
+struct MBKeyboardKey
+{
+  MBKeyboard            *kbd;
+  MBKeyboardKeyState    *states[N_MBKeyboardKeyStateTypes];
+  MBKeyboardRow         *row;
+
+  int                    alloc_x, alloc_y, alloc_width, alloc_height;
+
+  int                    extra_width_pad;  /* via win resizes */
+  int                    extra_height_pad;
+
+  boolean                obeys_caps;
+  boolean                fill;	     /* width fills avialble space */
+  int                    req_uwidth; /* unit width in 1/1000's */
+  boolean                is_blank;   /* 'blank' keys are spacers */
+  boolean                extended;   /* only show in landscape */
+
+  MBKeyboardStateType    sets_kbdstate; /* needed */
+};
+
+static void
+_mb_kbd_key_init_state(MBKeyboardKey           *key,
+		       MBKeyboardKeyStateType   state)
+{
+  key->states[state] = util_malloc0(sizeof(MBKeyboardKeyState));
+}
+
+MBKeyboardKey*
+mb_kbd_key_new(MBKeyboard *kbd)
+{
+  MBKeyboardKey *key = NULL;
+  int            i;
+
+  key      = util_malloc0(sizeof(MBKeyboardKey));
+  key->kbd = kbd;
+
+  for (i=0; i<N_MBKeyboardKeyStateTypes; i++)
+    key->states[i] = NULL;
+
+  return key;
+}
+
+void
+mb_kbd_key_set_obey_caps(MBKeyboardKey  *key, boolean obey)
+{
+  key->obeys_caps = obey;
+}
+
+boolean
+mb_kbd_key_get_obey_caps(MBKeyboardKey  *key)
+{
+  return key->obeys_caps;
+}
+
+void
+mb_kbd_key_set_req_uwidth(MBKeyboardKey  *key, int uwidth)
+{
+  key->req_uwidth = uwidth;
+}
+
+int
+mb_kbd_key_get_req_uwidth(MBKeyboardKey  *key)
+{
+  return key->req_uwidth;
+}
+
+void
+mb_kbd_key_set_fill(MBKeyboardKey  *key, boolean fill)
+{
+  MARK();
+  key->fill = fill;
+}
+
+boolean
+mb_kbd_key_get_fill(MBKeyboardKey  *key)
+{
+  return key->fill;
+}
+
+void
+mb_kbd_key_set_blank(MBKeyboardKey  *key, boolean blank)
+{
+  key->is_blank = blank;
+}
+
+boolean
+mb_kbd_key_is_blank(MBKeyboardKey  *key)
+{
+  return key->is_blank;
+}
+
+
+void
+mb_kbd_key_set_geometry(MBKeyboardKey  *key,
+			int x,
+			int y,
+			int width,
+			int height)
+{
+  if (x != -1)
+    key->alloc_x = x;
+
+  if (y != -1)
+    key->alloc_y = y;
+
+  if (width != -1)
+    key->alloc_width = width;
+
+  if (height != -1)
+    key->alloc_height = height;
+}
+
+int 
+mb_kbd_key_abs_x(MBKeyboardKey *key) 
+{ 
+  return mb_kbd_row_x(key->row) + key->alloc_x;
+}
+
+int 
+mb_kbd_key_abs_y(MBKeyboardKey *key) 
+{ 
+  return mb_kbd_row_y(key->row) + key->alloc_y;
+}
+
+int 
+mb_kbd_key_x(MBKeyboardKey *key) 
+{ 
+  return key->alloc_x;
+}
+
+int 
+mb_kbd_key_y(MBKeyboardKey *key) 
+{ 
+  return key->alloc_y;
+}
+
+int 
+mb_kbd_key_width(MBKeyboardKey *key) 
+{ 
+  return key->alloc_width;
+}
+
+int 
+mb_kbd_key_height(MBKeyboardKey *key) 
+{ 
+  return key->alloc_height;
+}
+
+void
+mb_kbd_key_set_extra_width_pad(MBKeyboardKey  *key, int pad)
+{
+  key->alloc_width -= key->extra_width_pad;
+  key->extra_width_pad = pad;
+  key->alloc_width += key->extra_width_pad;
+}
+
+void
+mb_kbd_key_set_extra_height_pad(MBKeyboardKey  *key, int pad)
+{
+  key->alloc_height -= key->extra_height_pad;
+  key->extra_height_pad = pad;
+  key->alloc_height += key->extra_height_pad;
+}
+
+int
+mb_kbd_key_get_extra_height_pad(MBKeyboardKey  *key)
+{
+  return key->extra_height_pad;
+}
+
+int
+mb_kbd_key_get_extra_width_pad(MBKeyboardKey  *key)
+{
+  return key->extra_width_pad;
+}
+
+void
+mb_kbd_key_set_extended(MBKeyboardKey  *key, boolean extend)
+{
+  key->extended = extend;
+}
+
+boolean
+mb_kbd_key_get_extended(MBKeyboardKey  *key)
+{
+  return key->extended;
+}
+
+
+/* URG Nasty - some stuf should be public-ish */
+void 
+mb_kbd_key_set_row(MBKeyboardKey *key, MBKeyboardRow *row) 
+{ 
+  key->row = row;
+}
+
+
+boolean
+mb_kdb_key_has_state(MBKeyboardKey           *key,
+		     MBKeyboardKeyStateType   state)
+{
+  return (key->states[state] != NULL);
+}
+
+void
+mb_kbd_key_set_glyph_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state,
+			  const char              *glyph)
+{
+  if (key->states[state] == NULL)
+    _mb_kbd_key_init_state(key, state);
+
+  key->states[state]->face.type    = MBKeyboardKeyFaceGlyph;
+  key->states[state]->face.u.str   = strdup(glyph);
+}
+
+const char*
+mb_kbd_key_get_glyph_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state)
+{
+  if (key->states[state] 
+      && key->states[state]->face.type == MBKeyboardKeyFaceGlyph)
+    {
+      return key->states[state]->face.u.str;
+    }
+  return NULL;
+}
+
+void
+mb_kbd_key_set_image_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state,
+			  MBKeyboardImage         *image)
+{
+
+  if (key->states[state] == NULL)
+    _mb_kbd_key_init_state(key, state);
+
+  key->states[state]->face.type    = MBKeyboardKeyFaceImage;
+  key->states[state]->face.u.image = image;
+}
+
+MBKeyboardImage*
+mb_kbd_key_get_image_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state)
+{
+  if (key->states[state] 
+      && key->states[state]->face.type == MBKeyboardKeyFaceImage)
+    {
+      return key->states[state]->face.u.image;
+    }
+  return NULL;
+}
+
+void
+mb_kbd_key_set_char_action(MBKeyboardKey           *key,
+			   MBKeyboardKeyStateType   state,
+			   const char              *glyphs)
+{
+  if (key->states[state] == NULL)
+    _mb_kbd_key_init_state(key, state);
+  
+  key->states[state]->action.type = MBKeyboardKeyActionGlyph;
+  key->states[state]->action.u.glyph = strdup(glyphs);
+}
+
+const char*
+mb_kbd_key_get_char_action(MBKeyboardKey           *key,
+			   MBKeyboardKeyStateType   state)
+{
+  if (key->states[state] 
+      && key->states[state]->action.type == MBKeyboardKeyActionGlyph)
+    return key->states[state]->action.u.glyph;
+
+  return NULL;
+}
+
+void
+mb_kbd_key_set_keysym_action(MBKeyboardKey           *key,
+			     MBKeyboardKeyStateType   state,
+			     KeySym                   keysym)
+{
+  if (key->states[state] == NULL)
+    _mb_kbd_key_init_state(key, state);
+
+  key->states[state]->action.type = MBKeyboardKeyActionXKeySym;
+  key->states[state]->action.u.keysym = keysym;
+}
+
+KeySym
+mb_kbd_key_get_keysym_action(MBKeyboardKey           *key,
+			     MBKeyboardKeyStateType   state)
+{
+  if (key->states[state] 
+      && key->states[state]->action.type == MBKeyboardKeyActionXKeySym)
+    return key->states[state]->action.u.keysym;
+
+  return None;
+}
+
+
+void
+mb_kbd_key_set_modifer_action(MBKeyboardKey          *key,
+			      MBKeyboardKeyStateType  state,
+			      MBKeyboardKeyModType    type)
+{
+  if (key->states[state] == NULL)
+    _mb_kbd_key_init_state(key, state);
+
+  key->states[state]->action.type = MBKeyboardKeyActionModifier;
+  key->states[state]->action.u.type   = type;
+}
+
+MBKeyboardKeyModType 
+mb_kbd_key_get_modifer_action(MBKeyboardKey          *key,
+			      MBKeyboardKeyStateType  state)
+{
+  if (key->states[state] 
+      && key->states[state]->action.type == MBKeyboardKeyActionModifier)
+    return key->states[state]->action.u.type;
+
+  return 0;
+}
+
+
+MBKeyboardKeyFaceType
+mb_kbd_key_get_face_type(MBKeyboardKey           *key,
+			 MBKeyboardKeyStateType   state)
+{
+  if (key->states[state]) 
+    return key->states[state]->face.type;
+
+  return 0;
+}
+
+
+MBKeyboardKeyActionType
+mb_kbd_key_get_action_type(MBKeyboardKey           *key,
+			   MBKeyboardKeyStateType   state)
+{
+  if (key->states[state]) 
+    return key->states[state]->action.type;
+
+  return 0;
+}
+
+
+void
+mb_kbd_key_press(MBKeyboardKey *key)
+{
+  /* XXX what about state handling XXX */
+  MBKeyboardKeyStateType state;
+  int                    flags = 0;
+  boolean                queue_full_kbd_redraw = False;
+
+  if (mb_kbd_key_is_blank(key))
+    return;
+
+  state = mb_kbd_keys_current_state(key->kbd);
+
+  if (mb_kbd_has_state(key->kbd, MBKeyboardStateCaps)
+      && mb_kbd_key_get_obey_caps(key))
+    state = MBKeyboardKeyStateShifted;
+
+  /* XXX below fakekey mods probably better in ui */
+
+  if (state == MBKeyboardKeyStateShifted)
+    flags |= FAKEKEYMOD_SHIFT; 	/* does fakekey actually need this ? */
+
+  if (mb_kbd_has_state(key->kbd, MBKeyboardStateControl))
+    flags |= FAKEKEYMOD_CONTROL;
+
+  if (mb_kbd_has_state(key->kbd, MBKeyboardStateAlt))
+    flags |= FAKEKEYMOD_ALT;
+
+  if (!mb_kdb_key_has_state(key, state))
+    {
+      if (state == MBKeyboardKeyStateNormal)
+	return;  /* keys should at least have a normal state */
+      else
+        state = MBKeyboardKeyStateNormal;
+    }
+
+  switch (mb_kbd_key_get_action_type(key, state))
+    {
+    case MBKeyboardKeyActionGlyph:
+      {
+	const char *key_char;
+
+	if ((key_char = mb_kbd_key_get_char_action(key, state)) != NULL)
+	  {
+	    mb_kbd_ui_send_press(key->kbd->ui, key_char, flags);
+	    mb_kbd_set_held_key(key->kbd, key);
+	  }
+	break;
+
+
+      }
+    case MBKeyboardKeyActionXKeySym:
+      {
+	KeySym ks;
+	if ((ks = mb_kbd_key_get_keysym_action(key, state)) != None)
+	  {
+	    mb_kbd_ui_send_keysym_press(key->kbd->ui, ks, flags);
+	    mb_kbd_set_held_key(key->kbd, key);
+	  }
+	break;
+      }
+    case MBKeyboardKeyActionModifier:
+      {
+	
+	switch ( mb_kbd_key_get_modifer_action(key, state) )
+	  {
+	  case MBKeyboardKeyModShift:
+	    mb_kbd_toggle_state(key->kbd, MBKeyboardStateShifted);
+	    queue_full_kbd_redraw = True;
+	    break;
+	  case MBKeyboardKeyModMod1:
+	    mb_kbd_toggle_state(key->kbd, MBKeyboardStateMod1);
+	    queue_full_kbd_redraw = True;
+	    break;
+	  case MBKeyboardKeyModMod2:
+	    mb_kbd_toggle_state(key->kbd, MBKeyboardStateMod2);
+	    queue_full_kbd_redraw = True;
+	    break;
+	  case MBKeyboardKeyModMod3:
+	    mb_kbd_toggle_state(key->kbd, MBKeyboardStateMod3);
+	    queue_full_kbd_redraw = True;
+	    break;
+	  case MBKeyboardKeyModCaps:
+	    mb_kbd_toggle_state(key->kbd, MBKeyboardStateCaps);
+	    queue_full_kbd_redraw = True;
+	    break;
+          case MBKeyboardKeyModControl:
+	    mb_kbd_toggle_state(key->kbd, MBKeyboardStateControl);
+	    break;
+	  case MBKeyboardKeyModAlt:
+	    mb_kbd_toggle_state(key->kbd, MBKeyboardStateAlt);
+	    break;
+	  default:
+	    DBG("unknown modifier action");
+	    break;
+	  }
+
+	/* we dont actually have to send a key sym here - but should we ? 
+         *
+         * Also we dont set a held key, as we've changed the keyboard 
+         * state instead.
+	*/
+	break;
+      }
+
+    default:
+      break;
+    }  
+  
+  if (queue_full_kbd_redraw)
+    mb_kbd_redraw(key->kbd);
+  else
+    mb_kbd_redraw_key(key->kbd, key);
+}
+
+boolean 
+mb_kbd_key_is_held(MBKeyboard *kbd, MBKeyboardKey *key)
+{
+  MBKeyboardKeyStateType  state;
+
+  if (mb_kbd_get_held_key(key->kbd) ==  key)
+    return True;
+
+  /* XXX below should probably go into own func */
+
+  state = mb_kbd_keys_current_state(kbd); 
+
+  if (!mb_kdb_key_has_state(key, state))
+    {
+      if (state == MBKeyboardKeyStateNormal)
+	return False;  /* keys should at least have a normal state */
+      else
+        state = MBKeyboardKeyStateNormal;
+    }
+
+  if (mb_kbd_key_get_action_type(key, state) == MBKeyboardKeyActionModifier)
+    {
+	switch ( mb_kbd_key_get_modifer_action(key, state) )
+	  {
+	  case MBKeyboardKeyModShift:
+	    if (mb_kbd_has_state(kbd, MBKeyboardStateShifted))
+	      return True;
+	    break;
+	  case MBKeyboardKeyModMod1:
+	    if (mb_kbd_has_state(kbd, MBKeyboardStateMod1))
+	      return True;
+	    break;
+	  case MBKeyboardKeyModMod2:
+	    if (mb_kbd_has_state(kbd, MBKeyboardStateMod2))
+	      return True;
+	    break;
+	  case MBKeyboardKeyModMod3:
+	    if (mb_kbd_has_state(kbd, MBKeyboardStateMod3))
+	      return True;
+	    break;
+	  case MBKeyboardKeyModCaps:
+	    if (mb_kbd_has_state(kbd, MBKeyboardStateCaps))
+	      return True;
+	    break;
+          case MBKeyboardKeyModControl:
+	    if (mb_kbd_has_state(kbd, MBKeyboardStateControl))
+	      return True;
+	    break;
+	  case MBKeyboardKeyModAlt:
+	    if (mb_kbd_has_state(kbd, MBKeyboardStateAlt))
+	      return True;
+	    break;
+	  default:
+	    DBG("unknown modifier action");
+	    break;
+	  }
+    }
+
+  return False;
+}
+
+void
+mb_kbd_key_release(MBKeyboard *kbd)
+{
+  MBKeyboardKey *key = mb_kbd_get_held_key(kbd);
+
+  mb_kbd_set_held_key(kbd, NULL);
+
+  if (key)
+    {
+      boolean queue_full_kbd_redraw = False;
+
+      if (mb_kbd_key_get_action_type(key, MBKeyboardKeyStateNormal) != MBKeyboardKeyActionModifier)
+	{
+	  if (mb_kbd_has_any_state(kbd))
+	    {
+	      mb_kbd_remove_state(kbd, (MBKeyboardStateShifted|
+					MBKeyboardStateMod1|
+					MBKeyboardStateMod2|
+					MBKeyboardStateMod3|
+					MBKeyboardStateControl|
+					MBKeyboardStateAlt));
+	      queue_full_kbd_redraw = True;
+	    }
+	}
+
+      if (queue_full_kbd_redraw)
+	mb_kbd_redraw(key->kbd);
+      else
+	mb_kbd_redraw_key(key->kbd, key);
+
+      mb_kbd_ui_send_release(kbd->ui);
+    }
+}
+
+void
+mb_kbd_key_dump_key(MBKeyboardKey *key)
+{
+  int i;
+
+  char state_lookup[][32] =
+    {
+      /* MBKeyboardKeyStateNormal  */ "Normal",
+      /* MBKeyboardKeyStateShifted */ "Shifted" ,
+      /* MBKeyboardKeyStateMod1,    */ "Mod1" ,
+      /* MBKeyboardKeyStateMod2,    */ "Mod2" ,
+      /* MBKeyboardKeyStateMod3,    */ "Mod3" 
+    };
+
+  fprintf(stderr, "-------------------------------\n");
+  fprintf(stderr, "Dumping info for key at %p\n", key);
+
+  for (i = 0; i < N_MBKeyboardKeyStateTypes; i++)
+    {
+      if (mb_kdb_key_has_state(key, i))
+	{
+	  fprintf(stderr, "state : %s\n", state_lookup[i]);
+	  fprintf(stderr, "\tface type %i", mb_kbd_key_get_face_type(key, i));
+
+	  if (mb_kbd_key_get_face_type(key, i) == MBKeyboardKeyFaceGlyph)
+	    {
+	      fprintf(stderr, ", showing '%s'", 
+		      mb_kbd_key_get_glyph_face(key , i));
+	    }
+
+	  fprintf(stderr, "\n");
+
+	  fprintf(stderr, "\taction type %i\n", 
+		  mb_kbd_key_get_action_type(key, i));
+
+	}
+    }
+
+  fprintf(stderr, "-------------------------------\n");
+
+}
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-layout.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-layout.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-layout.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,55 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+struct MBKeyboardLayout
+{
+  MBKeyboard       *kbd;  
+  char             *id;
+  List             *rows;
+};
+
+
+MBKeyboardLayout*
+mb_kbd_layout_new(MBKeyboard *kbd, const char *id)
+{
+  MBKeyboardLayout *layout = NULL;
+
+  layout = util_malloc0(sizeof(MBKeyboardLayout));
+
+  layout->kbd = kbd;
+  layout->id  = strdup(id);
+
+  return layout;
+}
+
+void
+mb_kbd_layout_append_row(MBKeyboardLayout *layout,
+			 MBKeyboardRow    *row)
+{
+  layout->rows = util_list_append(layout->rows, (pointer)row);
+}
+
+List*
+mb_kbd_layout_rows(MBKeyboardLayout *layout)
+{
+  return util_list_get_first(layout->rows);
+}
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-row.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-row.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-row.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,150 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+struct MBKeyboardRow
+{
+  MBKeyboard       *kbd;
+  List             *keys;
+
+  int               alloc_x, alloc_y;
+};
+
+MBKeyboardRow*
+mb_kbd_row_new(MBKeyboard *kbd)
+{
+  MBKeyboardRow *row = NULL;
+
+  row = util_malloc0(sizeof(MBKeyboardRow));
+  row->kbd = kbd;
+
+  return row;
+}
+
+void
+mb_kbd_row_set_x(MBKeyboardRow *row, int x)
+{
+  row->alloc_x = x;
+}
+
+void
+mb_kbd_row_set_y(MBKeyboardRow *row, int y)
+{
+  row->alloc_y = y;
+}
+
+int 
+mb_kbd_row_x (MBKeyboardRow *row) 
+{ 
+  return row->alloc_x;
+}
+
+int 
+mb_kbd_row_y(MBKeyboardRow *row) 
+{
+  return row->alloc_y;
+}
+
+int 
+mb_kbd_row_height(MBKeyboardRow *row) 
+{
+  List          *key_item;
+
+  /* XX this is a little crazed 
+   * We avoid keys with 0 height - spacers or non allocated extended ones
+  */
+
+  mb_kbd_row_for_each_key(row, key_item)
+    {
+      if (!mb_kbd_is_extended(row->kbd) 
+	  && mb_kbd_key_get_extended(key_item->data))
+	continue;
+
+
+      if (mb_kbd_key_height(key_item->data) > 0)
+	return mb_kbd_key_height(key_item->data);
+    }
+
+  return 0;
+}
+
+int 
+mb_kbd_row_width(MBKeyboardRow *row) 
+{
+  List *key_item;
+  int   result;
+
+  /* XXX we should cache this result somehow as locate_key calls this */
+
+  result = mb_kbd_col_spacing(row->kbd);
+
+  
+  mb_kbd_row_for_each_key(row, key_item) 
+   {
+      MBKeyboardKey *key = key_item->data;
+      
+      if (!mb_kbd_is_extended(row->kbd) 
+	  && mb_kbd_key_get_extended(key))
+	continue;
+
+      result += (mb_kbd_key_width(key) + mb_kbd_col_spacing(row->kbd));
+    }
+
+  return result;
+}
+
+int 
+mb_kbd_row_base_width(MBKeyboardRow *row) 
+{
+  List *key_item;
+  int   result;
+
+  result = mb_kbd_col_spacing(row->kbd);
+
+  mb_kbd_row_for_each_key(row, key_item) 
+    {
+      MBKeyboardKey *key = key_item->data;
+      
+      if (!mb_kbd_is_extended(row->kbd) 
+	  && mb_kbd_key_get_extended(key))
+	continue;
+
+      result += (mb_kbd_key_width(key) 
+		 + mb_kbd_col_spacing(row->kbd) 
+		 - mb_kbd_key_get_extra_width_pad(key));
+
+    }
+
+  return result;
+}
+
+void
+mb_kbd_row_append_key(MBKeyboardRow *row, MBKeyboardKey *key)
+{
+  row->keys = util_list_append(row->keys, (pointer)key);
+
+  mb_kbd_key_set_row(key, row);
+}
+
+List*
+mb_kdb_row_keys(MBKeyboardRow *row)
+{
+  return util_list_get_first(row->keys);
+}

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,354 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+typedef struct MBKeyboardUIBackendCario
+{
+  MBKeyboardUIBackend backend;
+
+  cairo_surface_t    *surface;
+  cairo_t            *cr;
+
+  Pixmap              foo_pxm;
+
+} MBKeyboardUIBackendCairo;
+
+static void 
+mb_kbd_ui_cairo_text_extents (MBKeyboardUI  *ui, 
+			      const  char   *str, 
+			      int           *width, 
+			      int           *height)
+{
+  MBKeyboardUIBackendCairo *cairo_backend = NULL;
+  cairo_text_extents_t      extents;
+
+  cairo_backend = (MBKeyboardUIBackendCairo*)mb_kbd_ui_backend(ui);
+
+  cairo_text_extents (cairo_backend->cr, str, &extents);
+
+  *width  = extents.width;
+  *height = extents.height;
+}
+
+static int
+mb_kbd_ui_cairo_load_font(MBKeyboardUI *ui)
+{
+  MBKeyboard *kb = NULL;
+  MBKeyboardUIBackendCairo *cairo_backend = NULL;
+  double                    mm_per_pixel,  pixel_size;
+
+  cairo_backend = (MBKeyboardUIBackendCairo*)mb_kbd_ui_backend(ui);
+  kb          = mb_kbd_ui_kbd(ui);
+
+  /* FIXME: font weights from  kb->font_variant */
+  cairo_select_font_face (cairo_backend->cr,
+			  kb->font_family,
+			  CAIRO_FONT_SLANT_NORMAL,
+			  CAIRO_FONT_WEIGHT_NORMAL);
+
+  mm_per_pixel = (double)DisplayHeightMM(mb_kbd_ui_x_display(ui), 
+					 mb_kbd_ui_x_screen(ui))
+                   / DisplayHeight(mb_kbd_ui_x_display(ui), 
+					 mb_kbd_ui_x_screen(ui));
+
+  /* 1 millimeter = 0.0393700787 inches */
+  
+  /* 1 inch = 72 PostScript points */
+
+  pixel_size = (double)kb->font_pt_size / ( (double)mm_per_pixel * 0.03 * 72 );
+  
+  cairo_set_font_size (cairo_backend->cr, pixel_size);
+  
+  return 1;
+}
+
+
+void
+mb_kbd_ui_cairo_redraw_key(MBKeyboardUI  *ui, MBKeyboardKey *key)
+{
+  MBKeyboardUIBackendCairo *cairo_backend = NULL;
+
+  XRectangle             rect;
+  MBKeyboardKeyStateType state;
+  Display               *xdpy;
+  int                    xscreen;
+  Pixmap                 backbuffer;
+  MBKeyboard            *kbd;
+  cairo_pattern_t       *pat;
+
+  if (mb_kbd_key_is_blank(key)) /* spacer */
+    return;
+
+  cairo_backend = (MBKeyboardUIBackendCairo*)mb_kbd_ui_backend(ui);
+
+  xdpy        = mb_kbd_ui_x_display(ui);
+  xscreen     = mb_kbd_ui_x_screen(ui);
+  backbuffer  = mb_kbd_ui_backbuffer(ui);
+  kbd         = mb_kbd_ui_kbd(ui);
+
+  rect.x      = mb_kbd_key_abs_x(key); 
+  rect.y      = mb_kbd_key_abs_y(key); 
+  rect.width  = mb_kbd_key_width(key);       
+  rect.height = mb_kbd_key_height(key);       
+
+
+  /* clear it */
+
+  cairo_set_line_width (cairo_backend->cr, 0.04);
+  cairo_set_source_rgb(cairo_backend->cr, 0.9, 0.9, 0.8);
+
+  cairo_stroke( cairo_backend->cr );
+
+  pat = cairo_pattern_create_linear (0, rect.y, 0, rect.y + rect.height);
+
+  cairo_pattern_add_color_stop_rgb (pat, 1, 0.2, 0.2, 0.2 );
+  cairo_pattern_add_color_stop_rgb (pat, 0, 0.7, 0.7, 0.7 );
+
+  cairo_set_source (cairo_backend->cr, pat);
+
+  cairo_rectangle( cairo_backend->cr, 
+		   rect.x, rect.y, 
+		   rect.width, rect.height);
+
+  cairo_fill (cairo_backend->cr);
+
+  cairo_pattern_destroy (pat);
+
+
+  /* border */
+
+  cairo_move_to(cairo_backend->cr,
+                rect.x + 1,
+                (mb_kbd_key_abs_y(key) + mb_kbd_key_height(key)) - 1);
+
+  cairo_rel_line_to(cairo_backend->cr,
+                    rect.width - 2,
+                    0);
+
+  cairo_rel_line_to(cairo_backend->cr,
+                    0,
+                    -rect.height);
+
+  cairo_set_source_rgba(cairo_backend->cr, 0, 0, 0, 0.2);
+
+  cairo_move_to(cairo_backend->cr,
+                rect.x,
+                rect.y + rect.height - 1);
+
+  cairo_rel_line_to(cairo_backend->cr,
+                     0,
+                    - rect.height);
+
+  cairo_rel_line_to(cairo_backend->cr,
+                    rect.width - 1,
+                    0);
+
+  cairo_stroke ( cairo_backend->cr );
+
+  cairo_set_source_rgb(cairo_backend->cr, 0, 0, 0);
+
+  cairo_set_line_width (cairo_backend->cr, 1);
+
+  cairo_rectangle( cairo_backend->cr,
+                   rect.x, rect.y, rect.width, rect.height);
+
+  cairo_stroke(cairo_backend->cr);
+
+  /* Handle state related painting */
+
+  state = mb_kbd_keys_current_state(kbd); 
+
+  if (mb_kbd_has_state(kbd, MBKeyboardStateCaps)
+      && mb_kbd_key_get_obey_caps(key))
+    state = MBKeyboardKeyStateShifted;
+
+  if (!mb_kdb_key_has_state(key, state))
+    {
+      if (state == MBKeyboardKeyStateNormal)
+	return;  /* keys should at least have a normal state */
+      else
+        state = MBKeyboardKeyStateNormal;
+    }
+
+  cairo_set_source_rgb(cairo_backend->cr, 0, 0, 0);
+
+  if (mb_kbd_key_get_face_type(key, state) == MBKeyboardKeyFaceGlyph)
+  {
+    const char *face_str = mb_kbd_key_get_glyph_face(key, state);
+
+    if (face_str)
+      {
+        double x, y;
+	int    face_width, face_height;
+	cairo_font_extents_t font_extents;
+
+	/* FIXME: Below is borked */
+	mb_kbd_ui_cairo_text_extents (ui, face_str, &face_width, &face_height);
+
+	cairo_font_extents (cairo_backend->cr, &font_extents);
+	
+	DBG(" %i - %i = %i", 
+	    rect.width, face_width,
+	    (rect.width - face_width) );
+
+        x = rect.x + ( (rect.width - face_width) / 2.0);
+
+        y = rect.y + ( (rect.height - (font_extents.ascent + font_extents.descent)) / 2.0 ) + font_extents.ascent;
+
+	/* DBG("draw text to %d,%d", __func__, x, y); */
+
+        cairo_move_to(cairo_backend->cr, x, y);
+        cairo_show_text (cairo_backend->cr, face_str);
+
+      }
+  }
+
+  if ( mb_kbd_key_is_held(kbd, key) )
+    {
+      cairo_set_source_rgba(cairo_backend->cr,
+			    0,
+			    0,
+			    0,
+			    0.2);
+      
+      cairo_rectangle(cairo_backend->cr,
+		      rect.x,
+		      rect.y,
+		      rect.width,
+		      rect.height );
+      
+      cairo_fill( cairo_backend->cr );
+    }
+
+  // cairo_show_page(cairo_backend->cr);
+  // cairo_destroy (cairo_backend->cr);
+
+}
+
+
+void 	 /* FIXME: rename to clear backbuffer ? */
+mb_kbd_ui_cairo_pre_redraw(MBKeyboardUI  *ui)
+{
+  MBKeyboardUIBackendCairo *cairo_backend = NULL;
+
+  cairo_backend = (MBKeyboardUIBackendCairo*)mb_kbd_ui_backend(ui);
+
+  cairo_set_source_rgb (cairo_backend->cr, 0.95, 0.95, 0.95);
+
+  cairo_rectangle( cairo_backend->cr,
+                   0,
+                   0,
+		   mb_kbd_ui_x_win_width(ui),
+		   mb_kbd_ui_x_win_height(ui));
+
+  cairo_fill( cairo_backend->cr );
+
+  // cairo_destroy( cairo_backend->cr );
+}
+
+static int
+mb_kbd_ui_cairo_resources_create(MBKeyboardUI  *ui)
+{
+  MBKeyboardUIBackendCairo *cairo_backend = NULL;
+
+  cairo_backend = (MBKeyboardUIBackendCairo*)mb_kbd_ui_backend(ui);
+
+  /* switch now to 'real' drawable */
+  cairo_xlib_surface_set_drawable (cairo_backend->surface, 
+				   mb_kbd_ui_backbuffer(ui),
+				   mb_kbd_ui_x_win_width(ui),
+				   mb_kbd_ui_x_win_height(ui));
+
+  XFreePixmap(mb_kbd_ui_x_display(ui),  cairo_backend->foo_pxm);
+
+  cairo_xlib_surface_set_size (cairo_backend->surface, 
+			       mb_kbd_ui_x_win_width(ui),
+			       mb_kbd_ui_x_win_height(ui));
+
+  return True;
+}
+
+static int
+mb_kbd_ui_cairo_resize(MBKeyboardUI  *ui, int width, int height)
+{
+  MBKeyboardUIBackendCairo *cairo_backend = NULL;
+
+  cairo_backend = (MBKeyboardUIBackendCairo*)mb_kbd_ui_backend(ui);
+
+  if (cairo_backend->cr != NULL) /* may get called before initialised */
+    {
+      cairo_xlib_surface_set_size (cairo_get_target(cairo_backend->cr), 
+				   mb_kbd_ui_x_win_width(ui),
+				   mb_kbd_ui_x_win_height(ui));
+
+      cairo_xlib_surface_set_drawable (cairo_backend->surface, 
+				       mb_kbd_ui_backbuffer(ui),
+				       mb_kbd_ui_x_win_width(ui),
+				       mb_kbd_ui_x_win_height(ui));
+      /*
+      cairo_scale (cairo_get_target(cairo_backend->cr), 
+		   mb_kbd_ui_x_win_width(ui),
+		   mb_kbd_ui_x_win_height(ui));
+      */
+    }
+
+  return True;
+}
+
+MBKeyboardUIBackend*
+mb_kbd_ui_cairo_init(MBKeyboardUI *ui)
+{
+  MBKeyboardUIBackendCairo *cairo_backend = NULL;
+
+  cairo_backend = util_malloc0(sizeof(MBKeyboardUIBackendCairo));
+
+  cairo_backend->backend.init             = mb_kbd_ui_cairo_init;
+  cairo_backend->backend.font_load        = mb_kbd_ui_cairo_load_font;
+  cairo_backend->backend.text_extents     = mb_kbd_ui_cairo_text_extents;
+  cairo_backend->backend.redraw_key       = mb_kbd_ui_cairo_redraw_key;
+  cairo_backend->backend.pre_redraw       = mb_kbd_ui_cairo_pre_redraw;
+  cairo_backend->backend.resources_create = mb_kbd_ui_cairo_resources_create;
+  cairo_backend->backend.resize           = mb_kbd_ui_cairo_resize;
+
+  /* We need to make a temp surface so we can make cairo
+   * cairo font calls ok with a context before ui knows
+   * its window and therefore backbuffer sizes etc.
+  */
+  cairo_backend->foo_pxm = XCreatePixmap(mb_kbd_ui_x_display(ui),
+					 mb_kbd_ui_x_win_root(ui),
+					 10,
+					 10,
+					 DefaultDepth(mb_kbd_ui_x_display(ui),
+						      mb_kbd_ui_x_screen(ui)));
+
+  cairo_backend->surface 
+    = cairo_xlib_surface_create (mb_kbd_ui_x_display(ui),
+				 cairo_backend->foo_pxm,
+				 DefaultVisual(mb_kbd_ui_x_display(ui), 
+					       mb_kbd_ui_x_screen(ui)),
+				 10, 10);
+
+  cairo_backend->cr = cairo_create (cairo_backend->surface);
+
+  cairo_reference(cairo_backend->cr);
+
+  return (MBKeyboardUIBackend*)cairo_backend;
+}
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.h
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.h	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-cairo-backend.h	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,33 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#ifndef HAVE_MB_KEYBOARD_CAIRO_BACKEND_XFT_H
+#define HAVE_MB_KEYBOARD_CAIRO_BACKEND_XFT_H
+
+#include "matchbox-keyboard.h"
+
+#include <cairo/cairo.h>
+#include <cairo/cairo-xlib.h>
+
+MBKeyboardUIBackend*
+mb_kbd_ui_cairo_init(MBKeyboardUI *ui);
+
+#define MB_KBD_UI_BACKEND_INIT_FUNC(ui)  mb_kbd_ui_cairo_init((ui))
+
+#endif

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,381 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+typedef struct MBKeyboardUIBackendXft
+{
+  MBKeyboardUIBackend backend;
+
+  XftFont            *font;
+  XftColor            font_col; 
+  XftDraw            *xft_backbuffer;  
+  GC                  xgc;
+
+  /* Our theme */
+
+  XColor xcol_c5c5c5, xcol_d3d3d3, xcol_f0f0f0, xcol_f8f8f5, 
+    xcol_f4f4f4, xcol_a4a4a4;
+
+} MBKeyboardUIBackendXft;
+
+static void 
+mb_kbd_ui_xft_text_extents (MBKeyboardUI        *ui, 
+			    const char          *str, 
+			    int                 *width, 
+			    int                 *height)
+{
+  XGlyphInfo  extents;
+  MBKeyboardUIBackendXft *xft_backend = NULL;
+
+  xft_backend = (MBKeyboardUIBackendXft*)mb_kbd_ui_backend(ui);
+  
+  XftTextExtentsUtf8(mb_kbd_ui_x_display(ui), 
+		     xft_backend->font,
+		     (unsigned char*)str, 
+		     strlen(str),
+		     &extents);
+
+  *width  = extents.width;
+  /* *height = extents.height; */
+  *height = xft_backend->font->ascent + xft_backend->font->descent;
+}
+
+void
+alloc_color(MBKeyboardUI  *ui, XColor *xcol, char *spec)
+{
+  int           result;
+
+  if (spec[0] != '#')
+    return;
+
+  if ( sscanf (spec+1, "%x", &result))
+    {
+      xcol->red   = ((result >> 16) & 0xff) << 8;
+      xcol->green = ((result >> 8) & 0xff)  << 8;
+      xcol->blue  = (result & 0xff) << 8;
+      xcol->flags = DoRed|DoGreen|DoBlue;
+
+      XAllocColor(mb_kbd_ui_x_display(ui), 
+		  DefaultColormap(mb_kbd_ui_x_display(ui), 
+				  mb_kbd_ui_x_screen(ui)), 
+		  xcol);
+    }
+  
+  return;
+}
+
+static int
+mb_kbd_ui_xft_load_font(MBKeyboardUI *ui)
+{
+  MBKeyboard *kb = NULL;
+  char desc[512];
+  MBKeyboardUIBackendXft *xft_backend = NULL;
+
+  xft_backend = (MBKeyboardUIBackendXft*)mb_kbd_ui_backend(ui);
+  kb          = mb_kbd_ui_kbd(ui);
+
+  /* load_font */
+
+  snprintf(desc, 512, "%s-%i:%s", 
+	   kb->font_family, kb->font_pt_size, kb->font_variant);
+
+  if (xft_backend->font != NULL)
+    XftFontClose(mb_kbd_ui_x_display(ui), xft_backend->font);
+
+  if ((xft_backend->font = XftFontOpenName(mb_kbd_ui_x_display(ui), 
+					   mb_kbd_ui_x_screen(ui), 
+					   desc)) == NULL)
+    return 0;
+  
+  return 1;
+}
+
+
+void
+mb_kbd_ui_xft_redraw_key(MBKeyboardUI  *ui, MBKeyboardKey *key)
+{
+  MBKeyboardUIBackendXft *xft_backend = NULL;
+  XRectangle             rect;
+  MBKeyboardKeyStateType state;
+  int                    side_pad;
+  Display               *xdpy;
+  int                    xscreen;
+  Pixmap                 backbuffer;
+  MBKeyboard            *kbd;
+
+  if (mb_kbd_key_is_blank(key)) /* spacer */
+    return;
+
+  xft_backend = (MBKeyboardUIBackendXft*)mb_kbd_ui_backend(ui);
+  xdpy        = mb_kbd_ui_x_display(ui);
+  xscreen     = mb_kbd_ui_x_screen(ui);
+  backbuffer  = mb_kbd_ui_backbuffer(ui);
+  kbd         = mb_kbd_ui_kbd(ui);
+
+
+  rect.x      = mb_kbd_key_abs_x(key); 
+  rect.y      = mb_kbd_key_abs_y(key); 
+  rect.width  = mb_kbd_key_width(key);       
+  rect.height = mb_kbd_key_height(key);       
+
+  /* Hacky clip to work around issues with off by ones in layout code :( */
+
+  if (rect.x + rect.width >= mb_kbd_ui_x_win_width(ui)) 
+    rect.width  = mb_kbd_ui_x_win_width(ui) - rect.x - 1;
+
+  if (rect.y + rect.height >= mb_kbd_ui_x_win_height(ui)) 
+    rect.height  = mb_kbd_ui_x_win_height(ui) - rect.y - 1;
+
+  /* clear it */
+
+  XSetForeground(xdpy, xft_backend->xgc, WhitePixel(xdpy, xscreen));
+
+  XFillRectangles(xdpy, backbuffer, xft_backend->xgc, &rect, 1);
+
+  /* draw 'main border' */
+
+  XSetForeground(xdpy, xft_backend->xgc, xft_backend->xcol_c5c5c5.pixel);
+
+  XDrawRectangles(xdpy, backbuffer, xft_backend->xgc, &rect, 1);
+
+  /* shaded bottom line */
+
+  XSetForeground(xdpy, xft_backend->xgc, xft_backend->xcol_f4f4f4.pixel);
+  XDrawLine(xdpy, backbuffer, xft_backend->xgc,
+	    rect.x + 1,
+	    rect.y + rect.height - 1,
+	    rect.x + rect.width -2 ,
+	    rect.y + rect.height - 1);
+
+  /* Corners - XXX should really use drawpoints */
+
+  XSetForeground(xdpy, xft_backend->xgc, xft_backend->xcol_f0f0f0.pixel);
+
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x, rect.y);
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+rect.width, rect.y);
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+rect.width, rect.y+rect.height);
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x, rect.y+rect.height);
+
+  /* soften them more */
+
+  XSetForeground(xdpy, xft_backend->xgc, xft_backend->xcol_d3d3d3.pixel);
+
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+1, rect.y);
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x, rect.y+1);
+
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+rect.width-1, rect.y);
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+rect.width, rect.y+1);
+
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+rect.width-1, rect.y+rect.height);
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+rect.width, rect.y+rect.height-1);
+
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x, rect.y+rect.height-1);
+  XDrawPoint(xdpy, backbuffer, xft_backend->xgc, rect.x+1, rect.y+rect.height);
+
+  /* background */
+
+  if (mb_kbd_key_is_held(kbd, key))
+    XSetForeground(xdpy, xft_backend->xgc, xft_backend->xcol_a4a4a4.pixel);
+  else
+    XSetForeground(xdpy, xft_backend->xgc, xft_backend->xcol_f8f8f5.pixel);
+
+  side_pad = 
+    mb_kbd_keys_border(kbd)
+    + mb_kbd_keys_margin(kbd)
+    + mb_kbd_keys_pad(kbd);
+
+  /* Why does below need +1's ? */
+  XFillRectangle(xdpy, backbuffer, xft_backend->xgc, 
+		 rect.x + side_pad,
+		 rect.y + side_pad,
+		 rect.width  - (side_pad * 2) + 1,
+		 rect.height - (side_pad * 2) + 1);
+
+  /* real code is here */
+
+  state = mb_kbd_keys_current_state(kbd); 
+
+  if (mb_kbd_has_state(kbd, MBKeyboardStateCaps)
+      && mb_kbd_key_get_obey_caps(key))
+    state = MBKeyboardKeyStateShifted;
+
+  if (!mb_kdb_key_has_state(key, state))
+    {
+      if (state == MBKeyboardKeyStateNormal)
+	return;  /* keys should at least have a normal state */
+      else
+        state = MBKeyboardKeyStateNormal;
+    }
+
+  if (mb_kbd_key_get_face_type(key, state) == MBKeyboardKeyFaceGlyph)
+    {
+      const char *face_str = mb_kbd_key_get_glyph_face(key, state);
+      int         face_str_w, face_str_h;
+      
+      if (face_str)
+	{
+	  int x, y;
+	  
+	  mb_kbd_ui_xft_text_extents(ui, face_str, &face_str_w, &face_str_h);
+	  
+	  x = mb_kbd_key_abs_x(key) + ((mb_kbd_key_width(key) - face_str_w)/2);
+	  
+	  y = mb_kbd_key_abs_y(key) + 
+	    ( (mb_kbd_key_height(key) 
+                 - (xft_backend->font->ascent + xft_backend->font->descent))
+	                             / 2 );
+	  
+	  XftDrawStringUtf8(xft_backend->xft_backbuffer,
+			    &xft_backend->font_col,
+			    xft_backend->font,
+			    x,
+			    y + xft_backend->font->ascent,
+			    (unsigned char*)face_str, 
+			    strlen(face_str));
+	}
+    }
+  else if (mb_kbd_key_get_face_type(key, state) == MBKeyboardKeyFaceImage)
+    {
+      int x, y, w, h;
+      MBKeyboardImage *img;
+
+      img = mb_kbd_key_get_image_face(key, state);
+
+      w = mb_kbd_image_width (img);
+      h = mb_kbd_image_height (img);
+
+      x = mb_kbd_key_abs_x(key) + ((mb_kbd_key_width(key) - w) / 2);
+      y = mb_kbd_key_abs_y(key) + ((mb_kbd_key_height(key) - h ) / 2);
+
+
+      XRenderComposite(xdpy,
+		       PictOpOver, 
+		       mb_kbd_image_render_picture (img), 
+		       None, 
+		       XftDrawPicture (xft_backend->xft_backbuffer), 
+		       0, 0, 0, 0, x, y, w, h);
+    }
+}
+
+void
+mb_kbd_ui_xft_pre_redraw(MBKeyboardUI  *ui)
+{
+  MBKeyboardUIBackendXft *xft_backend = NULL;
+
+  xft_backend = (MBKeyboardUIBackendXft*)mb_kbd_ui_backend(ui);
+
+  /* Background */
+  XSetForeground(mb_kbd_ui_x_display(ui), 
+		 xft_backend->xgc, xft_backend->xcol_f4f4f4.pixel);
+
+  XFillRectangle(mb_kbd_ui_x_display(ui), 
+		 mb_kbd_ui_backbuffer(ui), 
+		 xft_backend->xgc,
+		 0, 0, 
+		 mb_kbd_ui_x_win_width(ui),
+		 mb_kbd_ui_x_win_height(ui));
+
+  XSetForeground(mb_kbd_ui_x_display(ui), 
+		 xft_backend->xgc, 
+		 BlackPixel(mb_kbd_ui_x_display(ui), 
+			    mb_kbd_ui_x_screen(ui)));
+
+
+}
+
+static int
+mb_kbd_ui_xft_resources_create(MBKeyboardUI  *ui)
+{
+  MBKeyboardUIBackendXft *xft_backend = NULL;
+  XRenderColor            coltmp;
+
+  xft_backend = (MBKeyboardUIBackendXft*)mb_kbd_ui_backend(ui);
+
+  xft_backend->xft_backbuffer = XftDrawCreate(mb_kbd_ui_x_display(ui),
+					      mb_kbd_ui_backbuffer(ui),
+					      DefaultVisual(mb_kbd_ui_x_display(ui), 
+							    mb_kbd_ui_x_screen(ui)),
+					      DefaultColormap(mb_kbd_ui_x_display(ui),
+							      mb_kbd_ui_x_screen(ui)));
+
+
+  coltmp.red   = coltmp.green = coltmp.blue  = 0x0000; coltmp.alpha = 0xcccc;
+
+  XftColorAllocValue(mb_kbd_ui_x_display(ui),
+		     DefaultVisual(mb_kbd_ui_x_display(ui), 
+				   mb_kbd_ui_x_screen(ui)), 
+		     DefaultColormap(mb_kbd_ui_x_display(ui), 
+				     mb_kbd_ui_x_screen(ui)),
+		     &coltmp,
+		     &xft_backend->font_col);
+
+  xft_backend->xgc = XCreateGC(mb_kbd_ui_x_display(ui), 
+			       mb_kbd_ui_x_win(ui), 0, NULL);
+
+  XSetForeground(mb_kbd_ui_x_display(ui), 
+		 xft_backend->xgc, 
+		 BlackPixel(mb_kbd_ui_x_display(ui), mb_kbd_ui_x_screen(ui)));
+
+  XSetBackground(mb_kbd_ui_x_display(ui), 
+		 xft_backend->xgc, 
+		 WhitePixel(mb_kbd_ui_x_display(ui), mb_kbd_ui_x_screen(ui)));
+
+  /* Crusty theme stuff  */
+
+  alloc_color(ui, &xft_backend->xcol_c5c5c5, "#c5c5c5");
+  alloc_color(ui, &xft_backend->xcol_d3d3d3, "#d3d3d3");
+  alloc_color(ui, &xft_backend->xcol_f0f0f0, "#f0f0f0");
+  alloc_color(ui, &xft_backend->xcol_f8f8f5, "#f8f8f5");
+  alloc_color(ui, &xft_backend->xcol_f4f4f4, "#f4f4f4");
+  alloc_color(ui, &xft_backend->xcol_a4a4a4, "#a4a4a4");
+
+  return True;
+}
+
+static int
+mb_kbd_ui_xft_resize(MBKeyboardUI  *ui, int width, int height)
+{
+  MBKeyboardUIBackendXft *xft_backend = NULL;
+
+  xft_backend = (MBKeyboardUIBackendXft*)mb_kbd_ui_backend(ui);
+
+  XftDrawChange (xft_backend->xft_backbuffer, mb_kbd_ui_backbuffer(ui));
+
+  return True;
+}
+
+MBKeyboardUIBackend*
+mb_kbd_ui_xft_init(MBKeyboardUI *ui)
+{
+  MBKeyboardUIBackendXft *xft_backend = NULL;
+
+  xft_backend = util_malloc0(sizeof(MBKeyboardUIBackendXft));
+
+  xft_backend->backend.init             = mb_kbd_ui_xft_init;
+  xft_backend->backend.font_load        = mb_kbd_ui_xft_load_font;
+  xft_backend->backend.text_extents     = mb_kbd_ui_xft_text_extents;
+  xft_backend->backend.redraw_key       = mb_kbd_ui_xft_redraw_key;
+  xft_backend->backend.pre_redraw       = mb_kbd_ui_xft_pre_redraw;
+  xft_backend->backend.resources_create = mb_kbd_ui_xft_resources_create;
+  xft_backend->backend.resize           = mb_kbd_ui_xft_resize;
+
+  return (MBKeyboardUIBackend*)xft_backend;
+}
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.h
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.h	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui-xft-backend.h	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,31 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#ifndef HAVE_MB_KEYBOARD_UI_BACKEND_XFT_H
+#define HAVE_MB_KEYBOARD_UI_BACKEND_XFT_H
+
+#include "matchbox-keyboard.h"
+#include <X11/Xft/Xft.h>
+
+MBKeyboardUIBackend*
+mb_kbd_ui_xft_init(MBKeyboardUI *ui);
+
+#define MB_KBD_UI_BACKEND_INIT_FUNC(ui)  mb_kbd_ui_xft_init((ui))
+
+#endif

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-ui.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,1291 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+#define PROP_MOTIF_WM_HINTS_ELEMENTS    5
+#define MWM_HINTS_DECORATIONS          (1L << 1)
+#define MWM_DECOR_BORDER               (1L << 1)
+
+typedef struct
+{
+  unsigned long       flags;
+  unsigned long       functions;
+  unsigned long       decorations;
+  long                inputMode;
+  unsigned long       status;
+} 
+PropMotifWmHints;
+
+
+
+struct MBKeyboardUI
+{
+  Display            *xdpy;
+  int                 xscreen;
+  Window              xwin_root, xwin;
+  Pixmap              backbuffer;
+
+  int                 dpy_width, dpy_height;
+  int                 xwin_width, xwin_height;
+
+  int                 key_uwidth, key_uheight;
+
+  int                 base_alloc_width, base_alloc_height;
+  int                 base_font_pt_size;
+
+  Bool                want_embedding;
+
+  FakeKey             *fakekey;
+  MBKeyboardUIBackend *backend; 
+  MBKeyboard          *kbd;
+};
+
+static void
+mb_kbd_ui_resize(MBKeyboardUI *ui, int width, int height);
+
+static int
+mb_kbd_ui_load_font(MBKeyboardUI *ui);
+
+
+static char*
+get_current_window_manager_name (MBKeyboardUI  *ui)
+{
+  Atom           atom_utf8_string, atom_wm_name, atom_check, type;
+  int            result, format;
+  char          *val, *retval;
+  unsigned long  nitems, bytes_after;
+  Window        *support_xwin = NULL;
+
+  atom_check = XInternAtom (ui->xdpy, "_NET_SUPPORTING_WM_CHECK", False);
+
+  XGetWindowProperty (ui->xdpy, 
+		      RootWindow(ui->xdpy, ui->xscreen),
+		      atom_check,
+		      0, 16L, False, XA_WINDOW, &type, &format,
+		      &nitems, &bytes_after, (unsigned char **)&support_xwin);
+
+  if (support_xwin == NULL)
+      return NULL;
+
+  atom_utf8_string = XInternAtom (ui->xdpy, "UTF8_STRING", False);
+  atom_wm_name     = XInternAtom (ui->xdpy, "_NET_WM_NAME", False);
+
+  result = XGetWindowProperty (ui->xdpy, *support_xwin, atom_wm_name,
+			       0, 1000L,False, atom_utf8_string,
+			       &type, &format, &nitems,
+			       &bytes_after, (unsigned char **)&val);
+  if (result != Success)
+    return NULL;
+
+  if (type != atom_utf8_string || format !=8 || nitems == 0)
+    {
+      if (val) XFree (val);
+      return NULL;
+    }
+
+  retval = strdup (val);
+
+  XFree (val);
+
+  return retval;
+}
+
+static boolean
+get_desktop_area(MBKeyboardUI *ui, int *x, int *y, int *width, int *height)
+{
+  Atom           atom_area, type;
+  int            result, format;
+  unsigned long  nitems, bytes_after;
+  int           *geometry = NULL;
+
+  atom_area = XInternAtom (ui->xdpy, "_NET_WORKAREA", False);
+
+  result = XGetWindowProperty (ui->xdpy, 
+			       RootWindow(ui->xdpy, ui->xscreen),
+			       atom_area,
+			       0, 16L, False, XA_CARDINAL, &type, &format,
+			       &nitems, &bytes_after, 
+			       (unsigned char **)&geometry);
+
+  if (result != Success || nitems < 4 || geometry == NULL)
+    {
+      if (geometry) XFree(geometry);
+      return False;
+    }
+
+  if (x) *x           = geometry[0];
+  if (y) *y           = geometry[1];
+  if (width)  *width  = geometry[2];
+  if (height) *height = geometry[3];
+  
+  XFree(geometry);
+
+  return True;
+}
+
+static void
+update_display_size(MBKeyboardUI *ui)
+{
+  XWindowAttributes winattr;
+
+  XGetWindowAttributes(ui->xdpy, ui->xwin_root, &winattr);
+
+  /* XXX should actually trap an X error here */
+
+  ui->dpy_width  = winattr.width;
+  ui->dpy_height = winattr.height;
+
+  return;
+}
+
+static boolean
+want_extended(MBKeyboardUI *ui)
+{
+  /* Are we in portrait ? */
+  if (ui->dpy_width > ui->dpy_height)
+    return True;
+
+  return False;
+}
+
+static boolean
+get_xevent_timed(Display        *dpy,
+		 XEvent         *event_return, 
+		 struct timeval *tv)
+{
+  if (tv->tv_usec == 0 && tv->tv_sec == 0)
+    {
+      XNextEvent(dpy, event_return);
+      return True;
+    }
+
+  XFlush(dpy);
+
+  if (XPending(dpy) == 0) 
+    {
+      int fd = ConnectionNumber(dpy);
+
+      fd_set readset;
+      FD_ZERO(&readset);
+      FD_SET(fd, &readset);
+
+      if (select(fd+1, &readset, NULL, NULL, tv) == 0) 
+	return False;
+      else 
+	{
+	  XNextEvent(dpy, event_return);
+	  return True;
+	}
+    } else {
+      XNextEvent(dpy, event_return);
+      return True;
+    }
+}
+
+
+void
+mb_kbd_ui_send_press(MBKeyboardUI        *ui,
+		     const char          *utf8_char_in,
+		     int                  modifiers)
+{
+  DBG("Sending '%s'", utf8_char_in);
+  fakekey_press(ui->fakekey, (unsigned char*)utf8_char_in, -1, modifiers);
+}
+
+void
+mb_kbd_ui_send_keysym_press(MBKeyboardUI  *ui,
+			    KeySym         ks,
+			    int            modifiers)
+{
+  fakekey_press_keysym(ui->fakekey, ks, modifiers);
+}
+
+void
+mb_kbd_ui_send_release(MBKeyboardUI  *ui)
+{
+  fakekey_release(ui->fakekey);
+}
+
+static void
+mb_kdb_ui_unit_key_size(MBKeyboardUI *ui, int *width, int *height)
+{
+  MBKeyboardLayout       *layout;
+  List                   *row_item, *key_item;
+  MBKeyboardKeyStateType  state;
+  const char             *face_str;
+
+  *width = 0; *height = 0;
+
+  layout   = mb_kbd_get_selected_layout(ui->kbd);
+  row_item = mb_kbd_layout_rows(layout);
+
+  /*
+   * Figure out the base size of a 'regular' single glyph key.    
+  */
+
+  while (row_item != NULL)
+    {
+      mb_kbd_row_for_each_key(row_item->data, key_item)
+	{
+	  MBKeyboardKey *key = key_item->data;
+
+	  if (!mb_kbd_is_extended(ui->kbd) 
+	      && mb_kbd_key_get_extended(key))
+	    continue;
+
+	  /* Ignore keys whose width is forced */
+	  if (mb_kbd_key_get_req_uwidth(key))
+	    continue;
+
+	  mb_kdb_key_foreach_state(key, state)
+	    {
+	      if (mb_kbd_key_get_face_type(key, state) == MBKeyboardKeyFaceGlyph)
+		{
+		  face_str = mb_kbd_key_get_glyph_face(key, state);
+
+		  if (util_utf8_char_cnt(face_str) == 1)
+		    {
+		      int str_w =0, str_h = 0;
+
+		      ui->backend->text_extents(ui, face_str, &str_w, &str_h);
+		      
+		      if (str_w > *width) *width = str_w;
+		      if (str_h > *height) *height = str_h;
+
+		    }
+		}
+	      else if (mb_kbd_key_get_face_type(key, state) == MBKeyboardKeyFaceImage)
+		{
+		  MBKeyboardImage *img;
+
+		  img = mb_kbd_key_get_image_face(key, state);
+
+		  if (mb_kbd_image_width (img) > *width) 
+		    *width = mb_kbd_image_width (img);
+
+		  if (mb_kbd_image_height (img) > *height) 
+		    *height = mb_kbd_image_height (img);
+		}
+	    }
+	}
+      row_item = util_list_next(row_item);
+    }
+
+  /* FIXME: hack for small displays */
+  if (mb_kbd_ui_display_height(ui) <= 320)
+    {
+      *height += 4;
+    }
+
+}
+
+static void
+mb_kbd_ui_min_key_size(MBKeyboardUI  *ui,
+		       MBKeyboardKey *key,
+		       int           *width,
+		       int           *height)
+{
+  const char *face_str = NULL;
+  int         max_w = 0, max_h = 0, state, kw, kh;
+
+  /* 
+   * Figure out how small a key can really be UI wise.
+  */
+
+  if (mb_kbd_key_get_req_uwidth(key) || mb_kbd_key_is_blank(key))
+    {
+      *width = (ui->key_uwidth * mb_kbd_key_get_req_uwidth(key)) / 1000 ;
+      *height = ui->key_uheight;
+      return;
+    }
+
+  mb_kdb_key_foreach_state(key, state)
+    {
+      if (mb_kbd_key_get_face_type(key, state) == MBKeyboardKeyFaceGlyph)
+	{
+	  face_str = mb_kbd_key_get_glyph_face(key, state);
+
+	  ui->backend->text_extents(ui, face_str, &kw, &kh);
+
+	  if (kw > max_w) max_w = kw;
+	  if (kh > max_h) max_h = kh;
+	}
+      else if (mb_kbd_key_get_face_type(key, state) == MBKeyboardKeyFaceImage)
+	{
+	  MBKeyboardImage *img;
+
+	  img = mb_kbd_key_get_image_face(key, state);
+
+	  if (mb_kbd_image_width (img) > max_w) 
+	    max_w = mb_kbd_image_width (img);
+
+	  if (mb_kbd_image_height (img) > max_h) 
+	    max_h = mb_kbd_image_height (img);
+	}
+    }
+}
+
+void
+mb_kbd_ui_allocate_ui_layout(MBKeyboardUI *ui,
+			     int          *width,
+			     int          *height)
+{
+  MBKeyboardLayout *layout;
+  List             *row_item, *key_item;
+  int               key_y = 0, key_x = 0; 
+  int               row_y, max_row_key_height, max_row_width;
+
+  layout = mb_kbd_get_selected_layout(ui->kbd);
+
+  /* Do an initial run to figure out a 'base' size for single glyph keys */
+  mb_kdb_ui_unit_key_size(ui, &ui->key_uwidth, &ui->key_uheight);
+
+  row_item = mb_kbd_layout_rows(layout);
+
+  row_y = mb_kbd_row_spacing(ui->kbd); 
+
+  max_row_width = 0;
+
+  /* 
+   * First of entire keyboard, basically get the minimum space needed
+  */
+  while (row_item != NULL)
+    {
+      MBKeyboardRow *row = row_item->data;
+      
+      key_x = mb_kbd_col_spacing(ui->kbd);
+
+      max_row_key_height = 0;
+
+      mb_kbd_row_for_each_key(row, key_item)
+	{
+	  int            key_w = 0, key_h = 0;          
+	  MBKeyboardKey *key = key_item->data;
+
+	  mb_kbd_key_set_extra_height_pad(key, 0);
+	  mb_kbd_key_set_extra_width_pad(key, 0);
+	  mb_kbd_key_set_geometry(key, 0, 0, 0, 0);
+
+	  if (!mb_kbd_is_extended(ui->kbd) && mb_kbd_key_get_extended(key))
+	    continue;
+
+	  mb_kbd_ui_min_key_size(ui, key, &key_w, &key_h);
+
+	  if (!mb_kbd_key_get_req_uwidth(key)
+	      && key_w < ui->key_uwidth)
+	    key_w = ui->key_uwidth;
+
+	  if (key_h < ui->key_uheight) 
+	    key_h = ui->key_uheight;
+
+	  key_y = 0;
+
+	  key_w += 2 * ( mb_kbd_keys_border(ui->kbd) 
+			 + mb_kbd_keys_margin(ui->kbd) 
+			 + mb_kbd_keys_pad(ui->kbd) );
+
+	  key_h += 2 * ( mb_kbd_keys_border(ui->kbd) 
+			 + mb_kbd_keys_margin(ui->kbd) 
+			 + mb_kbd_keys_pad(ui->kbd) );
+	  
+	  if (key_h > max_row_key_height)
+	    max_row_key_height = key_h;
+
+	  mb_kbd_key_set_geometry(key, key_x, key_y, key_w, key_h); 
+	  
+	  key_x += (mb_kbd_col_spacing(ui->kbd) + key_w);
+	}
+
+      if (key_x > max_row_width) /* key_x now represents row width */
+	max_row_width = key_x;
+
+      mb_kbd_row_set_y(row, row_y);
+
+      row_y += max_row_key_height + mb_kbd_row_spacing(ui->kbd);
+
+      row_item = util_list_next(row_item);
+    }
+
+  *height = row_y; 
+
+  row_item = mb_kbd_layout_rows(layout);
+
+  /* Now pass again allocating any extra space with have left over */
+
+  while (row_item != NULL)
+    {
+      MBKeyboardRow *row        = row_item->data;
+      int            n_fillers  = 0, free_space = 0, new_w = 0;
+
+      mb_kbd_row_for_each_key(row,key_item)
+	{
+	  if (!mb_kbd_is_extended(ui->kbd) 
+	      && mb_kbd_key_get_extended(key_item->data))
+	    continue;
+
+	  if (mb_kbd_key_get_fill(key_item->data)
+	      || mb_kbd_ui_display_height(ui) <= 320
+	      || mb_kbd_ui_display_width(ui) <= 320 )
+	      n_fillers++;
+	}
+
+      if (!n_fillers)
+	goto next_row;
+
+      free_space = max_row_width - mb_kbd_row_width(row);
+
+      mb_kbd_row_for_each_key(row, key_item)
+	{
+	  if (!mb_kbd_is_extended(ui->kbd) 
+	      && mb_kbd_key_get_extended(key_item->data))
+	    continue;
+
+	  if (mb_kbd_key_get_fill(key_item->data)
+	      || mb_kbd_ui_display_height(ui) <= 320
+	      || mb_kbd_ui_display_width(ui) <= 320 )
+	    {
+	      int   old_w;
+	      List *nudge_key_item = util_list_next(key_item);
+
+	      old_w = mb_kbd_key_width(key_item->data);
+	      new_w = old_w + (free_space/n_fillers);
+
+	      mb_kbd_key_set_geometry(key_item->data, -1, -1, new_w, -1);
+
+	      /* nudge next keys forward */
+
+	      for (; 
+		   nudge_key_item != NULL; 
+		   nudge_key_item = util_list_next(nudge_key_item)) 
+		{
+		  if (!mb_kbd_is_extended(ui->kbd) 
+		      && mb_kbd_key_get_extended(nudge_key_item->data))
+		    continue;
+
+		  mb_kbd_key_set_geometry(nudge_key_item->data,
+					  mb_kbd_key_x(nudge_key_item->data) + (new_w - old_w ), -1, -1, -1);
+		  
+		}
+	    }
+
+	}
+    next_row:
+      row_item = util_list_next(row_item);
+    }
+
+
+  /* Now center the rows */
+  
+  row_item = mb_kbd_layout_rows(layout);
+
+  while (row_item != NULL)
+    {
+      MBKeyboardRow *row = row_item->data;
+
+      mb_kbd_row_set_x(row, (max_row_width - mb_kbd_row_width(row))/2);
+
+      row_item = util_list_next(row_item);
+    }
+  
+  *width = max_row_width;
+}
+
+void
+mb_kbd_ui_redraw_key(MBKeyboardUI  *ui, MBKeyboardKey *key)
+{
+  ui->backend->redraw_key(ui, key);
+}
+
+
+static void
+mb_kbd_ui_redraw_row(MBKeyboardUI  *ui, MBKeyboardRow *row)
+{
+  List *key_item;
+
+  mb_kbd_row_for_each_key(row, key_item)
+    {
+      if (!mb_kbd_is_extended(ui->kbd) 
+	  && mb_kbd_key_get_extended(key_item->data))
+	continue;
+
+      mb_kbd_ui_redraw_key(ui, key_item->data);
+    }
+}
+
+void
+mb_kbd_ui_swap_buffers(MBKeyboardUI  *ui)
+{
+  XClearWindow(ui->xdpy, ui->xwin);
+  XSync(ui->xdpy, False);
+}
+
+void
+mb_kbd_ui_redraw(MBKeyboardUI  *ui)
+{
+  List             *row_item;
+  MBKeyboardLayout *layout;
+
+  MARK();
+
+  /* gives backend a chance to clear everything */
+  ui->backend->pre_redraw(ui);
+
+  layout = mb_kbd_get_selected_layout(ui->kbd);
+
+  row_item = mb_kbd_layout_rows(layout);
+
+  while (row_item != NULL)
+    {
+      MBKeyboardRow *row = row_item->data;
+
+      mb_kbd_ui_redraw_row(ui, row);
+
+      row_item = util_list_next(row_item);
+    }
+
+  mb_kbd_ui_swap_buffers(ui);
+}
+
+void
+mb_kbd_ui_show(MBKeyboardUI  *ui)
+{
+  XMapWindow(ui->xdpy, ui->xwin);
+}
+			  
+static int
+mb_kbd_ui_resources_create(MBKeyboardUI  *ui)
+{
+
+#define PROP_MOTIF_WM_HINTS_ELEMENTS    5
+#define MWM_HINTS_DECORATIONS          (1L << 1)
+#define MWM_DECOR_BORDER               (1L << 1)
+
+  typedef struct
+  {
+    unsigned long       flags;
+    unsigned long       functions;
+    unsigned long       decorations;
+    long                inputMode;
+    unsigned long       status;
+  } PropMotifWmHints ;
+
+
+  Atom /* atom_wm_protocols[3], */ 
+     atom_NET_WM_WINDOW_TYPE, 
+     atom_NET_WM_WINDOW_TYPE_TOOLBAR,
+     atom_NET_WM_WINDOW_TYPE_DOCK,
+     atom_NET_WM_STRUT_PARTIAL,
+     atom_NET_WM_STATE_SKIP_PAGER,
+     atom_NET_WM_STATE_SKIP_TASKBAR,
+     atom_NET_WM_STATE,
+     atom_MOTIF_WM_HINTS;
+  
+
+  PropMotifWmHints    *mwm_hints;
+  XSizeHints           size_hints;
+  XWMHints            *wm_hints;
+  XSetWindowAttributes win_attr;
+
+
+  char                *wm_name;
+  boolean              have_matchbox_wm = False;             
+  boolean              have_ewmh_wm     = False;             
+
+  /*
+  atom_wm_protocols = { 
+    XInternAtom(ui->xdpy, "WM_DELETE_WINDOW",False),
+    XInternAtom(ui->xdpy, "WM_PROTOCOLS",False),
+    XInternAtom(ui->xdpy, "WM_NORMAL_HINTS", False),
+  };
+  */
+  atom_NET_WM_WINDOW_TYPE =
+    XInternAtom(ui->xdpy, "_NET_WM_WINDOW_TYPE" , False);
+
+  atom_NET_WM_WINDOW_TYPE_TOOLBAR =
+    XInternAtom(ui->xdpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
+
+  atom_NET_WM_WINDOW_TYPE_DOCK = 
+    XInternAtom(ui->xdpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
+
+  atom_MOTIF_WM_HINTS =
+    XInternAtom(ui->xdpy, "_MOTIF_WM_HINTS", False);
+
+  atom_NET_WM_STRUT_PARTIAL = 
+    XInternAtom(ui->xdpy, "_NET_WM_STRUT_PARTIAL", False);
+
+  atom_NET_WM_STATE_SKIP_TASKBAR =
+    XInternAtom(ui->xdpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
+
+  atom_NET_WM_STATE_SKIP_PAGER = 
+    XInternAtom(ui->xdpy, "_NET_WM_STATE_SKIP_PAGER", False);
+
+  atom_NET_WM_STATE =
+    XInternAtom(ui->xdpy, "_NET_WM_STATE", False);
+
+  if ((wm_name = get_current_window_manager_name(ui)) != NULL)
+    {
+      have_ewmh_wm = True; 	/* basically assumed to be Metacity
+				   or at least only tested with mcity */
+
+      if (streq(wm_name, "matchbox"))
+	have_matchbox_wm = True;
+    }
+
+  win_attr.override_redirect = False; /* Set to true for extreme case */
+  win_attr.event_mask 
+    = ButtonPressMask|ButtonReleaseMask|Button1MotionMask|StructureNotifyMask;
+
+  ui->xwin = XCreateWindow(ui->xdpy,
+			   ui->xwin_root,
+			   0, 0,
+			   ui->xwin_width, ui->xwin_height,
+			   0,
+			   CopyFromParent, CopyFromParent, CopyFromParent,
+			   CWOverrideRedirect|CWEventMask,
+			   &win_attr);
+
+
+  wm_hints = XAllocWMHints();
+
+  if (wm_hints)
+    {
+      DBG("setting no focus hint");
+      wm_hints->input = False;
+      wm_hints->flags = InputHint;
+      XSetWMHints(ui->xdpy, ui->xwin, wm_hints );
+      XFree(wm_hints);
+    }
+
+  size_hints.flags = PPosition | PSize | PMinSize;
+  size_hints.x = 0;
+  size_hints.y = 0;
+  size_hints.width      =  ui->xwin_width; 
+  size_hints.height     =  ui->xwin_height;
+  size_hints.min_width  =  ui->xwin_width;
+  size_hints.min_height =  ui->xwin_height;
+    
+  XSetStandardProperties(ui->xdpy, ui->xwin, "Keyboard", 
+			 NULL, 0, NULL, 0, &size_hints);
+
+  if (!ui->want_embedding)
+    {
+      mwm_hints = util_malloc0(sizeof(PropMotifWmHints));
+  
+      if (mwm_hints)
+	{
+	  mwm_hints->flags = MWM_HINTS_DECORATIONS;
+	  mwm_hints->decorations = 0;
+	  
+	  XChangeProperty(ui->xdpy, ui->xwin, atom_MOTIF_WM_HINTS, 
+			  XA_ATOM, 32, PropModeReplace, 
+			  (unsigned char *)mwm_hints, 
+			  PROP_MOTIF_WM_HINTS_ELEMENTS);
+	  
+	  free(mwm_hints);
+	}
+      
+      if (have_ewmh_wm)
+	{
+	  /* XXX Fix this for display size */
+	  int wm_struct_vals[] = { 0, /* left */			
+				   0, /* right */ 
+				   0, /* top */
+				   0, /* bottom */
+				   0, /* left_start_y */
+				   0, /* left_end_y */
+				   0, /* right_start_y */
+				   0, /* right_end_y */
+				   0, /* top_start_x */
+				   0, /* top_end_x */
+				   0, /* bottom_start_x */
+				   1399 }; /* bottom_end_x */
+	  
+	  Atom states[] = { atom_NET_WM_STATE_SKIP_TASKBAR, atom_NET_WM_STATE_SKIP_PAGER };
+	  int  desk_width = 0, desk_height = 0, desk_y = 0;
+	  
+	  XChangeProperty(ui->xdpy, ui->xwin, 
+			  atom_NET_WM_STATE, XA_ATOM, 32, 
+			  PropModeReplace, 
+			  (unsigned char *)states, 2);
+	  
+	  if (get_desktop_area(ui, NULL, &desk_y, &desk_width, &desk_height))
+	    {
+	      /* Assuming we take up all available display width 
+	       * ( at least true with matchbox wm ). we resize
+	       * the base ui width to this ( and height as a factor ) 
+	       * to avoid the case of mapping and then the wm resizing
+	       * us, causing an ugly repaint. 
+	       */
+	      if (desk_width > ui->xwin_width)
+		{
+		  mb_kbd_ui_resize(ui, 
+				   desk_width, 
+				   ( desk_width * ui->xwin_height ) / ui->xwin_width);
+		}
+	      
+	      wm_struct_vals[2]  = desk_y + desk_height - ui->xwin_height;
+	      wm_struct_vals[11] = desk_width;
+	      
+	      XChangeProperty(ui->xdpy, ui->xwin, 
+			      atom_NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, 
+			      PropModeReplace, 
+			      (unsigned char *)wm_struct_vals , 12);
+	      
+	      DBG("desk width: %i, desk height: %i xwin_height :%i",
+		  desk_width, desk_height, ui->xwin_height);
+	      
+	    }
+	  
+	  if (have_matchbox_wm)
+	    {
+	      XChangeProperty(ui->xdpy, ui->xwin, 
+			      atom_NET_WM_WINDOW_TYPE, XA_ATOM, 32, 
+			      PropModeReplace, 
+			      (unsigned char *) &atom_NET_WM_WINDOW_TYPE_TOOLBAR, 1);
+	    }
+	  else
+	    {
+	      /*
+		XChangeProperty(ui->xdpy, ui->xwin, 
+		atom_NET_WM_WINDOW_TYPE, XA_ATOM, 32, 
+		PropModeReplace, 
+		(unsigned char *) &atom_NET_WM_WINDOW_TYPE_DOCK, 1);
+	      */
+	      
+	    }
+	}
+    }
+
+  ui->backbuffer = XCreatePixmap(ui->xdpy,
+				 ui->xwin,
+				 ui->xwin_width, 
+				 ui->xwin_height,
+				 DefaultDepth(ui->xdpy, ui->xscreen));
+
+
+  XSetWindowBackgroundPixmap(ui->xdpy,
+			     ui->xwin, 
+			     ui->backbuffer);
+
+  ui->backend->resources_create(ui);
+
+
+  /* Get root size change events for rotation */
+
+  /* XSelectInput(ui->xdpy, ui->xwin_root, StructureNotifyMask); */
+
+  return 1;
+}
+
+static void
+mb_kbd_ui_resize(MBKeyboardUI *ui, int width, int height) 
+{
+  MBKeyboard       *kbd = ui->kbd;
+  MBKeyboardLayout *layout;
+  List              *row_item, *key_item;
+  int               width_diff, height_diff;
+  int               height_font_pt_size, width_font_pt_size;
+  int               next_row_y,  n_rows, extra_key_height;
+
+  MARK();
+
+  width_diff  = width  - ui->base_alloc_width; 
+  height_diff = height - ui->base_alloc_height; 
+
+  if (width_diff < 0 || height_diff < 0)
+    return;  /* dont go smaller than our int request - get clipped */
+
+  layout   = mb_kbd_get_selected_layout(ui->kbd);
+  row_item = mb_kbd_layout_rows(layout);
+
+  /* load a bigger font ? 
+   * Only load if height and width have changed
+   */
+
+  width_font_pt_size = ( (ui->base_font_pt_size * width) 
+		               / ui->base_alloc_width );
+  
+  if (util_abs(width_font_pt_size - kbd->font_pt_size) > 2)
+    {
+      height_font_pt_size = ( (ui->base_font_pt_size * height) 
+			         / ui->base_alloc_height );
+
+      if (util_abs(height_font_pt_size - kbd->font_pt_size) > 2)
+	{
+	  ui->kbd->font_pt_size = (height_font_pt_size > width_font_pt_size) 
+                 	       ? width_font_pt_size : height_font_pt_size;
+
+	  mb_kbd_ui_load_font(ui);
+	}
+    }
+
+  n_rows = util_list_length(row_item);
+
+  extra_key_height = (height_diff / n_rows);
+
+  DBG("****** extra height is %i ******", extra_key_height);
+
+  next_row_y = mb_kbd_row_spacing(ui->kbd);
+
+  /* allocate the extra width we have as padding to keys */
+
+  while (row_item != NULL)
+    {
+      int row_base_width, new_row_base_width, row_width_diff;
+      int  next_key_x = 0,  n_fillers  = 0, free_space = 0, new_w = 0;
+
+      row_base_width = mb_kbd_row_base_width(row_item->data);
+
+      new_row_base_width = ( row_base_width * width ) / ui->base_alloc_width;
+
+      row_width_diff = new_row_base_width - row_base_width;
+
+      DBG("row_width_diff = %i", row_width_diff);
+
+      next_key_x = mb_kbd_col_spacing(ui->kbd);
+
+      /* 
+       * row_base_width       
+       * --------------  X  new_width  = new_base_width
+       *   base_width      
+       *
+       * key_extra_pad  = key_base_width X base_width_diff 
+       *                  --------------------------------
+       *                          row_base_width
+      */
+
+      mb_kbd_row_for_each_key(row_item->data, key_item)
+	{
+	  MBKeyboardKey *key = key_item->data;
+	  int            key_base_width, key_new_pad;
+
+	  if (!mb_kbd_is_extended(kbd) && mb_kbd_key_get_extended(key))
+	    continue;
+
+	  key_base_width =( mb_kbd_key_width(key) 
+			    - mb_kbd_key_get_extra_width_pad(key));
+
+	  key_new_pad= ( (key_base_width + mb_kbd_col_spacing(kbd)) * row_width_diff) / row_base_width; 
+                             
+	  mb_kbd_key_set_extra_width_pad (key, key_new_pad );
+
+	  /* Height */
+
+	  mb_kbd_key_set_extra_height_pad (key, extra_key_height);
+
+	  mb_kbd_key_set_geometry(key, next_key_x, -1, -1, -1);
+
+	  next_key_x += (mb_kbd_key_width(key) + mb_kbd_col_spacing(ui->kbd)); 
+
+	  if (mb_kbd_key_get_fill(key))
+	      n_fillers++;
+	}
+
+      /* The above ( likely due to rounding ) leaves a few pixels free. 
+       * This can be critical on a small handheld display. Therefore 
+       * we do a second parse deviding up any left over space between
+       * keys marked as fill. 
+      */
+
+      if (n_fillers)
+	{
+	  free_space = width - mb_kbd_row_width(row_item->data);
+
+	  mb_kbd_row_for_each_key(row_item->data, key_item)
+	    {
+	      if (!mb_kbd_is_extended(kbd) 
+		  && mb_kbd_key_get_extended(key_item->data))
+		continue;
+
+	      if (mb_kbd_key_get_fill(key_item->data))
+		{
+		  int   old_w;
+		  List *nudge_key_item = util_list_next(key_item);
+		  
+		  old_w = mb_kbd_key_width(key_item->data);
+		  new_w = old_w + (free_space/n_fillers);
+		  
+		  mb_kbd_key_set_geometry(key_item->data, -1, -1, new_w, -1);
+		  
+		  /* nudge next keys forward */
+
+		  for (; 
+		       nudge_key_item != NULL; 
+		       nudge_key_item = util_list_next(nudge_key_item)) 
+		    {
+		      if (!mb_kbd_is_extended(ui->kbd) 
+			  && mb_kbd_key_get_extended(nudge_key_item->data))
+			continue;
+
+		      mb_kbd_key_set_geometry(nudge_key_item->data,
+					      mb_kbd_key_x(nudge_key_item->data) + (new_w - old_w ), -1, -1, -1);
+
+		    }
+		}
+
+	    }
+	}
+
+
+      /* re-center row */
+
+      mb_kbd_row_set_x(row_item->data, 
+		       (width - mb_kbd_row_width(row_item->data))/2);
+
+      /* and position down */
+
+      mb_kbd_row_set_y(row_item->data, next_row_y);
+
+      next_row_y  += (mb_kbd_row_height(row_item->data) 
+		      + mb_kbd_row_spacing(ui->kbd));
+
+      row_item = util_list_next(row_item);
+    }
+
+  /* center entire layout vertically if space left */
+
+  if (next_row_y < height)
+    {
+      int vspace = ( height - next_row_y ) / 2;
+
+      row_item = mb_kbd_layout_rows(layout);
+
+      while (row_item != NULL)
+	{
+	  mb_kbd_row_set_y(row_item->data, 
+			   mb_kbd_row_y(row_item->data) + vspace + 1);
+
+	  row_item = util_list_next(row_item);
+	}
+    }
+
+  XResizeWindow(ui->xdpy, ui->xwin, width, height);
+
+  ui->xwin_width  = width;
+  ui->xwin_height = height;
+
+
+  if (ui->backbuffer) /* may get called before initialised */
+    {
+      XFreePixmap(ui->xdpy, ui->backbuffer);
+      ui->backbuffer = XCreatePixmap(ui->xdpy,
+				     ui->xwin,
+				     ui->xwin_width, 
+				     ui->xwin_height,
+				     DefaultDepth(ui->xdpy, ui->xscreen));
+
+      ui->backend->resize(ui, width, height);
+
+      XSetWindowBackgroundPixmap(ui->xdpy, ui->xwin, ui->backbuffer);
+
+      mb_kbd_ui_redraw(ui);
+    }
+
+
+}
+
+void
+mb_kbd_ui_handle_configure(MBKeyboardUI *ui,
+			   int           width,
+			   int           height)
+{
+  boolean old_state, new_state;
+
+  MARK();
+
+  /* Figure out if screen size has changed - does a round trip - bad */
+
+  update_display_size(ui);
+
+  old_state = mb_kbd_is_extended(ui->kbd);
+  new_state = want_extended(ui);
+   
+  if (new_state == old_state) 	/* Not a rotation */
+    {
+      mb_kbd_ui_resize(ui, width, height); 
+      return;
+    }
+
+  mb_kbd_set_extended(ui->kbd, new_state);
+
+  /* realocate the layout */
+
+  mb_kbd_ui_allocate_ui_layout(ui, 
+			       &ui->base_alloc_width, &ui->base_alloc_height);
+
+  mb_kbd_ui_resize(ui, width, height); 
+
+}
+
+void
+mb_kbd_ui_event_loop(MBKeyboardUI *ui)
+{
+  MBKeyboardKey *key = NULL;
+  struct timeval tvt;
+
+  /* Key repeat - values for standard xorg install ( xset q) */
+  int repeat_delay = 100 * 10000;
+  int repeat_rate  = 30  * 1000;
+
+  int press_x = 0, press_y = 0; 
+
+  tvt.tv_sec  = 0;
+  tvt.tv_usec = repeat_delay;
+
+  while (True)
+      {
+	XEvent xev;
+
+	if (get_xevent_timed(ui->xdpy, &xev, &tvt))
+	  {
+	    switch (xev.type) 
+	      {
+	      case ButtonPress:
+		press_x = xev.xbutton.x; press_y = xev.xbutton.y;
+		DBG("got button bress at %i,%i", xev.xbutton.x, xev.xbutton.y);
+		key = mb_kbd_locate_key(ui->kbd, xev.xbutton.x, xev.xbutton.y);
+		if (key)
+		  {
+		    /* Hack if we never get a release event */
+		    if (key != mb_kbd_get_held_key(ui->kbd))
+		      {
+			mb_kbd_key_release(ui->kbd);
+			tvt.tv_usec = repeat_delay;   
+		      }
+		    else
+		      tvt.tv_usec = repeat_rate;
+
+		    DBG("found key for press");
+		    mb_kbd_key_press(key);
+
+		  }
+		break;
+	      case ButtonRelease:
+		if (mb_kbd_get_held_key(ui->kbd) != NULL)
+		  {
+		    mb_kbd_key_release(ui->kbd);	 
+		    tvt.tv_usec = repeat_delay;
+
+		    /* Gestures */
+
+		    /* FIXME: check time first */
+		    if ( (press_x - xev.xbutton.x) > ui->key_uwidth )
+		      {
+			/* <-- slide back ...backspace */
+			fakekey_press_keysym(ui->fakekey, XK_BackSpace, 0);
+			fakekey_repeat(ui->fakekey);
+			fakekey_release(ui->fakekey);
+			/* FIXME: add <-- --> <-- --> support */
+		      }
+		    else if ( (xev.xbutton.y - press_y) > ui->key_uheight )
+		      {
+			/* V slide down ...return  */
+			fakekey_press_keysym(ui->fakekey, XK_BackSpace, 0);
+			fakekey_release(ui->fakekey);
+			fakekey_press_keysym(ui->fakekey, XK_Return, 0);
+			fakekey_release(ui->fakekey);
+		      }
+		    /* TODO ^ caps support */
+
+		  }
+		break;
+	      case ConfigureNotify:
+		if (xev.xconfigure.width != ui->xwin_width
+		    || xev.xconfigure.height != ui->xwin_height)
+		  mb_kbd_ui_handle_configure(ui,
+					     xev.xconfigure.width,
+					     xev.xconfigure.height);
+		break;
+	      case MappingNotify: 
+		fakekey_reload_keysyms(ui->fakekey);
+		XRefreshKeyboardMapping(&xev.xmapping);
+		break;
+	      default:
+		break;
+	      }
+	    if (ui->want_embedding)
+	      mb_kbd_xembed_process_xevents (ui, &xev);
+	  }
+	else
+	  {
+	    /* Keyrepeat */
+	    if (mb_kbd_get_held_key(ui->kbd) != NULL)
+	      {
+		fakekey_repeat(ui->fakekey);
+		tvt.tv_usec = repeat_rate;
+	      }
+	  }
+      }
+}
+
+static int
+mb_kbd_ui_load_font(MBKeyboardUI *ui)
+{
+  return ui->backend->font_load(ui);
+}
+
+
+int
+mb_kbd_ui_display_width(MBKeyboardUI *ui)
+{
+  return ui->dpy_width;
+}
+
+int
+mb_kbd_ui_display_height(MBKeyboardUI *ui)
+{
+  return ui->dpy_height;
+}
+
+MBKeyboardUIBackend*
+mb_kbd_ui_backend(MBKeyboardUI *ui)
+{
+  return ui->backend;
+}
+
+Display*
+mb_kbd_ui_x_display(MBKeyboardUI *ui)
+{
+  return ui->xdpy;
+}
+
+int
+mb_kbd_ui_x_screen(MBKeyboardUI *ui)
+{
+  return ui->xscreen;
+}
+
+Window
+mb_kbd_ui_x_win(MBKeyboardUI *ui)
+{
+  return ui->xwin;
+}
+
+Window
+mb_kbd_ui_x_win_root(MBKeyboardUI *ui)
+{
+  return ui->xwin_root;
+}
+
+int
+mb_kbd_ui_x_win_height(MBKeyboardUI *ui)
+{
+  return ui->xwin_height;
+}
+
+int
+mb_kbd_ui_x_win_width(MBKeyboardUI *ui)
+{
+  return ui->xwin_width;
+}
+
+
+Pixmap
+mb_kbd_ui_backbuffer(MBKeyboardUI *ui)
+{
+  return ui->backbuffer;
+}
+
+MBKeyboard*
+mb_kbd_ui_kbd(MBKeyboardUI *ui)
+{
+  return ui->kbd;
+}
+
+
+int
+mb_kbd_ui_realize(MBKeyboardUI *ui)
+{
+  ui->base_font_pt_size = ui->kbd->font_pt_size;
+
+  if (!mb_kbd_ui_load_font(ui))
+    return 0;
+
+  /* potrait or landscape */
+  if (want_extended(ui))
+    mb_kbd_set_extended(ui->kbd, True);
+
+  /* 
+   * figure out how small this keyboard can be..
+  */
+  mb_kbd_ui_allocate_ui_layout(ui, 
+			       &ui->base_alloc_width, &ui->base_alloc_height);
+
+  ui->xwin_width  = ui->base_alloc_width;
+  ui->xwin_height = ui->base_alloc_height;
+
+  mb_kbd_ui_resources_create(ui);
+
+  unless (mb_kbd_ui_embeded(ui))
+    {
+      mb_kbd_ui_show(ui);
+      mb_kbd_ui_redraw(ui);
+    }
+  else
+    mb_kbd_xembed_init (ui);
+
+  return 1;
+}
+
+int
+mb_kbd_ui_init(MBKeyboard *kbd)
+{
+  MBKeyboardUI     *ui = NULL;
+  
+  ui = kbd->ui = util_malloc0(sizeof(MBKeyboardUI));
+  
+  ui->kbd = kbd;
+
+  if ((ui->xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+    return 0;
+
+  if ((ui->fakekey = fakekey_init(ui->xdpy)) == NULL)
+    return 0;
+
+  ui->xscreen   = DefaultScreen(ui->xdpy);
+  ui->xwin_root = RootWindow(ui->xdpy, ui->xscreen);   
+
+  ui->backend = MB_KBD_UI_BACKEND_INIT_FUNC(ui);
+
+  update_display_size(ui);
+
+  return 1;
+}
+
+/* Embedding */
+
+void
+mb_kbd_ui_set_embeded (MBKeyboardUI *ui, int embed)
+{
+  ui->want_embedding = embed;
+}
+ 
+int
+mb_kbd_ui_embeded (MBKeyboardUI *ui)
+{
+  return ui->want_embedding;
+}
+
+void
+mb_kbd_ui_print_window (MBKeyboardUI *ui)
+{
+  fprintf(stdout, "%li\n", mb_kbd_ui_x_win(ui));
+  fflush(stdout);
+}

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-xembed.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-xembed.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard-xembed.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,172 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+#define MAX_SUPPORTED_XEMBED_VERSION   1
+
+#define XEMBED_MAPPED          (1 << 0)
+
+/* XEMBED messages */
+#define XEMBED_EMBEDDED_NOTIFY          0
+#define XEMBED_WINDOW_ACTIVATE          1
+#define XEMBED_WINDOW_DEACTIVATE        2
+#define XEMBED_REQUEST_FOCUS            3
+#define XEMBED_FOCUS_IN                 4
+#define XEMBED_FOCUS_OUT                5
+#define XEMBED_FOCUS_NEXT               6
+#define XEMBED_FOCUS_PREV               7
+/* 8-9 were used for XEMBED_GRAB_KEY/XEMBED_UNGRAB_KEY */
+#define XEMBED_MODALITY_ON              10
+#define XEMBED_MODALITY_OFF             11
+#define XEMBED_REGISTER_ACCELERATOR     12
+#define XEMBED_UNREGISTER_ACCELERATOR   13
+#define XEMBED_ACTIVATE_ACCELERATOR     14
+
+static Atom Atom_XEMBED; /* FIXME: put array of atoms in UI struct  */
+static Window ParentEmbedderWin = None;
+
+static void
+mb_kbd_xembed_set_win_info (MBKeyboardUI *ui, int flags)
+{
+   CARD32 list[2];
+
+   Atom atom_ATOM_XEMBED_INFO;
+
+   atom_ATOM_XEMBED_INFO 
+     = XInternAtom(mb_kbd_ui_x_display(ui), "_XEMBED_INFO", False);
+
+
+   list[0] = MAX_SUPPORTED_XEMBED_VERSION;
+   list[1] = flags;
+   XChangeProperty (mb_kbd_ui_x_display(ui), 
+		    mb_kbd_ui_x_win(ui), 
+		    atom_ATOM_XEMBED_INFO,
+		    atom_ATOM_XEMBED_INFO, 32,
+		    PropModeReplace, (unsigned char *) list, 2);
+}
+
+static Bool
+mb_kbd_xembed_send_message (MBKeyboardUI *ui,
+			    Window        w,
+			    long          message,
+			    long          detail,
+			    long          data1, 
+			    long          data2)
+{
+  XEvent ev;
+
+  memset(&ev, 0, sizeof(ev));
+
+  ev.xclient.type = ClientMessage;
+  ev.xclient.window = w;
+  ev.xclient.message_type = Atom_XEMBED;
+  ev.xclient.format = 32;
+  ev.xclient.data.l[0] = CurrentTime; /* FIXME: Is this correct */
+  ev.xclient.data.l[1] = message;
+  ev.xclient.data.l[2] = detail;
+  ev.xclient.data.l[3] = data1;
+  ev.xclient.data.l[4] = data2;
+
+  util_trap_x_errors();
+
+  XSendEvent(mb_kbd_ui_x_display(ui), w, False, NoEventMask, &ev);
+  XSync(mb_kbd_ui_x_display(ui), False);
+
+  if (util_untrap_x_errors()) 
+    return False;
+
+  return True;
+}
+
+void
+mb_kbd_xembed_init (MBKeyboardUI *ui)
+{
+  /* FIXME: Urg global  */
+  Atom_XEMBED = XInternAtom(mb_kbd_ui_x_display(ui), "_XEMBED", False);
+
+  mb_kbd_xembed_set_win_info (ui, 0);
+}
+
+void
+mb_kbd_xembed_process_xevents (MBKeyboardUI *ui, XEvent *xevent)
+{
+
+  switch (xevent->type)
+    {
+    case MapNotify:
+      DBG("### got Mapped ###");
+      break;
+    case ClientMessage:
+      if (xevent->xclient.message_type == Atom_XEMBED)
+	{
+	  switch (xevent->xclient.data.l[1])
+	    {
+	    case XEMBED_EMBEDDED_NOTIFY:
+	      /* We are now reparented. Call the repaint. 
+               * note, 'data1' ( see spec ) is is embedders window
+	      */
+	      DBG("### got XEMBED_EMBEDDED_NOTIFY ###");
+	      ParentEmbedderWin = xevent->xclient.data.l[3];
+
+	      /* FIXME: we really want to know what our final
+               *        size will be before mapping as this can
+               *        look ugly when window is mapped then a 
+               *        load of resizes.
+               *        Maybe fixible in GTK calling code ?
+	      */ 
+
+	      mb_kbd_ui_redraw(ui);	      
+
+	      XSync(mb_kbd_ui_x_display(ui), False);
+
+	      /* And please Map us */
+
+
+
+	      mb_kbd_xembed_set_win_info (ui, XEMBED_MAPPED);
+
+	      break;
+	    case XEMBED_WINDOW_ACTIVATE:
+	      /* FIXME: What to do here */
+	      DBG("### got XEMBED_WINDOW_ACTIVATE ###");
+	      break;
+	    case XEMBED_WINDOW_DEACTIVATE:
+	      /* FIXME: What to do here ? unmap or exit */
+	      DBG("### got XEMBED_WINDOW_DEACTIVATE ###");
+	      break;
+	    case XEMBED_FOCUS_IN:
+	      DBG("### got XEMBED_FOCUS_IN ###");
+	      /* 
+               * Please never give us key focus...
+	      */
+	      if (ParentEmbedderWin)
+		mb_kbd_xembed_send_message (ui,
+					    ParentEmbedderWin,
+					    XEMBED_FOCUS_NEXT,
+					    0, 0, 0);
+	      break
+;	      /* TODO: Modility + rest of spec ? */
+	    }
+	}
+    }
+
+  /* FIXME: Handle case of Embedder dieing ( Xfixes call ) ? */
+
+}

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,288 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "matchbox-keyboard.h"
+
+static void
+mb_kbd_usage (char *progname)
+{
+  fprintf(stderr, "Usage:\n   %s [Options ] [ Layout Variant ]\n", progname);
+  fprintf(stderr, "\nOptions are;\n"
+	  "   -xid,--xid            Print window ID to stdout ( for embedding )\n");
+  fprintf(stderr, "\nmatchbox-keyboard %s \nCopyright (C) 2005 Matthew Allum, OpenedHand Ltd.\n", VERSION);
+
+  exit(-1);
+}
+
+MBKeyboard*
+mb_kbd_new (int argc, char **argv)
+{
+  MBKeyboard *kb = NULL;
+  char       *variant = NULL; 
+  Bool        want_embedding = False;
+  int         i;
+
+  kb = util_malloc0(sizeof(MBKeyboard));
+
+  kb->key_border = 1;
+  kb->key_pad    = 2;
+  kb->key_margin = 0;
+
+  kb->col_spacing = 5;
+  kb->row_spacing = 5;
+
+  kb->font_family  = strdup("sans");
+  kb->font_pt_size = 5;
+  kb->font_variant = strdup("bold");
+
+  for (i = 1; i < argc; i++) 
+    {
+      if (streq ("-xid", argv[i]) || streq ("--xid", argv[i])) 
+	{
+	  want_embedding = True;
+	  continue;
+	}
+
+      if (i == (argc-1) && argv[i][0] != '-')
+	variant = argv[i];
+      else
+	mb_kbd_usage(argv[0]);
+    }
+
+  if (variant == NULL)
+    variant = getenv("MB_KBD_VARIANT");
+
+  if (!mb_kbd_ui_init(kb))
+    return NULL;
+
+  if (mb_kbd_ui_display_width(kb->ui) <= 320) 
+    {
+      kb->key_border   = 1;
+      kb->key_pad      = 0;
+      kb->col_spacing  = 0;
+      kb->row_spacing  = 0;
+      kb->font_pt_size = 8;
+    }
+
+  if (!mb_kbd_config_load(kb, variant))
+    return NULL;
+
+  kb->selected_layout 
+    = (MBKeyboardLayout *)util_list_get_nth_data(kb->layouts, 0);
+
+  if (want_embedding)
+    mb_kbd_ui_set_embeded( kb->ui, True );
+
+  if (!mb_kbd_ui_realize(kb->ui))
+    return NULL;
+
+  if (want_embedding)
+    mb_kbd_ui_print_window( kb->ui );
+
+  return kb;
+}
+
+int
+mb_kbd_row_spacing(MBKeyboard *kb)
+{
+  return kb->row_spacing;
+}
+
+int
+mb_kbd_col_spacing(MBKeyboard *kb)
+{
+  return kb->col_spacing;
+}
+
+int
+mb_kbd_keys_border(MBKeyboard *kb)
+{
+  return kb->key_border;
+}
+
+int
+mb_kbd_keys_pad(MBKeyboard *kb)
+{
+  return kb->key_pad;
+}
+
+int
+mb_kbd_keys_margin(MBKeyboard *kb)
+{
+  return kb->key_margin;
+}
+
+void
+mb_kbd_add_state(MBKeyboard *kbd, MBKeyboardStateType state)
+{
+  kbd->keys_state |= state;
+}
+
+void
+mb_kbd_toggle_state(MBKeyboard *kbd, MBKeyboardStateType state)
+{
+  kbd->keys_state ^= state;
+}
+
+boolean
+mb_kbd_has_state(MBKeyboard *kbd, MBKeyboardStateType state)
+{
+  return (kbd->keys_state & state);
+}
+
+boolean
+mb_kbd_has_any_state(MBKeyboard *kbd)
+{
+  return  (kbd->keys_state > 0);
+}
+
+void
+mb_kbd_remove_state(MBKeyboard *kbd, MBKeyboardStateType state)
+{
+  kbd->keys_state &= ~(state);
+}
+
+MBKeyboardKeyStateType
+mb_kbd_keys_current_state(MBKeyboard *kbd)
+{
+  if (mb_kbd_has_state(kbd, MBKeyboardStateShifted))
+    return MBKeyboardKeyStateShifted;
+
+  if (mb_kbd_has_state(kbd, MBKeyboardStateMod1))
+    return MBKeyboardKeyStateMod1;
+
+  if (mb_kbd_has_state(kbd, MBKeyboardStateMod2))
+    return MBKeyboardKeyStateMod2;
+  
+  if (mb_kbd_has_state(kbd, MBKeyboardStateMod3))
+    return MBKeyboardKeyStateMod3;
+  
+  return MBKeyboardKeyStateNormal;
+}
+
+void
+mb_kbd_redraw(MBKeyboard *kb)
+{
+  mb_kbd_ui_redraw(kb->ui);
+}
+
+void
+mb_kbd_redraw_key(MBKeyboard *kb, MBKeyboardKey *key)
+{
+  mb_kbd_ui_redraw_key(kb->ui, key);
+  mb_kbd_ui_swap_buffers(kb->ui);
+}
+
+MBKeyboardKey*
+mb_kbd_locate_key(MBKeyboard *kb, int x, int y)
+{
+  MBKeyboardLayout *layout;
+  List             *row_item, *key_item;
+
+  layout = mb_kbd_get_selected_layout(kb);
+
+  row_item = mb_kbd_layout_rows(layout);
+
+  while (row_item != NULL)
+    {
+      MBKeyboardRow *row = row_item->data;
+
+      if (x >= mb_kbd_row_x(row) 
+	  && x <= mb_kbd_row_x(row) + mb_kbd_row_width(row) 
+	  && y >= mb_kbd_row_y(row)
+	  && y <= mb_kbd_row_y(row) + mb_kbd_row_height(row) )
+	{
+	  mb_kbd_row_for_each_key(row, key_item) 
+	    {
+	      MBKeyboardKey *key = key_item->data;
+
+	      if (!mb_kbd_is_extended(kb) 
+		      && mb_kbd_key_get_extended(key))
+		continue;
+
+	      if (!mb_kbd_key_is_blank(key)
+		  && x >= mb_kbd_key_abs_x(key)
+		  && x <= mb_kbd_key_abs_x(key) + mb_kbd_key_width(key))
+		return key;
+
+	    }
+	 
+	  return NULL;
+	}
+
+      row_item = util_list_next(row_item);
+    }
+  return NULL;
+}
+
+void
+mb_kbd_add_layout(MBKeyboard *kb, MBKeyboardLayout *layout)
+{
+  kb->layouts = util_list_append(kb->layouts, (pointer)layout);
+}
+
+MBKeyboardLayout*
+mb_kbd_get_selected_layout(MBKeyboard *kb)
+{
+  return kb->selected_layout;
+}
+
+void
+mb_kbd_set_held_key(MBKeyboard *kb, MBKeyboardKey *key)
+{
+  kb->held_key = key;
+}
+
+MBKeyboardKey *
+mb_kbd_get_held_key(MBKeyboard *kb)
+{
+  return kb->held_key;
+}
+
+void
+mb_kbd_set_extended(MBKeyboard *kb, boolean extend)
+{
+  kb->extended = extend;
+}
+
+boolean
+mb_kbd_is_extended(MBKeyboard *kb)
+{
+  return kb->extended;
+}
+
+
+void
+mb_kbd_run(MBKeyboard *kb)
+{
+  mb_kbd_ui_event_loop(kb->ui);
+}
+
+
+int 
+main(int argc, char **argv)
+{
+  MBKeyboard *kb;
+
+  kb = mb_kbd_new(argc, argv);
+
+  if (kb) mb_kbd_run(kb);
+
+  return 0;
+}

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.h
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.h	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/matchbox-keyboard.h	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,598 @@
+/* 
+ *  Matchbox Keyboard - A lightweight software keyboard.
+ *
+ *  Authored By Matthew Allum <mallum at o-hand.com>
+ *
+ *  Copyright (c) 2005 OpenedHand Ltd - http://o-hand.com
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#ifndef HAVE_MB_KEYBOARD_H
+#define HAVE_MB_KEYBOARD_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include <png.h>
+
+#include <locale.h>
+
+#include <expat.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xresource.h>
+#include <X11/keysym.h>
+
+#include <fakekey/fakekey.h>
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if (WANT_DEBUG)
+#define DBG(x, a...) \
+ fprintf (stderr,  __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
+#else
+#define DBG(x, a...) do {} while (0)
+#endif
+
+#define MARK() DBG("mark")
+
+typedef void*         pointer;
+typedef unsigned char uchar ;
+typedef Bool          boolean ;
+
+typedef struct Pixbuf Pixbuf;
+typedef struct List List;
+
+typedef void (*ListForEachCB) (void *data, void *userdata);
+
+struct List 
+{
+  List *next, *prev;
+  void *data;
+};
+
+typedef struct MBKeyboard       MBKeyboard;
+typedef struct MBKeyboardLayout MBKeyboardLayout;
+typedef struct MBKeyboardRow    MBKeyboardRow;
+typedef struct MBKeyboardKey    MBKeyboardKey;
+typedef struct MBKeyboardUI     MBKeyboardUI;
+typedef struct MBKeyboardUIBackend MBKeyboardUIBackend;
+typedef struct MBKeyboardImage  MBKeyboardImage;
+
+typedef enum 
+{
+  MBKeyboardKeyActionNone  = 0,
+  MBKeyboardKeyActionGlyph,
+  MBKeyboardKeyActionXKeySym, 	/* 'specials' be converted into this */
+  MBKeyboardKeyActionModifier,
+
+} MBKeyboardKeyActionType;
+
+typedef enum 
+{
+  MBKeyboardKeyModUnknown,
+  MBKeyboardKeyModShift,
+  MBKeyboardKeyModMod1,
+  MBKeyboardKeyModMod2,
+  MBKeyboardKeyModMod3,
+  MBKeyboardKeyModCaps,
+  MBKeyboardKeyModControl,
+  MBKeyboardKeyModAlt,
+  MBKeyboardKeyModLayout
+
+} MBKeyboardKeyModType;
+
+typedef enum 
+{
+  MBKeyboardKeyFaceNone  = 0,
+  MBKeyboardKeyFaceGlyph = 1,
+  MBKeyboardKeyFaceImage = 2,
+
+} MBKeyboardKeyFaceType;
+
+typedef enum 
+{
+  MBKeyboardKeyStateNormal = 0,
+  MBKeyboardKeyStateShifted,
+  MBKeyboardKeyStateMod1,
+  MBKeyboardKeyStateMod2,
+  MBKeyboardKeyStateMod3,
+  N_MBKeyboardKeyStateTypes
+} 
+MBKeyboardKeyStateType;
+
+typedef enum 
+{
+  MBKeyboardStateNormal = 0,
+  MBKeyboardStateShifted = (1<<1),
+  MBKeyboardStateMod1    = (1<<2),
+  MBKeyboardStateMod2    = (1<<3),
+  MBKeyboardStateMod3    = (1<<4),
+  MBKeyboardStateCaps    = (1<<5),
+  MBKeyboardStateControl = (1<<6),
+  MBKeyboardStateAlt     = (1<<7),
+  N_MBKeyboardStateTypes
+} 
+MBKeyboardStateType;
+
+
+struct MBKeyboard
+{
+  MBKeyboardUI          *ui;
+  char                  *font_family;
+  int                    font_pt_size;
+  char                  *font_variant;
+
+  char                  *config_file;
+
+  List                  *layouts;
+  MBKeyboardLayout      *selected_layout;
+
+  int                    key_border, key_pad, key_margin;
+  int                    row_spacing, col_spacing;
+
+  boolean                extended; /* are we showing extended keys ? */
+
+  MBKeyboardKey         *held_key;
+  MBKeyboardStateType    keys_state;
+};
+
+/**** UI ***********/
+
+struct MBKeyboardUIBackend
+{
+  MBKeyboardUIBackend*  (*init) (MBKeyboardUI *ui);
+  int  (*font_load) (MBKeyboardUI  *ui);
+  void (*redraw_key) (MBKeyboardUI  *ui, MBKeyboardKey *key);
+  void (*pre_redraw) (MBKeyboardUI  *ui);
+  int  (*resources_create) (MBKeyboardUI  *ui);
+  int  (*resize) (MBKeyboardUI  *ui, int width, int height);
+  void  (*text_extents) (MBKeyboardUI  *ui, 
+			 const char    *str, 
+			 int           *width, 
+			 int           *height);
+};
+
+int
+mb_kbd_ui_init(MBKeyboard *kbd);
+
+int
+mb_kbd_ui_realize(MBKeyboardUI  *ui);
+
+void
+mb_kbd_ui_show(MBKeyboardUI  *ui);
+
+void
+mb_kbd_ui_redraw_key(MBKeyboardUI  *ui, MBKeyboardKey *key);
+
+void
+mb_kbd_ui_redraw(MBKeyboardUI  *ui);
+
+void
+mb_kbd_ui_swap_buffers(MBKeyboardUI  *ui);
+
+void
+mb_kbd_ui_send_press(MBKeyboardUI        *ui,
+		     const char          *utf8_char_in,
+		     int                  modifiers);
+
+void
+mb_kbd_ui_send_keysym_press(MBKeyboardUI  *ui,
+			    KeySym         ks,
+			    int            modifiers);
+
+void
+mb_kbd_ui_send_release(MBKeyboardUI  *ui);
+
+int
+mb_kbd_ui_display_width(MBKeyboardUI *ui);
+
+int
+mb_kbd_ui_display_height(MBKeyboardUI *ui);
+
+MBKeyboardUIBackend*
+mb_kbd_ui_backend(MBKeyboardUI *ui);
+
+Display*
+mb_kbd_ui_x_display(MBKeyboardUI *ui);
+
+int
+mb_kbd_ui_x_screen(MBKeyboardUI *ui);
+
+Window
+mb_kbd_ui_x_win(MBKeyboardUI *ui);
+
+int
+mb_kbd_ui_x_win_height(MBKeyboardUI *ui);
+
+int
+mb_kbd_ui_x_win_width(MBKeyboardUI *ui);
+
+Window
+mb_kbd_ui_x_win_root(MBKeyboardUI *ui);
+
+Pixmap
+mb_kbd_ui_backbuffer(MBKeyboardUI *ui);
+
+MBKeyboard*
+mb_kbd_ui_kbd(MBKeyboardUI *ui);
+
+void
+mb_kbd_ui_event_loop(MBKeyboardUI *ui);
+
+void
+mb_kbd_ui_set_embeded (MBKeyboardUI *ui, int embed);
+ 
+int
+mb_kbd_ui_embeded (MBKeyboardUI *ui);
+
+void
+mb_kbd_ui_print_window (MBKeyboardUI *ui);
+
+/*** Images ***/
+
+MBKeyboardImage*
+mb_kbd_image_new (MBKeyboard *kbd, const char *filename);
+
+int
+mb_kbd_image_width (MBKeyboardImage *img);
+
+int
+mb_kbd_image_height (MBKeyboardImage *img);
+
+void
+mb_kbd_image_destroy (MBKeyboardImage *img);
+
+/*** XEmbed ***/
+
+void
+mb_kbd_xembed_init (MBKeyboardUI *ui);
+
+void
+mb_kbd_xembed_process_xevents (MBKeyboardUI *ui, XEvent *xevent);
+
+/**** Keyboard ****/
+
+int
+mb_kbd_row_spacing(MBKeyboard *kb);
+
+int
+mb_kbd_col_spacing(MBKeyboard *kb);
+
+int
+mb_kbd_keys_border(MBKeyboard *kb);
+
+int
+mb_kbd_keys_pad(MBKeyboard *kb);
+
+int
+mb_kbd_keys_margin(MBKeyboard *kb);
+
+void
+mb_kbd_add_state(MBKeyboard *kbd, MBKeyboardStateType state);
+
+void
+mb_kbd_toggle_state(MBKeyboard *kbd, MBKeyboardStateType state);
+
+boolean
+mb_kbd_has_state(MBKeyboard *kbd, MBKeyboardStateType state);
+
+boolean
+mb_kbd_has_any_state(MBKeyboard *kbd);
+
+void
+mb_kbd_remove_state(MBKeyboard *kbd, MBKeyboardStateType state);
+
+MBKeyboardKeyStateType
+mb_kbd_keys_current_state(MBKeyboard *kbd);
+
+void
+mb_kbd_set_extended(MBKeyboard *kb, boolean extend);
+
+boolean
+mb_kbd_is_extended(MBKeyboard *kb);
+
+void
+mb_kbd_add_layout(MBKeyboard *kb, MBKeyboardLayout *layout);
+
+MBKeyboardLayout*
+mb_kbd_get_selected_layout(MBKeyboard *kb);
+
+MBKeyboardKey*
+mb_kbd_locate_key(MBKeyboard *kb, int x, int y);
+
+void
+mb_kbd_set_held_key(MBKeyboard *kb, MBKeyboardKey *key);
+
+MBKeyboardKey *
+mb_kbd_get_held_key(MBKeyboard *kb);
+
+void
+mb_kbd_redraw(MBKeyboard *kb);
+
+void
+mb_kbd_redraw_key(MBKeyboard *kb, MBKeyboardKey *key);
+
+
+/**** Layout ****/
+
+MBKeyboardLayout*
+mb_kbd_layout_new(MBKeyboard *kbd, const char *id);
+
+void
+mb_kbd_layout_append_row(MBKeyboardLayout *layout,
+			 MBKeyboardRow    *row);
+
+List*
+mb_kbd_layout_rows(MBKeyboardLayout *layout);
+
+
+/**** Rows ******/
+
+MBKeyboardRow*
+mb_kbd_row_new(MBKeyboard *kbd);
+
+void
+mb_kbd_row_set_x(MBKeyboardRow *row, int x);
+
+void
+mb_kbd_row_set_y(MBKeyboardRow *row, int y);
+
+int 
+mb_kbd_row_x (MBKeyboardRow *row) ;
+
+int 
+mb_kbd_row_y(MBKeyboardRow *row) ;
+
+int 
+mb_kbd_row_height(MBKeyboardRow *row);
+
+int 
+mb_kbd_row_width(MBKeyboardRow *row);
+
+int 
+mb_kbd_row_base_width(MBKeyboardRow *row);
+
+void
+mb_kbd_row_append_key(MBKeyboardRow *row, MBKeyboardKey *key);
+
+List*
+mb_kdb_row_keys(MBKeyboardRow *row);
+
+#define mb_kbd_row_for_each_key(r,k)            \
+      for ((k) = mb_kdb_row_keys((r));          \
+	   (k) != NULL;                         \
+	   (k) = util_list_next((k))) 
+
+
+/**** Keys ******/
+
+MBKeyboardKey*
+mb_kbd_key_new(MBKeyboard *kbd);
+
+void
+mb_kbd_key_set_obey_caps(MBKeyboardKey  *key, boolean obey);
+
+boolean
+mb_kbd_key_get_obey_caps(MBKeyboardKey  *key);
+
+void
+mb_kbd_key_set_req_uwidth(MBKeyboardKey  *key, int uwidth);
+
+int
+mb_kbd_key_get_req_uwidth(MBKeyboardKey  *key);
+
+void
+mb_kbd_key_set_fill(MBKeyboardKey  *key, boolean fill);
+
+boolean
+mb_kbd_key_get_fill(MBKeyboardKey  *key);
+
+void
+mb_kbd_key_set_blank(MBKeyboardKey  *key, boolean blank);
+
+boolean
+mb_kbd_key_is_blank(MBKeyboardKey  *key);
+
+void 
+mb_kbd_key_set_row(MBKeyboardKey *key, MBKeyboardRow *row);
+
+void
+mb_kbd_key_set_geometry(MBKeyboardKey  *key,
+			int x,
+			int y,
+			int width,
+			int height);
+int 
+mb_kbd_key_abs_x(MBKeyboardKey *key) ;
+
+int 
+mb_kbd_key_abs_y(MBKeyboardKey *key) ;
+
+int 
+mb_kbd_key_x(MBKeyboardKey *key) ;
+
+int 
+mb_kbd_key_y(MBKeyboardKey *key);
+
+int 
+mb_kbd_key_width(MBKeyboardKey *key) ;
+
+int 
+mb_kbd_key_height(MBKeyboardKey *key);
+
+void
+mb_kbd_key_set_extended(MBKeyboardKey  *key, boolean extend);
+
+boolean
+mb_kbd_key_get_extended(MBKeyboardKey  *key);
+
+void
+mb_kbd_key_set_extra_width_pad(MBKeyboardKey  *key, int pad);
+
+void
+mb_kbd_key_set_extra_height_pad(MBKeyboardKey  *key, int pad);
+
+int
+mb_kbd_key_get_extra_height_pad(MBKeyboardKey  *key);
+
+int
+mb_kbd_key_get_extra_width_pad(MBKeyboardKey  *key);
+
+Bool
+mb_kdb_key_has_state(MBKeyboardKey           *key,
+		     MBKeyboardKeyStateType   state);
+
+void
+mb_kbd_key_set_glyph_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state,
+			  const  char             *glyph);
+
+const char*
+mb_kbd_key_get_glyph_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state);
+
+void
+mb_kbd_key_set_image_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state,
+			  MBKeyboardImage         *image);
+
+MBKeyboardImage*
+mb_kbd_key_get_image_face(MBKeyboardKey           *key,
+			  MBKeyboardKeyStateType   state);
+
+
+MBKeyboardKeyFaceType
+mb_kbd_key_get_face_type(MBKeyboardKey           *key,
+			 MBKeyboardKeyStateType   state);
+
+void
+mb_kbd_key_set_char_action(MBKeyboardKey           *key,
+			   MBKeyboardKeyStateType   state,
+			   const char              *glyphs);
+
+void
+mb_kbd_key_set_keysym_action(MBKeyboardKey           *key,
+			     MBKeyboardKeyStateType   state,
+			     KeySym                   keysym);
+
+KeySym
+mb_kbd_key_get_keysym_action(MBKeyboardKey           *key,
+			     MBKeyboardKeyStateType   state);
+
+void
+mb_kbd_key_set_modifer_action(MBKeyboardKey          *key,
+			      MBKeyboardKeyStateType  state,
+			      MBKeyboardKeyModType    type);
+
+MBKeyboardKeyModType 
+mb_kbd_key_get_modifer_action(MBKeyboardKey          *key,
+			      MBKeyboardKeyStateType  state);
+
+boolean 
+mb_kbd_key_is_held(MBKeyboard *kbd, MBKeyboardKey *key);
+
+void
+mb_kbd_key_press(MBKeyboardKey *key);
+
+void
+mb_kbd_key_release(MBKeyboard *kbd);
+
+void
+mb_kbd_key_dump_key(MBKeyboardKey *key);
+
+#define mb_kdb_key_foreach_state(k,s)                     \
+       for((s)=0; (s) < N_MBKeyboardKeyStateTypes; (s)++) \
+            if (mb_kdb_key_has_state((k), (s)))
+
+/*** Config *****/
+
+int
+mb_kbd_config_load(MBKeyboard *kbd, char *varient);
+
+
+/**** Util *****/
+
+#define streq(a,b)      (strcmp(a,b) == 0)
+#define strcaseeq(a,b)  (strcasecmp(a,b) == 0)
+#define unless(x)       if (!(x))
+#define util_abs(x)     ((x) > 0) ? (x) : -1*(x)
+
+void
+util_trap_x_errors(void);
+
+int
+util_untrap_x_errors(void);
+
+void*
+util_malloc0(int size);
+
+void
+util_fatal_error(char *msg);
+
+int
+util_utf8_char_cnt(const char *str);
+
+boolean 
+util_file_readable(char *path);
+
+/* Util list */
+
+#define util_list_next(l) (l)->next
+#define util_list_previous(l) (l)->prev
+
+List*
+util_list_alloc_item(void);
+
+int
+util_list_length(List *list);
+
+List*
+util_list_get_last(List *list);
+
+List*
+util_list_get_first(List *list);
+
+void*
+util_list_get_nth_data(List *list, int n);
+
+List*
+util_list_append(List *list, void *data);
+
+void
+util_list_foreach(List *list, ListForEachCB func, void *userdata);
+
+/* Backends */
+
+#if WANT_CAIRO
+#include "matchbox-keyboard-ui-cairo-backend.h"
+#else
+#include "matchbox-keyboard-ui-xft-backend.h"
+
+Picture
+mb_kbd_image_render_picture (MBKeyboardImage *img);
+
+#endif
+
+#endif

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,93 @@
+#include "matchbox-keyboard.h"
+
+List *
+util_list_alloc_item(void)
+{
+  return util_malloc0(sizeof(List));
+}
+
+int
+util_list_length(List *list)
+{
+  int result = 1;
+
+  list = util_list_get_first(list);
+
+  while ((list = util_list_next(list)) != NULL)
+    result++;
+
+  return result;
+}
+
+List*
+util_list_get_last(List *list)
+{
+  if (list == NULL) 
+    return NULL;
+
+  while (list->next) 
+    list = util_list_next(list);
+  return list;
+}
+
+List*
+util_list_get_first(List *list)
+{
+  if (list == NULL) 
+    return NULL;
+
+  while (list->prev) 
+    list = util_list_previous(list);
+  return list;
+}
+
+void*
+util_list_get_nth_data(List *list, int n)
+{
+  if (list == NULL) 
+    return NULL;
+
+  list = util_list_get_first(list);
+
+  while (list->next && n)
+    {
+      list = util_list_next(list);
+      n--;
+    }
+
+  if (n) return NULL;
+
+  return (void *)list->data;
+}
+
+
+
+List*
+util_list_append(List *list, void *data)
+{
+  if (list == NULL)
+    {
+      list = util_list_alloc_item();
+      list->data = data;
+    }
+  else
+    {
+      list = util_list_get_last(list);
+
+      list->next = util_list_alloc_item();
+      list->next->prev = list;
+      list->next->data = data;
+    }
+
+  return list;
+}
+
+void
+util_list_foreach(List *list, ListForEachCB func, void *userdata)
+{
+  while (list)
+    {
+      func(list->data, userdata);
+      list = util_list_next(list);
+    }
+}

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.h
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.h	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util-list.h	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,6 @@
+#ifndef HAVE_MBKB_UTIL_LIST_H
+#define HAVE_MBKB_UTIL_LIST_H
+
+
+#endif
+

Added: trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util.c	2007-01-08 01:40:40 UTC (rev 510)
+++ trunk/src/target/OM-2007/applications/openmoko-keyboard/src/util.c	2007-01-08 02:22:58 UTC (rev 511)
@@ -0,0 +1,111 @@
+#include "matchbox-keyboard.h"
+
+static int TrappedErrorCode = 0;
+static int (*old_error_handler) (Display *, XErrorEvent *);
+
+static int
+error_handler(Display     *xdpy,
+	      XErrorEvent *error)
+{
+  TrappedErrorCode = error->error_code;
+  return 0;
+}
+
+void
+util_trap_x_errors(void)
+{
+  TrappedErrorCode  = 0;
+  old_error_handler = XSetErrorHandler(error_handler);
+}
+
+int
+util_untrap_x_errors(void)
+{
+  XSetErrorHandler(old_error_handler);
+  return TrappedErrorCode;
+}
+
+void*
+util_malloc0(int size)
+{
+  void *p;
+
+  p = malloc(size);
+  memset(p, 0, size);
+
+  return p;
+}
+
+void
+util_fatal_error(char *msg)
+{
+  fprintf(stderr, "matchbox-keyboard: *Error*  %s", msg);
+  exit(1);
+}
+
+
+
+#define UTF8_COMPUTE(Char, Mask, Len)                                         \
+  if (Char < 128)                                                             \
+    {                                                                         \
+      Len = 1;                                                                \
+      Mask = 0x7f;                                                            \
+    }                                                                         \
+  else if ((Char & 0xe0) == 0xc0)                                             \
+    {                                                                         \
+      Len = 2;                                                                \
+      Mask = 0x1f;                                                            \
+    }                                                                         \
+  else if ((Char & 0xf0) == 0xe0)                                             \
+    {                                                                         \
+      Len = 3;                                                                \
+      Mask = 0x0f;                                                            \
+    }                                                                         \
+  else if ((Char & 0xf8) == 0xf0)                                             \
+    {                                                                         \
+      Len = 4;                                                                \
+      Mask = 0x07;                                                            \
+    }                                                                         \
+  else if ((Char & 0xfc) == 0xf8)                                             \
+    {                                                                         \
+      Len = 5;                                                                \
+      Mask = 0x03;                                                            \
+    }                                                                         \
+  else if ((Char & 0xfe) == 0xfc)                                             \
+    {                                                                         \
+      Len = 6;                                                                \
+      Mask = 0x01;                                                            \
+    }                                                                         \
+  else                                                                        \
+    Len = -1;
+
+
+int
+util_utf8_char_cnt(const char *str)
+{
+  const unsigned char *p = (unsigned char *)str;
+  int         mask, len, result = 0;
+
+  /* XXX Should validate too */
+
+  while (*p != '\0')
+    {
+      UTF8_COMPUTE(*p, mask, len);
+      p += len;
+      result++;
+    }
+
+  return result;
+}
+
+boolean 
+util_file_readable(char *path)
+{
+  struct stat st;
+
+  if (stat(path, &st)) 
+    return False;
+ 
+ return True;
+}
+





More information about the commitlog mailing list