xref: /petsc/src/sys/classes/draw/impls/x/xinit.c (revision 48db01dbaf7213d9604721bf982f95b4af452dee)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith /*
35c6c1daeSBarry Smith    This file contains routines to open an X window display and window
45c6c1daeSBarry Smith    This consists of a number of routines that set the various
55c6c1daeSBarry Smith    fields in the Window structure, which is passed to
65c6c1daeSBarry Smith    all of these routines.
75c6c1daeSBarry Smith 
85c6c1daeSBarry Smith    Note that if you use the default visual and colormap, then you
95c6c1daeSBarry Smith    can use these routines with any X toolkit that will give you the
105c6c1daeSBarry Smith    Window id of the window that it is managing.  Use that instead of the
115c6c1daeSBarry Smith    call to PetscDrawXiCreateWindow .  Similarly for the Display.
125c6c1daeSBarry Smith */
135c6c1daeSBarry Smith 
145c6c1daeSBarry Smith #include <../src/sys/classes/draw/impls/x/ximpl.h>
155c6c1daeSBarry Smith 
1615d5bc79SLisandro Dalcin extern PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,Colormap);
175c6c1daeSBarry Smith 
185c6c1daeSBarry Smith /*
1915d5bc79SLisandro Dalcin   PetscDrawXiOpenDisplay - Open and setup a display
205c6c1daeSBarry Smith */
215c6c1daeSBarry Smith #undef __FUNCT__
225c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiOpenDisplay"
2309440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiOpenDisplay(PetscDraw_X *XiWin,const char display[])
245c6c1daeSBarry Smith {
255c6c1daeSBarry Smith   PetscFunctionBegin;
2615d5bc79SLisandro Dalcin   XiWin->disp = XOpenDisplay(display);
275c6c1daeSBarry Smith   if (!XiWin->disp) {
2815d5bc79SLisandro Dalcin     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open display on %s\n\
2915d5bc79SLisandro Dalcin     Make sure your COMPUTE NODES are authorized to connect \n\
305c6c1daeSBarry Smith     to this X server and either your DISPLAY variable\n\
3115d5bc79SLisandro Dalcin     is set or you use the -display name option\n",display);
325c6c1daeSBarry Smith   }
335c6c1daeSBarry Smith   XiWin->screen     = DefaultScreen(XiWin->disp);
34481cee7bSLisandro Dalcin   XiWin->vis        = DefaultVisual(XiWin->disp,XiWin->screen);
35481cee7bSLisandro Dalcin   XiWin->depth      = DefaultDepth(XiWin->disp,XiWin->screen);
3615d5bc79SLisandro Dalcin   XiWin->cmap       = DefaultColormap(XiWin->disp,XiWin->screen);
3715d5bc79SLisandro Dalcin   XiWin->background = WhitePixel(XiWin->disp,XiWin->screen);
3815d5bc79SLisandro Dalcin   XiWin->foreground = BlackPixel(XiWin->disp,XiWin->screen);
395c6c1daeSBarry Smith   PetscFunctionReturn(0);
405c6c1daeSBarry Smith }
415c6c1daeSBarry Smith 
42815f00f0SLisandro Dalcin #undef __FUNCT__
43815f00f0SLisandro Dalcin #define __FUNCT__ "PetscDrawXiClose"
44815f00f0SLisandro Dalcin PetscErrorCode PetscDrawXiClose(PetscDraw_X *XiWin)
45815f00f0SLisandro Dalcin {
46815f00f0SLisandro Dalcin   PetscErrorCode ierr;
47815f00f0SLisandro Dalcin 
48815f00f0SLisandro Dalcin   PetscFunctionBegin;
49815f00f0SLisandro Dalcin   if (!XiWin) PetscFunctionReturn(0);
50815f00f0SLisandro Dalcin   ierr = PetscFree(XiWin->font);CHKERRQ(ierr);
51815f00f0SLisandro Dalcin   if (XiWin->disp) {
52815f00f0SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H)
53815f00f0SLisandro Dalcin     jmp_buf              jmpbuf;
54815f00f0SLisandro Dalcin     PetscXIOErrorHandler xioerrhdl;
55815f00f0SLisandro Dalcin     ierr = PetscMemcpy(&jmpbuf,&PetscXIOErrorHandlerJumpBuf,sizeof(jmpbuf));CHKERRQ(ierr);
56815f00f0SLisandro Dalcin     xioerrhdl = PetscSetXIOErrorHandler(PetscXIOErrorHandlerJump);
57815f00f0SLisandro Dalcin     if (!setjmp(PetscXIOErrorHandlerJumpBuf))
58815f00f0SLisandro Dalcin #endif
59815f00f0SLisandro Dalcin     {
60815f00f0SLisandro Dalcin       XFreeGC(XiWin->disp,XiWin->gc.set);
61815f00f0SLisandro Dalcin       XCloseDisplay(XiWin->disp);
62815f00f0SLisandro Dalcin     }
63815f00f0SLisandro Dalcin     XiWin->disp = NULL;
64815f00f0SLisandro Dalcin #if defined(PETSC_HAVE_SETJMP_H)
65815f00f0SLisandro Dalcin     (void)PetscSetXIOErrorHandler(xioerrhdl);
66815f00f0SLisandro Dalcin     ierr = PetscMemcpy(&PetscXIOErrorHandlerJumpBuf,&jmpbuf,sizeof(jmpbuf));CHKERRQ(ierr);
67815f00f0SLisandro Dalcin #endif
68815f00f0SLisandro Dalcin   }
69815f00f0SLisandro Dalcin   PetscFunctionReturn(0);
70815f00f0SLisandro Dalcin }
71815f00f0SLisandro Dalcin 
725c6c1daeSBarry Smith /*
7309440f25SLisandro Dalcin    PetscDrawXiCreateGC - setup the GC structure
745c6c1daeSBarry Smith */
755c6c1daeSBarry Smith #undef __FUNCT__
7609440f25SLisandro Dalcin #define __FUNCT__ "PetscDrawXiCreateGC"
7709440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiCreateGC(PetscDraw_X *XiWin,PetscDrawXiPixVal fg)
785c6c1daeSBarry Smith {
795c6c1daeSBarry Smith   XGCValues gcvalues;             /* window graphics context values */
805c6c1daeSBarry Smith 
815c6c1daeSBarry Smith   PetscFunctionBegin;
825c6c1daeSBarry Smith   /* Set the graphics contexts */
835c6c1daeSBarry Smith   /* create a gc for the ROP_SET operation (writing the fg value to a pixel) */
845c6c1daeSBarry Smith   /* (do this with function GXcopy; GXset will automatically write 1) */
855c6c1daeSBarry Smith   gcvalues.function   = GXcopy;
865c6c1daeSBarry Smith   gcvalues.foreground = fg;
875c6c1daeSBarry Smith   XiWin->gc.cur_pix   = fg;
885c6c1daeSBarry Smith   XiWin->gc.set       = XCreateGC(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),GCFunction|GCForeground,&gcvalues);
8915d5bc79SLisandro Dalcin   if (!XiWin->gc.set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to create X graphics context");
9015d5bc79SLisandro Dalcin   PetscFunctionReturn(0);
9115d5bc79SLisandro Dalcin }
9215d5bc79SLisandro Dalcin 
9315d5bc79SLisandro Dalcin /*
94815f00f0SLisandro Dalcin    PetscDrawXiInit - basic setup the draw (display, graphics context, font)
9515d5bc79SLisandro Dalcin */
9615d5bc79SLisandro Dalcin #undef __FUNCT__
97815f00f0SLisandro Dalcin #define __FUNCT__ "PetscDrawXiInit"
9865d9662dSLisandro Dalcin PetscErrorCode PetscDrawXiInit(PetscDraw_X *XiWin,const char display[])
9915d5bc79SLisandro Dalcin {
10015d5bc79SLisandro Dalcin   PetscErrorCode ierr;
10115d5bc79SLisandro Dalcin   PetscFunctionBegin;
10215d5bc79SLisandro Dalcin   ierr = PetscDrawXiOpenDisplay(XiWin,display);CHKERRQ(ierr);
10309440f25SLisandro Dalcin   ierr = PetscDrawXiCreateGC(XiWin,XiWin->foreground);CHKERRQ(ierr);
10415d5bc79SLisandro Dalcin   ierr = PetscDrawXiFontFixed(XiWin,6,10,&XiWin->font);CHKERRQ(ierr);
1055c6c1daeSBarry Smith   PetscFunctionReturn(0);
1065c6c1daeSBarry Smith }
1075c6c1daeSBarry Smith 
1085c6c1daeSBarry Smith /*
10909440f25SLisandro Dalcin     This routine waits until the window is actually created or destroyed
11009440f25SLisandro Dalcin     Returns 0 if window is mapped; 1 if window is destroyed.
11109440f25SLisandro Dalcin  */
11209440f25SLisandro Dalcin #undef __FUNCT__
11309440f25SLisandro Dalcin #define __FUNCT__ "PetscDrawXiWaitMap"
11409440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiWaitMap(PetscDraw_X *XiWin)
11509440f25SLisandro Dalcin {
11609440f25SLisandro Dalcin   XEvent event;
11709440f25SLisandro Dalcin 
11809440f25SLisandro Dalcin   PetscFunctionBegin;
11909440f25SLisandro Dalcin   while (1) {
12009440f25SLisandro Dalcin     XMaskEvent(XiWin->disp,ExposureMask|StructureNotifyMask,&event);
12109440f25SLisandro Dalcin     if (event.xany.window != XiWin->win) break;
12209440f25SLisandro Dalcin     else {
12309440f25SLisandro Dalcin       switch (event.type) {
12409440f25SLisandro Dalcin       case ConfigureNotify:
12509440f25SLisandro Dalcin         /* window has been moved or resized */
12609440f25SLisandro Dalcin         XiWin->w = event.xconfigure.width  - 2 * event.xconfigure.border_width;
12709440f25SLisandro Dalcin         XiWin->h = event.xconfigure.height - 2 * event.xconfigure.border_width;
12809440f25SLisandro Dalcin         break;
12909440f25SLisandro Dalcin       case DestroyNotify:
13009440f25SLisandro Dalcin         PetscFunctionReturn(1);
13109440f25SLisandro Dalcin       case Expose:
13209440f25SLisandro Dalcin         PetscFunctionReturn(0);
13309440f25SLisandro Dalcin         /* else ignore event */
13409440f25SLisandro Dalcin       }
13509440f25SLisandro Dalcin     }
13609440f25SLisandro Dalcin   }
13709440f25SLisandro Dalcin   PetscFunctionReturn(0);
13809440f25SLisandro Dalcin }
13909440f25SLisandro Dalcin 
14009440f25SLisandro Dalcin /*
1415c6c1daeSBarry Smith     Actually display a window at [x,y] with sizes (w,h)
1425c6c1daeSBarry Smith */
1435c6c1daeSBarry Smith #undef __FUNCT__
1445c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiDisplayWindow"
14509440f25SLisandro Dalcin static PetscErrorCode PetscDrawXiDisplayWindow(PetscDraw_X *XiWin,char *label,int x,int y,int w,int h)
1465c6c1daeSBarry Smith {
1475c6c1daeSBarry Smith   unsigned int         wavail,havail;
1485c6c1daeSBarry Smith   XSizeHints           size_hints;
1495c6c1daeSBarry Smith   XWindowAttributes    in_window_attributes;
1505c6c1daeSBarry Smith   XSetWindowAttributes window_attributes;
15115d5bc79SLisandro Dalcin   unsigned int         border_width = 0;
15215d5bc79SLisandro Dalcin   unsigned long        backgnd_pixel = WhitePixel(XiWin->disp,XiWin->screen);
1535c6c1daeSBarry Smith   unsigned long        wmask;
1545c6c1daeSBarry Smith 
1555c6c1daeSBarry Smith   PetscFunctionBegin;
1565c6c1daeSBarry Smith   /* get the available widths */
1575c6c1daeSBarry Smith   wavail = DisplayWidth(XiWin->disp,XiWin->screen);
1585c6c1daeSBarry Smith   havail = DisplayHeight(XiWin->disp,XiWin->screen);
1595c6c1daeSBarry Smith   if (w <= 0 || h <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"X Window display has invalid height or width");
1605c6c1daeSBarry Smith   if ((unsigned int)w > wavail) w = wavail;
1615c6c1daeSBarry Smith   if ((unsigned int)h > havail) h = havail;
1625c6c1daeSBarry Smith 
16315d5bc79SLisandro Dalcin   if (x < 0) x = (int)(wavail - (unsigned int)w + (unsigned int)x);
16415d5bc79SLisandro Dalcin   if (y < 0) y = (int)(havail - (unsigned int)h + (unsigned int)y);
16515d5bc79SLisandro Dalcin   x = ((unsigned int)x + w > wavail) ? (int)(wavail - (unsigned int)w) : x;
16615d5bc79SLisandro Dalcin   y = ((unsigned int)y + h > havail) ? (int)(havail - (unsigned int)h) : y;
1675c6c1daeSBarry Smith 
1685c6c1daeSBarry Smith   /* We need XCreateWindow since we may need an visual other than the default one */
1695c6c1daeSBarry Smith   XGetWindowAttributes(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),&in_window_attributes);
1705c6c1daeSBarry Smith   window_attributes.background_pixmap = None;
1715c6c1daeSBarry Smith   window_attributes.background_pixel  = backgnd_pixel;
1725c6c1daeSBarry Smith   /* No border for now */
1735c6c1daeSBarry Smith   window_attributes.border_pixmap     = None;
1745c6c1daeSBarry Smith   /*
1755c6c1daeSBarry Smith   window_attributes.border_pixel      = border_pixel;
1765c6c1daeSBarry Smith   */
1775c6c1daeSBarry Smith   window_attributes.bit_gravity       = in_window_attributes.bit_gravity;
1785c6c1daeSBarry Smith   window_attributes.win_gravity       = in_window_attributes.win_gravity;
1795c6c1daeSBarry Smith   /* Backing store is too slow in color systems */
18015d5bc79SLisandro Dalcin   window_attributes.backing_store     = NotUseful;
1815c6c1daeSBarry Smith   window_attributes.backing_pixel     = backgnd_pixel;
1825c6c1daeSBarry Smith   window_attributes.save_under        = 1;
1835c6c1daeSBarry Smith   window_attributes.event_mask        = 0;
1845c6c1daeSBarry Smith   window_attributes.do_not_propagate_mask = 0;
1855c6c1daeSBarry Smith   window_attributes.override_redirect = 0;
1865c6c1daeSBarry Smith   window_attributes.colormap          = XiWin->cmap;
1875c6c1daeSBarry Smith   /* None for cursor does NOT mean none, it means cursor of Parent */
1885c6c1daeSBarry Smith   window_attributes.cursor            = None;
189a297a907SKarl Rupp 
1905c6c1daeSBarry Smith   wmask = CWBackPixmap | CWBackPixel    | CWBorderPixmap  | CWBitGravity |
1915c6c1daeSBarry Smith           CWWinGravity | CWBackingStore | CWBackingPixel  | CWOverrideRedirect |
1925c6c1daeSBarry Smith           CWSaveUnder  | CWEventMask    | CWDontPropagate |
1935c6c1daeSBarry Smith           CWCursor     | CWColormap;
1945c6c1daeSBarry Smith 
19515d5bc79SLisandro Dalcin   XiWin->win = XCreateWindow(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),x,y,w,h,border_width,XiWin->depth,InputOutput,XiWin->vis,wmask,&window_attributes);
1965c6c1daeSBarry Smith   if (!XiWin->win) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Unable to open X window");
1975c6c1daeSBarry Smith 
1985c6c1daeSBarry Smith   /* set window manager hints */
1995c6c1daeSBarry Smith   {
2005c6c1daeSBarry Smith     XWMHints      wm_hints;
2015c6c1daeSBarry Smith     XClassHint    class_hints;
2025c6c1daeSBarry Smith     XTextProperty windowname,iconname;
2035c6c1daeSBarry Smith 
204a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&windowname);
205a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&windowname);
206a297a907SKarl Rupp     if (label) XStringListToTextProperty(&label,1,&iconname);
207a297a907SKarl Rupp     else       XStringListToTextProperty(&label,0,&iconname);
2085c6c1daeSBarry Smith 
2095c6c1daeSBarry Smith     wm_hints.initial_state = NormalState;
2105c6c1daeSBarry Smith     wm_hints.input         = True;
2115c6c1daeSBarry Smith     wm_hints.flags         = StateHint|InputHint;
2125c6c1daeSBarry Smith 
2135c6c1daeSBarry Smith     /* These properties can be used by window managers to decide how to display a window */
2145c6c1daeSBarry Smith     class_hints.res_name  = (char*)"petsc";
2155c6c1daeSBarry Smith     class_hints.res_class = (char*)"PETSc";
2165c6c1daeSBarry Smith 
2175c6c1daeSBarry Smith     size_hints.x          = x;
2185c6c1daeSBarry Smith     size_hints.y          = y;
2195c6c1daeSBarry Smith     size_hints.min_width  = 4*border_width;
2205c6c1daeSBarry Smith     size_hints.min_height = 4*border_width;
2215c6c1daeSBarry Smith     size_hints.width      = w;
2225c6c1daeSBarry Smith     size_hints.height     = h;
2235c6c1daeSBarry Smith     size_hints.flags      = USPosition | USSize | PMinSize;
2245c6c1daeSBarry Smith 
2255c6c1daeSBarry Smith     XSetWMProperties(XiWin->disp,XiWin->win,&windowname,&iconname,0,0,&size_hints,&wm_hints,&class_hints);
2265c6c1daeSBarry Smith     XFree((void*)windowname.value);
2275c6c1daeSBarry Smith     XFree((void*)iconname.value);
2285c6c1daeSBarry Smith   }
229481cee7bSLisandro Dalcin 
2305c6c1daeSBarry Smith   /* make the window visible */
2315c6c1daeSBarry Smith   XSelectInput(XiWin->disp,XiWin->win,ExposureMask|StructureNotifyMask);
2325c6c1daeSBarry Smith   XMapWindow(XiWin->disp,XiWin->win);
2335c6c1daeSBarry Smith   /* some window systems are cruel and interfere with the placement of
2345c6c1daeSBarry Smith      windows.  We wait here for the window to be created or to die */
23509440f25SLisandro Dalcin   if (PetscDrawXiWaitMap(XiWin)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Wait for X window failed");
23673ecf448SLisandro Dalcin   XSelectInput(XiWin->disp,XiWin->win,NoEventMask);
2375c6c1daeSBarry Smith   PetscFunctionReturn(0);
2385c6c1daeSBarry Smith }
2395c6c1daeSBarry Smith 
2405c6c1daeSBarry Smith #undef __FUNCT__
2415c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindow"
24215d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindow(PetscDraw_X *XiWin,char *name,int x,int y,int nx,int ny)
2435c6c1daeSBarry Smith {
2445c6c1daeSBarry Smith   PetscErrorCode ierr;
2455c6c1daeSBarry Smith 
2465c6c1daeSBarry Smith   PetscFunctionBegin;
24715d5bc79SLisandro Dalcin   ierr = PetscDrawSetColormap_X(XiWin,(Colormap)0);CHKERRQ(ierr);
24815d5bc79SLisandro Dalcin   ierr = PetscDrawXiDisplayWindow(XiWin,name,x,y,nx,ny);CHKERRQ(ierr);
24915d5bc79SLisandro Dalcin   XSetWindowBackground(XiWin->disp,XiWin->win,XiWin->background);
25015d5bc79SLisandro Dalcin   XClearWindow(XiWin->disp,XiWin->win);
2515c6c1daeSBarry Smith   PetscFunctionReturn(0);
2525c6c1daeSBarry Smith }
2535c6c1daeSBarry Smith 
2545c6c1daeSBarry Smith /*
2555c6c1daeSBarry Smith    A version from an already defined window
2565c6c1daeSBarry Smith */
2575c6c1daeSBarry Smith #undef __FUNCT__
2585c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawXiQuickWindowFromWindow"
25915d5bc79SLisandro Dalcin PetscErrorCode PetscDrawXiQuickWindowFromWindow(PetscDraw_X *XiWin,Window win)
2605c6c1daeSBarry Smith {
2615c6c1daeSBarry Smith   XWindowAttributes attributes;
26215d5bc79SLisandro Dalcin   PetscErrorCode    ierr;
2635c6c1daeSBarry Smith 
2645c6c1daeSBarry Smith   PetscFunctionBegin;
26515d5bc79SLisandro Dalcin   XiWin->win = win;
26615d5bc79SLisandro Dalcin   XGetWindowAttributes(XiWin->disp,XiWin->win,&attributes);
26715d5bc79SLisandro Dalcin   ierr = PetscDrawSetColormap_X(XiWin,attributes.colormap);CHKERRQ(ierr);
2685c6c1daeSBarry Smith   PetscFunctionReturn(0);
2695c6c1daeSBarry Smith }
2705c6c1daeSBarry Smith 
27109440f25SLisandro Dalcin #undef __FUNCT__
27209440f25SLisandro Dalcin #define __FUNCT__ "PetscDrawXiQuickPixmap"
27309440f25SLisandro Dalcin PetscErrorCode PetscDrawXiQuickPixmap(PetscDraw_X* XiWin)
27409440f25SLisandro Dalcin {
2755c6c1daeSBarry Smith   PetscFunctionBegin;
27609440f25SLisandro Dalcin   if (XiWin->drw) XFreePixmap(XiWin->disp,XiWin->drw);
27709440f25SLisandro Dalcin   XiWin->drw = XCreatePixmap(XiWin->disp,RootWindow(XiWin->disp,XiWin->screen),XiWin->w,XiWin->h,XiWin->depth);
27809440f25SLisandro Dalcin   PetscDrawXiSetPixVal(XiWin,XiWin->background);
27909440f25SLisandro Dalcin   XFillRectangle(XiWin->disp,XiWin->drw,XiWin->gc.set,0,0,XiWin->w,XiWin->h);
28009440f25SLisandro Dalcin   XSync(XiWin->disp,False);
2815c6c1daeSBarry Smith   PetscFunctionReturn(0);
2825c6c1daeSBarry Smith }
283*48db01dbSLisandro Dalcin 
284*48db01dbSLisandro Dalcin #undef __FUNCT__
285*48db01dbSLisandro Dalcin #define __FUNCT__ "PetscDrawXiGetGeometry"
286*48db01dbSLisandro Dalcin PetscErrorCode PetscDrawXiGetGeometry(PetscDraw_X *XiWin,int *x,int *y,int *w,int *h)
287*48db01dbSLisandro Dalcin {
288*48db01dbSLisandro Dalcin   XWindowAttributes attributes;
289*48db01dbSLisandro Dalcin   Window            root,parent,child;
290*48db01dbSLisandro Dalcin   int               xx=0,yy=0;
291*48db01dbSLisandro Dalcin   unsigned int      ww=0,hh=0,dummy;
292*48db01dbSLisandro Dalcin   PetscFunctionBegin;
293*48db01dbSLisandro Dalcin   if (XiWin->win) {
294*48db01dbSLisandro Dalcin     XGetGeometry(XiWin->disp,XiWin->win,&parent,&xx,&yy,&ww,&hh,&dummy,&dummy);
295*48db01dbSLisandro Dalcin     root = RootWindow(XiWin->disp,XiWin->screen);
296*48db01dbSLisandro Dalcin     if (!XTranslateCoordinates(XiWin->disp,XiWin->win,root,0,0,&xx,&yy,&child)) {
297*48db01dbSLisandro Dalcin       XGetWindowAttributes(XiWin->disp,XiWin->win,&attributes);
298*48db01dbSLisandro Dalcin       root = attributes.screen->root;
299*48db01dbSLisandro Dalcin       (void)XTranslateCoordinates(XiWin->disp,XiWin->win,root,0,0,&xx,&yy,&child);
300*48db01dbSLisandro Dalcin     }
301*48db01dbSLisandro Dalcin   } else if (XiWin->drw) {
302*48db01dbSLisandro Dalcin     XGetGeometry(XiWin->disp,XiWin->drw,&root,&xx,&yy,&ww,&hh,&dummy,&dummy);
303*48db01dbSLisandro Dalcin   }
304*48db01dbSLisandro Dalcin   if (x) *x = xx;
305*48db01dbSLisandro Dalcin   if (y) *y = yy;
306*48db01dbSLisandro Dalcin   if (w) *w = (int)ww;
307*48db01dbSLisandro Dalcin   if (h) *h = (int)hh;
308*48db01dbSLisandro Dalcin   PetscFunctionReturn(0);
309*48db01dbSLisandro Dalcin }
310