Encoding 14.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
/* Copyright 1997 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/***************************************************/
/* File   : Encoding.c                             */
/*                                                 */
/* Purpose: Routines to handle the encoding menus. */
/*                                                 */
/* Author : K.J.Bracey                             */
/*                                                 */
/* History: 05-Sep-97: Created.                    */
/***************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include "swis.h"

#include "wimp.h"
#include "toolbox.h"
#include "menu.h"
#include "event.h"

38
#include "Unicode/iso10646.h"
39 40 41 42

#include "Global.h"
#include "Utils.h"

43
#include "Choices.h"
44 45
#include "Encoding.h"

46 47
/* Statics */

48
static ObjectId menu_id         = NULL_ObjectId;
49
static int      ticked_encoding = 0xffffffff;
50
static int      entries_faded;
51

52
static int encoding_get_encoding_item_r(ObjectId o, int encoding, ObjectId *encobjid, ComponentId *enccompid);
53

54 55 56 57 58 59 60 61 62 63 64 65
/*************************************************/
/* encoding_fade_unusable_entries()              */
/*                                               */
/* Scan the Encoding menu, fading out encodings  */
/* that aren't supported.                        */
/*                                               */
/* Parameters: The object ID of the Encoding     */
/*             menu.                             */
/*************************************************/

static int encoding_fade_unusable_entries(ObjectId o)
{
66 67 68
  /* How do we do this without an enumerate call? */

  return 0;
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
}

/*************************************************/
/* encoding_tick_entry()                         */
/*                                               */
/* Select or deselect the entry corresponding    */
/* to a specified encoding. Parent menu items    */
/* are also selected/deselected.                 */
/*                                               */
/* Parameters: The object ID of the Encoding     */
/*             menu;                             */
/*                                               */
/*             The number of the encoding;       */
/*                                               */
/*             0 to untick, 1 to tick.           */
/*                                               */
/* Returns:    1 if entry found, 0 if not.       */
/*                                               */
/* Assumes:    Parent menu items have            */
/*             consecutive component IDs         */
/*             starting at 0x11000 in each menu; */
/*                                               */
/*             The component ID of an encoding   */
/*             item is the number of the         */
/*             encoding it represents;           */
/*                                               */
/*             A given encoding is only          */
/*             represented once in the menu      */
/*             tree.                             */
/*************************************************/

static int encoding_tick_entry(ObjectId o, int enc, int state)
{
  ComponentId c;
  _kernel_oserror *e;

  e = menu_set_tick(0, o, enc, state);
106 107

  if (!e) return 1;
108 109

  /* The encoding isn't in this menu, so scan the submenus. */
110

111 112 113 114 115 116 117 118
  for (c = 0x11000; ; c++)
  {
    ObjectId sub;

    e = menu_get_sub_menu_show(0, o, c, &sub);

    /* If an error - component not found - end of submenus */

119 120 121
    if (e) return 0;

    if (sub == NULL_ObjectId) continue;
122 123 124 125 126 127 128 129 130 131 132 133 134

    if (encoding_tick_entry(sub, enc, state))
    {
      ChkError(menu_set_tick(0, o, c, state));
      return 1;
    }
  }
}

/*************************************************/
/* encoding_prepare_menu()                       */
/*                                               */
/* Ensure that the state of the Encoding menu    */
135 136
/* is correct for a supplied encoding_priority   */
/* and encoding type.                            */
137 138 139
/*                                               */
/* Parameters: Object ID of the Encoding menu;   */
/*                                               */
140 141 142
/*             The encoding priority             */
/*                                               */
/*             The encoding number               */
143 144 145 146 147 148 149 150 151
/*                                               */
/* Assumes:    The "From document" item is       */
/*             component 0x11FFF in the top-     */
/*             level menu;                       */
/*                                               */
/*             The Encoding menu is a shared     */
/*             object.                           */
/*************************************************/

152
void encoding_prepare_menu(ObjectId o, encoding_priority encoding_priority, int encoding)
153
{
154
  menu_set_tick(0, o, 0x11FFF, encoding_priority != priority_user);
155

156
  if (ticked_encoding != encoding)
157
  {
158
    if (ticked_encoding) encoding_tick_entry(o, ticked_encoding, 0);
159

160 161
    encoding_tick_entry(o, encoding, 1);
    ticked_encoding = encoding;
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
  }
}

/*************************************************/
/* encoding_select()                             */
/*                                               */
/* Event handler for the selection of an         */
/* encoding (EEncoding_Select).                  */
/*                                               */
/* Parameters are as for a standard Toolbox      */
/* event handler.                                */
/*                                               */
/* Assumes: The top-level Encoding menu is an    */
/*          ancestor object;                     */
/*                                               */
/*          The component ID is the number of    */
/*          the encoding to select.              */
/*************************************************/

181
int encoding_select(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle)
182 183
{
  browser_data * b;
184
  _kernel_oserror *e;
185 186 187

  ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b));

188 189 190
  if (!is_known_browser(b))
  {
    ObjectId ancestor;
191

192
    e = toolbox_get_ancestor(0, menu_id, &ancestor, NULL);
193 194 195 196 197

    if (!e && ancestor == choices_windowid && new_choices)
    {
      new_choices->encoding = idb->self_component;
      choices_set_encoding_field();
198
      encoding_prepare_menu(menu_id, priority_default, new_choices->encoding);
199 200 201 202 203 204 205 206 207 208 209
      return 1;
    }
    else
    {
      return 0;
    }
  }
  else
  {
    b->encoding          = idb->self_component;
    b->encoding_priority = priority_user;
210

211
    encoding_prepare_menu(menu_id, b->encoding_priority, b->encoding);
212
  }
213 214 215 216 217 218 219 220 221 222 223 224 225 226

  return 1;
}

/*************************************************/
/* encoding_from_document_select()               */
/*                                               */
/* Handle the selection of the "From document"   */
/* menu entry.                                   */
/*                                               */
/* Parameters are as for a standard Toolbox      */
/* event handler.                                */
/*************************************************/

227
int encoding_from_document_select(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle)
228 229
{
  browser_data * b;
230

231 232 233 234 235
  ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b));

  if (!is_known_browser(b)) return 0;

  if (b->encoding_priority == priority_user)
236
  {
237
    b->encoding_priority = priority_default;
238
  }
239
  else
240
  {
241
    b->encoding_priority = priority_user;
242
  }
243

244
  encoding_prepare_menu(menu_id, b->encoding_priority, b->encoding);
245 246 247 248 249 250 251 252 253 254 255

  return 1;
}

/*************************************************/
/* encoding_show_menu()                          */
/*                                               */
/* Set up the Encoding menu before it is shown.  */
/*                                               */
/* Parameters are as for a standard Toolbox      */
/* event handler.                                */
256 257 258 259
/*                                               */
/* Assumes:    The "From document" item is       */
/*             component 0x11FFF in the top-     */
/*             level menu;                       */
260 261
/*************************************************/

262
int encoding_show_menu(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle)
263 264 265 266 267
{
  browser_data * b;

  ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b));

268
  if (!is_known_browser(b))
269
  {
270 271 272
    if (idb->ancestor_id == choices_windowid && new_choices)
    {
      /* Fade "From document" item as it is not relevant to choices */
273

274
      menu_set_fade(0, idb->self_id, 0x11FFF, 1);
275 276 277 278
      encoding_prepare_menu(menu_id, priority_default, new_choices->encoding);

      toolbox_set_client_handle(0, idb->self_id, NULL);

279 280 281 282 283 284
      return 1;
    }
    else
    {
      return 0;
    }
285
  }
286
  else
287
  {
288
    /* Unfade "From document" item as it is relevant to browser windows */
289

290 291 292 293 294 295 296
    menu_set_fade(0, idb->self_id, 0x11FFF, 0);

    if (!entries_faded)
    {
      encoding_fade_unusable_entries(idb->self_id);
      entries_faded = 1;
    }
297

298
    toolbox_set_client_handle(0, idb->self_id, b);
299

300
    encoding_prepare_menu(menu_id, b->encoding_priority, b->encoding);
301
  }
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

  return 1;
}

/*************************************************/
/* encoding_changed_by_meta()                    */
/*                                               */
/* Called by HTMLLib when a META tag that        */
/* changes encoding is found. Update the         */
/* browser_data struct and the menu accordingly. */
/*                                               */
/* This routine is registered with HTMLLib in    */
/* html_get_next_token() when the parse starts.  */
/*                                               */
/* Parameters: The number of the new encoding;   */
/*                                               */
/*             Pointer to the relevant           */
/*             browser_data struct.              */
/*************************************************/

void encoding_changed_by_meta(int encoding, void * handle)
{
  browser_data * b = (browser_data *) handle;

  b->encoding          = encoding;
  b->encoding_priority = priority_meta;

  encoding_update_menus(b);
}

/*************************************************/
/* encoding_update_menus()                       */
/*                                               */
/* Update the Encoding menu if it is currently   */
/* open for the specified browser.               */
/*                                               */
/* Parameters: Pointer to the browser_data       */
/*             whose encoding has changed.       */
/*************************************************/

342
void encoding_update_menus(browser_data * b)
343 344 345 346 347
{
  if (menu_id != NULL_ObjectId)
  {
    browser_data * b2;

348
    if (toolbox_get_client_handle(0, menu_id, (void *) &b2)) return;
349

350
    if (b2 == b) encoding_prepare_menu(menu_id, b->encoding_priority, b->encoding);
351 352
  }
}
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379

/*************************************************/
/* encoding_get_encoding_item()                  */
/*                                               */
/* Finds the menu item containing the name       */
/* of the specified encoding.                    */
/*                                               */
/* Parameters: the required encoding             */
/*                                               */
/*             Pointer to the objectid to return */
/*             information in                    */
/*                                               */
/*             Pointer to the componentid to     */
/*             return the information in.        */
/*                                               */
/* Returns:    1 if the encoding was found       */
/*             0 if it was not                   */
/*                                               */
/* Assumes:    Parent menu items have            */
/*             consecutive component IDs         */
/*             starting at 0x11000 in each menu; */
/*                                               */
/*             The component ID of an encoding   */
/*             item is the number of the         */
/*             encoding it represents;           */
/*************************************************/

380
int encoding_get_encoding_item(int encoding, ObjectId * encobjid, ComponentId * enccompid)
381 382 383 384 385 386 387 388 389 390 391
{
  return encoding_get_encoding_item_r(menu_id, encoding, encobjid, enccompid);
}

/*************************************************/
/* encoding_get_encoding_item_r()                */
/*                                               */
/* Recursive backend to                          */
/* encoding_get_encoding_item                    */
/*************************************************/

392
static int encoding_get_encoding_item_r(ObjectId o, int encoding, ObjectId * encobjid, ComponentId * enccompid)
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
{
  _kernel_oserror *e;
  ComponentId c;
  int state;

  /* We don't really want to know if this item is ticked, we just want to see if the item exists */

  e = menu_get_tick(0, o, encoding, &state);

  if (!e)
  {
    *encobjid  = o;
    *enccompid = encoding;
    return 1;
  }

  for (c = 0x11000; ; c++)
  {
    ObjectId sub;

    e = menu_get_sub_menu_show(0, o, c, &sub);

    /* If an error - component not found - end of submenus */

    if (e) return 0;

    if (sub == NULL_ObjectId) continue;

    if (encoding_get_encoding_item_r(sub, encoding, encobjid, enccompid)) return 1;
  }
}

/*************************************************/
/* encoding_init()                               */
/*                                               */
428 429 430 431
/* Initialises the encoding system - basically,  */
/* creates the menu now (rather than letting it  */
/* autocreate later - it's a shared object) so   */
/* that the Object ID is known.                  */
432 433 434 435
/*************************************************/

_kernel_oserror *encoding_init(void)
{
436 437 438 439 440 441
  /* Encoding menu may not be there, so this should be able to */
  /* fail silently.                                            */

  toolbox_create_object(0, "Encoding", &menu_id);

  return NULL;
442 443 444 445 446 447 448 449 450 451 452 453 454
}

/*************************************************/
/* encoding_get_menuid(void)                     */
/*                                               */
/* Returns the ObjectId of the main encoding     */
/* menu.                                         */
/*************************************************/

ObjectId encoding_get_menuid(void)
{
  return menu_id;
}