home *** CD-ROM | disk | FTP | other *** search
- /* $XConsortium: wsb.c,v 5.8 93/01/27 16:07:36 mor Exp $ */
-
- /***********************************************************
- Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. and the X Consortium.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the names of Sun Microsystems,
- the X Consortium, and MIT not be used in advertising or publicity
- pertaining to distribution of the software without specific, written
- prior permission.
-
- SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
- SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
-
- ******************************************************************/
-
- /* PEX/PHIGS workstation utility functions for the B model (client side
- * workstations and structure storage).
- */
-
- #include "phg.h"
- #include "cp.h"
- #include "ws.h"
- #include "css.h"
- #include "alloc.h"
- #include "PEX.h"
- #include "PEXproto.h"
- #include "PEXmacs.h"
- #include "PEXfuncs.h"
- #include "phigspex.h"
-
-
- static void
- wsb_load_funcs( ws )
- Ws *ws;
- {
- ws->close = phg_wsb_close_ws;
- ws->redraw_all = phg_wsb_redraw_all;
- ws->conditional_redraw = phg_wsb_conditional_redraw;
- ws->repaint_all = phg_wsb_repaint_all;
- ws->make_requested_current = phg_wsb_make_requested_current;
- ws->update = phg_wsb_update;
- ws->set_disp_update_state = phg_wsb_set_disp_update_state;
- ws->set_rep = phg_wsb_set_rep;
- ws->set_filter = phg_wsb_set_filter;
- ws->set_colour_model = (void(*)())NULL; /* state set by CP */
- ws->set_hlhsr_mode = phg_wsb_set_hlhsr_mode;
- ws->set_view_input_priority = phg_wsb_set_view_input_priority;
- ws->set_ws_window = phg_wsb_set_ws_window;
- ws->set_ws_vp = phg_wsb_set_ws_vp;
- ws->delete_el_for_repl = (void(*)())NULL; /* not used */
- ws->add_el = phg_wsb_add_el;
- ws->copy_struct = phg_wsb_copy_struct;
- ws->close_struct = phg_wsb_close_struct;
- ws->move_ep = (void(*)())NULL; /* not used */
- ws->delete_el = phg_wsb_delete_el;
- ws->delete_struct = phg_wsb_delete_struct;
- ws->delete_struct_net = phg_wsb_delete_struct_net;
- ws->delete_all_structs = phg_wsb_delete_all_structs;
- ws->post = phg_wsb_post;
- ws->unpost = phg_wsb_unpost;
- ws->unpost_all = phg_wsb_unpost_all;
- ws->change_posting = phg_wsb_change_posting;
- ws->drawable_pick = phg_wsb_drawable_pick;
- ws->map_points = phg_wsb_map_points;
- ws->redraw_regions = phg_wsb_redraw_regions;
-
- ws->inq_view_indices = phg_wsb_inq_view_indices;
- ws->inq_bundle_indices = phg_wsx_inq_LUT_indices;
- ws->inq_posted = phg_wsb_inq_posted;
- ws->inq_representation = phg_wsb_inq_rep;
- ws->inq_view_rep = phg_wsb_inq_view_rep;
- ws->inq_ws_xform = phg_wsb_inq_ws_xform;
- ws->inq_disp_update_state = phg_wsb_inq_disp_update_state;
- ws->inq_filter = phg_wsb_inq_filter;
- ws->inq_hlhsr_mode = phg_wsb_inq_hlhsr_mode;
- ws->inq_colour_model = (void(*)())NULL; /* have CP return it */
- }
-
- /*
- * Tables that determine what update action is valid at a give point
- * in time. The table has 3 axes:
- * [Time] [Modification Mode] [Deferral Mode].
- */
-
- static Ws_action_table default_action_table =
- {
- { /* PHG_TIME_NOW */
- { /* NIVE */
- PHG_UPDATE_ACCURATE, /* ASAP */
- PHG_UPDATE_IF_IG, /* BNIG */
- PHG_UPDATE_IF_IL, /* BNIL */
- PHG_UPDATE_NOTHING, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- { /* UWOR */
- PHG_UPDATE_ACCURATE, /* ASAP */
- PHG_UPDATE_IF_IG, /* BNIG */
- PHG_UPDATE_IF_IL, /* BNIL */
- PHG_UPDATE_UWOR, /* ASTI */
- PHG_UPDATE_UWOR /* WAIT */
- },
- { /* UQUM */
- PHG_UPDATE_ACCURATE, /* ASAP */
- PHG_UPDATE_IF_IG, /* BNIG */
- PHG_UPDATE_IF_IL, /* BNIL */
- PHG_UPDATE_UQUM, /* ASTI */
- PHG_UPDATE_UQUM /* WAIT */
- },
- },
-
- { /* PHG_TIME_BIG */
- { /* NIVE */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_ACCURATE, /* BNIG */
- PHG_UPDATE_NOTHING, /* BNIL */
- PHG_UPDATE_NOTHING, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- { /* UWOR */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_ACCURATE, /* BNIG */
- PHG_UPDATE_NOTHING, /* BNIL */
- PHG_UPDATE_NOTHING, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- { /* UQUM */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_ACCURATE, /* BNIG */
- PHG_UPDATE_NOTHING, /* BNIL */
- PHG_UPDATE_NOTHING, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- },
- { /* PHG_TIME_BIL */
- { /* NIVE */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_ACCURATE, /* BNIG */
- PHG_UPDATE_ACCURATE, /* BNIL */
- PHG_UPDATE_NOTHING, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- { /* UWOR */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_ACCURATE, /* BNIG */
- PHG_UPDATE_ACCURATE, /* BNIL */
- PHG_UPDATE_NOTHING, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- { /* UQUM */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_ACCURATE, /* BNIG */
- PHG_UPDATE_ACCURATE, /* BNIL */
- PHG_UPDATE_NOTHING, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- },
- { /* PHG_TIME_ATI */
- { /* NIVE */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_IF_INCORRECT, /* BNIG */
- PHG_UPDATE_IF_INCORRECT, /* BNIL */
- PHG_UPDATE_ACCURATE, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- { /* UWOR */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_IF_INCORRECT, /* BNIG */
- PHG_UPDATE_IF_INCORRECT, /* BNIL */
- PHG_UPDATE_ACCURATE, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- { /* UQUM */
- ASSURE_CORRECT, /* ASAP */
- PHG_UPDATE_IF_INCORRECT, /* BNIG */
- PHG_UPDATE_IF_INCORRECT, /* BNIL */
- PHG_UPDATE_ACCURATE, /* ASTI */
- PHG_UPDATE_NOTHING /* WAIT */
- },
- }
- };
-
-
- static
- void
- init_update_state( ws, wst )
- Ws *ws;
- Wst *wst;
- {
- register Ws_output_ws *ows = &ws->out_ws;
- register Wsb_output_ws *owsb = &ows->model.b;
-
- ows->def_mode = ws->type->desc_tbl.phigs_dt.out_dt.deferral_mode;
- ows->mod_mode = ws->type->desc_tbl.phigs_dt.out_dt.modification_mode;
-
- owsb->update_action_table = (Ws_action_table_ptr)default_action_table;
-
- /* cache action for time "NOW" */
- owsb->now_action = (*owsb->update_action_table)
- [(int)PHG_TIME_NOW][(int)ows->mod_mode][(int)ows->def_mode];
-
- owsb->vis_rep = PVISUAL_ST_CORRECT;
- owsb->surf_state = PSURF_EMPTY;
- }
-
-
- static int
- init_view_table( ws, wst )
- Ws *ws;
- Wst *wst;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- register Ws_view_entry *view;
- register Pview_rep3 *predef_view;
- register int i, max_pd_view;
-
- ALLOC_DECLARE(5);
-
- /* Allocate and initiailize the view table to correspond to the
- * predefined views in the PEX view LUT. This code puts a limit on the
- * number of view entries that can be defined. This limit may
- * be less than the server's limit.
- */
- owsb->num_views = ws->type->desc_tbl.phigs_dt.num_view_indices;
-
- if ( !ALLOCATED( owsb->views = (Ws_view_entry *)
- malloc((unsigned)(owsb->num_views * sizeof(Ws_view_entry)))) ) {
- ERR_BUF( ws->erh, ERR900 );
- return 0;
- }
-
- owsb->top_view = 0;
- if ( !ALLOCATED( owsb->view_priorities = (Ws_view_priority *)
- malloc((unsigned)(owsb->num_views * sizeof(Ws_view_priority)))) ) {
- ERR_BUF( ws->erh, ERR900 );
- ALLOC_FREE;
- return 0;
- }
-
- owsb->num_pending_views = 0;
- if ( !ALLOCATED( owsb->pending_views = (Ws_pending_view *)
- malloc((unsigned)(owsb->num_views * sizeof(Ws_pending_view)))) ) {
- ERR_BUF( ws->erh, ERR900 );
- ALLOC_FREE;
- return 0;
- }
-
- max_pd_view = wst->desc_tbl.phigs_dt.num_predefined_views - 1;
- predef_view = wst->desc_tbl.phigs_dt.default_views;
- view = owsb->views;
- /* Load the predefined views. */
- for ( i = 0; i <= max_pd_view; i++, predef_view++, view++ ) {
- view->pending = PUPD_NOT_PEND;
- bcopy( (char *)predef_view->ori_matrix,(char *) view->vom,
- sizeof(Pmatrix3) );
- bcopy( (char *)predef_view->map_matrix, (char *)view->vmm,
- sizeof(Pmatrix3) );
- view->clip_limit = predef_view->clip_limit;
- view->xy_clip = predef_view->xy_clip;
- view->back_clip = predef_view->back_clip;
- view->front_clip = predef_view->front_clip;
- /* view->npc_to_wc not computed until needed in input code. */
- view->npc_to_wc_state = WS_INV_NOT_CURRENT;
- }
-
- /* Load the available but not predefined views. */
- for ( /* use existing index */ ; i < owsb->num_views; i++, view++ )
- *view = owsb->views[0];
-
- /* Initialize the view transformation priorities. The list is
- * terminated at top and bottom by -1.
- */
- for ( i = 0; i < owsb->num_views; i++ ) {
- owsb->view_priorities[i].higher = i - 1;
- owsb->view_priorities[i].lower = i + 1;
- }
- owsb->view_priorities[owsb->num_views - 1].lower = -1;
-
- return 1;
- }
-
-
- static int
- init_output_state( ws )
- Ws *ws;
- {
- Wst *wst = ws->type;
-
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- if ( !init_view_table( ws, wst ) )
- return 0;
-
- /* Initialize the workstation transform. */
- owsb->req_ws_window.x_min = 0.0;
- owsb->req_ws_window.x_max = 1.0;
- owsb->req_ws_window.y_min = 0.0;
- owsb->req_ws_window.y_max = 1.0;
- owsb->req_ws_window.z_min = 0.0;
- owsb->req_ws_window.z_max = 1.0;
- owsb->ws_window = owsb->req_ws_window;
- owsb->ws_window_pending = PUPD_NOT_PEND;
-
- owsb->req_ws_viewport.x_min = 0.0;
- owsb->req_ws_viewport.x_max = ws->ws_rect.width;
- owsb->req_ws_viewport.y_min = 0.0;
- owsb->req_ws_viewport.y_max = ws->ws_rect.height;
- owsb->req_ws_viewport.z_min = 0.0;
- owsb->req_ws_viewport.z_max = 1.0;
- owsb->ws_viewport = owsb->req_ws_viewport;
- owsb->ws_viewport_pending = PUPD_NOT_PEND;
-
- phg_wsx_compute_ws_transform( &owsb->ws_window, &owsb->ws_viewport,
- &owsb->ws_xform );
-
- /* Initialize the list of posted structs. */
- owsb->posted.lowest.higher = &owsb->posted.highest;
- owsb->posted.lowest.lower = NULL;
- owsb->posted.highest.higher = NULL;
- owsb->posted.highest.lower = &owsb->posted.lowest;
-
- /* Initialize other miscellaneous output state. */
- owsb->cur_hlhsr_mode = PHIGS_HLHSR_MODE_NONE;
- owsb->req_hlhsr_mode = PHIGS_HLHSR_MODE_NONE;
- owsb->hlhsr_mode_pending = PUPD_NOT_PEND;
-
- return 1;
- }
-
- static int
- wsb_init_resources( ws )
- Ws *ws;
- {
- CARD16 count;
- CARD32 size, *rid_list;
- pexTableIndex start;
- pexBitmask pmask[PEXMSPipeline], rmask;
- CARD32 *card32_p;
- pexReflectionAttr *refl_attr, *bf_refl_attr;
- pexFloatColour *spec_colr, *bf_spec_colr;
- pexViewport *vp;
-
- register int i;
- register Ws_view_entry *view;
- register pexViewEntry *pex_view;
-
- /* Initialize all the predefined table entries from the WDT. */
- if ( !phg_wsx_init_LUTs( ws, 1 ) )
- return 0;
-
- /* Initialize the Pipeline Context. Since PEX and PHIGS defaults
- * are different for reflection attrs and culling mode, set those in
- * PEX when creating the context.
- */
- size = 0;
- bzero((char *)pmask, sizeof(pmask));
- PEX_BITSET(pmask,PEXPCSurfaceReflAttr);
- size += sizeof(*refl_attr) + sizeof(*spec_colr);
- refl_attr = (pexReflectionAttr *)ws->scratch.buf;
- spec_colr = (pexFloatColour *)(refl_attr + 1);
- refl_attr->ambient = 1.0;
- refl_attr->diffuse = 1.0;
- refl_attr->specular = 1.0;
- refl_attr->specularConc = 0.0;
- refl_attr->transmission = 0.0;
- refl_attr->specularColour.colourType = PEXRgbFloatColour;
- spec_colr->first = spec_colr->second = spec_colr->third = 1.0;
- PEX_BITSET(pmask,PEXPCBfSurfaceReflAttr);
- size += sizeof(*bf_refl_attr) + sizeof(*bf_spec_colr);
- bf_refl_attr = (pexReflectionAttr *)(spec_colr + 1);
- *bf_refl_attr = *refl_attr;
- bf_spec_colr = (pexFloatColour *)(bf_refl_attr + 1);
- *bf_spec_colr = *spec_colr;
- PEX_BITSET(pmask,PEXPCCullingMode); size += sizeof(CARD32);
- card32_p = (CARD32 *)(bf_spec_colr + 1);
- *card32_p = 0;
- (void)PEXChangePipelineContext( ws->display, ws->out_ws.model.b.pipeline,
- pmask, size, (char *)ws->scratch.buf );
-
- /* Initialize the renderer. */
- size = 0;
- bzero((char *)&rmask, sizeof(rmask));
- rid_list = (XID *)ws->scratch.buf;
- /* The way the bits are defined in PEX.h doesn't allow the use of
- * PEX_BITSET().
- */
- rmask |= PEXRDPipelineContext; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.model.b.pipeline;
- rmask |= PEXRDMarkerBundle; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.marker;
- rmask |= PEXRDTextBundle; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.text;
- rmask |= PEXRDLineBundle; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.line;
- rmask |= PEXRDInteriorBundle; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.interior;
- rmask |= PEXRDEdgeBundle; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.edge;
- rmask |= PEXRDViewTable; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.view;
- rmask |= PEXRDColourTable; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.colour;
- rmask |= PEXRDDepthCueTable; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.depth_cue;
- rmask |= PEXRDLightTable; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.light_source;
- rmask |= PEXRDColourApproxTable; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.colour_approx;
- rmask |= PEXRDPatternTable; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.pattern;
- rmask |= PEXRDTextFontTable; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.lut.font;
- rmask |= PEXRDHighlightIncl; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.nset.hlt_incl;
- rmask |= PEXRDHighlightExcl; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.nset.hlt_excl;
- rmask |= PEXRDInvisibilityIncl; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.nset.invis_incl;
- rmask |= PEXRDInvisibilityExcl; size += sizeof(CARD32);
- *rid_list++ = ws->out_ws.nset.invis_excl;
- rmask |= PEXRDHlhsrMode; size += sizeof(CARD32);
- *rid_list++ = (CARD32)PEX_CONV_PHIGS_HLHSR_MODE(PHIGS_HLHSR_MODE_NONE);
- rmask |= PEXRDViewport; size += sizeof(pexViewport);
- vp = (pexViewport *)rid_list++;
- vp->minval.x = ws->out_ws.model.b.req_ws_viewport.x_min;
- vp->minval.y = ws->out_ws.model.b.req_ws_viewport.y_min;
- vp->minval.z = ws->out_ws.model.b.req_ws_viewport.z_min;
- vp->maxval.x = ws->out_ws.model.b.req_ws_viewport.x_max;
- vp->maxval.y = ws->out_ws.model.b.req_ws_viewport.y_max;
- vp->maxval.z = ws->out_ws.model.b.req_ws_viewport.z_max;
- vp->useDrawable = 0;
- /* No need to set the NPC volume since the PEX default is correct. */
- (void)PEXChangeRenderer( ws->display, ws->rid, rmask, size,
- (char *)ws->scratch.buf );
-
- return 1;
- }
-
- static int
- wsb_create_resources( ws )
- Ws *ws;
- {
- pexBitmask pmask[PEXMSPipeline];
- pexBitmask dyn_tbls, dyn_nsets, dyn_attrs;
- Pint err;
- CARD16 *card16_p;
- Drawable draw;
- int numbufs, mbuf_event_base, mbuf_error_base;;
-
-
- /* Create the LUTs, renderer and pipeline context. */
- if ( !phg_wsx_create_LUTs( ws, 1, &err ) ) {
- ERR_BUF( ws->erh, err );
- return 0;
- }
-
- /* Create the pipeline context. */
- ws->out_ws.model.b.pipeline = XAllocID(ws->display);
- (void)PEXCreatePipelineContext( ws->display, ws->out_ws.model.b.pipeline,
- (pexBitmask *)NULL, (CARD32)0, (char *)NULL );
-
- /* Make an inquiry to see if the create worked. */
- /* TODO: Remove when GetPipeline fixed.
- bzero((char *)pmask, sizeof(pmask));
- PEX_BITSET(pmask,PEXPCCullingMode);
- if ( !PEXGetPipelineContext( ws->display, ws->out_ws.model.b.pipeline,
- pmask, (char **)&card16_p ) ) {
- ERR_BUF( ws->erh, ERRN202 );
- return 0;
- }
- */
-
- /* Check the Workstation buffer mode and do the double buffer
- create here if necessary This is simpler than on the workstation
- since this PHIGS implementation only lets the Double Buffers
- be created when the workstation is created, so no change action
- need be done
- */
-
- /* initialize the local drawable variable */
- draw = ws->drawable_id;
- ws->out_ws.model.b.has_double_buffer = FALSE;
-
- if (ws->type->desc_tbl.xwin_dt.buffer_mode == PHIGS_BUF_DOUBLE) {
- if (XmbufQueryExtension(ws->display, &mbuf_event_base, &mbuf_error_base)){
-
- /* the Multi-Buffer extension is there */
- numbufs = XmbufCreateBuffers(ws->display, ws->drawable_id, 2,
- MultibufferUpdateActionBackground,
- MultibufferUpdateHintFrequent,
- &ws->out_ws.model.b.double_drawable[0]);
- if (numbufs == 2) {
- /* got the buffers OK */
- ws->out_ws.model.b.front = 0;
- ws->out_ws.model.b.back = 1;
- ws->out_ws.model.b.has_double_buffer = TRUE;
- draw = ws->out_ws.model.b.double_drawable[1];
- /* this isn't implemented yet
- XmbufClearBufferArea(ws->display, draw, 0, 0, 0, 0, False);
- */
- } else
- /* buffers didn't get created correctly, bag them */
- XmbufDestroyBuffers(ws->display, ws->drawable_id);
- }
- }
-
-
- /* Create the renderer, initializing the necessary attributes. */
- ws->rid = XAllocID(ws->display);
- (void)PEXCreateRenderer( ws->display, ws->rid, draw,
- (pexBitmask)0, (CARD32)0, (char *)NULL );
-
- /* Make an inquiry to see if the create worked. */
- if ( !PEXGetRendererDynamics( ws->display, ws->rid, &dyn_tbls,
- &dyn_nsets, &dyn_attrs ) ) {
- ERR_BUF( ws->erh, ERRN202 );
- return 0;
- }
-
- return 1;
- }
-
-
- static void
- wsb_update_wdt( ws )
- Ws *ws;
- {
- /* Update the dynamics flags -- everything IRG for client-side WSs. */
- ws->type->desc_tbl.phigs_dt.out_dt.view_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.polyline_bundle_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.polymarker_bundle_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.text_bundle_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.interior_bundle_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.edge_bundle_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.pattern_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.colour_rep = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.ws_xform = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.highlight_filter = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.invis_filter = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.hlhsr_mode = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.struct_content_mod = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.post = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.unpost = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.struct_delete = PDYN_IRG;
- ws->type->desc_tbl.phigs_dt.out_dt.ref_mod = PDYN_IRG;
- }
-
-
- Ws*
- phg_wsb_open_ws( cph, cp_args, ret, css_srvr )
- Cp_handle cph;
- Phg_args *cp_args;
- Phg_ret *ret;
- Cpx_css_srvr *css_srvr;
- {
- void wsb_destroy_ws();
- Phg_args_open_ws *args = &cp_args->data.open_ws;
- char *avlist[4];
- Ws *ws;
- XWindowAttributes wattr;
- Phg_pex_ext_info pex_info;
-
- ret->err = -1;
- if ( !(ws = phg_wsx_create( cph, args, css_srvr )) )
- return ws;
-
- switch ( args->type->base_type ) {
- case WST_BASE_TYPE_X_DRAWABLE:
- ws->display = args->conn_info.display;
- ws->drawable_id = args->conn_info.drawable_id;
- phg_cpx_instance_connection( cph, ws->display, 0 );
- break;
-
- case WST_BASE_TYPE_X_TOOL:
- /* Get a display connection for it. */
- if ( (ws->display = phg_cpx_connection_exists( cph, CPX_BY_NAME,
- args->conn_info.display_name )) ) {
- /* We know PEX is supported on this display because it's in
- * the CPs connection list.
- */
- phg_cpx_instance_connection( cph, ws->display, 0 );
- } else if ( ws->display = phg_utx_open_pex_display(
- args->conn_info.display_name, &pex_info, &ret->err ) ) {
- phg_cpx_instance_connection( cph, ws->display, 1 );
- } else {
- ERR_BUF( ws->erh, ret->err );
- goto abort;
- }
-
- /* Create the window. */
- if ( !phg_wsx_setup_tool( ws, &args->conn_info, args->type ) )
- goto abort;
- break;
- }
-
- (void)XGetWindowAttributes( ws->display, ws->drawable_id, &wattr );
- WS_SET_WS_RECT( ws, &wattr )
-
- /* Build an accurate WDT after the window is open. */
- avlist[0] = PHIGS_X_DISPLAY_WINDOW;
- avlist[1] = (char *)ws->display;
- avlist[2] = (char *)ws->drawable_id;
- avlist[3] = (char *)0;
- if ( ws->type = phg_wst_create( cph->erh, args->type, avlist ) ) {
- ws->type->wsid = ws->id;
- ws->type->bound_status = WST_BOUND;
- wsb_update_wdt( ws );
- } else
- goto abort;
-
- ws->current_colour_model =
- ws->type->desc_tbl.phigs_dt.out_dt.default_colour_model;
- ws->category = ws->type->desc_tbl.phigs_dt.ws_category;
- ws->out_ws.model.b.cssh = css_srvr->model.b.cssh;
- if ( !init_output_state( ws ) )
- goto abort;
- init_update_state( ws, ws->type );
-
- /* Create and initialize all the PEX resources. */
- if ( !wsb_create_resources( ws ) )
- goto abort;
- if ( !wsb_init_resources( ws ) )
- goto abort;
-
- if ( !phg_wsx_setup_colormap( ws, &ret->err ) ) {
- ERR_BUF(ws->erh, ret->err);
- goto abort;
- }
-
- wsb_load_funcs( ws );
-
- /* Fill in the WDT fields that depend on an open workstaton. */
- ws->type->desc_tbl.phigs_dt.out_dt.num_display_priorities = 0;
- ws->type->desc_tbl.phigs_dt.dev_coords[0] = ws->ws_rect.width;
- ws->type->desc_tbl.phigs_dt.dev_coords[1] = ws->ws_rect.height;
- ws->type->desc_tbl.phigs_dt.dev_addrs_units[0] = ws->ws_rect.width;
- ws->type->desc_tbl.phigs_dt.dev_addrs_units[1] = ws->ws_rect.height;
-
- /* Fill in the return data. */
- ret->err = 0;
- ret->data.open_ws.wstype = ws->type;
- ret->data.open_ws.wst_buffer = ws->type->buffer;
- ret->data.open_ws.wst_buffer_size = ws->type->buffer_size;
- ret->data.open_ws.drawable_id = ws->drawable_id;
- ret->data.open_ws.overlay_id = ws->input_overlay_window;
-
- return ws;
-
- abort:
- wsb_destroy_ws( ws );
- return (Ws *)NULL;
- }
-
-
- void
- wsb_free_all_posted( owsb )
- Wsb_output_ws *owsb;
- {
- register Ws_post_str *cur, *end;
-
- cur = owsb->posted.lowest.higher;
- end = &owsb->posted.highest;
- while ( cur != end ) {
- cur = cur->higher;
- free( (char *)cur->lower );
- }
- owsb->posted.lowest.higher = end;
- end->lower = &owsb->posted.lowest;
- }
-
-
- void
- wsb_destroy_ws( ws )
- Ws *ws;
- {
- if ( ws ) {
- if ( ws->out_ws.model.b.views )
- free( (char *)ws->out_ws.model.b.views );
- if ( ws->out_ws.model.b.pending_views )
- free( (char *)ws->out_ws.model.b.pending_views );
- if ( ws->out_ws.model.b.view_priorities )
- free( (char *)ws->out_ws.model.b.view_priorities );
- if ( ws->display ) {
- if ( ws->drawable_id )
- phg_wsx_release_window( ws );
- if ( ws->out_ws.model.b.pipeline )
- PEXFreePipelineContext( ws->display,
- ws->out_ws.model.b.pipeline );
- if ( ws->rid )
- PEXFreeRenderer( ws->display, ws->rid );
- phg_wsx_destroy_LUTs( ws );
- XFlush( ws->display );
- phg_cpx_release_connection( ws->cph, ws->display );
- }
- phg_wsx_destroy( ws );
- }
- }
-
-
- void
- phg_wsb_close_ws( ws )
- Ws *ws;
- {
- if ( ws ) {
- wsb_free_all_posted( &ws->out_ws.model.b );
- wsb_destroy_ws( ws );
- }
- }
-
-
- void
- phg_wsb_redraw_all( ws, clear_control )
- Ws *ws;
- Pctrl_flag clear_control;
- {
- (*ws->make_requested_current)( ws );
- (*ws->repaint_all)( ws, clear_control, 0, (XRectangle *)NULL );
- ws->out_ws.model.b.vis_rep = PVISUAL_ST_CORRECT;
- }
-
-
-
- /* Make all "requested" and pending data current. */
- void
- phg_wsb_make_requested_current( ws )
- Ws *ws;
- {
- Ws_view_entry *view;
- Ws_pending_view *req_view;
- pexViewEntry pex_view;
- pexViewport vp;
- pexNpcSubvolume win;
-
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- /* WS transform */
- if ( owsb->ws_window_pending == PUPD_PEND
- || owsb->ws_viewport_pending == PUPD_PEND ) {
- if ( owsb->ws_window_pending == PUPD_PEND ) {
- owsb->ws_window = owsb->req_ws_window;
- owsb->ws_window_pending = PUPD_NOT_PEND;
- win.minval.x = owsb->ws_window.x_min;
- win.minval.y = owsb->ws_window.y_min;
- win.minval.z = owsb->ws_window.z_min;
- win.maxval.x = owsb->ws_window.x_max;
- win.maxval.y = owsb->ws_window.y_max;
- win.maxval.z = owsb->ws_window.z_max;
- (void)PEXChangeRenderer( ws->display, ws->rid,
- (pexBitmask)PEXRDNpcSubvolume,
- (CARD32)sizeof(pexNpcSubvolume), (char *)&win );
- }
-
- if ( owsb->ws_viewport_pending == PUPD_PEND ) {
- owsb->ws_viewport = owsb->req_ws_viewport;
- owsb->ws_viewport_pending = PUPD_NOT_PEND;
- vp.minval.x = owsb->ws_viewport.x_min;
- vp.minval.y = owsb->ws_viewport.y_min;
- vp.minval.z = owsb->ws_viewport.z_min;
- vp.maxval.x = owsb->ws_viewport.x_max;
- vp.maxval.y = owsb->ws_viewport.y_max;
- vp.maxval.z = owsb->ws_viewport.z_max;
- vp.useDrawable = 0;
- (void)PEXChangeRenderer( ws->display, ws->rid,
- (pexBitmask)PEXRDViewport,
- (CARD32)sizeof(pexViewport), (char *)&vp );
- }
-
- phg_wsx_compute_ws_transform( &owsb->ws_window, &owsb->ws_viewport,
- &owsb->ws_xform );
- }
-
- /* View table */
- if ( owsb->num_pending_views > 0 ) {
- req_view = owsb->pending_views;
- while ( owsb->num_pending_views > 0 ) {
- view = &owsb->views[req_view->id];
- /*Set it locally. */
- view->pending = PUPD_NOT_PEND;
- bcopy( (char *)req_view->view.ori_matrix, (char *)view->vom,
- sizeof(Pmatrix3) );
- bcopy( (char *)req_view->view.map_matrix, (char *)view->vmm,
- sizeof(Pmatrix3) );
- view->clip_limit = req_view->view.clip_limit;
- view->xy_clip = req_view->view.xy_clip;
- view->back_clip = req_view->view.back_clip;
- view->front_clip = req_view->view.front_clip;
- view->npc_to_wc_state = WS_INV_NOT_CURRENT;
-
- /* Set it in the server. Can't set them all as a block with one
- * request because the pending views may not be contiguous.
- */
- (void)phg_utx_view_entry_to_pex( &req_view->view, &pex_view );
- (void)PEXSetTableEntries( ws->display, ws->out_ws.lut.view,
- (pexTableIndex)req_view->id, (CARD16)1,
- (CARD32)sizeof(pex_view), (char *)&pex_view );
- ++req_view;
- --owsb->num_pending_views;
- }
- }
-
- /* Other pending data */
- if ( owsb->hlhsr_mode_pending == PUPD_PEND) {
- CARD32 new_mode;
-
- owsb->cur_hlhsr_mode = owsb->req_hlhsr_mode;
- owsb->hlhsr_mode_pending = PUPD_NOT_PEND;
-
- new_mode = (CARD32)PEX_CONV_PHIGS_HLHSR_MODE(owsb->cur_hlhsr_mode);
- (void)PEXChangeRenderer( ws->display, ws->rid,
- (pexBitmask)PEXRDHlhsrMode,
- (CARD32)sizeof(CARD32), (char *)&new_mode);
-
- }
-
- /* Make it all take effect. */
- XFlush( ws->display );
- }
-
-
- void
- phg_wsb_repaint_all( ws, clear_control, num_rects, exposure_rects )
- Ws *ws;
- Pctrl_flag clear_control;
- int num_rects; /* may be 0 */
- XRectangle *exposure_rects; /* may be NULL */
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
- int tmp;
- Drawable draw;
-
- register int i;
-
- /* assuming this stuff does clear then don't do it when using Double Buff
- since the swap will take care of that
- */
- if ((clear_control == PFLAG_ALWAYS || owsb->surf_state == PSURF_NOT_EMPTY)
- && !ws->out_ws.model.b.has_double_buffer) {
- /* TODO: Need a way to "clear" the window that uses the zero-th
- * entry in the WS colour table and runs it through colour mapping.
- */
- if ( num_rects > 0 ) {
- for ( i = 0; i < num_rects; i++ )
- XClearArea( ws->display, ws->drawable_id,
- exposure_rects[i].x, exposure_rects[i].x,
- exposure_rects[i].width, exposure_rects[i].height,
- False );
- } else
- XClearWindow( ws->display, ws->drawable_id );
- }
- owsb->surf_state = PSURF_EMPTY;
-
- /* set the drawable correctly */
- if (ws->out_ws.model.b.has_double_buffer)
- draw = ws->out_ws.model.b.double_drawable[ws->out_ws.model.b.back];
- else /* single buffer */
- draw = ws->drawable_id;
-
- phg_wsb_traverse_all_postings( ws, draw );
-
- /* now swap the buffers and update the drawable indices */
- if (ws->out_ws.model.b.has_double_buffer) {
- XmbufDisplayBuffers(ws->display, 1, &draw, 0, 0);
- tmp = ws->out_ws.model.b.front;
- ws->out_ws.model.b.front = ws->out_ws.model.b.back;
- ws->out_ws.model.b.back = tmp;
- }
-
- /* Redraw input prompts & echos of any active input devices. */
- if ( ws->input_repaint && WS_ANY_INP_DEV_ACTIVE(ws) )
- (ws->input_repaint)( ws, num_rects, exposure_rects );
-
- XFlush( ws->display );
- }
-
-
- void
- phg_wsb_traverse_all_postings( ws, draw )
- Ws *ws;
- Drawable draw;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
- register Ws_post_str *post_str, *end;
-
- WSB_CHECK_POSTED(&owsb->posted)
- if( WSB_SOME_POSTED(&owsb->posted) ) {
- /* Set up for complete traversal. */
- post_str = owsb->posted.lowest.higher;
- end = &(owsb->posted.highest);
- PEXBeginRendering( ws->display, ws->rid, draw);
- while ( post_str != end ) {
- phg_wsb_traverse_net( ws, post_str->structh );
- post_str = post_str->higher;
- }
- PEXEndRendering( ws->display, ws->rid, PEXOn );
- XFlush( ws->display );
- owsb->surf_state = PSURF_NOT_EMPTY;
- }
- }
-
-
- void
- phg_wsb_traverse_net( ws, structp )
- Ws_handle ws;
- Struct_handle structp;
- {
- register El_handle el;
-
- PEXBeginStructure( ws->display, ws->rid, (CARD32)structp->struct_id );
- el = structp->first_el;
- while ( 1 ) { /* termination test is at the bottom */
- switch ( el->eltype ) {
- case PELEM_NIL:
- break;
- case PELEM_EXEC_STRUCT:
- phg_wsb_traverse_net( ws, (Struct_handle)el->eldata.ptr );
- break;
- default:
- PEXRenderOutputCommands( ws->display, ws->rid, (CARD32)1,
- (CARD32)(((pexElementInfo *)el->eldata.ptr)->length
- * sizeof(CARD32)),
- (char *)el->eldata.ptr );
- break;
- }
-
- if ( el == structp->last_el )
- break; /* out of the while over all elements in struct */
- el = el->next;
- }
- PEXEndStructure( ws->display, ws->rid );
- }
-
-
- static int
- wsb_visible_element_type( el )
- El_handle el;
- {
- int status = 1; /* almost all are */
-
- switch ( el->eltype ) {
- case PELEM_APPL_DATA:
- case PELEM_LABEL:
- case PELEM_PICK_ID:
- status = 0;
- break;
- }
-
- return status;
- }
-
- void
- phg_wsb_add_el( ws )
- Ws *ws;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
- El_handle cur_el = CSS_CUR_ELP(owsb->cssh);
-
- assure(CSS_CUR_STRUCTP(owsb->cssh)); /* A structure must be open */
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- default:
- if ( wsb_visible_element_type( cur_el ) )
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
-
- int
- phg_wsb_asti_update( ws, clear_control )
- Ws *ws;
- Pctrl_flag clear_control;
- {
- /* Returns non-zero if redraw occurred. */
-
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- switch ( (*owsb->update_action_table)
- [(int)PHG_TIME_ATI]
- [(int)ws->out_ws.mod_mode]
- [(int)ws->out_ws.def_mode] ) {
- case PHG_UPDATE_IF_INCORRECT:
- case PHG_UPDATE_IF_IL:
- case PHG_UPDATE_IF_IG:
- if ( owsb->vis_rep == PVISUAL_ST_CORRECT )
- break;
- /* else fall through to PHG_UPDATE_ACCURATE case */
- case PHG_UPDATE_ACCURATE:
- (*ws->redraw_all)( ws, clear_control );
- return 1;
-
- case PHG_UPDATE_UQUM:
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- break;
- }
-
- return 0;
- }
-
- void
- phg_wsb_close_struct( ws, structh )
- Ws *ws;
- Struct_handle structh;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- /* First, do processing that is independent of screen output */
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- default:
- break;
- }
-
- /* Updates are implementation dependent in ASTI mode. This is one
- * of the cases where we do an ASTI update; we're hopefully doing the
- * application a favor.
- */
- (void)phg_wsb_asti_update( ws, PFLAG_COND );
- }
-
-
- static void
- wsb_update_a_posting( ws, posting )
- Ws *ws;
- Ws_post_str *posting;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
-
- void
- phg_wsb_post( ws, structh, priority, first_posting )
- Ws *ws;
- Struct_handle structh;
- Pfloat priority;
- int first_posting; /* 0 if already posted */
- {
- Ws_post_str *start;
-
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
- register Ws_post_str *cur, *end;
- register Ws_post_str *new;
-
-
- if ( !first_posting ) {
- /* Check to see if structure is already posted. */
- cur = owsb->posted.lowest.higher;
- end = &owsb->posted.highest;
- while ( cur != end && cur->structh != structh )
- cur = cur->higher;
- }
-
- /* The structure is already_posted if (cur != end). */
- if ( !first_posting && cur != end ) {
- if( cur->higher != end && priority >= cur->higher->disp_pri ) {
- start = end->lower;
- assure(start == owsb->posted.highest.lower);
- end = cur->higher; /* insert betw. cur->higher & posted.highest */
- } else if ( cur->lower != &owsb->posted.lowest
- && priority < cur->lower->disp_pri ) {
- /* Will insert between start and cur->lower. */
- start = cur->lower;
- end = &owsb->posted.lowest;
- } else {
- /* This is a reposting with the same *relative* prio. */
- cur->disp_pri = priority;
- return;
- }
-
- /* Struct is posted. Remove it, but re-use its Ws_post_str entry */
- cur->lower->higher = cur->higher;
- cur->higher->lower = cur->lower;
- new = cur;
-
- } else {
- /* Struct is not currently posted, malloc an element. */
- if ( !(new = (Ws_post_str *)malloc(sizeof(Ws_post_str))) ) {
- ERR_BUF( ws->erh, ERR900);
- return;
- }
- start = owsb->posted.highest.lower;
- end = &owsb->posted.lowest;
- }
-
- /* Now figure out where to insert it, working backwards from start
- * to end
- */
- cur = start;
- while ( cur != end && cur->disp_pri > priority )
- cur = cur->lower; /* if priorities equal, new after cur */
- /* insert new element w/prio >= than cur's, so cur->higher will be new */
- new->lower = cur;
- new->higher = cur->higher;
- cur->higher = new;
- new->higher->lower = new;
- new->structh = structh;
- new->disp_pri = priority;
-
- if ( structh->num_el != 0 )
- wsb_update_a_posting( ws, new );
- }
-
-
- /* This function only called from the css for change struct ids/refs -
- * it is used to change the structure pointers referencing a given
- * structure, because the way the change struct ids/refs functions work
- * is by changing struct_id fields rather than copying whole structures,
- * so any lists using structure pointers to reference specific structures
- * have to be changed to use the correct pointers.
- */
-
- void
- phg_wsb_change_posting( ws, unpost, post )
- Ws *ws;
- Struct_handle unpost, post;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
- register Ws_post_str *cur, *end;
-
- cur = owsb->posted.lowest.higher;
- end = &owsb->posted.highest;
- while ( cur != end && cur->structh != unpost )
- cur = cur->higher;
-
- if ( cur != end ) {
- if ( post ) {
- /* if the structure to be "posted" is already posted, remove it */
- phg_wsb_change_posting( ws, post, (Struct_handle)NULL );
- /* Change posted structure from "unpost" to "post", same priority*/
- cur->structh = post;
- } else {
- /* Post is NULL - just remove Ws_post_str entry for unpost. */
- cur->lower->higher = cur->higher;
- cur->higher->lower = cur->lower;
- free( (char *)cur );
- }
- }
- }
-
-
- /* Search the list of posted structures for this one.
- * If found, return pointer to next-higher-priority posted structure element.
- * (Remember that that could be the dummy element owsb->posted.highest)
- * If not, return NULL.
- */
- static Ws_post_str*
- wsb_unpost_struct_if_found( owsb, structh )
- Wsb_output_ws *owsb;
- Struct_handle structh;
- {
- register Ws_post_str *cur, *end;
-
- cur = owsb->posted.lowest.higher;
- end = &owsb->posted.highest;
- while ( cur != end && cur->structh != structh )
- cur = cur->higher;
- if ( cur != end ) {
- /* Found it -- now delete it */
- cur->lower->higher = cur->higher;
- cur->higher->lower = cur->lower;
- end = cur->higher; /* Save this around the free */
- free( (char *)cur );
- return end;
- } else
- return (Ws_post_str*)NULL;
- }
-
-
- void
- phg_wsb_unpost( ws, structh )
- Ws *ws;
- Struct_handle structh;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- if ( !wsb_unpost_struct_if_found( owsb, structh ) )
- /* Tried to unpost structure that wasn't there; but that's okay. */
- return;
-
- if ( structh->num_el != 0 ) {
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
- }
-
-
- void
- phg_wsb_unpost_all( ws )
- Ws *ws;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- wsb_free_all_posted( owsb );
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
-
- void
- phg_wsb_delete_all_structs( ws )
- Ws *ws;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- phg_wsb_unpost_all( ws );
- }
-
-
- int
- phg_wsb_delete_struct( ws, structh, flag )
- Ws *ws;
- Struct_handle structh;
- Ws_delete_flag flag;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
- int call_again = 0;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- if ( flag == WS_PRE_CSS_DELETE ) {
- (void)wsb_unpost_struct_if_found( owsb, structh );
- call_again = 1;
- } else
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- (void)wsb_unpost_struct_if_found( owsb, structh );
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
-
- return call_again;
- }
-
-
- int
- phg_wsb_delete_struct_net( ws, structh, reff, flag )
- Ws *ws;
- Struct_handle structh;
- Pref_flag reff;
- Ws_delete_flag flag;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
- int call_again = 0;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- if ( flag == WS_PRE_CSS_DELETE ) {
- (void)wsb_unpost_struct_if_found( owsb, structh );
- call_again = 1;
- } else
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- default:
- (void)wsb_unpost_struct_if_found( owsb, structh );
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- return call_again;
- }
-
-
- void
- phg_wsb_copy_struct( ws, first_el )
- Ws *ws;
- El_handle first_el;
- {
- (*ws->conditional_redraw)( ws );
- }
-
-
- /* Delete elements elh1 through elh2, inclusive, in structure structh */
- int
- phg_wsb_delete_el( ws, structh, elh1, elh2, flag )
- Ws *ws;
- Struct_handle structh;
- El_handle elh1, elh2;
- Ws_delete_flag flag;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
- int call_again = 0;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- default:
- if ( flag == WS_PRE_CSS_DELETE ) {
- if ( elh1 == elh2 && !wsb_visible_element_type( elh1 ) )
- call_again = 0; /* avoid second call. */
- else
- call_again = 1;
- } else /* POST_CSS_DELETE */
- (*ws->redraw_all)(ws, PFLAG_COND);
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- case PHG_UPDATE_UQUM:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
-
- return call_again;
- }
-
-
- /* Called by CP after difficult operations like change struct refs/ids.
- * Redraws workstation, if that is permitted, else DEFERs.
- */
- void
- phg_wsb_conditional_redraw( ws )
- Ws *ws;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_ALWAYS );
- break;
-
- case PHG_UPDATE_UQUM:
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
-
- /* Resolves PHG_UPDATE_IF_Ix to the ASTI now_action, if no input device active.
- *
- * Check this function before every (out_ws->now_action) use.
- * Then use case_PHG_UPDATE_ACCURATE_or_IF_Ix in switch (out_ws->now_action),
- * so that PHG_UPDATE_IF_Ix acts as PHG_UPDATE_ACCURATE (i.e., ASAP)
- * while appicable input devices are (still) active.
- */
- void
- phg_wsb_resolve_now_action( ws, now_action_ptr )
- Ws *ws;
- Ws_update_action *now_action_ptr;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- switch ( *now_action_ptr ) {
- case PHG_UPDATE_IF_IL:
- /* If none active, treat like ASTI until next bnig_update(ws,ws) */
- if ( !WS_ANY_INP_DEV_ACTIVE(ws) ) {
- *now_action_ptr = (*owsb->update_action_table)
- [(int)PHG_TIME_NOW][(int)ws->out_ws.mod_mode][(int)PDEFER_ASTI];
- }
- break;
-
- case PHG_UPDATE_IF_IG:
- /* If none active, treat like ASTI until next bnig_update(ws,*) */
- if ( !phg_cp_any_inp_device_active( ws->cph ) ) {
- *now_action_ptr = (*owsb->update_action_table)
- [(int)PHG_TIME_NOW][(int)ws->out_ws.mod_mode][(int)PDEFER_ASTI];
- }
- break;
- }
- }
-
-
- void
- phg_wsb_update( ws, flag )
- Ws *ws;
- Pregen_flag flag;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- if ( flag != PFLAG_POSTPONE && owsb->vis_rep != PVISUAL_ST_CORRECT )
- (*ws->redraw_all)( ws, PFLAG_COND );
- else
- (*ws->make_requested_current)( ws );
- }
-
-
- void
- phg_wsb_set_disp_update_state( ws, def_mode, mod_mode )
- Ws *ws;
- Pdefer_mode def_mode;
- Pmod_mode mod_mode;
- {
- Ws_update_action previous_now_action;
-
- register Ws_output_ws *out_ws = &ws->out_ws;
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- out_ws->def_mode = def_mode;
- out_ws->mod_mode = mod_mode;
-
- previous_now_action = owsb->now_action;
- owsb->now_action = (*owsb->update_action_table)
- [(int)PHG_TIME_NOW][(int)out_ws->mod_mode][(int)out_ws->def_mode];
- assure(owsb->now_action != PHG_UPDATE_IF_INCORRECT);
-
- if ( owsb->now_action != previous_now_action ) {
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- if( owsb->vis_rep != PVISUAL_ST_CORRECT )
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
- }
- }
- }
-
-
- void
- phg_wsb_set_hlhsr_mode( ws, mode )
- Ws *ws;
- Pint mode;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- if( ws->type->desc_tbl.phigs_dt.num_hlhsr_modes == 1 )
- return; /* No need to update if the user asks for what he has! */
-
- owsb->req_hlhsr_mode = mode;
- owsb->hlhsr_mode_pending = PUPD_PEND;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_UQUM:
- case PHG_UPDATE_NOTHING:
- default:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
-
- void
- phg_wsb_set_ws_window( ws, two_d, limits )
- Ws *ws;
- int two_d;
- Plimit3 *limits;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- owsb->ws_window_pending = PUPD_PEND;
- if ( two_d ) { /* leave the z values as they are */
- owsb->req_ws_window.x_min = limits->x_min;
- owsb->req_ws_window.x_max = limits->x_max;
- owsb->req_ws_window.y_min = limits->y_min;
- owsb->req_ws_window.y_max = limits->y_max;
- } else
- owsb->req_ws_window = *limits;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UQUM:
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- default:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
-
- void
- phg_wsb_set_ws_vp( ws, two_d, limits )
- Ws *ws;
- int two_d;
- Plimit3 *limits;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- owsb->ws_viewport_pending = PUPD_PEND;
- if ( two_d ) { /* leave the z values as they are */
- owsb->req_ws_viewport.x_min = limits->x_min;
- owsb->req_ws_viewport.x_max = limits->x_max;
- owsb->req_ws_viewport.y_min = limits->y_min;
- owsb->req_ws_viewport.y_max = limits->y_max;
- } else
- owsb->req_ws_viewport = *limits;
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UQUM:
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- default:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
-
- void
- phg_wsb_set_view_input_priority( ws, index, ref_index, priority )
- Ws *ws;
- register Pint index;
- Pint ref_index;
- Prel_pri priority;
- {
- Pint old;
-
- register Ws_view_priority *ref, *idx;
- register Pint *highest;
- register Ws_view_priority *vp;
-
- vp = ws->out_ws.model.b.view_priorities;
- highest = &ws->out_ws.model.b.top_view;
- idx = &vp[index];
- ref = &vp[ref_index];
-
- if ( priority == PPRI_LOWER ) {
- if ( ref->lower != index ) {
- if ( index == *highest)
- *highest = idx->lower;
-
- old = ref->lower;
- if ( ref->lower != -1 ) /* if ref not lowest priority */
- vp[ref->lower].higher = index;
- ref->lower = index;
-
- if ( idx->higher != -1 ) /* if idx not highest priority */
- vp[idx->higher].lower = idx->lower;
- if ( idx->lower != -1 ) /* if idx not lowest priority */
- vp[idx->lower].higher = idx->higher;
- idx->higher = ref_index;
- idx->lower = old;
- }
- /* Don't need to do anything if priority is already as desired. */
-
- } else if ( ref->higher != index ) { /* PPRI_HIGHER */
- if ( ref_index == *highest )
- *highest = index;
- else if ( index == *highest )
- *highest = idx->lower;
-
- old = ref->higher;
- if ( ref->higher != -1 )
- vp[ref->higher].lower = index;
- ref->higher = index;
-
- if ( idx->higher != -1 )
- vp[idx->higher].lower = idx->lower;
- if ( idx->lower != -1 )
- vp[idx->lower].higher = idx->higher;
- idx->lower = ref_index;
- idx->higher = old;
- }
-
- /* Has no effect on the screen */
- }
-
-
- void
- phg_wsb_set_rep( ws, type, rep )
- Ws *ws;
- Phg_args_rep_type type;
- Phg_args_rep_data *rep;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
- register int i;
-
- switch ( type ) {
- case PHG_ARGS_LNREP:
- case PHG_ARGS_EXTLNREP:
- case PHG_ARGS_MKREP:
- case PHG_ARGS_EXTMKREP:
- case PHG_ARGS_TXREP:
- case PHG_ARGS_EXTTXREP:
- case PHG_ARGS_INTERREP:
- case PHG_ARGS_EXTINTERREP:
- case PHG_ARGS_EDGEREP:
- case PHG_ARGS_EXTEDGEREP:
- case PHG_ARGS_PTREP:
- case PHG_ARGS_EXTPTREP:
- case PHG_ARGS_DCUEREP:
- case PHG_ARGS_LIGHTSRCREP:
- case PHG_ARGS_COLRMAPREP:
- phg_wsx_set_LUT_entry( ws, type, rep, (Pgcolr*)NULL );
- break;
-
- case PHG_ARGS_VIEWREP:
- /* Add it to the list of pending views. */
- if ( owsb->views[rep->index].pending == PUPD_NOT_PEND )
- i = owsb->num_pending_views++;
- else {
- /* Find the existing pending entry so it can be replaced. */
- for ( i = 0; i < owsb->num_pending_views; i++ )
- if ( owsb->pending_views[i].id == rep->index )
- break;
- }
- owsb->pending_views[i].id = rep->index;
- owsb->pending_views[i].view = rep->bundl.viewrep;
- owsb->views[rep->index].pending = PUPD_PEND;
- break;
-
- case PHG_ARGS_COREP: {
- Pgcolr gcolr;
-
- /* Store in current colour model. */
- gcolr.type = ws->current_colour_model;
- gcolr.val.general.x = rep->bundl.corep.rgb.red;
- gcolr.val.general.y = rep->bundl.corep.rgb.green;
- gcolr.val.general.z = rep->bundl.corep.rgb.blue;
- phg_wsx_set_LUT_entry( ws, type, rep, &gcolr );
- } break;
- }
-
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- default:
- case PHG_UPDATE_UQUM:
- case PHG_UPDATE_UWOR:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
-
- case PHG_UPDATE_NOTHING:
- /* Defer if rep has PENDING flag, or if screen could be affected. */
- if ( WSB_SOME_POSTED(&owsb->posted) || (type == PHG_ARGS_VIEWREP) )
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
-
- void
- phg_wsb_set_filter( ws, type, devid, inc_set, exc_set )
- Ws *ws;
- Phg_args_flt_type type;
- Pint devid;
- Pint_list *inc_set;
- Pint_list *exc_set;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- phg_wsx_set_name_set( ws, type, devid, inc_set, exc_set );
-
- if ( (type == PHG_ARGS_FLT_HIGH || type == PHG_ARGS_FLT_INVIS)
- && WSB_SOME_POSTED(&owsb->posted) ) {
- WSB_CHECK_FOR_INTERACTION_UNDERWAY(ws, &owsb->now_action)
- switch ( owsb->now_action ) {
- case_PHG_UPDATE_ACCURATE_or_IF_Ix:
- (*ws->redraw_all)( ws, PFLAG_COND );
- break;
-
- case PHG_UPDATE_UQUM:
- case PHG_UPDATE_UWOR:
- case PHG_UPDATE_NOTHING:
- default:
- owsb->vis_rep = PVISUAL_ST_DEFER;
- break;
- }
- }
- }
-
-
- void
- phg_wsb_inq_view_indices( ws, ret )
- Ws *ws;
- Phg_ret *ret;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- register Pint *list, view;
- register int i;
- register Ws_view_priority *prio = owsb->view_priorities;
-
- if ( !PHG_SCRATCH_SPACE( &ws->scratch, owsb->num_views * sizeof(Pint))) {
- ret->err = ERR900;
-
- } else {
- ret->err = 0;
- ret->data.int_list.num_ints = owsb->num_views;
- ret->data.int_list.ints = list = (Pint *)ws->scratch.buf;
- view = owsb->top_view;
- i = 0;
- while ( view != -1 ) {
- list[i++] = view;
- view = prio[view].lower;
- }
- }
- }
-
-
- void
- phg_wsb_inq_posted( ws, ret )
- Ws *ws;
- Phg_ret *ret;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- register Ws_post_str *cur, *end;
- register int cnt;
- register Pposted_struct *list;
-
- cur = owsb->posted.lowest.higher;
- end = &owsb->posted.highest;
-
- /* Count them */
- cnt = 0;
- while ( cur != end ) {
- ++cnt;
- cur = cur->higher;
- }
-
- ret->err = 0;
- ret->data.postlist.num_postings = cnt;
- if ( cnt > 0 ) {
- if ( PHG_SCRATCH_SPACE(&ws->scratch, cnt * sizeof(Pposted_struct)) ) {
- ret->data.postlist.postings = list =
- (Pposted_struct *)ws->scratch.buf;
- cur = owsb->posted.lowest.higher;
- while ( cur != end ) {
- list->id = cur->structh->struct_id;
- list++->disp_pri = cur->disp_pri;
- cur = cur->higher;
- }
-
- } else {
- ret->err = ERR900;
- ret->data.postlist.num_postings = 0;
- }
- }
- }
-
-
- void
- phg_wsb_inq_view_rep( ws, index, ret )
- Ws *ws;
- Pint index;
- Phg_ret *ret;
- {
- register int i;
- register Pview_rep3 *cr;
- register Ws_view_entry *cv;
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
- register Phg_ret_view_rep *vr = &ret->data.view_rep;
-
- ret->err = 0;
- vr->update_state = owsb->views[index].pending;
- /* Load the "current" view. */
- if ( !PHG_SCRATCH_SPACE( &ws->scratch, sizeof(Pview_rep3) ) ) {
- ret->err = ERR900;
- return;
- } else {
- vr->cur_rep = cr = (Pview_rep3 *)ws->scratch.buf;
- cv = &owsb->views[index];
- cr->clip_limit = cv->clip_limit;
- cr->xy_clip = cv->xy_clip;
- cr->back_clip = cv->back_clip;
- cr->front_clip = cv->front_clip;
- bcopy( (char *)cv->vom, (char *)cr->ori_matrix, sizeof(Pmatrix3) );
- bcopy( (char *)cv->vmm, (char *)cr->map_matrix, sizeof(Pmatrix3) );
- }
-
- /* Load the "requested" view. */
- if ( vr->update_state == PUPD_NOT_PEND ) /* save some time */
- vr->req_rep = vr->cur_rep;
- else {
- /* Find the requested entry in the pending view list. */
- for ( i = 0; i < owsb->num_pending_views; i++ ) {
- if ( owsb->pending_views[i].id == index ) {
- cr = &owsb->pending_views[i].view;
- break; /* we've found it, no need to keep searching */
- }
- }
- vr->req_rep = cr;
- }
- }
-
-
- void
- phg_wsb_inq_ws_xform( ws, ret )
- Ws *ws;
- Phg_ret *ret;
- {
- register Phg_ret_ws_tran3 *wsxf = &ret->data.ws_xform;
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- ret->err = 0;
- wsxf->state =
- owsb->ws_window_pending == PUPD_PEND
- || owsb->ws_viewport_pending == PUPD_PEND
- ? PUPD_PEND : PUPD_NOT_PEND;
- wsxf->req_window = owsb->req_ws_window;
- wsxf->req_viewport = owsb->req_ws_viewport;
- wsxf->cur_window = owsb->ws_window;
- wsxf->cur_viewport = owsb->ws_viewport;
- }
-
-
- void
- phg_wsb_inq_disp_update_state( ws, ret)
- Ws *ws;
- Phg_ret *ret;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- ret->err = 0;
- ret->data.update_state.def_mode = ws->out_ws.def_mode;
- ret->data.update_state.mod_mode = ws->out_ws.mod_mode;
- ret->data.update_state.display_surf = owsb->surf_state;
- ret->data.update_state.state = owsb->vis_rep;
- }
-
-
- void
- phg_wsb_inq_hlhsr_mode( ws, ret )
- Ws *ws;
- Phg_ret *ret;
- {
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
-
- ret->err = 0;
- ret->data.hlhsr_mode.state = owsb->hlhsr_mode_pending;
- ret->data.hlhsr_mode.cur_mode = owsb->cur_hlhsr_mode;
- ret->data.hlhsr_mode.req_mode = owsb->req_hlhsr_mode;
- }
-
-
- void
- phg_wsb_inq_rep( ws, index, how, rep_type, ret )
- Ws *ws;
- Pint index;
- Pinq_type how; /* set or realized */
- Phg_args_rep_type rep_type;
- Phg_ret *ret;
- {
- ret->err = 0;
- switch ( rep_type ) {
- case PHG_ARGS_LNREP:
- case PHG_ARGS_EXTLNREP:
- case PHG_ARGS_MKREP:
- case PHG_ARGS_EXTMKREP:
- case PHG_ARGS_TXREP:
- case PHG_ARGS_EXTTXREP:
- case PHG_ARGS_INTERREP:
- case PHG_ARGS_EXTINTERREP:
- case PHG_ARGS_EDGEREP:
- case PHG_ARGS_EXTEDGEREP:
- case PHG_ARGS_PTREP:
- case PHG_ARGS_EXTPTREP:
- case PHG_ARGS_DCUEREP:
- case PHG_ARGS_LIGHTSRCREP:
- case PHG_ARGS_COLRMAPREP:
- /* View rep is done elsewhere. */
- phg_wsx_inq_LUT_entry( ws, index, how, rep_type, ret,
- (Pgcolr *)NULL, (Pview_rep3 *)NULL );
- break;
-
- case PHG_ARGS_COREP: {
- Pgcolr src_gcolr, gcolr;
- Pcolr_rep *cb = &ret->data.rep.corep;
-
- /* Need to convert to current colour model. */
- phg_wsx_inq_LUT_entry( ws, index, how, rep_type, ret,
- &src_gcolr, (Pview_rep3 *)NULL );
- gcolr.type = ws->current_colour_model;
- (void)phg_utx_convert_colour( &src_gcolr, &gcolr,
- &ws->type->desc_tbl.phigs_dt.out_dt.chroma_info );
- cb->rgb.red = gcolr.val.general.x;
- cb->rgb.green = gcolr.val.general.y;
- cb->rgb.blue = gcolr.val.general.z;
- } break;
- }
- }
-
-
- static void
- update_inv_view_xform( view )
- Ws_view_entry *view;
- {
- /* Calculate the inverse xform, if necessary. */
- if ( view->npc_to_wc_state == WS_INV_NOT_CURRENT ) {
- phg_mat_mul( view->npc_to_wc, view->vmm, view->vom );
- phg_mat_inv( view->npc_to_wc );
- view->npc_to_wc_state = WS_INV_CURRENT;
- }
- }
-
-
- int
- phg_wsb_map_initial_points( ws, view_index, num_pts, wc_pts, dwbl_pts )
- Ws *ws;
- Pint view_index;
- Pint *num_pts;
- Ppoint3 *wc_pts;
- XPoint *dwbl_pts;
- {
- Ppoint3 scratch[20]; /* enough for most cases */
- Pmatrix3 wc_to_npc;
- Ppoint3 dc_pt;
-
- register Ppoint3 *npc_pts = (Ppoint3 *)NULL;
- register int i;
- register Ws_view_entry *view;
- register Ws_xform *wsxf = &ws->out_ws.model.b.ws_xform;
-
- /* Transform the initial points to NPC and check that they all fit
- * in the clip limits of the specified view. Then transform and map
- * them to drawable coordinates.
- */
- if ( *num_pts <= 0 )
- return 0;
- if ( *num_pts <= sizeof(scratch)/sizeof(scratch[0]) )
- npc_pts = scratch;
- else if ( *num_pts > sizeof(scratch)/sizeof(scratch[0]) ) {
- if ( !(npc_pts = (Ppoint3 *)malloc( (unsigned)(*num_pts *
- sizeof(Ppoint3)) )) ) {
- *num_pts = 0;
- ERR_BUF( ws->erh, ERR900 );
- return 0;
- }
- }
-
- view = &ws->out_ws.model.b.views[view_index];
- phg_mat_mul( wc_to_npc, view->vmm, view->vom );
- if ( !phg_tranpts3( wc_to_npc, *num_pts, wc_pts, npc_pts ) ) {
- *num_pts = 0;
- return 0;
- }
-
- for ( i = 0; i < *num_pts; i++ ) {
- if ( !WS_PT_IN_LIMIT( &view->clip_limit, &npc_pts[i] ) ) {
- *num_pts = 0;
- break;
- } else {
- WS_NPC_TO_DC( wsxf, &npc_pts[i], &dc_pt )
- WS_DC_TO_DRWBL2( ws, &dc_pt, &dwbl_pts[i] );
- }
- }
-
- if ( npc_pts && npc_pts != scratch )
- free( (char *)npc_pts );
-
- return ( *num_pts > 0 ? 1 : 0 );
- }
-
-
- int
- phg_wsb_resolve_locator( ws, dc_pt, determine_z, view_index, wc_pt )
- Ws *ws;
- pexDeviceCoord *dc_pt;
- int determine_z; /* ignored */
- Pint *view_index;
- Ppoint3 *wc_pt;
- {
- Ppoint3 npc_pt;
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
- Ws_view_priority *priorities = owsb->view_priorities;
- Ws_xform *wsxf = &owsb->ws_xform;
- Plimit3 *ws_win = &owsb->ws_window;
- int status = 0;
-
- register Ws_view_entry *view;
-
- /* Apply the inverse WS transform and see if it's in the ws window.
- * Can't just check against the viewport boundaries because the
- * window may be smaller if the aspect ratios are different.
- */
- WS_DC_TO_NPC2(wsxf, dc_pt, &npc_pt)
- if ( npc_pt.x >= ws_win->x_min && npc_pt.x <= ws_win->x_max
- && npc_pt.y >= ws_win->y_min && npc_pt.y <= ws_win->y_max ) {
-
- /* Find the highest priority view that contains the point. */
- for ( *view_index = owsb->top_view; *view_index != -1;
- *view_index = priorities[*view_index].lower ) {
- view = &owsb->views[*view_index];
- if ( WS_PT_IN_LIMIT2(&view->clip_limit, &npc_pt) ) {
- /* Assign the clip window minimum to Z. */
- npc_pt.z = view->clip_limit.z_min;
-
- /* Calculate the inverse xform if necessary. */
- if ( view->npc_to_wc_state == WS_INV_NOT_CURRENT )
- update_inv_view_xform( view );
-
- /* Map point to WC if xform invertible. */
- if ( view->npc_to_wc_state == WS_INV_CURRENT ) {
- if ( phg_tranpt3( &npc_pt, view->npc_to_wc, wc_pt ) ) {
- status = 1;
- break; /* out of the for on view index */
- }
- }
- }
- }
- }
- return status;
- }
-
-
- static int
- wsb_resolve_stroke( ws, two_d, dc_ll, dc_ur, view_index )
- Ws *ws;
- int two_d; /* input points are 2D */
- pexDeviceCoord *dc_ll, *dc_ur;
- Pint *view_index; /* resolved view index */
-
- /* Returns 1 if stroke resolvable, else 0 */
- {
- Ppoint3 npc_ll, npc_ur;
- Wsb_output_ws *owsb = &ws->out_ws.model.b;
- Ws_view_priority *priorities = owsb->view_priorities;
- Ws_xform *wsxf = &owsb->ws_xform;
- Plimit3 *ws_win = &owsb->ws_window;
- int status = 0, in_limit;
-
- register Ws_view_entry *view;
-
- /* Apply the inverse WS transform and see if the bounding box is in
- * the ws window. Can't just check against the viewport boundaries
- * because the window may be smaller if the aspect ratios are different.
- */
- in_limit = 0;
- if ( two_d ) {
- WS_DC_TO_NPC2(wsxf, dc_ll, &npc_ll)
- WS_DC_TO_NPC2(wsxf, dc_ur, &npc_ur)
- in_limit = WS_PT_IN_LIMIT2(ws_win, &npc_ll)
- && WS_PT_IN_LIMIT2(ws_win, &npc_ur);
- } else {
- WS_DC_TO_NPC(wsxf, dc_ll, &npc_ll)
- WS_DC_TO_NPC(wsxf, dc_ur, &npc_ur)
- in_limit = WS_PT_IN_LIMIT(ws_win, &npc_ll)
- && WS_PT_IN_LIMIT(ws_win, &npc_ur);
- }
-
- if ( in_limit ) {
- /* Find the highest priority view that contains the bounding box. */
- for ( *view_index = owsb->top_view; *view_index != -1;
- *view_index = priorities[*view_index].lower ) {
- view = &owsb->views[*view_index];
- in_limit = 0;
- if ( two_d )
- in_limit = WS_PT_IN_LIMIT2(&view->clip_limit, &npc_ll)
- && WS_PT_IN_LIMIT2(&view->clip_limit, &npc_ur);
- else
- in_limit = WS_PT_IN_LIMIT(&view->clip_limit, &npc_ll)
- && WS_PT_IN_LIMIT(&view->clip_limit, &npc_ur);
-
- if ( in_limit ) {
- /* Found the view. Calculate its inverse transform if
- * necessary.
- */
- if ( view->npc_to_wc_state == WS_INV_NOT_CURRENT )
- update_inv_view_xform( view );
-
- if ( view->npc_to_wc_state == WS_INV_CURRENT ) {
- status = 1;
- break; /* break out of the view loop when view found */
- }
- }
- }
- }
- return status;
- }
-
-
- static void
- wsb_transform_stroke( ws, view_index, two_d, num_pts, dc_pts, wc_pts )
- Ws *ws;
- Pint view_index;
- int two_d;
- register int num_pts;
- register pexDeviceCoord *dc_pts;
- Ppoint_list3 *wc_pts;
- {
- register int i;
- register Ppoint3 *npc_pts;
- register Ws_xform *wsxf = &ws->out_ws.model.b.ws_xform;
- register Ws_view_entry *view = &ws->out_ws.model.b.views[view_index];
-
- /* Shouldn't call this function with num_pts == 0. */
- if ( !(npc_pts = (Ppoint3 *)
- malloc( (unsigned)(num_pts * sizeof(Ppoint3)) )) ) {
- wc_pts->num_points = 0;
- ERR_BUF( ws->erh, ERR900 );
- return;
- }
-
- /* Transform the points to npc and add the z value. */
- for ( i = 0; i < num_pts; i++ ) {
- if ( two_d ) {
- WS_DC_TO_NPC2(wsxf, &dc_pts[i], &npc_pts[i])
- /* Assign the back clip limit. */
- npc_pts[i].z = view->clip_limit.z_min;
- } else {
- WS_DC_TO_NPC(wsxf, &dc_pts[i], &npc_pts[i])
- }
- }
-
- /* Transform the points to wc. */
- if ( !phg_tranpts3( view->npc_to_wc, num_pts, npc_pts, wc_pts->points ) )
- wc_pts->num_points = 0;
-
- free( (char *)npc_pts );
- }
-
-
- int
- phg_wsb_resolve_stroke( ws, num_pts, dc_pts, determine_z, view_index, wc_pts )
- Ws *ws;
- register int num_pts;
- pexDeviceCoord *dc_pts;
- int determine_z; /* ignored */
- Pint *view_index;
- Ppoint_list3 *wc_pts;
- {
- pexDeviceCoord ll, ur;
- int status = 0, two_d = determine_z;
-
- register pexDeviceCoord *dp;
- register int i, xmin, xmax, ymin, ymax, zmin, zmax;
-
- /* Get the bounding box of all the points. */
- xmin = dc_pts->x; xmax = dc_pts->x;
- ymin = dc_pts->y; ymax = dc_pts->y;
- if ( !two_d )
- zmin = dc_pts->z, zmax = dc_pts->z;
- for ( i = 1, dp = &dc_pts[1]; i < num_pts; i++, dp++ ) {
- if ( dp->x < xmin )
- xmin = dp->x;
- else if ( dp->x > xmax )
- xmax = dp->x;
-
- if ( dp->y < ymin )
- ymin = dp->y;
- else if ( dp->y > ymax )
- ymax = dp->y;
-
- if ( !two_d ) {
- /* The incoming points have Z values. */
- if ( dp->z < zmin )
- zmin = dp->z;
- else if ( dp->z > zmax )
- zmax = dp->z;
- }
- }
- ll.x = xmin; ll.y = ymax;
- ur.x = xmax; ur.y = ymin;
- if ( !two_d )
- ur.x = xmax, ur.y = ymin;
-
- /* Resolve and transform the points. Don't change the current
- * measure if the points can't be resolved.
- */
- if ( wsb_resolve_stroke( ws, two_d, &ll, &ur, view_index ) ) {
- wc_pts->num_points = num_pts;
- wsb_transform_stroke( ws, *view_index, two_d, num_pts, dc_pts, wc_pts );
- status = 1;
- }
-
- return status;
- }
-
-
- int
- phg_wsb_resolve_pick( ws, dev, echo, dc_pt, pick )
- Ws *ws;
- Ws_inp_pick *dev;
- int echo;
- pexDeviceCoord *dc_pt;
- Ppick *pick;
- {
- register Wsb_output_ws *owsb = &ws->out_ws.model.b;
- register Ws_post_str *post_str, *end;
- pexDeviceCoord2D dc_vol[2];
- Ppoint npc_pt[2];
- pexPickElementRef *pickPath;
- int pickDepth;
- int betterPick, i;
-
- CARD32 pickDataBytes;
-
- struct {
- pexEnumTypeIndex pickType;
- CARD16 unused;
- union {
- pexPD_DC_HitBox dcHitBox;
- pexPD_NPC_HitVolume npcHitVolume;
- } pickRec;
- } pickData;
-
- WSB_CHECK_POSTED (&owsb->posted)
-
- if (WSB_SOME_POSTED (&owsb->posted)) {
-
- /*
- * Use pick rendering to get the pick results. Call BeginPickOne, do
- * a complete traversal (starting with highest priority structure,
- * then call EndPickOne to get the pick results.
- */
-
- if (dev->dev_type == PEXPickDeviceDC_HitBox) {
-
- pickData.pickType = PEXPickDeviceDC_HitBox;
-
- pickData.pickRec.dcHitBox.position.x = dc_pt->x;
- pickData.pickRec.dcHitBox.position.y = dc_pt->y;
- pickData.pickRec.dcHitBox.distance = dev->ap_size;
-
- pickDataBytes = 4 + sizeof (pexPD_DC_HitBox);
-
- } else {
-
- pickData.pickType = PEXPickDeviceNPC_HitVolume;
-
- dc_vol[0].x = dc_pt->x - dev->ap_size;
- dc_vol[0].y = dc_pt->y - dev->ap_size;
- dc_vol[1].x = dc_pt->x + dev->ap_size;
- dc_vol[1].y = dc_pt->y + dev->ap_size;
-
- WS_DC_TO_NPC2 (&owsb->ws_xform, &dc_vol[0], &npc_pt[0])
- WS_DC_TO_NPC2 (&owsb->ws_xform, &dc_vol[1], &npc_pt[1])
-
- pickData.pickRec.npcHitVolume.minval.x = npc_pt[0].x;
- pickData.pickRec.npcHitVolume.minval.y = npc_pt[0].y;
- pickData.pickRec.npcHitVolume.maxval.x = npc_pt[1].x;
- pickData.pickRec.npcHitVolume.maxval.y = npc_pt[1].y;
- pickData.pickRec.npcHitVolume.minval.z = owsb->ws_window.z_min;
- pickData.pickRec.npcHitVolume.maxval.z = owsb->ws_window.z_max;
-
- pickDataBytes = 4 + sizeof (pexPD_NPC_HitVolume);
- }
-
- PEXChangeRenderer (ws->display, ws->rid,
- (pexBitmask) PEXRDPickInclusion, (CARD32) sizeof (pexNameSet),
- (char *) &(dev->filter.incl));
-
- PEXChangeRenderer (ws->display, ws->rid,
- (pexBitmask) PEXRDPickExclusion, (CARD32) sizeof (pexNameSet),
- (char *) &(dev->filter.excl));
-
-
- PEXBeginPickOne (ws->display, ws->rid, ws->drawable_id, -1,
- PEXLast, pickDataBytes, &pickData);
-
- post_str = owsb->posted.highest.lower;
- end = &(owsb->posted.lowest);
-
- while (post_str != end) {
- phg_wsb_traverse_net (ws, post_str->structh);
- post_str = post_str->lower;
- }
-
- PEXEndPickOne (ws->display, ws->rid, &betterPick,
- &pickPath, &pickDepth);
- }
-
-
- if (!pickDepth) {
-
- pick->status = PIN_STATUS_NONE;
- pick->pick_path.depth = 0;
- pick->pick_path.path_list = (Ppick_path_elem *) NULL;
-
- } else {
-
- /*
- * The protocol pick element ref data structure has its fields
- * layed out in a different order than the PHIGS data structure.
- * We must repack the data into PHIGS format.
- */
-
- for (i = 1; i < pickDepth; i++) {
- Ppick_path_elem *dst = (Ppick_path_elem *) &pickPath[i];
- pexPickElementRef src;
-
- src = pickPath[i];
- dst->struct_id = src.sid;
- dst->pick_id = src.pickid;
- dst->elem_pos = src.offset;
- }
-
- /*
- * order = bottom first?
- */
-
- if (dev->order == PORDER_BOTTOM_FIRST) {
- int head, tail;
- pexPickElementRef temp;
-
- head = 1;
- tail = pickDepth - 1;
-
- for (i = 0; i < (pickDepth - 1) / 2; i++) {
- temp = pickPath[head];
- pickPath[head] = pickPath[tail];
- pickPath[tail] = temp;
- head++;
- tail--;
- }
- }
-
- /*
- * return status and pick path
- */
-
- pick->status = PIN_STATUS_OK;
- pick->pick_path.depth = pickDepth - 1;
- pick->pick_path.path_list = (Ppick_path_elem *) &(pickPath[1]);
- }
-
- return 1;
- }
-
- void
- phg_wsb_inq_filter( ws, type, ret )
- Ws *ws;
- Phg_args_flt_type type;
- Phg_ret *ret;
- {
- phg_wsx_inq_name_set( ws, type, (Pint)0, ret );
- }
-
-
- void
- phg_wsb_drawable_pick( ws, args, ret )
- Ws *ws;
- Phg_args_drawable_pick *args;
- Phg_ret *ret;
- {
- ret->err = ERRN500;
- ERR_BUF( ws->erh, ret->err );
- ret->data.drawable_pick.status = PIN_STATUS_NO_IN;
- ret->data.drawable_pick.pick.depth = 0;
- ret->data.drawable_pick.pick.path_list = (Ppick_path_elem *)NULL;
- }
-
-
- void
- phg_wsb_map_points( ws, args, ret )
- Ws *ws;
- Phg_args_map_points *args;
- Phg_ret *ret;
- {
- pexDeviceCoord *dc_pts;
-
- register int i;
-
- ret->err = 0;
- ret->data.map_points.view_index = 0;
- ret->data.map_points.points.num_points = 0;
- ret->data.map_points.points.points = (Ppoint3 *)NULL;
-
- /* Allocate space for both the DC and WC points. */
- if ( !PHG_SCRATCH_SPACE( &ws->scratch,
- (unsigned)(args->points.num_points
- * (sizeof(Ppoint) + sizeof(Ppoint3))) ) ) {
- ERR_BUF( ws->erh, ERR900 );
- return;
- }
- dc_pts = (pexDeviceCoord *)ws->scratch.buf;
- ret->data.map_points.points.points =
- (Ppoint3 *)(dc_pts + args->points.num_points);
-
- /* Convert the points to DC. */
- phg_wsx_update_ws_rect( ws );
- for ( i = 0; i < args->points.num_points; i++ ) {
- /* Z coord is already in DC. */
- WS_DRWBL_TO_DC2(ws, &args->points.points[i], &dc_pts[i]);
- dc_pts[i].z = args->points.points[i].z;
- }
-
- /* Convert the DC points to WC. */
- if ( !phg_wsb_resolve_stroke( ws, args->points.num_points, dc_pts, 0,
- &ret->data.map_points.view_index,
- &ret->data.map_points.points ) ) {
- ret->data.map_points.points.num_points = 0;
- }
- }
-
- void
- phg_wsb_redraw_regions( ws, args )
- Ws *ws;
- Phg_args_redraw_regions *args;
- {
- pexDeviceRect *pex_rects;
- pexBitmask rmask;
- CARD32 *card32_p;
-
- if ( args->num_regions <= 0 )
- return;
-
- if ( !(pex_rects = (pexDeviceRect *)PHG_SCRATCH_SPACE( &ws->scratch,
- sizeof(CARD32) +
- (unsigned)(args->num_regions * sizeof(*pex_rects)) )) ) {
- ERR_BUF( ws->erh, ERR900 );
- return;
- }
- card32_p = (CARD32 *)ws->scratch.buf;
- pex_rects = (pexDeviceRect *)(card32_p + 1);
-
- *card32_p = args->num_regions;
- phg_wsx_convert_rects( ws, args->num_regions, args->regions, pex_rects );
- rmask = PEXRDClipList;
- (void)PEXChangeRenderer( ws->display, ws->rid, rmask,
- (CARD32)(sizeof(CARD32) + args->num_regions * sizeof(pexDeviceRect)),
- (char *)card32_p );
- (*ws->repaint_all)( ws, PFLAG_COND, args->num_regions, args->regions );
-
- /* Reset the renderer's clip list. */
- *card32_p = 0;
- (void)PEXChangeRenderer( ws->display, ws->rid, rmask,(CARD32)sizeof(CARD32),
- (char *)card32_p );
- }
-