FreeCalypso > hg > fc-magnetite
view src/aci2/atb/ATBEditor.c @ 662:8cd8fd15a095
SIM speed enhancement re-enabled and made configurable
TI's original code supported SIM speed enhancement, but Openmoko had it
disabled, and OM's disabling of speed enhancement somehow caused certain
SIM cards to start working which didn't work before (OM's bug #666).
Because our FC community is much smaller in year 2020 than OM's community
was in their day, we are not able to find one of those #666-affected SIMs,
thus the real issue they had encountered remains elusive. Thus our
solution is to re-enable SIM speed enhancement and simply wait for if
and when someone runs into a #666-affected SIM once again. We provide
a SIM_allow_speed_enhancement global variable that allows SIM speed
enhancement to be enabled or disabled per session, and an /etc/SIM_spenh
file in FFS that allows it to enabled or disabled on a non-volatile
basis. SIM speed enhancement is now enabled by default.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 24 May 2020 05:02:28 +0000 |
parents | 93999a60b835 |
children |
line wrap: on
line source
/******************************************************************************* CONDAT (UK) ******************************************************************************** This software product is the property of Condat (UK) Ltd and may not be disclosed to any third party without the express permission of the owner. ******************************************************************************** $Project name: $Project code: $Module: $File: ATBEditor.c $Revision: $Author: SH - Condat(UK) $Date: ******************************************************************************** Description: ATB Editor component. ******************************************************************************** $History: ATBEditor.c Feb 02, 2006 DR: OMAPS00061468 - x0035544. Description: SAT 27.22.4.22.2 SET UP IDLE MODE TEXT (Icon support) fails Solution : Modifications for displaying idle mode text and icon are done in ATB_edit_OutTextLines. Jan 16, 2006 DR: OMAPS00061460 - Shashi Shekar B.S. Description: SAT Icon support Solution : Modifications done in ATB_edit_OutTextLines for display of the title icon. CRR:25542 - xpradipg - 26 Oct 2004 Description: The last character is not deleted from the text entry screen in any WAP page. Solution: The formatIndex was set to zero on reaching the last character which skips the removal of the last character. This assignment is moved out. Jul 22,2004 CRR:21605 xrashmic - SASKEN Description: After deleting all the characters in the editor the case does not change to sentence case. Fix: After deleting a character, check if editor is empty and then set the case to sentence case only if the user has not modified the case. $End *******************************************************************************/ #ifndef ATB_EDITOR_C #define ATB_EDITOR_C #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 <math.h> #include "dspl.h" #include "ATBCommon.h" #include "ATBDisplay.h" #include "ATBEditor.h" #include "font_bitmaps.h" #include "cus_aci.h" #include "prim.h" #include "pcm.h" #undef TRACE_ATBEDITOR extern UBYTE CaseChanged; // SPR 21605 // Shashi Shekar B.S., a0876501, Jan 16, 2006, DR: OMAPS00061460 #ifdef FF_MMI_SAT_ICON const unsigned char SATIconQuestionMark[] = { 0x25,0x25,0x00,0x00,0x00,0x00,0x25,0x25, 0x25,0x00,0xE0,0xE0,0xE0,0xE0,0x00,0x25, 0x00,0xE0,0xE0,0xFF,0xFF,0xE0,0xE0,0x00, 0x00,0xE0,0xFF,0xE0,0xE0,0xFF,0xE0,0x00, 0x00,0xE0,0xE0,0xE0,0xE0,0xFF,0xE0,0x00, 0x00,0xE0,0xE0,0xFF,0xFF,0xE0,0xE0,0x00, 0x00,0xE0,0xE0,0xFF,0xE0,0xE0,0xE0,0x00, 0x00,0xE0,0xE0,0xFF,0xE0,0xE0,0xE0,0x00, 0x25,0x00,0xE0,0xE0,0xE0,0xE0,0x00,0x25, 0x25,0x25,0x00,0x00,0x00,0x00,0x25,0x25, }; #endif /******************************************************************************* LOCAL FUNCTION PROTOTYPES *******************************************************************************/ /* SPR#1983 - SH - Add 'text' parameter */ static int ATB_edit_Insert (T_ED_DATA *editor, T_ATB_TEXT *text, USHORT character); static void ATB_edit_FindNext(T_ED_DATA *editor); static USHORT ATB_edit_FindPrev(T_ED_DATA *editor); static void ATB_edit_OutTextLines (T_ED_DATA *editor); static void ATB_edit_WordWrap(T_ED_DATA *editor); static void ATB_edit_UpdateCursorPos(T_ED_DATA *editor); static ED_RES ATB_edit_Update (T_ED_DATA *editor, int dy); static void ATB_edit_LineDestroyAll(T_ED_DATA *editor); /******************************************************************************* $Function: ATB_edit_Create $Description: Create the editor. Allocate memory for the editor data and set up some default parameters. $Returns: Pointer to the editor data, or NULL if memory allocation failed. $Arguments: editAttr - The editor attributes (caller allocated) callback - Callback function *******************************************************************************/ T_ED_DATA* ATB_edit_Create (T_ED_ATTR *editAttr, T_ED_CB callback) { T_ED_DATA *editor; TRACE_FUNCTION("ATB_edit_Create()"); /* Allocate memory for editor data */ editor = (T_ED_DATA *) ATB_mem_Alloc(sizeof(T_ED_DATA)); if (!editor) return NULL; /* Reset editor data */ memset(editor, 0, sizeof(T_ED_DATA)); editor->display = FALSE; editor->handler = callback; editor->attr = editAttr; editor->cursor.width = 8; editor->initialised = FALSE; editor->line = NULL; return editor; } /******************************************************************************* $Function: ATB_edit_Destroy $Description: Delete the editor. Free the allocated memory. $Returns: ED_OK - OK ED_BAD_HANDLE - Editor data is null pointer $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_Destroy (T_ED_DATA *editor) { ED_RES result = ED_OK; TRACE_FUNCTION("ATB_edit_Destroy()"); if (editor) { ATB_edit_LineDestroyAll(editor); if (editor->hiddenText) { ATB_edit_HiddenExit(editor); } ATB_mem_Free((void *)editor, sizeof(T_ED_DATA)); } else result = ED_BAD_HANDLE; return result; } /******************************************************************************* $Function: ATB_edit_Init $Description: Initialise the editor. Ensures that valid combinations of editing modes are set. Sets uppercase/lowercase appropriately. Moves the cursor to the correct place in the text. Performs a word-wrap. $Returns: ED_OK - OK $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_Init (T_ED_DATA *editor) { TRACE_FUNCTION("ATB_edit_Init()"); if (!editor) /* If editor handle doesn't exist, return error */ return ED_BAD_HANDLE; /* Get the length of the supplied string */ ATB_string_Length(&editor->attr->text); /* SPR#1983 - SH - Set CAPS preference after moving cursor, * as any cursor moves now reset CAPS to LOWER case. */ ATB_edit_SetCase(editor, ED_CASE_LOWER); /* Non read-only modes*/ if (!ATB_edit_Mode(editor, ED_MODE_READONLY)) { /* Initialise hidden mode */ if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_edit_HiddenInit(editor); ATB_edit_SetMode(editor, ED_MODE_OVERWRITE); } /* Initialise formatted mode */ if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) { ATB_edit_SetMode(editor, ED_MODE_OVERWRITE | ED_MODE_ALPHA); ATB_edit_MoveCursor(editor,ctrlTop,FALSE); /* Send cursor to start of string */ /* Check for "M" & "m" formats; these set the case to upper/lower by default. */ /* SPR#1983 - SH - Also, overwrite mode can be switched off for these * cases, free entry allowed.*/ ATB_edit_SetCase(editor, ED_CASE_CAPS); /* Caps is on by default */ if (strcmp(editor->attr->FormatString, "*M")==0) { ATB_edit_SetCase(editor, ED_CASE_UPPER); ATB_edit_ResetMode(editor, ED_MODE_OVERWRITE); } if (strcmp(editor->attr->FormatString, "*m")==0) { ATB_edit_SetCase(editor, ED_CASE_LOWER); ATB_edit_ResetMode(editor, ED_MODE_OVERWRITE); } } /* Of the cursor modes, only formatted starts at the top, others start at the bottom */ else { ATB_edit_MoveCursor(editor, ctrlBottom, FALSE); /* SPR#1983 - SH - If the buffer is empty, first character will be capitalised. * Otherwise, lowercase is the default. */ if (editor->attr->text.len==0) { ATB_edit_SetCase(editor, ED_CASE_CAPS); /* Caps is on if first character */ } } } /* No cursor modes */ else { ATB_edit_MoveCursor(editor, ctrlTop, FALSE); } /* Format text */ ATB_edit_Update(editor, 0); /* Make editor visible */ editor->display = TRUE; /* really show it */ return ED_OK; } /******************************************************************************* $Function: ATB_edit_Reset $Description: Reset the editor - move the cursor to the start. $Returns: ED_BAD_HANDLE - Editor data pointer is null ED_OK - OK $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_Reset (T_ED_DATA *editor) { TRACE_FUNCTION("ATB_edit_Reset()"); if (!editor) return ED_BAD_HANDLE; /* Editor does not exist */ editor->cursor.pos = 0; /* Reset cursor position */ editor->initialised = FALSE; /* Fully wrap all of text */ ATB_edit_Refresh(editor); /* Refresh word wrap */ return ED_OK; } /******************************************************************************* $Function: ATB_edit_Show $Description: Show the editor, if it is visible. $Returns: ED_OK - OK $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_Show (T_ED_DATA *editor) { UBYTE previousFont = -1; // store previous font USHORT editX = editor->attr->win_size.px; // pos. of left of edit window USHORT editY = editor->attr->win_size.py; // pos. of top of edit window USHORT editWidth = editor->attr->win_size.sx; // width of edit window USHORT editHeight = editor->attr->win_size.sy; // height of edit window TRACE_FUNCTION("ATB_edit_Show()"); if (!editor) return ED_BAD_HANDLE; // Editor doesn't exist if (editor->display) { resources_setColour(editor->attr->colour); if (editor->attr->font != (UBYTE) -1) previousFont = dspl_SelectFontbyID(editor->attr->font); // setup font dspl_Clear(editX,editY,editX+editWidth-1,editY+editHeight-1); // Clear the editor window ATB_edit_OutTextLines(editor); // Show text /* Display cursor, if it's switched on and we're not in multitap */ if (editor->attr->cursor!=ED_CURSOR_NONE && !editor->multitap) { ATB_display_Cursor(&editor->attr->text, editor->cursor.pos, editor->attr->cursor, editX+editor->cursor.x,editY+editor->cursor.y, editor->cursor.width,editor->cursor.height); } } if (previousFont != (UBYTE) -1) dspl_SelectFontbyID(previousFont); // Restore previous font return ED_OK; } /******************************************************************************* $Function: ATB_edit_Refresh $Description: Refresh the editor word wrap etc. $Returns: ED_OK - OK $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_Refresh (T_ED_DATA *editor) { TRACE_FUNCTION("ATB_edit_Refresh()"); if (!editor) return ED_BAD_HANDLE; /* editor does not exist */ /* Get the length of the supplied string */ ATB_string_Length(&editor->attr->text); /* Update word wrap */ ATB_edit_Update(editor, 0); return ED_OK; } /******************************************************************************* $Function: ATB_edit_Hide $Description: Hide the editor $Returns: ED_BAD_HANDLE - Editor data pointer is null ED_OK - OK $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_Hide (T_ED_DATA *editor) { TRACE_FUNCTION("ATB_edit_Hide()"); if (!editor) return ED_BAD_HANDLE; /* element does not exist */ editor->display = FALSE; /* editor is not visible */ if (editor->handler) /* call event handler */ { editor->handler(ED_INVISIBLE,editor); } return ED_OK; } /******************************************************************************* $Function: ATB_edit_Unhide $Description: Unhide the editor $Returns: ED_BAD_HANDLE - Editor data pointer is null ED_OK - OK $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_Unhide (T_ED_DATA *editor) { TRACE_FUNCTION("ATB_edit_Unhide()"); if (!editor) return ED_BAD_HANDLE; /* element does not exist */ editor->display = TRUE; if (editor->handler) /* call event handler */ { editor->handler(ED_VISIBLE,editor); } return ED_OK; } /******************************************************************************* $Function: ATB_edit_MoveCursor $Description: Move the cursor $Returns: ED_ERROR - Unexpected cursor movement ED_OK - OK $Arguments: editor - The editor data character - The control character (ctrlLeft etc) update - TRUE if word wrap is to be carried out after move *******************************************************************************/ ED_RES ATB_edit_MoveCursor (T_ED_DATA *editor, USHORT control, UBYTE update) { USHORT altCursorPos; SHORT dy; ED_RES result; TRACE_FUNCTION("ATB_edit_MoveCursor"); if (!editor) return ED_BAD_HANDLE; /* element does not exist */ /* Can't move cursor in hidden mode, except to start and end */ result = ED_OK; dy = 0; switch(control) { case ctrlLeft: if (!ATB_edit_Mode(editor, ED_MODE_READONLY)) /* Not in read only mode*/ { if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) /* formatted input */ { ATB_edit_FindPrev(editor); /* find previous non-fixed character */ } else { altCursorPos = editor->cursor.pos; /* Store original cursor position */ editor->cursor.pos = ATB_string_IndexMove(&editor->attr->text, editor->cursor.pos, -1); if (editor->cursor.pos==altCursorPos) /* If we're at the start of text */ { ATB_edit_MoveCursor(editor, ctrlBottom, FALSE); /* .. then go to the end of text! */ } } } break; case ctrlRight: if (!ATB_edit_Mode(editor, ED_MODE_READONLY)) /* Not in read only mode*/ { if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) /* formatted input */ { ATB_edit_FindNext(editor); /* Move cursor forward once */ } else { altCursorPos = editor->cursor.pos; /* Store original cursor position */ editor->cursor.pos = ATB_string_IndexMove(&editor->attr->text, editor->cursor.pos, 1); if (editor->cursor.pos==altCursorPos) /* If we're at the end of text */ { ATB_edit_MoveCursor(editor, ctrlTop, FALSE); /* .. then go to the start of text! */ } } } break; case ctrlUp: if (editor->cursor.line > 0) dy = -1; break; case ctrlDown: if (editor->cursor.line < (editor->numLines-1)) dy = 1; break; case ctrlTop: editor->cursor.pos = 0; editor->initialised = FALSE; /* We need to recalculate whole editor */ /* For formatted mode, skip over any fixed characters at the start */ if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) { editor->formatIndex = 0; editor->fieldIndex = 0; ATB_edit_FindNext(editor); ATB_edit_FindPrev(editor); } break; case ctrlBottom: /* Search until we find end of text */ while (ATB_string_GetChar(&editor->attr->text, editor->cursor.pos)!=UNICODE_EOLN) { editor->cursor.pos++; } editor->initialised = FALSE; /* We need to recalculate whole editor */ break; default: TRACE_EVENT("** ERROR ** Unexpected cursor movement."); return ED_ERROR; break; } /* SPR#1983 - SH - In caps mode, any keypress switches to lower case */ if (editor->textcase==ED_CASE_CAPS) editor->textcase = ED_CASE_LOWER; if (update || dy!=0) { ATB_edit_Update(editor, dy); } return ED_OK; } /******************************************************************************* $Function: ATB_edit_DeleteLeft $Description: Delete the character to the left of the cursor SPR#2342 - SH - Added flag 'update' $Returns: ED_OK - OK $Arguments: editor - The editor data update - TRUE if word wrap is to be carried out after deletion *******************************************************************************/ ED_RES ATB_edit_DeleteLeft (T_ED_DATA *editor, UBYTE update) { ED_RES result = ED_OK; USHORT altCursorPos; char formatchar; TRACE_FUNCTION("ATB_edit_DeleteLeft"); if (!editor) return ED_BAD_HANDLE; /* element does not exist */ /* SPR#1983 - SH - Hidden text changes now mirror normal text changes. */ /* Formatted mode */ if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) /* Formatted input */ { if (ATB_edit_FindPrev(editor)!=FINDPREV_FIRST_CHAR) /* Skip over fixed characters */ { if (editor->formatIndex>0) /* So we don't look back beyond start of string */ { /* If we're in a delimited field, do normal delete, otherwise just cursor back */ formatchar = editor->attr->FormatString[editor->formatIndex-1]; if ((formatchar>'0' && formatchar<='9') || formatchar=='*') /* If it's a number between 1 and 9, or a * */ { ATB_string_MoveLeft(&editor->attr->text, editor->cursor.pos, 1); if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_string_MoveLeft(editor->hiddenText, editor->cursor.pos, 1); } //CRR:25546 - xpradipg - 26 Oct 2004 //the if block is moved out from the ATB_edit_FindPrev() if (editor->fieldIndex==0) // If we've reached the beginning of the field editor->formatIndex--; } } result = ED_OK; } else { result = ED_DONE; /* Delete with empty buffer - escape from editor */ } } /* Overwrite mode */ else if (ATB_edit_Mode(editor, ED_MODE_OVERWRITE)) { /* If we're at the end of the string, shift the '0' back */ if (editor->cursor.pos>0) { if (editor->cursor.pos == editor->attr->text.len) { result = ATB_edit_MoveCursor(editor, ctrlLeft, FALSE); ATB_string_SetChar(&editor->attr->text, editor->cursor.pos, UNICODE_EOLN); editor->attr->text.len--; if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_string_SetChar(editor->hiddenText, editor->cursor.pos, UNICODE_EOLN); editor->hiddenText->len--; } } /* Otherwise, overwrite with a space */ else { result = ATB_edit_MoveCursor(editor, ctrlLeft, FALSE); ATB_string_SetChar(&editor->attr->text, editor->cursor.pos, UNICODE_SPACE); if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_string_SetChar(editor->hiddenText, editor->cursor.pos, UNICODE_SPACE); } } } else { result = ED_DONE; /* Delete with empty buffer - escape from editor */ } } else { /* Otherwise, just perform normal delete operation */ altCursorPos = ATB_string_IndexMove(&editor->attr->text, editor->cursor.pos,-1); if (altCursorPos!=editor->cursor.pos) { ATB_string_MoveLeft(&editor->attr->text, altCursorPos, editor->cursor.pos-altCursorPos); // Delete the difference! if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_string_MoveLeft(editor->hiddenText, altCursorPos, editor->cursor.pos-altCursorPos); // Delete the difference! } editor->cursor.pos = altCursorPos; result = ED_OK; } else result = ED_DONE; } /* SPR#1983 - SH - In caps mode, any keypress switches to lower case */ if (editor->textcase==ED_CASE_CAPS) editor->textcase = ED_CASE_LOWER; // Jul 22,2004 CRR:21605 xrashmic - SASKEN // When deleting a character, if editor is empty, then set the case to // sentence case only if the user has not modified the case explicitly. if(editor->cursor.pos==0 && CaseChanged == FALSE) { editor->textcase = ED_CASE_CAPS; } if (update) { ATB_edit_Update(editor,0); } return result; } /******************************************************************************* $Function: ATB_edit_DeleteRight $Description: Delete the character to the right of the cursor SPR#2342 - SH - Added flag 'update' $Returns: ED_OK - OK $Arguments: editor - The editor data update - TRUE if word wrap is to be carried out after deletion *******************************************************************************/ ED_RES ATB_edit_DeleteRight (T_ED_DATA *editor, UBYTE update) { ED_RES result; char formatchar; TRACE_FUNCTION("ATB_edit_DeleteRight"); if (!editor) return ED_BAD_HANDLE; /* element does not exist */ /* SPR#1983 - SH - Hidden text changes now mirror normal text changes. */ /* Formatted mode */ if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) /* Formatted input */ { /* If we're in a delimited field, do normal delete right, otherwise ignore */ if (editor->formatIndex>0) { formatchar = editor->attr->FormatString[editor->formatIndex-1]; if ((formatchar>'0' && formatchar<='9') || formatchar=='*') /* If it's a number between 1 and 9, or a * */ { ATB_string_MoveLeft(&editor->attr->text, editor->cursor.pos, 1); if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_string_MoveLeft(editor->hiddenText, editor->cursor.pos, 1); } } } } /* Overwrite mode */ else if (ATB_edit_Mode(editor, ED_MODE_OVERWRITE)) { /* Make sure we're not at the end of the string */ if (editor->cursor.pos<editor->attr->text.len) { if (!ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_string_SetChar(&editor->attr->text, editor->cursor.pos, UNICODE_SPACE); } } } else { ATB_string_MoveLeft(&editor->attr->text, editor->cursor.pos, 1); /* Otherwise, just perform normal delete operation */ if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { ATB_string_MoveLeft(&editor->attr->text, editor->cursor.pos, 1); /* Otherwise, just perform normal delete operation */ } } /* SPR#1983 - SH - In caps mode, any keypress switches to lower case, if we're * not in multi-tap */ if (!editor->multitap && editor->textcase==ED_CASE_CAPS) editor->textcase = ED_CASE_LOWER; if (update) { ATB_edit_Update(editor,0); } return ED_OK; } /******************************************************************************* $Function: ATB_edit_ClearAll $Description: Clear all text from the editor, move cursor to the top $Returns: ED_BAD_HANDLE - Editor data pointer is null ED_DONE - Deleted from start of editor, exit editor ED_OK - OK $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_ClearAll (T_ED_DATA *editor) { /* SPR#2275 - SH - No longer use variable 'textlength' */ ED_RES result; TRACE_FUNCTION("ATB_edit_ClearAll()"); if (!editor) return ED_BAD_HANDLE; // element does not exist /* FORMATTED MODE */ if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) { /* Find first non-fixed character. SPR#2275 - Simplified */ ATB_edit_MoveCursor(editor, ctrlTop, FALSE); // starting from the top. } /* NORMAL MODE */ else { if (editor->attr->text.len==0) { result = ED_DONE; } else { memset(editor->attr->text.data,'\0',editor->attr->size*ATB_string_Size(&editor->attr->text)); /* Clear buffer */ editor->attr->text.len = 0; if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { memset(editor->hiddenText->data,'\0',editor->attr->size*ATB_string_Size(&editor->attr->text)); editor->hiddenText->len = 0; } ATB_edit_Reset(editor); /* Send cursor to start */ result = ED_OK; } } ATB_edit_Update(editor,0); /* Update word wrap & cursor */ return ED_OK; } /******************************************************************************* $Function: ATB_edit_Char $Description: Insert a character into the editor text, or execute a control code $Returns: ED_OK - OK $Arguments: editor - The editor data character - The character - in unicode representation update - TRUE if word wrap is to be carried out after insertion *******************************************************************************/ ED_RES ATB_edit_Char (T_ED_DATA *editor, USHORT character, UBYTE update) { TRACE_FUNCTION("ATB_edit_Char()"); if (!editor) return ED_BAD_HANDLE; // element does not exist switch (character) { /* Quit editor */ case ctrlEscape: return ED_DONE; break; /* Cursor movements*/ case ctrlLeft: case ctrlRight: case ctrlUp: case ctrlDown: case ctrlTop: case ctrlBottom: ATB_edit_MoveCursor(editor, character, update); break; /* Backspace */ case ctrlBack: ATB_edit_DeleteLeft(editor, update); /* SPR#2342 - SH */ break; /* Delete character under cursor */ case ctrlDel: ATB_edit_DeleteRight(editor, update); /* SPR#2342 - SH */ break; /* CR/LF */ case ctrlEnter: character = UNICODE_LINEFEED; /* SPR#1983 - SH - Insert into normal buffer */ if (ATB_edit_Insert(editor, &editor->attr->text, character)) { ATB_edit_MoveCursor(editor,ctrlRight,update); } break; /* Normal character */ default: /* SPR#1983 - SH - Insert into normal buffer */ if (ATB_edit_Insert(editor, &editor->attr->text, character)) { /* Character inserted OK. Move cursor to right if we're not in multitap */ if (!editor->multitap) { ATB_edit_MoveCursor(editor,ctrlRight,FALSE); } if (update) { ATB_edit_Update(editor, 0); } } break; } /* SPR#1983 - SH - In caps mode, any keypress switches to lower case */ if (!editor->multitap && editor->textcase==ED_CASE_CAPS) editor->textcase = ED_CASE_LOWER; return ED_OK; } /******************************************************************************* $Function: ATB_edit_AsciiChar $Description: Insert an ascii character into the editor text, or execute a control code $Returns: ED_OK - OK $Arguments: editor - The editor data character - The ascii character update - TRUE if word wrap is to be carried out after insertion *******************************************************************************/ ED_RES ATB_edit_AsciiChar (T_ED_DATA *editor, char character, UBYTE update) { USHORT unicodeChar; if (character<ctrlMax) unicodeChar = (USHORT)character; else unicodeChar = ATB_char_Unicode(character); return ATB_edit_Char(editor, unicodeChar, update); } /******************************************************************************* $Function: ATB_edit_Insert $Description: Insert a character into the editor text SPR#1983 - SH - Added 'text' parameter. $Returns: TRUE if character was inserted $Arguments: editor - The editor data text - The text string (normal or hidden buffer) character - The character - in unicode representation *******************************************************************************/ static int ATB_edit_Insert (T_ED_DATA *editor, T_ATB_TEXT *text, USHORT character) { int result = FALSE; TRACE_FUNCTION("ATB_edit_Insert()"); if (!ATB_edit_Mode(editor, ED_MODE_READONLY)) // Can't insert into read only mode { if (ATB_edit_Mode(editor, ED_MODE_OVERWRITE)) { if (editor->cursor.pos < (editor->attr->size-1)) /* Make sure character will fit */ { result = TRUE; /* We can write the cahracter */ /* If overwriting end of line, we need to increment length of string */ if (ATB_string_GetChar(text, editor->cursor.pos)==UNICODE_EOLN) { /* Ensure string ends with end of line character */ ATB_string_SetChar(text, editor->cursor.pos+1, UNICODE_EOLN); text->len++; } } } else /* For insert mode, check if we have space */ { result = ATB_string_MoveRight(text, editor->cursor.pos, 1, editor->attr->size); // move rest of text right to leave space } if (result) { ATB_string_SetChar(text, editor->cursor.pos, character); // Insert the character } } else { result = FALSE; } return result; } /******************************************************************************* $Function: ATB_edit_MultiTap $Description: Displays the specified character over the cursor $Returns: None. $Arguments: editor - The editor data character - The character to display multitap - TRUE if multi-tap is currently in progress *******************************************************************************/ ED_RES ATB_edit_MultiTap(T_ED_DATA *editor, USHORT character, BOOL multitap) { UBYTE oldmultitap; ED_RES result = ED_OK; TRACE_FUNCTION("ATB_edit_MultiTap()"); if (!editor) return ED_BAD_HANDLE; // element does not exist oldmultitap = editor->multitap; editor->multitap = multitap; /* If we were previously in multitap, and in insert mode, delete character under cursor. * Since this deletes current character in both visible and * hidden buffer, do this before inserting character to either buffer. */ if (oldmultitap && !multitap && !ATB_edit_Mode(editor, ED_MODE_HIDDEN)) { result = ATB_edit_MoveCursor(editor, ctrlRight, TRUE); } else { if (oldmultitap && !ATB_edit_Mode(editor, ED_MODE_OVERWRITE)) { ATB_edit_DeleteRight(editor, FALSE); /* SPR#2342 - SH */ } /* Hidden mode */ if (ATB_edit_Mode(editor, ED_MODE_HIDDEN)) /* In hidden mode... */ { ATB_edit_Insert(editor, editor->hiddenText, character); if (!multitap) /* n multi-tap, show character...*/ character = UNICODE_STAR; /* ...otherwise show star */ } result = ATB_edit_Char(editor,character,TRUE); } return result; } /******************************************************************************* $Function: ATB_edit_AsciiMultiTap $Description: Displays the specified ascii character over the cursor $Returns: None. $Arguments: editor - The editor data character - The ascii character to display multitap - TRUE if multi-tap is currently in progress *******************************************************************************/ ED_RES ATB_edit_AsciiMultiTap(T_ED_DATA *editor, char character, BOOL multitap) { USHORT unicodeChar; if (character<ctrlMax) unicodeChar = (USHORT)character; else unicodeChar = ATB_char_Unicode(character); return ATB_edit_MultiTap(editor, unicodeChar, multitap); } /******************************************************************************* $Function: ATB_edit_FindNext $Description: For formatted input, adds a character to the input buffer then finds the next non-fixed character space for the cursor to occupy $Returns: None $Arguments: editor - The editor data character - The character (or code) to insert *******************************************************************************/ static void ATB_edit_FindNext(T_ED_DATA *editor) { char *format = editor->attr->FormatString; char formatchar; UBYTE inField = ENTRY_NOT_IN_FIELD; TRACE_FUNCTION("ATB_edit_FindNext()"); // xreddymn - Included xrashmic's fix for 12470 if(editor->attr->text.len==0) { return; } /* Check for delimited field */ if (editor->formatIndex>0) { formatchar = format[editor->formatIndex-1]; if ((formatchar>'0' && formatchar<='9') || formatchar=='*') inField = ENTRY_IN_FIELD; } formatchar = format[editor->formatIndex]; if ((formatchar>'0' && formatchar<='9') || formatchar=='*') inField = ENTRY_ENTERING_FIELD; /* Check for cursor right at end of string - don't allow */ if (editor->cursor.pos>=editor->attr->text.len && editor->formatIndex>-1 && inField==ENTRY_NOT_IN_FIELD) { return; } /* Move cursor position right */ editor->cursor.pos = ATB_string_IndexMove(&editor->attr->text, editor->cursor.pos, 1); /* Check for start of fixed input field */ if (inField==ENTRY_ENTERING_FIELD) { editor->formatIndex++; // Get us into the field... editor->fieldIndex = 0; // ...and reset the field index formatchar = format[editor->formatIndex]; if (formatchar=='M') editor->textcase = ED_CASE_UPPER; if (formatchar=='m') editor->textcase = ED_CASE_LOWER; inField = ENTRY_IN_FIELD; } /* Check whether we're in a fixed input field, e.g. "4N" or "8X" */ if (inField==ENTRY_IN_FIELD) // So we don't look back beyond start of string { formatchar = format[editor->formatIndex-1]; editor->fieldIndex++; // Increment the position in the field if (editor->fieldIndex==(int)(formatchar-'0')) // If we've entered the number of characters specified (note- will never happen for the '*' !) { editor->formatIndex++; // point to NULL at end of string (no more input) } return; } /* If not, just look at next format character as usual */ editor->formatIndex++; // Point to next character while (editor->formatIndex<strlen(format) && format[editor->formatIndex]=='\\') // Fixed characters encountered { editor->cursor.pos = ATB_string_IndexMove(&editor->attr->text, editor->cursor.pos, 1); // Skip over them editor->formatIndex+=2; } if (editor->formatIndex>(strlen(format))) // Don't look beyond end of string editor->formatIndex = strlen(format); return; } /******************************************************************************* $Function: ATB_edit_FindPrev $Description: For formatted input, finds the previous non-fixed character and moves the cursor there if possible $Returns: FINDPREV_NO_CHANGE if the cursor position is not changed (nowhere to go) FINDPREV_PREV_FOUND if the previous character has been found FINDPREV_FIRST_CHAR if the cursor was over the first non-fixed character FINDPREV_LAST_CHAR if the cursor is at the last non-fixed character $Arguments: editor - The editor data *******************************************************************************/ static USHORT ATB_edit_FindPrev(T_ED_DATA *editor) { char *format = editor->attr->FormatString; char formatchar; SHORT editIndex; TRACE_FUNCTION("ATB_edit_FindPrev()"); /* Check if cursor is at start of string, return 2 */ if (editor->cursor.pos == 0) { return FINDPREV_FIRST_CHAR; } /* Check whether we're in a fixed input field, e.g. "4N" or "8X" */ if (editor->formatIndex>0) // So we don't look back beyond start of string { formatchar = format[editor->formatIndex-1]; if ((formatchar>'0' && formatchar<='9') || formatchar=='*') // If it's a number between 1 and 9, or a * { if (editor->cursor.pos > 0) editor->cursor.pos--; if (editor->cursor.pos < editor->attr->size-1) // (Don't decrement if at last char in string) editor->fieldIndex--; // Decrement the position in the field if (editor->cursor.pos==editor->attr->text.len-1) // Special case if last character - tell editor to shorten the string return FINDPREV_LAST_CHAR; return FINDPREV_PREV_FOUND; // then we're done } } /* If not (or if we've just come out of one) just look at next format character as usual */ editIndex = editor->formatIndex-1; // Make copy of format position, starting off to left while (editIndex>0) { if (format[editIndex-1]=='\\') // If there's a fixed char editIndex -=2; // Look back a further 2 characters else // If there's a non-fixed character break; // then exit loop } if (editIndex==-1) // Go back from 1st character in editor { return FINDPREV_FIRST_CHAR; } formatchar = format[editIndex-1]; if ((formatchar>'0' && formatchar<='9') || formatchar=='*') editor->fieldIndex--; if (editIndex>-1) // Provided there is somewhere to go.... { while(editor->formatIndex>editIndex) { if (editor->cursor.pos > 0) { editor->cursor.pos--; // move cursor there editor->formatIndex--; } if (format[editor->formatIndex]=='\\') editor->formatIndex--; } return FINDPREV_PREV_FOUND; // Found new position } return FINDPREV_NO_CHANGE; // Position unchanged } /******************************************************************************* $Function: ATB_edit_GetCasePref $Description: Returns the preferred case for the current position in the editor $Returns: ED_CASEPREF_NUM - Any numeric character ED_CASEPREF_ALPHA_UC - Any symbolic or alphabetic uppercase character ED_CASEPREF_ALPHA_LC - Any symbolic or alphabetic lowercase character ED_CASEPREF_ALPHANUM - Any symbolic, numeric, or alphabetic character ED_CASEPREF_ALPHANUM_UC - Any symbolic, numeric, or alphabetic uppercase character ED_CASEPREF_ALPHANUM_LC - Any symbolic, numeric, or alphabetic lowercase character $Arguments: editor - The editor data *******************************************************************************/ T_ED_CASE_PREF ATB_edit_GetCasePref(T_ED_DATA *editor) { T_ED_CASE_PREF casePref; char formatchar; char *format; /* FORMATTED MODE */ if (ATB_edit_Mode(editor, ED_MODE_FORMATTED)) { format = editor->attr->FormatString; formatchar = format[editor->formatIndex]; if ((formatchar>'0' && formatchar<='9') || formatchar=='*') // Delimiter for format field { editor->formatIndex++; editor->fieldIndex = 0; formatchar = format[editor->formatIndex]; // Next character is the format for the field } switch(formatchar) { case 'X': /* Uppercase alphanumeric */ casePref = ED_CASEPREF_ALPHANUM_UC; break; case 'x': casePref = ED_CASEPREF_ALPHANUM_LC; /* Lowercase alphanumeric */ break; case 'A': /* Uppercase alphabetic */ casePref = ED_CASEPREF_ALPHA_UC; break; case 'a': /* Lowercase alphabetic */ casePref = ED_CASEPREF_ALPHA_LC; break; case 'M': casePref = ED_CASEPREF_ALPHANUM; break; case 'm': casePref = ED_CASEPREF_ALPHANUM; break; case 'N': casePref = ED_CASEPREF_NUM; break; default: casePref = ED_CASEPREF_NONE; break; } } /* NORMAL MODE */ else { casePref = ED_CASEPREF_NUM; /* SPR#2342 - SH - Default to numeric mode */ if (ATB_edit_Mode(editor, ED_MODE_ALPHA) && ATB_edit_GetCase(editor)!=ED_CASE_NUM) { casePref = ED_CASEPREF_ALPHANUM; } } return casePref; } /******************************************************************************* $Function: ATB_edit_OutTextLines $Description: Draw the visible lines of text onto the screen $Returns: None $Arguments: editor - The editor data *******************************************************************************/ static void ATB_edit_OutTextLines (T_ED_DATA *editor) { USHORT editX = editor->attr->win_size.px; /* X position in editor */ USHORT editY = editor->attr->win_size.py; /* Y position in editor */ USHORT editWidth = editor->attr->win_size.sx; /* Height of the editor */ USHORT editHeight = editor->attr->win_size.sy; /* Height of the editor */ USHORT lineNo; USHORT heightOnScreen; /* Height of lines shown so far */ USHORT offsetX; /* X offset of line */ T_DS_TEXTFORMAT tempFormat; /* Temporary storage for format attributes */ T_ED_LINE *line; /* Current line attributes */ T_ATB_TEXT currentLine; /* Current line */ // Shashi Shekar B.S., a0876501, Jan 16, 2006, DR: OMAPS00061460 #ifdef FF_MMI_SAT_ICON USHORT titleIconWidth = 0; USHORT iconX, iconY; USHORT titleHeight = 0; #endif TRACE_FUNCTION("ATB_edit_OutTextLines()"); if (editor == NULL) return; // Shashi Shekar B.S., a0876501, Jan 16, 2006, DR: OMAPS00061460 #ifdef FF_MMI_SAT_ICON if (editor->attr->TitleIcon.data != NULL && !editor->attr->TitleIcon.isTitle) { if (editor->attr->TitleIcon.width > TITLE_ICON_WIDTH) { titleIconWidth = TITLE_ICON_WIDTH; } else { titleIconWidth = editor->attr->TitleIcon.width; } } else { titleIconWidth = 0; } if(titleIconWidth) editX = editX + titleIconWidth + 1; #endif heightOnScreen = 0; line = ATB_edit_LineGet(editor, editor->winStartLine); // Shashi Shekar B.S., a0876501, Jan 16, 2006, DR: OMAPS00061460 #ifdef FF_MMI_SAT_ICON if(line != NULL) titleHeight = line->height; #endif for (lineNo = editor->winStartLine; lineNo < editor->numLines && heightOnScreen<=editHeight; lineNo++) { heightOnScreen += line->height; /* Add this height to the total height so far... */ if (editor->display && heightOnScreen <= editHeight) /* and make sure this fits onto the screen */ { currentLine.len = line->next->pos - line->pos; /* End of line is the first character of the next line */ currentLine.dcs = editor->attr->text.dcs; currentLine.data = &editor->attr->text.data[line->pos*ATB_string_Size(¤tLine)]; offsetX = 0; if (line->format.attr & DS_ALIGN_RIGHT) { offsetX = editWidth-ATB_display_StringWidth(¤tLine, &line->format); } else if (line->format.attr & DS_ALIGN_CENTRE) { offsetX = (editWidth-ATB_display_StringWidth(¤tLine, &line->format))/2; } ATB_display_CopyFormat(&tempFormat, &line->format); /* So format of lines doesn't change */ ATB_display_Text(offsetX+editX, editY, &tempFormat, ¤tLine); } editY += line->height; /* Move down by line height, ready for the next one */ line = line->next; /* Get next line */ } //Sudha.V., x0035544, Feb 02, 2006, DR: OMAPS00061468 // Shashi Shekar B.S., a0876501, Jan 16, 2006, DR: OMAPS00061460 #ifdef FF_MMI_SAT_ICON if(editor->attr->TitleIcon.data != NULL && !editor->attr->TitleIcon.isTitle) { switch(editor->attr->TitleIcon.display_type) { case SAT_ICON_NONE: break; case SAT_ICON_IDLEMODE_TEXT: if ((editor->attr->TitleIcon.width > TITLE_ICON_WIDTH) || (editor-> attr->TitleIcon.height > TITLE_ICON_HEIGHT)) { iconX = editX+offsetX - editor->attr->TitleIcon.width-2; iconY = editor->attr->win_size.py+ ((titleHeight-2)/2); dspl_BitBlt2(iconX, iconY, 8, 10, (void*)SATIconQuestionMark, 0, BMP_FORMAT_256_COLOUR); } else { iconX = editX+offsetX - editor->attr->TitleIcon.width-2; iconY = editor->attr->win_size.py + ((titleHeight-2)/2) - ( editor->attr->TitleIcon.height / 2); dspl_BitBlt2(iconX, iconY, editor->attr->TitleIcon.width, editor->attr->TitleIcon.height, (void*)editor->attr->TitleIcon. data, 0, BMP_FORMAT_256_COLOUR); } break; case SAT_ICON_DISPLAY_TEXT: if ((editor->attr->TitleIcon.width > TITLE_ICON_WIDTH) || (editor-> attr->TitleIcon.height > TITLE_ICON_HEIGHT)) { iconX = 1; iconY = 1+ ((titleHeight-2) / 2) - (10 / 2); dspl_BitBlt2(iconX, iconY, 8, 10, (void*)SATIconQuestionMark, 0, BMP_FORMAT_256_COLOUR); } else { iconX = 1; iconY = 1+ ((titleHeight-2) / 2) - (editor->attr->TitleIcon. height / 2); dspl_BitBlt2(iconX, iconY, editor->attr->TitleIcon.width, editor->attr->TitleIcon.height, (void*)editor->attr->TitleIcon.data, 0 , BMP_FORMAT_256_COLOUR); } break; } } #endif return; } /******************************************************************************* $Function: ATB_edit_Update $Description: Update editor (without displaying), moving cursor up or down by 'dy' lines. This function goes through the text, word-wraps it with the help of ATB_edit_WordWrap, and works out the start position of text on-screen and the X and Y pixel positions of the cursor (with the help of ATB_edit_UpdateCursorPos). The character position of the start of each line within the string is stored, so that ATB_edit_OutTextLines can quickly display the editor contents without further calculation. $Returns: ED_BAD_HANDLE - Editor data pointer is null ED_OK - OK $Arguments: editor - The editor data dy - number of lines (+ or -) that the cursor must scroll up or down. *******************************************************************************/ static ED_RES ATB_edit_Update (T_ED_DATA *editor, int dy) { USHORT cursorCharPos; /* New cursor character position */ USHORT linePos; /* Char pos in string of current line. */ USHORT lineNo; /* Line being considered */ USHORT editComplete; /* Flag indicating cursor position found/updated or end of line reached. */ USHORT character; /* Current unicode char. */ T_ED_LINE *line; /* Pointer to current entry in line chain */ USHORT cursorColumn; /* Column cursor is in - always multiple of 8 pixels */ SHORT charMaxWidth; TRACE_FUNCTION("ATB_edit_Update()"); /* Make sure the editor exists and has text in it */ if (!editor) return ED_BAD_HANDLE; /* For non read-only modes, or on first process, perform word wrap */ if (!ATB_edit_Mode(editor, ED_MODE_READONLY) || editor->initialised==FALSE) { editor->viewStartPos = 0; editor->viewHeight = 0; editor->totalHeight = 0; editor->startOfLine = TRUE; /* We're at the start of a line */ editor->endOfText = FALSE; editor->precedingEOL = FALSE; /* Used to detect if preceding character was CR/LF */ editor->thischar.lineWidth = 0; /* Width of current line */ editor->cursor.line = 0; /* Line that the cursor is on */ editor->space.pos = 0; /* Possible position for soft linebreak - none as yet */ /* Set up data if this is the first time... */ if (!editor->initialised) { editor->thischar.pos = 0; editor->numLines = 0; /* total number of lines in editor, start at 0 */ line = ATB_edit_LineGet(editor, 0); line->pos = 0; /* first line starts at start of buffer */ line->height = 0; /* Height of first line */ ATB_display_CopyFormat(&line->format, &editor->attr->startFormat); /* Start with this text formatting */ ATB_display_CopyFormat(&editor->thischar.format, &editor->attr->startFormat); // Start with this text formatting editor->winStartLine = 0; /* First line to be displayed in window */ editor->initialised = TRUE; } /* Set up data if this is NOT the first time */ else { /* We only need to word wrap text that might have been changed by user text entry. * The user can affect the previous line (by inserting a space or deleting, so the word is * wrapped to a previous line) and all subsequent lines. Therefore if we start word wrapping * on the line previous to where the cursor is, we can encompass all changes. */ line = ATB_edit_LineGet(editor, 0); for (lineNo = 0; lineNo<editor->numLines && editor->cursor.pos>=line->pos; lineNo++) { line = line->next; } if (lineNo>0) lineNo--; if (lineNo>0) lineNo--; line = ATB_edit_LineGet(editor, lineNo); editor->thischar.pos = line->pos; /* Start looking at this line */ editor->numLines = lineNo; /* This no. of lines so far */ ATB_display_CopyFormat(&editor->thischar.format, &line->format); /* Start with this text formatting */ line->height = 0; /* Height of first line */ } /* Set up some values */ cursorCharPos = editor->cursor.pos; /* Cursor position in the string */ linePos = 0; // Position on the current line /* Word wrap the text into separate lines, storing the start position and height of each. * Also, find the cursor and work out its X position. */ while(!editor->endOfText) // Go through from first character to last character { ATB_edit_WordWrap(editor); // What is the character? What's its width? if (editor->endOfLine) // Newline, or current char will not fit on previous line. { editor->numLines++; // We've got another line editor->startOfLine = TRUE; // New line is starting } if (editor->startOfLine) { line = ATB_edit_LineGet(editor, editor->numLines); line->pos = editor->startPos; line->height = editor->thischar.height; // Height of line set to that of first character ATB_display_CopyFormat(&line->format,&editor->thischar.format); /* Formatting at start of line to that of 1st character */ editor->thischar.lineWidth = 0; line = ATB_edit_LineGet(editor, editor->winStartLine); if (editor->startPos <= line->pos) /* Is this the first line to be displayed in the editor? */ { editor->winStartLine = editor->numLines; /* If so, set this line to the start window line */ } editor->startOfLine = FALSE; } if (editor->endOfText) /* If it's a unicode terminator... */ { if (cursorCharPos > editor->thischar.pos) /* Cursor is past end of text - move to char before end of line. */ cursorCharPos = editor->thischar.pos; } if (editor->startPos == cursorCharPos) // We've found the cursor { editor->cursor.line = editor->numLines; // Store the line it's on editor->cursor.width = editor->thischar.width; // Set the width of the cursor editor->cursor.x = editor->thischar.lineWidth; // And its position editor->cursor.attr = editor->thischar.format.attr; // Save the format attribute } editor->thischar.lineWidth += editor->thischar.width; editor->thischar.pos++; } // End while editor->numLines++; // Number of lines is one more than the last line line = ATB_edit_LineGet(editor, editor->numLines); line->pos = editor->thischar.pos; // End of last line ATB_edit_UpdateCursorPos(editor); // Update, but if dy!=0 we may have to change this } /* We now have the start position of each line and its height stored in an array. * We also have the cursor's current X position on its line (but its line may be offscreen) */ if (dy) // If we're sending the cursor up/down some lines... { editor->cursor.line = editor->cursor.line+dy; // Change cursor line if (editor->cursor.line >= editor->numLines ) // Make sure line cursor is on doesn't go beyond... editor->cursor.line = editor->numLines-1; // ...last line of editor... if (editor->cursor.line < 0) // ...or above... editor->cursor.line = 0; // ...first line of editor /* In read-only mode, stop scrolling down when the bottom line of the text * is visible at the bottom of the window */ if (ATB_edit_Mode(editor,ED_MODE_READONLY)) { if (editor->numLines>=editor->linesPerScreen && editor->cursor.line >= (editor->numLines - editor->linesPerScreen)) { editor->cursor.line = (editor->numLines - editor->linesPerScreen); } editor->winStartLine = editor->cursor.line; } } /* Reset all our horizontal variables */ editor->thischar.pos = 0; editor->thischar.lineWidth = 0; editComplete = TRUE; editor->endOfText = FALSE; editor->space.pos = 0; /* Work out how many lines fit on the current screen */ ATB_edit_UpdateCursorPos(editor); lineNo = 0; /* Update the line where we start showing the text on the window */ if (editor->cursor.line < editor->winStartLine) //cursor is on a line before current window screen { editor->winStartLine = editor->cursor.line; editComplete = FALSE; } else if (editor->cursor.line >= (editor->winStartLine+editor->linesPerScreen)) //cursor is below the bottom of the screen { editor->winStartLine = editor->cursor.line-(editor->linesPerScreen-1); editComplete = FALSE; } if (dy!= 0) /* If we're moving up or down */ { editComplete = FALSE; } if (!editComplete) /* Calculate new cursor X and Y positions */ { if (dy!=0) /* If we've changed line, find new X position */ { line = ATB_edit_LineGet(editor, editor->cursor.line); editor->thischar.lineWidth = 0; linePos = line->pos; // Start of current line ATB_display_CopyFormat(&editor->thischar.format, &line->format); // Format attributes of 1st character /* Get column - is always a multiple of the maximum character width. Makes sure cursor doesn't wander * left or right too much when moving up or down by lines */ charMaxWidth = (SHORT)ATB_display_GetMaxCharWidth(&editor->thischar.format); cursorColumn = editor->cursor.x - (editor->cursor.x % charMaxWidth); linePos--; editor->thischar.width = 0; /* SPR#2342 - SH - Improved finding cursor position on adjacent lines. * First search until we're in the column or at the end of the line */ do { linePos++; editor->thischar.lineWidth += editor->thischar.width; character = ATB_string_GetChar(&editor->attr->text, linePos); editor->thischar.width = ATB_display_GetCharWidth(character, &editor->thischar.format); } while (editor->thischar.lineWidth<cursorColumn && linePos < (line->next->pos-1)); /* Is there a character also in the column, but closer to our original character? */ while ((editor->thischar.lineWidth+editor->thischar.width) < (cursorColumn+charMaxWidth) && linePos< (line->next->pos-1) && (editor->cursor.x - editor->thischar.lineWidth)> editor->thischar.width) { linePos++; editor->thischar.lineWidth += editor->thischar.width; character = ATB_string_GetChar(&editor->attr->text, linePos); editor->thischar.width = ATB_display_GetCharWidth(character, &editor->thischar.format); } /* Set the new cursor X position */ cursorCharPos = linePos; // New cursor position in buffer editor->cursor.width = editor->thischar.width; // Set the width of the cursor editor->cursor.x = editor->thischar.lineWidth; // And its position editor->cursor.attr = editor->thischar.format.attr; // Save the format attribute } ATB_edit_UpdateCursorPos(editor); } /* Change cursor position */ editor->cursor.pos = cursorCharPos; return ED_OK; } /******************************************************************************* $Function: ATB_edit_WordWrap $Description: Main word wrap function. Takes in the characters of the string one by one, calculating the total width displayed on screen and setting flags when a string should be wrapped, a carriage return is encountered, the end of string has been reached. Tracks the last space character and goes back there when a word runs over the edge of the screen. Also works out the height of the current line, based on the maximum character height found. $Returns: None $Arguments: editor - The editor data *******************************************************************************/ static void ATB_edit_WordWrap(T_ED_DATA *editor) { USHORT character; char asciiChar; int punctuation; T_ED_LINE *line; #ifdef TRACE_ATBEDITOR TRACE_FUNCTION("ATB_edit_WordWrap()"); #endif editor->endOfLine = FALSE; line = ATB_edit_LineGet(editor, editor->numLines); /* Get the character from the buffer */ editor->startPos = editor->thischar.pos; character = ATB_string_GetChar(&editor->attr->text, editor->thischar.pos); /* Find the character's dimensions */ /* If we're multi-tapping a character, or in fixed-width mode, it has the maximum width */ if (editor->multitap && editor->thischar.pos==editor->cursor.pos) editor->thischar.width = ATB_display_GetCharWidth(UNICODE_WIDEST_CHAR, &editor->thischar.format); else editor->thischar.width = ATB_display_GetCharWidth(character, &editor->thischar.format); // Character width editor->thischar.height = ATB_display_GetCharHeight(character, &editor->thischar.format); /* Check to see if last character was a CR/LF */ if (editor->precedingEOL) { editor->endOfLine = TRUE; editor->precedingEOL = FALSE; } else // otherwise, character included on line { if (editor->thischar.height > line->height) // if height>height so far... line->height = editor->thischar.height; // ...adjust the height so far } /* Set flags appropriate for the character */ switch(character) { case UNICODE_EOLN: editor->endOfText = TRUE; // We're at the end of the editor text break; case UNICODE_LINEFEED: case UNICODE_CR: editor->precedingEOL = TRUE; // This is an end of line break; default: break; } /* Check if wrapping required */ if ( (editor->thischar.lineWidth+editor->thischar.width)>editor->attr->win_size.sx ) // Current character will go off edge of editor { editor->endOfLine = TRUE; // If we've found a space, and it's a word wrapping mode */ if (editor->space.pos > 0 && editor->precedingSpace==FALSE && !ATB_edit_Mode(editor, ED_MODE_OVERWRITE)) { editor->thischar.pos = editor->space.pos; // reset character position back to here editor->startPos = editor->space.pos; // character is space, so start of block=character pos editor->thischar.width = editor->space.width; editor->thischar.height = editor->space.height; ATB_display_CopyFormat(&editor->thischar.format,&editor->space.format); line->height = editor->space.lineHeight; editor->endOfText = FALSE; // If we're wrapping on an EOLN, we've gone back } editor->space.pos = 0; // Reset space position to start of line editor->precedingSpace = FALSE; } else { if (editor->precedingSpace) // Remember enough info so that this point can be restored { editor->space.pos = editor->startPos; // Store position of start of current block, or just character pos. editor->space.width = editor->thischar.width; editor->space.height = editor->thischar.height; ATB_display_CopyFormat(&editor->space.format,&editor->thischar.format); editor->space.lineHeight = line->height; editor->precedingSpace = FALSE; } punctuation = FALSE; if (character==UNICODE_SPACE) // Wrap only on spaces { punctuation = TRUE; } if ((punctuation) && (editor->thischar.lineWidth > 0)) //A space is a good point for a soft break { editor->precedingSpace = TRUE; } } return; } /******************************************************************************* $Function: ATB_edit_UpdateCursorPos $Description: Update the cursor's vertical position, based on its position within the string. $Returns: None $Arguments: editor - The editor data *******************************************************************************/ static void ATB_edit_UpdateCursorPos(T_ED_DATA *editor) { USHORT lineNo; USHORT lineHeight; USHORT editHeight = editor->attr->win_size.sy; T_ED_LINE *line; #ifdef TRACE_ATBEDITOR TRACE_FUNCTION("ATB_edit_UpdateCursorPos()"); #endif editor->cursor.y = 0; // Recalculate cursor Y position... editor->viewHeight = 0; // ...and height of viewable screen... editor->totalHeight = 0; // ...and total height of screen... editor->viewStartPos = 0; // ...and the start pixel position of the view... editor->linesPerScreen = 0; // ...and number of lines to the screen lineNo = 0; while (lineNo<editor->numLines) { line = ATB_edit_LineGet(editor, lineNo); lineHeight = line->height; if (lineNo==editor->cursor.line) editor->cursor.y = editor->viewHeight; // Y position of cursor if (lineNo==editor->winStartLine) // starting posn rel to start of editor text editor->viewStartPos = editor->totalHeight; if (lineNo>=editor->winStartLine && (editor->viewHeight+lineHeight)<=editHeight) { editor->viewHeight += lineHeight; editor->linesPerScreen++; } editor->totalHeight += lineHeight; lineNo++; } line = ATB_edit_LineGet(editor, editor->cursor.line); editor->cursor.height = line->height; // Change its height return; } /************************************/ /* GLOBAL PROCEDURES */ /* Add/removing words in the editor */ /************************************/ /******************************************************************************* $Function: ATB_edit_InsertString $Description: Insert a string at the cursor. $Returns: ED_BAD_HANDLE - Editor data pointer is null ED_OK - OK $Arguments: editor - The editor data insText - The text to insert *******************************************************************************/ ED_RES ATB_edit_InsertString (T_ED_DATA *editor, T_ATB_TEXT *insText) { T_ATB_TEXT *text; int textIndex; USHORT character; TRACE_FUNCTION("ATB_edit_InsertString()"); if (!editor) // Make sure editor exists return ED_BAD_HANDLE; if (insText==NULL || insText->len==0) return ED_OK; /* No string to insert - trivial operation. */ if (ATB_edit_Mode(editor, ED_MODE_READONLY) ) /* Don't insert in read-only mode*/ return ED_ERROR; text = &editor->attr->text; if ((text->len+insText->len) >= editor->attr->size) return ED_ERROR; /* String too long */ /* Move text up by the length of insText */ ATB_string_MoveRight(text, editor->cursor.pos, insText->len, editor->attr->size); /* Copy string into buffer */ for (textIndex=0; textIndex<insText->len; textIndex++) { character = ATB_string_GetChar(insText, textIndex); ATB_string_SetChar(text, editor->cursor.pos+textIndex, character); } editor->cursor.pos = editor->cursor.pos+insText->len; /* Reformat updated text */ ATB_edit_Update(editor, 0); return ED_OK; } /******************************************************************************* $Function: ATB_edit_GetCursorChar $Description: Return the character at a position offset from the current cursor position by the value supplied. $Returns: The character, or UNICODE_EOLN if goes beyond bounds of string. $Arguments: editor - The editor data offset - The offset from the current cursor position from which to get the character *******************************************************************************/ USHORT ATB_edit_GetCursorChar(T_ED_DATA *editor, int offset) { USHORT textIndex; USHORT character; TRACE_FUNCTION("ATB_edit_GetCursorChar"); textIndex = editor->cursor.pos+offset; if (textIndex<0 || textIndex > editor->attr->text.len) character = UNICODE_EOLN; else character = ATB_string_GetChar(&editor->attr->text, textIndex); return character; } /******************************************************************************* $Function: ATB_edit_CapitaliseWord $Description: Returns TRUE if next word after cursor ought to be capitalised $Returns: None. $Arguments: editor - The editor data *******************************************************************************/ BOOL ATB_edit_CapitaliseWord(T_ED_DATA *editor) { USHORT LastChar; USHORT CharBefore; /* First check to see if first word is to be capitalised */ if (editor->textcase==ED_CASE_CAPS) return TRUE; /* If not, look at preceding characters */ LastChar = ATB_edit_GetCursorChar(editor, -1); CharBefore = ATB_edit_GetCursorChar(editor, -2); if (LastChar==UNICODE_FULLSTOP || LastChar==UNICODE_EXCLAMATION || LastChar==UNICODE_QUESTION || LastChar==UNICODE_EOLN) return TRUE; if (LastChar==UNICODE_SPACE) if(CharBefore==UNICODE_FULLSTOP || CharBefore==UNICODE_EXCLAMATION || CharBefore==UNICODE_QUESTION) return TRUE; return FALSE; } /******************************************************************************* $Function: ATB_edit_FindCapital $Description: returns the code of the input char converted to a capital. If char has no upper case equivalent returns original char. Added for issue 1508 $Returns: UBYTE $Arguments: char *******************************************************************************/ USHORT ATB_edit_FindCapital(USHORT small_char) { char ascii_code= ATB_char_Ascii(small_char); /*if "normal" character*/ if (ascii_code>96 && ascii_code< 123) return (ATB_char_Unicode(ascii_code - 0x20)); switch (ascii_code) { case (130): return ATB_char_Unicode(154);break;/*U with umlaut*/ case (132): return ATB_char_Unicode(142);break;/*A with umlaut*/ case (148): return ATB_char_Unicode(153);break;/*O with umlaut*/ default: return ATB_char_Unicode(ascii_code); } } /******************************************************************************* $Function: ATB_edit_HiddenInit $Description: Initialize editor for hidden mode. $Returns: None. $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_HiddenInit(T_ED_DATA *editor) { USHORT len = editor->attr->text.len; TRACE_FUNCTION("ATB_edit_HiddenInit()"); if (!editor) return ED_BAD_HANDLE; // element does not exist if (editor->hiddenText) return ED_ERROR; /* get memory for the temporary buffer */ editor->hiddenText = (T_ATB_TEXT *) ATB_mem_Alloc(sizeof(T_ATB_TEXT)); editor->hiddenText->len = 0; editor->hiddenText->data = (UBYTE *)ATB_mem_Alloc(editor->attr->size*ATB_string_Size(&editor->attr->text)); /* copy text to the temporary buffer */ ATB_string_Copy(editor->hiddenText, &editor->attr->text); /* overwrite the string in the editor buffer with stars */ memset(editor->attr->text.data,'\0',editor->attr->size*ATB_string_Size(&editor->attr->text)); /* Clear buffer */ editor->attr->text.len = 0; ATB_edit_Reset(editor); /* Send cursor to start */ while (editor->attr->text.len < len) ATB_edit_AsciiChar(editor,'*',FALSE); return ED_OK; } /******************************************************************************* $Function: ATB_edit_HiddenExit $Description: Deinitialize editor for hidden mode. $Returns: None. $Arguments: editor - The editor data *******************************************************************************/ ED_RES ATB_edit_HiddenExit(T_ED_DATA *editor) { TRACE_FUNCTION("ATB_edit_HiddenExit()"); if (!editor) return ED_BAD_HANDLE; // element does not exist if (!editor->hiddenText) return ED_ERROR; /* For hidden mode, copy the hidden text into the buffer & free memory */ ATB_string_Copy(&editor->attr->text, editor->hiddenText); ATB_mem_Free ((void *)editor->hiddenText->data, editor->attr->size*ATB_string_Size(editor->hiddenText)); ATB_mem_Free ((void *)editor->hiddenText, sizeof(T_ATB_TEXT)); editor->hiddenText = NULL; return; } /******************************************************************************* $Function: ATB_edit_Mode $Description: Returns TRUE if the appropriate bits are set in the editor mode $Returns: None. $Arguments: editor - The editor data mode - The mode bits to check *******************************************************************************/ void ATB_edit_SetAttr(T_ED_DATA *editor, T_ATB_WIN_SIZE *win_size, ULONG colour, UBYTE font, USHORT mode, USHORT cursor, T_ATB_TEXT *text, USHORT size) { memcpy(&editor->attr->win_size, win_size, sizeof(T_ATB_WIN_SIZE)); editor->attr->colour = colour; editor->attr->font = font; editor->attr->cursor = cursor; editor->attr->mode = mode; memcpy(&editor->attr->text, text, sizeof(T_ATB_TEXT)); editor->attr->size = size; return; } /******************************************************************************* $Function: ATB_edit_Mode $Description: Returns TRUE if the appropriate bits are set in the editor mode $Returns: None. $Arguments: editor - The editor data mode - The mode bits to check *******************************************************************************/ UBYTE ATB_edit_Mode(T_ED_DATA *editor, USHORT mode) { UBYTE result; if (editor->attr->mode & mode) result = TRUE; else result = FALSE; return result; } /******************************************************************************* $Function: ATB_edit_SetMode $Description: Sets the appropriate bits in the editor mode $Returns: None. $Arguments: editor - The editor data mode - The mode bits to set *******************************************************************************/ void ATB_edit_SetMode(T_ED_DATA *editor, USHORT mode) { editor->attr->mode |= mode; return; } /******************************************************************************* $Function: ATB_edit_ResetMode $Description: Resets the appropriate bits in the editor mode $Returns: None. $Arguments: editor - The editor data mode - The mode bits to reset *******************************************************************************/ void ATB_edit_ResetMode(T_ED_DATA *editor, USHORT mode) { editor->attr->mode &= (~mode); return; } /******************************************************************************* $Function: ATB_edit_SetStyle $Description: Sets the appropriate bits in the editor style $Returns: None. $Arguments: editor - The editor data format - The format bits to set *******************************************************************************/ void ATB_edit_SetStyle(T_ED_DATA *editor, USHORT style) { UBYTE mask; mask = 0; switch(style) { case DS_ALIGN_LEFT: case DS_ALIGN_RIGHT: case DS_ALIGN_CENTRE: mask = DS_ALIGN_RIGHT | DS_ALIGN_CENTRE; break; } /* Switch off previous format */ editor->attr->startFormat.attr &= (~mask); /* Switch on new format */ editor->attr->startFormat.attr |= style; return; } /******************************************************************************* $Function: ATB_edit_ResetFormat $Description: Resets the appropriate bits in the editor format $Returns: None. $Arguments: editor - The editor data format - The format bits to reset *******************************************************************************/ void ATB_edit_ResetFormat(T_ED_DATA *editor, USHORT format) { editor->attr->startFormat.attr &= (~format); return; } /******************************************************************************* $Function: ATB_edit_GetCase $Description: Returns the currently selected text case $Returns: ED_CASE_UPPER ED_CASE_LOWER ED_CASE_CAPS ED_CASE_NUM ED_CASE_NONE $Arguments: editor - The editor data *******************************************************************************/ UBYTE ATB_edit_GetCase(T_ED_DATA *editor) { return (UBYTE)editor->textcase; } /******************************************************************************* $Function: ATB_edit_SetCase $Description: Changes the currently selected text case $Returns: None $Arguments: editor - The editor data textcase - Case to select. One of: ED_CASE_UPPER ED_CASE_LOWER ED_CASE_CAPS ED_CASE_NUM ED_CASE_NONE *******************************************************************************/ void ATB_edit_SetCase(T_ED_DATA *editor, UBYTE textcase) { editor->textcase = textcase; return; } /******************************************************************************* $Function: ATB_edit_LineGet $Description: Get the pointer to the requested line in the linked list $Returns: The required line structure $Arguments: editor - The text editor lineNo - The line required *******************************************************************************/ T_ED_LINE *ATB_edit_LineGet(T_ED_DATA *editor, SHORT lineNo) { T_ED_LINE *line = editor->line; SHORT thisLineNo; thisLineNo = 0; if (lineNo<0) lineNo = 0; /* If the first line doesn't exist... */ if (line==NULL) { editor->line = (T_ED_LINE *)ATB_mem_Alloc(sizeof(T_ED_LINE)); memset(editor->line, 0, sizeof(T_ED_LINE)); editor->line->next = NULL; line = editor->line; } /* Search for the line required */ while (thisLineNo<lineNo) { if (line->next==NULL) { line->next = (T_ED_LINE *)ATB_mem_Alloc(sizeof(T_ED_LINE)); memset(line->next, 0, sizeof(T_ED_LINE)); line->next->next = NULL; } line = line->next; lineNo--; } return line; } /******************************************************************************* $Function: ATB_edit_LineDestroyAll $Description: Destroy all entries in the line linked list $Returns: None $Arguments: editor - The text editor *******************************************************************************/ static void ATB_edit_LineDestroyAll(T_ED_DATA *editor) { T_ED_LINE *line = editor->line; T_ED_LINE *newLine; SHORT lineNo; while (line!=NULL) { newLine = line->next; ATB_mem_Free((void *)line, sizeof(T_ED_LINE)); line = newLine; } return; } #endif