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) 1994 FUJITSU LIMITED */
24 /* All Rights Reserved */
27 * $TOG: GraphicsMgr.C /main/29 1998/04/17 11:36:15 mgreess $
29 * Copyright (c) 1992 HaL Computer Systems, Inc. All rights reserved.
30 * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
31 * States. Use of a copyright notice is precautionary only and does not
32 * imply publication or disclosure.
34 * This software contains confidential information and trade secrets of HaL
35 * Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
36 * without the prior express written permission of HaL Computer Systems, Inc.
38 * RESTRICTED RIGHTS LEGEND
39 * Use, duplication, or disclosure by the Government is subject to
40 * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
41 * Technical Data and Computer Software clause at DFARS 252.227-7013.
42 * HaL Computer Systems, Inc.
43 * 1315 Dell Avenue, Campbell, CA 95008
47 #include <DtI/GraphicsP.h>
49 #define C_PixmapGraphic
60 #define C_WindowSystem
67 #define C_GraphicAgent
68 #define C_ViewportAgent
76 #include "../cgm/spec.h"
78 #include "utility/funcs.h"
80 LONG_LIVED_CC(GraphicsMgr,graphics_mgr);
82 // ////////////////////////////////////////////////////////////
84 // ////////////////////////////////////////////////////////////
86 GraphicsMgr::GraphicsMgr ()
90 // ////////////////////////////////////////////////////////////
92 // ////////////////////////////////////////////////////////////
94 GraphicsMgr::~GraphicsMgr ()
98 // /////////////////////////////////////////////////////////////////
99 // get_graphic - get a pixmap given a locator and a scale factor
100 // /////////////////////////////////////////////////////////////////
103 GraphicsMgr::get_graphic (UAS_Pointer<Graphic> &gr)
105 extern AppPrintData * l_AppPrintData;
107 String string_resolution ;
109 // if printing, get print resolution from default-printer-resolution
111 if (window_system().printing()) {
112 string_resolution = XpGetOneAttribute(window_system().printDisplay(),
113 l_AppPrintData->f_print_data->print_context,
114 XPDocAttr, "default-printer-resolution") ;
115 resolution = atoi(string_resolution);
116 XFree(string_resolution);
119 // if not printing, or default-printer-resolution not defined, calcuate from
120 // the X screen resolution
124 // calculate the display (or printer) resolution in dots per inch.
127 (254 * WidthOfScreen(window_system().screen()) +
128 5 * WidthMMOfScreen(window_system().screen())) /
129 (10 * WidthMMOfScreen(window_system().screen())) ;
131 // cgm needs resolution to be 100--this is to fix
132 // fit_graphic_to_window problem.
133 UAS_String cgm_type("application/CGM");
134 if(cgm_type == gr->content_type())
139 return get_graphic(gr->data(), gr->data_length(), gr->content_type(), resolution);
142 // /////////////////////////////////////////////////////////////////
143 // get_graphic - get a pixmap given a locator
144 // /////////////////////////////////////////////////////////////////
147 GraphicsMgr::get_graphic (const UAS_String &imdata,
149 const UAS_String &imtype,
150 unsigned short scale_factor)
152 //ON_DEBUG(cerr << "GraphicsMgr::get_graphic( " << gr->locator() << " )" << endl);
153 //ON_DEBUG(cerr << "type = " << gr->content_type() << endl);
154 ON_DEBUG(cerr << "type = " << imtype << endl);
156 // made changes to the interface to allow the image data to be passed in instead
157 // of the graphic object. this is to allow the image data to be saved before
158 // it is passed to this method. when scaling is done, need to be able to scale
159 // the original data each time. this is why the image data is saved before calling
160 // this method. EAM - 6/27/96
161 static int initialized=0;
165 _DtGrRegisterConverter("CGM", processCGM, NULL, NULL, NULL);
170 UAS_String content_type(imtype);
172 // if content_type is a NULL string, image type is unknown
173 if (content_type == "")
175 image_type = "unknown";
179 image_type = content_type;
180 image_type = strchr(image_type, '/');
183 image_type++; // advance past the '/'
186 // this is called by a graphic to retrieve the pixmap
188 PixmapGraphic *the_pixmap = NULL ;
190 Dimension width = 0 ;
191 Dimension height = 0;
193 //if (gr == (const int)NULL)
194 if ((char*)imdata == (char*)NULL)
196 fprintf (stderr, "*** Graphic not found in database ***\n");
197 throw (CASTEXCEPT Exception());
200 // setup the DtGrStream Buffer
202 _DtGrStream gr_stream ;
204 UAS_String base(imdata);
206 gr_stream.type = _DtGrBUFFER ;
207 gr_stream.source.buffer.base = base ;
208 gr_stream.source.buffer.size = length;
209 gr_stream.source.buffer.current = (char*)gr_stream.source.buffer.base ;
210 gr_stream.source.buffer.end = (char *)(gr_stream.source.buffer.base + gr_stream.source.buffer.size) ;
212 // get some basic graphical info to pass to the routine
219 Pixel foreground, background ;
225 XtSetArg(arg[n], XmNdepth, &depth) ; n++ ;
226 XtSetArg(arg[n], XmNcolormap, &colormap) ; n++ ;
227 XtSetArg(arg[n], XmNscreen, &screen) ; n++ ;
228 XtSetArg(arg[n], XmNvisual, &visual) ; n++ ;
229 XtSetArg(arg[n], XmNforeground, &foreground) ; n++ ;
230 XtSetArg(arg[n], XmNbackground, &background) ; n++ ;
232 XtGetValues(window_system().toplevel(), arg, n) ;
234 if (visual == CopyFromParent) {
235 visual= DefaultVisualOfScreen(screen);
239 cerr << "depth: " << depth << "\tcolormap: " << colormap <<
240 "\tscreen: " << screen << "\tvisual: " << visual << endl;
244 int ret_num_colors = 0;
245 Pixel *ret_colors = 0;
246 Pixmap ret_pixmap = 0;
249 if (!strcasecmp (image_type, "unknown")) {
250 // If it is unknown at this point then it needs to be nulled out so the
251 // graphics api will determine the type.
255 if (!strcasecmp (image_type, "XBM")) {
256 // match up infolib name for XBM to DtGr library
260 if (!strcasecmp (image_type, "XPM")) {
261 // match up infolib name for XPM to DtGr library
266 if (!image_type || !strcasecmp (image_type, "unknown"))
270 // Context struct is required for TIFF data type only
271 _DtGrContext *ret_context = NULL ;
272 if (!strcasecmp (image_type, "TIFF")) {
273 ret_context = new _DtGrContext ;
274 ret_context->image_type = NULL ;
275 ret_context->context = NULL ;
279 _DtGrLoadStatus status =
280 _DtGrLoad(&gr_stream, // image
288 XDefaultGCOfScreen(screen),
289 _DtGrCOLOR, // color_model
290 FALSE, // don't allow reduced colors
293 scale_factor, // media_resolution
301 if (status == _DtGrCOLOR_FAILED)
305 "Insufficient color cells for graphic. Retry with degraded colors.\n" );
307 _DtGrLoadStatus status =
308 _DtGrLoad(&gr_stream, // image
316 XDefaultGCOfScreen(screen),
317 _DtGrCOLOR, // color_model
318 TRUE, // allow reduced colors
321 scale_factor, // media_resolution
330 if ((status == _DtGrSUCCESS) ||
331 (status == _DtGrCOLOR_REDUCE))
333 // get rid of memory the routine may have allocated for XPM,
334 // but which is not needed
336 XFreePixmap (window_system().display(), ret_mask);
339 // build our pixmap object
340 the_pixmap = new PixmapGraphic(ret_pixmap,
341 width, height, PixmapGraphic::NORMAL);
344 "pixmap %lx used to create PixmapGraphic %p\n", ret_pixmap, the_pixmap );
347 // set the associated colormap reservations so they can be freed later.
348 // Note static local struct ptr ret_context is used for TIFF.
349 the_pixmap->set_colormap( colormap, ret_num_colors, ret_colors,
354 const char *statusv ;
358 statusv = " _DtGrSUCCESS";
360 case _DtGrCOLOR_REDUCE:
361 statusv = "_DtGrCOLOR_REDUCE";
363 case _DtGrCONVERT_FAILURE:
364 statusv = " _DtGrCONVERT_FAILURE";
366 case _DtGrOPEN_FAILED:
367 statusv = "_DtGrOPEN_FAILED";
369 case _DtGrFILE_INVALID:
370 statusv = "_DtGrFILE_INVALID";
373 statusv = "_DtGrNO_MEMORY";
375 case _DtGrCOLOR_FAILED:
376 statusv = "_DtGrCOLOR_FAILED";
379 statusv = "Unknown" ;
381 cerr << "status = " << statusv << " " << status << endl ;
386 /* -------- Fallback by reading in default graphic. -------- */
387 if (the_pixmap == NULL)
389 Pixmap pixmap = window_system().default_pixmap(&width, &height);
392 the_pixmap = new PixmapGraphic(pixmap,
394 PixmapGraphic::DEFAULT_PIXMAP);
402 // /////////////////////////////////////////////////////////////////////////
404 // /////////////////////////////////////////////////////////////////////////
407 GraphicsMgr::detach (UAS_Pointer<UAS_Common> &node_ptr,
408 UAS_Pointer<Graphic> &gr)
410 // called from ViewportAgent
411 // ViewportAgent will actually remove it from display
413 gr->set_detached(TRUE);
414 PixmapGraphic *pgraphic = gr->pixmap_graphic();
415 GraphicAgent *ga = new GraphicAgent(node_ptr, gr);
419 // add graphic agent to list if not already there.
422 DetachGraphic dg(gr, ga);
423 //pgraphic->UAS_Sender<DetachGraphic>::send_message(dg);
424 UAS_Sender<DetachGraphic>::send_message(dg);
431 GraphicsMgr::detached_graphic()
433 Dimension width, height;
435 Pixmap pixmap = window_system().detached_pixmap (&width, &height);
437 return new PixmapGraphic(pixmap, width, height,
438 PixmapGraphic::DETACHED_PIXMAP);
443 GraphicsMgr::reattach_graphic(UAS_Pointer<Graphic> &gr)
446 gr->set_detached(FALSE);
447 ReAttachGraphic rg(gr);
448 UAS_Sender<ReAttachGraphic>::send_message(rg);
449 UAS_String locator_str = gr->locator();
450 GraphicAgent *ga = get_agent(locator_str);
457 GraphicsMgr::uncache(Graphic *gr)
459 ON_DEBUG(cerr << "GraphicsMgr uncache: " << gr << endl);
460 List_Iterator<Graphic* > cursor(&f_graphic_cache) ;
461 for (; cursor; cursor++)
463 if (cursor.item() == gr)
465 ON_DEBUG(cerr << "found...uncache" << endl);
466 f_graphic_cache.remove(cursor);
467 break; // exit, return
473 GraphicsMgr::get(UAS_Pointer<UAS_Common> &node_ptr, const char *locator)
477 // iterate through the list looking for our graphic.
479 List_Iterator<Graphic * > cursor (&f_graphic_cache);
481 for (; cursor; cursor++)
482 if (cursor.item()->locator() == locator)
483 return cursor.item();
486 //Graphic *gr = new Graphic (node_ptr, locator);
487 UAS_Pointer<Graphic> gr(new Graphic (node_ptr, locator));
490 f_graphic_cache.insert (gr);
496 gr->set_detached(TRUE);
503 GraphicsMgr::get_agent(UAS_String &locator)
505 // iterate through the list looking for our graphic.
506 // if our graphic is in the list, return it.
507 // Otherwise, return NULL.
508 List_Iterator<GraphicAgent*> dgl (&f_detached_list);
512 UAS_Pointer<Graphic> gr(dgl.item()->graphic());
513 if (gr->locator() == locator)
520 GraphicsMgr::add_detached(GraphicAgent *ga)
522 UAS_Pointer<Graphic> gr(ga->graphic());
524 f_detached_list.insert(ga);
529 GraphicsMgr::remove_detached(GraphicAgent *ga)
531 // iterate through the list looking for our graphic.
532 // if our graphic is in the list, return it.
533 // Otherwise, return NULL.
534 List_Iterator<GraphicAgent*> dgl (&f_detached_list);
539 UAS_Pointer<Graphic> oldgr = ga->graphic();
543 UAS_Pointer<Graphic> gr(dgl.item()->graphic());
544 if (gr->locator() == oldgr->locator())
546 f_detached_list.remove(ga);
553 GraphicsMgr::is_detached(UAS_Pointer<Graphic> &gr)
555 // iterate through the list looking for our graphic.
556 // if our graphic is in the list, return True.
557 // Otherwise, return False.
558 List_Iterator<GraphicAgent*> dgl (&f_detached_list);
562 UAS_Pointer<Graphic> g = dgl.item()->graphic();
563 if (gr->locator() == g->locator())
572 GraphicsMgr::init_gr(UAS_Pointer<Graphic> &gr)
574 //gr->detached_graphic();
575 //gr->pixmap_graphic();
576 gr->set_detached(TRUE);
577 //ga->set_graphic(gr);
580 ///////////////////////////////////////////////////////////////////////////////
581 ///////////////////////////////////////////////////////////////////////////////
583 // Graphic implementation
585 ///////////////////////////////////////////////////////////////////////////////
586 ///////////////////////////////////////////////////////////////////////////////
588 Graphic::Graphic (UAS_Pointer<UAS_Common> &doc, const UAS_String &locator):
592 fObj (doc->create_embedded_object (locator)) {
595 Graphic::~Graphic () {
596 //graphics_mgr().uncache(this);
597 //graphics_mgr().remove_detached(this);
599 printf( "for Graphic %p, delete PixmapGraphic %p\n", this, fPixmap );
602 delete fDetachedPixmap;
606 // If this one is called instead of the null arg version, the resulting
607 // PixmapGraphic instance is not tracked nor recorded by this instance
609 Graphic::pixmap_graphic (UAS_String& imdata,
611 UAS_String& imtype, unsigned short scale) {
612 PixmapGraphic *the_pixmap;
613 //UAS_Pointer<Graphic> tmp(this);
617 the_pixmap = graphics_mgr().get_graphic (imdata, imlen, imtype, scale);
622 Graphic::pixmap_graphic () {
623 UAS_Pointer<Graphic> tmp(this);
624 // fPixmap records the PixmapGraphic & pixmap once created (and only
625 // if created via this method) for this instance of Graphic
627 fPixmap = graphics_mgr().get_graphic (tmp);
632 Graphic::detached_graphic () {
633 if (!fDetachedPixmap)
634 fDetachedPixmap = graphics_mgr().detached_graphic();
635 return fDetachedPixmap;
638 UAS_String Graphic::title()
640 return fObj->title();
643 UAS_String Graphic::content_type()
645 return fObj->content_type();
648 UAS_String Graphic::locator()
650 return fObj->locator() ;
653 UAS_String Graphic::id()