FreeCalypso > hg > tcs211-l1-reconst
diff g23m/condat/ms/src/mfw/mfw_edt.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/g23m/condat/ms/src/mfw/mfw_edt.c Mon Jun 01 03:24:05 2015 +0000 @@ -0,0 +1,2109 @@ +/* ++--------------------------------------------------------------------+ +| 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); +} + + + + + + + +