nanogui: A IME demo program


Previous by date: 16 Feb 2005 03:35:29 +0000 Cannot initialize mouse, kentropy
Next by date: 16 Feb 2005 03:35:29 +0000 problems compiling viewml, R R
Previous in thread:
Next in thread:

Subject: A IME demo program
From: "Zhang Hongbiao" ####@####.####
Date: 16 Feb 2005 03:35:29 +0000
Message-Id: <BAY18-DAV10752D4A9C06636AF2FA31BE6C0@phx.gbl>

I'd like to present a IME demo program, maybe you can call it in this way.
It's quite a simple application.
'cause I wrote a request before to seek some information of input method
in Microwindows.
I found less information finally.
So I wrote a demo program to demonstrate the feasibilities of introducing
a input method to Microwindows.
I think it may do help to some guys who are working on that direction.

It employes a event-block-and-process-and-redispatch mechanism.
Whenever you press a digit button, it blocks the event and translate to a '9' 
button event and redispathc it. Maybe you can revise it to make it work better.

You should write a makefile for it and compile it in Linux.


p.s. Jack is my English name.


Enjoy using it!        ^__^

Jack
Email: ####@####.####
2005/2/16




Below is the source code of the demo program :
-------------------------------------------------

/*******************************************************************************
IMEDemo.c  - General description about this file.    
 
                    REVISION HISTORY
 
 Date       EngineerName   Updation/Reason
----------  ------------   -------------------
2004-12-15    Jack           File creation.
 
*******************************************************************************/

/*==============================================================================

                      INCLUDE FILES FOR MODULE

==============================================================================*/

/* $include */
#define MWINCLUDECOLORS
#include "windows.h"
#include "wintern.h"    /* for MwSetDesktopWallpaper*/
#include "device.h"
#include "stdio.h"
#include "string.h"
#include "assert.h"

#include "nano-X.h"

/* begin: added by Jack, 2004-12-15 */
/*  */
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <sched.h>
#include <semaphore.h>
/* end  : added by Jack, 2004-12-15 */

/*==============================================================================

          EXTERNAL DATA AND FUNCTIONS REFRENCE DECLARATIONS

==============================================================================*/

/* $extern */

/*==============================================================================

            LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE

==============================================================================*/

/* $macro */

/* $enum */

/* $global variable definition */

/* $global function declaration */

/* $local variable definition */
static HWND hTheEDWnd;
static char l_strEDClass[] = "EDClass";
static char l_strEDName[]  = "ED";

static HWND hTheIMEWnd;
static char l_strIMEClass[] = "IMEClass";
static char l_strIMEName[]  = "IME";


#define MAX_BUF_LEN 32
static char l_aEDBuf[MAX_BUF_LEN +1];
static int  l_iEDBufLen;

static char l_aIMEBuf[MAX_BUF_LEN +1];
static int  l_iIMEBufLen;

static MSG  l_stMsg;

static BOOL l_bIMEStart = FALSE;

#define PTHREAD_STACK_MIN 4096
static char ime_thread_stack[PTHREAD_STACK_MIN*2];
static pthread_t ime_thread;

/* For safe condition variable usage, must use a boolean predicate and  */
/* a mutex with the condition.                                          */
pthread_cond_t      cond  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t     mutex = PTHREAD_MUTEX_INITIALIZER;
sem_t               sem;
/* $local function declaration */
static LRESULT CALLBACK
EDProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp);
static LRESULT CALLBACK
IMEProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp);
static int
ime_main();

/*==============================================================================

                        FUNCTION IMPLEMENTIONS

==============================================================================*/

/* $global function implemention */

/* local function implemention */
static BOOL 
EDRegisterClass()
{
  WNDCLASS wndclass;      
  /* Register Main Window */
  wndclass.style          = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc    = (WNDPROC)EDProc;
  wndclass.cbClsExtra     = 0;
  wndclass.cbWndExtra     = 0;
  wndclass.hInstance      = 0;
  wndclass.hIcon          = 0;
  wndclass.hCursor        = 0;
  wndclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wndclass.lpszMenuName   = NULL;
  wndclass.lpszClassName  = l_strEDClass;

  RegisterClass(&wndclass);

  return TRUE;
}
static BOOL 
EDCreateWindow()
{
  RECT stRc;

  GetWindowRect(GetDesktopWindow(), &stRc);  
  /* Create APP main window */
  hTheEDWnd =CreateWindowEx(0L,
                    l_strEDClass,
                    l_strEDName,
                    WS_VISIBLE|WS_OVERLAPPEDWINDOW,
                    20,
                    20,
                    128,
                    160,
                    NULL,
                    NULL,
                    NULL,
                    NULL);
         
  if (!hTheEDWnd)
  {
     return FALSE;
  }  
  
  return TRUE;
}

static BOOL
EDInit()
{ 
  /* Register app class */
  if (!EDRegisterClass()) 
  {
    printf("EDRegisterClass FAIL!!!\n");
    return FALSE;
  }  
  /* Create app window */
  if(!EDCreateWindow())
  {
    printf("EDCreateWindow FAIL!!!\n");  
    return FALSE;
  }  
  return TRUE;
}

static BOOL 
IMERegisterClass()
{
  WNDCLASS wndclass;      
  /* Register Main Window */
  wndclass.style          = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc    = (WNDPROC)IMEProc;
  wndclass.cbClsExtra     = 0;
  wndclass.cbWndExtra     = 0;
  wndclass.hInstance      = 0;
  wndclass.hIcon          = 0;
  wndclass.hCursor        = 0;
  wndclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wndclass.lpszMenuName   = NULL;
  wndclass.lpszClassName  = l_strIMEClass;

  RegisterClass(&wndclass);

  return TRUE;
}
static BOOL 
IMECreateWindow()
{
  RECT stRc;

  GetWindowRect(GetDesktopWindow(), &stRc);  
  /* Create APP main window */
  hTheIMEWnd =CreateWindowEx(0L,
                    l_strIMEClass,
                    l_strIMEName,
                    WS_VISIBLE|WS_BORDER,
                    160,
                    20,
                    128,
                    32,
                    NULL,
                    NULL,
                    NULL,
                    NULL);
         
  if (!hTheIMEWnd)
  {
     return FALSE;
  }  
  
  return TRUE;
}

static BOOL
IMEInit()
{
  /* Register app class */
  if(!IMERegisterClass()) 
  {
    printf("IMERegisterClass FAIL!!!\n");
    return FALSE;
  }  
  /* Create app window */
  if(!IMECreateWindow())
  {
    printf("IMECreateWindow FAIL!!!\n");  
    return FALSE;
  }  
  return TRUE;
  
}

int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd)
{
  MSG msg;

  /* Perform application initialization */
  if (!EDInit()) 
  {
    printf("EDInit FAIL!!!\n");    
    return FALSE;
  }  
  if (!IMEInit()) 
  {
    printf("IMEInit FAIL!!!\n");    
    return FALSE;
  }  

  SetFocus(hTheEDWnd);

  sem_init(&sem, 0, 0);
  
  /* Enter message loop */
  while (GetMessage(&msg,NULL,0,0)) 
  {
    if(l_bIMEStart)
    {
      printf("msg.message = 0x%x\n", msg.message);
      if(msg.message == WM_CHAR)
      {
        pthread_mutex_lock(&mutex);
        l_stMsg = msg;    
        printf("pthread_cond_signal\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex); 
        printf("sem_wait\n");        
        sem_wait(&sem);
        msg = l_stMsg;
      }
    }
    //else
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }      
  return 0;

}
static void *
ime_thread_entry( void *arg)
{ 
  struct sched_param   param;
  int                  policy;
  int                  rc;
 
  rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  if(rc)
  {
    printf("ime_thread_entry: pthread_setcancelstate FAIL(%d)!!!\n", rc);
  }
  rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  if(rc)
  {
    printf("ime_thread_entry: pthread_setcanceltype FAIL(%d)!!!\n", rc);
  }

  printf("ime_thread_entry: Thread start..\n");

#if 0 /* Jack 2004-12-15 : */
  while(1)
  {
    sleep(1);  
    pthread_testcancel();
    printf("ime_thread_entry: Thread rolls once\n");  
  }
#else /* !0  */
  ime_main();
#endif /* 0 Jack 2004-12-15 */

  printf("Unexpectedly got out of loop!\n"); 
  l_bIMEStart = FALSE;
  pthread_exit( 0 );
}
static int
StartIME()
{
  pthread_attr_t attr;   
  int                  policy;
  int                  rc;

  pthread_attr_init( &attr );
  pthread_attr_setstack(&attr, (void *)ime_thread_stack, sizeof(ime_thread_stack));
 
  
  printf("Create thread\n");
  if(pthread_create(&ime_thread, &attr, ime_thread_entry, (void*)0x1234))
  {
    printf("pthread_create FAIL!!!\n");
  } 
  else
  {
    l_bIMEStart = TRUE;
  }
  
  return 0;
}
static int
StopIME()
{
  printf("pthread_cancel\n");
  if(pthread_cancel(ime_thread))
  {
    printf("pthread_cancel FAIL!~!!\n");
  }
  else
  {
    sem_post(&sem);
    sem_init(&sem, 0, 0);  
    l_bIMEStart = FALSE;
  }
  return 0;
}
static void DrawIME(HWND hwnd)
{
  HDC hdc;
  RECT rect;

  GetClientRect(hwnd, &rect);  
  hdc = GetDC(hwnd);
  FillRect(hdc, &rect, GetStockObject(WHITE_BRUSH));
  DrawText(hdc, l_aIMEBuf, l_iIMEBufLen, &rect, DT_TOP|DT_LEFT);
  ReleaseDC(hwnd, hdc);  
}
static LRESULT CALLBACK
IMEProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp)
{
  PAINTSTRUCT  ps;
  HDC    hdc;
  RECT  rect;

  switch (uMsg) 
  {
  case WM_PAINT:
    //hdc=BeginPaint(hwnd,&ps);
    //GetClientRect(hwnd,&rect);
    //FillRect(hdc, &rect, GetStockObject(WHITE_BRUSH));
    //EndPaint(hwnd,&ps);
    break;   
  case WM_COMMAND:
    break;
  case WM_CHAR:
    
    break;
  case WM_DESTROY:
    //PostQuitMessage(0);
    break;
  default:
    return DefWindowProc(hwnd,uMsg,wp,lp);
  }      

  return (0);
}

static LRESULT CALLBACK
EDProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp)
{
  PAINTSTRUCT  ps;
  HDC    hdc;
  RECT  rect;

  switch (uMsg) 
  {
  case WM_PAINT:
    hdc=BeginPaint(hwnd,&ps);
    GetClientRect(hwnd,&rect);
    FillRect(hdc, &rect, GetStockObject(WHITE_BRUSH));
    DrawText(hdc, l_aEDBuf, l_iEDBufLen, &rect, DT_TOP|DT_LEFT);
    EndPaint(hwnd,&ps);
    break;   
  case WM_COMMAND:
    break;
  case WM_CHAR:
    switch(wp)
    {
    case VK_NUMPAD0:
    case VK_NUMPAD1:       
    case VK_NUMPAD2:
    case VK_NUMPAD3:
    case VK_NUMPAD4:
    case VK_NUMPAD5:
    case VK_NUMPAD6:
    case VK_NUMPAD7:
    case VK_NUMPAD8:
    case VK_NUMPAD9:  
      if(l_iEDBufLen == MAX_BUF_LEN)
      {
        break;
      }
      l_aEDBuf[l_iEDBufLen++]= (wp-VK_NUMPAD0)+'0';

      GetClientRect(hwnd, &rect);
      InvalidateRect(hwnd, &rect, TRUE);
      break;
    case VK_F1:
      l_iEDBufLen = 0;
      l_aEDBuf[0]='\0';
      GetClientRect(hwnd, &rect);
      InvalidateRect(hwnd, &rect, TRUE);
      break;
    case VK_F12:
      if(l_bIMEStart)
      {
        StopIME();        
      }
      else
      {
        StartIME();
      }
      break;
    }
    break;
  case WM_DESTROY:
    //PostQuitMessage(0);
    break;
  default:
    return DefWindowProc(hwnd,uMsg,wp,lp);
  }      

  return (0);
}

static int
ime_sendback(int c)
{
 
 return 0;
}
static int
ime_main()
{
  MSG msg;

  for(;;)
  {
   pthread_mutex_lock(&mutex);
    printf("pthread_cond_wait\n");
    pthread_cond_wait(&cond, &mutex);

    printf("pthread_cond_wait got unlocked\n");
    
    msg = l_stMsg;
    switch(msg.message)
    {
    case WM_CHAR:
      switch(msg.wParam)
      {
      case VK_NUMPAD0:
      case VK_NUMPAD1:
      case VK_NUMPAD2:
      case VK_NUMPAD3:
      case VK_NUMPAD4:
      case VK_NUMPAD5:
      case VK_NUMPAD6:
      case VK_NUMPAD7:
      case VK_NUMPAD8:
      case VK_NUMPAD9:
        l_iIMEBufLen = 1;
        l_aIMEBuf[0]= (msg.wParam - VK_NUMPAD0)+'0';
        DrawIME(hTheIMEWnd);
      
        msg.wParam = VK_NUMPAD9;
        break;
      }
      break;  
    }
    l_stMsg = msg;
    pthread_mutex_unlock(&mutex);

    printf("sem_post\n");
    sem_post(&sem);
 }
 
  return 0;
}

Previous by date: 16 Feb 2005 03:35:29 +0000 Cannot initialize mouse, kentropy
Next by date: 16 Feb 2005 03:35:29 +0000 problems compiling viewml, R R
Previous in thread:
Next in thread:


Powered by ezmlm-browse 0.20.