示例#1
0
		private void CreateConversionArray (KeyboardLayouts layouts, KeyboardLayout layout)
		{
			XEvent e2 = new XEvent ();
			uint keysym = 0;
			int [] ckey = new int [] { 0, 0, 0, 0 };

			e2.KeyEvent.display = display;
			e2.KeyEvent.state = 0;

			for (int keyc = min_keycode; keyc <= max_keycode; keyc++) {
				int vkey = 0;
				int scan = 0;

				e2.KeyEvent.keycode = keyc;
				XKeySym t;

				XLookupStatus status;
				LookupString (ref e2, 0, out t, out status);

				keysym = (uint) t;
				if (keysym != 0) {
					if ((keysym >> 8) == 0xFF) {
						vkey = nonchar_key_vkey [keysym & 0xFF];
						scan = nonchar_key_scan [keysym & 0xFF];
						// Set extended bit
						if ((scan & 0x100) != 0)
							vkey |= 0x100;
					} else if (keysym == 0x20) { // spacebar
						vkey = (int) VirtualKeys.VK_SPACE;
						scan = 0x39;
					} else {
						// Search layout dependent scancodes
						int maxlen = 0;
						int maxval = -1;;
						
						for (int i = 0; i < syms; i++) {
							keysym = XKeycodeToKeysym (display, keyc, i);
							if ((keysym < 0x800) && (keysym != ' '))
								ckey [i] = (sbyte) (keysym & 0xFF);
							else
								ckey [i] = (sbyte) MapDeadKeySym ((int) keysym);
						}
						
						for (int keyn = 0; keyn < layout.Keys.Length; keyn++) {
							int ml = Math.Min (layout.Keys [keyn].Length, 4);
							int ok = -1;
							for (int i = 0; (ok != 0) && (i < ml); i++) {
								sbyte ck = (sbyte) layout.Keys [keyn][i];
								if (ck != ckey [i])
									ok = 0;
								if ((ok != 0) || (i > maxlen)) {
									maxlen = i;
									maxval = keyn;
								}
								if (ok != 0)
									break;
							}
						}
						if (maxval >= 0) {
							if (maxval < layouts.scan_table [(int) layout.ScanIndex].Length)
								scan = layouts.scan_table [(int) layout.ScanIndex][maxval];
							if (maxval < layouts.vkey_table [(int) layout.VKeyIndex].Length)
								vkey = layouts.vkey_table [(int) layout.VKeyIndex][maxval];
						}
					}
				}
				keyc2vkey [e2.KeyEvent.keycode] = vkey;
				keyc2scan [e2.KeyEvent.keycode] = scan;
			}
			
			
		}
示例#2
0
		private KeyboardLayout DetectLayout (KeyboardLayouts layouts)
		{
			XDisplayKeycodes (display, out min_keycode, out max_keycode);
			IntPtr ksp = XGetKeyboardMapping (display, (byte) min_keycode,
					max_keycode + 1 - min_keycode, out keysyms_per_keycode);
			lock (XlibLock) {
				XplatUIX11.XFree (ksp);
			}

			syms = keysyms_per_keycode;
			if (syms > 4) {
				//Console.Error.WriteLine ("{0} keysymbols per a keycode is not supported, setting to 4", syms);
				syms = 2;
			}

			IntPtr	modmap_unmanaged;
			XModifierKeymap xmk = new XModifierKeymap ();

			modmap_unmanaged = XGetModifierMapping (display);
			xmk = (XModifierKeymap) Marshal.PtrToStructure (modmap_unmanaged, typeof (XModifierKeymap));

			int mmp = 0;
			for (int i = 0; i < 8; i++) {
				for (int j = 0; j < xmk.max_keypermod; j++, mmp++) {
					byte b = Marshal.ReadByte (xmk.modifiermap, mmp);
					if (b != 0) {
						for (int k = 0; k < keysyms_per_keycode; k++) {
							if ((int) XKeycodeToKeysym (display, b, k) == (int) MiscKeys.XK_Num_Lock)
								NumLockMask = 1 << i;
						}
					}
				}
			}
			XFreeModifiermap (modmap_unmanaged);

			int [] ckey = new int [4];
			KeyboardLayout layout = null;
			int max_score = 0;
			int max_seq = 0;
			
			foreach (KeyboardLayout current in layouts.Layouts) {
				int ok = 0;
				int score = 0;
				int match = 0;
				int mismatch = 0;
				int seq = 0;
				int pkey = -1;
				int key = min_keycode;
				int i;

				for (int keyc = min_keycode; keyc <= max_keycode; keyc++) {
					for (i = 0; i < syms; i++) {
						uint keysym = XKeycodeToKeysym (display, keyc, i);
						
						if ((keysym < 0x800) && (keysym != ' ')) {
							ckey [i] = (sbyte) (keysym & 0xFF);
						} else {
							ckey [i] = (sbyte) MapDeadKeySym ((int) keysym);
						}
					}
					if (ckey [0] != 0) {
						for (key = 0; key < current.Keys.Length; key++) {
							int ml = Math.Min (syms, current.Keys [key].Length);
							for (ok = 0, i = 0; (ok >= 0) && (i < ml); i++) {
								sbyte ck = (sbyte) current.Keys [key][i];
								if (ck != 0 && ck == ckey[i])
									ok++;
								if (ck != 0 && ck != ckey[i])
									ok = -1;
							}
							if (ok > 0) {
								score += ok;
								break;
							}
						}
						if (ok > 0) {
							match++;
							/* and how much the keycode order matches */
							if (key > pkey)
								seq++;
							pkey = key;
						} else {
							/* print spaces instead of \0's */
							mismatch++;
							score -= syms;
						}
					}
				}

				if ((score > max_score) || ((score == max_score) && (seq > max_seq))) {
					// best match so far
					layout = current;
					max_score = score;
					max_seq = seq;
				}
			}

			if (layout != null)  {
                                return layout;
			} else {
				Console.WriteLine (Locale.GetText("Keyboard layout not recognized, using default layout: " +
								   layouts.Layouts [0].Name));
			}

			return layouts.Layouts [0];
		}
示例#3
0
		public void EnsureLayoutInitialized ()
		{
			if (initialized)
				return;

			KeyboardLayouts layouts = new KeyboardLayouts ();
			KeyboardLayout layout = DetectLayout (layouts);
			lcid = layout.Lcid;
			CreateConversionArray (layouts, layout);
			SetupXIM ();
			initialized = true;
		}