1. Abstract

   This documents describes about what HOTKEY PROFILE and HOTKEY is, 
   how it works and how Server and LEs can register them using the 
   new LEIF APIs. This document also explains the overall architecture 
   behind the Hotkey implementation.

2. Hotkey

   Hotkey is a special keyevent (introduced recently as part of IIIMF),
   that can be registered by the IIIMServer and Language Engines to the 
   client. When an input event matches one of the registered HOTKEYS, 
   the client (IIIMCF) determines what to do depending on the particular 
   Hotkey's settings.

3. Hotkey Profile

   Hotkey Profile typically contains a PROFILE_ID and a list of HOTKEYS.
   The idea of HOTKEY PROFILE is to allow Language Engines to register
   multiple Hotkey Profiles and switch between them depending on their
   requirement.

   Here is how LEs can create Hotkey Profiles:

   Hotkey Manager +-- Hotkey Profile (1) +-- Hotkey (1)-- Kev 1, Kev 2 ...
                  |                      |
                  |                      +-- Hotkey (2)-- Kev 1, Kev 2 ...
                  |
                  |
                  +-- Hotkey Profile (2) +-- Hotkey (1)-- Kev 1, Kev 2 ...
                                         |
                                         +-- Hotkey (2)-- Kev 1, Kev 2 ...
                                         |
                                         +-- Hotkey (3)-- Kev 1, Kev 2 ...

   Note: (1) Each HOTKEY PROFILE can have multiple HOTKEYS, and each HOTKEY 
             can have multiple KEYEVENTS defined.
         (2) HOTKEY MANAGER basically contains the HOTKEY PROFILE LIST and 
             number of hotkey profiles created.

4. IIIMF Hotkey Architecture

   The IIIMF Hotkey architecture allows IIIMServer/LEs to switch a set of 
   hotkeys (under a hotkey profile) atomically.  You can define different
   sets of hotkeys (under a hotkey profile) for their own purposes, such as 
   per input mode or input state(such as preedit is empty, or during initial 
   input or after hitting conversion key to enter clause based editing etc),
   and switch among them quickly. Therefore, LEs must be able to register 
   multiple set of hotkey profiles and one profile can include multiple hotkeys.

   When hotkey event is fired, IIIMServer is notified with the IIIM Protocol, 
   IM_HOTKEY_NOTIFY. This notification is delivered to the corresponding LE 
   somehow, when the hotkey under the current profile is registered by LE.

5. Defining if_GetHotKeyInfo() in LE module for registering Hotkey Profiles.

   Each Language Engine can register their own Hotkey Profiles using the 
   special method for the SunIM Library called if_GetHotKeyInfo(). The Hotkey
   definitions could be in an external configuration file that can be loaded 
   dynamically by IIIMServer or it can hardcoded in the Language Engine. 

   If the Hotkeys are hardcoded, then you cannot change it at runtime.
   Here is an example:

   static IMHotkeyManagerStruct *g_hkms = NULL;
   static IMKeyEventStruct *sampleja_hotkey;

   IMHotkeyManagerStruct*
   if_GetHotKeyInfo (
   IMLEName *a_le_name
   )
   {
      if (g_hkms)
        return (IMHotkeyManagerStruct *)g_hkms;

      g_hkms = calloc(1, sizeof(IMHotkeyManagerStruct));
      g_hkms->num_hotkey_profiles = 1;

      /* Creating two profiles */
      g_hkms->hkps = calloc(g_hkms->num_hotkey_profiles, 
                                     sizeof(IMHotkeyProfileStruct));

      /* 1st Hotkey Profile */
      g_hkms->hkps[0].profile_id = 777;     /* Any random number */
      g_hkms->hkps[0].scope = SESSION_SPECIFIC_HOTKEY;
      g_hkms->hkps[0].num_hotkeys = 1;
      g_hkms->hkps[0].name = a_le_name;

      g_hkms->hkps[0].hks = calloc(g_hkms->hkps[0].num_hotkeys, 
                                     sizeof(IMHotkeyStruct));

      sampleja_hotkey = (IMKeyEventStruct *) calloc (1, 
                                     sizeof(IMKeyEventStruct));
      if (sampleja_hotkey == NULL) return (IMHotkeyManagerStruct *)NULL;

      /* Hotkey 1 */
      sampleja_hotkey[0].keyCode = IM_VK_F8;
      sampleja_hotkey[0].keyChar = 0;
      sampleja_hotkey[0].modifier = 0;
      sampleja_hotkey[0].time_stamp = 0;

      g_hkms->hkps[0].hks[0].label = "SAMPLEJA_HOTKEY_F8";
      g_hkms->hkps[0].hks[0].state_flag = 0;
      g_hkms->hkps[0].hks[0].action_flag = 1;
      g_hkms->hkps[0].hks[0].nkeys = 1;
      g_hkms->hkps[0].hks[0].keys = &sampleja_hotkey[0];

      return g_hkms;
   }

   Incase of defining Hotkeys in an external configuration file, you can
   add/delete/modify hotkey defitions dynamically. Here is an example ..

   static IMHotkeyManagerStruct *g_hkms = NULL;

   IMHotkeyManagerStruct*
   if_GetHotKeyInfo (
   IMLEName *a_le_name
   )
   {
      if (g_hkms)
        return (IMHotkeyManagerStruct *)g_hkms;

      /* Load the hotkey configuration file dynamically and fill the  */
      /* IMHotkeyManagerStruct structure                              */

      g_hkms = load_hotkey_config_file(filename);

      return g_hkms;
   }      

6. LEs switching between Hotkey Profiles

   SunIM library provides a special interface for HOTKEY related 
   functionalities. Here is the sample code for LE to switch to a 
   particular Hotkey Profile :

   iml_hkc       *hkc; /* iml_hkc defined in ~/trunk/include/iml/SunIMMthd.h */

   hkc = desktop->desktopGetValue(IML_HOTKEY_CONTEXT, "iiim.le.sampleja");
   hkc->switchLEProfile(IME_HOTKEY_PROFILE_TWO, &leName);
   hkc->hotkey_context_free(hkc);

   Note: Since the desktopGetValue() method is part of iml_desktop, switching
         can be done only after the desktop is created.

7. IIIMServer registering Hotkey Profiles

   Here is how IIIMServer registers HOTKEYS PROFILES:

   a. While loading all LEs, IIIMServer collects the Hotkey Profiles 
      registered by all Language Engines and assigns a unique PROFILE_ID.

   b. IIIMServer also creates a DEFAULT HOTKEY PROFILE (also called 
      SUPER HOTKEY PROFILE). This contains the following SUPER HOTKEYS:
      1. IM on/off keys ( <Ctrl>space / <Shift>/space / Kanji-key )
      2. Language Selection Window (for LE switching)
         ( <Ctrl+Shift>space  / <Ctrl+Alt>space )

   c. For enabling the profile switching from LE, IIIMServer creates a 
      list of the following mapping
              <Unique Profile ID, IMHotkeyProtocolStruct *>

      Note: IMHotkeyProtocolStruct contains both the profile_id assigned 
            by each LE (which need not be unique) and the LE name.

   d. IIIMServer merges the SUPER HOTKEYS with the HOTKEYS defined by 
      each LE. So, all the Hotkey Profiles from LE, will include the 
      SUPER HOTKEYS.

   e. After merging, IIIMServer sends all the Hotkey Profiles from LE and 
      the DEFAULT HOTKEY PROFILE in IM_REGISTER_HOTKEYS request. Since there 
      is no separate protocol for registering the list of Hotkey Profiles, 
      IIIMServer registers all the Hotkey Profiles one by one.

   f. After registering, IIIMServer selects the DEFAULT HOTKEY PROFILE as 
      the Client's current profile by sending IM_SELECT_HOTKEY_PROFILE 
      request with the default PROFILE_ID.

   g. If a particular LE registers HOTKEY PROFILE and it is chosed as the 
      default LE for the client application, then the LE can switch the 
      profile by using the interface explained in question 4.

