FreeCalypso > hg > fc-magnetite
view src/aci2/mfw/mfw_edt.c @ 629:3231dd9b38c1
armio.c: make GPIOs 8 & 13 outputs driving 1 on all "classic" targets
Calypso GPIOs 8 & 13 are pinmuxed with MCUEN1 & MCUEN2, respectively,
and on powerup these pins are MCUEN, i.e., outputs driving 1. TI's code
for C-Sample and earlier turns them into GPIOs configured as outputs also
driving 1 - so far, so good - but TI's code for BOARD 41 (which covers
D-Sample, Leonardo and all real world Calypso devices derived from the
latter) switches them from MCUEN to GPIOs, but then leaves them as inputs.
Given that the hardware powerup state of these two pins is outputs driving 1,
every Calypso board design MUST be compatible with such driving; typically
these GPIO signals will be either unused and unconnected or connected as
outputs driving some peripheral. Turning these pins into GPIO inputs will
result in floating inputs on every reasonably-wired board, thus I am
convinced that this configuration is nothing but a bug on the part of
whoever wrote this code at TI.
This floating input bug had already been fixed earlier for GTA modem and
FCDEV3B targets; the present change makes the fix unconditional for all
"classic" targets. The newly affected targets are D-Sample, Leonardo,
Tango and GTM900.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 02 Jan 2020 05:38:26 +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); }