Encoding 14.4 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 38 39 40 41 42
/* 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"

#include "iso10646.h"

#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 53
int encoding_get_encoding_item_r(ObjectId o, int encoding, ObjectId *encobjid, ComponentId *enccompid);

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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    e = toolbox_get_ancestor(0, idb->ancestor_id, &ancestor, NULL);

    if (!e && ancestor == choices_windowid && new_choices)
    {
      new_choices->encoding = idb->self_component;
      choices_set_encoding_field();
      encoding_prepare_menu(idb->ancestor_id, priority_default, new_choices->encoding);
      return 1;
    }
    else
    {
      return 0;
    }
  }
  else
  {
    b->encoding          = idb->self_component;
    b->encoding_priority = priority_user;
210

211 212
    encoding_prepare_menu(idb->ancestor_id, b->encoding_priority, b->encoding);
  }
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 230 231 232 233 234
{
  browser_data * b;
  ChkError(toolbox_get_client_handle(0, idb->ancestor_id, (void *) &b));

  if (!is_known_browser(b)) return 0;

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

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

  return 1;
}

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

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

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

267
  if (!is_known_browser(b))
268
  {
269 270 271 272 273 274 275 276 277 278 279
    if (idb->ancestor_id == choices_windowid && new_choices)
    {
      /* Fade "From document" item as it is not relevant to choices */
      encoding_prepare_menu(idb->self_id, priority_default, new_choices->encoding);
      menu_set_fade(0, idb->self_id, 0x11FFF, 1);
      return 1;
    }
    else
    {
      return 0;
    }
280
  }
281
  else
282
  {
283
    /* Unfade "From document" item as it is relevant to browser windows */
284

285 286 287 288 289 290 291
    menu_set_fade(0, idb->self_id, 0x11FFF, 0);

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

293
    toolbox_set_client_handle(0, idb->self_id, b);
294

295 296
    encoding_prepare_menu(idb->self_id, b->encoding_priority, b->encoding);
  }
297 298 299 300 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

  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.       */
/*************************************************/

337
void encoding_update_menus(browser_data * b)
338 339 340 341 342
{
  if (menu_id != NULL_ObjectId)
  {
    browser_data * b2;

343
    if (toolbox_get_client_handle(0, menu_id, (void *) &b2)) return;
344

345
    if (b2 == b) encoding_prepare_menu(menu_id, b->encoding_priority, b->encoding);
346 347
  }
}
348 349 350 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 380 381 382 383 384 385 386 387 388 389 390 391 392 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 428 429 430 431 432 433 434 435 436 437 438 439 440 441

/*************************************************/
/* 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;           */
/*************************************************/

int encoding_get_encoding_item(int encoding, ObjectId *encobjid, ComponentId *enccompid)
{
  return encoding_get_encoding_item_r(menu_id, encoding, encobjid, enccompid);
}

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

int encoding_get_encoding_item_r(ObjectId o, int encoding, ObjectId *encobjid, ComponentId *enccompid)
{
  _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()                               */
/*                                               */
/* Creates the encoding menu.                    */
/*************************************************/

_kernel_oserror *encoding_init(void)
{
  return toolbox_create_object(0, "Encoding", &menu_id);
}

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

ObjectId encoding_get_menuid(void)
{
  return menu_id;
}