view src/aci2/mfw/mfw_edt.c @ 581:a0a45c5eb3ef

gsmcomp.c: bumping trace partition size to 220 like in gprscomp.c This change is safe in terms of RAM usage because all of these partition pools have already been moved from XRAM to IRAM earlier, and our IRAM usage in VO configs is currently quite low - the one near the limit is XRAM on C11x.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 29 Jan 2019 03:52:49 +0000
parents 93999a60b835
children
line wrap: on
line source

/*
+--------------------------------------------------------------------+
| PROJECT: MMI-Framework (8417)         $Workfile:: mfw_edt.c       $|
| $Author:: Es  $ CONDAT GmbH           $Revision:: 15              $|
| CREATED: 21.09.98                     $Modtime:: 23.03.00 8:57    $|
| STATE  : code                                                      |
+--------------------------------------------------------------------+

   MODULE  : MFW_EDT

   PURPOSE : edit handling functions

   EXPORT  :

   TO DO   :

   $History:: mfw_edt.c    
   
	Aug 16, 2004    REF: CRR 24323   Deepa M.D
	Bug:Clenup of sprintf used for tracing
	Fix:Replace the char buf[]; sprintf (buf, "...", ...); TRACE_EVENT (buf); statements by TRACE_EVENT_PX                                     $
 * 
 * *****************  Version 15  *****************
 * User: Es           Date: 23.03.00   Time: 14:40
 * Updated in $/GSM/Condat/MS/SRC/MFW
 * added edtUnhide()
 * 
 * *****************  Version 14  *****************
 * User: Kk           Date: 21.02.00   Time: 9:36
 * Updated in $/GSM/Condat/MS/SRC/MFW
 * changes from es inserted
 *
 * *****************  Version 13  *****************
 * User: Es           Date: 18.02.00   Time: 15:45
 * Updated in $/GSM/Condat/MS/SRC/MFW
 * added edit controls: ecTop, ecBottom
|
| *****************  Version 12  *****************
| User: Le           Date: 6.01.00    Time: 9:23
| Updated in $/GSM/Condat/MS/SRC/MFW
| Alignment of MFW versions
 *
 * *****************  Version 3  *****************
 * User: Kk           Date: 13.12.99   Time: 17:30
 * Updated in $/GSM/Condat/SND-MMI/MFW
 *
 * *****************  Version 2  *****************
 * User: Es           Date: 22.11.99   Time: 10:29
 * Updated in $/GSM/Condat/SND-MMI/MFW
 *
 * *****************  Version 1  *****************
 * User: Es           Date: 18.11.99   Time: 16:35
 * Created in $/GSM/Condat/SND-MMI/MFW
 * Initial
 *
 * *****************  Version 11  *****************
 * User: Es           Date: 6.07.99    Time: 12:18
 * Updated in $/GSM/DEV/MS/SRC/MFW
 *
 * *****************  Version 10  *****************
 * User: Es           Date: 14.04.99   Time: 17:34
 * Updated in $/GSM/DEV/MS/SRC/MFW
 * moved to CST
|
| *****************  Version 9  *****************
| User: Le           Date: 14.04.99   Time: 9:51
| Updated in $/GSM/DEV/MS/SRC/MFW
 *
 * *****************  Version 8  *****************
 * User: Es           Date: 1.04.99    Time: 17:07
 * Updated in $/GSM/DEV/MS/SRC/MFW
 * removed lots of traces
 *
 * *****************  Version 7  *****************
 * User: Es           Date: 18.02.99   Time: 17:01
 * Updated in $/GSM/DEV/MS/SRC/MFW
 *
 * *****************  Version 6  *****************
 * User: Es           Date: 17.02.99   Time: 19:10
 * Updated in $/GSM/DEV/MS/SRC/MFW
 *
 * *****************  Version 5  *****************
 * User: Es           Date: 8.02.99    Time: 19:06
 * Updated in $/GSM/DEV/MS/SRC/MFW
 * Cursor auf 0 !
 *
 * *****************  Version 4  *****************
 * User: Es           Date: 27.01.99   Time: 15:06
 * Updated in $/GSM/DEV/MS/SRC/MFW
 *
 * *****************  Version 3  *****************
 * User: Es           Date: 14.01.99   Time: 17:19
 * Updated in $/GSM/DEV/MS/SRC/MFW
 *
 * *****************  Version 2  *****************
 * User: Es           Date: 23.12.98   Time: 16:19
 * Updated in $/GSM/DEV/MS/SRC/MFW
*/


#if defined (NEW_FRAME)

#include "typedefs.h"
#include "vsi.h"
#include "pei.h"
#include "custom.h"
#include "gsm.h"

#else

#include "STDDEFS.H"
#include "custom.h"
#include "gsm.h"
#include "vsi.h"

#endif

#include <stdio.h>
#include <string.h>

#include "mfw_mfw.h"
#include "mfw_sys.h"
#include "gdi.h"
#include "dspl.h"
#include "mfw_edt.h"
#include "font_bitmaps.h"

#include "mfw_mmi.h"

#define TIME_TRACE_EVENT TRACE_EVENT
#ifndef TIME_TRACE_EVENT 
#define TIME_TRACE_EVENT
#endif

static int edtInsert (int c, char *b, int s, U8 curMode, U16 curCP);
static int edtCommand (U32 cmd, void *h);
void moveLeft (char * str, int ofs);

static void edtUnicodeSplitLine (int px, int py, int ls, int ly, U16 *tp);

static void moveLeftUnicode(U16 *unicodeStr, int nChars);
static int  edtInsertUnicode (MfwEdt *e, int c, U16 *b, int s);

U16 strlenUnicode(U16* str);

static void edtOutTextLines (int px, int py, int ls, int ly, U16 *tpUnicode, unsigned char* tpAscii,
							 int fontHeight, int display);
MfwRes updateWindow (MfwEdt *e, int  dy	);

int isAWordChar( char chr);

//Define the chars that correspond to the end of a word.
#define STR_WORDBREAK " .?!"

/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtInit            |
+--------------------------------------------------------------------+

  PURPOSE : initialize edit handler

*/

MfwRes edtInit (void)
{
    mfwCommand[MfwTypEdt] = (MfwCb) edtCommand;

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtExit            |
+--------------------------------------------------------------------+

  PURPOSE : finalize edit handler

*/

MfwRes edtExit (void)
{
    mfwCommand[MfwTypEdt] = 0;

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtCreate          |
+--------------------------------------------------------------------+

  PURPOSE : create editor control

*/

MfwHnd edtCreate (MfwHnd w, MfwEdtAttr *a, MfwEvt e, MfwCb f)
{
    MfwHdr *hdr = (MfwHdr *) mfwAlloc(sizeof(MfwHdr));
    MfwEdt *edt = (MfwEdt *) mfwAlloc(sizeof(MfwEdt));
	MfwHdr *insert_status =0;
	TRACE_FUNCTION("edtCreate");
	
    if (!hdr || !edt)
    {
    	TRACE_ERROR("ERROR: edtCreate() Mem Alloc Failed.");
			
	   	if(hdr)
   			mfwFree((U8*)hdr,sizeof(MfwHdr));

   		if(edt)
   			mfwFree((U8*)edt,sizeof(MfwEdt));
	   	return 0;
  	}

    edt->mask = e;
    edt->flags = 0;
    edt->handler = f;
    edt->attr = a;
    edt->cp = 0;                        /* cursor position          */
    edt->curOffs = 0;

    hdr->data = edt;
    hdr->type = MfwTypEdt;

    edtUpdate(edt);

    insert_status = mfwInsert(w,hdr);
    
    if(!insert_status)
	{
  		TRACE_ERROR("ERROR: edtCreate() Failed to Install Handler. ");
   		mfwFree((U8*)hdr,sizeof(MfwHdr));
   		mfwFree((U8*)edt,sizeof(MfwEdt));
		return 0;
  	}
    return insert_status;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtDelete          |
+--------------------------------------------------------------------+

  PURPOSE : delete editor control

*/

MfwRes edtDelete (MfwHnd e)
{
    MfwRes res;

    if (!e)
        return MfwResIllHnd;

    edtHide(e);                         /* hide editor contents     */
    res = (mfwRemove(e)) ? MfwResOk : MfwResIllHnd;

    mfwFree(((MfwHdr *) e)->data,sizeof(MfwEdt));
    mfwFree(e,sizeof(MfwHdr));

    return res;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtReset           |
+--------------------------------------------------------------------+

  PURPOSE : reset editor control

*/

MfwRes edtReset (MfwHnd w)
{
    MfwEdt *e;


	TRACE_FUNCTION("edtReset()");
    if (!w)
        return MfwResIllHnd;            /* editor does not exist    */

    e = ((MfwHdr *) w)->data;

    if (!e)
        return MfwResIllHnd;            /* editor does not exist    */

    e->cp = 0;                          /* cursor position          */
    e->curOffs = 0;

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtShow            |
+--------------------------------------------------------------------+

  PURPOSE : show editor

*/

MfwRes edtShow (MfwHnd e)
{
    MfwEdt *edt;

	TRACE_FUNCTION("edtShow()");

    if (!e)
        return MfwResIllHnd;            /* editor does not exist    */

    edt = ((MfwHdr *) e)->data;         /* get control block        */

    edt->flags |= MfwEdtVisible;        /* editor is visible        */
    if (edt->handler)                   /* call event handler       */
        if (edt->mask & MfwEdtVisible)
            edt->handler(MfwEdtVisible,edt);
    edt->display = 1;                        /* really show it           */
    edtUpdate(edt);                     /* draw editor elements     */

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtHide            |
+--------------------------------------------------------------------+

  PURPOSE : hide editor

*/

MfwRes edtHide (MfwHnd e)
{
    MfwEdt *edt;

	TRACE_FUNCTION("edtHide()");
    if (!e)
        return MfwResIllHnd;            /* element does not exist   */

    edt = ((MfwHdr *) e)->data;         /* get edit control block   */
    edt->flags &= ~MfwEdtVisible;       /* editor is not visible    */
    if (edt->handler)                   /* call event handler       */
        if (edt->mask & MfwEdtVisible)
            edt->handler(MfwEdtVisible,edt);

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtUnhide          |
+--------------------------------------------------------------------+

  PURPOSE : unhide editor (without drawing)

*/

MfwRes edtUnhide (MfwHnd e)
{
    MfwEdt *edt;
    
	TRACE_FUNCTION("edtunhide()");
	
    if (!e)
        return MfwResIllHnd;            /* element does not exist   */

    edt = ((MfwHdr *) e)->data;         /* get edit control block   */
    edt->flags |= MfwEdtVisible;        /* editor is visible        */
    if (edt->handler)                   /* call event handler       */
        if (edt->mask & MfwEdtVisible)
            edt->handler(MfwEdtVisible,edt);

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtClear           |
+--------------------------------------------------------------------+

  PURPOSE : clear editor

*/

MfwRes edtClear (MfwHnd e)
{
    MfwEdt *edt;

    TRACE_FUNCTION("edtClear()");

    if (!e)
        return MfwResIllHnd;            /* element does not exist   */

    edt = ((MfwHdr *) e)->data;         /* get edit control block   */
    if (edtReset(e) && edt->attr->text)
    {
        *(edt->attr->text) = 0;         /* clear buffer             */
        edtUpdate(edt);                 /* clear edit area          */
    }

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtUpdate          |
+--------------------------------------------------------------------+

  PURPOSE : draw editor
GW 06/09/01 - Call chinese update if first char is 0x80,0x81 or 0x82.
GW 06/09/01 - Added extra parameters to displ_setCursorPos for the size of cursor.
*/

//Return non-zero result if chr is in the string str.
int chrInString(char chr,char* str)
{
	int i;
	i=0;

	TRACE_FUNCTION("chrInString()");
	
	while (str[i] != 0x00)
	{
		if (str[i]== chr)
			return (i+1);
		else
			i++;
	}
	//Not found -
	return (0);
}

//GW 18/09/01 Use 'isAWordChar' procedure instead of 'chrInString' 
void findWordBounds(MfwEdt *e, int *opStChr, int *opEndChr)
{
	int found;
	int stChr,endChr;

	TRACE_FUNCTION("findWordBounds()");
	
	//Find char before start of the word.
	stChr = e->cp-1;
	found = FALSE;
	while ((stChr >0) && (!found))
	{
		if (isAWordChar(e->attr->text[stChr])==0)
			found = TRUE;
		else
			stChr--;
	}
	//find char after end of the word.
	endChr = e->cp;
	found = FALSE;
	while ((e->attr->text[endChr]!=0x00 ) && (!found))
	{
		if (isAWordChar(e->attr->text[endChr])==0)
			found = TRUE;
		else
			endChr++;
	}
	*opStChr  = stChr;
	*opEndChr = endChr;
}

//GW 18/09/01 Commented out debug code. 
MfwRes edtUpdate (MfwEdt *e)
{
	UBYTE temp;

    char *tp;
    S16 px, py;                         /* top left corner of edit  */
    S16 ls;                             /* width of edit window     */
    S16 ly;                             /* bottom of edit window    */
    U8 oldFont = -1;                    /* store previous font      */
	char* endChar;

    unsigned char *tb;

	//Data used to add word highlight 
	char saveChr[2];
	char startHtext[2] = {0x01,0x00};
	char endHtext[2]   = {0x02,0x00};
	int stChr,endChr;

	U16* tmp;

	TRACE_FUNCTION("edtUpdate()");

    if (!e)
        return MfwResIllHnd;

    if (!e->attr->text)
        return MfwResErr;               /* no text to display       */

	//Have we still got keys in the buffer to process? - process them first!
    if (mfwKey_skipDisplay())
		return (MfwResOk);
    
	tb = (unsigned char*)e->attr->text;

	if ((tb[0] == 0x80) || (tb[0] == 0x81) || (tb[0] == 0x82))
	{
		return( edtUpdateUnicode (e ) );
	}

	temp = dspl_get_char_type();		
	dspl_set_char_type(DSPL_TYPE_ASCII);

	//TRACE_EVENT_P1("flags: %d", e->flags);
    if (!(e->flags & MfwEdtVisible))
        e->display = 0;                    /* invisible editor         */

	resources_setColour(e->attr->edtCol);	
    tp = e->attr->text + e->curOffs;    /* start of display buffer  */
    px = e->attr->win.px;               /* left of edit window      */
    py = e->attr->win.py;               /* top of edit window       */
    ls = e->attr->win.sx;               /* width of edit window     */
    ly = (S16) (py+e->attr->win.sy);	/* bottom of edit window    */
    if (e->attr->font != (U8) -1)
        oldFont = dspl_SelectFontbyID(e->attr->font); /* setup font */
    e->fontHeight = dspl_GetFontHeight();  /* get height of curr font  */
    e->curMode = e->attr->mode;            /* setup edi mode           */
    if (e->display)
	{
		dspl_TextOut (e->attr->win.px, e->attr->win.py, 0, endHtext);
        dspl_Clear(e->attr->win.px,e->attr->win.py,(U16)(ls+e->attr->win.px-1),(U16)(ly-1));
	}

    dspl_SetCursor(0,(U8)(e->curMode&edtCurMask));

	//Add a space to the end of the line
	endChar = &tp[strlen(tp)];
	if ((endChar[0] == 0x00) &&
		(endChar[1] == 0x00))
	{
		endChar[0] = ' ';
		endChar[1] = 0x00;
		//For some editors, we want to highlight a complete word
		if (e->curMode & edtModWordSkip)
		{

			//find char at the start of the word
			findWordBounds(e,&stChr,&endChr);
			saveChr[0] = e->attr->text[stChr];
			saveChr[1] = e->attr->text[endChr];
			if (endChr == e->cp) // do not highlight if at the start of a word
			{
				if (stChr > e->curOffs)
					e->attr->text[stChr] = 0x01;
				else
					dspl_TextOut (e->attr->win.px, e->attr->win.py, 0, startHtext);
				e->attr->text[endChr] = 0x02;
			}

		}
		edtOutTextLines(e->attr->win.px, e->attr->win.py, ls, ly, NULL, (unsigned char*)tp,
						e->fontHeight, e->display); //* show it     * /
		if (e->curMode & edtModWordSkip)
		{
			e->attr->text[stChr] = saveChr[0];
			e->attr->text[endChr]= saveChr[1];
		}
		//and remove space again.
		endChar[0] = 0x00;
	}
	else
	{	//Cannot add space
		edtOutTextLines(e->attr->win.px, e->attr->win.py, ls, ly, NULL, (unsigned char*)tp,
						e->fontHeight, e->display); //* show it     * /
	}
	//GW 18/09/01 - Display predicted word.
    if (e->display)
	{
		if ((e->attr->predText[0] != '\0') && (e->attr->win.py >=e->fontHeight))
        {
			dspl_TextOut(0,e->attr->win.py-e->fontHeight,0,"             " );
			dspl_TextOut(0,e->attr->win.py-e->fontHeight,1,e->attr->predText );
        }
	}

    if (e->display && (e->curMode & edtCurMask))
    	{
        dspl_SetCursorPos(e->curCX+e->attr->win.px,e->curCY,e->curCSize,(S16)e->fontHeight); // sbh 19/02/02, position cursor correctly
    	}
    if (oldFont != (U8) -1)
        dspl_SelectFontbyID(oldFont);   /* restore previous font    */

#ifdef MFW_DEBUG_DISPLAY_SIZE
	{
		USHORT ax,ay,aw,ah;
		ax = e->attr->win.px;
		ay = e->attr->win.py;
		aw = e->attr->win.sx;
		ah = e->attr->win.sy;
    	dspl_DrawRect(ax,ay,(ax+aw-1),(ay+ah-1));
	    {
			/***************************Go-lite Optimization changes Start***********************/
	    	//	Aug 16, 2004    REF: CRR 24323   Deepa M.D
	    	TRACE_EVENT_P4(" ax:%d ay:%d aw:%d ah:%d",ax,ay,aw,ah);
			/***************************Go-lite Optimization changes end***********************/
	    } 	
    }
#endif
	dspl_set_char_type(temp);
	resources_restoreColour();
TIME_TRACE_EVENT("edtUpdate-end");
    return MfwResOk;
}



//GW 18/09/01 - Corrected linefeed definition and added carriage return definition.
#define UNICODE_SPACE			0x2000
#define UNICODE_LINEFEED		0x0A00
#define UNICODE_CR				0x0D00
#define UNICODE_EOLN			0x0000
#define UNICODE_NONASCII		0x00FF
#define UNICODE_STARTHIGHLIGHT	0x0100 
#define UNICODE_ENDHIGHLIGHT	0x0200


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtChar            |
+--------------------------------------------------------------------+

  PURPOSE : handle editing char
//GW 06/09/01 - Call chinese procedure if first char is 0x80,0x81 or 0x82 or display type is not ascii.

*/
char getCursorChar(MfwHnd e, int offset )
{
    MfwEdt *edit; 
	int chPos;

	TRACE_FUNCTION("getCursorChar()");

	if (!e)
        return (0xFF);

    if (((MfwHdr *)e)->type != MfwTypEdt)
        return (0xFF);            /* not an editor            */

	edit = ((MfwHdr *) e)->data;


	chPos = offset + edit->cp;
	if ((chPos < 0) || (chPos > strlen(edit->attr->text)))
		return (0x00);
	else
		return (edit->attr->text[chPos]);
}
int isAWordChar( char chr)
{	TRACE_FUNCTION("isAWordChar()");



	if ( ((chr >='A') && (chr <='Z')) || 
		 ((chr >='a') && (chr <='z')) )
		return (TRUE);
	else
		return(FALSE);
}
MfwRes edtChar (MfwHnd e, int c)
{
	int warn99;
    MfwEdt *edit; 
    U16 bs; 
	int dy;	//Change in cursor y position when moving up/down lines.
    char *tbString; 
	int found;

	TRACE_FUNCTION("edtChar()");

   if (!e)
        return MfwResIllHnd;

    if (((MfwHdr *)e)->type != MfwTypEdt)
        return MfwResIllHnd;            /* not an editor            */

	edit = ((MfwHdr *) e)->data;
 	tbString = &edit->attr->text[0];

	if (tbString[0] & 0x80)
	{
		return(edtCharUnicode(e,c));
	}
	bs = edit->attr->size;
	dy = 0;
    switch (c)
    {
		
        case ecEscape:                  //* quit editor              
            return MfwResDone;
        case ecLeft:					//* cursor left              
			if (edit->attr->mode & edtModWordSkip) 
			{
				edit->cp = edit->cp-1;
				if (isAWordChar(edit->attr->text[edit->cp]))
				{	//pointing to a letter in a word. Move left until next char is not a word char
					found = FALSE;
					while (!found)
					{
				        if (edit->cp == 0)
							found = TRUE;
						else if (isAWordChar(edit->attr->text[edit->cp-1]))
							edit->cp = edit->cp-1;
						else
							found = TRUE;
					}
				}
			}
			else
				edit->cp = edit->cp-1;
	        if (edit->cp <= 0)
				edit->cp = 0;
            break;
        case ecRight:                   //* cursor right 
			if (edit->attr->mode & edtModWordSkip) 
			{
				if (!isAWordChar(edit->attr->text[edit->cp]))
					edit->cp = edit->cp+1;//current char is not a word - move to next and stop.
				else 
				{
					found = FALSE;
					while (!found)
					{
						edit->cp = edit->cp+1;
				        if (!isAWordChar(edit->attr->text[edit->cp]))
							found = TRUE;//found a non-word char (could be the end of the string
					}
				}
			}
			else
				edit->cp = edit->cp+1;
            break;
        case ecUp:                      //* cursor up      
  			dy =  -1;
            break;
        case ecDown:                    //* cursor down           
  			dy = 1;
            break;
        case ecTop:                     //* cursor to start of text  
            edit->cp = 0;
            edit->curOffs = 0;
            break;
        case ecBottom:                  //* cursor to end of text   
            edit->cp = strlen(tbString);
            edit->curOffs = 0;
            break;
        case ecBack:                    //* backspace                *
            if ((edit->cp != 0) && (strlen(tbString)+1 > edit->cp))
			{
				moveLeft(&tbString[edit->cp-1],1);
			}
			edit->cp = edit->cp-1;
	        if (edit->cp <= 0)
				edit->cp = 0;
            break;
        case ecDel:                     //* delete                   *
			if (strlen(tbString) > edit->cp)
			{
				moveLeft(&tbString[edit->cp],1);
			}
            break;
        case ecEnter:                   //* cr/lf                    
            c = UNICODE_LINEFEED;
            edtInsert(c,tbString,bs, edit->curMode, edit->cp);
			return (edtChar(e,ecRight));
            break;
        default:                        //* normal char              
            edtInsert(c,tbString,bs, edit->curMode, edit->cp);

			if (edit->attr->alphaMode NEQ TRUE)
				return (edtChar(e,ecRight));
			/*NM, p003 end*/	
            break;
    }
    edit->display = 1;                        //* really show it           
  	updateWindow( edit, dy);
    edtUpdate(edit);

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtCharUnicode     |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/
MfwRes edtCharUnicode (MfwHnd e, int c)
{
    MfwEdt *edit; 
    U16 bs; 
	int dy;
    U16 *tbUnicode; 

 	TRACE_FUNCTION("edtCharUnicode()");
 	
    if (!e)
        return MfwResIllHnd;

    if (((MfwHdr *)e)->type != MfwTypEdt)
        return MfwResIllHnd;            //* not an editor            

	edit = ((MfwHdr *) e)->data;
	bs = edit->attr->size;
	tbUnicode = (U16*) &edit->attr->text[2];

	dy = 0;
    switch (c)
    {
        case ecEscape:                  //* quit editor              
            return MfwResDone;
        case ecLeft:                    //* cursor left              
            if (edit->cp <= 0)
				edit->cp = 0;
			else
	            edit->cp = edit->cp-1;
            break;
        case ecRight:                   //* cursor right             
			if (tbUnicode[edit->cp]!=UNICODE_EOLN)
	            edit->cp = edit->cp +1;
            break;
        case ecUp:                      //* cursor up                
  			dy = -1;
            break;
        case ecDown:                    //* cursor down              
  			dy = 1;
            break;
        case ecTop:                     //* cursor to start of text  
            edit->cp = 0;
            edit->curOffs = 0;
  			dy = 0;
            break;
        case ecBottom:                  //* cursor to end of text    
			while (tbUnicode[edit->cp]!=UNICODE_EOLN)
			{
	            edit->cp = edit->cp +1;
			}
            break;
        case ecBack:                    //* backspace                
            if (edit->cp != 0)
	            moveLeftUnicode(tbUnicode+edit->cp-1,1);
            return edtCharUnicode(e,ecLeft);
        case ecDel:                     //* delete                   
            moveLeftUnicode(tbUnicode+edit->cp,1);
            break;
        case ecEnter:                   //* cr/lf                    
            c = UNICODE_LINEFEED;
            edtInsertUnicode(edit,c,tbUnicode,bs);
            return edtCharUnicode(e,ecRight);
        default:                        //* normal char  
            edtInsertUnicode(edit,c,tbUnicode,bs);

			if (edit->attr->alphaMode NEQ TRUE)
				return (edtCharUnicode(e,ecRight));
			/*MC end*/	
            break;

    }
    edit->display = 1;                        // really show it           
  	updateWindow( edit, dy);
    edtUpdateUnicode(edit);


    return MfwResOk;
}




/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : Return no of chinese chars in a string

  GW 06/09/01 - Created
  GW 25/09/01 - Corrected length - now skips first two chars.
*/

U16 strlenUnicode(U16* str)
{
	U16 len = 2; //First char is 0x80, second char is 0x00

	TRACE_FUNCTION("strlenUnicode()");
	
	while (*str!=UNICODE_EOLN)
	{
		//treat ascii chars as half size chinese chars.
		len = len + 2;
		str++;
	}
	return (len);
}


//Assumptions :-
//str is a null-terminated string 
//edit->cp is the cursor position of the char 
//The string is inserted before the cursor char
//The cursor is moved strlen(str) chars forward.
MfwRes edtInsertString (MfwHnd e, char* insWord)
{
    MfwEdt *edit;
    char *textBfr;

	int lenText;
	int lenInsWord;
    int maxTextBfrLen;
	int i;


TRACE_FUNCTION("edtInsertString()");

    if (!e)
        return MfwResIllHnd;

    if (((MfwHdr *)e)->type != MfwTypEdt)
        return MfwResIllHnd;            /* not an editor            */

	edit = ((MfwHdr *) e)->data;
	if (insWord == NULL)
		return (MfwResOk);	//no string to insert - trivial operation.
	if (insWord[0] == 0x00)
		return (MfwResOk);	//no string to insert - trivial operation.
	textBfr			= edit->attr->text;
	if ((textBfr[0] == 0x80) || (textBfr[1] == 0x81) || (textBfr[2] == 0x82))
	{//String is unicode
		return (edtInsertUnicodeString (e, insWord));
	}
	maxTextBfrLen	= edit->attr->size;
	lenText		= strlen(textBfr);
	lenInsWord	= strlen(insWord);
	if ((lenText+lenInsWord) >= maxTextBfrLen)
		return (MfwResErr); //String too long 

	//move text up by 'lemnInsWord' words
	for (i=lenText;i>=edit->cp;i--)
	{
		textBfr[i+lenInsWord]=textBfr[i];
	}
	//and copy string into buffer.
	for (i=0;i<lenInsWord;i++)
		textBfr[edit->cp+i] = insWord[i];
	edit->cp = edit->cp+lenInsWord;
	//Update cursor position
	//<TBD>
	//And output updated text
	edit->display = 1;
	updateWindow( edit, 0);
    edtUpdate(edit);

    return MfwResOk;
}
#define MAXWORD_ARRAY 32
//Assumptions :-
//'removeWord' is char array of MAXWORD chars 
//edit->cp is the cursor position of the char 
//The word removed is at or just before the cursor char
//The cursor is placed before the previous word.
//a space char (start or end) will be removed if there is one.
//GW 18/09/01 - Use 'isAWordChar' procedure
MfwRes edtRemoveString (MfwHnd e, char* removeWord)
{
    MfwEdt *edit;
    char *textBfr;

	int i,j;
	int stChr,endChr;

	TRACE_FUNCTION("edtRemoveString");
	
	if (dspl_get_char_type() != DSPL_TYPE_ASCII)
	{	//String is unicode - can't remove word (could remove a char but...)
		return(MfwResIllHnd);
	}

    if (!e)
        return MfwResIllHnd;

    if (((MfwHdr *)e)->type != MfwTypEdt)
        return MfwResIllHnd;            //* not an editor            *

	edit = ((MfwHdr *) e)->data;
	textBfr			= edit->attr->text;
	if ((textBfr[0] == 0x80) || (textBfr[1] == 0x81) || (textBfr[2] == 0x82))
	{//String is unicode - can't remove word (could remove a char but...)
		return(MfwResIllHnd);
	}

	findWordBounds(edit, &stChr, &endChr);
	//Copy word out
	j = 0;
	for (i=stChr;i<endChr;i++)
	{
		if (j<MAXWORD_ARRAY-1)
		{
			removeWord[j] = textBfr[i];
			if (isAWordChar(removeWord[j]))
				j++;//not punctuation .
			else if (removeWord[j] == ' ') //but do include last space (if it is a space)
				j++;
		}
	}
	removeWord[j] = 0x00;

	//and now move text up by 'j' chars.
	i=stChr;
	j=endChr; 
	//skip one space at start/end.
	if (textBfr[i] != ' ')
	{
		i++;
		if (textBfr[j] == ' ')
			j++;
	}
	//else overwrite first space
	edit->cp = i;

	while((textBfr[i] != 0x00) && (i < j))
	{
		textBfr[i] = textBfr[j];
		i++;
		j++;
	}

	edit->display = 1;
	updateWindow( edit, 0);
    edtUpdate(edit);

    return MfwResOk;
}


//Create a copy of the current word.
//GW 18/09/01 - Use 'isAWordChar' procedure
MfwRes edtCopyString (MfwHnd e, char* removeWord)
{
    MfwEdt *edit;
    char *textBfr;

	int i,j;
	int stChr,endChr;
	
	TRACE_FUNCTION("edtCopyString");
	
	if (dspl_get_char_type() != DSPL_TYPE_ASCII)
	{	//String is unicode - can't remove word (could remove a char but...)
		return(MfwResIllHnd);
	}

    if (!e)
        return MfwResIllHnd;

    if (((MfwHdr *)e)->type != MfwTypEdt)
        return MfwResIllHnd;            //* not an editor            *

	edit = ((MfwHdr *) e)->data;
	textBfr			= edit->attr->text;
	if ((textBfr[0] == 0x80) || (textBfr[0] == 0x81) || (textBfr[0] == 0x82))
	{//String is unicode - can't remove word (could remove a char but...)
		return(MfwResIllHnd);
	}

	findWordBounds(edit, &stChr, &endChr);
	//Copy word out
	j = 0;
	for (i=stChr;i<endChr;i++)
	{
		if (j<MAXWORD_ARRAY-1)
		{
			removeWord[j] = textBfr[i];
			if (isAWordChar(removeWord[j]))
				j++;//not punctuation.
			else if (removeWord[j] == ' ') //but do include last space (if it is a space)
				j++;
		}
	}
	removeWord[j] = 0x00;

	edit->display = 1;
	updateWindow( edit, 0);
    edtUpdate(edit);

    return MfwResOk;
}




MfwRes edtInsertUnicodeString (MfwHnd e, char* insWordChar)
{
    MfwEdt *edit;
    U16 *unicodeBfr;

	int lenText;
	int lenInsWord;
    int maxTextBfrLen;
	int i;
	U16* insWordUnicode;
	insWordUnicode = (U16*) insWordChar;


	TRACE_FUNCTION("edtInsertUnicodeString");
    if (!e)
        return MfwResIllHnd;

    if (((MfwHdr *)e)->type != MfwTypEdt)
        return MfwResIllHnd;            //* not an editor 

	edit = ((MfwHdr *) e)->data;
	if (insWordUnicode == NULL)
		return (MfwResOk);	//no string to insert - trivial operation.
	if (insWordUnicode[0] == 0x0000)
		return (MfwResOk);	//no string to insert - trivial operation.
	unicodeBfr	= (U16*) &edit->attr->text[2];
	if ((edit->attr->text[0] != (char)0x80) && 
		(edit->attr->text[0] != (char)0x81) && 
		(edit->attr->text[0] != (char)0x82))
	{//String is unicode
		return (edtInsertString (e, insWordChar));
	}

	maxTextBfrLen	= edit->attr->size;
	lenText		= strlenUnicode(unicodeBfr);
	lenInsWord	= strlenUnicode(insWordUnicode);
	if ((lenText+lenInsWord) >= maxTextBfrLen)
		return (MfwResErr); //String too long 

	//move text up by 'lemnInsWord' chars
	for (i=lenText/2;i>=edit->cp;i--)
	{
		unicodeBfr[i+lenInsWord]=unicodeBfr[i];
	}
	//and copy string into buffer.
	for (i=0;i<lenInsWord/2;i++)
		unicodeBfr[edit->cp+i] = insWordUnicode[i];
	edit->cp = edit->cp+lenInsWord/2;
	//Update cursor position
	//<TBD>
	//And output updated text
	edit->display = 1;
	updateWindow( edit, 0);
    edtUpdateUnicode(edit);

    return MfwResOk;
}




/*

  
	
	  
		
		  
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtInsert          |
+--------------------------------------------------------------------+

  PURPOSE : insert editing char
  SPR1017 - NH  - Added "curMode" and "curCP" parameters.

*/

static int edtInsert (int c, char *b, int s, U8 curMode, U16 curCP)
{
    int size = (c > 0x80) ? 2 : 1;

	TRACE_FUNCTION("edtInsert");
    if (!curMode)
        return 0;

	if (!(curMode & edtModOverWr))
		{
		if ((int) strlen(b) >= s - size)          /* no more space in buffer  */
        	return 0;
    	
        moveRight(b+curCP,strlen(b+curCP),size);
		}
	else
		{
		if (curCP > s-size )				/* SH - for overwrite mode, only stop input */
			return 0;						/* when the cursor is at the maximum string size */
		}

    if (size == 2)
        *((U16 *) (b+curCP)) = (U16) c;
    else
    	{
    	*(b+strlen(b)+1) = (char) 0;		// SH - make sure string is null terminated
        *(b+curCP) = (char) c;
    	}
    return 1;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : moveRight          |
+--------------------------------------------------------------------+

  PURPOSE : move right memory
  s = no of chars to move 
  d = size (no of chars to be inserted in string) 
  b = current position
*/
void moveRight (char *b, int s, int d)
{
    char *p;
    
	TRACE_FUNCTION("edtInsert");
	
    b += s++;                           /* start with trailing zero */
    p = b + d;                          /* new = old + distance     */
    while (s--)
    {
        *p = *b;
        p--;
        b--;
    }
}

/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : moveLeft           |
+--------------------------------------------------------------------+

  PURPOSE : move left memory
  s = no of chars to move 
  d = size (no of chars to be inserted in string) 
  b = current position
  str - string
*/
void moveLeft (char * str, int ofs)
{

	
	while (*str)
	{
		str[0] = str[ofs];
		if (*str)
			str++;
	}
	
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE : edtCommand         |
+--------------------------------------------------------------------+

  PURPOSE : handle mfw windows command

*/

static int edtCommand (U32 cmd, void *h)
{
	TRACE_FUNCTION("edtCommand");

    switch (cmd)
    {
        case MfwCmdDelete:              /* delete me                */
            if (!h)
                return 0;
            edtDelete(h);
            return 1;
        case MfwCmdUpdate:              /* repaint                  */
            if (!h || ((MfwHdr *) h)->type != MfwTypEdt)
                return 0;
            edtUpdate(((MfwHdr *) h)->data);
            return 1;
        default:
            break;
    }

    return 0;
}




/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/
  //Move part of string right (delete char)
void moveLeftUnicode(U16* unicodeStr, int nChars)
{
	TRACE_FUNCTION("moveLeftUnicode");
	//Copy until end of line char reached - do not overwrite existing EOLN char 
	while (unicodeStr[0] != UNICODE_EOLN)
	{
		unicodeStr[0] = unicodeStr[nChars];
		if (unicodeStr[0] != UNICODE_EOLN)
			unicodeStr++;
		//else we have copied end of line char - stop.
	}

}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/
U16 strlenUnicodePixels(U16* str)
{
	U16 len = 0;

	TRACE_FUNCTION("strlenUnicodePixels");
	
	while (*str!=UNICODE_EOLN)
	{	//Is next char an ascii char ? 
		if ((*str & UNICODE_NONASCII) != 0)
			len = len+12;
		else
			len = len+6;
		str++;
	}
	return (len);
}

/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/
U16* strchrUnicode(U16* str,U16 chr)
{
	TRACE_FUNCTION("strchrUnicode");
	
	while (*str!=UNICODE_EOLN)
	{
		if (*str==chr)
			return (str);
		else
			str++;
	}
	return (NULL);
}

/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/
//Return pointer to end of unicode string.
U16* strendUnicode(U16* tp)
{	TRACE_FUNCTION("strendUnicode");
	while (*tp!=UNICODE_EOLN)
	{
		tp++;
	}
	return (tp);

}
/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/
//Move string right by 'nChars' (insert char)
static void moveRightUnicode(U16 *unicodeStr, int nChars)
{
	U16* strEndPtr;

	TRACE_FUNCTION("moveRightUnicode");
	
	strEndPtr = strendUnicode( unicodeStr);
	while (strEndPtr >= unicodeStr)
	{
		strEndPtr[nChars] = strEndPtr[0];
		strEndPtr--;
	}
}

static int edtInsertUnicode (MfwEdt *edit, int c, U16 *b, int s)
{	//Unicode chars are always 2 bytes.
	U16* bCursor;

	TRACE_FUNCTION("edtInsertUnicode");

    if (!edit->curMode)
        return 0;

    if ( strlenUnicode(b) >= s/* -2 MC SPR 1319, allow last 2 bytes to be used*/ )          //* no more space in buffer  *
        return 0;

	bCursor = b+edit->cp;

    if (!(edit->curMode & edtModOverWr))
        moveRightUnicode(bCursor,1);

	*((U16 *) (b+edit->cp )) = (U16) c;

    return 1;

}

int wArray[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int getCharWidth(int nextChar)
{
	int w;
	if ((nextChar == UNICODE_LINEFEED) || (nextChar == UNICODE_CR))
		w = 6;
	else
		w = font_getCharWidth( ((nextChar & 0x00FF) <<8) | ((nextChar & 0xFF00) >>8) );
	return (w);
}

static void edtOutTextLines (int px, int py, int ls, int ly, U16 *tpUnicode, unsigned char* tpAscii,
							 int fontHeight, int display)
{
    U16 ctWord;
	unsigned char ctByte;
    unsigned int fitChars;			//No of chars that fit on this line.
	U16 nextChar;					//next char to display
	int lineWidth;					//Width (so far) of the current line of text.
	int dispEnd = 0;
	int spaceChar;
	int charWidth;
	int punctuation;
	char chr;
	if ((tpAscii==NULL) && (tpUnicode == NULL))
		return;

         
	fitChars = 0;
	if (tpAscii)
	{
		nextChar = (tpAscii[fitChars] << 8) & 0xFF00;
		if ((nextChar == UNICODE_LINEFEED) || (nextChar == UNICODE_CR))
		{
			fitChars++;
			nextChar = (tpAscii[fitChars] << 8) & 0xFF00;
		}
	}
	else
	{
		 nextChar = tpUnicode[fitChars];
		if ((nextChar == UNICODE_LINEFEED) || (nextChar == UNICODE_CR))
		{
			fitChars++;
			nextChar = tpUnicode[fitChars];
		}
	}

    while ((nextChar != UNICODE_EOLN) && (!dispEnd))                /* any more to display      */
    {
		fitChars = 0;
		if (tpAscii)
		{
			charWidth = getCharWidth(nextChar);
			nextChar = (tpAscii[fitChars] << 8) & 0xFF00;
			if ((nextChar == UNICODE_LINEFEED) || (nextChar == UNICODE_CR))
			{	//linefeed - always start a new-line.
				charWidth = ls+1;
			}
		}
		else
		{
			nextChar = tpUnicode[fitChars];
			charWidth = getCharWidth(nextChar);
			if ((nextChar == UNICODE_LINEFEED) || (nextChar == UNICODE_CR))
				{	//linefeed - always start a new-line.
					charWidth = ls+1;
				}
		}
		lineWidth = 0;
		spaceChar = -1;

		while ((lineWidth <= ls) && (nextChar != UNICODE_EOLN))
		{
			lineWidth = lineWidth + charWidth;

			//If the last char added still fits on the line
			if (lineWidth <= ls)
			{	//move on to the next character.
				fitChars++;
				//if the previous char was a space, we can cut the line on the next char.
				punctuation = FALSE;
				if ((nextChar & UNICODE_NONASCII) == 0)
				{
					chr = (nextChar >> 8) & 0x00FF;
					if (chr==' ')			// sbh - only space is punctuation now.
						punctuation = TRUE;
				}
				//Remember when we find a space if it is not the first char of a new line
				if ((fitChars > 1) &&
					((punctuation) || 
					 (nextChar == UNICODE_STARTHIGHLIGHT)|| 
					 (nextChar == UNICODE_ENDHIGHLIGHT)))
				{	//save char after space.
					spaceChar = fitChars;
				}
				if (tpAscii)
				{
					charWidth = getCharWidth(nextChar);
					nextChar = (tpAscii[fitChars] << 8) & 0xFF00;
				}
				else
				{
					 nextChar = tpUnicode[fitChars];
					charWidth = getCharWidth(nextChar);
				}
				if ((nextChar == UNICODE_LINEFEED) || (nextChar == UNICODE_CR))
				{	//linefeed - always start a new-line.
					charWidth = ls+1;
				}

			}
		}
        if (nextChar == UNICODE_EOLN)
        {                               /* all fits fine ...        */
			dispEnd = TRUE;
		}
		else if ((nextChar == UNICODE_LINEFEED) || (nextChar == UNICODE_CR))
		{	//Break line on this linefeed char
		}
		else if (spaceChar != -1) // we have a space in the line
		{	
			fitChars = spaceChar;
		}
		if (tpAscii)
		{
	        ctByte = tpAscii[fitChars];			/* save not fitting char    */		
	        tpAscii[fitChars] = 0x00;//UNICODE_EOLN;	/* cut the line             */
			if (display)
				dspl_TextOut((U16)px,(U16)py, 0, (char*)tpAscii); /* display line         */
			tpAscii[fitChars] = ctByte;			/* restore                  */
	        tpAscii = &tpAscii[fitChars];				/* and go ahead             */
			//For linefeed char - move to next char.
			if (((ctByte <<8) == UNICODE_LINEFEED) || ((ctByte <<8) == UNICODE_CR))
				tpAscii++;

		}
		else
		{
	        ctWord = tpUnicode[fitChars];			/* save not fitting char    */
	        tpUnicode[fitChars] = UNICODE_EOLN;	/* cut the line             */
			if (display)
				dspl_TextOut((U16)px,(U16)py, DSPL_TXTATTR_UNICODE, (char*)tpUnicode); /* display line         */
			tpUnicode[fitChars] = ctWord;			/* restore                  */
	        tpUnicode = &tpUnicode[fitChars];				/* and go ahead             */
			if ((ctWord == UNICODE_LINEFEED) || (ctWord == UNICODE_CR))
				tpUnicode++;
		}        
        py = py + fontHeight;			/* move to next screen line */
        if (py > ly - fontHeight)		/* past end of screen ?     */
            dispEnd = TRUE;             /* clip the rest            */
    }
}

/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/
MfwRes edtUpdateUnicode (MfwEdt *e)
{
	int warn;
	UBYTE temp;

    S16 ls;                             /* width of edit window     */
    S16 ly;                             /* bottom of edit window    */
    U8 oldFont = -1;                    /* store previous font      */
	/* NM p004
	U8 uMode;
	*/
    U16 *tpWord;	
	U16 *endChar;	
	static char bmp[5];

	TRACE_FUNCTION("edtUpdateUnicode");
	
    if (!e)
        return MfwResIllHnd;

    if (!e->attr->text)
        return MfwResErr;               /* no text to display       */

	if (((unsigned char)e->attr->text[0] < 0x80) || ((unsigned char)e->attr->text[0] > 0x83))
        return MfwResErr;               /* text is not unicode      */
		
	temp = dspl_get_char_type();		
	dspl_set_char_type(DSPL_TYPE_UNICODE);

    if (!(e->flags & MfwEdtVisible))
        e->display = 0;                    /* invisible editor         */

	tpWord = ((U16*)&e->attr->text[2]) + e->curOffs;
    ls = e->attr->win.sx;               /* width of edit window     */
    ly = (S16) (e->attr->win.py+e->attr->win.sy);  /* bottom of edit window    */
    if (e->attr->font != (U8) -1)
        oldFont = dspl_SelectFontbyID(e->attr->font); /* setup font */
    e->fontHeight = dspl_GetFontHeight();  /* get height of curr font  */
    e->curMode = e->attr->mode;            /* setup edi mode           */
    if (e->display)
        dspl_Clear(e->attr->win.px,e->attr->win.py,(U16)(ls+e->attr->win.px-1),(U16)(ly-1));
    dspl_SetCursor(0,(U8)(e->curMode&edtCurMask));

	//Add a space to the end of the line
	endChar = strendUnicode(tpWord);
	if ((endChar[0] == UNICODE_EOLN) &&
		(endChar[1] == UNICODE_EOLN))
	{

		endChar[0] = UNICODE_SPACE;
		endChar[1] = UNICODE_EOLN;

		edtOutTextLines(e->attr->win.px, e->attr->win.py, ls, ly, tpWord, NULL,
						e->fontHeight, e->display); //* show it     * /

		//and remove space again.
		endChar[0] = UNICODE_EOLN;
	}
	else
	{	//Cannot add space
		edtOutTextLines(e->attr->win.px, e->attr->win.py, ls, ly, tpWord, NULL,
						e->fontHeight, e->display); //* show it     * /
	}
	
	
    if (e->display && (e->curMode & edtCurMask))
        dspl_SetCursorPos(e->curCX,e->curCY,e->curCSize,(S16)e->fontHeight); /* display cursor           */
    if (oldFont != (U8) -1)
        dspl_SelectFontbyID(oldFont);   /* restore previous font    */


		
	dspl_set_char_type(temp);

    return MfwResOk;
}


/*
+--------------------------------------------------------------------+
| PROJECT : MMI-Framework (8417)        MODULE  : MFW_EDT            |
| STATE   : code                        ROUTINE :        |
+--------------------------------------------------------------------+

  PURPOSE : 

  GW 06/09/01 - Created
*/

//Incodmation relating to last 'space' char found.
typedef struct {
	int charWidth;
	int lineCharPos;
} T_SPACE_EDITINFO;

//Information about current editor
typedef struct  {
	int txtWidth;
	int charWidth;
	int endOfLine;		//TRUE indicates end of a text line
	int endOfText;		//TRUE indicates no more chars in line.
	int lineXpos;		//Current x-pos (in pixels) of cursor.
	int lineCharPos;	//Current char/word position in array
	int lastChar;		//index of last char on cursor line
	BOOL precedingEOL;	// sbh - preceding character was a CR/LF
	T_SPACE_EDITINFO space;
} T_EDITINFO;


//Calculate width of chars on screen so far.
//GW 18/09/01 - Corrected code dealing with linefeeds and also deal with carriage returns.
void getTotalWidth(U16 txtChar, int scrSxPixels, T_EDITINFO *editInfo )
{
	char chr;
	int punctuation;
	
	TRACE_FUNCTION("getTotalWidth");
	
	editInfo->endOfLine = FALSE;

	if (editInfo->precedingEOL)				// Previous character was CR/LF
		{
		editInfo->precedingEOL = FALSE;
		editInfo->endOfLine = TRUE;
		}
		
	if (txtChar == UNICODE_EOLN)
	{
		editInfo->endOfText = TRUE;		
		editInfo->charWidth = getCharWidth(txtChar);//6;	// sbh - Has width, so it can be wrapped if necessary
	}
	else if ((txtChar == UNICODE_LINEFEED) || (txtChar == UNICODE_CR))
	{
		editInfo->precedingEOL = TRUE;
		editInfo->charWidth = getCharWidth(txtChar);//6;
	}
	else //GW-Get actual width for proportional fonts.
		editInfo->charWidth = getCharWidth(txtChar);
	
	if (editInfo->txtWidth+editInfo->charWidth >  scrSxPixels)
	{	//newline
		editInfo->txtWidth = 0;
		editInfo->endOfLine = TRUE;

		//update start of window.
		if ((txtChar == UNICODE_LINEFEED)||(txtChar == UNICODE_CR))
		{
			editInfo->lineCharPos	= editInfo->space.lineCharPos+1;

		}
		else if (editInfo->space.lineCharPos > 0) 
		{	//reset editor position back to here
			editInfo->lineCharPos	= editInfo->space.lineCharPos+1;
			editInfo->charWidth     = editInfo->space.charWidth;
			editInfo->endOfText = FALSE;
		}

		editInfo->space.lineCharPos = 0;
	}
	else
	{	
		punctuation = FALSE;
		if (txtChar==UNICODE_SPACE)						// sbh - will only wrap on a space
			punctuation = TRUE;

		if ((punctuation) && (editInfo->txtWidth > 0)) 
		{	//A space is a good point for a soft break - remember enough info so that this
			//point can be restored
			editInfo->space.lineCharPos = editInfo->lineCharPos;		
			if ((txtChar == UNICODE_LINEFEED) || (txtChar == UNICODE_CR))
				editInfo->space.charWidth   = getCharWidth(txtChar);
			else
				editInfo->space.charWidth   = editInfo->charWidth;
			}
	}

}
//Update the cursor position
// SPR920 - NH (SH) - provide editor handle e, as cursor vars are now in structure

void updateCursorPos(MfwEdt *e, T_EDITINFO *editInfo)
{
	TRACE_FUNCTION("updateCursorPos");
	e->curCSize	= editInfo->charWidth;
	if (e->curCSize < 3)
		e->curCSize = 3;
	e->curCX	= editInfo->txtWidth;
}

//dy - move cursor up/down screen by dy lines
MfwRes updateWindow (MfwEdt *e, int  dy	)
{
T_EDITINFO editInfo;

	int winCharPos;		//char position  in string of the first text line in current window
	int winLineNo;		//line no of the first text line to be displayed

	int ipCursorCharPos;	
	int opCursorCharPos;	
	int cursorLineNo;	//line no the cursor is on

	int linePos;		//char pos in string of current line.
	int lineNo;			//overall displayed line (from start of text)

	int editComplete;	//flag indicating cursor position found/updated or end of line reached.

	int scrSxPixels;
	int scrSyLines;

	char* textStartAscii;
	U16* textStartUnicode;
	U16  charUnicode;	//current unicode char.

	int textStrType;

	TRACE_FUNCTION("UpdateWindow()");

	//Set up screen size - the width in pixels and no of lines displayed.
	if (e->fontHeight > 5)
		scrSyLines = e->attr->win.sy / e->fontHeight;
	else
		scrSyLines = e->attr->win.sy / 6;
	scrSxPixels = e->attr->win.sx;

	ipCursorCharPos = e->cp;
	if ((ipCursorCharPos < 0) || (ipCursorCharPos > 32767))
		ipCursorCharPos = 0;
	opCursorCharPos = ipCursorCharPos;
	lineNo = 0;
	winLineNo = 0;
	winCharPos = 0;
	editComplete = FALSE;
	editInfo.endOfText = FALSE;
	editInfo.lineCharPos = 0;
	editInfo.lastChar = 9999;
	editInfo.space.lineCharPos = 0;
	editInfo.precedingEOL = FALSE;
	linePos = 0;

	editInfo.txtWidth = 0;
	cursorLineNo = 0;

	if ((e->attr->text[0] == (char)0x80) || 
		(e->attr->text[0] == (char)0x81) || 
		(e->attr->text[0] == (char)0x82))
	{
		textStrType = DSPL_TYPE_UNICODE;
		textStartUnicode = (U16*) &e->attr->text[2];    /* start of edit text - 16 bits/char      */
	}
	else
	{
		textStrType = DSPL_TYPE_ASCII;
		textStartAscii = &e->attr->text[0];				/* start of edit text - 8 bits/char       */
	}

	//Go through editor and work out 
	// (1) current x-pixel position for cursor 
	// (2) line number of the start of the display.
	while( (!editInfo.endOfText) && (!editComplete) )
	{
		if (textStrType == DSPL_TYPE_UNICODE)
		{
			charUnicode = textStartUnicode[editInfo.lineCharPos];
			getTotalWidth(charUnicode,scrSxPixels,&editInfo);
		}
		else
		{
			charUnicode = (textStartAscii[editInfo.lineCharPos] << 8) & 0xFF00;
			getTotalWidth(charUnicode,scrSxPixels,&editInfo);
		}

		if (editInfo.endOfLine)
		{
			//newline or current char will not fit on previous line.
			lineNo++;
			linePos = editInfo.lineCharPos;
			editInfo.txtWidth = 0;
			//Is this the first line to be displayed in the editor?
			if (editInfo.lineCharPos <= e->curOffs)
			{
				winLineNo = lineNo;
				winCharPos= editInfo.lineCharPos;
			}
		}

		if (editInfo.endOfText)
		{
			//Cursor is past end of line - move to char before end of line.
			if (ipCursorCharPos > editInfo.lineCharPos)
			{
				ipCursorCharPos = editInfo.lineCharPos;
				opCursorCharPos = editInfo.lineCharPos;
			}
		}
		
		if (editInfo.lineCharPos == ipCursorCharPos)
		{	//found the cursor position - either 
			//		the new pos if dy=0 or 
			//		the old pos if we have moved up/down a line.
			updateCursorPos(e, &editInfo);
			editInfo.lineXpos  = editInfo.txtWidth;
			cursorLineNo   = lineNo;
		}
		else if ((editInfo.lineCharPos > ipCursorCharPos) &&
		  		 (lineNo      > cursorLineNo      ) &&
				 (lineNo      > cursorLineNo + dy))
		{
			//we have moved far enough down to store all required information
			editComplete   = TRUE;
		}
		editInfo.txtWidth = editInfo.txtWidth + editInfo.charWidth;
		editInfo.lineCharPos++;
	}	//end while
	
	//We now know either (a) the line the cursor is on and the char offset of the cursor or (b) the
	//original line the cursor was on and the x-pixel position of the cursor (for dy != 0)  
	
	if (dy)
	{	//update line with the cursor on it
		if (cursorLineNo+dy >lineNo )
			cursorLineNo = lineNo; //last line of editor.
		else if (cursorLineNo+dy < 0)
			cursorLineNo = 0;
		else
			cursorLineNo = cursorLineNo+dy;

		//Now we need to calculate cursor char pos. 'opCursorCharPos'

	}
	else
	{	
		//Cursor line no is already set up.

		//the new cursor position was passed into the procedure.
		opCursorCharPos = ipCursorCharPos;
	}

	editInfo.lineCharPos = 0;
	lineNo    = 0;
	editInfo.txtWidth  = 0;
	editComplete = FALSE;
	editInfo.endOfText = FALSE;
	editInfo.space.lineCharPos = 0;

	//Update start of windows position
	if (cursorLineNo < winLineNo || !(e->attr->mode & edtCurMask)) 
	{//cursor is on a line before current window screen - search from the start
	// sbh - or we're in read-only mode, no cursor, scroll with every up/down press
		winLineNo = cursorLineNo;
		winCharPos = 0;
	}
	else if (cursorLineNo >= winLineNo+scrSyLines) 
	{	//cursor is below the bottom of the screen
		winLineNo = cursorLineNo-(scrSyLines-1);
		winCharPos = 0;
	}
	else if (dy != 0)
	{	//windows line no is unchanged - start search at win char pos.
		editInfo.lineCharPos = winCharPos;
		lineNo = winLineNo;
	}
	else
	{	//we do not need to calculate new window position - it is unchanged.
		//and we have already calculated the new cursor position.
		editComplete = TRUE;
	}

	//Calculate last char on cursor line and winCharPos
	if (!editComplete)
	{
		while( (!editInfo.endOfText) && (!editComplete) )
		{
			if (textStrType == DSPL_TYPE_UNICODE)
			{
				charUnicode = textStartUnicode[editInfo.lineCharPos];
				getTotalWidth(charUnicode,scrSxPixels,&editInfo);
			}
			else
			{
				charUnicode = (textStartAscii[editInfo.lineCharPos] << 8) & 0xFF00;
				getTotalWidth(charUnicode,scrSxPixels,&editInfo);
			}
			if (editInfo.endOfLine)
			{	//newline
				editInfo.txtWidth = 0;
				//update start of window.
				linePos = editInfo.lineCharPos;

				//Remember char before first char on next line.
				if (lineNo == cursorLineNo)
				{
					if (ipCursorCharPos >=  editInfo.lineCharPos) 
						ipCursorCharPos = editInfo.lineCharPos-1;
				}
				lineNo++;
				if (winLineNo == lineNo)
					winCharPos = editInfo.lineCharPos;
			}
			if (dy!=0)
			{	//line number has changed
				//Once we have found the correct line, look for the char at the same x-pixel pos
				//as before (or the last char before we pass the position).
				if (lineNo == cursorLineNo)
				{	
					if (editInfo.txtWidth <= editInfo.lineXpos)
					{	//Update cursor char pos...
						ipCursorCharPos = editInfo.lineCharPos;
					}
				}
			}
			else if (lineNo > cursorLineNo) //...or we start a new line
			{
				editComplete = TRUE;
			}
		
			editInfo.txtWidth = editInfo.txtWidth + editInfo.charWidth;
			editInfo.lineCharPos++;
		}	//end while

		editComplete = FALSE;
	}
	
	editInfo.lineCharPos = winCharPos;
	lineNo    = winLineNo;
	editInfo.txtWidth  = 0;
	editInfo.endOfText = FALSE;
	editInfo.space.lineCharPos = 0;

	//Calculate where the window is to start from
	while( (!editInfo.endOfText) && (!editComplete) )
	{
		if (textStrType == DSPL_TYPE_UNICODE)
		{
			charUnicode = textStartUnicode[editInfo.lineCharPos];
			getTotalWidth(charUnicode,scrSxPixels,&editInfo);
		}
		else
		{
			charUnicode = (textStartAscii[editInfo.lineCharPos] << 8) & 0xFF00;
			getTotalWidth(charUnicode,scrSxPixels,&editInfo);
		}
		if (editInfo.endOfLine)
		{	//newline
			editInfo.txtWidth = 0;
			//update start of window.
			linePos = editInfo.lineCharPos;
			lineNo++;
		}

		if ((lineNo == cursorLineNo) &&
			(ipCursorCharPos == editInfo.lineCharPos))
		{	//we have reached desired char.
			opCursorCharPos = editInfo.lineCharPos;
			updateCursorPos(e, &editInfo);
			cursorLineNo   = lineNo;
			editComplete = TRUE;
		}
	
		editInfo.txtWidth = editInfo.txtWidth + editInfo.charWidth;
		editInfo.lineCharPos++;
	}	//end while

	//Calculate y position of cursor
	//GW 17/09/01 Place cursor for windows that have blank lines at the top of the screen
	e->curCY = (cursorLineNo - winLineNo)*e->fontHeight+e->attr->win.py; 

	//Output updated window start position
	e->curOffs = winCharPos;
	e->cp = opCursorCharPos;

    return (MfwResOk);
}