From e36770dc7c929f48f18d727260461d1efa985351 Mon Sep 17 00:00:00 2001 From: Kevin Bracey <kbracey@gitlab.riscosopen.org> Date: Fri, 1 Aug 1997 09:00:59 +0000 Subject: [PATCH] Made INPUT type=image work --- c/Browser | 16 +++-- c/Fetch | 25 +++---- c/FontManage | 40 +++++------ c/Forms | 189 ++++++++++++++++++++++++++++----------------------- c/Handlers | 67 ++++++++++++------ c/Images | 4 +- c/Redraw | 66 ++++++++++-------- c/Reformat | 92 ++++++++++++++++--------- h/Browser | 14 ++-- h/FontManage | 4 +- h/Forms | 4 +- h/Reformat | 2 +- 12 files changed, 302 insertions(+), 221 deletions(-) diff --git a/c/Browser b/c/Browser index 4e3b9d1..0c55ac3 100644 --- a/c/Browser +++ b/c/Browser @@ -1249,7 +1249,8 @@ int browser_move_selection(browser_data * b, int key) ) form_click_field(owner, new, - key == akbd_RightK ? 1 : 2); + key == akbd_RightK ? 1 : 2, + 0, 0); /* Turn the pointer off, and reset the check to see if */ /* the user has moved it manually. */ @@ -1303,7 +1304,9 @@ static int browser_navigate_map(browser_data * b, int key) { tp = browser_get_pointer_token(b, &p, NULL, NULL); - if (tp && redraw_selected(b, tp) && (tp->style & IMG) && (tp->type & TYPE_ISMAP)) + if (tp && redraw_selected(b, tp) && + (((tp->style & IMG) && (tp->type & TYPE_ISMAP)) || + ((tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_IMAGE))) { int last_move = 4; int last_key, start_key; @@ -1676,7 +1679,9 @@ int browser_pointer_check(int eventcode, WimpPollBlock * b, IdBlock * idb, brows if ((tp->style & IMG) && (tp->type & TYPE_ISMAP)) mouse_set_pointer_shape(Mouse_Shape_Map); else mouse_set_pointer_shape(Mouse_Shape_Link); } - else mouse_set_pointer_shape(Mouse_Shape_Normal); + else if ((tp->style & INPUT) && + HtmlINPUTtype(tp) == inputtype_IMAGE) mouse_set_pointer_shape(Mouse_Shape_Link); + else mouse_set_pointer_shape(Mouse_Shape_Normal); } /* If the mouse pointer is on, then update the status bar */ @@ -2010,13 +2015,14 @@ static HStream * browser_get_pointer_token_r(browser_data * b, reformat_cell * c /* If the token represents an image... */ - else if (tp->style & IMG) + else if ((tp->style & IMG) || + ((tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_IMAGE)) { reformat_get_image_size(b, tp, &box); /* Correct for the border size, if the image is a link */ - if (ISLINK(tp)) + if (ISLINK(tp) && (tp->style & IMG)) { int b; diff --git a/c/Fetch b/c/Fetch index e272940..3c841f7 100644 --- a/c/Fetch +++ b/c/Fetch @@ -219,8 +219,9 @@ void * fetch_token_data_address(browser_data * b, HStream * token) { /* No data for horizontal rules or images */ - if (token->style & HR) return NULL; - if (token->style & IMG) return NULL; + if (token->style & HR) return NULL; + if (token->style & IMG) return NULL; + if ((token->style & INPUT) && HtmlINPUTtype(token) == inputtype_IMAGE) return NULL; /* Otherwise, return a pointer to the text */ @@ -431,16 +432,16 @@ void fetch_preprocess_token(browser_data * b, HStream * tptr) if (tptr->style & INPUT) { - switch(tptr->type&TYPE_RESET) + switch(HtmlINPUTtype(tptr)) { - case TYPE_TEXT: if (fetch_chkerror(b, form_new_field(b, tptr, form_text, tptr->text ))) return; break; - case TYPE_PASSWORD:if (fetch_chkerror(b, form_new_field(b, tptr, form_password, tptr->text ))) return; break; - case TYPE_CHECKBOX:if (fetch_chkerror(b, form_new_field(b, tptr, form_checkbox, (char *) (tptr->type & TYPE_CHECKED) ))) return; break; - case TYPE_RADIO: if (fetch_chkerror(b, form_new_field(b, tptr, form_radio, (char *) (tptr->type & TYPE_CHECKED) ))) return; break; - case TYPE_IMAGE: if (fetch_chkerror(b, form_new_field(b, tptr, form_image, NULL ))) return; break; - case TYPE_HIDDEN: if (fetch_chkerror(b, form_new_field(b, tptr, form_hidden, NULL ))) return; break; - case TYPE_SUBMIT: if (fetch_chkerror(b, form_new_field(b, tptr, form_submit, NULL ))) return; break; - case TYPE_RESET: if (fetch_chkerror(b, form_new_field(b, tptr, form_reset, NULL ))) return; break; + case inputtype_TEXT: if (fetch_chkerror(b, form_new_field(b, tptr, form_text, tptr->text ))) return; break; + case inputtype_PASSWORD:if (fetch_chkerror(b, form_new_field(b, tptr, form_password, tptr->text ))) return; break; + case inputtype_CHECKBOX:if (fetch_chkerror(b, form_new_field(b, tptr, form_checkbox, (char *) HtmlINPUTchecked(tptr) ))) return; break; + case inputtype_RADIO: if (fetch_chkerror(b, form_new_field(b, tptr, form_radio, (char *) HtmlINPUTchecked(tptr) ))) return; break; + case inputtype_IMAGE: if (fetch_chkerror(b, form_new_field(b, tptr, form_image, NULL ))) return; break; + case inputtype_HIDDEN: if (fetch_chkerror(b, form_new_field(b, tptr, form_hidden, NULL ))) return; break; + case inputtype_SUBMIT: if (fetch_chkerror(b, form_new_field(b, tptr, form_submit, NULL ))) return; break; + case inputtype_RESET: if (fetch_chkerror(b, form_new_field(b, tptr, form_reset, NULL ))) return; break; } } @@ -455,7 +456,7 @@ void fetch_preprocess_token(browser_data * b, HStream * tptr) if ((tptr->style) & SELECT) { - if (fetch_chkerror(b, form_new_field(b, tptr, form_select, tptr->value))) return; + if (fetch_chkerror(b, form_new_field(b, tptr, form_select, (char *)HtmlSELECToptions(tptr)))) return; } b->formflag = 1; diff --git a/c/FontManage b/c/FontManage index 50b9ec0..0ea79e1 100644 --- a/c/FontManage +++ b/c/FontManage @@ -981,7 +981,7 @@ _kernel_oserror * fm_set_font_colour(fm_face h, int fore, int back) /* Font Manager earlier than v3.37. */ /*************************************************/ -_kernel_oserror * fm_puts(fm_face h, int x, int y,char * s, int os, int blend) +_kernel_oserror * fm_puts(fm_face h, int x, int y, const char * s, int os, int blend) { #ifdef TRACE if (tl & (1u<<10)) Printf("\nfm_puts: Called with handle %p\n String '%s'\n",(void *) h, s); @@ -1450,7 +1450,7 @@ void fm_shutdown(void) /* Returns: See parameters list. */ /*************************************************/ -_kernel_oserror * fm_get_string_width(fm_face h, char * s, int maxwid, int maxbytes, +_kernel_oserror * fm_get_string_width(fm_face h, const char * s, int maxwid, int maxbytes, int split, int * bytes, int * width) { if (h >= 0) @@ -1464,13 +1464,13 @@ _kernel_oserror * fm_get_string_width(fm_face h, char * s, int maxwid, int maxby e = _swix(Font_SetFont,_IN(0),h); - /* Force a terminator in the string */ - - if (maxbytes < strlen(s)) - { - c1 = s[maxbytes]; - s[maxbytes] = 0; - } +// /* Force a terminator in the string */ +// +// if (maxbytes < strlen(s)) +// { +// c1 = s[maxbytes]; +// s[maxbytes] = 0; +// } /* Get the width */ @@ -1520,7 +1520,7 @@ _kernel_oserror * fm_get_string_width(fm_face h, char * s, int maxwid, int maxby if (!e && !*width && split > 0) { - char * p = s; + const char * p = s; /* Adjust the string length to the first split character. */ /* (Thanks to Tony Cheal for spotting this when doing */ @@ -1532,13 +1532,13 @@ _kernel_oserror * fm_get_string_width(fm_face h, char * s, int maxwid, int maxby while (*p && *(p++) != split); - /* Force a terminator at the split character, if found */ - - if (*p) - { - c2 = *p; - *p = 0; - } +// /* Force a terminator at the split character, if found */ +// +// if (*p) +// { +// c2 = *p; +// *p = 0; +// } /* Now call the Font Manager without asking for a split, knowing that */ /* the string length only runs up to the split character. */ @@ -1550,19 +1550,19 @@ _kernel_oserror * fm_get_string_width(fm_face h, char * s, int maxwid, int maxby 0x1000000, /* Maximum width if splitting is allowed */ 0x1000000, /* Maximum height if splitting is allowed */ -1, /* Character to split on, or -1 for no split */ - maxbytes, /* Maximum string length */ + p - s /*maxbytes*/, /* Maximum string length */ width, /* Width of scanned string */ bytes); /* Length of scanned string */ /* Restore the overwritten character, if any */ - if (c2) *p = c2; +// if (c2) *p = c2; } /* Put the character that was overwritten by a terminator (if any) back */ - if (c1) s[maxbytes] = c1; +// if (c1) s[maxbytes] = c1; /* Exit if there was some error */ diff --git a/c/Forms b/c/Forms index 8448112..72512d0 100644 --- a/c/Forms +++ b/c/Forms @@ -42,6 +42,7 @@ #include "Browser.h" #include "FetchPage.h" #include "FontManage.h" +#include "Images.h" #include "Redraw.h" #include "TokenUtils.h" #include "Toolbars.h" @@ -482,7 +483,7 @@ static _kernel_oserror * form_validate_select(browser_data * b, HStream * tp, in /* If the SELECT item can take multiple selections, there's */ /* no work to do, so exit. */ - if (tp->type & TYPE_MULTIPLE) return NULL; + if (HtmlSELECTmultiple(tp)) return NULL; /* Otherwise, find the form field record */ @@ -584,7 +585,7 @@ static _kernel_oserror * form_validate_radio(browser_data * b, HStream * token) form_field * fp; form_header * hp; HStream * tp; - char * name; + const char * name; int selectthis; int foundone; int i; @@ -601,7 +602,7 @@ static _kernel_oserror * form_validate_radio(browser_data * b, HStream * token) /* 'name' to the radio's name. */ selectthis = fp->value.checked; - name = token->name; + name = HtmlINPUTname(token); /* Find the form header and first record of the form that */ /* the given token lies in. */ @@ -626,7 +627,7 @@ static _kernel_oserror * form_validate_radio(browser_data * b, HStream * token) /* See if the name of the token representing this radio */ /* matches the name of the token given to the function */ - if (name && tp->name && !strcmp(name, tp->name)) + if (name && HtmlINPUTname(tp) && !strcmp(name, HtmlINPUTname(tp))) { /* If so, it's in the same group of radio buttons. */ @@ -925,16 +926,15 @@ _kernel_oserror * form_put_field(browser_data * b, HStream * token, char * value /* hold selections plus terminator). */ /*************************************************/ -static void form_build_selection(char * value, char * selection) +static void form_build_selection(const int * value, char * selection) { int i, n; char * p; /* Find the number of entries and point to the first in 'p' */ - p = value; - n = *(int *) p; - p += 8; + p = (char *) (value + 2); + n = value[0]; /* Can't go past the internal limit (see top of this file) */ @@ -1020,7 +1020,7 @@ _kernel_oserror * form_new_field(browser_data * b, HStream * token, form_fieldty case form_select: { - form_build_selection(value, select); + form_build_selection((int *) value, select); value = select; space += strlen(value) + 1 + sizeof(fv_select) - 4; @@ -1105,6 +1105,12 @@ _kernel_oserror * form_new_field(browser_data * b, HStream * token, form_fieldty if (type == form_radio) form_validate_radio (b, token); if (type == form_select) form_validate_select(b, token, 0); + /* Start an image fetch for these beauties... */ + if (type == form_image && HtmlINPUTsrc(token)) + { + e = image_new_image(b, HtmlINPUTsrc(token), token, 0); + } + /* Finished */ return NULL; @@ -1166,19 +1172,20 @@ form_field_value * form_get_field(browser_data * b, HStream * token) static char * form_select_text(browser_data * b, HStream * tp, char * selection) { - int i, n, s; - char * p; - char * f; + int i, n, s; + const int * pi; + const char * p; + char * f; s = 0; /* Find the number of entries in the list and skip to the first */ /* one in 'p' and 'f'. */ - p = tp->value; - n = *(int *) p; - p += 8; - f = p; + pi = HtmlSELECToptions(tp); + n = pi[0]; + p = (const char *) (pi + 2); + f = (char *) p; if (n > MAXSELECTIONS) n = MAXSELECTIONS; @@ -1193,7 +1200,7 @@ static char * form_select_text(browser_data * b, HStream * tp, char * selection) { s++; - f = p; + f = (char *) p; } /* Move past the selected/unselected inidicator char */ @@ -1357,7 +1364,7 @@ static _kernel_oserror * form_reset_form(browser_data * b, HStream * token) { /* Value is NULL for unselected, non-NULL for selected */ - value = (char *) (tp->type & TYPE_CHECKED); + value = (char *) HtmlINPUTchecked(tp); } break; @@ -1365,7 +1372,7 @@ static _kernel_oserror * form_reset_form(browser_data * b, HStream * token) { /* Value is the array of FORM_SELCHAR and FORM_UNSELCHAR characters */ - form_build_selection(tp->value, select); + form_build_selection(HtmlSELECToptions(tp), select); value = select; } break; @@ -1444,7 +1451,7 @@ void form_get_linesize(BBox * fontbox, int * lh, int * lb) /* Assumes: That the int pointer is not NULL. */ /*************************************************/ -static void form_textarea_find_caret(char * p, int fh, int * index, int x, int y) +static void form_textarea_find_caret(const char * p, int fh, int * index, int x, int y) { int i, l, w; char c; @@ -1522,11 +1529,11 @@ static void form_textarea_find_caret(char * p, int fh, int * index, int x, int y /* Returns: See parameters list. */ /*************************************************/ -static void form_textarea_caretpos(char * p, int fh, int index, int * x, int * y) +static void form_textarea_caretpos(const char * p, int fh, int index, int * x, int * y) { - int ox, oy, i, li; - char * t; - char * l; + int ox, oy, i, li; + const char * t; + const char * l; i = li = oy = ox = 0; @@ -1795,6 +1802,7 @@ static _kernel_oserror * form_create_menu(browser_data * b, HStream * tp) { form_field * fp; char * p, * o; + const int * pi; int w, i, n, size; WimpGetPointerInfoBlock m; wimp_menuhdr * mhp; @@ -1817,8 +1825,8 @@ static _kernel_oserror * form_create_menu(browser_data * b, HStream * tp) /* and thus get the number of items in 'n'. */ size = sizeof(wimp_menuhdr); - p = tp->value; - n = *(int *) p; + pi = HtmlSELECToptions(tp); + n = pi[0]; /* Can't create a field if there are no items! */ @@ -1834,7 +1842,7 @@ static _kernel_oserror * form_create_menu(browser_data * b, HStream * tp) /* Skip 'p' to the first item's selected/deselected char */ - p += 8; + p = (char *)&pi[2]; /* Keep a running count of the width used so far in 'w' */ /* (for earlier OS versions which need this to be specified) */ @@ -1893,7 +1901,7 @@ static _kernel_oserror * form_create_menu(browser_data * b, HStream * tp) /* Use the item name for a menu title */ - strncpy(mhp->title, tp->name, 12); + strncpy(mhp->title, HtmlSELECTname(tp), 12); /* If the title is now a NULL string or is a full */ /* 12 chars long excluding terminator, replace it */ @@ -1913,7 +1921,7 @@ static _kernel_oserror * form_create_menu(browser_data * b, HStream * tp) /* Point to the first item's selected/deselected char */ - p = tp->value + 8; + p = (char *)(HtmlSELECToptions(tp) + 2); /* Point past the nth menu item structure (note the pointer */ /* arithmetic...) - i.e. the limit of the menu item */ @@ -2249,7 +2257,7 @@ static _kernel_oserror * form_start_textarea_edit(browser_data * b, HStream * tp if (e) return e; fe_single = !(tp->style & TEXTAREA); - fe_password = (tp->type & TYPE_RESET) == TYPE_PASSWORD; + fe_password = (tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_PASSWORD; fe_browser = b; fe_token = tp; @@ -2613,7 +2621,7 @@ static int form_extend_flex(void **data, int size) /* escaped character sequences). */ /*************************************************/ -static int form_encode_flex_data(void ** data, char * enctype, int start_at) +static int form_encode_flex_data(void ** data, const char * enctype, int start_at) { int i, o; char * p; @@ -2702,15 +2710,15 @@ static int form_encode_flex_data(void ** data, char * enctype, int start_at) /* to hold the item. */ /*************************************************/ -static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp) +static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp, unsigned int x, unsigned int y) { int size; size = 0; - if (tp->name) + if (HtmlELEMENTname(tp)) { - size = strlen(tp->name) + 1; /* add one for the ' = ' sign */ + size = strlen(HtmlELEMENTname(tp)) + 1; /* add one for the ' = ' sign */ switch(fp->header.type) { case form_textarea: /* form_textarea same as form_password: no break */ @@ -2731,8 +2739,8 @@ static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp) if (fp->value.checked) { - if (tp->value) size += strlen(tp->value); - else size += 2; + if (HtmlINPUTvalue(tp)) size += strlen(HtmlINPUTvalue(tp)); + else size += 2; } else size = 0; } @@ -2749,8 +2757,8 @@ static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp) /* name is present (use p). */ s = 0; - n = *(int *) tp->value; - p = tp->value + 8; + n = HtmlSELECToptions(tp)[0]; + p = (char *)(HtmlSELECToptions(tp) + 2); for (i = 0; i < n; i++) { @@ -2772,11 +2780,18 @@ static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp) } break; - // Image button types not supported yet... + /* Image buttons send "name.x=123&name.y=123" */ case form_image: { - size = 0; + char tempbuf[32]; + + /* We've already added up length of "name=", this gives us */ + /* length of "name.x=&name.y=" */ + size = (size+2) * 2 + 1; + + /* Add in length of the two coordinates */ + size += sprintf(tempbuf, "%u%u", x, y); break; } @@ -2792,8 +2807,8 @@ static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp) case form_hidden: { - if (tp->value) size += strlen(tp->value); - else size = 0; + if (HtmlINPUTvalue(tp)) size += strlen(HtmlINPUTvalue(tp)); + else size = 0; } break; } @@ -2817,7 +2832,7 @@ static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp) /* included as part of this data. */ /* */ /* x and y are coords for forms submitted by */ -/* INPUT TYPE = IMAGE [not implemented]. */ +/* INPUT TYPE = IMAGE. */ /* */ /* Parameters: Pointer to a browser_data struct */ /* relevant to the form; */ @@ -2826,10 +2841,10 @@ static int form_field_data_size(browser_data * b, form_field * fp, HStream * tp) /* representing the form; */ /* */ /* X coord for INPUT TYPE = IMAGE */ -/* submissions [not implemented]; */ +/* submissions; */ /* */ /* Y coord for INPUT TYPE = IMAGE */ -/* submissions [not implemented]; */ +/* submissions; */ /* */ /* Pointer to the flex anchor for */ /* the flex block in which the data */ @@ -2912,7 +2927,7 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int /* which case the item will be included in the encoded data. */ if ( - tp->name && + HtmlELEMENTname(tp) && fp->header.type != form_reset && (fp->header.type != form_submit || fp->header.token == token) && (fp->header.type != form_image || fp->header.token == token) @@ -2922,7 +2937,7 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int /* Find out how much space the encoded item will need */ - size = form_field_data_size(b, fp, tp); + size = form_field_data_size(b, fp, tp, x, y); if (size) { @@ -2955,7 +2970,7 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int *p = 0; - strcpy(p, tp->name); + strcpy(p, HtmlELEMENTname(tp)); /* Put in a name/value separator */ @@ -2981,8 +2996,8 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int /* If the item has a value, use this. Otherwise use the default */ /* string of 'on'. */ - if (tp->value) strcpy(p, tp->value); - else strcpy(p, "on"); + if (HtmlINPUTvalue(tp)) strcpy(p, HtmlINPUTvalue(tp)); + else strcpy(p, "on"); } break; @@ -2993,8 +3008,8 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int char * q; first = 1; - n = *(int *) tp->value; - f = tp->value + 8; + n = HtmlSELECToptions(tp)[0]; + f = (char *)(HtmlSELECToptions(tp) + 2); for (i = 0; i < n; i++) { @@ -3010,7 +3025,7 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int { *p++ = ENCODE_FIELDSEP; - strcpy(p, tp->name); + strcpy(p, HtmlSELECTname(tp)); p = strchr(p, 0); *p++ = ENCODE_VALUESEP; @@ -3035,7 +3050,8 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int case form_image: { - // Not implemented yet + /* Need to back up a bit */ + p += sprintf(p-1, ".x%c%u%c%s.y%c%u", ENCODE_VALUESEP, x, ENCODE_FIELDSEP, HtmlINPUTname(tp), ENCODE_VALUESEP, y) - 1; } break; @@ -3051,7 +3067,7 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int { /* Use the item value */ - if (tp->value) strcat(p, tp->value); + if (HtmlINPUTvalue(tp)) strcat(p, HtmlINPUTvalue(tp)); } break; } @@ -3074,7 +3090,7 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int /* Now encode the block according to the specified encoding type */ - if (!form_encode_flex_data(data, tp->enctype, additions_start)) + if (!form_encode_flex_data(data, HtmlFORMenctype(tp), additions_start)) { make_no_cont_memory_error(7); return &erb; @@ -3101,7 +3117,7 @@ static _kernel_oserror * form_build_data(browser_data * b, HStream * token, int /* to submit the form to. */ /*************************************************/ -static _kernel_oserror * form_submit_form(browser_data * b, HStream * token) +static _kernel_oserror * form_submit_form(browser_data * b, HStream * token, int x, int y) { void * data; _kernel_oserror * e; @@ -3122,7 +3138,7 @@ static _kernel_oserror * form_submit_form(browser_data * b, HStream * token) if (HtmlFORMmethod(tp) == formmethod_GET && HtmlFORMaction(tp)) { - e = form_build_data(b, token, 0, 0, &data); // 0, 0 need filling in for INPUT TYPE = IMAGE + e = form_build_data(b, token, x, y, &data); if (!e) e = fetchpage_new(b, data, 1); if (data) @@ -3142,7 +3158,7 @@ static _kernel_oserror * form_submit_form(browser_data * b, HStream * token) else if (HtmlFORMmethod(tp) == formmethod_POST && HtmlFORMaction(tp)) { - e = form_build_data(b, token, 0, 0, &b->extradata); // 0, 0 need filling in for INPUT TYPE = IMAGE + e = form_build_data(b, token, x, y, &b->extradata); tp = hp->token; if (e) @@ -3185,9 +3201,13 @@ static _kernel_oserror * form_submit_form(browser_data * b, HStream * token) /* 1 = start of line for text area, */ /* end of line for writable, */ /* 2 = end of line. */ +/* */ +/* x-coordinate (if input image) */ +/* */ +/* y-coordinate (if input image) */ /*************************************************/ -_kernel_oserror * form_click_field(browser_data * b, HStream * token, int mode) +_kernel_oserror * form_click_field(browser_data * b, HStream * token, int mode, int x, int y) { form_field * fp; _kernel_oserror * e = NULL; @@ -3226,16 +3246,13 @@ _kernel_oserror * form_click_field(browser_data * b, HStream * token, int mode) case form_select: e = form_start_select_edit(b, token); break; - // Images not implemented yet - - case form_image: break; - /* For 'submit' buttons, slab the button in and out and submit the form */ + case form_image: case form_submit: { browser_flash_token(b, token); - e = form_submit_form(b, token); + e = form_submit_form(b, token, x, y); } break; @@ -3306,14 +3323,14 @@ _kernel_oserror * form_finish_edit(browser_data * b) /* unknown button type. */ /*************************************************/ -char * form_button_text(HStream * tp) +const char * form_button_text(HStream * tp) { - char * p; + const char * p; - p = tp->value; + p = HtmlINPUTvalue(tp); - if (!p && ((tp->type & TYPE_RESET) == TYPE_SUBMIT)) p = lookup_token("Submit:Submit",0,0); - if (!p && ((tp->type & TYPE_RESET) == TYPE_RESET)) p = lookup_token("Reset:Reset", 0,0); + if (!p && HtmlINPUTtype(tp) == inputtype_SUBMIT) p = lookup_token("Submit:Submit",0,0); + else if (!p && HtmlINPUTtype(tp) == inputtype_RESET) p = lookup_token("Reset:Reset", 0,0); if (!p) p = "Unknown:Action"; @@ -3465,7 +3482,7 @@ static _kernel_oserror * form_next_field(int auto_submit, int * used) /* Either submit the form, or jump back up to the first editable */ /* element. */ - if (auto_submit) return (form_submit_form(fe_browser, fe_token)); + if (auto_submit) return (form_submit_form(fe_browser, fe_token, 0, 0)); else next = first; } @@ -3528,7 +3545,7 @@ static _kernel_oserror * form_next_field(int auto_submit, int * used) { browser_select_token(owner, t, 0); - return form_click_field(owner, t, 2); + return form_click_field(owner, t, 2, 0, 0); } else { @@ -3550,7 +3567,7 @@ static _kernel_oserror * form_next_field(int auto_submit, int * used) if (next && next != fe_token) { if (choices.keyboardctl) browser_select_token(fe_browser, next, 0); /* If moving by Tab, make sure the selection keeps up */ - return form_click_field(fe_browser, next, 2); + return form_click_field(fe_browser, next, 2, 0, 0); } } @@ -3675,7 +3692,7 @@ static _kernel_oserror * form_previous_field(int * used) { browser_select_token(owner, t, 0); - return form_click_field(owner, t, 2); + return form_click_field(owner, t, 2, 0, 0); } else { @@ -3697,7 +3714,7 @@ static _kernel_oserror * form_previous_field(int * used) if (previous && previous != fe_token) { if (choices.keyboardctl) browser_select_token(fe_browser, previous, 0); /* If moving by Tab, make sure the selection keeps up */ - return form_click_field(fe_browser, previous, 2); + return form_click_field(fe_browser, previous, 2, 0, 0); } } @@ -3724,7 +3741,7 @@ static _kernel_oserror * form_cursor_right(int * used) if (fe_token && fe_browser) { - char * p; + const char * p; p = form_get_field_text(fe_browser, fe_token); @@ -3769,7 +3786,7 @@ static _kernel_oserror * form_cursor_bottom(void) if (fe_token && fe_browser) { - char *p; + const char *p; p = form_get_field_text(fe_browser, fe_token); @@ -3797,8 +3814,8 @@ static _kernel_oserror * form_cursor_eol(void) { if(fe_token && fe_browser) { - char *p; - int o; + const char *p; + int o; p = form_get_field_text(fe_browser, fe_token); o = fe_index; @@ -3831,8 +3848,8 @@ static _kernel_oserror * form_cursor_bol(void) { if (fe_token && fe_browser && fe_index) { - char * p; - int o; + const char * p; + int o; p = form_get_field_text(fe_browser, fe_token); o = fe_index; @@ -3962,9 +3979,9 @@ static _kernel_oserror * form_cursor_y(int dir, int * used) if (fe_token && fe_browser && dir) { - char * p; - int o, x, y, fh; - HStream * tp; + const char * p; + int o, x, y, fh; + HStream * tp; /* For single line items, just look at the relevant direction to move */ @@ -4563,7 +4580,7 @@ void form_select_menu_event(WimpPollBlock * e) /* of items that the menu should have */ tp = fe_mtoken; - n = *(int *) tp->value; + n = HtmlSELECToptions(tp)[0]; o = e->menu_selection[0]; if (o >= n) return; @@ -4578,7 +4595,7 @@ void form_select_menu_event(WimpPollBlock * e) /* the selection type. Otherwise, need to make sure that any */ /* other selected item is cleared. */ - if (tp->type & TYPE_MULTIPLE) + if (HtmlSELECTmultiple(tp)) { select[o] = (select[o] == FORM_SELCHAR) ? FORM_UNSELCHAR : FORM_SELCHAR; } diff --git a/c/Handlers b/c/Handlers index c3c759d..52cc22b 100644 --- a/c/Handlers +++ b/c/Handlers @@ -1521,6 +1521,42 @@ int handle_clicks(int eventcode, WimpPollBlock * b, IdBlock * idb, browser_data return 0; } +/*************************************************/ +/* handle_calc_image_click_coords() */ +/* */ +/* Calculate the coordinates of a click on an */ +/* image in pixels from the top left corner, as */ +/* required by image maps and image input */ +/* fields. */ +/*************************************************/ +int handle_calc_image_click_coords(HStream * p, WimpGetPointerInfoBlock * i, int * x, int * y, browser_data * handle) +{ + WimpGetWindowStateBlock s; + BBox box; + + /* Get the image's size and position on screen */ + + s.window_handle = handle->window_handle; + if (wimp_get_window_state(&s)) return 0; + + if (image_get_token_image_size(handle, p, &box)) return 0; + if (image_get_token_image_position(handle, p, x, y)) return 0; + + *x = coords_x_toscreen(*x, (WimpRedrawWindowBlock *) &s); + *y = coords_y_toscreen(*y, (WimpRedrawWindowBlock *) &s); + + /* Get the offset of the pointer position from the top left */ + /* of the image in ox and oy */ + + *x = i->x - *x; + *y = *y + (box.ymax - box.ymin) - i->y; + + image_convert_to_pixels(handle, p, x, y); + + return 1; +} + + /*************************************************/ /* handle_link_clicks() */ /* */ @@ -1595,7 +1631,12 @@ int handle_link_clicks(int eventcode, WimpPollBlock * b, IdBlock * idb, browser_ ) ) { - ChkError(form_click_field(handle, p, 0)); + int x = 0, y = 0; + + if ((p->style & INPUT) && HtmlINPUTtype(p) == inputtype_IMAGE && eventcode >= 0) + handle_calc_image_click_coords(p, &i, &x, &y, handle); + + ChkError(form_click_field(handle, p, 0, x, y)); used = 1; } else @@ -1643,11 +1684,8 @@ int handle_link_clicks(int eventcode, WimpPollBlock * b, IdBlock * idb, browser_ if ((p->style & IMG) && (p->type & TYPE_ISMAP)) { - WimpGetWindowStateBlock s; char coords[64]; browser_data * targetted; - BBox box; - int x, y; if (eventcode < 0) { @@ -1656,27 +1694,12 @@ int handle_link_clicks(int eventcode, WimpPollBlock * b, IdBlock * idb, browser_ if (!p) return 0; } - /* Get the image's size and position on screen */ - - s.window_handle = handle->window_handle; - if (wimp_get_window_state(&s)) return 0; - - if (image_get_token_image_size(handle, p, &box)) return 0; - if (image_get_token_image_position(handle, p, &x, &y)) return 0; - - x = coords_x_toscreen(x, (WimpRedrawWindowBlock *) &s); - y = coords_y_toscreen(y, (WimpRedrawWindowBlock *) &s); - - /* Get the offset of the pointer position from the top left */ - /* of the image in ox and oy */ - - ox = i.x - x; - oy = y + (box.ymax - box.ymin) - i.y; + /* Find out which pixel we clicked on */ + handle_calc_image_click_coords(p, &i, &ox, &oy, handle); if (ox >= 0 && oy >= 0) { - /* Convert the coordinate to pixels and build an appropriate */ - /* CGI string including this information. */ + /* Build an appropriate CGI string including this information. */ image_convert_to_pixels(handle, p, &ox, &oy); sprintf(coords, "?%d,%d", ox, oy); diff --git a/c/Images b/c/Images index 784d672..e3a4f54 100644 --- a/c/Images +++ b/c/Images @@ -886,7 +886,7 @@ _kernel_oserror * image_new_image(browser_data * b, const char * url, HStream * /* width and height fields according to any details in the */ /* HTML source. */ - if (!background) + if (!background && !(tp->style & INPUT)) { if (tp->cols > 0) idata[nimages].currw = tp->cols * 2; if (tp->rows > 0) idata[nimages].currh = tp->rows * 2; @@ -2294,7 +2294,7 @@ static _kernel_oserror * image_update_image(browser_data * b, int image, BBox * /* correct its X and Y coordinates appropriately */ o = 0; - if (ISLINK(tp)) o = tp->maxlen * 2; + if (ISLINK(tp) && (tp->style & IMG)) o = tp->maxlen * 2; x += o; y += ibox.ymin + o; diff --git a/c/Redraw b/c/Redraw index 1defe06..2cb952b 100644 --- a/c/Redraw +++ b/c/Redraw @@ -1627,9 +1627,9 @@ _kernel_oserror * redraw_draw_r(int toplevel, int xorg, int yorg, browser_data * /* A text-based element */ if ( - (tp->type & TYPE_RESET) == TYPE_TEXT || - (tp->type & TYPE_RESET) == TYPE_PASSWORD || - (tp->style & (TEXTAREA | SELECT)) + (tp->style & (TEXTAREA | SELECT)) || + HtmlINPUTtype(tp) == inputtype_TEXT || + HtmlINPUTtype(tp) == inputtype_PASSWORD ) { BBox box; @@ -1676,7 +1676,7 @@ _kernel_oserror * redraw_draw_r(int toplevel, int xorg, int yorg, browser_data * &r->redraw_area, fh, !!(tp->style & TEXTAREA), - (tp->type & TYPE_RESET) == TYPE_PASSWORD); + (tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_PASSWORD); } /* If the element is a SELECT field, it needs a menu icon too */ @@ -1740,37 +1740,41 @@ _kernel_oserror * redraw_draw_r(int toplevel, int xorg, int yorg, browser_data * // } } } - else switch(tp->type & TYPE_RESET) + else switch(HtmlINPUTtype(tp)) { /* Graphics-based forms elements */ - case TYPE_CHECKBOX: if (nocontent != tp) redraw_switch(b, - tp, - x, - y + base, - form_get_field(b, - d->cdata[cn].t) -> checked ? "fopton" : "foptoff", - r); + case inputtype_CHECKBOX: + if (nocontent != tp) + redraw_switch(b, + tp, + x, + y + base, + form_get_field(b, d->cdata[cn].t) -> checked ? "fopton" : "foptoff", + r); break; - case TYPE_RADIO: if (nocontent != tp) redraw_switch(b, - tp, - x, - y + base, - form_get_field(b, - d->cdata[cn].t) -> checked ? "fradioon" : "fradiooff", - r); + case inputtype_RADIO: + if (nocontent != tp) + redraw_switch(b, + tp, + x, + y + base, + form_get_field(b, d->cdata[cn].t) -> checked ? "fradioon" : "fradiooff", + r); break; - case TYPE_IMAGE: - case TYPE_HIDDEN: break; + case inputtype_IMAGE: + goto do_image; + + case inputtype_HIDDEN: break; - case TYPE_SUBMIT: /* SUBMIT same as RESET: no break */ - case TYPE_RESET: + case inputtype_SUBMIT: /* SUBMIT same as RESET: no break */ + case inputtype_RESET: { - BBox box; - int fh, ox, oy, colour; - char * p; + BBox box; + int fh, ox, oy, colour; + const char * p; p = form_button_text(tp); @@ -1845,7 +1849,11 @@ _kernel_oserror * redraw_draw_r(int toplevel, int xorg, int yorg, browser_data * else if (tp->style & IMG) { BBox box; - int ox, oy, o = 0; + int ox, oy, o; + + do_image: + + o = 0; convert_pair_to_os(x, y + base, &ox, &oy); @@ -1874,7 +1882,7 @@ _kernel_oserror * redraw_draw_r(int toplevel, int xorg, int yorg, browser_data * if (ISLINK(tp)) { - o = tp->maxlen * 2; + o = (tp->style & IMG) ? tp->maxlen * 2 : 4; if (o) { @@ -1887,6 +1895,8 @@ _kernel_oserror * redraw_draw_r(int toplevel, int xorg, int yorg, browser_data * } else if (redraw_selected(b, tp)) redraw_border_around_box(&box, b->selecol); } + else if ((tp->style & INPUT) && redraw_selected(b, tp)) + redraw_border_around_box(&box, b->selecol); /* Redraw the image itself */ diff --git a/c/Reformat b/c/Reformat index 54cb472..4ad16d8 100644 --- a/c/Reformat +++ b/c/Reformat @@ -162,7 +162,8 @@ _kernel_oserror * reformat_stop(browser_data * b) static int reformat_istext(HStream * tp) { - return (((tp->style) & (IMG | HR)) == 0); + return (((tp->style) & (IMG | HR)) == 0 && + !((tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_IMAGE)); } /*************************************************/ @@ -194,6 +195,7 @@ static int reformat_istext(HStream * tp) static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned int flags) { _kernel_oserror * e = NULL; + BBox box; /* Deal with tables */ @@ -281,13 +283,12 @@ static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned else if (w->tp->style & (INPUT | TEXTAREA | SELECT)) { - if ( - (w->tp->type & TYPE_RESET) == TYPE_TEXT || - (w->tp->type & TYPE_RESET) == TYPE_PASSWORD || - (w->tp->style & (TEXTAREA | SELECT)) + if ( (w->tp->style & (TEXTAREA | SELECT) || + HtmlINPUTtype(w->tp) == inputtype_TEXT || + HtmlINPUTtype(w->tp) == inputtype_PASSWORD + ) ) { - BBox box; int h, length, extra = 0; if (w->tp->style & TEXTAREA) @@ -314,7 +315,7 @@ static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned width += 32; /* Account for border and gap */ convert_to_points(width, &extra); - p = w->tp->value + 8; + p = (char *) HtmlSELECToptions(w->tp) + 8; l = 8; while(*p != 0xff) @@ -330,7 +331,7 @@ static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned { /* One line writable */ - length = w->tp->size; + length = HtmlINPUTsize(w->tp); if (length == 1) length = 2; else if (length < 2) @@ -361,12 +362,12 @@ static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned return e; } - else switch(w->tp->type & TYPE_RESET) + else switch(HtmlINPUTtype(w->tp)) { - case TYPE_SUBMIT: /*; no break - same as RESET */ - case TYPE_RESET: + case inputtype_SUBMIT: /*; no break - same as RESET */ + case inputtype_RESET: { - char * p; + const char * p; int h, length, end; p = form_button_text(w->tp); @@ -395,7 +396,7 @@ static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned } break; - case TYPE_CHECKBOX: + case inputtype_CHECKBOX: { w->bytes = 0; @@ -405,7 +406,7 @@ static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned } break; - case TYPE_RADIO: + case inputtype_RADIO: { w->bytes = 0; @@ -415,17 +416,23 @@ static _kernel_oserror * reformat_token_width(reformat_width_data * w, unsigned } break; - case TYPE_IMAGE: - case TYPE_HIDDEN: + case inputtype_HIDDEN: { w->width = w->bytes = 0; } break; + + case inputtype_IMAGE: + { + goto do_image; + } + break; } } else if (w->tp->style & IMG) { - BBox box; + + do_image: w->bytes = 0; w->width = 0; @@ -1201,27 +1208,41 @@ void reformat_free_queue(browser_data * b) _kernel_oserror * reformat_get_image_size(browser_data * b, HStream * tp, BBox * box) { _kernel_oserror * e; + imgalign al; e = image_get_token_image_size(b, tp, box); if (e) return e; - if ((tp->type & TYPE_ALIGN_MASK) == TYPE_MIDDLE) + if (tp->style & IMG) { - box->ymin -= box->ymax / 2; - box->ymax /= 2; + if ((tp->type & TYPE_ALIGN_MASK) == TYPE_MIDDLE) + al = imgalign_MIDDLE; + else if ((tp->type & TYPE_ALIGN_MASK) == TYPE_TOP) + al = imgalign_TOP; + else + al = imgalign_NONE; } + else + al = HtmlINPUTalign(tp); - if ((tp->type & TYPE_ALIGN_MASK) == TYPE_TOP) + switch (al) { - box->ymin =- box->ymax; - box->ymax = 0; + case imgalign_MIDDLE: + box->ymin -= box->ymax / 2; + box->ymax /= 2; + break; + + case imgalign_TOP: + box->ymin =- box->ymax; + box->ymax = 0; + break; } /* Deal with links - need to account for a border */ /* of maxlen * 2 pixels width. ISLINK is defined */ /* in Fetch.h. */ - if (ISLINK(tp)) + if (ISLINK(tp) && (tp->style & IMG)) { int b; @@ -1350,7 +1371,8 @@ static _kernel_oserror * reformat_check_height(int toplevel, browser_data * b, r /* Find out the height of an image */ - if (tp->style & IMG) + if ((tp->style & IMG) || + (tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_IMAGE) { BBox box; @@ -1394,14 +1416,14 @@ static _kernel_oserror * reformat_check_height(int toplevel, browser_data * b, r /* A few easy to work out forms elements */ - else if ((tp->style & INPUT) && (tp->type & TYPE_RESET) == TYPE_CHECKBOX) + else if ((tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_CHECKBOX) { read_sprite_size("fopton", NULL, &top); top -= 8; bot = 8; } - else if ((tp->style & INPUT) && (tp->type & TYPE_RESET) == TYPE_RADIO) + else if ((tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_RADIO) { read_sprite_size("fradioon", NULL, &top); top -= 8; @@ -1585,15 +1607,15 @@ static _kernel_oserror * reformat_check_height(int toplevel, browser_data * b, r { /* General input types */ - switch(tp->type & TYPE_RESET) + switch(HtmlINPUTtype(tp)) { - case TYPE_TEXT: /* No break - same as PASSWORD */ - case TYPE_PASSWORD: + case inputtype_TEXT: /* No break - same as PASSWORD */ + case inputtype_PASSWORD: bot += 8; top += 8; break; - case TYPE_SUBMIT: /* No break - same as RESET */ - case TYPE_RESET: + case inputtype_SUBMIT: /* No break - same as RESET */ + case inputtype_RESET: bot += 8; top += 12; break; @@ -2430,7 +2452,9 @@ if (!tpCurr) done = 1; /* moved. The new position will be set when the reformatted */ /* region is next redrawn. */ - if (tpCurr->style & IMG) image_set_token_image_position(b, tpCurr, -1, -1); + if (tpCurr->style & IMG || + ((tpCurr->style & INPUT) && HtmlINPUTtype(tpCurr)==inputtype_IMAGE)) + image_set_token_image_position(b, tpCurr, -1, -1); /* If the image has a known width and height, the reformatter has */ /* dealt with it - so the image library can mark it as redrawable */ @@ -2882,7 +2906,7 @@ void reformat_change_text(browser_data * b, HStream * tp) /* If we have ALT text for an image, strip off any preceeding */ /* spaces or [s, and any trailing spaces or ]s. */ - else if (tp && tp->text && (tp->style & IMG)) + else if (tp && tp->text && ((tp->style & IMG) || ((tp->style & INPUT) && HtmlINPUTtype(tp) == inputtype_IMAGE))) { char * start, * end; char last; diff --git a/h/Browser b/h/Browser index fc1a6c7..a8f84c4 100644 --- a/h/Browser +++ b/h/Browser @@ -25,13 +25,13 @@ /* (e.g. by drawing a box around it, changing its colour, etc.) and has */ /* some defined action if clicked on. */ -#define CanBeSelected(t) ( \ - ISLINK(t) || \ - ( \ - ((t)->style & (INPUT | TEXTAREA | SELECT)) && \ - ((t)->type & TYPE_RESET) != TYPE_HIDDEN && \ - ((t)->type & TYPE_RESET) != TYPE_IMAGE \ - ) \ +#define CanBeSelected(t) ( \ + ISLINK(t) || \ + ((t)->style & (TEXTAREA | SELECT)) || \ + ( \ + ((t)->style & INPUT) && \ + (HtmlINPUTtype(t) != inputtype_HIDDEN) \ + ) \ ) /* Function prototypes */ diff --git a/h/FontManage b/h/FontManage index 21bc2ad..68b719a 100644 --- a/h/FontManage +++ b/h/FontManage @@ -70,7 +70,7 @@ _kernel_oserror * fm_rescale_fonts (browser_data * b); _kernel_oserror * fm_font_box (fm_face h,BBox * box); _kernel_oserror * fm_set_font_colour (fm_face h,int fore,int back); -_kernel_oserror * fm_puts (fm_face h,int x,int y,char * s,int os,int blend); +_kernel_oserror * fm_puts (fm_face h,int x,int y,const char * s,int os,int blend); _kernel_oserror * fm_putsl (fm_face handle,int x,int y,char * s,int chars,int os,int blend); _kernel_oserror * fm_write_descriptor (char * name,char * buffer); @@ -84,7 +84,7 @@ int fm_system_font (void); void fm_init (int systemfont, int base_size); void fm_shutdown (void); -_kernel_oserror * fm_get_string_width (fm_face h, char * s, int maxwid, int maxbytes, int split, int * bytes, int * width); +_kernel_oserror * fm_get_string_width (fm_face h, const char * s, int maxwid, int maxbytes, int split, int * bytes, int * width); void fm_token_font_info (HStream * t, int * facenum, int * size, int * italic, int * bold); fm_face fm_find_token_font (browser_data * b, HStream * t); diff --git a/h/Forms b/h/Forms index d65226a..c8fb9d6 100644 --- a/h/Forms +++ b/h/Forms @@ -66,10 +66,10 @@ void form_abandon_menu (void); int form_give_focus (browser_data * b); -_kernel_oserror * form_click_field (browser_data * b, HStream * token, int mode); +_kernel_oserror * form_click_field (browser_data * b, HStream * token, int mode, int x, int y); _kernel_oserror * form_cancel_edit (browser_data * b); _kernel_oserror * form_finish_edit (browser_data * b); -char * form_button_text (HStream * tp); +const char * form_button_text (HStream * tp); int form_token_cursor_editable (browser_data * b, HStream * token); _kernel_oserror * form_process_key (browser_data * b, int * key); void form_select_menu_event (WimpPollBlock * e); diff --git a/h/Reformat b/h/Reformat index e193d57..a6d711a 100644 --- a/h/Reformat +++ b/h/Reformat @@ -38,7 +38,7 @@ /* Other tag classification masks */ -#define VISUALDATA (HR | IMG) /* Does the tag contain displayable data, despite */ +#define VISUALDATA (HR | IMG | INPUT) /* Does the tag contain displayable data, despite */ /* having no text inside it? If the tag's style */ /* word contains the bit(s) defined here, it is */ /* deemed to contain such data. */ -- GitLab