2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: LinkMgr.c /main/10 1996/11/01 10:10:59 drk $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 ** Project: Cde Help System
31 ** Description: Hypertext manager for the core engine of the help
32 ** system. Processes requests from the UI to move, turn
33 ** on, or turn off the traversal indicator, to return
34 ** information about a hypertext link and to determine
35 ** if a spot selected contains a hypertext link.
37 ** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
39 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
40 ** (c) Copyright 1993, 1994 International Business Machines Corp.
41 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
42 ** (c) Copyright 1993, 1994 Novell, Inc.
44 ****************************************************************************
45 ************************************<+>*************************************/
61 * Canvas Engine Includes
68 #include "CanvasOsI.h"
69 #include "CvStringI.h"
77 /******** Private Function Declarations ********/
78 /******** End Private Function Declarations ********/
80 /*****************************************************************************
82 *****************************************************************************/
85 /*****************************************************************************
87 *****************************************************************************/
88 const static struct _dtCvLinkDb DefLinkDb = { 0, NULL };
90 /*****************************************************************************
92 *****************************************************************************/
93 /*****************************************************************************
94 * Function: FindLink (
97 *****************************************************************************/
108 for (i = 0; -1 == result && i < link_db->max; i++)
110 if (_DtLinkTypeNone != link_db->list[i].type
111 && NULL != link_db->list[i].id
112 && 0 == _DtCvStrCaseCmpLatin1(link_db->list[i].id, id))
115 * return a valid index
120 * check to see if the hint changes
122 if (_DtLinkTypeLink == link_db->list[i].type &&
123 _DtCvWindowHint_Original != link_db->list[i].info.link.hint)
124 *ret_hint = link_db->list[i].info.link.hint;
127 * clear the error return
136 /*****************************************************************************
137 * Function: ResolveSwitch (_DtCvLinkDb link_db, int *ret_link)
140 *****************************************************************************/
152 char *valueData = NULL;
154 if (iterations < 100)
156 result = _DtCvRunInterp(filter, client_data,
157 link_db->list[link_no].info.swtch.interp,
158 link_db->list[link_no].info.swtch.cmd,
163 int value = atoi(valueData);
164 char *idRefs = link_db->list[link_no].info.swtch.branches;
169 while (value > 0 && *idRefs != '\0')
174 while(*idRefs != ' ' && *idRefs != '\0')
180 while(*idRefs == ' ')
184 * decrement the index.
190 * if the value returned is more than the id list or we hit
191 * the end, back up to the first idref
193 if (value > 0 || *idRefs == '\0')
194 idRefs = link_db->list[link_no].info.swtch.branches;
197 * duplicate the id and null out the
200 rid = strdup (idRefs);
202 while(*idRefs != ' ' && *idRefs != '\0')
206 result = FindLink(link_db, rid, &link_no, ret_hint);
207 if (0 == result && _DtLinkTypeSwitch == link_db->list[link_no].type)
208 result = ResolveSwitch (link_db, link_no, iterations, filter,
209 client_data, &link_no, ret_hint);
213 if (valueData != NULL)
221 /*****************************************************************************
222 * Function: GetNextEntry (
225 *****************************************************************************/
232 while (i < link_db->max && _DtLinkTypeNone != link_db->list[i].type)
235 if (i >= link_db->max)
237 link_db->max += GROW_SIZE;
238 if (link_db->list != NULL)
239 link_db->list = (_DtCvLinkEntry *) realloc(link_db->list,
240 (sizeof (_DtCvLinkEntry) * link_db->max));
242 link_db->list = (_DtCvLinkEntry *) malloc(
243 sizeof (_DtCvLinkEntry) * link_db->max);
245 if (link_db->list == NULL)
248 while (i < link_db->max)
250 link_db->list[i ].id = NULL;
251 link_db->list[i++].type = _DtLinkTypeNone;
260 /*****************************************************************************
261 * Semi-Public Functions
262 *****************************************************************************/
263 /******************************************************************************
264 * Function: int _DtLinkDbGetLinkType (link_index)
272 * Purpose: Return the hypertext link type.
274 *****************************************************************************/
276 _DtLinkDbGetLinkType (
282 if (link_index < link_db->max &&
283 _DtLinkTypeNone != link_db->list[link_index].type)
284 value = link_db->list[link_index].info.link.lnk_type;
289 /******************************************************************************
290 * Function: int _DtLinkDbGetHint (link_index)
298 * Purpose: Return the hypertext link type.
300 *****************************************************************************/
308 if (link_index < link_db->max &&
309 _DtLinkTypeNone != link_db->list[link_index].type)
310 value = link_db->list[link_index].info.link.hint;
315 /******************************************************************************
316 * Function: char *_DtLinkDbGetLinkSpec (link_index)
324 * Purpose: Return the hypertext link type.
326 *****************************************************************************/
328 _DtLinkDbGetLinkSpec (
334 if (link_index < link_db->max &&
335 _DtLinkTypeNone != link_db->list[link_index].type)
336 ptr = link_db->list[link_index].info.link.spec;
341 /******************************************************************************
342 * Function: int _DtLinkDbGetLinkInfo (link_index, ret_info)
350 * Purpose: Return the hypertext link type.
352 *****************************************************************************/
354 _DtLinkDbGetLinkInfo (
359 _DtCvLinkInfo *ret_info)
365 if (link_index < link_db->max &&
366 _DtLinkTypeNone != link_db->list[link_index].type)
370 spec = link_db->list[link_index].info.link.spec;
371 hint = link_db->list[link_index].info.link.hint;
374 * is this a link to a switch? Check the switches for
375 * the spec (id) and resolve to another link if so.
377 if (_DtLinkTypeSwitch == link_db->list[link_index].type ||
378 (0 == FindLink(link_db, spec, &link_index, &hint)
379 && _DtLinkTypeSwitch == link_db->list[link_index].type))
380 result = ResolveSwitch(link_db, link_index, 0, filter, client_data,
385 ret_info->win_hint = hint;
386 ret_info->hyper_type =
387 link_db->list[link_index].info.link.lnk_type;
388 ret_info->specification =
389 link_db->list[link_index].info.link.spec;
390 ret_info->description =
391 link_db->list[link_index].info.link.descrip;
398 /*****************************************************************************
400 *****************************************************************************/
401 /*****************************************************************************
402 * Function: _DtCvLinkDb _DtLinkDbCreate ()
406 * Returns: A link data base handle.
408 * Purpose: Create a link data base.
410 *****************************************************************************/
412 _DtLinkDbCreate (void)
414 _DtCvLinkDb newDb = (_DtCvLinkDb) malloc (sizeof(struct _dtCvLinkDb));
422 /*****************************************************************************
423 * Function: void _DtLinkDbDestroy (_DtCvLinkDb link_db)
426 * canvas Specifies the handle for the canvas.
428 * Returns: A handle to the canvas or NULL if an error occurs.
432 *****************************************************************************/
441 for (i = 0; i < link_db->max; i++)
443 if (_DtLinkTypeLink == link_db->list[i].type)
445 if (NULL != link_db->list[i].id)
446 free(link_db->list[i].id);
447 free(link_db->list[i].info.link.spec);
448 if (NULL != link_db->list[i].info.link.descrip)
449 free(link_db->list[i].info.link.descrip);
451 else if (_DtLinkTypeSwitch == link_db->list[i].type)
453 free(link_db->list[i].id);
454 free(link_db->list[i].info.swtch.interp);
455 free(link_db->list[i].info.swtch.cmd);
456 free(link_db->list[i].info.swtch.branches);
459 if (NULL != link_db->list)
466 /******************************************************************************
467 * Function: int _DtLinkDbAddLink (link_data, char *link, int type,
471 * link Specifies the hypertext link specification.
472 * type Specifies the type of hypertext link.
473 * link Specifies the hypertext link description.
475 * Returns The index into the list of hypertext links.
481 * Purpose: Place a hypertext link into an array.
483 * Note: The link and description pointers are hereafter owned by
484 * the hypertext list. The caller should not free or realloc
487 *****************************************************************************/
497 int i = GetNextEntry(link_db);
499 if (spec == NULL || 0 > i)
503 * copy the information
515 if (NULL != id) free (id);
519 if (NULL != description)
521 description = strdup(description);
522 if (NULL == description)
524 if (NULL != id) free (id);
533 link_db->list[i].type = _DtLinkTypeLink;
534 link_db->list[i].id = id;
536 link_db->list[i].info.link.spec = spec;
537 link_db->list[i].info.link.lnk_type = type;
538 link_db->list[i].info.link.hint = hint;
539 link_db->list[i].info.link.descrip = description;
544 /******************************************************************************
545 * Function: void _DtLinkDbRemoveLink (link_index)
553 * Purpose: Remove a hypertext link from the array.
555 *****************************************************************************/
557 _DtLinkDbRemoveLink (
561 if (link_index < link_db->max &&
562 _DtLinkTypeNone != link_db->list[link_index].type)
564 if (NULL != link_db->list[link_index].id)
565 free(link_db->list[link_index].id);
567 if (_DtLinkTypeLink == link_db->list[link_index].type)
569 free(link_db->list[link_index].info.link.spec);
570 if (NULL != link_db->list[link_index].info.link.descrip)
571 free(link_db->list[link_index].info.link.descrip);
573 else if (_DtLinkTypeSwitch == link_db->list[link_index].type)
575 free(link_db->list[link_index].info.swtch.interp);
576 free(link_db->list[link_index].info.swtch.cmd);
577 free(link_db->list[link_index].info.swtch.branches);
580 link_db->list[link_index].type = _DtLinkTypeNone;
581 link_db->list[link_index].id = NULL;
585 /******************************************************************************
586 * Function: int _DtLinkDbAddSwitch (
594 * Purpose: Add a switch to the link database
596 *****************************************************************************/
605 int i = GetNextEntry(link_db);
607 if (NULL == id || NULL == interp || NULL == cmd
608 || NULL == branches || 0 > i)
612 * copy the information
615 interp = strdup(interp);
617 branches = strdup(branches);
619 if (NULL == id || NULL == interp || NULL == cmd || NULL == branches)
621 if (NULL != id) free(id);
622 if (NULL != interp) free(interp);
623 if (NULL != cmd) free(cmd);
624 if (NULL != branches) free(branches);
628 link_db->list[i].type = _DtLinkTypeSwitch;
629 link_db->list[i].id = id;
631 link_db->list[i].info.swtch.interp = interp;
632 link_db->list[i].info.swtch.cmd = cmd;
633 link_db->list[i].info.swtch.branches = branches;