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 (char*)(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",
194 f_pixmap_list.remove(gli) ;
198 printf( "kill NodeViewInfo %p\n\n", this );
203 NodeViewInfo::add_graphic(UAS_Pointer<Graphic> &pg)
205 f_pixmap_list.append(pg);
208 printf( "NodeViewInfo: add UAS_Pointer<Graphic> %p\n", (void*)pg );
209 if (f_pixmap_list != NULL)
211 List_Iterator<UAS_Pointer<Graphic> > gli (f_pixmap_list) ;
212 printf( "graphics list is now: " );
215 printf( " %p ", (void*)gli.item() );
224 DtCvStrLen(_DtCvSegment* seg)
226 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
229 unsigned int len = 0;
231 if (seg->type & _DtCvWIDE_CHAR) {
232 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
233 for (; *seg_str; seg_str++, len++);
236 char* seg_str = (char*)seg->handle.string.string;
237 for (; *seg_str; seg_str++, len++);
244 DtCvStrVccToIndex(_DtCvSegment* seg, unsigned int vcc)
246 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
247 || seg->client_use == NULL)
248 return (unsigned int)-1;
250 unsigned int index = 0;
252 unsigned int rel_vcc;
253 if ((int)(rel_vcc = vcc - ((SegClientData*)seg->client_use)->vcc()) < 0)
254 return (unsigned int)-1;
256 if (seg->type & _DtCvWIDE_CHAR) {
257 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
258 for (; *seg_str && rel_vcc > 0; seg_str++, index++) {
259 if (*seg_str != ' ' && *seg_str != '\t' && *seg_str != '\n')
262 if (*seg_str == 0 && rel_vcc > 0)
263 index = (unsigned int)-1;
265 for (; *seg_str; seg_str++, index++) {
266 if (*seg_str != ' ' && *seg_str != '\t' && *seg_str != '\n')
272 unsigned char* seg_str = (unsigned char*)seg->handle.string.string;
273 for (; *seg_str && rel_vcc > 0; seg_str++, index++) {
274 if (*seg_str != ' ' && *seg_str != '\t' &&
275 *seg_str != '\n' && *seg_str != 0xA0)
278 if (*seg_str == 0 && rel_vcc > 0)
279 index = (unsigned int)-1;
281 for (; *seg_str; seg_str++, index++) {
282 if (*seg_str != ' ' && *seg_str != '\t' &&
283 *seg_str != '\n' && *seg_str != 0xA0)
293 DtCvStrVcLenSync(_DtCvSegment* seg)
295 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
296 || seg->client_use == NULL)
297 return (unsigned int)-1;
299 unsigned int vclen = 0;
301 if (seg->type & _DtCvWIDE_CHAR) {
302 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
303 for (; *seg_str; seg_str++) {
304 if (*seg_str != ' ' && *seg_str != '\t' && *seg_str != '\n')
309 unsigned char* seg_str = (unsigned char*)seg->handle.string.string;
310 for (; *seg_str; seg_str++) {
311 if (*seg_str != ' ' && *seg_str != '\t' &&
312 *seg_str != '\n' && *seg_str != 0xA0)
318 ((SegClientData*)seg->client_use)->vclen() = vclen;
324 DtCvStrVcLen(_DtCvSegment* seg)
326 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
329 return ((SegClientData*)seg->client_use)->vclen();
333 DtCvStrVcc(_DtCvSegment* seg)
335 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
336 || seg->client_use == NULL)
337 return (unsigned int)-1;
339 return ((SegClientData*)seg->client_use)->vcc();
343 DtCvStrVcc(_DtCvSegment* seg, unsigned int vcc)
345 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING
346 || seg->client_use == NULL)
349 ((SegClientData*)seg->client_use)->vcc() = vcc;
352 // Chop a segment into two separate segments.
353 // nc is the number of characters of the first segment.
356 chop_segment(_DtCvSegment* seg, unsigned int nc)
358 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
364 unsigned int seg_nc = DtCvStrLen(seg);
371 unsigned long widec = seg->type & _DtCvWIDE_CHAR;
375 wchar_t* src = (wchar_t*)seg->handle.string.string + nc;
376 wchar_t* dest = new wchar_t[seg_nc - nc + 1];
377 for (unsigned int i = 0; i < seg_nc - nc; i++)
379 dest[seg_nc - nc] = '\0';
380 nseg_str = (void*)dest;
382 wchar_t* seg_str = (wchar_t*)seg->handle.string.string;
383 seg_str[nc] = '\0'; // chop seg string
386 char* src = (char*)seg->handle.string.string + nc;
387 char* dest = new char[seg_nc - nc + 1];
388 for (unsigned int i = 0; i < seg_nc - nc; i++)
390 dest[seg_nc - nc] = '\0';
391 nseg_str = (void*)dest;
393 unsigned char* seg_str = (unsigned char*)seg->handle.string.string;
394 seg_str[nc] = '\0'; // chop seg string
396 DtCvStrVcLenSync(seg);
398 unsigned int seg_vcc = DtCvStrVcc(seg);
399 unsigned int seg_vclen = DtCvStrVcLen(seg);
401 #ifdef SYMBOL_HIGHLIGHT
402 _DtCvSegment* symseg = new _DtCvSegment(*seg);
403 symseg->next_seg = seg->next_seg;
404 symseg->next_disp = seg->next_disp;
405 seg ->next_seg = symseg;
406 seg ->next_disp = symseg;
408 symseg->handle.string.string = new char[2];
409 *(unsigned char*) symseg->handle.string.string = 0xA4;
410 *((unsigned char*)symseg->handle.string.string + 1) = 0x00;
411 symseg->client_use = NULL;
412 symseg->internal_use = NULL;
413 symseg->type |= _DtCvAPP_FLAG1;
414 symseg->type &= ~_DtCvWIDE_CHAR;
416 if (symseg->type & _DtCvNEW_LINE) // take _DtCvNEW_LINE over
417 seg->type &= ~_DtCvNEW_LINE;
420 ~(_DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END);
425 _DtCvSegment* nseg = new _DtCvSegment(*seg);
426 nseg->next_seg = seg->next_seg;
427 nseg->next_disp = seg->next_disp;
428 seg ->next_seg = nseg;
429 seg ->next_disp = nseg;
431 if (nseg->type & _DtCvNEW_LINE) // take _DtCvNEW_LINE over
432 seg->type &= ~_DtCvNEW_LINE;
435 nseg->type |= _DtCvWIDE_CHAR;
437 nseg->type &= ~_DtCvAPP_FLAG1;
439 nseg->type &= ~(_DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END);
441 nseg->internal_use = NULL;
443 nseg->handle.string.string = nseg_str;
445 // set client_use properly
446 nseg->client_use = (_DtCvPointer)new SegClientData(_DtCvSTRING);
447 DtCvStrVcc(nseg, seg_vcc + seg_vclen);
448 DtCvStrVcLenSync(nseg);
453 // FUNCTION highlight_search_hit
455 // vcc : vcc of the segment to be highlighted
456 // len : character length of the segment to be highlighted
459 // the segment to be highlighted
462 highlight_search_hit(_DtCvSegment* seg, unsigned int vcc, unsigned int len)
464 if (seg == NULL || (seg->type & _DtCvPRIMARY_MASK) != _DtCvSTRING)
470 unsigned int seg_vcc = DtCvStrVcc(seg);
471 unsigned int seg_nc = DtCvStrLen(seg);
473 if (vcc < seg_vcc) // vcc falls short
476 unsigned long widec = seg->type & _DtCvWIDE_CHAR;
478 // translate rel_vcc (vccs) into nseg_nc (characters)
479 unsigned int nseg_nc = DtCvStrVccToIndex(seg, vcc);
480 if (nseg_nc == (unsigned int)-1) // vcc is beyond segment
484 fprintf(stderr, "(DEBUG) vcc=%d, index=%d, clen=%d\n", vcc, nseg_nc, len);
489 else if (seg_vcc == vcc && seg_nc == len)
492 if (len > seg_nc - nseg_nc) { // len goes beyond this segment
493 if (seg->next_seg == NULL) {
494 len = seg_nc - nseg_nc;
497 _DtCvSegment* sibling = seg->next_seg;
498 unsigned long type = sibling->type & _DtCvPRIMARY_MASK;
499 if (type != _DtCvSTRING || sibling->client_use == NULL ||
500 DtCvStrVcc(sibling) == (unsigned int)-1 ||
501 (seg->type & _DtCvWIDE_CHAR) != (sibling->type & _DtCvWIDE_CHAR)) {
502 len = seg_nc - nseg_nc;
504 else { // let's merge segments
505 seg->next_seg = sibling->next_seg;
506 seg->next_disp = sibling->next_disp;
507 sibling->next_seg = NULL;
508 sibling->next_disp = NULL;
511 wchar_t* src = (wchar_t*)sibling->handle.string.string;
512 wchar_t* dst = (wchar_t*)seg->handle.string.string;
513 int slen = wcslen(dst);
514 int len = wcslen(src);
515 seg->handle.string.string = (void*)
516 realloc(seg->handle.string.string,
517 sizeof(wchar_t) * (slen + len + 1));
518 dst = (wchar_t*)seg->handle.string.string;
519 *((char *) memcpy(dst + slen, src, len) + len) = '\0';
522 char* src = (char*)sibling->handle.string.string;
523 char* dst = (char*)seg->handle.string.string;
524 int slen = strlen(dst);
525 int len = strlen(src);
526 seg->handle.string.string = (void*)
527 realloc(seg->handle.string.string, slen + len + 1);
528 dst = (char*)seg->handle.string.string;
529 *((char *) memcpy(dst + slen, src, len) + len) = '\0';
531 DtCvStrVcLenSync(seg);
533 if (sibling->handle.string.string)
534 free (sibling->handle.string.string);
535 if (sibling->client_use) {
536 delete (SegClientData*)sibling->client_use;
537 sibling->client_use = NULL;
540 // NOTE: sibling is kept (i.e. not deleted)
541 // this fact may cause problems in next highlight_search_hit
543 return highlight_search_hit(seg, vcc, len);
551 char buf[MB_LEN_MAX + 1];
552 wchar_t* debug_p = (wchar_t*)seg->handle.string.string + nseg_nc;
553 int n = wctomb(buf, *debug_p);
556 fprintf(stderr, "(DEBUG) initial=%s\n", buf);
559 char* debug_p = (char*)seg->handle.string.string + nseg_nc;
560 fprintf(stderr, "(DEBUG) initial=%c\n", *debug_p);
563 if ((seg = chop_segment(seg, nseg_nc)) == NULL)
567 if (len != seg_nc - nseg_nc)
568 chop_segment(seg, len);
573 static _DtCvSegment *
574 traverse_for_vcc(_DtCvSegment* seg, unsigned int vcc)
579 unsigned long seg_ptype = seg->type & _DtCvPRIMARY_MASK;
581 if (seg_ptype == _DtCvSTRING && seg->client_use) {
583 assert( DtCvStrVcc(seg) <= vcc );
585 if (DtCvStrVcc(seg) != (unsigned int)-1) { // check for validity
586 if (vcc < DtCvStrVcc(seg) + DtCvStrVcLen(seg)) // found
591 _DtCvSegment* therein = NULL;
593 if (seg_ptype == _DtCvCONTAINER) { // traverse subordinates
594 _DtCvSegment* subordinates;
595 if ((subordinates = seg->handle.container.seg_list) != NULL)
596 therein = traverse_for_vcc(subordinates, vcc);
598 else if (seg_ptype == _DtCvTABLE) {
599 _DtCvSegment** cell = seg->handle.table.cells;
600 for (; *cell; cell++) {
601 if ((therein = traverse_for_vcc(*cell, vcc)))
609 _DtCvSegment* siblings;
610 if ((siblings = seg->next_seg) != NULL)
611 therein = traverse_for_vcc(siblings, vcc);
617 NodeViewInfo::top_container()
622 // retrieve the top container
623 _DtCvSegment* root_seg;
624 if ((root_seg = f_topic->seg_list) == NULL)
626 assert( (root_seg->type & _DtCvPRIMARY_MASK) == _DtCvCONTAINER );
632 clear_search_hits_traverse(_DtCvSegment* seg)
637 unsigned long seg_ptype = seg->type & _DtCvPRIMARY_MASK;
639 if (seg_ptype == _DtCvSTRING && seg->client_use) {
640 if (seg->type & _DtCvSEARCH_FLAG)
642 ~(_DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END |
646 if (seg_ptype == _DtCvCONTAINER) { // traverse subordinates
647 _DtCvSegment* subordinates;
648 if ((subordinates = seg->handle.container.seg_list) != NULL)
649 clear_search_hits_traverse(subordinates);
651 else if (seg_ptype == _DtCvTABLE) {
652 _DtCvSegment** cell = seg->handle.table.cells;
653 for (; *cell; cell++)
654 clear_search_hits_traverse(*cell);
658 _DtCvSegment* siblings;
659 if ((siblings = seg->next_seg) != NULL)
660 clear_search_hits_traverse(siblings);
666 NodeViewInfo::clear_search_hits()
668 // retrieve the top container
669 _DtCvSegment* root_seg;
670 if ((root_seg = top_container()) == NULL)
673 clear_search_hits_traverse(root_seg);
675 f_hits.clearAndDestroy();
676 f_current_hit = NULL;
680 NodeViewInfo::set_search_hits(UAS_Pointer<UAS_List<UAS_TextRun> >& hits)
682 if (f_current_hit) { // clear search hits previously displayed
686 // retrieve the top container
687 _DtCvSegment* root_seg;
688 if ((root_seg = top_container()) == NULL)
693 for (idx = 0; idx < hits->length(); idx++) { // for each TextRun
695 UAS_Pointer<UAS_TextRun>& hit = hits->item(idx);
699 if ((seg = traverse_for_vcc(root_seg, hit->offset())) == NULL) {
701 fprintf(stderr, "(DEBUG) traverse_for_vcc failed, offset=%d\n",
708 fprintf(stderr, "(DEBUG) traverse_for_vcc succeeded, offset=%d\n",
712 assert( (seg->type & _DtCvPRIMARY_MASK) == _DtCvSTRING );
714 if ((seg = highlight_search_hit(seg, hit->offset(), hit->length()))) {
716 fprintf(stderr, "(DEBUG) highlight_search_hit succeeded, "
717 "offset=%d\n", hit->offset());
720 _DtCvSEARCH_FLAG | _DtCvSEARCH_BEGIN | _DtCvSEARCH_END;
722 sr_DtCvSegment* sr_seg = new sr_DtCvSegment(seg);
725 seg->type |= _DtCvAPP_FLAG2;
726 f_current_hit = sr_seg;
728 f_hits.append(sr_seg);
732 fprintf(stderr, "(DEBUG) highlight_search_hit failed, offset=%d\n",
738 // returns 0 if upon success. returns -1 if it traversal was not changed.
740 NodeViewInfo::trav_status_t
741 NodeViewInfo::adjust_current_search_hit(trav_dir_t dir)
743 trav_status_t status = SUCCESS;
745 CC_TPtrDlistIterator<sr_DtCvSegment> iter(f_hits);
747 for (++iter; *iter.key() != *f_current_hit;)
751 if (*iter.key() != *f_hits.first())
755 assert( dir == NEXT );
756 if (*iter.key() != *f_hits.last())
760 if (*f_current_hit != *iter.key()) {
761 f_current_hit->hitseg->type &= ~_DtCvAPP_FLAG2;
763 f_current_hit = iter.key();
764 f_current_hit->hitseg->type |= _DtCvAPP_FLAG2;
767 if (*f_current_hit == *f_hits.first())
768 status = REACH_LIMIT;
771 if (*f_current_hit == *f_hits.last())
772 status = REACH_LIMIT;
781 NodeViewInfo::hit_entries() const
783 return f_hits.entries();
787 NodeViewInfo::search_hit_idx()
791 CC_TPtrDlistIterator<sr_DtCvSegment> iter(f_hits);
793 for (i = 0, ++iter; *iter.key() != *f_current_hit; i++)
800 NodeViewInfo::comp_pixel_values_traverse(_DtCvSegment* seg, Display* dpy,
806 unsigned long seg_ptype = seg->type & _DtCvPRIMARY_MASK;
808 if (seg_ptype == _DtCvSTRING && seg->client_use) {
809 XColor screen, exact;
810 SegClientData* pSCD = (SegClientData*)seg->client_use;
811 assert( pSCD->type() == _DtCvSTRING );
813 if (pSCD->bg_color() && pSCD->bg_pixel() == (unsigned long)-1) {
814 UAS_String bg_color = pSCD->bg_color();
815 unsigned long& bg_pixel = f_color_dict[bg_color];
816 if (bg_pixel == (unsigned long)-1) {
817 if (XAllocNamedColor(dpy, cmap, pSCD->bg_color(),
819 pSCD->bg_pixel(bg_pixel = screen.pixel);
822 pSCD->bg_pixel(bg_pixel);
825 if (pSCD->fg_color() && pSCD->fg_pixel() == (unsigned long)-1) {
826 UAS_String fg_color = pSCD->fg_color();
827 unsigned long& fg_pixel = f_color_dict[fg_color];
828 if (fg_pixel == (unsigned long)-1) {
829 if (XAllocNamedColor(dpy, cmap, pSCD->fg_color(),
831 pSCD->fg_pixel(fg_pixel = screen.pixel);
834 pSCD->fg_pixel(fg_pixel);
838 if (seg_ptype == _DtCvCONTAINER) { // traverse subordinates
839 _DtCvSegment* subordinates;
840 if ((subordinates = seg->handle.container.seg_list) != NULL)
841 comp_pixel_values_traverse(subordinates, dpy, cmap);
845 _DtCvSegment* siblings;
846 if ((siblings = seg->next_seg) != NULL)
847 comp_pixel_values_traverse(siblings, dpy, cmap);
853 NodeViewInfo::comp_pixel_values(Display* dpy, Colormap &cmap)
855 // retrieve the top container
856 _DtCvSegment* root_seg;
857 if ((root_seg = top_container()) == NULL)
860 comp_pixel_values_traverse(root_seg, dpy, cmap);
863 DictIter<UAS_String, unsigned long> dictiter;
864 for (dictiter = f_color_dict.first(); dictiter() ; dictiter++) {
865 fprintf(stderr, "(DEBUG) color=\"%s\", pixel=0x%lx\n",
866 (char*)dictiter.key(), dictiter.value());
874 NodeViewInfo::get_segment(unsigned int vcc)
876 return traverse_for_vcc(top_container(), vcc);
880 NodeViewInfo::segment_to_vcc(_DtCvSegment* seg)
882 return DtCvStrVcc(seg);