2 using System.Collections.Generic;
3 using System.Runtime.InteropServices;
4 using System.Threading.Tasks;
7 using Tizen.Applications;
9 using Tizen.NUI.Components;
10 using Tizen.Uix.InputMethod;
11 using static Interop.SclNuiCSharp;
13 namespace ISEDefaultNUI
15 class Program : NUIApplication
17 private static Navigator navigator = null;
18 private static SCLNUI SclNui = null;
19 private static SCLDBUS SclDbus = null;
21 public Program(string styleSheet, WindowMode windowMode, WindowType type) : base(styleSheet, windowMode, type)
25 protected override void OnCreate()
28 InputMethodEditor.Create();
32 protected override void OnTerminate()
37 static private void RegisterLanguageInfo()
39 string xmlURL = Application.Current.DirectoryInfo.Resource + "ise_lang_table.xml";
42 XmlDocument xml = new XmlDocument();
45 XmlElement KeyList = xml.DocumentElement;
46 XmlNodeList uuidList = xml.SelectNodes("/languages/keyboard_uuid_table/rec");
47 XmlNodeList languageList = xml.SelectNodes("/languages/language_table/rec");
49 foreach (XmlNode node in uuidList)
51 KeyboardUuidInfo uuidInfo = new KeyboardUuidInfo();
52 uuidInfo.Name = node.Attributes["name"]?.Value;
53 uuidInfo.Uuid = node.Attributes["uuid"]?.Value;
54 LanguageManager.Instance.AddUuidInfo(uuidInfo);
57 foreach (XmlNode node in languageList)
59 InputModeInfo inputModeInfo = new InputModeInfo();
60 inputModeInfo.Name = node.Attributes["inputmode_QTY"]?.Value;
61 inputModeInfo.DisplayName = node.Attributes["inputmode_QTY_name"]?.Value;
63 LanguageInfo languageInfo = new LanguageInfo();
64 languageInfo.Name = node.Attributes["language"]?.Value;
65 languageInfo.DisplayName = node.Attributes["language_name"]?.Value;
66 languageInfo.LocaleString = node.Attributes["locale_string"]?.Value;
67 languageInfo.KeyboardISEUuid = node.Attributes["keyboard_ise_uuid"]?.Value;
68 languageInfo.CountryCodeURL = node.Attributes["country_code_URL"]?.Value;
69 if (node.Attributes["load_in_ime"] != null)
70 languageInfo.LoadInIME = bool.Parse(node.Attributes["load_in_ime"].Value);
71 languageInfo.InputModes = new List<InputModeInfo>();
72 languageInfo.InputModes.Add(inputModeInfo);
73 languageInfo.Priority = LanguagePriority.Default;
75 if (node.Attributes["is_latin_language"] != null)
76 languageInfo.IsLatinLanguage = Convert.ToBoolean(node.Attributes["is_latin_language"].Value);
78 if (node.Attributes["accepts_caps_mode"] != null)
79 languageInfo.AcceptsCapsMode = Convert.ToBoolean(node.Attributes["accepts_caps_mode"].Value);
81 languageInfo.Enabled = false;
82 languageInfo.SelectedInputMode = inputModeInfo.Name;
84 LanguageManager.Instance.AddLanguage(languageInfo);
89 Log.Error("NUIIME", "Failed to load XML data. error = " + ex.ToString());
93 static async void DbusInitialize()
97 int ret = SclDbus.Init();
99 Log.Info("NUIIME", "Failed to initialize dbus");
103 private static void Create()
105 SclNui = new SCLNUI(navigator);
106 SclDbus = new SCLDBUS();
107 Task.Run(() => DbusInitialize());
109 Window.Instance.AddAvailableOrientation(Window.WindowOrientation.Portrait);
110 Window.Instance.AddAvailableOrientation(Window.WindowOrientation.PortraitInverse);
111 Window.Instance.AddAvailableOrientation(Window.WindowOrientation.Landscape);
112 Window.Instance.AddAvailableOrientation(Window.WindowOrientation.LandscapeInverse);
114 List<Window.WindowOrientation> availableList = new List<Window.WindowOrientation>();
115 availableList.Add(Window.WindowOrientation.Portrait);
116 availableList.Add(Window.WindowOrientation.Landscape);
117 availableList.Add(Window.WindowOrientation.PortraitInverse);
118 availableList.Add(Window.WindowOrientation.LandscapeInverse);
119 Window.Instance.SetAvailableOrientations(availableList);
121 Window window = NUIApplication.GetDefaultWindow();
122 navigator = new Navigator()
124 WidthResizePolicy = ResizePolicyType.FillToParent,
125 HeightResizePolicy = ResizePolicyType.FillToParent
127 window.Add(navigator);
129 RegisterLanguageInfo();
130 bool exists = Preference.Contains(ResourceManager.IseConfigKeypadMode);
132 IseConfig.Instance.WriteIseConfig();
134 IseConfig.Instance.ReadIseConfig();
135 LanguageManager.Instance.SetEnabledLanguages(IseConfig.Instance.EnabledLanguages);
137 SclNui.Init(Application.Current.DirectoryInfo.Resource + "main_entry.xml");
138 SclNui.EnableSound(false);
139 SclNui.EnableVibration(false);
140 SclNui.EnableMagnifier(false);
142 LanguageInfo currentLanguage = LanguageManager.Instance.GetLanguageInfo(IseConfig.Instance.SelectedLanguage);
143 if (!currentLanguage.LoadInIME)
145 /* FIXME : This comment should be removed when using IMEngine
146 string uuid = LanguageManager.Instance.GetUuid(currentLanguage.KeyboardISEUuid);
147 ApplicationInfo applicationInfo = new ApplicationInfo(uuid);
148 SclDbus.SetImengine(uuid, applicationInfo.PackageId);
153 private static void Terminate()
155 UnregisterCallback();
158 InputMethodEditor.Destroy();
161 private static void Show(InputMethodEditor.ContextId a, Tizen.Uix.InputMethod.InputMethodContext b)
163 int inputContext = a.Equals(0) ? 0 : KeyboardState.Instance.FocusedContext;
164 bool returnKeyState = b.ReturnKeyState;
165 bool predictionAllow = b.PredictionMode;
166 bool passwordMode = b.PasswordMode;
167 AutoCapitalization autoCapitalization = b.AutoCapitalization;
168 SclDbus.SetInputHint((uint)b.InputHint);
169 SclDbus.UpdateBidiDirection((uint)b.BiDirection);
170 SclNui.SetUpdatePending(true);
173 if (b.Language == InputPanelLanguage.Alphabet)
175 Log.Info("NUIIME", "prefer latin");
176 KeyboardState.Instance.PreferLatin = true;
180 Log.Info("NUIIME", "prefer automatic");
181 KeyboardState.Instance.PreferLatin = false;
184 SetLayout((KeyboardLayout)b.Layout, (uint)b.LayoutVariation);
185 SetReturnKeyType(b.ReturnKey);
186 SetReturnKeyDisable(b.ReturnKeyState);
188 switch (autoCapitalization)
190 case AutoCapitalization.Word:
191 case AutoCapitalization.Sentence:
192 case AutoCapitalization.AllCharacter:
195 case AutoCapitalization.None:
196 case AutoCapitalization.Undefined:
201 UpdateCursorPosition(b.CursorPosition);
203 IMEShow(inputContext);
204 SclNui.SetUpdatePending(false);
205 navigator.Push(SclNui);
208 private static void Hide(InputMethodEditor.ContextId a)
210 if (!KeyboardState.Instance.VisibleState)
217 private static void IMEHide()
219 SclNui.ClearClickCount();
220 SclNui.SetUpdatePending(true);
221 SclNui.DisableInputEvent(true);
224 KeyboardState.Instance.VisibleState = false;
226 KeyboardState.Instance.ResetMultitapState(true);
229 private static void IMEShow(int ic)
231 switch (KeyboardState.Instance.Layout)
233 case KeyboardLayout.PhoneNumber:
234 case KeyboardLayout.IP:
235 case KeyboardLayout.Month:
236 case KeyboardLayout.NumberOnly:
237 /* FIXME : This comment should be removed when using IMEngine
238 * InputMethodEditor.SetIMEngine(ResourceManager.DefaultKeyboardUuid);
245 IMEDefaultValue defaultValue = new IMEDefaultValue();
246 LanguageManager languageManager = LanguageManager.Instance;
247 IseConfig iseConfig = IseConfig.Instance;
248 KeyboardState keyboardState = KeyboardState.Instance;
249 string currentLanguage = languageManager.GetCurrentLanguage();
250 IseConfig.Instance.ReadIseConfig();
251 LanguageInfo languageinfo = languageManager.GetLanguageInfo(iseConfig.SelectedLanguage);
252 bool resetInputMode = false;
254 SclNui.SetInputMode(languageinfo.SelectedInputMode);
255 SclNui.SetCurrentSublayout("DEFAULT");
256 SclNui.SetStringSubstitution("_LANGUAGE_", languageinfo.DisplayName);
257 SclNui.EnableMagnifier(IseConfig.Instance.PreviewOn);
259 KeyboardState.Instance.VisibleState = true;
261 if (keyboardState.Context != ic || keyboardState.NeedReset || !iseConfig.SelectedLanguage.Equals(currentLanguage))
262 resetInputMode = true;
264 keyboardState.NeedReset = false;
266 bool forcePrimaryLatin = false;
267 if (!languageinfo.IsLatinLanguage)
269 if (!keyboardState.DisableForceLatin)
271 if(defaultValue.Values[(int)keyboardState.Layout].ForceLatin)
273 forcePrimaryLatin = true;
277 if (keyboardState.PreferLatin)
278 forcePrimaryLatin = true;
283 if(forcePrimaryLatin)
285 bool selected = false;
286 for (int loop = 0; !selected && loop < languageManager.GetLanguagesNum(); loop++)
288 languageinfo = languageManager.GetLanguageInfo(loop);
289 if (languageinfo != null)
291 if (languageinfo.Enabled && languageinfo.IsLatinLanguage)
293 selected = languageManager.SelectLanguage(languageinfo);
295 forcePrimaryLatin = false;
305 if (!keyboardState.CapsMode)
306 SclNui.SetShiftState((uint)ShiftState.Off);
308 if (keyboardState.Layout < KeyboardLayout.Max)
310 uint layoutIndex = (uint)keyboardState.Layout;
311 if (keyboardState.Layout == KeyboardLayout.NumberOnly && keyboardState.LayoutVariation > 0 &&
312 keyboardState.LayoutVariation < ResourceManager.LayoutNumberOnlyVariationMax)
314 layoutIndex = (uint)KeyboardLayout.NumberOnlySig + keyboardState.LayoutVariation - 1;
316 else if (keyboardState.Layout == KeyboardLayout.Password && keyboardState.LayoutVariation > 0)
318 layoutIndex = (uint)KeyboardLayout.Password_3X4;
321 bool fileNameLayout = false;
322 if (keyboardState.Layout == KeyboardLayout.Normal && keyboardState.LayoutVariation == (uint)KeyboardLayoutNormalVariation.FileName)
323 fileNameLayout = true;
325 fileNameLayout = false;
327 SclNui.EnableButton("exclamation", !fileNameLayout);
328 SclNui.EnableButton("question", !fileNameLayout);
329 SclNui.EnableButton("divide", !fileNameLayout);
330 SclNui.EnableButton("multiply", !fileNameLayout);
331 SclNui.EnableButton("colon", !fileNameLayout);
332 SclNui.EnableButton("quotation", !fileNameLayout);
333 SclNui.EnableButton("CM_KEY", true);
335 Log.Info("NUIIME", "new layout index : " + layoutIndex.ToString());
337 if(defaultValue.Values[(int)layoutIndex].InputMode.Length > 0)
339 SclNui.SetInputMode(defaultValue.Values[(int)layoutIndex].InputMode);
342 SclNui.SetCurrentSublayout(defaultValue.Values[(int)layoutIndex].SublayoutName);
346 LanguageInfo languageInfo = LanguageManager.Instance.GetLanguageInfo(currentLanguage);
347 if (languageInfo != null)
349 if (languageInfo.AcceptsCapsMode)
351 if (keyboardState.Layout != KeyboardLayout.Normal)
353 SclNui.SetAutocapitalShiftState(true);
354 SclNui.SetShiftState((uint)ShiftState.Off);
358 Common.SendKeyEvent((KeyCode)ResourceManager.MVKShiftEnable);
359 if (keyboardState.CapsMode)
360 SclNui.SetAutocapitalShiftState(false);
365 SclNui.SetAutocapitalShiftState(true);
366 Common.SendKeyEvent((KeyCode)ResourceManager.MVKShiftDisable);
367 SclNui.SetShiftState((uint)ShiftState.Off);
372 SclNui.SetAutocapitalShiftState(true);
377 SclNui.DisableInputEvent(false);
381 private static void ResetContext()
383 KeyboardState.Instance.ResetMultitapState(true);
384 KeyboardState.Instance.DisableForceLatin = false;
385 LanguageManager.Instance.ResetLanguage(IseConfig.Instance.SelectedLanguage);
388 private static void SetLayout(KeyboardLayout layout, UInt32 layoutVariation)
390 KeyboardState keyboardState = KeyboardState.Instance;
391 if (layout < KeyboardLayout.Max)
393 if (keyboardState.Layout != layout || keyboardState.LayoutVariation != layoutVariation)
394 keyboardState.NeedReset = true;
395 keyboardState.Layout = layout;
396 keyboardState.LayoutVariation = layoutVariation;
397 Log.Info("NUIIME", "layout : " + layout.ToString() + ", variation : " + layoutVariation.ToString());
401 private static void SetReturnKeyType(InputPanelReturnKey returnKey)
403 Log.Info("NUIIME", "return key : " + returnKey.ToString());
404 string label = string.Empty;
407 case InputPanelReturnKey.Done:
408 label = Resource.Resources.IDS_IME_SK_DONE_ABB;
410 case InputPanelReturnKey.Go:
411 label = Resource.Resources.IDS_IME_BUTTON_GO_M_KEYBOARD;
413 case InputPanelReturnKey.Join:
414 label = Resource.Resources.IDS_IME_BUTTON_JOIN_M_KEYBOARD;
416 case InputPanelReturnKey.Login:
417 label = Resource.Resources.IDS_IME_BUTTON_LOG_IN_M_KEYBOARD;
419 case InputPanelReturnKey.Next:
420 label = Resource.Resources.IDS_IME_OPT_NEXT_ABB;
422 case InputPanelReturnKey.Search:
423 label = Resource.Resources.IDS_IME_BUTTON_SEARCH_M_KEYBOARD;
425 case InputPanelReturnKey.Send:
426 label = Resource.Resources.IDS_IME_BUTTON_SEND_M_KEYBOARD;
428 case InputPanelReturnKey.SignIn:
429 label = Resource.Resources.IDS_IME_BUTTON_SIGN_IN_M_KEYBOARD;
431 case InputPanelReturnKey.Default:
434 Log.Info("NUIIME", "Unknown return key : " + returnKey.ToString());
435 returnKey = InputPanelReturnKey.Default;
439 if (returnKey == InputPanelReturnKey.Default)
441 SclNui.UnsetPrivateKey("Enter");
445 string[] imageLabel = {" ", " ", " "};
446 SclNui.SetPrivateKey("Enter", label, imageLabel, null, 0, "Enter", true);
448 Log.Info("NUIIME", "return key label : " + label);
451 private static void SetReturnKeyDisable(bool disable)
453 Log.Info("NUIIME", "return key disable : " + disable);
454 SclNui.EnableButton("Enter", !disable);
457 private static void SetCapsMode(bool enable)
459 Log.Info("NUIIME", "capsmode : " + enable.ToString());
460 KeyboardState keyboardState = KeyboardState.Instance;
461 keyboardState.CapsMode = enable;
462 keyboardState.CapsModePending = false;
464 string currentLanguage = LanguageManager.Instance.GetCurrentLanguage();
465 if (currentLanguage != null)
467 LanguageInfo languageInfo = LanguageManager.Instance.GetLanguageInfo(currentLanguage);
468 if (languageInfo != null && languageInfo.AcceptsCapsMode)
470 if (keyboardState.PreviousModifier != (uint)SclNuiKeyModifier.MultitapStart && keyboardState.PreviousModifier != (uint)SclNuiKeyModifier.MultitapRepeat)
471 keyboardState.SetCapsmode(keyboardState.CapsMode);
473 keyboardState.CapsModePending = true;
478 private static void UpdateCursorPosition(int position)
480 KeyboardState keyboardState = KeyboardState.Instance;
481 if (keyboardState.Layout == KeyboardLayout.URL)
484 SclNui.SetStringSubstitution("www.", ".com");
486 SclNui.UnsetStringSubstitution("www.");
490 private static void ResetShiftState()
492 uint oldState, newState;
493 SclNui.GetShiftState(out oldState);
494 newState = (uint)ShiftState.Off;
496 if (oldState != newState)
497 SclNui.SetShiftState(newState);
500 private static void RegisterCallback()
502 InputMethodEditor.FocusedIn += FocusInEvent;
503 InputMethodEditor.FocusedOut += FocusOutEvent;
504 InputMethodEditor.RotationChanged += RotationChangedEvent;
505 InputMethodEditor.AccessibilityStateChanged += AccessibilityStateChangedEvent;
506 InputMethodEditor.SurroundingTextUpdated += SurroundingTextUpdatedEvent;
507 InputMethodEditor.InputContextReset += InputContextResetEvent;
508 InputMethodEditor.CursorPositionUpdated += CursorPositionUpdatedEvent;
509 InputMethodEditor.LanguageSet += LanguageSetEvent;
510 InputMethodEditor.DataSet += DataSetEvent;
511 InputMethodEditor.LayoutSet += LayoutSetEvent;
512 InputMethodEditor.ReturnKeySet += ReturnKeySetEvent;
513 InputMethodEditor.ReturnKeyStateSet += ReturnKeyStateSetEvent;
514 InputMethodEditor.DisplayLanguageChanged += DisplayLanguageChangedEvent;
517 private static void UnregisterCallback()
519 InputMethodEditor.FocusedIn -= FocusInEvent;
520 InputMethodEditor.FocusedOut -= FocusOutEvent;
521 InputMethodEditor.RotationChanged -= RotationChangedEvent;
522 InputMethodEditor.AccessibilityStateChanged -= AccessibilityStateChangedEvent;
523 InputMethodEditor.SurroundingTextUpdated -= SurroundingTextUpdatedEvent;
524 InputMethodEditor.InputContextReset -= InputContextResetEvent;
525 InputMethodEditor.CursorPositionUpdated -= CursorPositionUpdatedEvent;
526 InputMethodEditor.LanguageSet -= LanguageSetEvent;
527 InputMethodEditor.DataSet -= DataSetEvent;
528 InputMethodEditor.LayoutSet -= LayoutSetEvent;
529 InputMethodEditor.ReturnKeySet -= ReturnKeySetEvent;
530 InputMethodEditor.ReturnKeyStateSet -= ReturnKeyStateSetEvent;
531 InputMethodEditor.DisplayLanguageChanged -= DisplayLanguageChangedEvent;
534 private static void DisplayLanguageChangedEvent(object sender, DisplayLanguageChangedEventArgs e)
536 Log.Info("NUIIME", "language : " + e.Language);
539 private static void ReturnKeyStateSetEvent(object sender, ReturnKeyStateSetEventArgs e)
541 Log.Info("NUIIME", "state : " + e.State.ToString());
542 SetReturnKeyDisable(e.State);
545 private static void ReturnKeySetEvent(object sender, ReturnKeySetEventArgs e)
547 Log.Info("NUIIME", "type : " + e.Type.ToString());
548 SetReturnKeyType(e.Type);
550 if (KeyboardState.Instance.VisibleState)
551 IMEShow(KeyboardState.Instance.FocusedContext);
554 private static void LayoutSetEvent(object sender, LayoutSetEventArgs e)
556 Log.Info("NUIIME", "layout : " + e.Layout.ToString());
557 KeyboardLayout newLayout = (KeyboardLayout)e.Layout;
558 KeyboardState keyboardState = KeyboardState.Instance;
560 if (newLayout < KeyboardLayout.Max)
562 if (keyboardState.Layout != newLayout)
563 keyboardState.NeedReset = true;
564 keyboardState.Layout = newLayout;
567 if (keyboardState.VisibleState)
568 IMEShow(KeyboardState.Instance.FocusedContext);
571 private static void DataSetEvent(object sender, SetDataEventArgs e)
573 Log.Info("NUIIME", "data length : " + e.DataLength.ToString());
576 private static void LanguageSetEvent(object sender, LanguageSetEventArgs e)
578 Log.Info("NUIIME", "language mode : " + e.Language.ToString());
581 private static void CursorPositionUpdatedEvent(object sender, CursorPositionUpdatedEventArgs e)
583 Log.Info("NUIIME", "cursor position : " + e.CursorPosition.ToString());
584 UpdateCursorPosition(e.CursorPosition);
587 private static void InputContextResetEvent(object sender, EventArgs e)
589 Log.Info("NUIIME", "");
592 private static void SurroundingTextUpdatedEvent(object sender, SurroundingTextUpdatedEventArgs e)
594 Log.Info("NUIIME", "context id : " + e.ContextId.ToString() + ", text : " + e.Text + ", cursor position : " + e.CursorPosition.ToString());
595 InputMethodEditor.DeleteSurroundingText(-(e.CursorPosition), e.Text.Length);
598 private static void AccessibilityStateChangedEvent(object sender, AccessibilityStateChangedEventArgs e)
600 Log.Info("NUIIME", "state : " + e.State.ToString());
603 private static void RotationChangedEvent(object sender, RotationChangedEventArgs e)
605 Log.Info("NUIIME", "degree : " + e.Degree.ToString());
606 SclNui.SetRotation(e.Degree);
609 private static void FocusOutEvent(object sender, FocusedOutEventArgs e)
611 Log.Info("NUIIME", "context id : " + e.ContextId.ToString());
612 KeyboardState.Instance.FocusedContext = 0;
613 KeyboardState.Instance.ResetMultitapState(true);
617 private static void FocusInEvent(object sender, FocusedInEventArgs e)
619 Log.Info("NUIIME", "context id : " + e.ContextId.ToString());
620 KeyboardState keyboardState = KeyboardState.Instance;
621 if (keyboardState.CheckContextTemporary(keyboardState.Context) && !keyboardState.CheckContextTemporary(e.ContextId))
622 keyboardState.Context = e.ContextId;
623 keyboardState.FocusedContext = e.ContextId;
627 private static void SetIMESize()
630 SclNui.GetInputMode(out inputModePtr);
631 string inputMode = Marshal.PtrToStringAnsi(inputModePtr);
633 int portraitWidth, portraitHeight, landscapeWidth, landscapeHeight;
634 SclNui.GetInputModeSize(inputMode, (int)WindowAttribute.DisplayMode.Portrait, out portraitWidth, out portraitHeight);
635 SclNui.GetInputModeSize(inputMode, (int)WindowAttribute.DisplayMode.Landscape, out landscapeWidth, out landscapeHeight);
637 IntPtr nativeHandle = new Window.SafeNativeWindowHandle().DangerousGetHandle();
638 InputMethodEditor.SetSize(nativeHandle, portraitWidth, portraitHeight, landscapeWidth, landscapeHeight);
641 private static void UpdateSpaceKey()
643 int languageNum = LanguageManager.Instance.GetLanguagesNum();
644 Log.Info("NUIIME", "language number : " + languageNum.ToString());
646 if (languageNum <= 1)
648 LanguageInfo languageInfo = LanguageManager.Instance.GetLanguageInfo(LanguageManager.Instance.GetCurrentLanguage());
649 if (languageInfo != null && languageInfo.Enabled)
651 SclNui.EnableButton("SPACE_ARROW_LEFT", false);
652 SclNui.EnableButton("SPACE_ARROW_RIGHT", false);
657 SclNui.EnableButton("SPACE_ARROW_LEFT", true);
658 SclNui.EnableButton("SPACE_ARROW_RIGHT", true);
662 static void Main(string[] args)
664 InputMethodEditor.Run(Create, Terminate, Show, Hide);
666 var app = new Program("", WindowMode.Opaque, WindowType.Ime);