FreeCalypso > hg > fc-magnetite
view src/aci2/mfw/mfw_edt.c @ 285:504c9dcbffb2
GTA0x target: GPIOs 3, 10, 11 and 12 are unconnected, so drive them as outputs
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 08 Aug 2017 01:28:52 +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); }