2527 lines
78 KiB
C
2527 lines
78 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these librararies and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: XInterface.c /main/37 1996/11/11 12:28:19 cde-hp $ */
|
|
/************************************<+>*************************************
|
|
****************************************************************************
|
|
**
|
|
** File: XInterface.c
|
|
**
|
|
** Project: Cde Help System
|
|
**
|
|
** Description: This is the UI dependant layer to the Help System.
|
|
** It recieves requests from the Core Engine for
|
|
** information or to do rendering. It does the
|
|
** appropriate work based on a Motif and X Lib
|
|
** interface.
|
|
**
|
|
** (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 Hewlett-Packard Company
|
|
**
|
|
** (c) Copyright 1993, 1994 Hewlett-Packard Company
|
|
** (c) Copyright 1993, 1994 International Business Machines Corp.
|
|
** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
|
** (c) Copyright 1993, 1994 Novell, Inc.
|
|
**
|
|
****************************************************************************
|
|
************************************<+>*************************************/
|
|
|
|
/*
|
|
* system includes
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <limits.h>
|
|
#include <errno.h>
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xos.h>
|
|
#ifdef X_NOT_STDC_ENV
|
|
extern int errno;
|
|
#endif
|
|
|
|
/*
|
|
* Canvas Engine
|
|
*/
|
|
#include "CanvasP.h"
|
|
#include "CanvasSegP.h"
|
|
|
|
/*
|
|
* private includes
|
|
*/
|
|
#include "AsciiSpcI.h"
|
|
#include "DisplayAreaP.h"
|
|
#include "HelpErrorP.h"
|
|
#include "FontAttrI.h"
|
|
#include "FontI.h"
|
|
#include "GraphicsI.h"
|
|
#include "RegionI.h"
|
|
#include "StringFuncsI.h"
|
|
#include "XInterfaceI.h"
|
|
|
|
#include <X11/bitmaps/root_weave>
|
|
|
|
#ifdef NLS16
|
|
#endif
|
|
|
|
/******** Private Function Declarations ********/
|
|
static void DADrawSpc (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer spc_handle,
|
|
_DtCvUnit x,
|
|
_DtCvUnit y,
|
|
_DtCvUnit box_x,
|
|
_DtCvUnit box_y,
|
|
_DtCvUnit box_height,
|
|
int link_type,
|
|
_DtCvFlags old_flags,
|
|
_DtCvFlags new_flags );
|
|
/******** End Private Function Declarations ********/
|
|
|
|
/*****************************************************************************
|
|
* Private Defines
|
|
*****************************************************************************/
|
|
#define GROW_SIZE 3
|
|
|
|
/*****************************************************************************
|
|
* Private Macros
|
|
*****************************************************************************/
|
|
#define IsHyperLink(x) ((x) & _DtCvLINK_FLAG)
|
|
#define IsHyperBegin(x) ((x) & _DtCvLINK_BEGIN)
|
|
#define IsHyperEnd(x) ((x) & _DtCvLINK_END)
|
|
#define IsPopUp(x) ((x) & _DtCvLINK_POP_UP)
|
|
#define IsNewWindow(x) ((x) & _DtCvLINK_NEW_WINDOW)
|
|
|
|
#define HasTraversal(x) ((x) & _DtCvTRAVERSAL_FLAG)
|
|
#define IsTraversalBegin(x) ((x) & _DtCvTRAVERSAL_BEGIN)
|
|
#define IsTraversalEnd(x) ((x) & _DtCvTRAVERSAL_END)
|
|
|
|
#define IsSelected(x) ((x) & _DtCvSELECTED_FLAG)
|
|
|
|
#define IsMarkOn(x) (((x) & _DtCvMARK_FLAG) && ((x) & _DtCvMARK_ON))
|
|
|
|
#define TocIsOn(x) ((x) & _DT_HELP_TOC_ON)
|
|
#define TocIsOff(x) (!((x) & _DT_HELP_TOC_ON))
|
|
|
|
#define TurnTocOn(x) (x) |= _DT_HELP_TOC_ON
|
|
#define TurnTocOff(x) (x) &= ~(_DT_HELP_TOC_ON)
|
|
|
|
#define IsEndOfLine(x) ((x) & _DtCvEND_OF_LINE)
|
|
|
|
/*****************************************************************************
|
|
* Private Variables
|
|
*****************************************************************************/
|
|
static const char IsoString[] = "ISO-8859-1";
|
|
static const char SymbolString[] = "DT-SYMBOL-1";
|
|
static const char DefaultStr[] = "default_spc";
|
|
|
|
#define MAX_STR_LEN 5
|
|
|
|
typedef struct {
|
|
const char *symbol;
|
|
const char spc_string[MAX_STR_LEN];
|
|
const char *spc_value;
|
|
} SpecialSymbolTable;
|
|
|
|
|
|
static SpecialSymbolTable SpcTable[] =
|
|
{
|
|
{"[aacute]", {'\341','\0'}, IsoString }, /*ISOlat1, small a, acute accent */
|
|
{"[acirc ]", {'\342','\0'}, IsoString }, /*ISOlat1, small a, circumflex */
|
|
{"[aelig ]", {'\346','\0'}, IsoString }, /*ISOlat1, small ae diphthong */
|
|
{"[agrave]", {'\340','\0'}, IsoString }, /*ISOlat1, small a, grave accent */
|
|
{"[alpha ]", {'\141','\0'}, SymbolString}, /*ISOgrk3, Greek, small alpha */
|
|
{"[aleph ]", {'\300','\0'}, SymbolString}, /*ISOtech, aleph, Hebrews */
|
|
{"[amp ]", { '&' ,'\0'}, IsoString }, /*ISOnum , ampersand */
|
|
{"[and ]", {'\331','\0'}, SymbolString}, /*ISOtech, wedge, logical and */
|
|
{"[ang ]", {'\320','\0'}, SymbolString}, /*ISOamso, angle */
|
|
{"[angst ]", {'\305','\0'}, IsoString }, /*ISOtech, Angstrom, cap A, ring */
|
|
{"[ap ]", {'\273','\0'}, SymbolString}, /*ISOtech, approximately equal */
|
|
{"[apos ]", { '\'' ,'\0'}, IsoString }, /*ISOnum , apostrophe */
|
|
{"[aring ]", {'\345','\0'}, IsoString }, /*ISOlat1, small a, ring */
|
|
{"[ast ]", { '*' ,'\0'}, IsoString }, /*ISOnum , asterisk */
|
|
{"[atilde]", {'\343','\0'}, IsoString }, /*ISOlat1, small a, tilde */
|
|
{"[auml ]", {'\344','\0'}, IsoString }, /*ISOlat1, small a, umlaut mark */
|
|
{"[beta ]", {'\142','\0'}, SymbolString}, /*ISOgrk3, Greek, small beta */
|
|
{"[blank ]", { ' ' ,'\0'}, IsoString }, /*ISOpub , significant blank */
|
|
{"[bottom]", {'\136','\0'}, SymbolString}, /*ISOtech, bottom symbol */
|
|
{"[brvbar]", {'\246','\0'}, IsoString }, /*ISOnum , broken vertical bar */
|
|
{"[bsol ]", { '\\' ,'\0'}, IsoString }, /*ISOnum , backslash, rev solidus*/
|
|
{"[bull ]", {'\267','\0'}, SymbolString}, /*ISOpub , round bullet,filled */
|
|
{"[cap ]", {'\307','\0'}, SymbolString}, /*ISOtech, intersection */
|
|
{"[ccedil]", {'\347','\0'}, IsoString }, /*ISOlat1, small c, cedilla */
|
|
{"[cent ]", {'\242','\0'}, IsoString }, /*ISOnum , cent sign */
|
|
{"[chi ]", {'\143','\0'}, SymbolString}, /*ISOgrk3, Greek, small chi */
|
|
{"[clubs ]", {'\247','\0'}, SymbolString}, /*ISOpub , clubs suit symbol */
|
|
{"[colon ]", { ':' ,'\0'}, IsoString }, /*ISOnum , colon */
|
|
{"[comma ]", { ',' ,'\0'}, IsoString }, /*ISOnum , comma */
|
|
{"[commat]", { '@' ,'\0'}, IsoString }, /*ISOnum , commercial at */
|
|
{"[cong ]", {'\100','\0'}, SymbolString}, /*ISOtech, congruent with */
|
|
{"[copy ]", {'\323','\0'}, SymbolString}, /*ISOnum , copyright symbol */
|
|
{"[cup ]", {'\310','\0'}, SymbolString}, /*ISOtech, union or logical sum */
|
|
{"[curren]", {'\244','\0'}, IsoString }, /*ISOnum , general currency sign */
|
|
{"[darr ]", {'\257','\0'}, SymbolString}, /*ISOnum , downward arrow */
|
|
{"[dArr ]", {'\337','\0'}, SymbolString}, /*ISOamsa, down double arrow */
|
|
{"[dash ]", { '-' ,'\0'}, IsoString }, /*ISOpub , dash */
|
|
{"[deg ]", {'\260','\0'}, SymbolString}, /*ISOnum , degree sign */
|
|
{"[delta ]", {'\144','\0'}, SymbolString}, /*ISOgrk3, Greek, small delta */
|
|
{"[diams ]", {'\250','\0'}, SymbolString}, /*ISOpub , diamond suit symbol */
|
|
{"[divide]", {'\270','\0'}, SymbolString}, /*ISOnum , divide sign */
|
|
{"[dollar]", { '$' ,'\0'}, IsoString }, /*ISOnum , dollar sign */
|
|
{"[eacute]", {'\351','\0'}, IsoString }, /*ISOlat1, small e, acute accent */
|
|
{"[ecirc ]", {'\352','\0'}, IsoString }, /*ISOlat1, small e, circumflex */
|
|
{"[egrave]", {'\350','\0'}, IsoString }, /*ISOlat1, small e, grave accent */
|
|
{"[empty ]", {'\370','\0'}, IsoString }, /*ISOamso, empty string */
|
|
{"[epsiv ]", {'\145','\0'}, SymbolString}, /*ISOgrk3, Greek,sm epsilon, var */
|
|
{"[equals]", { '=' ,'\0'}, IsoString }, /*ISOnum , equals sign */
|
|
{"[equiv ]", {'\272','\0'}, SymbolString}, /*ISOtech, identical with */
|
|
{"[eta ]", {'\150','\0'}, SymbolString}, /*ISOgrk3, Greek, small eta */
|
|
{"[eth ]", {'\360','\0'}, IsoString }, /*ISOlat1, small eth, Icelandic */
|
|
{"[euml ]", {'\353','\0'}, IsoString }, /*ISOlat1, small e, umlaut mark */
|
|
{"[excl ]", { '!' ,'\0'}, IsoString }, /*ISOnum , exclamation mark */
|
|
{"[exist ]", {'\044','\0'}, SymbolString}, /*ISOtech, at least one exists */
|
|
{"[forall]", {'\042','\0'}, SymbolString}, /*ISOtech, for all */
|
|
{"[frac12]", {'\275','\0'}, IsoString }, /*ISOnum , fraction one-half */
|
|
{"[frac13]", {'1','/','3','\0'},
|
|
IsoString }, /*ISOnum , fraction one-third */
|
|
{"[frac14]", {'\274','\0'}, IsoString }, /*ISOnum , fraction one-quarter */
|
|
{"[frac15]", {'1','/','5','\0'},
|
|
IsoString }, /*ISOnum , fraction one-fifth */
|
|
{"[frac16]", {'1','/','6','\0'},
|
|
IsoString }, /*ISOnum , fraction one-sixth */
|
|
{"[frac18]", {'1','/','8','\0'},
|
|
IsoString }, /*ISOnum , fraction one-eight */
|
|
{"[frac23]", {'2','/','3','\0'},
|
|
IsoString }, /*ISOnum , fraction two-thirds */
|
|
{"[frac25]", {'2','/','5','\0'},
|
|
IsoString }, /*ISOnum , fraction two-fifths */
|
|
{"[frac34]", {'\276','\0'}, IsoString }, /*ISOnum , fraction three-quarter*/
|
|
{"[frac35]", {'3','/','5','\0'},
|
|
IsoString }, /*ISOnum , fraction three-fifths */
|
|
{"[frac38]", {'3','/','8','\0'},
|
|
IsoString }, /*ISOnum , fraction three-eights */
|
|
{"[frac45]", {'4','/','5','\0'},
|
|
IsoString }, /*ISOnum , fraction four-fifths */
|
|
{"[frac56]", {'5','/','6','\0'},
|
|
IsoString }, /*ISOnum , fraction five-sixths */
|
|
{"[frac58]", {'5','/','8','\0'},
|
|
IsoString }, /*ISOnum , fraction five-eights */
|
|
{"[frac78]", {'7','/','8','\0'},
|
|
IsoString }, /*ISOnum , fraction seven-eights */
|
|
{"[gamma ]", {'\147','\0'}, SymbolString}, /*ISOgrk3, Greek, small gamma */
|
|
{"[ge ]", {'\263','\0'}, SymbolString}, /*ISOtech, greater-than-or-equal */
|
|
{"[gt ]", { '>' ,'\0'}, IsoString }, /*ISOnum , greater than sign */
|
|
{"[half ]", {'\275','\0'}, IsoString }, /*ISOnum , fraction one-half */
|
|
{"[harr ]", {'\253','\0'}, SymbolString}, /*ISOamsa, left & right arrow */
|
|
{"[hArr ]", {'\333','\0'}, SymbolString}, /*ISOamsa, l & r double arrow */
|
|
{"[hearts]", {'\251','\0'}, SymbolString}, /*ISOpub , hearts suit symbol */
|
|
{"[hellip]", {'\274','\0'}, SymbolString}, /*ISOpub , ellipsis(horizontal) */
|
|
{"[horbar]", {'\276','\0'}, SymbolString}, /*ISOnum , horizontal bar */
|
|
{"[hyphen]", { '-' ,'\0'}, IsoString }, /*ISOnum , hyphen */
|
|
{"[iacute]", {'\355','\0'}, IsoString }, /*ISOlat1, small i, acute accent */
|
|
{"[icirc ]", {'\356','\0'}, IsoString }, /*ISOlat1, small i, circumflex */
|
|
{"[iexcl ]", {'\241','\0'}, IsoString }, /*ISOnum , inverted ! mark */
|
|
{"[igrave]", {'\354','\0'}, IsoString }, /*ISOlat1, small i, grave accent */
|
|
{"[image ]", {'\301','\0'}, SymbolString}, /*ISOamso,imaginary number symbol*/
|
|
{"[infin ]", {'\245','\0'}, SymbolString}, /*ISOtech, infinity */
|
|
{"[int ]", {'\246','\0'}, SymbolString}, /*ISOtech, intergral operator */
|
|
{"[iota ]", {'\151','\0'}, SymbolString}, /*ISOgrk3, Greek, small iota */
|
|
{"[iquest]", {'\277','\0'}, IsoString }, /*ISOnum , inverted ? mark */
|
|
{"[isin ]", {'\316','\0'}, SymbolString}, /*ISOtech, set membership */
|
|
{"[iuml ]", {'\357','\0'}, IsoString }, /*ISOlat1, small i, umlaut mark */
|
|
{"[kappa ]", {'\153','\0'}, SymbolString}, /*ISOgrk3, Greek, small kappa */
|
|
{"[lambda]", {'\154','\0'}, SymbolString}, /*ISOgrk3, Greek, small lambda */
|
|
{"[lang ]", {'\341','\0'}, SymbolString}, /*ISOtech, left angle bracket */
|
|
{"[laquo ]", {'\253','\0'}, IsoString }, /*ISOnum , left angle quotation */
|
|
{"[larr ]", {'\254','\0'}, SymbolString}, /*ISOnum , leftward arrow */
|
|
{"[lArr ]", {'\334','\0'}, SymbolString}, /*ISOtech, is implied by */
|
|
{"[lcub ]", { '{' ,'\0'}, IsoString }, /*ISOnum , left curly brace */
|
|
{"[ldquo ]", { '"' ,'\0'}, IsoString }, /*ISOnum , left double quote */
|
|
{"[le ]", {'\243','\0'}, SymbolString}, /*ISOtech, less-than-or-equal */
|
|
{"[lowbar]", { '_' ,'\0'}, IsoString }, /*ISOnum , low line */
|
|
{"[lpar ]", { '(' ,'\0'}, IsoString }, /*ISOnum , left parenthesis */
|
|
{"[lsqb ]", { '[' ,'\0'}, IsoString }, /*ISOnum , left square bracket */
|
|
{"[lsquo ]", { '`' ,'\0'}, IsoString }, /*ISOnum , left single quote */
|
|
{"[lsquor]", { ',' ,'\0'}, IsoString }, /*ISOnum,rising single quote(low)*/
|
|
{"[lt ]", { '<' ,'\0'}, IsoString }, /*ISOnum , less-than sign */
|
|
{"[mdash ]", {'\276','\0'}, SymbolString}, /*ISOpub , em dash(long dash) */
|
|
{"[micro ]", {'\155','\0'}, SymbolString}, /*ISOnum , micro */
|
|
{"[middot]", {'\267','\0'}, IsoString }, /*ISOnum , middle dot */
|
|
{"[minus ]", { '-' ,'\0'}, IsoString }, /*ISOtech, minus sign */
|
|
{"[mldr ]", {'.','.','.','.','\0'},
|
|
IsoString }, /*ISOpub , em leader */
|
|
{"[mnplus]", {'\140','\b','+','\0'},
|
|
SymbolString}, /*ISOtech, minus-or-plus sign */
|
|
{"[mu ]", {'\155','\0'}, SymbolString}, /*ISOgrk3, Greek, small mu */
|
|
{"[nabla ]", {'\321','\0'}, SymbolString}, /*ISOtech, del, Hamilton operator*/
|
|
{"[nbsp ]", { ' ' ,'\0'}, IsoString }, /*ISOnum , no break space */
|
|
{"[ndash ]", { '-' ,'\0'}, IsoString }, /*ISOpub , en dash(short dash) */
|
|
{"[ne ]", {'\271','\0'}, SymbolString}, /*ISOtech, not equal */
|
|
{"[ni ]", {'\047','\0'}, SymbolString}, /*ISOtech, contains */
|
|
{"[nldr ]", {'.','.','\0'},IsoString }, /*ISOpub , double baseline dot */
|
|
{"[not ]", {'\330','\0'}, SymbolString}, /*ISOnum , not */
|
|
{"[notin ]", {'\317','\0'}, SymbolString}, /*ISOtech, negated set membership*/
|
|
{"[ntilde]", {'\361','\0'}, IsoString }, /*ISOlat1, small N, tilde */
|
|
{"[nu ]", {'\156','\0'}, SymbolString}, /*ISOgrk3, Greek, small nu */
|
|
{"[num ]", { '#' ,'\0'}, IsoString }, /*ISOnum , number sign */
|
|
{"[oacute]", {'\363','\0'}, IsoString }, /*ISOlat1, small o, acute accent */
|
|
{"[ocirc ]", {'\364','\0'}, IsoString }, /*ISOlat1, small o, circumflex */
|
|
{"[ograve]", {'\362','\0'}, IsoString }, /*ISOlat1, small o, grave accent */
|
|
{"[ohm ]", {'\127','\0'}, SymbolString}, /*ISOnum , ohm */
|
|
{"[omega ]", {'\167','\0'}, SymbolString}, /*ISOgrk3, Greek, small omega */
|
|
{"[oplus ]", {'\305','\0'}, SymbolString}, /*ISOamsb, plus sign in circle */
|
|
{"[or ]", {'\332','\0'}, SymbolString}, /*ISOtech, vee, logical or */
|
|
{"[ordf ]", {'\252','\0'}, IsoString }, /*ISOnum , ordinal indicator, fem*/
|
|
{"[ordm ]", {'\272','\0'}, IsoString }, /*ISOnum , ordinal indicator,male*/
|
|
{"[oslash]", {'\370','\0'}, IsoString }, /*ISOlat1, small o, slash */
|
|
{"[osol ]", {'\306','\0'}, SymbolString}, /*ISOamsb, slash in circle */
|
|
{"[otilde]", {'\365','\0'}, IsoString }, /*ISOlat1, small o, tilde */
|
|
{"[otimes]", {'\304','\0'}, SymbolString}, /*ISOamsb,multiply sign in circle*/
|
|
{"[ouml ]", {'\366','\0'}, IsoString }, /*ISOlat1, small o, umlaut mark */
|
|
{"[over ]", {'\140','\0'}, SymbolString}, /*made up, over symbol */
|
|
{"[par ]", {'\275', '\275', '\0'},
|
|
SymbolString}, /*ISOtech, parallel */
|
|
{"[para ]", {'\266','\0'}, IsoString }, /*ISOnum , paragraph sign */
|
|
{"[part ]", {'\266','\0'}, SymbolString}, /*ISOtech, partial differential */
|
|
{"[percnt]", { '%' ,'\0'}, IsoString }, /*ISOnum , percent sign */
|
|
{"[period]", { '.' ,'\0'}, IsoString }, /*ISOnum , full stop, period */
|
|
{"[perp ]", {'\136','\0'}, SymbolString}, /*ISOtech, perpendicular */
|
|
{"[phis ]", {'\146','\0'}, SymbolString}, /*ISOgrk3, Greek, small phi */
|
|
{"[pi ]", {'\160','\0'}, SymbolString}, /*ISOgrk3, Greek, small pi */
|
|
{"[piv ]", {'\166','\0'}, SymbolString}, /*ISOgrk3, Greek, small pi, var */
|
|
{"[plus ]", { '+' ,'\0'}, IsoString }, /*ISOnum , plus sign */
|
|
{"[plusmn]", {'\261','\0'}, SymbolString}, /*ISOnum , plus or minus sign */
|
|
{"[pound ]", {'\243','\0'}, IsoString }, /*ISOnum , pound sign */
|
|
{"[prime ]", {'\242','\0'}, SymbolString}, /*ISOtech, prime or minute */
|
|
{"[prop ]", {'\265','\0'}, SymbolString}, /*ISOtech, proportional to */
|
|
{"[psi ]", {'\171','\0'}, SymbolString}, /*ISOgrk3, Greek, small psi */
|
|
{"[quest ]", { '?' ,'\0'}, IsoString }, /*ISOnum , question mark */
|
|
{"[quot ]", { '\'' ,'\0'}, IsoString }, /*ISOnum , quote mark */
|
|
{"[radic ]", {'\326','\0'}, SymbolString}, /*ISOtech, radical */
|
|
{"[rang ]", {'\361','\0'}, SymbolString}, /*ISOtech, right angle bracket */
|
|
{"[raquo ]", {'\273','\0'}, IsoString }, /*ISOnum , right angle quotation */
|
|
{"[rarr ]", {'\256','\0'}, SymbolString}, /*ISOnum , rightward arrow */
|
|
{"[rArr ]", {'\336','\0'}, SymbolString}, /*ISOtech, rt dbl arrow,implies */
|
|
{"[rcub ]", { '}' ,'\0'}, IsoString }, /*ISOnum , right curly brace */
|
|
{"[rdquo ]", { '"' ,'\0'}, IsoString }, /*ISOnum , right double quote */
|
|
{"[real ]", {'\302','\0'}, SymbolString}, /*ISOamso, real number symbol */
|
|
{"[reg ]", {'\322','\0'}, SymbolString}, /*ISOnum,circledR,registered sign*/
|
|
{"[rho ]", {'\162','\0'}, SymbolString}, /*ISOgrk3, Greek, small rho */
|
|
{"[rpar ]", { ')' ,'\0'}, IsoString }, /*ISOnum , right parenthesis */
|
|
{"[rsqb ]", { ']' ,'\0'}, IsoString }, /*ISOnum , right square bracket */
|
|
{"[rsquo ]", { '\'' ,'\0'}, IsoString }, /*ISOnum , right single quote */
|
|
{"[sect ]", {'\247','\0'}, IsoString }, /*ISOnum , section sign */
|
|
{"[semi ]", { ';' ,'\0'}, IsoString }, /*ISOnum , semicolon */
|
|
{"[shy ]", {'\255','\0'}, IsoString }, /*ISOnum , soft hypen */
|
|
{"[sigma ]", {'\163','\0'}, SymbolString}, /*ISOgrk3, Greek, small sigma */
|
|
{"[sim ]", { '~' ,'\0'}, IsoString }, /*ISOtech, similar to */
|
|
{"[sime ]", {'\100','\0'}, SymbolString}, /*ISOtech, similar, equals */
|
|
{"[sol ]", { '/' ,'\0'}, IsoString }, /*ISOnum , solidus */
|
|
{"[spades]", {'\252','\0'}, SymbolString}, /*ISOpub , spades suit symbol */
|
|
{"[sub ]", {'\314','\0'}, SymbolString}, /*ISOtech, subset/is implied by */
|
|
{"[sube ]", {'\315','\0'}, SymbolString}, /*ISOtech, subset, equals */
|
|
/*"[sung ]", { ?? ,'\0'}, }, /*ISOnum , musical note(sung txt)*/
|
|
{"[sup ]", {'\311','\0'}, SymbolString}, /*ISOtech, superset or implies */
|
|
{"[sup1 ]", {'\271','\0'}, IsoString }, /*ISOnum , superscript one */
|
|
{"[sup2 ]", {'\262','\0'}, IsoString }, /*ISOnum , superscript two */
|
|
{"[sup3 ]", {'\263','\0'}, IsoString }, /*ISOnum , superscript three */
|
|
{"[supe ]", {'\312','\0'}, SymbolString}, /*ISOtech, superset, equals */
|
|
{"[szlig ]", {'\337','\0'}, IsoString }, /*ISOlat1, small sharp s, German */
|
|
{"[tau ]", {'\164','\0'}, SymbolString}, /*ISOgrk3, Greek, small tau */
|
|
{"[there4]", {'\134','\0'}, SymbolString}, /*ISOtech, therefore */
|
|
{"[thetas]", {'\161','\0'}, SymbolString}, /*ISOgrk3, Greek, small theta */
|
|
{"[thetav]", {'\112','\0'}, SymbolString}, /*ISOgrk3, Greek, small theta,var*/
|
|
{"[times ]", {'\264','\0'}, SymbolString}, /*ISOnum , multipy sign */
|
|
{"[thorn ]", {'\376','\0'}, IsoString }, /*ISOlat1, small thorn, Icelandic*/
|
|
{"[tprime]", {'\242', '\242', '\242', '\0'},
|
|
SymbolString}, /*ISOtech, triple prime */
|
|
{"[trade ]", {'\324','\0'}, SymbolString}, /*ISOnum , trade mark sign */
|
|
{"[uarr ]", {'\255','\0'}, SymbolString}, /*ISOnum , upward arrow */
|
|
{"[uArr ]", {'\335','\0'}, SymbolString}, /*ISOamsa, up double arrow */
|
|
{"[uacute]", {'\372','\0'}, IsoString }, /*ISOlat1, small u, acute accent */
|
|
{"[ucirc ]", {'\373','\0'}, IsoString }, /*ISOlat1, small u, circumflex */
|
|
{"[ugrave]", {'\371','\0'}, IsoString }, /*ISOlat1, small u, grave accent */
|
|
{"[upsi ]", {'\165','\0'}, SymbolString}, /*ISOgrk3, Greek, small upsilon */
|
|
{"[uuml ]", {'\374','\0'}, IsoString }, /*ISOlat1, small u, umlaut mark */
|
|
{"[vellip]", {':','\n',':','\0'},
|
|
SymbolString}, /*ISOpub , vertical ellipsis */
|
|
{"[verbar]", {'\174','\0'}, IsoString }, /*ISOnum , vertical bar */
|
|
{"[weierp]", {'\303','\0'}, SymbolString}, /*ISOamso, Weierstrass p */
|
|
{"[xi ]", {'\170','\0'}, SymbolString}, /*ISOgrk3, Greek, small xi */
|
|
{"[yacute]", {'\375','\0'}, IsoString }, /*ISOlat1, small y, acute accent */
|
|
{"[yen ]", {'\245','\0'}, IsoString }, /*ISOnum , yen sign */
|
|
{"[yuml ]", {'\377','\0'}, IsoString }, /*ISOlat1, small y, umlaut mark */
|
|
{"[zeta ]", {'\172','\0'}, SymbolString}, /*ISOgrk3, Greek, small zeta */
|
|
|
|
{"[Aacute]", {'\301','\0'}, IsoString }, /*ISOlat1, capital a,acute accent*/
|
|
{"[Acirc ]", {'\302','\0'}, IsoString }, /*ISOlat1, capital a,circumflex */
|
|
{"[AElig ]", {'\306','\0'}, IsoString }, /*ISOlat1, capital ae diphthong */
|
|
{"[Agrave]", {'\300','\0'}, IsoString }, /*ISOlat1, capital a,grave accent*/
|
|
{"[Aring ]", {'\305','\0'}, IsoString }, /*ISOlat1, capital a,ring */
|
|
{"[Atilde]", {'\303','\0'}, IsoString }, /*ISOlat1, capital a,tilde */
|
|
{"[Auml ]", {'\304','\0'}, IsoString }, /*ISOlat1, capital a,umlaut mark */
|
|
{"[Ccedil]", {'\307','\0'}, IsoString }, /*ISOlat1, capital c, cedilla */
|
|
{"[Delta ]", {'\104','\0'}, SymbolString}, /*ISOgrk3, Greek, large delta */
|
|
{"[Dot ]", {'\250','\0'}, IsoString }, /*ISOtech, dieresis or umlaut mrk*/
|
|
{"[DotDot]", {'\250', '\250', '\0'},
|
|
IsoString }, /*ISOtech, four dots above */
|
|
{"[Eacute]", {'\311','\0'}, IsoString }, /*ISOlat1, capital E,acute accent*/
|
|
{"[Ecirc ]", {'\312','\0'}, IsoString }, /*ISOlat1, capital E,circumflex */
|
|
{"[Egrave]", {'\310','\0'}, IsoString }, /*ISOlat1, capital E,grave accent*/
|
|
{"[ETH ]", {'\320','\0'}, IsoString }, /*ISOlat1, capital Eth, Icelandic*/
|
|
{"[Euml ]", {'\313','\0'}, IsoString }, /*ISOlat1, capital E,umlaut mark */
|
|
{"[Gamma ]", {'\107','\0'}, SymbolString}, /*ISOgrk3, Greek, large gamma */
|
|
{"[Iacute]", {'\315','\0'}, IsoString }, /*ISOlat1, capital I,acute accent*/
|
|
{"[Icirc ]", {'\316','\0'}, IsoString }, /*ISOlat1, capital I,circumflex */
|
|
{"[Igrave]", {'\314','\0'}, IsoString }, /*ISOlat1, capital I,grave accent*/
|
|
{"[Iuml ]", {'\317','\0'}, IsoString }, /*ISOlat1, capital I,umlaut mark */
|
|
{"[Lambda]", {'\114','\0'}, SymbolString}, /*ISOgrk3, Greek, large lambda */
|
|
{"[Ntilde]", {'\321','\0'}, IsoString }, /*ISOlat1, capital N, tilde */
|
|
{"[Oacute]", {'\323','\0'}, IsoString }, /*ISOlat1, capital O,acute accent*/
|
|
{"[Ocirc ]", {'\324','\0'}, IsoString }, /*ISOlat1, capital O,circumflex */
|
|
{"[Ograve]", {'\322','\0'}, IsoString }, /*ISOlat1, capital O,grave accent*/
|
|
{"[Oslash]", {'\330','\0'}, IsoString }, /*ISOlat1, capital O, slash */
|
|
{"[Otilde]", {'\325','\0'}, IsoString }, /*ISOlat1, capital O, tilde */
|
|
{"[Omega ]", {'\127','\0'}, SymbolString}, /*ISOgrk3, Greek, large omega */
|
|
{"[Ouml ]", {'\326','\0'}, IsoString }, /*ISOlat1, capital O,umlaut mark */
|
|
{"[Pi ]", {'\120','\0'}, SymbolString}, /*ISOgrk3, Greek, large pi */
|
|
{"[Prime ]", {'\262','\0'}, SymbolString}, /*ISOtech, double prime/second */
|
|
{"[Phi ]", {'\106','\0'}, SymbolString}, /*ISOgrk3, Greek, large phi */
|
|
{"[Psi ]", {'\131','\0'}, SymbolString}, /*ISOgrk3, Greek, large psi */
|
|
{"[Sigma ]", {'\123','\0'}, SymbolString}, /*ISOgrk3, Greek, large sigma */
|
|
{"[THORN ]", {'\336','\0'}, IsoString }, /*ISOlat1,capital THORN,Icelandic*/
|
|
{"[Theta ]", {'\121','\0'}, SymbolString}, /*ISOgrk3, Greek, large theta */
|
|
{"[Uacute]", {'\332','\0'}, IsoString }, /*ISOlat1, capital U,acute accent*/
|
|
{"[Ucirc ]", {'\333','\0'}, IsoString }, /*ISOlat1, capital U,circumflex */
|
|
{"[Ugrave]", {'\331','\0'}, IsoString }, /*ISOlat1, capital U,grave accent*/
|
|
{"[Upsi ]", {'\125','\0'}, SymbolString}, /*ISOgrk3, Greek, large upsilon */
|
|
{"[Uuml ]", {'\334','\0'}, IsoString }, /*ISOlat1, capital U,umlaut mark */
|
|
{"[Verbar]", {'\174', '\174', '\0'},
|
|
IsoString }, /*ISOtech, dbl vertical bar */
|
|
{"[Xi ]", {'\130','\0'}, SymbolString}, /*ISOgrk3, Greek, large xi */
|
|
{"[Yacute]", {'\335','\0'}, IsoString }, /*ISOlat1, capital Y,acute accent*/
|
|
{ NULL , {' ' ,'\0'}, IsoString }, /* default character to use */
|
|
};
|
|
|
|
|
|
/*****************************************************************************
|
|
* Semi-Private Variables
|
|
*****************************************************************************/
|
|
/*****************************************************************************
|
|
* Private Functions
|
|
*****************************************************************************/
|
|
/*****************************************************************************
|
|
* Function: _DtCvUnit GetTocIndicator(pDAS);
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static _DtHelpFontHints DefFontAttrs = {
|
|
NULL, NULL,
|
|
10, 10, NULL,
|
|
NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL,
|
|
_DtHelpFontStyleSerif,
|
|
_DtHelpFontSpacingProp,
|
|
_DtHelpFontWeightMedium,
|
|
_DtHelpFontSlantRoman,
|
|
_DtHelpFontSpecialNone };
|
|
|
|
static void
|
|
GetTocIndicator (
|
|
DtHelpDispAreaStruct *pDAS)
|
|
{
|
|
_DtCvUnit ascent;
|
|
|
|
pDAS->toc_width = 0;
|
|
pDAS->toc_height = 0;
|
|
pDAS->toc_indicator = NULL;
|
|
if (_DtHelpDAResolveSpc (pDAS, "C", IsoString, DefFontAttrs, "[rArr ]",
|
|
&(pDAS->toc_indicator), &(pDAS->toc_width),
|
|
&(pDAS->toc_height), &ascent))
|
|
_DtHelpDAResolveSpc (pDAS, "C", IsoString, DefFontAttrs, "[ndash ]",
|
|
&(pDAS->toc_indicator), &(pDAS->toc_width),
|
|
&(pDAS->toc_height), &ascent);
|
|
}
|
|
|
|
static void
|
|
ClearTocMarker (
|
|
DtHelpDispAreaStruct *pDAS,
|
|
_DtCvFlags flag)
|
|
{
|
|
_DtCvUnit clearHeight;
|
|
_DtCvUnit clearWidth;
|
|
_DtCvUnit clearY = pDAS->toc_y + pDAS->decorThickness
|
|
- pDAS->firstVisible;
|
|
_DtCvUnit clearX = pDAS->decorThickness - pDAS->virtualX;
|
|
|
|
clearHeight = pDAS->toc_height;
|
|
clearWidth = pDAS->toc_width;
|
|
|
|
if (clearY < pDAS->decorThickness)
|
|
{
|
|
clearHeight = clearHeight - pDAS->decorThickness + clearY;
|
|
clearY = pDAS->decorThickness;
|
|
}
|
|
if (clearX < pDAS->decorThickness)
|
|
{
|
|
clearWidth = clearWidth - pDAS->decorThickness + clearX;
|
|
clearX = pDAS->decorThickness;
|
|
}
|
|
|
|
if (clearWidth > 0 && clearHeight > 0)
|
|
{
|
|
if (IsSelected(flag))
|
|
XFillRectangle (XtDisplay(pDAS->dispWid), XtWindow(pDAS->dispWid),
|
|
pDAS->invertGC,
|
|
clearX, clearY, clearWidth, clearHeight);
|
|
else
|
|
XClearArea(XtDisplay(pDAS->dispWid), XtWindow(pDAS->dispWid),
|
|
clearX, clearY, clearWidth, clearHeight, False);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void DrawTocIndicator ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static void
|
|
DrawTocIndicator (
|
|
DtHelpDispAreaStruct *pDAS,
|
|
_DtCvFlags flag)
|
|
{
|
|
|
|
if (XtIsRealized(pDAS->dispWid)
|
|
&& TocIsOn(pDAS->toc_flag)
|
|
&& ((int)(pDAS->toc_y+pDAS->toc_height)) >= ((int) pDAS->firstVisible)
|
|
&& ((int)pDAS->toc_y) < ((int)(pDAS->firstVisible+pDAS->dispUseHeight))
|
|
&& pDAS->toc_indicator)
|
|
{
|
|
_DtHelpDARegion *regInfo = (_DtHelpDARegion *) pDAS->toc_indicator;
|
|
|
|
DADrawSpc (((_DtCvPointer) pDAS), regInfo->handle,
|
|
0, pDAS->toc_base,
|
|
0, pDAS->toc_y,
|
|
pDAS->toc_height, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void DrawTraversal ();
|
|
*
|
|
* Parameters:
|
|
* pDAS Specifies the display area.
|
|
* dst_x Specifies the inside boundary of the segment.
|
|
* This is where the segment starts, so the
|
|
* traversal box must end at dst_x - 1.
|
|
* dst_y Specifies the upper pixel that the traversal
|
|
* will cover.
|
|
* width Specifies the inner width of the traversal box.
|
|
* height Specifies the outer height of the traversal box
|
|
* including the leading. But since the leading is
|
|
* also used for the bottom traversal line, its
|
|
* okay.
|
|
* flag Specifies whether to turn the traversal box on
|
|
* or off.
|
|
*
|
|
* Returns: Nothing.
|
|
*
|
|
* Purpose: Draw the traversal box.
|
|
*
|
|
*****************************************************************************/
|
|
static void
|
|
DrawTraversal (
|
|
DtHelpDispAreaStruct *pDAS,
|
|
_DtCvUnit dst_x,
|
|
_DtCvUnit dst_y,
|
|
_DtCvUnit width,
|
|
_DtCvUnit height,
|
|
_DtCvFlags flag)
|
|
{
|
|
int copyY1;
|
|
int copyY2;
|
|
|
|
int lineX1;
|
|
int lineY1;
|
|
int lineX2;
|
|
int lineY2;
|
|
|
|
int onLeftTop;
|
|
int onRightBot;
|
|
Display *dpy = XtDisplay(pDAS->dispWid);
|
|
Window win = XtWindow(pDAS->dispWid);
|
|
|
|
if (pDAS->neededFlags & _DT_HELP_FOCUS_FLAG)
|
|
{
|
|
XGCValues saved, gc_values;
|
|
/*
|
|
* SYSTEM
|
|
* see the SYSTEM note in XUICreate.c
|
|
*/
|
|
/*
|
|
* how many pixels will be above or to the left of the
|
|
* destination position.
|
|
*/
|
|
onLeftTop = pDAS->lineThickness / 2;
|
|
|
|
/*
|
|
* how many pixels will be on and inside the destination.
|
|
*/
|
|
onRightBot = pDAS->lineThickness - onLeftTop;
|
|
|
|
/*
|
|
* calculate the y position of the traversal lines
|
|
* for the top and bottom lines.
|
|
*/
|
|
lineY1 = dst_y + onLeftTop;
|
|
lineY2 = dst_y + height - onRightBot;
|
|
|
|
/*
|
|
* get the extreme y positions.
|
|
*/
|
|
copyY1 = dst_y;
|
|
copyY2 = dst_y + height;
|
|
|
|
/*
|
|
* adjust the source and destination positions.
|
|
*/
|
|
lineX1 = dst_x;
|
|
if (IsTraversalBegin (flag))
|
|
lineX1 = lineX1 - onRightBot;
|
|
|
|
lineX2 = dst_x + width;
|
|
if (IsTraversalEnd (flag))
|
|
lineX2 = lineX2 + onLeftTop;
|
|
|
|
XGetGCValues(dpy, pDAS->normalGC, GCLineStyle | GCForeground, &saved);
|
|
gc_values.line_style = saved.line_style;
|
|
if (HasTraversal(flag)) {
|
|
if (flag & _DtCvAPP_FLAG2) {
|
|
XSetForeground (dpy, pDAS->normalGC, pDAS->searchColor);
|
|
gc_values.line_style = LineOnOffDash;
|
|
}
|
|
else
|
|
XSetForeground (dpy, pDAS->normalGC, pDAS->traversalColor);
|
|
}
|
|
else
|
|
XSetForeground (dpy, pDAS->normalGC, pDAS->backgroundColor);
|
|
|
|
if (gc_values.line_style != saved.line_style)
|
|
XChangeGC(dpy, pDAS->normalGC, GCLineStyle, &gc_values);
|
|
|
|
/*
|
|
* draw the top and bottom lines
|
|
*/
|
|
if (lineX1 - onLeftTop < ((int) pDAS->dispWidth) &&
|
|
lineX2 + onRightBot - 1 > 0)
|
|
{
|
|
/*
|
|
* draw the top line
|
|
*/
|
|
if (copyY1 < ((int) pDAS->dispHeight) &&
|
|
copyY1 + ((int)pDAS->lineThickness) >
|
|
((int)pDAS->decorThickness))
|
|
XDrawLine(dpy,win,pDAS->normalGC,lineX1,lineY1,lineX2,lineY1);
|
|
|
|
/*
|
|
* draw the bottom line
|
|
*/
|
|
if (copyY2 - ((int)pDAS->lineThickness) < ((int)pDAS->dispHeight)
|
|
&& copyY2 > ((int)pDAS->decorThickness))
|
|
XDrawLine(dpy,win,pDAS->normalGC,lineX1,lineY2,lineX2,lineY2);
|
|
}
|
|
|
|
/*
|
|
* draw the left end
|
|
*/
|
|
if (IsTraversalBegin(flag)
|
|
&& lineX1 - onLeftTop < ((int)pDAS->dispWidth)
|
|
&& lineX1 + onRightBot - 1 > 0
|
|
&& copyY1 < ((int) pDAS->dispHeight)
|
|
&& copyY2 > ((int)pDAS->decorThickness))
|
|
XDrawLine(dpy, win, pDAS->normalGC, lineX1, copyY1, lineX1, copyY2);
|
|
|
|
/*
|
|
* draw the right end
|
|
*/
|
|
if (IsTraversalEnd(flag)
|
|
&& lineX2 - onLeftTop < ((int) pDAS->dispWidth)
|
|
&& lineX2 + onRightBot - 1 > 0
|
|
&& copyY1 < ((int) pDAS->dispHeight)
|
|
&& copyY2 > ((int) pDAS->decorThickness))
|
|
XDrawLine(dpy, win, pDAS->normalGC, lineX2, copyY1, lineX2, copyY2);
|
|
|
|
XSetForeground (dpy, pDAS->normalGC, saved.foreground);
|
|
XSetFillStyle(dpy, pDAS->normalGC, FillSolid);
|
|
|
|
if (gc_values.line_style != saved.line_style)
|
|
XChangeGC(dpy, pDAS->normalGC, GCLineStyle, &saved);
|
|
}
|
|
}
|
|
|
|
static void
|
|
DrawSearchTraversal(DtHelpDispAreaStruct* pDAS,
|
|
_DtCvUnit dst_x, _DtCvUnit dst_y,
|
|
_DtCvUnit width, _DtCvUnit height, _DtCvFlags flag)
|
|
{
|
|
short save = pDAS->neededFlags;
|
|
|
|
pDAS->neededFlags |= _DT_HELP_FOCUS_FLAG;
|
|
|
|
DrawTraversal(pDAS, dst_x, dst_y, width, height, flag);
|
|
|
|
pDAS->neededFlags = save;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void MyDrawString (Display *dpy, Drawable d, GC gc,
|
|
* int font_index,
|
|
* int x, int y, char *string, int length,
|
|
* int wc, DtHelpDAFontInfo font_info)
|
|
*
|
|
* Parameters:
|
|
* dpy Specifies the connection to the X Server.
|
|
* d Specifies the drawable.
|
|
* gc Specifies the graphic's context.
|
|
* font_index Specifies the font structure or set to use.
|
|
* If the value is positive, it indicates a
|
|
* font structure. If negative, it indicates
|
|
* a font set.
|
|
* x Specifies the x coordinate.
|
|
* y Specifies the y coordinate.
|
|
* string Specifies the string to render.
|
|
* length Specifies the number of bytes in 'string'
|
|
* to render.
|
|
* wc Flag to designate wide character data
|
|
*
|
|
* Return Value: Nothing
|
|
*
|
|
* Purpose: Renders an text string to the specified drawable.
|
|
*
|
|
*****************************************************************************/
|
|
static void
|
|
MyDrawString (
|
|
Display *dpy,
|
|
Drawable d,
|
|
GC gc,
|
|
long font_index,
|
|
long x,
|
|
long y,
|
|
const void *string,
|
|
int length,
|
|
int wc,
|
|
int image,
|
|
DtHelpDAFontInfo font_info)
|
|
{
|
|
|
|
/*
|
|
* If the 'font_index' is a negative number, it indicates a font set was
|
|
* opened for this string. Use the X11R5 I18N routines to render the
|
|
* glyphs. Otherwise use the standard X11 drawing routines.
|
|
*/
|
|
|
|
if (font_index < 0)
|
|
{
|
|
XFontSet mySet;
|
|
|
|
mySet = __DtHelpFontSetGet(font_info, font_index);
|
|
|
|
if (wc) {
|
|
if (image)
|
|
XwcDrawImageString(dpy, d, mySet, gc, x, y,
|
|
(wchar_t*)string, length);
|
|
else
|
|
XwcDrawString (dpy, d, mySet, gc, x, y,
|
|
(wchar_t*)string, length);
|
|
}
|
|
else {
|
|
/*
|
|
* have to use XmbDrawString here instead of XDrawString
|
|
* because we need to use a font set to render the string.
|
|
*/
|
|
if (image)
|
|
XmbDrawImageString (dpy, d, mySet, gc, x, y, string, length);
|
|
else
|
|
XmbDrawString (dpy, d, mySet, gc, x, y, string, length);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XFontStruct *myFont;
|
|
|
|
myFont = __DtHelpFontStructGet(font_info, font_index);
|
|
XSetFont (dpy, gc, myFont->fid);
|
|
|
|
if (image)
|
|
XDrawImageString (dpy, d, gc, x, y, string, length);
|
|
else
|
|
XDrawString (dpy, d, gc, x, y, string, length);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void ResolveFont ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static int
|
|
ResolveFont (
|
|
_DtCvPointer client_data,
|
|
char *lang,
|
|
const char *charset,
|
|
_DtHelpFontHints font_attr,
|
|
long *ret_idx )
|
|
{
|
|
int result = -1;
|
|
char *xlfdSpec = font_attr.xlfd;
|
|
char buffer[10];
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
XrmName xrmList[_DtHelpFontQuarkNumber];
|
|
|
|
_DtHelpCopyDefaultList(xrmList);
|
|
|
|
if (font_attr.spacing != _DtHelpFontSpacingProp)
|
|
xrmList[_DT_HELP_FONT_SPACING] = XrmStringToQuark("m");
|
|
|
|
sprintf(buffer, "%d", font_attr.pointsz);
|
|
xrmList[_DT_HELP_FONT_SIZE] = XrmStringToQuark(buffer);
|
|
|
|
if (font_attr.slant != _DtHelpFontSlantRoman)
|
|
{
|
|
xrmList[_DT_HELP_FONT_ANGLE] = XrmStringToQuark("italic");
|
|
if (font_attr.xlfdi != NULL)
|
|
xlfdSpec = font_attr.xlfdi;
|
|
}
|
|
|
|
if (font_attr.weight == _DtHelpFontWeightBold)
|
|
{
|
|
xrmList[_DT_HELP_FONT_WEIGHT] = XrmStringToQuark("bold");
|
|
if (xrmList[_DT_HELP_FONT_ANGLE] == XrmStringToQuark("italic"))
|
|
{
|
|
if (font_attr.xlfdib != NULL)
|
|
xlfdSpec = font_attr.xlfdib;
|
|
}
|
|
else if (font_attr.xlfdb != NULL)
|
|
xlfdSpec = font_attr.xlfdb;
|
|
}
|
|
|
|
if (font_attr.style == _DtHelpFontStyleSerif)
|
|
xrmList[_DT_HELP_FONT_TYPE] = XrmStringToQuark("serif");
|
|
else if (font_attr.style == _DtHelpFontStyleSymbol)
|
|
xrmList[_DT_HELP_FONT_TYPE] = XrmStringToQuark("symbol");
|
|
|
|
xrmList[_DT_HELP_FONT_LANG_TER] = XrmStringToQuark ("C");
|
|
if (lang != NULL)
|
|
xrmList[_DT_HELP_FONT_LANG_TER] = XrmStringToQuark(lang);
|
|
|
|
if (charset != NULL)
|
|
xrmList[_DT_HELP_FONT_CHAR_SET] = XrmStringToQuark(charset);
|
|
|
|
if (NULL == xlfdSpec ||
|
|
_DtHelpGetExactFontIndex(pDAS,lang,charset,xlfdSpec,ret_idx)!=0)
|
|
result = __DtHelpFontIndexGet (pDAS, xrmList, ret_idx);
|
|
|
|
return result;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void DADrawLine ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static void
|
|
DADrawLine (
|
|
_DtCvPointer client_data,
|
|
_DtCvUnit x1,
|
|
_DtCvUnit y1,
|
|
_DtCvUnit x2,
|
|
_DtCvUnit y2,
|
|
_DtCvUnit line_width)
|
|
{
|
|
int offset;
|
|
Display *dpy;
|
|
Window win;
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
XGCValues saved, gcValues;
|
|
|
|
gcValues.line_width = line_width;
|
|
offset = line_width / 2;
|
|
dpy = XtDisplay(pDAS->dispWid);
|
|
win = XtWindow(pDAS->dispWid);
|
|
|
|
/*
|
|
* get the current value of the gc.
|
|
*/
|
|
XGetGCValues(dpy, pDAS->normalGC, GCLineWidth, &saved);
|
|
|
|
/*
|
|
* does the old line width equal the width we want?
|
|
* If no, then change it to the desired width.
|
|
*/
|
|
if (line_width != saved.line_width)
|
|
XChangeGC(dpy, pDAS->normalGC, GCLineWidth, &gcValues);
|
|
|
|
/*
|
|
* drawing a horizontal line?
|
|
*/
|
|
if (x1 == x2)
|
|
{
|
|
x1 += offset;
|
|
x2 = x1;
|
|
}
|
|
else
|
|
{
|
|
y1 += offset;
|
|
y2 = y1;
|
|
}
|
|
|
|
y1 = y1 + pDAS->decorThickness - pDAS->firstVisible;
|
|
x1 = x1 + pDAS->decorThickness - pDAS->virtualX;
|
|
|
|
y2 = y2 + pDAS->decorThickness - pDAS->firstVisible;
|
|
x2 = x2 + pDAS->decorThickness - pDAS->virtualX;
|
|
|
|
XDrawLine (dpy, win, pDAS->normalGC, x1, y1, x2, y2);
|
|
|
|
/*
|
|
* did we change the gc's line_width? If so, change it back.
|
|
*/
|
|
if (line_width != saved.line_width)
|
|
XChangeGC(dpy, pDAS->normalGC, GCLineWidth, &saved);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void DADrawString ();
|
|
*
|
|
* Parameters:
|
|
* client_data Specifies the client specific data
|
|
* associated with this canvas.
|
|
* x Specifies the x unit at which the
|
|
* string is to be rendered.
|
|
* y Specifes the y unit at which the baseline
|
|
* of the string is to be rendered.
|
|
* string Specifies the string to render.
|
|
* byte_len Specifies the number of bytes of the
|
|
* string to render.
|
|
* char_len Specifies the number of bytes that
|
|
* comprise one character.
|
|
* font_ptr Specifies the font associated with this
|
|
* string.
|
|
* box_x,box_y Specifies the upper left hand corner of
|
|
* the bounding box for this string. This
|
|
* includes any traversal and/or link offsets
|
|
* relevent for the line this segment occupies.
|
|
* box_height Specifies the maximum height of the bounding
|
|
* box for this string. This includes any
|
|
* traversal and/or offsets relevent to this
|
|
* line.
|
|
* old_flags Specifies .............
|
|
* new_flags Specifies .............
|
|
*
|
|
* Returns: Nothing
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static void
|
|
DADrawString (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer data,
|
|
_DtCvUnit x,
|
|
_DtCvUnit y,
|
|
const void *string,
|
|
int byte_len,
|
|
int wc,
|
|
_DtCvPointer font_ptr,
|
|
_DtCvPointer scd,
|
|
_DtCvUnit box_x,
|
|
_DtCvUnit box_y,
|
|
_DtCvUnit box_height,
|
|
_DtCvFlags old_flags,
|
|
_DtCvFlags new_flags )
|
|
{
|
|
Boolean image_flag = False;
|
|
int strWidth = 0;
|
|
int width;
|
|
Display *dpy;
|
|
Window win;
|
|
GC drawGC;
|
|
GC fillGC;
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
_DtCvStringClientData* pSCD = (_DtCvStringClientData*)scd;
|
|
|
|
unsigned long mask1 = 0x00; /* to be replaced with highlight attrs */
|
|
unsigned long mask2 = 0x00; /* to be replaced with stippling attrs */
|
|
XGCValues gcValues;
|
|
XGCValues saved1, saved2;
|
|
|
|
/*
|
|
* if this is outside our display area, ignore it.
|
|
*/
|
|
if (box_y + box_height < pDAS->firstVisible ||
|
|
box_y > pDAS->firstVisible + pDAS->dispHeight)
|
|
return;
|
|
|
|
y = y + pDAS->decorThickness - pDAS->firstVisible;
|
|
x = x + pDAS->decorThickness - pDAS->virtualX;
|
|
|
|
box_x = box_x + pDAS->decorThickness - pDAS->virtualX;
|
|
box_y = box_y + pDAS->decorThickness - pDAS->firstVisible;
|
|
|
|
if (byte_len)
|
|
strWidth = _DtHelpDAGetStrWidth(client_data, _DtCvSTRING_TYPE, data);
|
|
|
|
width = strWidth + (x - box_x);
|
|
|
|
dpy = XtDisplay(pDAS->dispWid);
|
|
win = XtWindow(pDAS->dispWid);
|
|
|
|
/*
|
|
* initial colors for rendering.
|
|
*/
|
|
drawGC = pDAS->normalGC;
|
|
fillGC = pDAS->invertGC;
|
|
|
|
/*
|
|
* is this a search hit or does this string have its own color?
|
|
*/
|
|
if (strWidth && pDAS->dtinfo &&
|
|
((new_flags & _DtCvSEARCH_FLAG) ||
|
|
(NULL != pSCD && (pSCD->fg_color || pSCD->bg_color))))
|
|
{
|
|
XColor screen, exact;
|
|
|
|
/*
|
|
* indicate that we are going to change the foreground and background.
|
|
*/
|
|
mask1 = (GCForeground | GCBackground);
|
|
mask2 = (GCForeground | GCBackground);
|
|
|
|
/*
|
|
* remember the current values of the gc.
|
|
*/
|
|
XGetGCValues(dpy, drawGC, mask1, &saved1);
|
|
XGetGCValues(dpy, fillGC, mask2, &saved2);
|
|
|
|
/* search highlight should precede stylesheet-driven highlights */
|
|
/*
|
|
* is the search flag set? Set the foreground to the search color.
|
|
*/
|
|
if (new_flags & _DtCvSEARCH_FLAG)
|
|
{
|
|
XSetForeground(dpy, drawGC, pDAS->searchColor);
|
|
XSetBackground(dpy, fillGC, pDAS->searchColor);
|
|
}
|
|
/*
|
|
* is there a foreground color specified?
|
|
*/
|
|
else if (pSCD->fg_color)
|
|
{
|
|
/*
|
|
* does the foreground color need allocating?
|
|
*/
|
|
if (pSCD->fg_pixel == (unsigned long)-1)
|
|
{
|
|
if (XAllocNamedColor(dpy, pDAS->colormap, pSCD->fg_color,
|
|
&screen, &exact))
|
|
{
|
|
XSetForeground(dpy, drawGC, screen.pixel);
|
|
XSetBackground(dpy, fillGC, screen.pixel);
|
|
}
|
|
else /* the allocation went badly */
|
|
{
|
|
mask1 &= ~GCForeground;
|
|
mask2 &= ~GCBackground;
|
|
}
|
|
}
|
|
else /* dtinfo has calculated pSCD->fg_pixel */
|
|
{
|
|
XSetForeground(dpy, drawGC, pSCD->fg_pixel);
|
|
XSetBackground(dpy, fillGC, pSCD->fg_pixel);
|
|
}
|
|
}
|
|
else /* no foreground color specified */
|
|
{
|
|
mask1 &= ~GCForeground;
|
|
mask2 &= ~GCBackground;
|
|
}
|
|
|
|
/*
|
|
* was a background color specified?
|
|
*/
|
|
if (pSCD->bg_color)
|
|
{
|
|
/*
|
|
* does the background color need allocating?
|
|
*/
|
|
if (pSCD->bg_pixel == (unsigned long)-1)
|
|
{
|
|
if (XAllocNamedColor(dpy, pDAS->colormap, pSCD->bg_color,
|
|
&screen, &exact))
|
|
{
|
|
XSetBackground(dpy, drawGC, screen.pixel);
|
|
XSetForeground(dpy, fillGC, screen.pixel);
|
|
}
|
|
else /* the allocation went badly */
|
|
{
|
|
mask1 &= ~GCBackground;
|
|
mask2 &= ~GCForeground;
|
|
}
|
|
}
|
|
else /* the background color's been allocated */
|
|
{
|
|
XSetBackground(dpy, drawGC, pSCD->bg_pixel);
|
|
XSetForeground(dpy, fillGC, pSCD->bg_pixel);
|
|
}
|
|
}
|
|
else /* no background color specified */
|
|
{
|
|
mask1 &= ~GCBackground;
|
|
mask2 &= ~GCForeground;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* if selected, reverse the foreground and background colors
|
|
*/
|
|
if (IsSelected(new_flags))
|
|
{
|
|
unsigned long tmpMsk;
|
|
GC tmpGC;
|
|
|
|
/*
|
|
* swap the gc's
|
|
*/
|
|
tmpGC = drawGC;
|
|
drawGC = fillGC;
|
|
fillGC = tmpGC;
|
|
|
|
/*
|
|
* swap the saved values!
|
|
*/
|
|
if (mask1 || mask2)
|
|
{
|
|
/*
|
|
* swap the masks!
|
|
*/
|
|
tmpMsk = mask1;
|
|
mask1 = mask2;
|
|
mask2 = tmpMsk;
|
|
|
|
/*
|
|
* swap the saved values
|
|
*/
|
|
gcValues = saved1;
|
|
saved1 = saved2;
|
|
saved2 = gcValues;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* if the segment had the hypertext/mark traversal, turn it off
|
|
* this has the added benefit of also turning of the search hit
|
|
* traversal.
|
|
*/
|
|
if (HasTraversal(old_flags))
|
|
DrawTraversal (pDAS, x, box_y, strWidth, box_height,
|
|
(old_flags & (~_DtCvTRAVERSAL_FLAG)));
|
|
|
|
/*
|
|
* band-aid for Search traversal support (since it isn't there).
|
|
* simply draw a negative search traversal (if the link traversal
|
|
* hasn't already blanked it out) for *every* search hit because
|
|
* it may have had the current search flag and now doesn't.
|
|
*/
|
|
else if (pDAS->dtinfo && (new_flags & _DtCvSEARCH_FLAG))
|
|
DrawSearchTraversal(pDAS, x, box_y, strWidth, box_height,
|
|
(new_flags & (~_DtCvTRAVERSAL_FLAG)) |
|
|
_DtCvTRAVERSAL_BEGIN | _DtCvTRAVERSAL_END);
|
|
|
|
/*
|
|
* if the item was selected or is selected, we need to draw the
|
|
* inverse video rectangle.
|
|
*/
|
|
if (IsSelected(new_flags) || IsSelected(old_flags)
|
|
|| IsMarkOn(new_flags) || IsMarkOn(old_flags))
|
|
image_flag = True;
|
|
|
|
/*
|
|
* do we need to allocate the stipple pattern?
|
|
*/
|
|
if (IsMarkOn(new_flags) && None == pDAS->stipple)
|
|
pDAS->stipple = XCreateBitmapFromData(dpy, win, root_weave_bits,
|
|
root_weave_width, root_weave_height);
|
|
|
|
|
|
/*
|
|
* do we need to draw a rectangle?
|
|
*/
|
|
if (image_flag)
|
|
{
|
|
_DtCvUnit eff_x, eff_width;
|
|
|
|
/*
|
|
* do we need to stipple the rectangle for marks?
|
|
*/
|
|
if (pDAS->dtinfo && IsMarkOn(new_flags) && None != pDAS->stipple)
|
|
{
|
|
/*
|
|
* include the fill style and stipple in the mask.
|
|
* it will be used later to restore the gc.
|
|
*
|
|
* Don't bother to reset the stipple pattern. As long
|
|
* as FillStyle is set to FillSolid (or FillTiled)
|
|
* the stipple is ignored.
|
|
*/
|
|
mask2 = mask2 | GCFillStyle;
|
|
XSetFillStyle(dpy, fillGC, FillOpaqueStippled);
|
|
XSetStipple(dpy, fillGC, pDAS->stipple);
|
|
|
|
/*
|
|
* initialize the saved fill_style and stipple fields
|
|
* to what they should be restored to.
|
|
*/
|
|
saved2.fill_style = FillSolid;
|
|
}
|
|
|
|
if (HasTraversal(new_flags) && IsTraversalEnd(new_flags))
|
|
width += pDAS->lineThickness;
|
|
|
|
eff_x = box_x;
|
|
eff_width = width;
|
|
|
|
if (pDAS->dtinfo) {
|
|
/*
|
|
* search rending info
|
|
*/
|
|
if (new_flags & _DtCvAPP_FLAG3) {
|
|
eff_x += pDAS->lineThickness;
|
|
eff_width -= pDAS->lineThickness;
|
|
}
|
|
else if (new_flags & _DtCvAPP_FLAG4)
|
|
eff_width += pDAS->lineThickness;
|
|
}
|
|
|
|
XFillRectangle (dpy, win, fillGC, eff_x, (int) box_y,
|
|
eff_width, box_height);
|
|
}
|
|
|
|
if (strWidth)
|
|
{
|
|
MyDrawString (dpy, win, drawGC,
|
|
(long) font_ptr,
|
|
(long) x, (long) y, string, byte_len,
|
|
wc, False, pDAS->font_info);
|
|
|
|
if (pDAS->dtinfo && NULL != pSCD) {
|
|
_DtCvUnit line_y;
|
|
if (pSCD->hilite_type & hilite_underline) {
|
|
line_y = box_y + box_height - pDAS->lineThickness / 2;
|
|
XDrawLine (dpy, win, drawGC, x, line_y, x + strWidth, line_y);
|
|
}
|
|
if (pSCD->hilite_type & hilite_strikethrough) {
|
|
line_y = box_y + box_height / 2;
|
|
XDrawLine (dpy, win, drawGC, x, line_y, x + strWidth, line_y);
|
|
}
|
|
if (pSCD->hilite_type & hilite_overline) {
|
|
line_y = box_y + pDAS->lineThickness / 2;
|
|
XDrawLine (dpy, win, drawGC, x, line_y, x + strWidth, line_y);
|
|
}
|
|
}
|
|
|
|
if (IsHyperLink(new_flags))
|
|
{
|
|
y = y + pDAS->underLine;
|
|
|
|
if (IsPopUp(new_flags))
|
|
{
|
|
gcValues.line_style = LineOnOffDash;
|
|
XChangeGC (dpy, drawGC, GCLineStyle, &gcValues);
|
|
}
|
|
|
|
XDrawLine (dpy, win, drawGC, (int) x, (int) y,
|
|
(int) (x + strWidth), (int) y);
|
|
|
|
if (IsPopUp(new_flags))
|
|
{
|
|
gcValues.line_style = LineSolid;
|
|
XChangeGC (dpy, drawGC, GCLineStyle, &gcValues);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* draw the traversal first
|
|
*/
|
|
if (HasTraversal(new_flags))
|
|
DrawTraversal (pDAS, x, box_y, strWidth, box_height, new_flags);
|
|
|
|
/*
|
|
* draw the search traversal
|
|
*/
|
|
if (pDAS->dtinfo && (new_flags & _DtCvAPP_FLAG2)) {
|
|
_DtCvFlags eff_flags = new_flags;
|
|
eff_flags |= _DtCvTRAVERSAL_FLAG;
|
|
if (new_flags & _DtCvSEARCH_BEGIN)
|
|
eff_flags |= _DtCvTRAVERSAL_BEGIN;
|
|
else
|
|
eff_flags &= ~_DtCvTRAVERSAL_BEGIN;
|
|
|
|
if (new_flags & _DtCvSEARCH_END)
|
|
eff_flags |= _DtCvTRAVERSAL_END;
|
|
else
|
|
eff_flags &= ~_DtCvTRAVERSAL_END;
|
|
|
|
DrawSearchTraversal(pDAS, x, box_y, strWidth, box_height, eff_flags);
|
|
}
|
|
|
|
/*
|
|
* restore the gcs.
|
|
*/
|
|
if (mask1)
|
|
XChangeGC(dpy, drawGC, mask1, &saved1);
|
|
if (mask2)
|
|
XChangeGC(dpy, fillGC, mask2, &saved2);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void DADrawSpc ();
|
|
*
|
|
* Parameters:
|
|
* client_data Specifies the client specific data
|
|
* associated with this canvas.
|
|
* spc_handle Specifies the handle of the special
|
|
* character to render.
|
|
* x Specifies the x unit at which the
|
|
* spc is to be rendered.
|
|
* y Specifes the y unit at which the baseline
|
|
* of the spc is to be rendered.
|
|
* box_x,box_y Specifies the upper left hand corner of
|
|
* the bounding box for this string. This
|
|
* includes any traversal and/or link offsets
|
|
* relevent for the line this segment occupies.
|
|
* box_height Specifies the maximum height of the bounding
|
|
* box for this string. This includes any
|
|
* traversal and/or offsets relevent to this
|
|
* line.
|
|
* link_type Specifies the link type if this spc is
|
|
* part of a link.
|
|
* old_flags Specifies .............
|
|
* new_flags Specifies .............
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static void
|
|
DADrawSpc (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer spc_handle,
|
|
_DtCvUnit x,
|
|
_DtCvUnit y,
|
|
_DtCvUnit box_x,
|
|
_DtCvUnit box_y,
|
|
_DtCvUnit box_height,
|
|
int link_type,
|
|
_DtCvFlags old_flags,
|
|
_DtCvFlags new_flags )
|
|
{
|
|
int i;
|
|
long spcLstIdx = (long) spc_handle;
|
|
_DtCvUnit ascent;
|
|
_DtCvUnit descent;
|
|
const char *spcStr;
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
_DtCvStringInfo strInfo;
|
|
|
|
if (pDAS->max_spc == 0)
|
|
return;
|
|
|
|
spcStr = SpcTable[pDAS->spc_chars[spcLstIdx].spc_idx].spc_string;
|
|
_DtHelpDAGetFontMetrics(client_data, pDAS->spc_chars[spcLstIdx].font_ptr,
|
|
&ascent, &descent, NULL, NULL, NULL);
|
|
|
|
do
|
|
{
|
|
/*
|
|
* display the string up to the next newline or backspace
|
|
*/
|
|
i = 0;
|
|
while ('\0' != spcStr[i] && '\n' != spcStr[i] && '\b' != spcStr[i])
|
|
i++;
|
|
|
|
strInfo.string = (void *) spcStr;
|
|
strInfo.byte_len = i;
|
|
strInfo.wc = 0;
|
|
strInfo.font_ptr = (_DtCvPointer)(pDAS->spc_chars[spcLstIdx].font_ptr);
|
|
|
|
DADrawString (client_data, (_DtCvPointer) &strInfo, x, y,
|
|
spcStr, i, 0,
|
|
pDAS->spc_chars[spcLstIdx].font_ptr, NULL,
|
|
box_x, box_y, box_height, old_flags,
|
|
new_flags);
|
|
|
|
/*
|
|
* if we are looking at a newline character, that means that
|
|
* the special character takes up several 'lines' of height.
|
|
* So increment the next y position to go to the next 'line'.
|
|
*/
|
|
if ('\n' == spcStr[i])
|
|
y = y + ascent + descent;
|
|
|
|
/*
|
|
* if we are looking at a newline or a backspace, skip over it.
|
|
*/
|
|
if ('\n' == spcStr[i] || '\b' == spcStr[i])
|
|
i++;
|
|
|
|
/*
|
|
* reset the string pointer.
|
|
*/
|
|
spcStr += i;
|
|
|
|
/*
|
|
* do this while there is any string to display.
|
|
*/
|
|
} while ('\0' != *spcStr);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void DADrawGraphic ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static void
|
|
DADrawGraphic (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer graphic_ptr,
|
|
_DtCvUnit x,
|
|
_DtCvUnit y,
|
|
_DtCvUnit box_width,
|
|
_DtCvUnit box_height,
|
|
_DtCvFlags old_flags,
|
|
_DtCvFlags new_flags )
|
|
{
|
|
int width;
|
|
int height;
|
|
int old_x;
|
|
int old_y;
|
|
int srcX;
|
|
int srcY;
|
|
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
DtHelpGraphicStruct *pGS = (DtHelpGraphicStruct *) graphic_ptr;
|
|
Display *dpy = XtDisplay(pDAS->dispWid);
|
|
Window win = XtWindow(pDAS->dispWid);
|
|
XGCValues gcValues;
|
|
|
|
/*
|
|
* adjust for the scrolled window.
|
|
*/
|
|
y = y + pDAS->decorThickness - pDAS->firstVisible;
|
|
x = x + pDAS->decorThickness - pDAS->virtualX;
|
|
|
|
/*
|
|
* save away.
|
|
*/
|
|
old_x = x;
|
|
old_y = y;
|
|
|
|
/*
|
|
* adjust to get the correct y position for the graphic.
|
|
*/
|
|
y = y + box_height - pGS->height - 1;
|
|
|
|
/*
|
|
* add the line thickness of the traversal to the height.
|
|
*/
|
|
if (HasTraversal(old_flags))
|
|
DrawTraversal (pDAS, old_x, old_y, pGS->width, box_height,
|
|
(old_flags & (~_DtCvTRAVERSAL_FLAG)));
|
|
|
|
srcX = 0;
|
|
srcY = 0;
|
|
width = pGS->width;
|
|
height = 0;
|
|
|
|
/*
|
|
* Check and adjust the width of the graphic if it is
|
|
* to be displayed
|
|
*/
|
|
if (x < 0)
|
|
{
|
|
srcX = srcX - x;
|
|
width = width + x;
|
|
x = 0;
|
|
}
|
|
|
|
if (width > 0)
|
|
{
|
|
height = pGS->height;
|
|
|
|
if (y < pDAS->decorThickness)
|
|
{
|
|
srcY = pDAS->decorThickness - y;
|
|
height -= srcY;
|
|
y = pDAS->decorThickness;
|
|
}
|
|
if (y + height > ((int)(pDAS->dispHeight - pDAS->decorThickness)))
|
|
height = pDAS->dispHeight - pDAS->decorThickness - y;
|
|
}
|
|
|
|
/*
|
|
* If we found something to write out,
|
|
* height and width will/should be greater than zero.
|
|
*/
|
|
if (height > 0 && width > 0)
|
|
XCopyArea (dpy, pGS->pix, win, pDAS->normalGC,
|
|
srcX, srcY, width, height, x, y);
|
|
|
|
|
|
if (HasTraversal(new_flags))
|
|
DrawTraversal (pDAS, old_x, old_y, pGS->width, box_height, new_flags);
|
|
|
|
else if (IsHyperLink(new_flags))
|
|
{
|
|
int x,y;
|
|
|
|
XSetFillStyle(dpy, pDAS->normalGC, FillTiled);
|
|
|
|
if (IsPopUp(new_flags))
|
|
{
|
|
gcValues.line_style = LineOnOffDash;
|
|
XChangeGC (dpy, pDAS->normalGC, GCLineStyle, &gcValues);
|
|
}
|
|
|
|
x = old_x + 2;
|
|
y = old_y + pDAS->lineThickness / 2;
|
|
|
|
XDrawLine(dpy, win, pDAS->normalGC, x, y, x + box_width - 4, y);
|
|
|
|
y = old_y + box_height - pDAS->lineThickness
|
|
+ pDAS->lineThickness / 2;
|
|
|
|
XDrawLine(dpy, win, pDAS->normalGC, x, y, x + box_width - 4, y);
|
|
|
|
y = old_y + 2;
|
|
x = old_x - pDAS->lineThickness + pDAS->lineThickness / 2;
|
|
|
|
XDrawLine(dpy, win, pDAS->normalGC, x, y, x, y + box_height - 4);
|
|
|
|
x = old_x + box_width + pDAS->lineThickness / 2;
|
|
|
|
XDrawLine(dpy, win, pDAS->normalGC, x, y, x, y + box_height - 4);
|
|
|
|
if (IsPopUp(new_flags))
|
|
{
|
|
gcValues.line_style = LineSolid;
|
|
XChangeGC (dpy, pDAS->normalGC, GCLineStyle, &gcValues);
|
|
}
|
|
XSetFillStyle(dpy, pDAS->normalGC, FillSolid);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: _DtCvPointer DABuildSelectedString ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static _DtCvStatus
|
|
DABuildSelectedString (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer *prev_info,
|
|
const char *string,
|
|
int byte_len,
|
|
int wc,
|
|
_DtCvPointer font_ptr,
|
|
_DtCvUnit space,
|
|
_DtCvFlags flags )
|
|
{
|
|
int i;
|
|
int j;
|
|
int mbLen;
|
|
int totalLen;
|
|
int spaceNum = 0;
|
|
int stringLen = 0;
|
|
long spaceLong = space * 10;
|
|
char *myString = (char *)(*prev_info);
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
|
|
if (spaceLong > 0)
|
|
spaceNum = (int) (spaceLong / pDAS->charWidth +
|
|
((spaceLong % pDAS->charWidth) < pDAS->charWidth / 2 ? 0 : 1));
|
|
|
|
if (string == NULL)
|
|
byte_len = 0;
|
|
|
|
/*
|
|
* if we are processing a wide character string, we need to
|
|
* allocate MB_CUR_MAX bytes per character
|
|
*/
|
|
mbLen = 1;
|
|
if (0 != wc)
|
|
mbLen = MB_CUR_MAX;
|
|
|
|
totalLen = byte_len * mbLen + spaceNum + 1 + (IsEndOfLine(flags) ? 1 : 0);
|
|
|
|
/*
|
|
* allocate the string
|
|
*/
|
|
if (myString == NULL)
|
|
myString = (char *) malloc (sizeof(char) * totalLen);
|
|
else
|
|
{
|
|
stringLen = strlen(myString);
|
|
myString = (char *) realloc ((void *) myString,
|
|
(sizeof(char) * (stringLen + totalLen)));
|
|
}
|
|
|
|
if (myString == NULL)
|
|
return _DtCvSTATUS_BAD;
|
|
|
|
/*
|
|
* tack on the leading spaces.
|
|
*/
|
|
for (i = stringLen; spaceNum > 0; spaceNum--)
|
|
myString[i++] = ' ';
|
|
|
|
/*
|
|
* now tack on the characters.
|
|
*/
|
|
if (0 != wc)
|
|
{
|
|
/*
|
|
* have to translate the wide character into a multi-byte
|
|
* character.
|
|
*/
|
|
wchar_t *wStr = (wchar_t *) string;
|
|
|
|
for (j = 0; 0 < byte_len; byte_len--)
|
|
{
|
|
/*
|
|
* convert the next character
|
|
*/
|
|
mbLen = wctomb(&myString[i], wStr[j++]);
|
|
|
|
/*
|
|
* if a valid character, increase the destination pointer
|
|
*/
|
|
if (0 <= mbLen)
|
|
i += mbLen;
|
|
}
|
|
}
|
|
else
|
|
/*
|
|
* transfer the single byte string to the destination string
|
|
*/
|
|
for (j = 0; byte_len > 0 && string[j] != '\0'; byte_len--)
|
|
myString[i++] = string[j++];
|
|
|
|
if (flags)
|
|
myString[i++] = '\n';
|
|
|
|
myString[i] = '\0';
|
|
|
|
*prev_info = (_DtCvPointer) myString;
|
|
|
|
return _DtCvSTATUS_OK;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: _DtCvPointer DABuildSelectedSpc ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
static _DtCvStatus
|
|
DABuildSelectedSpc (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer *prev_info,
|
|
_DtCvPointer spc_handle,
|
|
_DtCvUnit space,
|
|
_DtCvFlags flags )
|
|
{
|
|
long spcIdx = (long) spc_handle;
|
|
int i;
|
|
int totalLen;
|
|
int spaceNum = 0;
|
|
int stringLen = 0;
|
|
long spaceLong = space * 10;
|
|
const char *spcStr;
|
|
char *myString = (char *)(*prev_info);
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
|
|
/*
|
|
* find the ascii version of this spc
|
|
*/
|
|
spcIdx = pDAS->spc_chars[spcIdx].spc_idx;
|
|
spcStr = _DtHelpCeResolveSpcToAscii(SpcTable[spcIdx].symbol);
|
|
|
|
if (spcStr == NULL)
|
|
return _DtCvSTATUS_BAD;
|
|
|
|
/*
|
|
* get the length to realloc
|
|
*/
|
|
totalLen = strlen(spcStr);
|
|
|
|
if (spaceLong > 0)
|
|
spaceNum = (int)(spaceLong / pDAS->charWidth +
|
|
((spaceLong % pDAS->charWidth) < pDAS->charWidth / 2 ? 0 : 1));
|
|
|
|
totalLen = totalLen + spaceNum + 1 + (IsEndOfLine(flags) ? 1 : 0);
|
|
|
|
if (myString == NULL)
|
|
myString = (char *) malloc (sizeof(char) * totalLen);
|
|
else
|
|
{
|
|
stringLen = strlen(myString);
|
|
myString = (char *) realloc ((void *) myString,
|
|
(sizeof(char) * (stringLen + totalLen)));
|
|
}
|
|
|
|
if (myString == NULL)
|
|
return _DtCvSTATUS_BAD;
|
|
|
|
for (i = stringLen; spaceNum > 0; spaceNum--)
|
|
myString[i++] = ' ';
|
|
|
|
while (*spcStr != '\0')
|
|
myString[i++] = *spcStr++;
|
|
|
|
if (flags)
|
|
myString[i++] = '\n';
|
|
|
|
myString[i] = '\0';
|
|
|
|
*prev_info = (_DtCvPointer) myString;
|
|
return _DtCvSTATUS_OK;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Semi-Public Functions
|
|
*****************************************************************************/
|
|
/*****************************************************************************
|
|
* Function: char * _DtHelpDAGetSpcString ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
const char *
|
|
_DtHelpDAGetSpcString (
|
|
int idx)
|
|
{
|
|
return (SpcTable[idx].spc_string);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void _DtHelpDAResolveFont ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDAResolveFont (
|
|
_DtCvPointer client_data,
|
|
char *lang,
|
|
const char *charset,
|
|
_DtHelpFontHints font_attr,
|
|
_DtCvPointer *ret_font )
|
|
{
|
|
/*
|
|
* note - if the mod_string comes in with a NULL pointer,
|
|
* it came from our own call rather than the Core Engine.
|
|
*/
|
|
long idx;
|
|
|
|
(void) ResolveFont(client_data, lang, charset, font_attr, &idx);
|
|
*ret_font = (_DtCvPointer) idx;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: _DtCvStatus _DtHelpDAResolveSpc ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
_DtCvStatus
|
|
_DtHelpDAResolveSpc (
|
|
_DtCvPointer client_data,
|
|
char *lang,
|
|
const char *charset,
|
|
_DtHelpFontHints font_attr,
|
|
const char *spc_symbol,
|
|
_DtCvPointer *ret_handle,
|
|
_DtCvUnit *ret_width,
|
|
_DtCvUnit *ret_height,
|
|
_DtCvUnit *ret_ascent)
|
|
{
|
|
register int i = 0;
|
|
int result = -1;
|
|
long fontIdx;
|
|
long spcTbIdx = 0;
|
|
_DtCvUnit ascent;
|
|
_DtCvUnit descent;
|
|
const char *newSet;
|
|
const char *spcStr;
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
_DtCvStringInfo strInfo;
|
|
|
|
while (SpcTable[spcTbIdx].symbol != NULL &&
|
|
strcmp(SpcTable[spcTbIdx].symbol, spc_symbol) != 0)
|
|
spcTbIdx++;
|
|
|
|
newSet = SpcTable[spcTbIdx].spc_value;
|
|
spcStr = SpcTable[spcTbIdx].spc_string;
|
|
|
|
result = ResolveFont(client_data, lang, newSet, font_attr, &fontIdx);
|
|
|
|
if (result == 0)
|
|
{
|
|
long spcLstIdx = 0;
|
|
_DtCvUnit maxWidth;
|
|
_DtHelpDARegion *pReg;
|
|
|
|
pReg = (_DtHelpDARegion *) malloc (sizeof(_DtHelpDARegion));
|
|
if (NULL == pReg)
|
|
return -1;
|
|
|
|
while (spcLstIdx < pDAS->cur_spc &&
|
|
pDAS->spc_chars[spcLstIdx].spc_idx != -1)
|
|
spcLstIdx++;
|
|
|
|
if (spcLstIdx == pDAS->cur_spc)
|
|
{
|
|
if (pDAS->cur_spc >= pDAS->max_spc)
|
|
{
|
|
pDAS->max_spc += GROW_SIZE;
|
|
if (pDAS->cur_spc > 0)
|
|
pDAS->spc_chars = (DtHelpSpecialChars *) realloc(
|
|
(void *)pDAS->spc_chars,
|
|
(sizeof(DtHelpSpecialChars)*pDAS->max_spc));
|
|
else
|
|
pDAS->spc_chars = (DtHelpSpecialChars *) malloc(
|
|
(sizeof(DtHelpSpecialChars)*pDAS->max_spc));
|
|
|
|
if (pDAS->spc_chars == NULL)
|
|
return -1;
|
|
|
|
for (i = pDAS->cur_spc; i < pDAS->max_spc; i++)
|
|
pDAS->spc_chars[i].spc_idx = -1;
|
|
}
|
|
pDAS->cur_spc++;
|
|
}
|
|
|
|
pDAS->spc_chars[spcLstIdx].font_ptr = (_DtCvPointer)fontIdx;
|
|
pDAS->spc_chars[spcLstIdx].spc_idx = spcTbIdx;
|
|
|
|
/*
|
|
* fill in the region information
|
|
*/
|
|
pReg->inited = True;
|
|
pReg->type = _DtHelpDASpc;
|
|
pReg->handle = (_DtCvPointer) spcLstIdx;
|
|
|
|
/*
|
|
* fill out the return information
|
|
*/
|
|
*ret_handle = (_DtCvPointer) pReg;
|
|
|
|
*ret_height = 0;
|
|
*ret_width = 0;
|
|
|
|
/*
|
|
* get the maximum ascent and descent for the font. Set the return
|
|
* ascent.
|
|
*/
|
|
_DtHelpDAGetFontMetrics(client_data, (_DtCvPointer)fontIdx,
|
|
&ascent, &descent, NULL, NULL, NULL);
|
|
*ret_ascent = ascent;
|
|
|
|
/*
|
|
* now go through the string and get the maximum width
|
|
* and total height of the special character.
|
|
*/
|
|
do
|
|
{
|
|
/*
|
|
* find the first 'break' in the string sequence.
|
|
*/
|
|
i = 0;
|
|
while ('\0' != spcStr[i] && '\n' != spcStr[i] && '\b' != spcStr[i])
|
|
i++;
|
|
|
|
/*
|
|
* set the height if it is zero or if this is a multi-height
|
|
* special character.
|
|
*/
|
|
if ('\n' == spcStr[i] || 0 == *ret_height)
|
|
*ret_height = *ret_height + ascent + descent;
|
|
|
|
/*
|
|
* now get the maximum width of the special character.
|
|
*/
|
|
strInfo.string = spcStr;
|
|
strInfo.byte_len = i;
|
|
strInfo.wc = 0;
|
|
strInfo.font_ptr = (_DtCvPointer)fontIdx;
|
|
|
|
maxWidth = _DtHelpDAGetStrWidth (client_data, _DtCvSTRING_TYPE,
|
|
(_DtCvPointer) &strInfo);
|
|
if (*ret_width < maxWidth)
|
|
*ret_width = maxWidth;
|
|
|
|
/*
|
|
* if this is a multi-height or a composite character
|
|
* skip the newline or backspace.
|
|
*/
|
|
if ('\n' == spcStr[i] || '\b' == spcStr[i])
|
|
i++;
|
|
|
|
/*
|
|
* reset the string pointer
|
|
*/
|
|
spcStr += i;
|
|
} while (*spcStr != '\0');
|
|
result = 0;
|
|
}
|
|
else if (spc_symbol != DefaultStr)
|
|
result = _DtHelpDAResolveSpc (client_data, lang, charset,
|
|
font_attr, DefaultStr,
|
|
ret_handle, ret_width,
|
|
ret_height, ret_ascent);
|
|
return result;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* Function: _DtCvStatus GraphicLoad ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
_DtCvStatus
|
|
_DtHelpDALoadGraphic (
|
|
_DtCvPointer client_data,
|
|
char *vol_xid,
|
|
char *topic_xid,
|
|
char *file_xid,
|
|
char *format,
|
|
char *method,
|
|
_DtCvUnit *ret_width,
|
|
_DtCvUnit *ret_height,
|
|
_DtCvPointer *ret_region)
|
|
{
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
DtHelpGraphicStruct *pGS;
|
|
_DtHelpDARegion *pReg;
|
|
Widget wid;
|
|
Window win;
|
|
char *ptr;
|
|
char *extptr;
|
|
char *fileName = file_xid;
|
|
Screen *retScr;
|
|
int screen;
|
|
|
|
pGS = (DtHelpGraphicStruct *) malloc (sizeof(DtHelpGraphicStruct));
|
|
pReg = (_DtHelpDARegion *) malloc (sizeof(_DtHelpDARegion));
|
|
if (pGS == NULL || NULL == pReg)
|
|
{
|
|
if (NULL != pGS)
|
|
free(pGS);
|
|
if (NULL != pReg)
|
|
free(pReg);
|
|
return -1;
|
|
}
|
|
|
|
wid = pDAS->dispWid;
|
|
retScr = XtScreen(wid);
|
|
screen = XScreenNumberOfScreen(retScr);
|
|
|
|
while (!XtIsRealized(wid) && XtParent(wid) != NULL)
|
|
wid = XtParent(wid);
|
|
|
|
win = XtWindow(wid);
|
|
if (!XtIsRealized(wid))
|
|
win = RootWindow(XtDisplay(pDAS->dispWid), screen);
|
|
|
|
if (fileName != NULL && *fileName != '/')
|
|
{
|
|
fileName = (char *) malloc (strlen(vol_xid) + strlen (file_xid) + 2);
|
|
if (fileName == NULL)
|
|
return -1;
|
|
|
|
strcpy(fileName, vol_xid);
|
|
|
|
if (_DtHelpCeStrrchr(fileName, "/", MB_CUR_MAX, &ptr) != -1)
|
|
*ptr = '\0';
|
|
|
|
strcat(fileName, "/");
|
|
strcat(fileName, file_xid);
|
|
}
|
|
|
|
/*
|
|
* Find out if this is a X Pixmap graphic and set flag if it is.
|
|
* This will be used later when/if colors need to be freed.
|
|
*/
|
|
if (fileName != NULL && _DtHelpCeStrrchr(fileName, ".", MB_CUR_MAX, &extptr) != -1)
|
|
if (strcmp (extptr, ".xpm") == 0 || strcmp (extptr, ".pm") == 0)
|
|
pGS->used = -1;
|
|
|
|
if (pDAS->context == NULL)
|
|
{
|
|
pDAS->context = (_DtGrContext *) XtMalloc(sizeof(_DtGrContext));
|
|
pDAS->context->image_type = NULL;
|
|
pDAS->context->context = NULL;
|
|
}
|
|
|
|
pGS->pix = _DtHelpProcessGraphic (XtDisplay(pDAS->dispWid), win,
|
|
XScreenNumberOfScreen(XtScreen(pDAS->dispWid)),
|
|
pDAS->depth,
|
|
pDAS->pixmapGC,
|
|
&(pDAS->def_pix),
|
|
&(pDAS->def_pix_width),
|
|
&(pDAS->def_pix_height),
|
|
pDAS->context,
|
|
pDAS->colormap,
|
|
pDAS->visual,
|
|
pDAS->foregroundColor,
|
|
pDAS->backgroundColor, fileName,
|
|
pDAS->media_resolution,
|
|
&(pGS->width), &(pGS->height), &(pGS->mask),
|
|
&(pGS->pixels), &(pGS->num_pixels));
|
|
|
|
if (pDAS->context->image_type == NULL)
|
|
{
|
|
XtFree((char *) pDAS->context);
|
|
pDAS->context = NULL;
|
|
}
|
|
|
|
if (fileName != file_xid)
|
|
free (fileName);
|
|
|
|
if (pGS->pix == 0)
|
|
{
|
|
free(pReg);
|
|
free(pGS);
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* fill in the region information
|
|
*/
|
|
pReg->inited = True;
|
|
pReg->type = _DtHelpDAGraphic;
|
|
pReg->handle = (_DtCvPointer) pGS;
|
|
|
|
/*
|
|
* fill out the return information
|
|
*/
|
|
*ret_width = pGS->width;
|
|
*ret_height = pGS->height;
|
|
*ret_region = (_DtCvPointer) pReg;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void _DtHelpDADestroyGraphic ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDADestroyGraphic (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer graphic_ptr )
|
|
{
|
|
Arg args[5];
|
|
|
|
Colormap colormap;
|
|
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
DtHelpGraphicStruct *pGS = (DtHelpGraphicStruct *) graphic_ptr;
|
|
Display *dpy = XtDisplay(pDAS->dispWid);
|
|
|
|
if (pGS->pix != pDAS->def_pix)
|
|
XFreePixmap(dpy, pGS->pix);
|
|
|
|
if (pGS->mask != None)
|
|
XFreePixmap(dpy, pGS->mask);
|
|
|
|
if (pGS->num_pixels)
|
|
{
|
|
XtSetArg (args[0], XmNcolormap, &colormap);
|
|
XtGetValues (pDAS->dispWid, args, 1);
|
|
|
|
/*
|
|
* This will only be set to -1 if the original graphic was an X Pixmap,
|
|
* <filename>.pm or <filename>.xpm.
|
|
*/
|
|
if (pGS->used != -1)
|
|
XFreeColors (dpy, colormap, pGS->pixels, pGS->num_pixels, 0);
|
|
|
|
free((void *) pGS->pixels);
|
|
}
|
|
|
|
free((char *) pGS);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void _DtHelpDADestroySpc ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDADestroySpc (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer spc_handle)
|
|
{
|
|
long spc_index = (long) spc_handle;
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
|
|
if (pDAS->max_spc == 0)
|
|
return;
|
|
|
|
pDAS->spc_chars[spc_index].spc_idx = -1;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void _DtHelpDADestroyRegion ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDADestroyRegion (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer reg_info)
|
|
{
|
|
_DtHelpDARegion *pReg = (_DtHelpDARegion *) reg_info;
|
|
|
|
if (True == pReg->inited)
|
|
{
|
|
if (_DtHelpDASpc == pReg->type)
|
|
_DtHelpDADestroySpc(client_data, pReg->handle);
|
|
else if (_DtHelpDAGraphic == pReg->type)
|
|
_DtHelpDADestroyGraphic(client_data, pReg->handle);
|
|
}
|
|
else if (False == pReg->inited && _DtHelpDASpc == pReg->type)
|
|
{
|
|
_DtHelpDASpcInfo *pSpc = (_DtHelpDASpcInfo *) pReg->handle;
|
|
|
|
free(pSpc->name);
|
|
_DtHelpFreeFontHints(&(pSpc->spc_fonts));
|
|
free(pReg->handle);
|
|
}
|
|
|
|
free (pReg);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: Widget _DtHelpDATocMarker ();
|
|
*
|
|
* Parameters:
|
|
* client_data Specifies the display area pointer.
|
|
*
|
|
* Returns: nothing
|
|
*
|
|
* Purpose: Turns on/off the toc marker. This includes setting the correct
|
|
* bit in pDAS->toc_flag and doing a physical XDraw or XClearArea.
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDATocMarker (
|
|
XtPointer client_data,
|
|
Boolean draw)
|
|
{
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
|
|
if (pDAS->toc_flag & _DT_HELP_SHADOW_TRAVERSAL)
|
|
{
|
|
if (False == draw)
|
|
{
|
|
if (XtIsRealized(pDAS->dispWid))
|
|
ClearTocMarker(pDAS, 0);
|
|
TurnTocOff(pDAS->toc_flag);
|
|
}
|
|
else if (True == draw)
|
|
{
|
|
TurnTocOn(pDAS->toc_flag);
|
|
DrawTocIndicator(pDAS, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Virtual UI Functions
|
|
*****************************************************************************/
|
|
/*****************************************************************************
|
|
* Function: void _DtHelpDAGetCvsMetrics ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDAGetCvsMetrics (
|
|
_DtCvPointer client_data,
|
|
_DtCvElemType elem_type,
|
|
_DtCvPointer ret_metrics)
|
|
{
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
_DtCvSpaceMetrics *retSpace = (_DtCvSpaceMetrics *) ret_metrics;
|
|
|
|
if (_DtCvCANVAS_TYPE == elem_type)
|
|
{
|
|
_DtCvMetrics *retCanvas = (_DtCvMetrics *) ret_metrics;
|
|
|
|
retCanvas->width = pDAS->dispUseWidth;
|
|
retCanvas->height = pDAS->dispUseHeight;
|
|
retCanvas->top_margin = pDAS->marginHeight;
|
|
retCanvas->side_margin = pDAS->marginWidth;
|
|
retCanvas->line_height = pDAS->lineHeight;
|
|
retCanvas->horiz_pad_hint = pDAS->charWidth / 10;
|
|
}
|
|
|
|
else if (_DtCvLINK_TYPE == elem_type)
|
|
{
|
|
retSpace->space_before = 0;
|
|
retSpace->space_after = 0;
|
|
retSpace->space_above = 0;
|
|
retSpace->space_below = 0;
|
|
}
|
|
else if (_DtCvTRAVERSAL_TYPE == elem_type)
|
|
{
|
|
retSpace->space_before = pDAS->lineThickness;
|
|
if (pDAS->toc_flag & _DT_HELP_SHADOW_TRAVERSAL)
|
|
{
|
|
if (pDAS->toc_flag & _DT_HELP_NOT_INITIALIZED)
|
|
{
|
|
GetTocIndicator(pDAS);
|
|
pDAS->toc_flag &= (~(_DT_HELP_NOT_INITIALIZED));
|
|
}
|
|
retSpace->space_before += pDAS->toc_width;
|
|
}
|
|
|
|
retSpace->space_after = pDAS->lineThickness;
|
|
retSpace->space_above = pDAS->lineThickness;
|
|
retSpace->space_below = 0;
|
|
}
|
|
else if (_DtCvLOCALE_TYPE == elem_type)
|
|
{
|
|
_DtCvLocale *retLocale = (_DtCvLocale *) ret_metrics;
|
|
|
|
retLocale->line_wrap_mode = _DtCvModeWrapNone;
|
|
retLocale->cant_begin_chars = pDAS->cant_begin_chars;
|
|
retLocale->cant_end_chars = pDAS->cant_end_chars;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void _DtHelpDAGetFontMetrics ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDAGetFontMetrics (
|
|
_DtCvPointer client_data,
|
|
_DtCvPointer font_ptr,
|
|
_DtCvUnit *ret_ascent,
|
|
_DtCvUnit *ret_descent,
|
|
_DtCvUnit *ret_width,
|
|
_DtCvUnit *ret_super,
|
|
_DtCvUnit *ret_sub)
|
|
{
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
|
|
__DtHelpFontMetrics (pDAS->font_info, (long) font_ptr,
|
|
ret_ascent, ret_descent, ret_width, ret_super, ret_sub);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: _DtCvUnit _DtHelpDAGetStrWidth ();
|
|
*
|
|
* Parameters:
|
|
*
|
|
* Returns:
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
_DtCvUnit
|
|
_DtHelpDAGetStrWidth (
|
|
_DtCvPointer client_data,
|
|
_DtCvElemType elem_type,
|
|
_DtCvPointer data)
|
|
{
|
|
DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data;
|
|
int length;
|
|
long font_index;
|
|
_DtCvStringInfo *strInfo;
|
|
|
|
if (elem_type != _DtCvSTRING_TYPE)
|
|
return 0;
|
|
|
|
/*
|
|
* cast the data to a string information structure.
|
|
*/
|
|
strInfo = (_DtCvStringInfo *) data;
|
|
|
|
/*
|
|
* If the 'font_index' is a negative number, it indicates a font set
|
|
* was opened for this string. Use the X11R5 I18N routine to figure
|
|
* out its length. Otherwise use the standard X11 text width call.
|
|
*/
|
|
font_index = (long) strInfo->font_ptr;
|
|
if (font_index < 0)
|
|
{
|
|
if (0 == strInfo->wc)
|
|
length = XmbTextEscapement(
|
|
__DtHelpFontSetGet(pDAS->font_info, font_index),
|
|
(char *) strInfo->string, strInfo->byte_len);
|
|
else
|
|
length = XwcTextEscapement(
|
|
__DtHelpFontSetGet(pDAS->font_info, font_index),
|
|
(wchar_t *) strInfo->string, strInfo->byte_len);
|
|
}
|
|
else
|
|
length = XTextWidth(__DtHelpFontStructGet(pDAS->font_info, font_index),
|
|
(char *) strInfo->string, strInfo->byte_len);
|
|
|
|
return ((_DtCvUnit) length);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: void _DtHelpDARenderElem ();
|
|
*
|
|
* Parameters:
|
|
* client_data Specifies the client specific data
|
|
* associated with this canvas.
|
|
* elem_type Specifies the element type that will be
|
|
* rendered.
|
|
* x Specifies the x unit at which the
|
|
* string is to be rendered.
|
|
* y Specifes the y unit at which the baseline
|
|
* of the string is to be rendered.
|
|
* link_type Specifies the link type if this element is
|
|
* part of a link.
|
|
* old_flags Specifies the old flags.
|
|
* new_flags Specifies the new flags.
|
|
* data Contains a pointer to the element specific
|
|
* structures required for rendering.
|
|
*
|
|
* Returns: Nothing
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
void
|
|
_DtHelpDARenderElem (
|
|
_DtCvPointer client_data,
|
|
_DtCvElemType elem_type,
|
|
_DtCvUnit x,
|
|
_DtCvUnit y,
|
|
int link_type,
|
|
_DtCvFlags old_flags,
|
|
_DtCvFlags new_flags,
|
|
_DtCvElemType trav_type,
|
|
_DtCvPointer trav_data,
|
|
_DtCvPointer data )
|
|
{
|
|
_DtCvStringInfo *strInfo;
|
|
_DtCvLineInfo *lnInfo = (_DtCvLineInfo *) data;
|
|
_DtCvRenderInfo *posInfo = (_DtCvRenderInfo *) data;
|
|
|
|
/*
|
|
* nothing is done with trav_type or trav_data for DtHelp.
|
|
*/
|
|
|
|
/*
|
|
* render the element based on its type.
|
|
*/
|
|
if (_DtCvSTRING_TYPE == elem_type)
|
|
{
|
|
strInfo = (_DtCvStringInfo *) posInfo->info;
|
|
DADrawString(client_data, posInfo->info, x, y, strInfo->string,
|
|
strInfo->byte_len, strInfo->wc,
|
|
strInfo->font_ptr, strInfo->csd,
|
|
posInfo->box_x, posInfo->box_y,
|
|
posInfo->box_height,
|
|
old_flags, new_flags);
|
|
}
|
|
else if (_DtCvLINE_TYPE == elem_type)
|
|
{
|
|
DADrawLine(client_data, x, y, lnInfo->x2, lnInfo->y2, lnInfo->width);
|
|
}
|
|
else if (_DtCvREGION_TYPE == elem_type)
|
|
{
|
|
_DtHelpDARegion *regInfo = (_DtHelpDARegion *) posInfo->info;
|
|
|
|
if (_DtHelpDAGraphic == regInfo->type)
|
|
{
|
|
DADrawGraphic(client_data, regInfo->handle,
|
|
posInfo->box_x,
|
|
posInfo->box_y,
|
|
posInfo->box_width,
|
|
posInfo->box_height,
|
|
old_flags, new_flags);
|
|
}
|
|
else if (_DtHelpDASpc == regInfo->type)
|
|
{
|
|
DADrawSpc (client_data, regInfo->handle, x, y,
|
|
posInfo->box_x ,
|
|
posInfo->box_y , posInfo->box_height,
|
|
link_type , old_flags,
|
|
new_flags);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: _DtCvStatus _DtHelpDABuildSelection ();
|
|
*
|
|
* Parameters:
|
|
* client_data Specifies the client specific data
|
|
* associated with this canvas.
|
|
* elem_type Specifies the element type that will be
|
|
* rendered.
|
|
* x Specifies the x unit at which the
|
|
* string is to be rendered.
|
|
* y Specifes the y unit at which the baseline
|
|
* of the string is to be rendered.
|
|
* link_type Specifies the link type if this element is
|
|
* part of a link.
|
|
* old_flags Specifies the old flags.
|
|
* new_flags Specifies the new flags.
|
|
* data Contains a pointer to the element specific
|
|
* structures required for rendering.
|
|
*
|
|
* Returns: Nothing
|
|
*
|
|
* Purpose:
|
|
*
|
|
*****************************************************************************/
|
|
_DtCvStatus
|
|
_DtHelpDABuildSelection (
|
|
_DtCvPointer client_data,
|
|
_DtCvElemType elem_type,
|
|
unsigned int mask,
|
|
_DtCvPointer *prev_info,
|
|
_DtCvUnit space,
|
|
_DtCvUnit width,
|
|
_DtCvFlags flags,
|
|
_DtCvPointer data)
|
|
{
|
|
_DtCvStatus result = _DtCvSTATUS_NONE;
|
|
|
|
if (_DtCvSTRING_TYPE == elem_type)
|
|
{
|
|
_DtCvStringInfo *strInfo = (_DtCvStringInfo *) data;
|
|
|
|
result = DABuildSelectedString(client_data, prev_info,
|
|
strInfo->string , strInfo->byte_len,
|
|
strInfo->wc,
|
|
strInfo->font_ptr, space, flags);
|
|
}
|
|
else if (_DtCvREGION_TYPE == elem_type)
|
|
{
|
|
_DtHelpDARegion *regInfo = (_DtHelpDARegion *) data;
|
|
|
|
if (_DtHelpDASpc == regInfo->type)
|
|
result = DABuildSelectedSpc (client_data, prev_info,
|
|
regInfo->handle, space, flags);
|
|
}
|
|
|
|
return result;
|
|
}
|