[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#348027: errors in Turkish keyboard setup



Package: xserver-xorg
Severity: important
Tags: patch l10n

[Due to the similar problems in Ubuntu, CCing to Daniel Stone to let him
 aware of the situation and also to review the patches attached.]

Hi,

I've noticed a serious bug in keyboard setup regarding Turkish.  What makes
Turkish so special in this respect is that, Turkish has three distinct
keyboard "layout"s.  The word "layout" is used here in the physical sense,
not as in XkbLayout (this situation causes too much confusion).  To make
the situation more worst, Turkish keyboard settings differ among the X
versions.  Here are the different XKB settings[1]:

    * xfree86 version 4.3 to xorg version 6.8 [2]
    +-----------+------------+-------------+-------------------------+
    | XkbLayout | XkbVariant |  XkbOptions | Description             |
    |===========+============+=============+=========================+
    | tr        | NONE [3]   | caps:shift  | qwerty + TR keys [4]    |
    +-----------+------------+-------------+-------------------------+
    | tr        | tr_f       | caps:shift  | fgGIod + TR keys [5]    |
    +-----------+------------+-------------+-------------------------+
    | tr        | tr_alt     | caps:shift  | qwerty + AltGr   [6]    |
    +-----------+------------+-------------+-------------------------+

    * xorg version 6.9 and above (including version 7.0) [7]
    +-----------+------------+-------------+-------------------------+
    | XkbLayout | XkbVariant |  XkbOptions | Description             |
    |===========+============+=============+=========================+
    | tr        | NONE       | caps:shift  | qwerty + TR keys        |
    +-----------+------------+-------------+-------------------------+
    | tr        | f          | caps:shift  | fgGIod + TR keys        |
    +-----------+------------+-------------+-------------------------+
    | tr        | alt        | caps:shift  | qwerty + AltGr          |
    +-----------+------------+-------------+-------------------------+

As shown in the tables, Turkish F/Alt keyboards are configured through the
XkbVariant; they must neither be configured as an XkbLayout (i.e. tr_f) nor
as an entry in XkbOptions which is the current case in xserver-xorg.config:

    ...
    trfu--*) XMAP="tr"; OPTIONS="tr_f";;
    trqu--*) XMAP="tr";;
    ...

Apart from such obvious errors, there are some other issues which I
would like to fix in the Turkish keyboard setup:

    * There are 5 Turkish VT keymaps (for i386): trq, trqu, trf, trfu and
      tralt.  Of these, the first two correspond to the Turkish Q layout
      (the one suffixed with 'u' is the console keymap defined with Unicode
      code-points), the next two are Turkish F layouts and the last one
      (tralt) corresponds to the Turkish programmers' Q layout (maps to the
      "XkbVariant 'tr_alt'")

      The current xserver-xorg.config code does not tolerate the changes in
      console keymap names.  (FYI, we've just experienced a bug because of
      such issues.)

    * There is no support for tralt which I'm planning to add in d-i.  We
      should also take the sunt5-trqalt keymap into account, the Sun
      version of tr_alt.  Sorry for the keymap mess. :-)

    * Finally, we should handle the "tr_f/f" and "tr_alt/alt" inconsistency
      gracefully.

I've prepared two separate patches targeting all these issues for your
convenience.  In the first (recommended) patch, which uses a more general
approach, I've changed the code to handle XkbVariant through an XKBVARIANT
variable.  (To eliminate the code duplication, I modified the 'br' setup a
little bit, though it could be improved further).  The 2nd not-so-invasive
patch treats Turkish as an exceptional case.

Both of the patches take care of the tr_f/f name change in a somewhat
kludgy way (you can remove the this kludge if you feel uncomfortable).
Could you please investigate them?  I haven't tested them in a real
installation, but the logic and shell expressions were tested separately.
Hope I haven't missed anything off.

Regards,

[1] http://necrotic.deadbeast.net/svn/xorg-x11/tags/6.9.0.dfsg.1-3/xc/programs/xkbcomp/symbols/tr
    As can be seen in the link above, there is the xkb/symbols/tr_f file
    (along with the xkb/symbols/tr) in the X distribution, which can be
    specified as a valid XkbLayout entry.  But both of the files are
    _obsolete_.  We use the xkb/symbols/pc/tr, an all-in-one file which
    includes Q, F and Alt layouts as depicted in the table above.

[2] http://necrotic.deadbeast.net/svn/xorg-x11/tags/6.8.2.dfsg.1-9/xc/programs/xkbcomp/symbols/pc/tr

[3] For Turkish Q layout XkbVariant should be left as empty.  There is _no_
    such "q" variant (and specifying it so causes serious problems, as in
    Ubuntu BZ#17787).

[4] http://www.katpatuka.org/pub/doc/keyboard/trq.html

[5] http://www.katpatuka.org/pub/doc/keyboard/trf.html

[6] In this layout (also known as "alternative Turkish Q" or "programmers'
    Q layout") Turkish characters are typed by holding AltGr key.

[7] http://necrotic.deadbeast.net/svn/xorg-x11/tags/6.9.0.dfsg.1-3/xc/programs/xkbcomp/symbols/pc/tr
    Unfortunately, I haven't been able to find a ChangeLog entry in the
    upstream documentation.  It appears that this change has (silently)
    occured in 6.9RC1.  Making such an important change without any notice
    is another unpleasant issue.

-- 
roktas
--- xserver-xorg.config.in.orig	2006-01-12 03:11:03.000000000 +0200
+++ xserver-xorg.config.in	2006-01-14 09:08:57.000000000 +0200
@@ -960,7 +960,7 @@
     br-abnt2--ie*) XMAP="ie";;
     br-abnt2--*) XMAP="br"; OPTIONS="abnt2";;
     by--*) XMAP="by";;
-    cf--tr*) XMAP="tr"; OPTIONS="tr_f";;
+    cf--tr*) XMAP="tr"; VARIANT="f";;
     cf--ie*) XMAP="ie";;
     cf--lv*) XMAP="lv";;
     cf--it*) XMAP="it";;
@@ -1009,7 +1009,7 @@
     gr--ua*) XMAP="ua";;
     gr--by*) XMAP="by";;
     gr--tj*) XMAP="tj";;
-    gr--tr*) XMAP="tr_f";;
+    gr--tr*) XMAP="tr"; VARIANT="f";;
     gr--uz*) XMAP="uz";;
     hu--*) XMAP="hu";;
     is-latin1--*) XMAP="is";;
@@ -1029,7 +1029,7 @@
     lt--tj*) XMAP="tj";;
     lt--lv*) XMAP="lv";;
     lt--mt*) XMAP="mt_us";;
-    lt--tr*) XMAP="tr"; OPTIONS="tr_f";;
+    lt--tr*) XMAP="tr"; VARIANT="f";;
     lt--uz*) XMAP="uz";;
     lt--*) XMAP="lt";;
     mac-us-std--*) XMAP="us";;
@@ -1037,7 +1037,7 @@
     mac-fr2-ext--*) XMAP="fr";;
     mac-fr3--*) XMAP="fr";;
     mac-es--*) XMAP="es";;
-    mk--tr*) XMAP="tr"; OPTIONS="tr_f";;
+    mk--tr*) XMAP="tr"; VARIANT="f";;
     mk--sr*) XMAP="sr";;
     mk--hr*) XMAP="hr";;
     no-latin1--*) XMAP="no";;
@@ -1065,14 +1065,18 @@
     sg-latin1--fr*) XMAP="ch"; OPTIONS="fr";;
     sk-qwerty--cz*) XMAP="cz_querty";;
     sk-qwerty--*) XMAP="sk_querty";;
-    sr-cy--tr*) XMAP="tr"; OPTIONS="tr_f";;
+    sr-cy--tr*) XMAP="tr"; VARIANT="f";;
     sr-cy--yu*) XMAP="yu";;
     sr-cy--*) XMAP="sr";;
+    tralt--*) XMAP="tr"; VARIANT="alt";;
     trfu--hu*) XMAP="hu"; OPTIONS="qwerty";;
     trfu--yu*) XMAP="yu";;
-    trfu--*) XMAP="tr"; OPTIONS="tr_f";;
+    trf--*) XMAP="tr"; VARIANT="f";;
+    trfu--*) XMAP="tr"; VARIANT="f";;
+    trq--*) XMAP="tr";;
+    *trqalt*) XMAP="tr"; VARIANT="alt";;
     trqu--*) XMAP="tr";;
-    ua--tr*) XMAP="tr"; OPTIONS="tr_f";;
+    ua--tr*) XMAP="tr"; VARIANT="f";;
     ua--by*) XMAP="by";;
     ua--*) XMAP="ua";;
     uk--mt*) XMAP="mt";;
@@ -1167,6 +1171,42 @@
     PRIORITY=high
   else
     PRIORITY=low
+
+    # handle Turkish keyboard setup specially due to its oddities
+    if [ "$XMAP" = "tr" ]; then
+      # add "caps:shift" option to make Caps Lock behave correctly
+      case "$OPTIONS" in
+        *caps:shift*) ;; # do nothing if it's already defined
+        "") OPTIONS="caps:shift" ;;
+         *) OPTIONS="$OPTIONS,caps:shift" ;;
+      esac
+
+      # be tolerant to the changes in the variant name
+      TR_KEYMAP="$CONFIG_DIR/xkb/symbols/pc/tr"
+      case "$VARIANT" in
+        f|tr_f)
+          # X.Org version < 6.9 uses "tr_f", while >= 6.9 uses only "f"
+          if [ -e "$TR_KEYMAP" ] &&
+            grep -q "^[[:space:]]*xkb_symbols[[:space:]]*\"tr_f\"" $TR_KEYMAP; then
+            VARIANT="tr_f"
+          else
+            VARIANT="f"
+          fi
+          ;;
+        alt|tr_alt)
+          # X.Org version < 6.9 uses "tr_alt", while >= 6.9 uses only "alt"
+          if [ -e "$TR_KEYMAP" ] &&
+            grep -q "^[[:space:]]*xkb_symbols[[:space:]]*\"tr_alt\"" $TR_KEYMAP; then
+            VARIANT="tr_alt"
+          else
+            VARIANT="alt"
+          fi
+          ;;
+        *)
+          warn "unknown variant '$VARIANT' for Turkish layout"
+          ;;
+      esac
+    fi
   fi
 
   # we can't do non-Latin usernames, so people with Latin layouts need a US
@@ -1190,6 +1230,7 @@
 
   XKBLAYOUT="$XMAP"
   XKBOPTIONS="$OPTIONS"
+  XKBVARIANT="$VARIANT"
 else
   db_get xserver-xorg/config/inputdevice/keyboard/layout || debug_report_status "db_get xserver-xorg/config/inputdevice/keyboard/layout"
   XKBLAYOUT="$RET"
@@ -1234,8 +1275,15 @@
 if [ "$RET" = "us" ]; then
   PRIORITY=low
 elif [ "$RET" = "br" ]; then
-  db_set xserver-xorg/config/inputdevice/keyboard/variant "abnt2"
+    # add "abnt2" option
+    case "$XKBVARIANT" in
+      *abnt2*) ;; # do nothing if it's already defined
+      "") XKBVARIANT="abnt2" ;;
+       *) XKBVARIANT="$XKBVARIANT,abnt2" ;;
+    esac
 fi
+
+db_set xserver-xorg/config/inputdevice/keyboard/variant "$XKBVARIANT"
 MAY_BE_NULL=yes validate_string_db_input "$(priority_ceil $PRIORITY)" xserver-xorg/config/inputdevice/keyboard/variant
 
 # ugly kludge, I know; map Apple->AltGr for most European Macs
--- xserver-xorg.config.in.orig	2006-01-12 03:11:03.000000000 +0200
+++ xserver-xorg.config.in	2006-01-14 09:49:17.000000000 +0200
@@ -1009,7 +1009,7 @@
     gr--ua*) XMAP="ua";;
     gr--by*) XMAP="by";;
     gr--tj*) XMAP="tj";;
-    gr--tr*) XMAP="tr_f";;
+    gr--tr*) XMAP="tr"; OPTIONS="tr_f";;
     gr--uz*) XMAP="uz";;
     hu--*) XMAP="hu";;
     is-latin1--*) XMAP="is";;
@@ -1068,10 +1068,14 @@
     sr-cy--tr*) XMAP="tr"; OPTIONS="tr_f";;
     sr-cy--yu*) XMAP="yu";;
     sr-cy--*) XMAP="sr";;
+    tralt--*) XMAP="tr"; OPTIONS="tr_alt";;
     trfu--hu*) XMAP="hu"; OPTIONS="qwerty";;
     trfu--yu*) XMAP="yu";;
+    trf--*) XMAP="tr"; OPTIONS="tr_f";;
     trfu--*) XMAP="tr"; OPTIONS="tr_f";;
+    trq--*) XMAP="tr";;
     trqu--*) XMAP="tr";;
+    *trqalt*) XMAP="tr"; OPTIONS="tr_alt";;
     ua--tr*) XMAP="tr"; OPTIONS="tr_f";;
     ua--by*) XMAP="by";;
     ua--*) XMAP="ua";;
@@ -1235,6 +1239,50 @@
   PRIORITY=low
 elif [ "$RET" = "br" ]; then
   db_set xserver-xorg/config/inputdevice/keyboard/variant "abnt2"
+
+# handle Turkish keyboard setup specially due to its oddities;
+# check if F or alternative Q keyboard layouts were specified
+# (as options), set the XkbVariant accordingly
+elif [ "$RET" = "tr" ]; then
+  # be tolerant to the changes in the variant name
+  TR_KEYMAP="$CONFIG_DIR/xkb/symbols/pc/tr"
+  case "$XKBOPTIONS" in
+    f|*,f|f,*|*,f,*|*tr_f*)
+      # X.Org version < 6.9 uses "tr_f", while >= 6.9 uses only "f"
+      if [ -e "$TR_KEYMAP" ] &&
+        grep -q "^[[:space:]]*xkb_symbols[[:space:]]*\"tr_f\"" $TR_KEYMAP; then
+        TR_VARIANT="tr_f"
+      else
+        TR_VARIANT="f"
+      fi
+      ;;
+    alt|*,alt|alt,*|*,alt,*|*tr_alt*)
+      # X.Org version < 6.9 uses "tr_alt", while >= 6.9 uses only "alt"
+      if [ -e "$TR_KEYMAP" ] &&
+        grep -q "^[[:space:]]*xkb_symbols[[:space:]]*\"tr_alt\"" $TR_KEYMAP; then
+        TR_VARIANT="tr_alt"
+      else
+        TR_VARIANT="alt"
+      fi
+      ;;
+  esac
+
+  # now, commit non-empty variant to debconf
+  if [ -n "$TR_VARIANT" ]; then
+    db_set xserver-xorg/config/inputdevice/keyboard/variant "$TR_VARIANT"
+
+    # remove the converted options
+    XKBOPTIONS=$(echo $XKBOPTIONS | \
+                 sed -e "s/\<\(tr_\)*\(f\|alt\)[[:space:]]*,//g" \
+                     -e "s/\(^\|,\)[[:space:]]*\(tr_\)*\(f\|alt\)[[:space:]]*$//g")
+  fi
+
+  # while on it ensure that Caps Lock behave correctly
+  case "$XKBOPTIONS" in
+    *caps:shift*) ;; # do nothing if it's already defined
+    "") XKBOPTIONS="caps:shift" ;;
+     *) XKBOPTIONS="$XKBOPTIONS,caps:shift" ;;
+  esac
 fi
 MAY_BE_NULL=yes validate_string_db_input "$(priority_ceil $PRIORITY)" xserver-xorg/config/inputdevice/keyboard/variant
 

Attachment: signature.asc
Description: Digital signature


Reply to: