/* $XConsortium: testutils.c,v 5.3 94/04/17 20:46:39 hersh Exp $ */ /***************************************************************** Copyright (c) 1989,1990, 1991 X Consortium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. 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, and the X Consortium, 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. ******************************************************************/ /* * This file contains PHIGS testing utilties */ #include "X11/Xlib.h" #include "X11/Xatom.h" #include "stdio.h" #include "signal.h" #include "pixutils.h" #include "logmsg.h" #include "imath.h" #include "testutils.h" #define BUFSIZE 1024 #ifdef NEWT #include "NewTvararg.h" #else #include "varargs.h" #endif #define MAXCOLOR 256 #define eqstring(a,b) !strcmp((a),(b)) /* compare text string */ #define SCALE_FACTOR 255 #define SEPS 1 #define SEQ(a,b) ( (int)(a)>(int)(b)-SEPS && (int)(a)<(int)(b)+SEPS ) #define MINIMUM(a,b) flt((a),(b))? (a):(b) /* * global variables */ /* * forward declaration */ /* * export routines */ void i_fake_button(); void i_open_phigs(); void i_open_ws(); void i_open_x_ws(); Ppoint3* i_generate_n_Ppoint3(); Ppoint_list3* i_generate_n_Ppoint_list3(); void i_grid(); int i_check_pixel3(); int i_check_line3(); void i_viewxform_point3(); void i_wsxform_point3(); void i_get_window_dim(); void i_make_xwindow(); Pint i_get_ws_type(); void i_print_var(); void i_pause(); int i_bogus_error(); Pdyn_mod i_get_ws_dyn_mod(); Pdyn_mod i_get_struct_dyn_mod(); int i_get_phigs_info(); int i_is_posted_struct(); #ifdef NEWT void _tfprintf(); void _tvprintf(); void _tabort(); #endif /* local data structure */ typedef struct { Pint x; Pint y; } int_point; /* local routines */ static void i_get_ws_info(); static void post_button(); static void post_button_on_interrupt(); /* global variables */ Display *save_display; Window save_window; int save_x; int save_y; /* * i_open_phigs(errfile,memsize) * call popen_phigs() by default, if environment variables * "I_NO_MONITOR" and/or "I_CLIENT_SIDE" is set, then * call popen_xphigs() instead */ void i_open_phigs(errfile,memsize) char* errfile; size_t memsize; { static Pxphigs_info pexinfo = {NULL,NULL,{NULL,NULL},{NULL,NULL},{0,0}}; unsigned long mask = 0; if (clientside) { pexinfo.flags.force_client_SS = 1; mask |= PXPHIGS_INFO_FLAGS_CLIENT_SS; } if (nomonitor) { pexinfo.flags.no_monitor = 1; mask |= PXPHIGS_INFO_FLAGS_NO_MON; } if (pexinfo.flags.force_client_SS || pexinfo.flags.no_monitor) popen_xphigs(errfile,memsize,mask,&pexinfo); else popen_phigs(errfile, memsize); } /* * i_open_ws(ws) * open a simple x_tool type PHIGS workstation */ void i_open_ws(ws) int ws; { popen_ws(ws,NULL,phigs_ws_type_x_tool); } /* * i_open_x_ws(ws,display,window,x,y,w,h) * open a x drawable type ws by default, if the environment variable * "I_X_TOOL_WS" is set, then open a x tool type ws. * If "I_WIN_X_OFFSET" and/or "I_WIN_Y_OFFSET" is set, the values are * used in offsetting the position of the window. * This functions takes as input the ws id, position of window (x,y) and * its width(w) and height(h), the display pointer(display) and the * window id of the ws (window) is returned. */ void i_open_x_ws(ws,display,window,x,y,w,h) int ws; Display **display; Window *window; int x,y,w,h; { Pconnid_x_drawable ws_conn; int wstype; Pescape_out_data *escout; Pescape_in_data escin; Pstore store; Pint err; if (xtoolws) { wstype = phigs_ws_type_create(phigs_ws_type_x_tool, PHIGS_TOOL_X, x + winxoffset, PHIGS_TOOL_Y, y + winyoffset, PHIGS_TOOL_WIDTH, w, PHIGS_TOOL_HEIGHT, h, NULL); popen_ws(1, NULL, wstype); pcreate_store(&err, &store ); if (err) tabort("ERROR: i_get_ws_info: %d in pcreate_store\n",err); escin.escape_in_u2.ws_id = ws; pescape(PUESC_DPYINFO, &escin, store, &escout); *window = escout->escape_out_u2.drawable_id; if (clientside && ! nomonitor) *display = XOpenDisplay(escout->escape_out_u2.display_name); else *display = escout->escape_out_u2.display; } else { i_make_xwindow(display, window, &ws_conn, x, y, w, h); popen_ws(ws,&ws_conn,phigs_ws_type_x_drawable); } } /* * i_get_ws_info(ws,display,overlay) * to return the X's display and the overlay input window of the given ws */ static void i_get_ws_info(ws,display,overlay) Pint ws; Display **display; Window *overlay; { Pescape_out_data *escout; Pescape_in_data escin; Pstore store; Pint err; pcreate_store(&err, &store ); if (err) tabort("ERROR: i_get_ws_info: %d in pcreate_store\n",err); escin.escape_in_u2.ws_id = ws; pescape(PUESC_DPYINFO, &escin, store, &escout); *overlay = escout->escape_out_u2.input_overlay_id; if (clientside && ! nomonitor) *display = XOpenDisplay(escout->escape_out_u2.display_name); else *display = escout->escape_out_u2.display; } /* * i_fake_button(ws,viewind,point,timeout) * to simulate button input, if timeout > 0, then post the event at interrupt * after timeout seconds */ void i_fake_button(ws,viewind,point,timeout) Pint ws; Pint viewind; Ppoint3 point; int timeout; { Display *display; Window overlay; int pcptx,pcpty; Ppoint3 ndcpt; int offdisplay; i_get_ws_info(ws,&display,&overlay); /* calculate position in dc */ /* apply view xform */ i_viewxform_point3(ws,viewind,point,&ndcpt); /* apply workstation xform */ i_wsxform_point3(display,overlay,ws,ndcpt,&pcptx,&pcpty,&offdisplay); if (offdisplay) {/* pixel is off display */ return; } if (timeout > 0) { save_display = display; save_window = overlay; save_x = pcptx; save_y = pcpty; signal(SIGALRM,post_button_on_interrupt); alarm(timeout); } else { post_button(display,overlay,pcptx,pcpty); } } /* * post_button_on_interrupt() * to post button input on receiving an alarm signal */ static void post_button_on_interrupt() { post_button(save_display,save_window,save_x,save_y); } /* * post_button(display,window,x,y) * to post button input to specified window */ static void post_button(display,window,x,y) Display *display; Window window; Pint x,y; { XEvent button; unsigned long mask; /* stuff event structure */ mask = ButtonPress; button.xbutton.display = display; button.xbutton.window = window; button.xbutton.root = DefaultRootWindow(display); button.xbutton.subwindow = None; button.xbutton.type = ButtonPress; button.xbutton.button = 1; button.xbutton.time = CurrentTime; button.xbutton.send_event = True; button.xbutton.same_screen = True; button.xbutton.x = x; button.xbutton.y = y; button.xbutton.x_root = 0; button.xbutton.y_root = 0; button.xbutton.serial = 0; /* send button press event */ XSendEvent(display,window,True,mask,&button); XSync(display,0); } /* * i_generate_n_Ppoint3(n) * return an array of n points */ Ppoint3* i_generate_n_Ppoint3(n,x,y,delta) int n; /* number of points */ Pfloat x; /* x coordinate of starting position */ Pfloat y; /* y coordinate of starting position */ Pfloat delta; /* increment */ { Ppoint3* p; int i; int xdir = 1; int ydir = 1; p = (Ppoint3*) malloc(n*sizeof(Ppoint3)); for (i=0;i 0); } else tvprintf(0,"i_get_phigs_info: unknown class\n"); } /* * i_get_ws_dyn_mod(ws,class) * return the dynamic modification type of the given class */ Pdyn_mod i_get_ws_dyn_mod(ws,class) Pint ws; char *class; { Pdyns_ws_attrs wsmods; Pint err; Pint wstype; Pconnid cid; pinq_ws_conn_type(ws,BUFSIZE,&err,&cid,&wstype); if (err) tabort("ERROR: i_get_ws_dyn_mod: %d in pinq_ws_conn_type\n",err); pinq_dyns_ws_attrs(wstype,&err,&wsmods); if (err) tabort("ERROR: i_get_ws_dyn_mod: %d in pinq_dyns_ws_attrs\n",err); if (eqstring(class,"workstation transformation modification")) return(wsmods.ws_tran); if (eqstring(class,"view representation modification")) return(wsmods.view_rep); if (eqstring(class,"invisibility filter modification")) return(wsmods.invis_filter); if (eqstring(class,"colour representation modification")) return(wsmods.colr_rep); if (eqstring(class,"polyline bundle representation modification")) return(wsmods.line_bundle); else tvprintf(0,"i_get_ws_dyn_mod: unknown class\n"); } /* * i_get_struct_dyn_mod(ws,class) * return the dynamic modification type of the given class */ Pdyn_mod i_get_struct_dyn_mod(ws,class) Pint ws; char *class; { Pdyns_structs structmods; Pint err; Pint wstype; Pconnid cid; pinq_ws_conn_type(ws,BUFSIZE,&err,&cid,&wstype); if (err) tabort("ERROR: i_get_struct_dyn_mod: %d in pinq_ws_conn_type\n",err); pinq_dyns_structs(wstype,&err,&structmods); if (err) tabort("ERROR: i_get_struct_dyn_mod: %d in pinq_dyns_structs\n",err); if (eqstring(class,"post structure")) return(structmods.post); if (eqstring(class,"unpost structure")) return(structmods.unpost); if (eqstring(class,"structure content modification")) return(structmods.content); if (eqstring(class,"reference modification")) return(structmods.ref); if (eqstring(class,"delete structure")) return(structmods.del); else tvprintf(0,"i_get_struct_dyn_mod: unknown class\n"); } /* * i_bogus_error() * return a bogus value -1234 */ int i_bogus_error() { return(-1234); } /* * i_check_line3(display,window,ws,viewind,line,dim,col) * check the existence of a line of the specified colour by sampling pixels * at the end points and the middle of the line after view and ws transformation * return value * = 1, if found * = 0, if not found */ int i_check_line3(display,window,ws,viewind,line,dim,col) Display *display; /* X display */ Window window; /* X window */ Pint ws; /* workstation id */ Pint viewind; /* view index */ Ppoint3 *line; /* line in wc 3D */ int dim; /* dimension of square area to be examined */ Pint col; /* colour index */ { Ppoint3 midpt; midpt.x = (line[0].x + line[1].x) /2; midpt.y = (line[0].y + line[1].y) /2; midpt.z = (line[0].z + line[1].z) /2; if ( i_check_pixel3(display,window,ws,viewind,line[0],dim,col) && i_check_pixel3(display,window,ws,viewind,line[1],dim,col) && i_check_pixel3(display,window,ws,viewind,midpt,dim,col) ) return(1); else return(0); } /* * i_check_pixel3(display,window,ws,viewind,wcpt,dim,col) * check the existence of the any pixel of the specifed colour within * the bounding box after view and ws transformation * return value * = 1, if found * = 0, if not found */ int i_check_pixel3(display,window,ws,viewind,wcpt,dim,col) Display *display; /* X display */ Window window; /* X window */ Pint ws; /* workstation id */ Pint viewind; /* view index */ Ppoint3 wcpt; /* wc point 3D */ Pint dim; /* dimension of square area to be examined */ Pint col; /* colour index */ { int pcptx,pcpty; Ppoint3 ndcpt; int x,y,i,j,err; int found; Unsign8 *pp,*pixbuf; Unsign8 cmaptbl[MAXCOLOR][4]; Unsign8 r,g,b; Colormap cmap; int offdisplay; Unsign8 colr,colg,colb; Pcolr_rep rep; int bits_per_rgb; XWindowAttributes attr; found = 0; for (i=0;i> 1)); y = (Pint) (pcpty - (dim >> 1)); /* make sure the pixel grid is entirely inside the window*/ if (!XGetWindowAttributes(display,window,&attr)) tabort("ERROR: i_check_pixel3: in XGetWIndowAttributes, exiting...\n"); if (x < 0) x = 0; else if (x+dim >= attr.width) x = attr.width - 1 - dim; if (y < 0) y = 0; else if (y+dim >= attr.height) y = attr.height - 1 - dim; /* retrieve pixels from xwindow */ pp = pixbuf = i_get_pixel_array(display,window,x,y,dim,dim); cmap = i_get_window_cmap(display,window); #ifdef INQ_COLR_REP_BUG printf("WARNING: test is faking pinq_colr_rep\n"); switch (col) { case 1: rep.rgb.red = rep.rgb.green = rep.rgb.blue = 1.0; break; case 2: rep.rgb.red = 1.0; rep.rgb.green = rep.rgb.blue = 0.0; break; case 3: rep.rgb.green = 1.0; rep.rgb.red = rep.rgb.blue = 0.0; break; case 4: rep.rgb.blue = 1.0; rep.rgb.red = rep.rgb.green = 0.0; break; case 5: rep.rgb.red = rep.rgb.green = 1.0; rep.rgb.blue = 0.0; break; case 6: rep.rgb.green = rep.rgb.blue = 1.0; rep.rgb.red = 0.0; break; case 7: rep.rgb.red = rep.rgb.blue = 1.0; rep.rgb.green = 0.0; break; default: puts("i_check_pixel3: unknown colour"); } #else pinq_colr_rep(ws,col,PINQ_REALIZED,&err,&rep); if (err) tabort("ERROR: i_check_pixel3: %d in pinq_colr_rep, exiting...\n",err); #endif colr = rep.rgb.red * SCALE_FACTOR + 0.5; colg = rep.rgb.green * SCALE_FACTOR + 0.5; colb = rep.rgb.blue * SCALE_FACTOR + 0.5; bits_per_rgb = i_get_bits_per_rgb(display); for (i=0;i= 3) { tvprintf(4, "i_check_pixel3: pcpt (%d,%d), pixel array: ",x,y); for (i=0;ix,npcpt->y,npcpt->z); } /* * i_wsxform_point3(display,window,ws,npcpt,pcptx,pcpty,offdisplay) * transform a pt from ndc to dc without ws clipping * OUT offdisplay = 1 if point in pixel coordinate is offdisplay * = 0 otherwise */ void i_wsxform_point3(display,window,ws,npcpt,pcptx,pcpty,offdisplay) Display *display; /* X display */ Window window; /* X window */ Pint ws; /* workstation id */ Ppoint3 npcpt; /* wc point 3D */ int *pcptx; /* OUT x in pixel coordinate */ int *pcpty; /* OUT y in pixel coordinate */ int *offdisplay; /* OUT is pixel offdisplay? */ { int err; Pmatrix3 wstr; float mult; int i,j; int w,h; Plimit3 *winp,*vportp; Ppoint3 dcpt; Plimit3 cwin,rwin,cvport,rvport; Pupd_st updst; *offdisplay = 0; pinq_ws_tran3(ws, &err, &updst,&rwin,&cwin,&rvport,&cvport); if (err) tabort("ERROR: i_wsform_point3: %d in pinq_ws_tran3, exiting\n",err); /* figure out matrix for ws xform */ vportp = &cvport; winp = &cwin; mult = MINIMUM((vportp->x_max-vportp->x_min)/(winp->x_max-winp->x_min), (vportp->y_max-vportp->y_min)/(winp->y_max-winp->y_min)); for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) wstr[i][j] = 0.0; for (i = 0; i < 2; i++) wstr[i][i] = mult; if (feq (winp->z_min, winp->z_max)) wstr[2][2] = 0.0; else wstr[2][2] = (vportp->z_max-vportp->z_min) / (winp->z_max - winp->z_min); wstr[0][3] = vportp->x_min - mult * winp->x_min; wstr[1][3] = vportp->y_min - mult * winp->y_min; wstr[2][3] = vportp->z_min - wstr[2][2] * winp->z_min; wstr[3][3] = 1.0; /* apply ws xform */ ptran_point3(&npcpt, wstr, &err, &dcpt); if (err) tabort("ERROR: i_wsform_point3: %d in ptranspt3, exiting...\n",err); /* convert dc (device coordinate) to pc (pixel coordinate) */ i_get_window_dim(display,window,&w,&h); *pcptx = dcpt.x; *pcpty = h - dcpt.y; if (fgt (*pcptx, w-1) || flt (*pcptx,0) || fgt (*pcpty, h-1) || flt (*pcpty,0) ) { tvprintf(3,"i_wsxform_point3:this point is off display\n"); *offdisplay = 1; } tvprintf(3,"i_wsxform_point3:npcpt(%.2f,%.2f,%.2f) dcpt(%.2f,%.2f,%.2f) pcpt(%d,%d)\n", npcpt.x,npcpt.y,npcpt.z,dcpt.x,dcpt.y,dcpt.z,*pcptx,*pcpty); } /* * i_get_window_dim(display,window,w,h) retrieve window's dimension */ void i_get_window_dim(display,window,w,h) Display *display; /* X display */ Window window; /* X window */ int *w; /* width */ int *h; /* height */ { /* Return the colormap of the window */ XWindowAttributes attr; if (!XGetWindowAttributes(display,window,&attr)) tabort("ERROR: i_get_window_dim: in XGetWindowAttributes, exiting\n"); *w = attr.width; *h = attr.height; } /* * i_get_ws_type(string) * returns a Pint variable according to the input string */ Pint i_get_ws_type(string) char *string; { if (eqstring(string,"phigs_ws_type_x_tool")) return(phigs_ws_type_x_tool); else if (eqstring(string,"phigs_ws_type_x_drawable")) return(phigs_ws_type_x_drawable); else tvprintf(0,"i_get_ws_type: unknown type\n"); } /* * i_make_xwindow(display,window,conn,x,y,w,h) * creates a X window origin at (x,y) with dimension (w,h) * it opens a X display if for the first time and initialize * the PHIGS connection id */ void i_make_xwindow(display,window,conn,x,y,w,h) Display **display; Window *window; Pconnid_x_drawable *conn; int x,y,w,h; { Visual visual; XSetWindowAttributes xswa; XEvent exposureEvent; static firsttime = 1; static Visual *vis; XSizeHints wmhint; int status; if (firsttime) { /* call XOpenDisplay only the first time */ /* this function is called */ firsttime = 0; *display = XOpenDisplay(""); if (!*display) tabort("ERROR: i_make_xwindow: in XOpenDisplay, exiting...\n"); vis = DefaultVisual(*display,DefaultScreen(*display)); if (vis->class != PseudoColor) tabort("ERROR: i_make_xwindow: inpex currently supports only PSEUDOCOLOR, exiting...\n"); } x += winxoffset; y += winyoffset; xswa.backing_store = NotUseful; xswa.event_mask = ExposureMask | StructureNotifyMask; xswa.background_pixel = BlackPixel(*display, DefaultScreen(*display)); xswa.border_pixel = WhitePixel(*display, DefaultScreen(*display)); visual.visualid = vis->visualid; *window = XCreateWindow(*display,RootWindow(*display,DefaultScreen(*display)), x, y, w, h, 1, DefaultDepth(*display, DefaultScreen(*display)),InputOutput, &visual,CWEventMask|CWBackingStore|CWBorderPixel|CWBackPixel, &xswa); if (!*window) tabort("ERROR: i_make_xwindow: in XCreateWindow, exiting...\n"); wmhint.x = x; wmhint.y = y; wmhint.width = w; wmhint.height = h; wmhint.flags = PPosition | PSize; XSetStandardProperties(*display,*window,"inspex","inspex",None,NULL,0, &wmhint); XMapWindow(*display,*window); XSync(*display,0); XWindowEvent(*display, *window, ExposureMask, &exposureEvent); conn->display = *display; conn->drawable_id = *window; } /* * i_print_var(type,va_alist) prints the value of a PHIGS variable */ void i_print_var(type,va_alist) char *type; va_dcl { int i,j; va_list ap; Pmatrix3 *vmatrix3; Pmatrix *vmatrix; Ppoint3 vpoint3; Ppoint vpoint; Pint_list vintlst; Plimit vlimit; Plimit3 vlimit3; printf("%s:",type); va_start(ap); if (eqstring(type,"Pmatrix")) { vmatrix = va_arg(ap,Pmatrix*); for (i=0;i<3;++i){ for (j=0;j<3;++j) printf("%.2f ",(*vmatrix)[i][j]); puts(""); } } else if (eqstring(type,"Pmatrix3")) { vmatrix3 = va_arg(ap,Pmatrix3*); for (i=0;i<4;++i){ for (j=0;j<4;++j) printf("%.2f ",(*vmatrix3)[i][j]); puts(""); } } else if (eqstring(type,"Ppoint3")) { vpoint3 = va_arg(ap,Ppoint3); printf("(%.4f,%.4f,%.4f)\n",vpoint3.x,vpoint3.y,vpoint3.z); } else if (eqstring(type,"Ppoint")) { vpoint = va_arg(ap,Ppoint); printf("(%.4f,%.4f)\n",vpoint.x,vpoint.y); } else if (eqstring(type,"Pint_list")) { vintlst = va_arg(ap,Pint_list); printf("number: %d, list: ",vintlst.num_ints); for (i=0;i= maxfail) { printf("%s: Exiting, too many failures (%d).\n",testname,numfail); tendtest(); exit(1); } } /* * _tvprintf(ver,fmt,va_alist) prints out message according to given verbosity */ void _tvprintf(ver, fmt, va_alist) int ver; /* current verbosity */ char *fmt; /* message fmt */ va_dcl /* variable data */ { va_list ap; /* print out message if VERBOSITY >= this message's verbosity */ if (ver <= verbosity) { va_start(ap); printf("%s: ",testname); _printf(fmt, ap); va_end(ap); } } /* * _tabort(fmt,va_alist) prints out message and abort test */ void _tabort(fmt, va_alist) char *fmt; /* message fmt */ va_dcl /* variable data */ { va_list ap; va_start(ap); printf("%s: ",testname); _printf(fmt, ap); va_end(ap); ++numfail; tendtest(); exit(1); } #endif