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 /* Copyright (c) 1996 FUJITSU LIMITED */
24 /* All Rights Reserved */
27 * $XConsortium: NodeViewInfo.C /main/17 1996/11/18 15:50:15 mustafa $
29 * Copyright (c) 1993 HAL Computer Systems International, Ltd.
30 * All rights reserved. Unpublished -- rights reserved under
31 * the Copyright Laws of the United States. USE OF A COPYRIGHT
32 * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
35 * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
36 * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. USE,
37 * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
38 * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
41 * RESTRICTED RIGHTS LEGEND
42 * Use, duplication, or disclosure by the Government is subject
43 * to the restrictions as set forth in subparagraph (c)(l)(ii)
44 * of the Rights in Technical Data and Computer Software clause
45 * at DFARS 252.227-7013.
47 * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
56 #define C_NodeViewInfo
62 #define C_PixmapGraphic
73 #include <DtI/LinkMgrP.h>
76 #include <DtI/DisplayAreaP.h>
77 #include <DtI/FontI.h>
78 #include <DtI/FontAttrI.h>
79 #include <DtI/RegionI.h>
81 #include "OnlineRender/SegClientData.hh"
83 #include "UAS/DtSR/Util_Classes/DictIter.hh"
85 // /////////////////////////////////////////////////////////////////
87 // /////////////////////////////////////////////////////////////////
89 NodeViewInfo::NodeViewInfo (UAS_Pointer<UAS_Common> &node_ptr, _DtCvTopicInfo *topic)
90 : f_node_ptr (node_ptr),
94 f_def_val((unsigned long)-1),
95 f_color_dict(f_def_key, f_def_val)
98 printf( "make NodeViewInfo %p\n\n", this );
104 Recursively clean up our segment structures
107 cleanup(_DtCvSegment *segment)
111 switch (segment->type & _DtCvPRIMARY_MASK)
114 if (segment->handle.container.id)
115 free (segment->handle.container.id);
116 cleanup (segment->handle.container.seg_list);
119 if (segment->handle.string.string)
120 delete (segment->handle.string.string);
121 if (segment->client_use) {
122 delete (SegClientData*)segment->client_use;
123 segment->client_use = NULL;
128 _DtCvTable *table = &segment->handle.table ;
131 for (int i = 0 ; i < table->num_cols; i++)
132 delete table->col_w[i] ;
133 delete table->col_w ;
136 delete table->col_justify ;
137 delete table->justify_chars ;
138 char **ids = table->cell_ids ;
141 delete table->cell_ids ;
142 _DtCvSegment **cells = table->cells ;
145 delete table->cells ;
149 delete segment->handle.marker ;
153 _DtHelpDARegion *pReg = (_DtHelpDARegion*) segment->handle.region.info ;
154 DtHelpGraphicStruct *pGS = (DtHelpGraphicStruct *) pReg->handle;
157 if (segment->client_use) {
158 // Note: ((SegClientData*)segment->client_use)->GraphicHandle()
159 // is deleted separately through f_pixmap_list
160 delete (SegClientData*)segment->client_use;
161 segment->client_use = NULL;
166 cleanup(segment->next_seg);
172 // /////////////////////////////////////////////////////////////////
174 // /////////////////////////////////////////////////////////////////
176 NodeViewInfo::~NodeViewInfo()
178 _DtLinkDbDestroy(f_topic->link_data); // kill the link database
180 cleanup(f_topic->seg_list); // kill the segments and their items
182 f_topic->seg_list = 0 ;
183 delete f_topic ; // sayonara
185 if (f_pixmap_list != NULL)
186 { // explicitly cleanup graphics in f_pixmap_list
187 List_Iterator<UAS_Pointer<Graphic> > gli (f_pixmap_list) ;
191 printf( "delete UAS_Pointer<Graphic> gli.item() = %p\n", gli.item() );
193 f_pixmap_list.remove(gli) ;
197 printf( "kill NodeViewInfo %p\n\n", this );
202 NodeViewInfo::add_graphic(UAS_Pointer<Graphic> &pg)
204 f_pixmap_list.append(pg);
207 printf( "NodeViewInfo: add UAS_Pointer<Graphic> %p\n", pg );
208 if (f_pixmap_list != NULL)
210 List_Iterator<UAS_Pointer<Graphic> > gli (f_pixmap_list) ;
211 printf( "graphics list is now: " );
214 printf( " %p ", gli.item() );
223 DtCvStrLen(_DtCvSegment* seg)
225 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
228 unsigned int len = 0;
230 if (seg->type & _DtCvWIDE_CHAR) {
231 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
232 for (; *seg_str; seg_str++, len++);
235 char* seg_str = (char*)seg->handle.string.string;
236 for (; *seg_str; seg_str++, len++);
243 DtCvStrVccToIndex(_DtCvSegment* seg, unsigned int vcc)
245 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
246 || seg->client_use == NULL)
247 return (unsigned int)-1;
249 unsigned int index = 0;
251 unsigned int rel_vcc;
252 if ((rel_vcc = vcc - ((SegClientData*)seg->client_use)->vcc()) < 0)
253 return (unsigned int)-1;
255 if (seg->type & _DtCvWIDE_CHAR) {
256 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
257 for (; *seg_str && rel_vcc > 0; seg_str++, index++) {
258 if (*seg_str != ' ' && *seg_str != '\t' && *seg_str != '\n')
261 if (*seg_str == 0 && rel_vcc > 0)
262 index = (unsigned int)-1;
264 for (; *seg_str; seg_str++, index++) {
265 if (*seg_str != ' ' && *seg_str != '\t' && *seg_str != '\n')
271 unsigned char* seg_str = (unsigned char*)seg->handle.string.string;
272 for (; *seg_str && rel_vcc > 0; seg_str++, index++) {
273 if (*seg_str != ' ' && *seg_str != '\t' &&
274 *seg_str != '\n' && *seg_str != 0xA0)
277 if (*seg_str == 0 && rel_vcc > 0)
278 index = (unsigned int)-1;
280 for (; *seg_str; seg_str++, index++) {
281 if (*seg_str != ' ' && *seg_str != '\t' &&
282 *seg_str != '\n' && *seg_str != 0xA0)
292 DtCvStrVcLenSync(_DtCvSegment* seg)
294 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
295 || seg->client_use == NULL)
296 return (unsigned int)-1;
298 unsigned int vclen = 0;
300 if (seg->type & _DtCvWIDE_CHAR) {
301 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
302 for (; *seg_str; seg_str++) {
303 if (*seg_str != ' ' && *seg_str != '\t' && *seg_str != '\n')
308 unsigned char* seg_str = (unsigned char*)seg->handle.string.string;
309 for (; *seg_str; seg_str++) {
310 if (*seg_str != ' ' && *seg_str != '\t' &&
311 *seg_str != '\n' && *seg_str != 0xA0)
317 ((SegClientData*)seg->client_use)->vclen() = vclen;
323 DtCvStrVcLen(_DtCvSegment* seg)
325 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
328 return ((SegClientData*)seg->client_use)->vclen();
332 DtCvStrVcc(_DtCvSegment* seg)
334 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
335 || seg->client_use == NULL)
336 return (unsigned int)-1;
338 return ((SegClientData*)seg->client_use)->vcc();
342 DtCvStrVcc(_DtCvSegment* seg, unsigned int vcc)
344 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
345 || seg->client_use == NULL)
348 ((SegClientData*)seg->client_use)->vcc() = vcc;
351 // Chop a segment into two separate segments.
352 // nc is the number of characters of the first segment.
355 chop_segment(_DtCvSegment* seg, unsigned int nc)
357 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
363 unsigned int seg_nc = DtCvStrLen(seg);
370 unsigned long widec = seg->type & _DtCvWIDE_CHAR;
374 wchar_t* src = (wchar_t*)seg->handle.string.string + nc;
375 wchar_t* dest = new wchar_t[seg_nc - nc + 1];
376 for (int i = 0; i < seg_nc - nc; i++)
378 dest[seg_nc - nc] = '\0';
379 nseg_str = (void*)dest;
381 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
382 seg_str[nc] = '\0'; // chop seg string
385 char* src = (char*)seg->handle.string.string + nc;
386 char* dest = new char[seg_nc - nc + 1];
387 for (int i = 0; i < seg_nc - nc; i++)
389 dest[seg_nc - nc] = '\0';
390 nseg_str = (void*)dest;
392 unsigned char* seg_str = (unsigned char*)seg->handle.string.string;
393 seg_str[nc] = '\0'; // chop seg string
395 DtCvStrVcLenSync(seg);
397 unsigned int seg_vcc = DtCvStrVcc(seg);
398 unsigned int seg_vclen = DtCvStrVcLen(seg);
400 #ifdef SYMBOL_HIGHLIGHT
401 _DtCvSegment* symseg = new _DtCvSegment(*seg);
402 symseg->next_seg = seg->next_seg;
403 symseg->next_disp = seg->next_disp;
404 seg ->next_seg = symseg;
405 seg ->next_disp = symseg;
407 symseg->handle.string.string = new char[2];
408 *(unsigned char*) symseg->handle.string.string = 0xA4;
409 *((unsigned char*)symseg->handle.string.string + 1) = 0x00;
410 symseg->client_use = NULL;
411 symseg->internal_use = NULL;
412 symseg->type |= _DtCvAPP_FLAG1;
413 symseg->type &= ~_DtCvWIDE_CHAR;
415 if (symseg->type & _DtCvNEW_LINE) // take _DtCvNEW_LINE over
416 seg->type &= ~_DtCvNEW_LINE;
419 ~(_DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END);
424 _DtCvSegment* nseg = new _DtCvSegment(*seg);
425 nseg->next_seg = seg->next_seg;
426 nseg->next_disp = seg->next_disp;
427 seg ->next_seg = nseg;
428 seg ->next_disp = nseg;
430 if (nseg->type & _DtCvNEW_LINE) // take _DtCvNEW_LINE over
431 seg->type &= ~_DtCvNEW_LINE;
434 nseg->type |= _DtCvWIDE_CHAR;
436 nseg->type &= ~_DtCvAPP_FLAG1;
438 nseg->type &= ~(_DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END);
440 nseg->internal_use = NULL;
442 nseg->handle.string.string = nseg_str;
444 // set client_use properly
445 nseg->client_use = (_DtCvPointer)new SegClientData(_DtCvSTRING);
446 DtCvStrVcc(nseg, seg_vcc + seg_vclen);
447 DtCvStrVcLenSync(nseg);
452 // FUNCTION highlight_search_hit
454 // vcc : vcc of the segment to be highlighted
455 // len : character length of the segment to be highlighted
458 // the segment to be highlighted
461 highlight_search_hit(_DtCvSegment* seg, unsigned int vcc, unsigned int len)
463 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
469 unsigned int seg_vcc = DtCvStrVcc(seg);
470 unsigned int seg_nc = DtCvStrLen(seg);
472 if (vcc < seg_vcc) // vcc falls short
475 unsigned long widec = seg->type & _DtCvWIDE_CHAR;
477 // translate rel_vcc (vccs) into nseg_nc (characters)
478 unsigned int nseg_nc = DtCvStrVccToIndex(seg, vcc);
479 if (nseg_nc == (unsigned int)-1) // vcc is beyond segment
483 fprintf(stderr, "(DEBUG) vcc=%d, index=%d, clen=%d\n", vcc, nseg_nc, len);
488 else if (seg_vcc == vcc && seg_nc == len)
491 if (len > seg_nc - nseg_nc) { // len goes beyond this segment
492 if (seg->next_seg == NULL) {
493 len = seg_nc - nseg_nc;
496 _DtCvSegment* sibling = seg->next_seg;
497 unsigned long type = sibling->type & _DtCvPRIMARY_MASK;
498 if (type != _DtCvSTRING || sibling->client_use == NULL ||
499 DtCvStrVcc(sibling) == (unsigned int)-1 ||
500 (seg->type & _DtCvWIDE_CHAR) != (sibling->type & _DtCvWIDE_CHAR)) {
501 len = seg_nc - nseg_nc;
503 else { // let's merge segments
504 seg->next_seg = sibling->next_seg;
505 seg->next_disp = sibling->next_disp;
506 sibling->next_seg = NULL;
507 sibling->next_disp = NULL;
510 wchar_t* src = (wchar_t*)sibling->handle.string.string;
511 wchar_t* dst = (wchar_t*)seg->handle.string.string;
512 int len = wcslen(dst) + wcslen(src);
513 seg->handle.string.string = (void*)
514 realloc(seg->handle.string.string,
515 sizeof(wchar_t) * (len + 1));
516 dst = (wchar_t*)seg->handle.string.string;
520 char* src = (char*)sibling->handle.string.string;
521 char* dst = (char*)seg->handle.string.string;
522 int len = strlen(dst) + strlen(dst);
523 seg->handle.string.string = (void*)
524 realloc(seg->handle.string.string, len + 1);
525 dst = (char*)seg->handle.string.string;
528 DtCvStrVcLenSync(seg);
530 if (sibling->handle.string.string)
531 free (sibling->handle.string.string);
532 if (sibling->client_use) {
533 delete sibling->client_use;
534 sibling->client_use = NULL;
537 // NOTE: sibling is kept (i.e. not deleted)
538 // this fact may cause problems in next highlight_search_hit
540 return highlight_search_hit(seg, vcc, len);
548 char buf[MB_LEN_MAX + 1];
549 wchar_t* debug_p = (wchar_t*)seg->handle.string.string + nseg_nc;
550 int n = wctomb(buf, *debug_p);
553 fprintf(stderr, "(DEBUG) initial=%s\n", buf);
556 char* debug_p = (char*)seg->handle.string.string + nseg_nc;
557 fprintf(stderr, "(DEBUG) initial=%c\n", *debug_p);
560 if ((seg = chop_segment(seg, nseg_nc)) == NULL)
564 if (len != seg_nc - nseg_nc)
565 chop_segment(seg, len);
570 static _DtCvSegment *
571 traverse_for_vcc(_DtCvSegment* seg, unsigned int vcc)
576 unsigned long seg_ptype = seg->type & _DtCvPRIMARY_MASK;
578 if (seg_ptype == _DtCvSTRING && seg->client_use) {
580 assert( DtCvStrVcc(seg) <= vcc );
582 if (DtCvStrVcc(seg) != (unsigned int)-1) { // check for validity
583 if (vcc < DtCvStrVcc(seg) + DtCvStrVcLen(seg)) // found
588 _DtCvSegment* therein = NULL;
590 if (seg_ptype == _DtCvCONTAINER) { // traverse subordinates
591 _DtCvSegment* subordinates;
592 if ((subordinates = seg->handle.container.seg_list) != NULL)
593 therein = traverse_for_vcc(subordinates, vcc);
595 else if (seg_ptype == _DtCvTABLE) {
596 _DtCvSegment** cell = seg->handle.table.cells;
597 for (; *cell; cell++) {
598 if (therein = traverse_for_vcc(*cell, vcc))
606 _DtCvSegment* siblings;
607 if ((siblings = seg->next_seg) != NULL)
608 therein = traverse_for_vcc(siblings, vcc);
614 NodeViewInfo::top_container()
619 // retrieve the top container
620 _DtCvSegment* root_seg;
621 if ((root_seg = f_topic->seg_list) == NULL)
623 assert( (root_seg->type & _DtCvPRIMARY_MASK) == _DtCvCONTAINER );
629 clear_search_hits_traverse(_DtCvSegment* seg)
634 unsigned long seg_ptype = seg->type & _DtCvPRIMARY_MASK;
636 if (seg_ptype == _DtCvSTRING && seg->client_use) {
637 if (seg->type & _DtCvSEARCH_FLAG)
639 ~(_DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END |
643 if (seg_ptype == _DtCvCONTAINER) { // traverse subordinates
644 _DtCvSegment* subordinates;
645 if ((subordinates = seg->handle.container.seg_list) != NULL)
646 clear_search_hits_traverse(subordinates);
648 else if (seg_ptype == _DtCvTABLE) {
649 _DtCvSegment** cell = seg->handle.table.cells;
650 for (; *cell; cell++)
651 clear_search_hits_traverse(*cell);
655 _DtCvSegment* siblings;
656 if ((siblings = seg->next_seg) != NULL)
657 clear_search_hits_traverse(siblings);
663 NodeViewInfo::clear_search_hits()
665 // retrieve the top container
666 _DtCvSegment* root_seg;
667 if ((root_seg = top_container()) == NULL)
670 clear_search_hits_traverse(root_seg);
672 f_hits.clearAndDestroy();
673 f_current_hit = NULL;
677 NodeViewInfo::set_search_hits(UAS_Pointer<UAS_List<UAS_TextRun> >& hits)
679 if (f_current_hit) { // clear search hits previously displayed
683 // retrieve the top container
684 _DtCvSegment* root_seg;
685 if ((root_seg = top_container()) == NULL)
690 for (idx = 0; idx < hits->length(); idx++) { // for each TextRun
692 UAS_Pointer<UAS_TextRun>& hit = hits->item(idx);
696 if ((seg = traverse_for_vcc(root_seg, hit->offset())) == NULL) {
698 fprintf(stderr, "(DEBUG) traverse_for_vcc failed, offset=%d\n",
705 fprintf(stderr, "(DEBUG) traverse_for_vcc succeeded, offset=%d\n",
709 assert( (seg->type & _DtCvPRIMARY_MASK) == _DtCvSTRING );
711 if (seg = highlight_search_hit(seg, hit->offset(), hit->length())) {
713 fprintf(stderr, "(DEBUG) highlight_search_hit succeeded, "
714 "offset=%d\n", hit->offset());
717 _DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END;
719 sr_DtCvSegment* sr_seg = new sr_DtCvSegment(seg);
722 seg->type |= _DtCvAPP_FLAG2;
723 f_current_hit = sr_seg;
725 f_hits.append(sr_seg);
729 fprintf(stderr, "(DEBUG) highlight_search_hit failed, offset=%d\n",
735 // returns 0 if upon success. returns -1 if it traversal was not changed.
737 NodeViewInfo::trav_status_t
738 NodeViewInfo::adjust_current_search_hit(trav_dir_t dir)
740 trav_status_t status = SUCCESS;
742 CC_TPtrDlistIterator<sr_DtCvSegment> iter(f_hits);
744 for (++iter; *iter.key() != *f_current_hit;)
748 if (*iter.key() != *f_hits.first())
752 assert( dir == NEXT );
753 if (*iter.key() != *f_hits.last())
757 if (*f_current_hit != *iter.key()) {
758 f_current_hit->hitseg->type &= ~_DtCvAPP_FLAG2;
760 f_current_hit = iter.key();
761 f_current_hit->hitseg->type |= _DtCvAPP_FLAG2;
764 if (*f_current_hit == *f_hits.first())
765 status = REACH_LIMIT;
768 if (*f_current_hit == *f_hits.last())
769 status = REACH_LIMIT;
778 NodeViewInfo::hit_entries() const
780 return f_hits.entries();
784 NodeViewInfo::search_hit_idx()
788 CC_TPtrDlistIterator<sr_DtCvSegment> iter(f_hits);
790 for (i = 0, ++iter; *iter.key() != *f_current_hit; i++)
797 NodeViewInfo::comp_pixel_values_traverse(_DtCvSegment* seg, Display* dpy,
803 unsigned long seg_ptype = seg->type & _DtCvPRIMARY_MASK;
805 if (seg_ptype == _DtCvSTRING && seg->client_use) {
806 XColor screen, exact;
807 SegClientData* pSCD = (SegClientData*)seg->client_use;
808 assert( pSCD->type() == _DtCvSTRING );
810 if (pSCD->bg_color() && pSCD->bg_pixel() == (unsigned long)-1) {
811 UAS_String bg_color = pSCD->bg_color();
812 unsigned long& bg_pixel = f_color_dict[bg_color];
813 if (bg_pixel == (unsigned long)-1) {
814 if (XAllocNamedColor(dpy, cmap, pSCD->bg_color(),
816 pSCD->bg_pixel(bg_pixel = screen.pixel);
819 pSCD->bg_pixel(bg_pixel);
822 if (pSCD->fg_color() && pSCD->fg_pixel() == (unsigned long)-1) {
823 UAS_String fg_color = pSCD->fg_color();
824 unsigned long& fg_pixel = f_color_dict[fg_color];
825 if (fg_pixel == (unsigned long)-1) {
826 if (XAllocNamedColor(dpy, cmap, pSCD->fg_color(),
828 pSCD->fg_pixel(fg_pixel = screen.pixel);
831 pSCD->fg_pixel(fg_pixel);
835 if (seg_ptype == _DtCvCONTAINER) { // traverse subordinates
836 _DtCvSegment* subordinates;
837 if ((subordinates = seg->handle.container.seg_list) != NULL)
838 comp_pixel_values_traverse(subordinates, dpy, cmap);
842 _DtCvSegment* siblings;
843 if ((siblings = seg->next_seg) != NULL)
844 comp_pixel_values_traverse(siblings, dpy, cmap);
850 NodeViewInfo::comp_pixel_values(Display* dpy, Colormap &cmap)
852 // retrieve the top container
853 _DtCvSegment* root_seg;
854 if ((root_seg = top_container()) == NULL)
857 comp_pixel_values_traverse(root_seg, dpy, cmap);
860 DictIter<UAS_String, unsigned long> dictiter;
861 for (dictiter = f_color_dict.first(); dictiter() ; dictiter++) {
862 fprintf(stderr, "(DEBUG) color=\"%s\", pixel=0x%lx\n",
863 (char*)dictiter.key(), dictiter.value());
871 NodeViewInfo::get_segment(unsigned int vcc)
873 return traverse_for_vcc(top_container(), vcc);
877 NodeViewInfo::segment_to_vcc(_DtCvSegment* seg)
879 return DtCvStrVcc(seg);