/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using static Interop.InputMethod;
namespace Tizen.Uix.InputMethod
{
///
/// Enumeration of the key codes.
/// If keycode & 0xff000000 == 0x01000000 then this key code is directly encoded 24-bit UCS character.The UCS value is keycode & 0x00ffffff.
/// Defines the list of keys supported by the system.Note that certain keys may not be available on all devices.
///
public enum KeyCode
{
///
/// The backspace key
///
BackSpace = 0xFF08,
///
/// The tab key
///
Tab = 0xFF09,
///
/// The linefeed key
///
Linefeed = 0xFF0A,
///
/// The clear key
///
Clear = 0xFF0B,
///
/// The return key
///
Return = 0xFF0D,
///
/// The pause key
///
Pause = 0xFF13,
///
/// The scroll lock key
///
ScrollLock = 0xFF14,
///
/// The sys req key
///
SysReq = 0xFF15,
///
/// The escape key
///
Escape = 0xFF1B,
///
/// The delete key
///
Delete = 0xFFFF,
/* Cursor control & motion */
///
/// The home key
///
Home = 0xFF50,
///
/// The left directional key
///
Left = 0xFF51,
///
/// The up directional key
///
Up = 0xFF52,
///
/// The right directional key
///
Right = 0xFF53,
///
/// The down directional key
///
Down = 0xFF54,
///
/// The prior, previous key
///
Prior = 0xFF55,
///
/// The page up key
///
Page_Up = 0xFF55,
///
/// The next key
///
Next = 0xFF56,
///
/// The page down key
///
Page_Down = 0xFF56,
///
/// The end key
///
End = 0xFF57,
///
/// The begin key
///
Begin = 0xFF58,
/* Misc Functions */
///
/// The select key
///
Select = 0xFF60,
///
/// The print key
///
Print = 0xFF61,
///
/// The execute, run, do key
///
Execute = 0xFF62,
///
/// The insert key
///
Insert = 0xFF63,
///
/// The undo key
///
Undo = 0xFF65,
///
/// The redo key
///
Redo = 0xFF66,
///
/// The menu key
///
Menu = 0xFF67,
///
/// The find key
///
Find = 0xFF68,
///
/// The cancel, stop, abort, exit key
///
Cancel = 0xFF69,
///
/// The help key
///
Help = 0xFF6A,
///
/// The break key
///
Break = 0xFF6B,
///
/// The character set switch key
///
Mode_switch = 0xFF7E,
///
/// The num lock key
///
Num_Lock = 0xFF7F,
/* Keypad */
///
/// The Numpad space key
///
KPSpace = 0xFF80,
///
/// The Numpad tab key
///
KPTab = 0xFF89,
///
/// The Numpad enter key
///
KPEnter = 0xFF8D,
///
/// The Numpad function 1 key
///
KPF1 = 0xFF91,
///
/// The Numpad function 2 key
///
KPF2 = 0xFF92,
///
/// The Numpad function 3 key
///
KPF3 = 0xFF93,
///
/// The Numpad function 4 key
///
KPF4 = 0xFF94,
///
/// The Numpad home key
///
KPHome = 0xFF95,
///
/// The Numpad left key
///
KPLeft = 0xFF96,
///
/// The Numpad up key
///
KPUp = 0xFF97,
///
/// The Numpad right key
///
KPRight = 0xFF98,
///
/// The Numpad down key
///
KPDown = 0xFF99,
///
/// The Numpad prior, previous key
///
KPPrior = 0xFF9A,
///
/// The Numpad page up key
///
KPPage_Up = 0xFF9A,
///
/// The Numpad next key
///
KPNext = 0xFF9B,
///
/// The Numpad page down key
///
KPPage_Down = 0xFF9B,
///
/// The Numpad end key
///
KPEnd = 0xFF9C,
///
/// The Numpad begin key
///
KPBegin = 0xFF9D,
///
/// The Numpad insert key
///
KPInsert = 0xFF9E,
///
/// The Numpad delete key
///
KPDelete = 0xFF9F,
///
/// The Numpad equal key
///
KPEqual = 0xFFBD,
///
/// The Numpad multiply key
///
KPMultiply = 0xFFAA,
///
/// The Numpad add key
///
KPAdd = 0xFFAB,
///
/// The Numpad separator key
///
KPSeparator = 0xFFAC,
///
/// The Numpad subtract key
///
KPSubtract = 0xFFAD,
///
/// The Numpad decimal key
///
KPDecimal = 0xFFAE,
///
/// The Numpad divide key
///
KPDivide = 0xFFAF,
///
/// The Numpad 0 key
///
KP0 = 0xFFB0,
///
/// The Numpad 1 key
///
KP1 = 0xFFB1,
///
/// The Numpad 2 key
///
KP2 = 0xFFB2,
///
/// The Numpad 3 key
///
KP3 = 0xFFB3,
///
/// The Numpad 4 key
///
KP4 = 0xFFB4,
///
/// The Numpad 5 key
///
KP5 = 0xFFB5,
///
/// The Numpad 6 key
///
KP6 = 0xFFB6,
///
/// The Numpad 7 key
///
KP7 = 0xFFB7,
///
/// The Numpad 8 key
///
KP8 = 0xFFB8,
///
/// The Numpad 9 key
///
KP9 = 0xFFB9,
/* Auxilliary Functions */
///
/// The function 1 key
///
F1 = 0xFFBE,
///
/// The function 2 key
///
F2 = 0xFFBF,
///
/// The function 3 key
///
F3 = 0xFFC0,
///
/// The function 4 key
///
F4 = 0xFFC1,
///
/// The function 5 key
///
F5 = 0xFFC2,
///
/// The function 6 key
///
F6 = 0xFFC3,
///
/// The function 7 key
///
F7 = 0xFFC4,
///
/// The function 8 key
///
F8 = 0xFFC5,
///
/// The function 9 key
///
F9 = 0xFFC6,
///
/// The function 10 key
///
F10 = 0xFFC7,
///
/// The function 11 key
///
F11 = 0xFFC8,
///
/// The function 12 key
///
F12 = 0xFFC9,
///
/// The function 13 key
///
F13 = 0xFFCA,
///
/// The function 14 key
///
F14 = 0xFFCB,
///
/// The function 15 key
///
F15 = 0xFFCC,
///
/// The function 16 key
///
F16 = 0xFFCD,
///
/// The function 17 key
///
F17 = 0xFFCE,
///
/// The function 18 key
///
F18 = 0xFFCF,
///
/// The function 19 key
///
F19 = 0xFFD0,
///
/// The function 20 key
///
F20 = 0xFFD1,
///
/// The function 21 key
///
F21 = 0xFFD2,
///
/// The function 22 key
///
F22 = 0xFFD3,
///
/// The function 23 key
///
F23 = 0xFFD4,
///
/// The function 24 key
///
F24 = 0xFFD5,
///
/// The function 25 key
///
F25 = 0xFFD6,
///
/// The function 26 key
///
F26 = 0xFFD7,
///
/// The function 27 key
///
F27 = 0xFFD8,
///
/// The function 28 key
///
F28 = 0xFFD9,
///
/// The function 29 key
///
F29 = 0xFFDA,
///
/// The function 30 key
///
F30 = 0xFFDB,
///
/// The function 31 key
///
F31 = 0xFFDC,
///
/// The function 32 key
///
F32 = 0xFFDD,
///
/// The function 33 key
///
F33 = 0xFFDE,
///
/// The function 34 key
///
F34 = 0xFFDF,
///
/// The function 35 key
///
F35 = 0xFFE0,
/* Modifier keys */
///
/// The left shift key
///
ShiftL = 0xFFE1,
///
/// The right shift key
///
ShiftR = 0xFFE2,
///
/// The left control key
///
ControlL = 0xFFE3,
///
/// The right control key
///
ControlR = 0xFFE4,
///
/// The caps lock key
///
CapsLock = 0xFFE5,
///
/// The shift lock key
///
ShiftLock = 0xFFE6,
///
/// The left meta key
///
MetaL = 0xFFE7,
///
/// The right meta key
///
MetaR = 0xFFE8,
///
/// The left alt key
///
AltL = 0xFFE9,
///
/// The right alt key
///
AltR = 0xFFEA,
///
/// The left super key
///
SuperL = 0xFFEB,
///
/// The right super key
///
SuperR = 0xFFEC,
///
/// The left hyper key
///
HyperL = 0xFFED,
///
/// The right hyper key
///
HyperR = 0xFFEE,
/* Latin 1 */
///
/// The space key
///
Space = 0x020,
///
/// The exclamation key
///
Exclam = 0x021,
///
/// The quotedbl key
///
Quotedbl = 0x022,
///
/// The number sign key
///
NumberSign = 0x023,
///
/// The dollar key
///
Dollar = 0x024,
///
/// The percent key
///
Percent = 0x025,
///
/// The ampersand key
///
Ampersand = 0x026,
///
/// The apostrophe key
///
Apostrophe = 0x027,
///
/// The parenleft key
///
Parenleft = 0x028,
///
/// The parenright key
///
Parenright = 0x029,
///
/// The asterisk key
///
Asterisk = 0x02a,
///
/// The plus key
///
Plus = 0x02b,
///
/// The comma key
///
Comma = 0x02c,
///
/// The minus key
///
Minus = 0x02d,
///
/// The period key
///
Period = 0x02e,
///
/// The slash key
///
Slash = 0x02f,
///
/// The 0 key
///
Keypad0 = 0x030,
///
/// The 1 key
///
Keypad1 = 0x031,
///
/// The 2 key
///
Keypad2 = 0x032,
///
/// The 3 key
///
Keypad3 = 0x033,
///
/// The 4 key
///
Keypad4 = 0x034,
///
/// The 5 key
///
Keypad5 = 0x035,
///
/// The 6 key
///
Keypad6 = 0x036,
///
/// The 7 key
///
Keypad7 = 0x037,
///
/// The 8 key
///
Keypad8 = 0x038,
///
/// The 9 key
///
Keypad9 = 0x039,
///
/// The colon key
///
Colon = 0x03a,
///
/// The semicolon key
///
Semicolon = 0x03b,
///
/// The less key
///
Less = 0x03c,
///
/// The equal key
///
Equal = 0x03d,
///
/// The greater key
///
Greater = 0x03e,
///
/// The question key
///
Question = 0x03f,
///
/// The at key
///
At = 0x040,
///
/// The A key
///
KeypadA = 0x041,
///
/// The B key
///
KeypadB = 0x042,
///
/// The C key
///
KeypadC = 0x043,
///
/// The D key
///
KeypadD = 0x044,
///
/// The E key
///
KeypadE = 0x045,
///
/// The F key
///
KeypadF = 0x046,
///
/// The G key
///
KeypadG = 0x047,
///
/// The H key
///
KeypadH = 0x048,
///
/// The I key
///
KeypadI = 0x049,
///
/// The J key
///
KeypadJ = 0x04a,
///
/// The K key
///
KeypadK = 0x04b,
///
/// The L key
///
KeypadL = 0x04c,
///
/// The M key
///
KeypadM = 0x04d,
///
/// The N key
///
KeypadN = 0x04e,
///
/// The O key
///
KeypadO = 0x04f,
///
/// The P key
///
KeypadP = 0x050,
///
/// The Q key
///
KeypadQ = 0x051,
///
/// The R key
///
KeypadR = 0x052,
///
/// The S key
///
KeypadS = 0x053,
///
/// The T key
///
KeypadT = 0x054,
///
/// The U key
///
KeypadU = 0x055,
///
/// The V key
///
KeypadV = 0x056,
///
/// The W key
///
KeypadW = 0x057,
///
/// The X key
///
KeypadX = 0x058,
///
/// The Y key
///
KeypadY = 0x059,
///
/// The Z key
///
KeypadZ = 0x05a,
///
/// The left bracket key
///
BracketLeft = 0x05b,
///
/// The backslash key
///
Backslash = 0x05c,
///
/// The right bracket key
///
BracketRight = 0x05d,
///
/// The circumflex key
///
AsciiCircum = 0x05e,
///
/// The underscore key
///
Underscore = 0x05f,
///
/// The grave key
///
Grave = 0x060,
///
/// The a key
///
Keypada = 0x061,
///
/// The b key
///
Keypadb = 0x062,
///
/// The c key
///
Keypadc = 0x063,
///
/// The d key
///
Keypadd = 0x064,
///
/// The e key
///
Keypade = 0x065,
///
/// The f key
///
Keypadf = 0x066,
///
/// The g key
///
Keypadg = 0x067,
///
/// The h key
///
Keypadh = 0x068,
///
/// The i key
///
Keypadi = 0x069,
///
/// The j key
///
Keypadj = 0x06a,
///
/// The k key
///
Keypadk = 0x06b,
///
/// The l key
///
Keypadl = 0x06c,
///
/// The m key
///
Keypadm = 0x06d,
///
/// The n key
///
Keypadn = 0x06e,
///
/// The o key
///
Keypado = 0x06f,
///
/// The p key
///
Keypadp = 0x070,
///
/// The q key
///
Keypadq = 0x071,
///
/// The r key
///
Keypadr = 0x072,
///
/// The s key
///
Keypads = 0x073,
///
/// The t key
///
Keypadt = 0x074,
///
/// The u key
///
Keypadu = 0x075,
///
/// The v key
///
Keypadv = 0x076,
///
/// The w key
///
Keypadw = 0x077,
///
/// The x key
///
Keypadx = 0x078,
///
/// The y key
///
Keypady = 0x079,
///
/// The z key
///
Keypadz = 0x07a,
///
/// The left brace key
///
BraceLeft = 0x07b,
///
/// The bar key
///
Bar = 0x07c,
///
/// The right brace key
///
BraceRight = 0x07d,
///
/// The tilde key
///
AsciiTilde = 0x07e,
};
///
/// Enumeration of the key masks.
/// The key masks indicate which modifier keys is pressed down during the keyboard hit.The special MASK_RELEASED indicates the key release event.
///
public enum KeyMask
{
///
/// Key press event without modifier key
///
Pressed = 0,
///
/// The Shift key is pressed down
///
Shift = (1 << 0),
///
/// The CapsLock key is pressed down
///
CapsLock = (1 << 1),
///
/// The Control key is pressed down
///
Control = (1 << 2),
///
/// The Alt key is pressed down
///
Alt = (1 << 3),
///
/// The Meta key is pressed down
///
Meta = (1 << 4),
///
/// The Win (between Control and Alt) is pressed down
///
Win = (1 << 5),
///
/// The Hyper key is pressed down
///
Hyper = (1 << 6),
///
/// The NumLock key is pressed down
///
NumLock = (1 << 7),
///
/// Key release event
///
Released = (1 << 15),
}
///
/// This class contains api's related to IME(Input method editor)
///
public static class InputMethodEditor
{
private static Object thisLock = new Object();
private static ImeCallbackStructGCHandle _imeCallbackStructGCHandle = new ImeCallbackStructGCHandle();
private static event EventHandler _focusIn;
private static ImeFocusedInCb _imeFocusedInDelegate;
private static event EventHandler _focusOut;
private static ImeFocusedOutCb _imeFocusedOutDelegate;
private static event EventHandler _surroundingTextUpdated;
private static ImeSurroundingTextUpdatedCb _imeSurroundingTextUpdatedDelegate;
private static event EventHandler _inputContextReset;
private static ImeInputContextResetCb _imeInputContextResetDelegate;
private static event EventHandler _cursorPositionUpdated;
private static ImeCursorPositionitionUpdatedCb _imeCursorPositionitionUpdatedDelegate;
private static event EventHandler _langaugeSet;
private static ImeLanguageSetCb _imeLanguageSetDelegate;
private static event EventHandler _imDataSet;
private static ImeImdataSetCb _imeDataSetDelegate;
private static event EventHandler _layoutSet;
private static ImeLayoutSetCb _imeLayoutSetDelegate;
private static event EventHandler _returnKeyTypeSet;
private static ImeReturnKeySetCb _imeReturnKeySetDelegate;
private static event EventHandler _returnKeyStateSet;
private static ImeReturnKeyStateSetCb _imeReturnKeyStateSetDelegate;
private static ImeProcessKeyEventCb _imeProcessKeyDelegate;
private static event EventHandler _displayLanaguageChanged;
private static ImeDisplayLanguageChangedCb _imeDisplayLanaguageChangedDelegate;
private static event EventHandler _rotationDegreeChanged;
private static ImeRotationChangedCb _imeRotationChangedDelegate;
private static event EventHandler _accessibilityStateChanged;
private static ImeAccessibilityStateChangedCb _imeAccessibilityStateChangedDelegate;
private static event EventHandler _optionWindowCreated;
private static ImeOptionWindowCreatedCb _imeOptionWindowCreatedDelegate;
private static event EventHandler _optionWindowDestroyed;
private static ImeOptionWindowDestroyedCb _imeOptionWindowDestroyedDelegate;
private static ImeLanguageRequestedCb _imeLanguageRequestedDelegate;
private static OutAction _languageRequestedDelegate;
private static BoolAction _processKeyDelagate;
private static ImeImdataRequestedCb _imeImDataRequestedDelegate;
private static OutArrayAction _imDataRequestedDelegate;
private static ImeGeometryRequestedCb _imeGeometryRequestedDelegate;
private static OutAction _geometryRequestedDelegate;
private static Action _userCreate;
private static Action _userTerminate;
private static Action _userShow;
private static Action _userHide;
private static ImeCreateCb _create = (IntPtr userData) =>
{
Log.Info(LogTag, "In Create Delegate");
_userCreate?.Invoke();
};
private static ImeTerminateCb _terminate = (IntPtr userData) =>
{
Log.Info(LogTag, "In terminate Delegate");
_userTerminate?.Invoke();
_imeCallbackStructGCHandle.Dispose();
};
private static ImeShowCb _show = (int contextId, IntPtr context, IntPtr userData) =>
{
Log.Info(LogTag, "In Show Delegate");
_userShow?.Invoke(new ContextId(contextId), new InputMethodContext(context));
};
private static ImeHideCb _hide = (int contextId, IntPtr userData) =>
{
Log.Info(LogTag, "In Hide Delegate");
_userHide?.Invoke(new ContextId(contextId));
};
///
/// Structure representing ContextId
///
public struct ContextId : IEquatable
{
internal ContextId(int id)
{
Id = id;
}
internal int Id
{
get;
private set;
}
public bool Equals(ContextId other)
{
return this.Id == other.Id;
}
}
///
/// rectangle representing the position and size of UI Control
///
public struct Rect
{
///
/// The x position in screen
///
public int x;
///
/// The y position in screen
///
public int y;
///
/// The window width
///
public int w;
///
/// The window height
///
public int h;
}
///
/// An Action with 1 out parameter
///
/// Generic Type
/// The out parameter
public delegate void OutAction(out T a);
///
/// An Action with an array out parameter
///
/// Generic Type
/// The out parameter 1
public delegate void OutArrayAction(out T[] a);
///
/// An Action with 3 Input Parameter returning a bool
///
/// Generic Type for Parameter 1
/// Generic Type for Parameter 2
/// Generic Type for Parameter 3
/// The Input Parameter 1
/// The Input Parameter 2
/// The Input Parameter 3
///
public delegate bool BoolAction(T a, T1 b, T2 c);
///
/// Called when an associated text input UI control has focus.
///
public static event EventHandler FocusedIn
{
add
{
lock (thisLock)
{
_imeFocusedInDelegate = (int contextId, IntPtr userData) =>
{
FocusedInEventArgs args = new FocusedInEventArgs(contextId);
_focusIn?.Invoke(null, args);
};
ErrorCode error = ImeEventSetFocusedInCb(_imeFocusedInDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add FocusedIn Failed with error " + error);
}
else
{
_focusIn += value;
}
}
}
remove
{
lock (thisLock)
{
_focusIn -= value;
}
}
}
///
/// Called when an associated text input UI control loses focus.
///
public static event EventHandler FocusedOut
{
add
{
lock (thisLock)
{
_imeFocusedOutDelegate = (int contextId, IntPtr userData) =>
{
FocusedOutEventArgs args = new FocusedOutEventArgs(contextId);
_focusOut?.Invoke(null, args);
};
ErrorCode error = ImeEventSetFocusedOutCb(_imeFocusedOutDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add FocusedOut Failed with error " + error);
}
else
{
_focusOut += value;
}
}
}
remove
{
lock (thisLock)
{
_focusOut -= value;
}
}
}
///
/// Called when an associated text input UI control responds to a request with the surrounding text.
///
public static event EventHandler SurroundingTextUpdated
{
add
{
lock (thisLock)
{
_imeSurroundingTextUpdatedDelegate = (int contextId, IntPtr text, int cursorPos, IntPtr userData) =>
{
SurroundingTextUpdatedEventArgs args = new SurroundingTextUpdatedEventArgs(contextId, Marshal.PtrToStringAnsi(text), cursorPos);
_surroundingTextUpdated?.Invoke(null, args);
};
ErrorCode error = ImeEventSetSurroundingTextUpdatedCb(_imeSurroundingTextUpdatedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add SurroundingTextUpdated Failed with error " + error);
}
else
{
_surroundingTextUpdated += value;
}
}
}
remove
{
lock (thisLock)
{
_surroundingTextUpdated -= value;
}
}
}
///
/// Called to reset the input context of an associated text input UI control.
///
public static event EventHandler InputContextReset
{
add
{
lock (thisLock)
{
_imeInputContextResetDelegate = (IntPtr userData) =>
{
_inputContextReset?.Invoke(null, EventArgs.Empty);
};
ErrorCode error = ImeEventSetInputContextResetCb(_imeInputContextResetDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add InputContextReset Failed with error " + error);
}
else
{
_inputContextReset += value;
}
}
}
remove
{
lock (thisLock)
{
_inputContextReset -= value;
}
}
}
///
/// Called when the position of the cursor in an associated text input UI control changes.
///
public static event EventHandler CursorPositionitionUpdated
{
add
{
lock (thisLock)
{
_imeCursorPositionitionUpdatedDelegate = (int cursorPos, IntPtr userData) =>
{
CursorPositionitionUpdatedEventArgs args = new CursorPositionitionUpdatedEventArgs(cursorPos);
_cursorPositionUpdated?.Invoke(null, args);
};
ErrorCode error = ImeEventSetCursorPositionitionUpdatedCb(_imeCursorPositionitionUpdatedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add CursorPositionitionUpdated Failed with error " + error);
}
else
{
_cursorPositionUpdated += value;
}
}
}
remove
{
lock (thisLock)
{
_cursorPositionUpdated -= value;
}
}
}
///
/// Called to set the preferred language to the input panel.
/// It will be only called when the client application changes the edit field's language attribute after the input panel is shown.
///
public static event EventHandler LanguageSet
{
add
{
lock (thisLock)
{
_imeLanguageSetDelegate = (InputPanelLanguage language, IntPtr userData) =>
{
LanguageSetEventArgs args = new LanguageSetEventArgs(language);
_langaugeSet?.Invoke(null, args);
};
ErrorCode error = ImeEventSetLanguageSetCb(_imeLanguageSetDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add LanguageSet Failed with error " + error);
}
else
{
_langaugeSet += value;
}
}
}
remove
{
lock (thisLock)
{
_langaugeSet -= value;
}
}
}
///
/// Called to set the application specific data to deliver to the input panel.
///
public static event EventHandler DataSet
{
add
{
lock (thisLock)
{
_imeDataSetDelegate = (IntPtr data, uint dataLength, IntPtr userData) =>
{
byte[] destination = new byte[dataLength];
Marshal.Copy(data, destination, 0, (int)dataLength);
SetDataEventArgs args = new SetDataEventArgs(destination, dataLength);
_imDataSet?.Invoke(null, args);
};
ErrorCode error = ImeEventSetImdataSetCb(_imeDataSetDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add DataSet Failed with error " + error);
}
else
{
_imDataSet += value;
}
}
}
remove
{
lock (thisLock)
{
_imDataSet -= value;
}
}
}
///
/// Called when an associated text input UI control requests the input panel to set its layout.
/// It will be only called when the client application changes the edit field's layout attribute after the input panel is shown.
///
public static event EventHandler LayoutSet
{
add
{
lock (thisLock)
{
_imeLayoutSetDelegate = (InputPanelLayout layout, IntPtr userData) =>
{
LayoutSetEventArgs args = new LayoutSetEventArgs(layout);
_layoutSet?.Invoke(null, args);
};
ErrorCode error = ImeEventSetLayoutSetCb(_imeLayoutSetDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add LayoutSet Failed with error " + error);
}
else
{
_layoutSet += value;
}
}
}
remove
{
lock (thisLock)
{
_layoutSet -= value;
}
}
}
///
/// Called when an associated text input UI control requests the input panel to set the Return key label.
/// The input panel can show text or image on the Return button according to the Return key action.
///
public static event EventHandler ReturnKeySet
{
add
{
lock (thisLock)
{
_imeReturnKeySetDelegate = (InputPanelReturnKey type, IntPtr userData) =>
{
ReturnKeySetEventArgs args = new ReturnKeySetEventArgs(type);
_returnKeyTypeSet?.Invoke(null, args);
};
ErrorCode error = ImeEventSetReturnKeySetCb(_imeReturnKeySetDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add ReturnKeySet Failed with error " + error);
}
else
{
_returnKeyTypeSet += value;
}
}
}
remove
{
lock (thisLock)
{
_returnKeyTypeSet -= value;
}
}
}
///
/// Called when an associated text input UI control requests the input panel to enable or disable the Return key state.
///
public static event EventHandler ReturnKeyStateSet
{
add
{
lock (thisLock)
{
_imeReturnKeyStateSetDelegate = (bool state, IntPtr userData) =>
{
ReturnKeyStateSetEventArgs args = new ReturnKeyStateSetEventArgs(state);
_returnKeyStateSet?.Invoke(null, args);
};
ErrorCode error = ImeEventSetReturnKeyStateSetCb(_imeReturnKeyStateSetDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add ReturnKeyStateSet Failed with error " + error);
}
else
{
_returnKeyStateSet += value;
}
}
}
remove
{
lock (thisLock)
{
_returnKeyStateSet -= value;
}
}
}
///
/// Called when the system display language is changed.
///
public static event EventHandler DisplayLanaguageChanged
{
add
{
lock (thisLock)
{
_imeDisplayLanaguageChangedDelegate = (IntPtr language, IntPtr userData) =>
{
DisplayLanaguageChangedEventArgs args = new DisplayLanaguageChangedEventArgs(Marshal.PtrToStringAnsi(language));
_displayLanaguageChanged?.Invoke(null, args);
};
ErrorCode error = ImeEventSetDisplayLanguageChangedCb(_imeDisplayLanaguageChangedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add DisplayLanaguageChanged Failed with error " + error);
}
else
{
_displayLanaguageChanged += value;
}
}
}
remove
{
lock (thisLock)
{
_displayLanaguageChanged -= value;
}
}
}
///
/// Called when the device is rotated.
///
public static event EventHandler RotationChanged
{
add
{
lock (thisLock)
{
_imeRotationChangedDelegate = (int degree, IntPtr userData) =>
{
RotationChangedEventArgs args = new RotationChangedEventArgs(degree);
_rotationDegreeChanged?.Invoke(null, args);
};
ErrorCode error = ImeEventSetRotationChangedCb(_imeRotationChangedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add RotationChanged Failed with error " + error);
}
else
{
_rotationDegreeChanged += value;
}
}
}
remove
{
lock (thisLock)
{
_rotationDegreeChanged -= value;
}
}
}
///
/// Called when Accessibility in Settings application is on or off.
///
public static event EventHandler AccessibilityStateChanged
{
add
{
lock (thisLock)
{
_imeAccessibilityStateChangedDelegate = (bool state, IntPtr userData) =>
{
AccessibilityStateChangedEventArgs args = new AccessibilityStateChangedEventArgs(state);
_accessibilityStateChanged?.Invoke(null, args);
};
ErrorCode error = ImeEventSetAccessibilityStateChangedCb(_imeAccessibilityStateChangedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add AccessibilityStateChanged Failed with error " + error);
}
else
{
_accessibilityStateChanged += value;
}
}
}
remove
{
lock (thisLock)
{
_accessibilityStateChanged -= value;
}
}
}
///
/// Called to create the option window.
///
///
/// if Input panel requests to open the option window, type will be OptionWindowType.Keyboard.
/// And if Settings application requests to open it, type will be OptionWindowType.SettingApplication.
///
public static event EventHandler OptionWindowCreated
{
add
{
lock (thisLock)
{
_imeOptionWindowCreatedDelegate = (IntPtr window, OptionWindowType type, IntPtr userData) =>
{
OptionWindow._handle = window;
OptionWindowCreatedEventArgs args = new OptionWindowCreatedEventArgs(new OptionWindow(), type);
_optionWindowCreated?.Invoke(null, args);
};
ErrorCode error = ImeEventSetOptionWindowCreatedCb(_imeOptionWindowCreatedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add OptionWindowCreated Failed with error " + error);
}
else
{
_optionWindowCreated += value;
}
}
}
remove
{
lock (thisLock)
{
_optionWindowCreated -= value;
}
}
}
///
/// Called to destroy the option window.
///
public static event EventHandler OptionWindowDestroyed
{
add
{
lock (thisLock)
{
_imeOptionWindowDestroyedDelegate = (IntPtr window, IntPtr userData) =>
{
OptionWindow._handle = window;
OptionWindowDestroyedEventArgs args = new OptionWindowDestroyedEventArgs(new OptionWindow());
_optionWindowDestroyed?.Invoke(null, args);
};
ErrorCode error = ImeEventSetOptionWindowDestroyedCb(_imeOptionWindowDestroyedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add OptionWindowDestroyed Failed with error " + error);
}
else
{
_optionWindowDestroyed += value;
}
}
}
remove
{
lock (thisLock)
{
_optionWindowDestroyed -= value;
}
}
}
///
/// Sets the languageRequested Action
///
///
/// Called when an associated text input UI control requests the language from the input panel, requesting for language code.
///
public static void SetLanguageRequestedCallback(OutAction languageRequested)
{
_imeLanguageRequestedDelegate = (IntPtr userData, out IntPtr langCode) =>
{
string langauage;
_languageRequestedDelegate(out langauage);
char[] languageArray = langauage.ToCharArray();
langCode = new IntPtr();
Marshal.Copy(languageArray, 0, langCode, languageArray.Length);
};
ErrorCode error = ImeEventSetLanguageRequestedCallbackCb(_imeLanguageRequestedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add SetLanguageRequestedCallback Failed with error " + error);
}
_languageRequestedDelegate = languageRequested;
}
///
/// Sets the processKey Action
/// If the key event is from the external device, DeviceInfo will have its name, class and subclass information.
///
///
/// The Action is alled when the key event is received from the external devices or SendKey function.
/// This Event processes the key event before an associated text input UI control does.
///
public static void SetProcessKeyCallback(BoolAction processKey)
{
_imeProcessKeyDelegate = (KeyCode keyCode, KeyMask keyMask, IntPtr devInfo, IntPtr userData) =>
{
return _processKeyDelagate(keyCode, keyMask, new VoiceControlDeviceInformation(devInfo));
};
ErrorCode error = ImeEventSetProcessKeyEventCb(_imeProcessKeyDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add ProcessKey Failed with error " + error);
}
_processKeyDelagate = processKey;
}
///
/// Sets the imDataRequested Action
///
///
/// Called when an associated text input UI control requests the application specific data from the input panel, requesting for data array and it's length.
///
public static void SetDataRequestedCallback(OutArrayAction imDataRequested)
{
_imeImDataRequestedDelegate = (IntPtr userData, out IntPtr data, out uint dataLength) =>
{
byte[] dataArr;
_imDataRequestedDelegate(out dataArr);
data = new IntPtr();
Marshal.Copy(dataArr, 0, data, dataArr.Length);
dataLength = (uint)dataArr.Length;
};
ErrorCode error = ImeEventSetImdataRequestedCb(_imeImDataRequestedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add SetDataRequestedCallback Failed with error " + error);
}
_imDataRequestedDelegate = imDataRequested;
}
///
/// Sets the GeometryRequested Action
///
///
/// Called when an associated text input UI control requests the position and size from the input panel, requesting for x,y,w,h values.
///
public static void SetGeometryRequestedCallback(OutAction geometryRequested)
{
_imeGeometryRequestedDelegate = (IntPtr userData, out int x, out int y, out int w, out int h) =>
{
Rect rect = new Rect();
_geometryRequestedDelegate(out rect);
x = rect.x;
y = rect.y;
w = rect.w;
h = rect.h;
};
ErrorCode error = ImeEventSetGeometryRequestedCallbackCb(_imeGeometryRequestedDelegate, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Add SetGeometryRequestedCallback Failed with error " + error);
}
_geometryRequestedDelegate = geometryRequested;
}
///
/// Runs the main loop of IME application.
/// This function starts to run IME application's main loop.
///
///
/// http://tizen.org/privilege/ime
///
///
/// This API is a blocking call, as it starts the main loop of the application.
///
/// This is called to initialize IME application before the main loop starts up
/// This is called when IME application is terminated
///
/// This is called when IME application is shown
/// It provides the Context Inofrmation and the Context Id
///
///
/// This is called when IME application is hidden
/// It provides the Context Id
///
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) Operation failed
///
public static void Run(Action create, Action terminate, Action show, Action hide)
{
_userCreate = create;
_userTerminate = terminate;
_userShow = show;
_userHide = hide;
_imeCallbackStructGCHandle._imeCallbackStruct.create = _create;
_imeCallbackStructGCHandle._imeCallbackStruct.terminate = _terminate;
_imeCallbackStructGCHandle._imeCallbackStruct.hide = _hide;
_imeCallbackStructGCHandle._imeCallbackStruct.show = _show;
ErrorCode error = ImeRun(ref _imeCallbackStructGCHandle._imeCallbackStruct, IntPtr.Zero);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "Run Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Sends a key event to the associated text input UI control.
///
///
/// This function sends key down or up event with key mask to the client application. If forwardKey is true, this key event goes to the edit filed directly.
/// And if forwardKey is false, the ProcessKey event receives the key event before the edit field.
///
///
/// http://tizen.org/privilege/ime
///
/// The key code to be sent
/// The modifier key mask
/// The flag to send the key event directly to the edit field
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
///
public static void SendKeyEvent(KeyCode keyCode, KeyMask keyMask, bool forwardKey = false)
{
ErrorCode error = ImeSendKeyEvent(keyCode, keyMask, forwardKey);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "SendEvent Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Sends the text to the associated text input UI control.
///
///
/// http://tizen.org/privilege/ime
///
/// The string to be committed
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
///
public static void CommitString(string str)
{
ErrorCode error = ImeCommitString(str);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "CommitString Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Requests to show preedit string.
///
///
/// http://tizen.org/privilege/ime
///
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
///
public static void ShowPreEditString()
{
ErrorCode error = ImeShowPreeditString();
if (error != ErrorCode.None)
{
Log.Error(LogTag, "ShowPreEditString Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Requests to hide preedit string.
///
///
/// http://tizen.org/privilege/ime
///
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
///
public static void HidePreEditString()
{
ErrorCode error = ImeHidePreeditString();
if (error != ErrorCode.None)
{
Log.Error(LogTag, "HidePreEditString Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Updates a new preedit string.
///
///
/// http://tizen.org/privilege/ime
///
/// The string to be updated in preedit
///
/// The list which has ime_preedit_attribute lists, strings can be composed of multiple string attributes: underline, highlight color and reversal color.
/// The attrs list can be empty if no attributes to set
///
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
/// 3) Invalid Parameter
///
public static void UpdatePreEditString(string str, IEnumerable attrs)
{
IntPtr einaList = IntPtr.Zero;
List attributeHandleList = new List();
foreach (PreEditAttribute attribute in attrs)
{
ImePreEditAttributeStruct imePreEditAttribute = new ImePreEditAttributeStruct();
imePreEditAttribute.start = attribute.Start;
imePreEditAttribute.length = attribute.Length;
imePreEditAttribute.type = (int)attribute.Type;
imePreEditAttribute.value = attribute.Value;
GCHandle attributeHandle = GCHandle.Alloc(imePreEditAttribute, GCHandleType.Pinned);
attributeHandleList.Add(attributeHandle);
einaList = Interop.EinaList.EinaListAppend(einaList, attributeHandle.AddrOfPinnedObject());
}
ErrorCode error = ImeUpdatePreeditString(str, einaList);
foreach (GCHandle handle in attributeHandleList)
{
handle.Free();
}
if (error != ErrorCode.None)
{
Log.Error(LogTag, "UpdatePreEditString Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Requests the surrounding text from the position of the cursor, asynchronously.
///
///
/// http://tizen.org/privilege/ime
///
/// The maximum length of string to be retrieved before the cursor, -1 means unlimited
/// The maximum length of string to be retrieved after the cursor, -1 means unlimited
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
///
///
/// The requested surrounding text can be received using the SurroundingTextUpdated Event, only if it is set.
///
public static void RequestSurroundingText(int maxLenBefore, int maxLenAfter)
{
ErrorCode error = ImeRequestSurroundingText(maxLenBefore, maxLenAfter);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "RequestSurroundingText Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Requests to delete surrounding text.
///
///
/// http://tizen.org/privilege/ime
///
/// The offset value from the cursor position
/// The length of the text to delete
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
/// 3) Invalid Parameter
///
public static void DeleteSurroundingText(int offset, int len)
{
ErrorCode error = ImeDeleteSurroundingText(offset, len);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "DeleteSurroundingText Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Gets the surrounding text from the position of the cursor, synchronously.
///
///
/// http://tizen.org/privilege/ime
///
/// The maximum length of string to be retrieved before the cursor, -1 means unlimited
/// The maximum length of string to be retrieved after the cursor, -1 means unlimited
/// The surrounding text
/// The cursor position
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
/// 3) Invalid Parameter
/// 4) Failed to obtain text due to out of memory
///
public static void GetSurroundingText(int maxLenBefore, int maxLenAfter, out string text, out int cursorPosition)
{
IntPtr txt;
ErrorCode error = ImeGetSurroundingText(maxLenBefore, maxLenAfter, out txt, out cursorPosition);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "GetSurroundingText Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
text = Marshal.PtrToStringAnsi(txt);
}
///
/// Requests to set selection.
///
///
/// http://tizen.org/privilege/ime
///
/// The start cursor position in text (in characters not bytes)
/// The end cursor position in text (in characters not bytes)
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
/// 3) Invalid Parameter
///
public static void SetSelection(int start, int end)
{
ErrorCode error = ImeSetSelection(start, end);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "SetSelection Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// This API returns the input panel main window.
///
///
/// http://tizen.org/privilege/ime
///
/// The input panel main window object on success, otherwise null
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) IME main loop isn't started yet
/// 3) Operation Failed
///
public static EditorWindow GetMainWindow()
{
EditorWindow._handle = ImeGetMainWindow();
EditorWindow obj = new EditorWindow();
ErrorCode error = (ErrorCode)Tizen.Internals.Errors.ErrorFacts.GetLastResult();
if (error != ErrorCode.None)
{
Log.Error(LogTag, "GetMainWindow Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
return obj;
}
///
/// This API requests the InputMethodEditor to initialize
///
///
/// http://tizen.org/privilege/ime
///
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) Operation Failed
///
public static void Create()
{
ErrorCode error = ImeInitialize();
Log.Info(LogTag, "ImeInitialize result : " + error);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "ImeInitialize Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
error = ImePrepare();
Log.Info(LogTag, "ImePrepare result : " + error);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "ImePrepare Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// This API requests the InputMethodEditor to finalize
///
///
/// http://tizen.org/privilege/ime
///
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) Operation Failed
///
public static void Destroy()
{
ErrorCode error = ImeFinalize();
Log.Info(LogTag, "ImeFinalize result : " + error);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "ImeFinalize Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Requests to create an option window from the input panel.
/// The input panel can call this function to open the option window. This function calls OptionWindowCreated Event with OptionWindowType.Keyboard.
///
///
/// http://tizen.org/privilege/ime
///
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) Operation failed
/// 3) IME main loop isn't started yet
/// 4) OptionWindowCreated event has not been set
///
///
/// OptionWindowCreated and OptionWindowDestroyed event should be set
///
public static void CreateOptionWindow()
{
ErrorCode error = ImeCreateOptionWindow();
if (error != ErrorCode.None)
{
Log.Error(LogTag, "CreapteOptionWindow Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
///
/// Requests to destroy an option window.
/// The input panel can call this function to close the option window which is created from either the input panel or Settings application.
///
///
/// http://tizen.org/privilege/ime
///
/// The option window to destroy
///
/// This can occur due to the following reasons:
/// 1) The application does not have the privilege to call this function
/// 2) Invalid Parameter
/// 3) IME main loop isn't started yet
///
///
/// OptionWindowDestroyed Event must be set.
///
///
/// This function triggers the OptionWindowDestroyed Event if it is set.
///
public static void DestroyOptionWindow(OptionWindow window)
{
ErrorCode error = ImeDestroyOptionWindow(window);
if (error != ErrorCode.None)
{
Log.Error(LogTag, "DestroyOptionWindow Failed with error " + error);
throw InputMethodExceptionFactory.CreateException(error);
}
}
}
}