Fix crash issue due to NUI API change
[platform/core/uifw/ise-default-nui.git] / ISEDefaultNUI / ISEDefaultNUI.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Runtime.InteropServices;
4 using System.Threading.Tasks;
5 using System.Xml;
6 using Tizen;
7 using Tizen.Applications;
8 using Tizen.NUI;
9 using Tizen.NUI.Components;
10 using Tizen.Uix.InputMethod;
11 using static Interop.SclNuiCSharp;
12
13 namespace ISEDefaultNUI
14 {
15     class Program : NUIApplication
16     {
17         private static Navigator navigator = null;
18         private static SCLNUI SclNui = null;
19         private static SCLDBUS SclDbus = null;
20
21         public Program(string styleSheet, WindowMode windowMode, WindowType type) : base(styleSheet, windowMode, type)
22         {
23         }
24
25         protected override void OnCreate()
26         {
27             base.OnCreate();
28             InputMethodEditor.Create();
29             RegisterCallback();
30         }
31
32         protected override void OnTerminate()
33         {
34             base.OnTerminate();
35         }
36
37         static private void RegisterLanguageInfo()
38         {
39             string xmlURL = Application.Current.DirectoryInfo.Resource + "ise_lang_table.xml";
40             try
41             {
42                 XmlDocument xml = new XmlDocument();
43                 xml.Load(xmlURL);
44
45                 XmlElement KeyList = xml.DocumentElement;
46                 XmlNodeList uuidList = xml.SelectNodes("/languages/keyboard_uuid_table/rec");
47                 XmlNodeList languageList = xml.SelectNodes("/languages/language_table/rec");
48
49                 foreach (XmlNode node in uuidList)
50                 {
51                     KeyboardUuidInfo uuidInfo = new KeyboardUuidInfo();
52                     uuidInfo.Name = node.Attributes["name"]?.Value;
53                     uuidInfo.Uuid = node.Attributes["uuid"]?.Value;
54                     LanguageManager.Instance.AddUuidInfo(uuidInfo);
55                 }
56
57                 foreach (XmlNode node in languageList)
58                 {
59                     InputModeInfo inputModeInfo = new InputModeInfo();
60                     inputModeInfo.Name = node.Attributes["inputmode_QTY"]?.Value;
61                     inputModeInfo.DisplayName = node.Attributes["inputmode_QTY_name"]?.Value;
62
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;
74
75                     if (node.Attributes["is_latin_language"] != null)
76                         languageInfo.IsLatinLanguage = Convert.ToBoolean(node.Attributes["is_latin_language"].Value);
77
78                     if (node.Attributes["accepts_caps_mode"] != null)
79                         languageInfo.AcceptsCapsMode = Convert.ToBoolean(node.Attributes["accepts_caps_mode"].Value);
80
81                     languageInfo.Enabled = false;
82                     languageInfo.SelectedInputMode = inputModeInfo.Name;
83
84                     LanguageManager.Instance.AddLanguage(languageInfo);
85                 }
86             }
87             catch(Exception ex)
88             {
89                 Log.Error("NUIIME", "Failed to load XML data. error = " + ex.ToString());
90             }
91         }
92
93         static async void DbusInitialize()
94         {
95             await Task.Run(() =>
96             {
97                 int ret = SclDbus.Init();
98                 if (ret != 0)
99                     Log.Info("NUIIME", "Failed to initialize dbus");
100             });
101         }
102
103         private static void Create()
104         {
105             SclNui = new SCLNUI(navigator);
106             SclDbus = new SCLDBUS();
107             Task.Run(() => DbusInitialize());
108
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);
113
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);
120
121             Window window = NUIApplication.GetDefaultWindow();
122             navigator = new Navigator()
123             {
124                 WidthResizePolicy = ResizePolicyType.FillToParent,
125                 HeightResizePolicy = ResizePolicyType.FillToParent
126             };
127             window.Add(navigator);
128
129             RegisterLanguageInfo();
130             bool exists = Preference.Contains(ResourceManager.IseConfigKeypadMode);
131             if (!exists)
132                 IseConfig.Instance.WriteIseConfig();
133
134             IseConfig.Instance.ReadIseConfig();
135             LanguageManager.Instance.SetEnabledLanguages(IseConfig.Instance.EnabledLanguages);
136
137             SclNui.Init(Application.Current.DirectoryInfo.Resource + "main_entry.xml");
138             SclNui.EnableSound(false);
139             SclNui.EnableVibration(false);
140             SclNui.EnableMagnifier(false);
141
142             LanguageInfo currentLanguage = LanguageManager.Instance.GetLanguageInfo(IseConfig.Instance.SelectedLanguage);
143             if (!currentLanguage.LoadInIME)
144             {
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);
149                 */
150             }
151         }
152
153         private static void Terminate()
154         {
155             UnregisterCallback();
156             SclNui.Fini();
157             SclDbus.Shutdown();
158             InputMethodEditor.Destroy();
159         }
160
161         private static void Show(InputMethodEditor.ContextId a, Tizen.Uix.InputMethod.InputMethodContext b)
162         {
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);
171             ResetContext();
172
173             if (b.Language == InputPanelLanguage.Alphabet)
174             {
175                 Log.Info("NUIIME", "prefer latin");
176                 KeyboardState.Instance.PreferLatin = true;
177             }
178             else
179             {
180                 Log.Info("NUIIME", "prefer automatic");
181                 KeyboardState.Instance.PreferLatin = false;
182             }
183
184             SetLayout((KeyboardLayout)b.Layout, (uint)b.LayoutVariation);
185             SetReturnKeyType(b.ReturnKey);
186             SetReturnKeyDisable(b.ReturnKeyState);
187
188             switch (autoCapitalization)
189             {
190                 case AutoCapitalization.Word:
191                 case AutoCapitalization.Sentence:
192                 case AutoCapitalization.AllCharacter:
193                     SetCapsMode(true);
194                     break;
195                 case AutoCapitalization.None:
196                 case AutoCapitalization.Undefined:
197                 default:
198                     SetCapsMode(false);
199                     break;
200             }
201             UpdateCursorPosition(b.CursorPosition);
202
203             IMEShow(inputContext);
204             SclNui.SetUpdatePending(false);
205             navigator.Push(SclNui);
206         }
207
208         private static void Hide(InputMethodEditor.ContextId a)
209         {
210             if (!KeyboardState.Instance.VisibleState)
211                 return;
212
213             IMEHide();
214             navigator.Pop();
215         }
216
217         private static void IMEHide()
218         {
219             SclNui.ClearClickCount();
220             SclNui.SetUpdatePending(true);
221             SclNui.DisableInputEvent(true);
222             SclNui.Hide();
223
224             KeyboardState.Instance.VisibleState = false;
225             ResetShiftState();
226             KeyboardState.Instance.ResetMultitapState(true);
227         }
228
229         private static void IMEShow(int ic)
230         {
231             switch (KeyboardState.Instance.Layout)
232             {
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);
239                     */
240                     break;
241                 default:
242                     break;
243             }
244
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;
253
254             SclNui.SetInputMode(languageinfo.SelectedInputMode);
255             SclNui.SetCurrentSublayout("DEFAULT");
256             SclNui.SetStringSubstitution("_LANGUAGE_", languageinfo.DisplayName);
257             SclNui.EnableMagnifier(IseConfig.Instance.PreviewOn);
258
259             KeyboardState.Instance.VisibleState = true;
260
261             if (keyboardState.Context != ic ||  keyboardState.NeedReset || !iseConfig.SelectedLanguage.Equals(currentLanguage))
262                 resetInputMode = true;
263
264             keyboardState.NeedReset = false;
265
266             bool forcePrimaryLatin = false;
267             if (!languageinfo.IsLatinLanguage)
268             {
269                 if (!keyboardState.DisableForceLatin)
270                 {
271                     if(defaultValue.Values[(int)keyboardState.Layout].ForceLatin)
272                     {
273                         forcePrimaryLatin = true;
274                     }
275                     else
276                     {
277                         if (keyboardState.PreferLatin)
278                             forcePrimaryLatin = true;
279                     }
280                 }
281             }
282
283             if(forcePrimaryLatin)
284             {
285                 bool selected = false;
286                 for (int loop = 0; !selected && loop < languageManager.GetLanguagesNum(); loop++)
287                 {
288                     languageinfo = languageManager.GetLanguageInfo(loop);
289                     if (languageinfo != null)
290                     {
291                         if (languageinfo.Enabled && languageinfo.IsLatinLanguage)
292                         {
293                             selected = languageManager.SelectLanguage(languageinfo);
294                             if (selected)
295                                 forcePrimaryLatin = false;
296                         }
297                     }
298                 }
299             }
300
301             if (resetInputMode)
302             {
303                 ResetContext();
304
305                 if (!keyboardState.CapsMode)
306                     SclNui.SetShiftState((uint)ShiftState.Off);
307
308                 if (keyboardState.Layout < KeyboardLayout.Max)
309                 {
310                     uint layoutIndex = (uint)keyboardState.Layout;
311                     if (keyboardState.Layout == KeyboardLayout.NumberOnly && keyboardState.LayoutVariation > 0 &&
312                         keyboardState.LayoutVariation < ResourceManager.LayoutNumberOnlyVariationMax)
313                     {
314                         layoutIndex = (uint)KeyboardLayout.NumberOnlySig + keyboardState.LayoutVariation - 1;
315                     }
316                     else if (keyboardState.Layout == KeyboardLayout.Password && keyboardState.LayoutVariation > 0)
317                     {
318                         layoutIndex = (uint)KeyboardLayout.Password_3X4;
319                     }
320
321                     bool fileNameLayout = false;
322                     if (keyboardState.Layout == KeyboardLayout.Normal && keyboardState.LayoutVariation == (uint)KeyboardLayoutNormalVariation.FileName)
323                         fileNameLayout = true;
324                     else
325                         fileNameLayout = false;
326
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);
334
335                     Log.Info("NUIIME", "new layout index : " + layoutIndex.ToString());
336
337                     if(defaultValue.Values[(int)layoutIndex].InputMode.Length > 0)
338                     {
339                         SclNui.SetInputMode(defaultValue.Values[(int)layoutIndex].InputMode);
340                     }
341
342                     SclNui.SetCurrentSublayout(defaultValue.Values[(int)layoutIndex].SublayoutName);
343                 }
344             }
345
346             LanguageInfo languageInfo = LanguageManager.Instance.GetLanguageInfo(currentLanguage);
347             if (languageInfo != null)
348             {
349                 if (languageInfo.AcceptsCapsMode)
350                 {
351                     if (keyboardState.Layout != KeyboardLayout.Normal)
352                     {
353                         SclNui.SetAutocapitalShiftState(true);
354                         SclNui.SetShiftState((uint)ShiftState.Off);
355                     }
356                     else
357                     {
358                         Common.SendKeyEvent((KeyCode)ResourceManager.MVKShiftEnable);
359                         if (keyboardState.CapsMode)
360                             SclNui.SetAutocapitalShiftState(false);
361                     }
362                 }
363                 else
364                 {
365                     SclNui.SetAutocapitalShiftState(true);
366                     Common.SendKeyEvent((KeyCode)ResourceManager.MVKShiftDisable);
367                     SclNui.SetShiftState((uint)ShiftState.Off);
368                 }
369             }
370             else
371             {
372                 SclNui.SetAutocapitalShiftState(true);
373             }
374
375             UpdateSpaceKey();
376             SclNui.Show();
377             SclNui.DisableInputEvent(false);
378             SetIMESize();
379         }
380
381         private static void ResetContext()
382         {
383             KeyboardState.Instance.ResetMultitapState(true);
384             KeyboardState.Instance.DisableForceLatin = false;
385             LanguageManager.Instance.ResetLanguage(IseConfig.Instance.SelectedLanguage);
386         }
387
388         private static void SetLayout(KeyboardLayout layout, UInt32 layoutVariation)
389         {
390             KeyboardState keyboardState = KeyboardState.Instance;
391             if (layout < KeyboardLayout.Max)
392             {
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());
398             }
399         }
400
401         private static void SetReturnKeyType(InputPanelReturnKey returnKey)
402         {
403             Log.Info("NUIIME", "return key : " + returnKey.ToString());
404             string label = string.Empty;
405             switch (returnKey)
406             {
407                 case InputPanelReturnKey.Done:
408                     label = Resource.Resources.IDS_IME_SK_DONE_ABB;
409                     break;
410                 case InputPanelReturnKey.Go:
411                     label = Resource.Resources.IDS_IME_BUTTON_GO_M_KEYBOARD;
412                     break;
413                 case InputPanelReturnKey.Join:
414                     label = Resource.Resources.IDS_IME_BUTTON_JOIN_M_KEYBOARD;
415                     break;
416                 case InputPanelReturnKey.Login:
417                     label = Resource.Resources.IDS_IME_BUTTON_LOG_IN_M_KEYBOARD;
418                     break;
419                 case InputPanelReturnKey.Next:
420                     label = Resource.Resources.IDS_IME_OPT_NEXT_ABB;
421                     break;
422                 case InputPanelReturnKey.Search:
423                     label = Resource.Resources.IDS_IME_BUTTON_SEARCH_M_KEYBOARD;
424                     break;
425                 case InputPanelReturnKey.Send:
426                     label = Resource.Resources.IDS_IME_BUTTON_SEND_M_KEYBOARD;
427                     break;
428                 case InputPanelReturnKey.SignIn:
429                     label = Resource.Resources.IDS_IME_BUTTON_SIGN_IN_M_KEYBOARD;
430                     break;
431                 case InputPanelReturnKey.Default:
432                     break;
433                 default:
434                     Log.Info("NUIIME", "Unknown return key : " + returnKey.ToString());
435                     returnKey = InputPanelReturnKey.Default;
436                     break;
437             }
438
439             if (returnKey == InputPanelReturnKey.Default)
440             {
441                 SclNui.UnsetPrivateKey("Enter");
442             }
443             else
444             {
445                 string[] imageLabel = {" ", " ", " "};
446                 SclNui.SetPrivateKey("Enter", label, imageLabel, null, 0, "Enter", true);
447             }
448             Log.Info("NUIIME", "return key label : " + label);
449         }
450
451         private static void SetReturnKeyDisable(bool disable)
452         {
453             Log.Info("NUIIME", "return key disable : " + disable);
454             SclNui.EnableButton("Enter", !disable);
455         }
456
457         private static void SetCapsMode(bool enable)
458         {
459             Log.Info("NUIIME", "capsmode : " + enable.ToString());
460             KeyboardState keyboardState = KeyboardState.Instance;
461             keyboardState.CapsMode = enable;
462             keyboardState.CapsModePending = false;
463
464             string currentLanguage = LanguageManager.Instance.GetCurrentLanguage();
465             if (currentLanguage != null)
466             {
467                 LanguageInfo languageInfo = LanguageManager.Instance.GetLanguageInfo(currentLanguage);
468                 if (languageInfo != null && languageInfo.AcceptsCapsMode)
469                 {
470                     if (keyboardState.PreviousModifier != (uint)SclNuiKeyModifier.MultitapStart && keyboardState.PreviousModifier != (uint)SclNuiKeyModifier.MultitapRepeat)
471                         keyboardState.SetCapsmode(keyboardState.CapsMode);
472                     else
473                         keyboardState.CapsModePending = true;
474                 }
475             }
476         }
477
478         private static void UpdateCursorPosition(int position)
479         {
480             KeyboardState keyboardState = KeyboardState.Instance;
481             if (keyboardState.Layout == KeyboardLayout.URL)
482             {
483                 if (position > 0)
484                     SclNui.SetStringSubstitution("www.", ".com");
485                 else
486                     SclNui.UnsetStringSubstitution("www.");
487             }
488         }
489
490         private static void ResetShiftState()
491         {
492             uint oldState, newState;
493             SclNui.GetShiftState(out oldState);
494             newState = (uint)ShiftState.Off;
495
496             if (oldState != newState)
497                 SclNui.SetShiftState(newState);
498         }
499
500         private static void RegisterCallback()
501         {
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;
515         }
516
517         private static void UnregisterCallback()
518         {
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;
532         }
533
534         private static void DisplayLanguageChangedEvent(object sender, DisplayLanguageChangedEventArgs e)
535         {
536             Log.Info("NUIIME", "language : " + e.Language);
537         }
538
539         private static void ReturnKeyStateSetEvent(object sender, ReturnKeyStateSetEventArgs e)
540         {
541             Log.Info("NUIIME", "state : " + e.State.ToString());
542             SetReturnKeyDisable(e.State);
543         }
544
545         private static void ReturnKeySetEvent(object sender, ReturnKeySetEventArgs e)
546         {
547             Log.Info("NUIIME", "type : " + e.Type.ToString());
548             SetReturnKeyType(e.Type);
549
550             if (KeyboardState.Instance.VisibleState)
551                 IMEShow(KeyboardState.Instance.FocusedContext);
552         }
553
554         private static void LayoutSetEvent(object sender, LayoutSetEventArgs e)
555         {
556             Log.Info("NUIIME", "layout : " + e.Layout.ToString());
557             KeyboardLayout newLayout = (KeyboardLayout)e.Layout;
558             KeyboardState keyboardState = KeyboardState.Instance;
559
560             if (newLayout < KeyboardLayout.Max)
561             {
562                 if (keyboardState.Layout != newLayout)
563                     keyboardState.NeedReset = true;
564                 keyboardState.Layout = newLayout;
565             }
566
567             if (keyboardState.VisibleState)
568                 IMEShow(KeyboardState.Instance.FocusedContext);
569         }
570
571         private static void DataSetEvent(object sender, SetDataEventArgs e)
572         {
573             Log.Info("NUIIME", "data length : " + e.DataLength.ToString());
574         }
575
576         private static void LanguageSetEvent(object sender, LanguageSetEventArgs e)
577         {
578             Log.Info("NUIIME", "language mode : " + e.Language.ToString());
579         }
580
581         private static void CursorPositionUpdatedEvent(object sender, CursorPositionUpdatedEventArgs e)
582         {
583             Log.Info("NUIIME", "cursor position : " + e.CursorPosition.ToString());
584             UpdateCursorPosition(e.CursorPosition);
585         }
586
587         private static void InputContextResetEvent(object sender, EventArgs e)
588         {
589             Log.Info("NUIIME", "");
590         }
591
592         private static void SurroundingTextUpdatedEvent(object sender, SurroundingTextUpdatedEventArgs e)
593         {
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);
596         }
597
598         private static void AccessibilityStateChangedEvent(object sender, AccessibilityStateChangedEventArgs e)
599         {
600             Log.Info("NUIIME", "state : " + e.State.ToString());
601         }
602
603         private static void RotationChangedEvent(object sender, RotationChangedEventArgs e)
604         {
605             Log.Info("NUIIME", "degree : " + e.Degree.ToString());
606             SclNui.SetRotation(e.Degree);
607         }
608
609         private static void FocusOutEvent(object sender, FocusedOutEventArgs e)
610         {
611             Log.Info("NUIIME", "context id : " + e.ContextId.ToString());
612             KeyboardState.Instance.FocusedContext = 0;
613             KeyboardState.Instance.ResetMultitapState(true);
614             SclDbus.FocusOut();
615         }
616
617         private static void FocusInEvent(object sender, FocusedInEventArgs e)
618         {
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;
624             SclDbus.FocusIn();
625         }
626
627         private static void SetIMESize()
628         {
629             IntPtr inputModePtr;
630             SclNui.GetInputMode(out inputModePtr);
631             string inputMode = Marshal.PtrToStringAnsi(inputModePtr);
632
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);
636
637             IntPtr nativeHandle = new Window.SafeNativeWindowHandle().DangerousGetHandle();
638             InputMethodEditor.SetSize(nativeHandle, portraitWidth, portraitHeight, landscapeWidth, landscapeHeight);
639         }
640
641         private static void UpdateSpaceKey()
642         {
643             int languageNum = LanguageManager.Instance.GetLanguagesNum();
644             Log.Info("NUIIME", "language number : " + languageNum.ToString());
645
646             if (languageNum <= 1)
647             {
648                 LanguageInfo languageInfo = LanguageManager.Instance.GetLanguageInfo(LanguageManager.Instance.GetCurrentLanguage());
649                 if (languageInfo != null && languageInfo.Enabled)
650                 {
651                     SclNui.EnableButton("SPACE_ARROW_LEFT", false);
652                     SclNui.EnableButton("SPACE_ARROW_RIGHT", false);
653                 }
654             }
655             else
656             {
657                 SclNui.EnableButton("SPACE_ARROW_LEFT", true);
658                 SclNui.EnableButton("SPACE_ARROW_RIGHT", true);
659             }
660         }
661
662         static void Main(string[] args)
663         {
664             InputMethodEditor.Run(Create, Terminate, Show, Hide);
665
666             var app = new Program("", WindowMode.Opaque, WindowType.Ime);
667             app.Run(args);
668         }
669     }
670 }