PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/hpc_kernel_samples/sparse_linear_algebra/casestudies/pagerank-petsc/petsc-2.3.2-p10/src/sys/draw/impls/x/xops.c

https://gitlab.com/steinret/CodeVault
C | 775 lines | 635 code | 99 blank | 41 comment | 66 complexity | fe8dfcc431fe87a376159a72aca60cc6 MD5 | raw file
  1. /*
  2. Defines the operations for the X PetscDraw implementation.
  3. */
  4. #include "src/sys/draw/impls/x/ximpl.h" /*I "petsc.h" I*/
  5. /*
  6. These macros transform from the users coordinates to the
  7. X-window pixel coordinates.
  8. */
  9. #define XTRANS(draw,xwin,x) \
  10. (int)(((xwin)->w)*((draw)->port_xl + (((x - (draw)->coor_xl)*\
  11. ((draw)->port_xr - (draw)->port_xl))/\
  12. ((draw)->coor_xr - (draw)->coor_xl))))
  13. #define YTRANS(draw,xwin,y) \
  14. (int)(((xwin)->h)*(1.0-(draw)->port_yl - (((y - (draw)->coor_yl)*\
  15. ((draw)->port_yr - (draw)->port_yl))/\
  16. ((draw)->coor_yr - (draw)->coor_yl))))
  17. #undef __FUNCT__
  18. #define __FUNCT__ "PetscDrawLine_X"
  19. PetscErrorCode PetscDrawLine_X(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int cl)
  20. {
  21. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  22. int x1,y_1,x2,y2;
  23. PetscFunctionBegin;
  24. XiSetColor(XiWin,cl);
  25. x1 = XTRANS(draw,XiWin,xl); x2 = XTRANS(draw,XiWin,xr);
  26. y_1 = YTRANS(draw,XiWin,yl); y2 = YTRANS(draw,XiWin,yr);
  27. XDrawLine(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,x1,y_1,x2,y2);
  28. PetscFunctionReturn(0);
  29. }
  30. #undef __FUNCT__
  31. #define __FUNCT__ "PetscDrawPoint_X"
  32. static PetscErrorCode PetscDrawPoint_X(PetscDraw draw,PetscReal x,PetscReal y,int c)
  33. {
  34. int xx,yy;
  35. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  36. PetscFunctionBegin;
  37. xx = XTRANS(draw,XiWin,x); yy = YTRANS(draw,XiWin,y);
  38. XiSetColor(XiWin,c);
  39. XDrawPoint(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,xx,yy);
  40. PetscFunctionReturn(0);
  41. }
  42. #undef __FUNCT__
  43. #define __FUNCT__ "PetscDrawRectangle_X"
  44. static PetscErrorCode PetscDrawRectangle_X(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
  45. {
  46. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  47. int x1,y_1,w,h,c = (c1 + c2 + c3 + c4)/4;
  48. PetscFunctionBegin;
  49. XiSetColor(XiWin,c);
  50. x1 = XTRANS(draw,XiWin,xl); w = XTRANS(draw,XiWin,xr) - x1;
  51. y_1 = YTRANS(draw,XiWin,yr); h = YTRANS(draw,XiWin,yl) - y_1;
  52. if (w <= 0) w = 1; if (h <= 0) h = 1;
  53. XFillRectangle(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,x1,y_1,w,h);
  54. PetscFunctionReturn(0);
  55. }
  56. #undef __FUNCT__
  57. #define __FUNCT__ "PetscDrawEllipse_X"
  58. static PetscErrorCode PetscDrawEllipse_X(PetscDraw Win, PetscReal x, PetscReal y, PetscReal a, PetscReal b, int c)
  59. {
  60. PetscDraw_X* XiWin = (PetscDraw_X*) Win->data;
  61. int xA, yA, w, h;
  62. PetscFunctionBegin;
  63. XiSetColor(XiWin, c);
  64. xA = XTRANS(Win, XiWin, x - a/2.0); w = XTRANS(Win, XiWin, x + a/2.0) - xA;
  65. yA = YTRANS(Win, XiWin, y + b/2.0); h = YTRANS(Win, XiWin, y - b/2.0) - yA;
  66. XFillArc(XiWin->disp, XiDrawable(XiWin), XiWin->gc.set, xA, yA, w, h, 0, 23040);
  67. PetscFunctionReturn(0);
  68. }
  69. EXTERN PetscErrorCode PetscDrawInterpolatedTriangle_X(PetscDraw_X*,int,int,int,int,int,int,int,int,int);
  70. #undef __FUNCT__
  71. #define __FUNCT__ "PetscDrawTriangle_X"
  72. static PetscErrorCode PetscDrawTriangle_X(PetscDraw draw,PetscReal X1,PetscReal Y_1,PetscReal X2,
  73. PetscReal Y2,PetscReal X3,PetscReal Y3,int c1,int c2,int c3)
  74. {
  75. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  76. PetscErrorCode ierr;
  77. PetscFunctionBegin;
  78. if (c1 == c2 && c2 == c3) {
  79. XPoint pt[3];
  80. XiSetColor(XiWin,c1);
  81. pt[0].x = XTRANS(draw,XiWin,X1);
  82. pt[0].y = YTRANS(draw,XiWin,Y_1);
  83. pt[1].x = XTRANS(draw,XiWin,X2);
  84. pt[1].y = YTRANS(draw,XiWin,Y2);
  85. pt[2].x = XTRANS(draw,XiWin,X3);
  86. pt[2].y = YTRANS(draw,XiWin,Y3);
  87. XFillPolygon(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,pt,3,Convex,CoordModeOrigin);
  88. } else {
  89. int x1,y_1,x2,y2,x3,y3;
  90. x1 = XTRANS(draw,XiWin,X1);
  91. y_1 = YTRANS(draw,XiWin,Y_1);
  92. x2 = XTRANS(draw,XiWin,X2);
  93. y2 = YTRANS(draw,XiWin,Y2);
  94. x3 = XTRANS(draw,XiWin,X3);
  95. y3 = YTRANS(draw,XiWin,Y3);
  96. ierr = PetscDrawInterpolatedTriangle_X(XiWin,x1,y_1,c1,x2,y2,c2,x3,y3,c3);CHKERRQ(ierr);
  97. }
  98. PetscFunctionReturn(0);
  99. }
  100. #undef __FUNCT__
  101. #define __FUNCT__ "PetscDrawString_X"
  102. static PetscErrorCode PetscDrawString_X(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
  103. {
  104. PetscErrorCode ierr;
  105. int xx,yy;
  106. size_t len;
  107. PetscDraw_X *XiWin = (PetscDraw_X*)draw->data;
  108. char *substr;
  109. PetscToken *token;
  110. PetscFunctionBegin;
  111. xx = XTRANS(draw,XiWin,x); yy = YTRANS(draw,XiWin,y);
  112. XiSetColor(XiWin,c);
  113. ierr = PetscTokenCreate(chrs,'\n',&token);CHKERRQ(ierr);
  114. ierr = PetscTokenFind(token,&substr);CHKERRQ(ierr);
  115. ierr = PetscStrlen(substr,&len);CHKERRQ(ierr);
  116. XDrawString(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,xx,yy - XiWin->font->font_descent,substr,len);
  117. ierr = PetscTokenFind(token,&substr);CHKERRQ(ierr);
  118. while (substr) {
  119. yy += 4*XiWin->font->font_descent;
  120. ierr = PetscStrlen(substr,&len);CHKERRQ(ierr);
  121. XDrawString(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,xx,yy - XiWin->font->font_descent,substr,len);
  122. ierr = PetscTokenFind(token,&substr);CHKERRQ(ierr);
  123. }
  124. ierr = PetscTokenDestroy(token);CHKERRQ(ierr);
  125. PetscFunctionReturn(0);
  126. }
  127. EXTERN PetscErrorCode XiFontFixed(PetscDraw_X*,int,int,XiFont **);
  128. #undef __FUNCT__
  129. #define __FUNCT__ "PetscDrawStringSetSize_X"
  130. static PetscErrorCode PetscDrawStringSetSize_X(PetscDraw draw,PetscReal x,PetscReal y)
  131. {
  132. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  133. PetscErrorCode ierr;
  134. int w,h;
  135. PetscFunctionBegin;
  136. w = (int)((XiWin->w)*x*(draw->port_xr - draw->port_xl)/(draw->coor_xr - draw->coor_xl));
  137. h = (int)((XiWin->h)*y*(draw->port_yr - draw->port_yl)/(draw->coor_yr - draw->coor_yl));
  138. ierr = PetscFree(XiWin->font);CHKERRQ(ierr);
  139. ierr = XiFontFixed(XiWin,w,h,&XiWin->font);CHKERRQ(ierr);
  140. PetscFunctionReturn(0);
  141. }
  142. #undef __FUNCT__
  143. #define __FUNCT__ "PetscDrawStringGetSize_X"
  144. PetscErrorCode PetscDrawStringGetSize_X(PetscDraw draw,PetscReal *x,PetscReal *y)
  145. {
  146. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  147. PetscReal w,h;
  148. PetscFunctionBegin;
  149. w = XiWin->font->font_w; h = XiWin->font->font_h;
  150. *x = w*(draw->coor_xr - draw->coor_xl)/(XiWin->w)*(draw->port_xr - draw->port_xl);
  151. *y = h*(draw->coor_yr - draw->coor_yl)/(XiWin->h)*(draw->port_yr - draw->port_yl);
  152. PetscFunctionReturn(0);
  153. }
  154. #undef __FUNCT__
  155. #define __FUNCT__ "PetscDrawStringVertical_X"
  156. PetscErrorCode PetscDrawStringVertical_X(PetscDraw draw,PetscReal x,PetscReal y,int c,const char chrs[])
  157. {
  158. PetscErrorCode ierr;
  159. int xx,yy;
  160. PetscDraw_X *XiWin = (PetscDraw_X*)draw->data;
  161. char tmp[2];
  162. PetscReal tw,th;
  163. size_t i,n;
  164. PetscFunctionBegin;
  165. ierr = PetscStrlen(chrs,&n);CHKERRQ(ierr);
  166. tmp[1] = 0;
  167. XiSetColor(XiWin,c);
  168. ierr = PetscDrawStringGetSize_X(draw,&tw,&th);CHKERRQ(ierr);
  169. xx = XTRANS(draw,XiWin,x);
  170. for (i=0; i<n; i++) {
  171. tmp[0] = chrs[i];
  172. yy = YTRANS(draw,XiWin,y-th*i);
  173. XDrawString(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,
  174. xx,yy - XiWin->font->font_descent,tmp,1);
  175. }
  176. PetscFunctionReturn(0);
  177. }
  178. #undef __FUNCT__
  179. #define __FUNCT__ "PetscDrawFlush_X"
  180. static PetscErrorCode PetscDrawFlush_X(PetscDraw draw)
  181. {
  182. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  183. PetscFunctionBegin;
  184. if (XiWin->drw) {
  185. XCopyArea(XiWin->disp,XiWin->drw,XiWin->win,XiWin->gc.set,0,0,XiWin->w,XiWin->h,0,0);
  186. }
  187. XFlush(XiWin->disp); XSync(XiWin->disp,False);
  188. PetscFunctionReturn(0);
  189. }
  190. #undef __FUNCT__
  191. #define __FUNCT__ "PetscDrawSynchronizedFlush_X"
  192. static PetscErrorCode PetscDrawSynchronizedFlush_X(PetscDraw draw)
  193. {
  194. PetscErrorCode ierr;
  195. PetscMPIInt rank;
  196. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  197. PetscFunctionBegin;
  198. XFlush(XiWin->disp);
  199. if (XiWin->drw) {
  200. ierr = MPI_Comm_rank(draw->comm,&rank);CHKERRQ(ierr);
  201. /* make sure data has actually arrived at server */
  202. XSync(XiWin->disp,False);
  203. ierr = MPI_Barrier(draw->comm);CHKERRQ(ierr);
  204. if (!rank) {
  205. XCopyArea(XiWin->disp,XiWin->drw,XiWin->win,XiWin->gc.set,0,0,XiWin->w,XiWin->h,0,0);
  206. XFlush(XiWin->disp);
  207. }
  208. XSync(XiWin->disp,False);
  209. ierr = MPI_Barrier(draw->comm);CHKERRQ(ierr);
  210. } else {
  211. ierr = MPI_Barrier(draw->comm);CHKERRQ(ierr);
  212. XSync(XiWin->disp,False);
  213. ierr = MPI_Barrier(draw->comm);CHKERRQ(ierr);
  214. }
  215. PetscFunctionReturn(0);
  216. }
  217. #undef __FUNCT__
  218. #define __FUNCT__ "PetscDrawSetViewport_X"
  219. static PetscErrorCode PetscDrawSetViewport_X(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr)
  220. {
  221. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  222. XRectangle box;
  223. PetscFunctionBegin;
  224. box.x = (int)(xl*XiWin->w); box.y = (int)((1.0-yr)*XiWin->h);
  225. box.width = (int)((xr-xl)*XiWin->w);box.height = (int)((yr-yl)*XiWin->h);
  226. XSetClipRectangles(XiWin->disp,XiWin->gc.set,0,0,&box,1,Unsorted);
  227. PetscFunctionReturn(0);
  228. }
  229. #undef __FUNCT__
  230. #define __FUNCT__ "PetscDrawClear_X"
  231. static PetscErrorCode PetscDrawClear_X(PetscDraw draw)
  232. {
  233. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  234. int x, y, w, h;
  235. PetscFunctionBegin;
  236. x = (int)(draw->port_xl*XiWin->w);
  237. w = (int)((draw->port_xr - draw->port_xl)*XiWin->w);
  238. y = (int)((1.0-draw->port_yr)*XiWin->h);
  239. h = (int)((draw->port_yr - draw->port_yl)*XiWin->h);
  240. XiSetPixVal(XiWin,XiWin->background);
  241. XFillRectangle(XiWin->disp,XiDrawable(XiWin),XiWin->gc.set,x,y,w,h);
  242. PetscFunctionReturn(0);
  243. }
  244. #undef __FUNCT__
  245. #define __FUNCT__ "PetscDrawSynchronizedClear_X"
  246. static PetscErrorCode PetscDrawSynchronizedClear_X(PetscDraw draw)
  247. {
  248. PetscErrorCode ierr;
  249. PetscMPIInt rank;
  250. PetscDraw_X* XiWin = (PetscDraw_X*)draw->data;
  251. PetscFunctionBegin;
  252. ierr = MPI_Barrier(draw->comm);CHKERRQ(ierr);
  253. ierr = MPI_Comm_rank(draw->comm,&rank);CHKERRQ(ierr);
  254. if (!rank) {
  255. ierr = PetscDrawClear_X(draw);CHKERRQ(ierr);
  256. }
  257. XFlush(XiWin->disp);
  258. ierr = MPI_Barrier(draw->comm);CHKERRQ(ierr);
  259. XSync(XiWin->disp,False);
  260. ierr = MPI_Barrier(draw->comm);CHKERRQ(ierr);
  261. PetscFunctionReturn(0);
  262. }
  263. #undef __FUNCT__
  264. #define __FUNCT__ "PetscDrawSetDoubleBuffer_X"
  265. static PetscErrorCode PetscDrawSetDoubleBuffer_X(PetscDraw draw)
  266. {
  267. PetscDraw_X* win = (PetscDraw_X*)draw->data;
  268. PetscErrorCode ierr;
  269. PetscMPIInt rank;
  270. PetscFunctionBegin;
  271. if (win->drw) PetscFunctionReturn(0);
  272. ierr = MPI_Comm_rank(draw->comm,&rank);CHKERRQ(ierr);
  273. if (!rank) {
  274. win->drw = XCreatePixmap(win->disp,win->win,win->w,win->h,win->depth);
  275. }
  276. /* try to make sure it is actually done before passing info to all */
  277. XSync(win->disp,False);
  278. ierr = MPI_Bcast(&win->drw,1,MPI_UNSIGNED_LONG,0,draw->comm);CHKERRQ(ierr);
  279. PetscFunctionReturn(0);
  280. }
  281. #include <X11/cursorfont.h>
  282. #undef __FUNCT__
  283. #define __FUNCT__ "PetscDrawGetMouseButton_X"
  284. static PetscErrorCode PetscDrawGetMouseButton_X(PetscDraw draw,PetscDrawButton *button,PetscReal* x_user,
  285. PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
  286. {
  287. XEvent report;
  288. PetscDraw_X* win = (PetscDraw_X*)draw->data;
  289. Window root,child;
  290. int root_x,root_y,px,py;
  291. unsigned int keys_button;
  292. Cursor cursor = 0;
  293. PetscFunctionBegin;
  294. /* change cursor to indicate input */
  295. if (!cursor) {
  296. cursor = XCreateFontCursor(win->disp,XC_hand2);
  297. if (!cursor) SETERRQ(PETSC_ERR_LIB,"Unable to create X cursor");
  298. }
  299. XDefineCursor(win->disp,win->win,cursor);
  300. XSelectInput(win->disp,win->win,ButtonPressMask | ButtonReleaseMask);
  301. while (XCheckTypedEvent(win->disp,ButtonPress,&report));
  302. XMaskEvent(win->disp,ButtonReleaseMask,&report);
  303. switch (report.xbutton.button) {
  304. case Button1:
  305. if (report.xbutton.state & ShiftMask)
  306. *button = BUTTON_LEFT_SHIFT;
  307. else
  308. *button = BUTTON_LEFT;
  309. break;
  310. case Button2:
  311. if (report.xbutton.state & ShiftMask)
  312. *button = BUTTON_CENTER_SHIFT;
  313. else
  314. *button = BUTTON_CENTER;
  315. break;
  316. case Button3:
  317. if (report.xbutton.state & ShiftMask)
  318. *button = BUTTON_RIGHT_SHIFT;
  319. else
  320. *button = BUTTON_RIGHT;
  321. break;
  322. }
  323. XQueryPointer(win->disp,report.xmotion.window,&root,&child,&root_x,&root_y,&px,&py,&keys_button);
  324. if (x_phys) *x_phys = ((double)px)/((double)win->w);
  325. if (y_phys) *y_phys = 1.0 - ((double)py)/((double)win->h);
  326. if (x_user) *x_user = draw->coor_xl + ((((double)px)/((double)win->w)-draw->port_xl))*
  327. (draw->coor_xr - draw->coor_xl)/(draw->port_xr - draw->port_xl);
  328. if (y_user) *y_user = draw->coor_yl +
  329. ((1.0 - ((double)py)/((double)win->h)-draw->port_yl))*
  330. (draw->coor_yr - draw->coor_yl)/(draw->port_yr - draw->port_yl);
  331. XUndefineCursor(win->disp,win->win);
  332. XFlush(win->disp); XSync(win->disp,False);
  333. PetscFunctionReturn(0);
  334. }
  335. #undef __FUNCT__
  336. #define __FUNCT__ "PetscDrawPause_X"
  337. static PetscErrorCode PetscDrawPause_X(PetscDraw draw)
  338. {
  339. PetscErrorCode ierr;
  340. PetscFunctionBegin;
  341. if (draw->pause > 0) PetscSleep(draw->pause);
  342. else if (draw->pause < 0) {
  343. PetscDrawButton button;
  344. PetscMPIInt rank;
  345. ierr = MPI_Comm_rank(draw->comm,&rank);CHKERRQ(ierr);
  346. if (!rank) {
  347. ierr = PetscDrawGetMouseButton(draw,&button,0,0,0,0);CHKERRQ(ierr);
  348. if (button == BUTTON_CENTER) draw->pause = 0;
  349. }
  350. ierr = MPI_Bcast(&draw->pause,1,MPI_INT,0,draw->comm);CHKERRQ(ierr);
  351. }
  352. PetscFunctionReturn(0);
  353. }
  354. #undef __FUNCT__
  355. #define __FUNCT__ "PetscDrawGetPopup_X"
  356. static PetscErrorCode PetscDrawGetPopup_X(PetscDraw draw,PetscDraw *popup)
  357. {
  358. PetscErrorCode ierr;
  359. PetscDraw_X* win = (PetscDraw_X*)draw->data;
  360. PetscFunctionBegin;
  361. ierr = PetscDrawOpenX(draw->comm,PETSC_NULL,PETSC_NULL,win->x,win->y+win->h+36,150,220,popup);CHKERRQ(ierr);
  362. draw->popup = *popup;
  363. PetscFunctionReturn(0);
  364. }
  365. #undef __FUNCT__
  366. #define __FUNCT__ "PetscDrawSetTitle_X"
  367. static PetscErrorCode PetscDrawSetTitle_X(PetscDraw draw,const char title[])
  368. {
  369. PetscDraw_X *win = (PetscDraw_X*)draw->data;
  370. XTextProperty prop;
  371. PetscErrorCode ierr;
  372. size_t len;
  373. PetscFunctionBegin;
  374. XGetWMName(win->disp,win->win,&prop);
  375. prop.value = (unsigned char *)title;
  376. ierr = PetscStrlen(title,&len);CHKERRQ(ierr);
  377. prop.nitems = (long) len;
  378. XSetWMName(win->disp,win->win,&prop);
  379. PetscFunctionReturn(0);
  380. }
  381. #undef __FUNCT__
  382. #define __FUNCT__ "PetscDrawResizeWindow_X"
  383. static PetscErrorCode PetscDrawResizeWindow_X(PetscDraw draw,int w,int h)
  384. {
  385. PetscDraw_X *win = (PetscDraw_X*)draw->data;
  386. unsigned int ww,hh,border,depth;
  387. int x,y;
  388. PetscErrorCode ierr;
  389. Window root;
  390. PetscFunctionBegin;
  391. XResizeWindow(win->disp,win->win,w,h);
  392. XGetGeometry(win->disp,win->win,&root,&x,&y,&ww,&hh,&border,&depth);
  393. ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
  394. PetscFunctionReturn(0);
  395. }
  396. #undef __FUNCT__
  397. #define __FUNCT__ "PetscDrawCheckResizedWindow_X"
  398. static PetscErrorCode PetscDrawCheckResizedWindow_X(PetscDraw draw)
  399. {
  400. PetscDraw_X *win = (PetscDraw_X*)draw->data;
  401. PetscErrorCode ierr;
  402. int x,y;
  403. PetscMPIInt rank;
  404. Window root;
  405. unsigned int w,h,border,depth,geo[2];
  406. PetscReal xl,xr,yl,yr;
  407. XRectangle box;
  408. PetscFunctionBegin;
  409. ierr = MPI_Comm_rank(draw->comm,&rank);CHKERRQ(ierr);
  410. if (!rank) {
  411. XSync(win->disp,False);
  412. XGetGeometry(win->disp,win->win,&root,&x,&y,geo,geo+1,&border,&depth);
  413. }
  414. ierr = MPI_Bcast(geo,2,MPI_INT,0,draw->comm);CHKERRQ(ierr);
  415. w = geo[0];
  416. h = geo[1];
  417. if (w == (unsigned int) win->w && h == (unsigned int) win->h) PetscFunctionReturn(0);
  418. /* record new window sizes */
  419. win->h = h; win->w = w;
  420. /* Free buffer space and create new version (only first processor does this) */
  421. if (win->drw) {
  422. win->drw = XCreatePixmap(win->disp,win->win,win->w,win->h,win->depth);
  423. }
  424. /* reset the clipping */
  425. xl = draw->port_xl; yl = draw->port_yl;
  426. xr = draw->port_xr; yr = draw->port_yr;
  427. box.x = (int)(xl*win->w); box.y = (int)((1.0-yr)*win->h);
  428. box.width = (int)((xr-xl)*win->w);box.height = (int)((yr-yl)*win->h);
  429. XSetClipRectangles(win->disp,win->gc.set,0,0,&box,1,Unsorted);
  430. /* try to make sure it is actually done before passing info to all */
  431. XSync(win->disp,False);
  432. ierr = MPI_Bcast(&win->drw,1,MPI_UNSIGNED_LONG,0,draw->comm);CHKERRQ(ierr);
  433. PetscFunctionReturn(0);
  434. }
  435. static PetscErrorCode PetscDrawGetSingleton_X(PetscDraw,PetscDraw*);
  436. static PetscErrorCode PetscDrawRestoreSingleton_X(PetscDraw,PetscDraw*);
  437. #undef __FUNCT__
  438. #define __FUNCT__ "PetscDrawDestroy_X"
  439. PetscErrorCode PetscDrawDestroy_X(PetscDraw draw)
  440. {
  441. PetscDraw_X *win = (PetscDraw_X*)draw->data;
  442. PetscErrorCode ierr;
  443. PetscFunctionBegin;
  444. XFreeGC(win->disp,win->gc.set);
  445. XCloseDisplay(win->disp);
  446. if (draw->popup) {ierr = PetscDrawDestroy(draw->popup);CHKERRQ(ierr);}
  447. ierr = PetscFree(win->font);CHKERRQ(ierr);
  448. ierr = PetscFree(win);CHKERRQ(ierr);
  449. PetscFunctionReturn(0);
  450. }
  451. static struct _PetscDrawOps DvOps = { PetscDrawSetDoubleBuffer_X,
  452. PetscDrawFlush_X,PetscDrawLine_X,
  453. 0,
  454. 0,
  455. PetscDrawPoint_X,
  456. 0,
  457. PetscDrawString_X,
  458. PetscDrawStringVertical_X,
  459. PetscDrawStringSetSize_X,
  460. PetscDrawStringGetSize_X,
  461. PetscDrawSetViewport_X,
  462. PetscDrawClear_X,
  463. PetscDrawSynchronizedFlush_X,
  464. PetscDrawRectangle_X,
  465. PetscDrawTriangle_X,
  466. PetscDrawEllipse_X,
  467. PetscDrawGetMouseButton_X,
  468. PetscDrawPause_X,
  469. PetscDrawSynchronizedClear_X,
  470. 0,
  471. 0,
  472. PetscDrawGetPopup_X,
  473. PetscDrawSetTitle_X,
  474. PetscDrawCheckResizedWindow_X,
  475. PetscDrawResizeWindow_X,
  476. PetscDrawDestroy_X,
  477. 0,
  478. PetscDrawGetSingleton_X,
  479. PetscDrawRestoreSingleton_X };
  480. EXTERN PetscErrorCode XiQuickWindow(PetscDraw_X*,char*,char*,int,int,int,int);
  481. EXTERN PetscErrorCode XiQuickWindowFromWindow(PetscDraw_X*,char*,Window);
  482. #undef __FUNCT__
  483. #define __FUNCT__ "PetscDrawGetSingleton_X"
  484. static PetscErrorCode PetscDrawGetSingleton_X(PetscDraw draw,PetscDraw *sdraw)
  485. {
  486. PetscErrorCode ierr;
  487. PetscDraw_X *Xwin = (PetscDraw_X*)draw->data,*sXwin;
  488. PetscFunctionBegin;
  489. ierr = PetscDrawCreate(PETSC_COMM_SELF,draw->display,draw->title,draw->x,draw->y,draw->w,draw->h,sdraw);CHKERRQ(ierr);
  490. ierr = PetscObjectChangeTypeName((PetscObject)*sdraw,PETSC_DRAW_X);CHKERRQ(ierr);
  491. ierr = PetscMemcpy((*sdraw)->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
  492. (*sdraw)->ops->destroy = 0;
  493. (*sdraw)->pause = draw->pause;
  494. (*sdraw)->coor_xl = draw->coor_xl;
  495. (*sdraw)->coor_xr = draw->coor_xr;
  496. (*sdraw)->coor_yl = draw->coor_yl;
  497. (*sdraw)->coor_yr = draw->coor_yr;
  498. (*sdraw)->port_xl = draw->port_xl;
  499. (*sdraw)->port_xr = draw->port_xr;
  500. (*sdraw)->port_yl = draw->port_yl;
  501. (*sdraw)->port_yr = draw->port_yr;
  502. (*sdraw)->popup = draw->popup;
  503. /* actually create and open the window */
  504. ierr = PetscNew(PetscDraw_X,&sXwin);CHKERRQ(ierr);
  505. ierr = XiQuickWindowFromWindow(sXwin,draw->display,Xwin->win);CHKERRQ(ierr);
  506. sXwin->x = Xwin->x;
  507. sXwin->y = Xwin->y;
  508. sXwin->w = Xwin->w;
  509. sXwin->h = Xwin->h;
  510. (*sdraw)->data = (void*)sXwin;
  511. PetscFunctionReturn(0);
  512. }
  513. #undef __FUNCT__
  514. #define __FUNCT__ "PetscDrawRestoreSingleton_X"
  515. static PetscErrorCode PetscDrawRestoreSingleton_X(PetscDraw draw,PetscDraw *sdraw)
  516. {
  517. PetscErrorCode ierr;
  518. PetscDraw_X *sXwin = (PetscDraw_X*)(*sdraw)->data;
  519. PetscFunctionBegin;
  520. XFreeGC(sXwin->disp,sXwin->gc.set);
  521. XCloseDisplay(sXwin->disp);
  522. if ((*sdraw)->popup) {ierr = PetscDrawDestroy((*sdraw)->popup);CHKERRQ(ierr);}
  523. ierr = PetscStrfree((*sdraw)->title);CHKERRQ(ierr);
  524. ierr = PetscStrfree((*sdraw)->display);CHKERRQ(ierr);
  525. ierr = PetscFree(sXwin->font);CHKERRQ(ierr);
  526. ierr = PetscFree(sXwin);CHKERRQ(ierr);
  527. ierr = PetscHeaderDestroy(*sdraw);CHKERRQ(ierr);
  528. PetscFunctionReturn(0);
  529. }
  530. #undef __FUNCT__
  531. #define __FUNCT__ "PetscDrawXGetDisplaySize_Private"
  532. PetscErrorCode PetscDrawXGetDisplaySize_Private(const char name[],int *width,int *height)
  533. {
  534. Display *display;
  535. PetscFunctionBegin;
  536. display = XOpenDisplay(name);
  537. if (!display) {
  538. *width = 0;
  539. *height = 0;
  540. SETERRQ1(PETSC_ERR_LIB,"Unable to open display on %s\n. Make sure your COMPUTE NODES are authorized to connect \n\
  541. to this X server and either your DISPLAY variable\n\
  542. is set or you use the -display name option\n",name);
  543. }
  544. *width = DisplayWidth(display,0);
  545. *height = DisplayHeight(display,0);
  546. XCloseDisplay(display);
  547. PetscFunctionReturn(0);
  548. }
  549. EXTERN_C_BEGIN
  550. #undef __FUNCT__
  551. #define __FUNCT__ "PetscDrawCreate_X"
  552. PetscErrorCode PETSC_DLLEXPORT PetscDrawCreate_X(PetscDraw draw)
  553. {
  554. PetscDraw_X *Xwin;
  555. PetscErrorCode ierr;
  556. PetscMPIInt rank;
  557. PetscInt xywh[4],osize = 4;
  558. int x = draw->x,y = draw->y,w = draw->w,h = draw->h;
  559. static int xavailable = 0,yavailable = 0,xmax = 0,ymax = 0,ybottom = 0;
  560. PetscTruth flg;
  561. PetscFunctionBegin;
  562. if (!draw->display) {
  563. ierr = PetscMalloc(128*sizeof(char),&draw->display);CHKERRQ(ierr);
  564. ierr = PetscGetDisplay(draw->display,128);CHKERRQ(ierr);
  565. }
  566. /*
  567. Initialize the display size
  568. */
  569. if (!xmax) {
  570. ierr = PetscDrawXGetDisplaySize_Private(draw->display,&xmax,&ymax);
  571. /* if some processors fail on this and others succed then this is a problem ! */
  572. if (ierr) {
  573. (*PetscErrorPrintf)("PETSc unable to use X windows\nproceeding without graphics\n");
  574. ierr = PetscDrawSetType(draw,PETSC_DRAW_NULL);CHKERRQ(ierr);
  575. PetscFunctionReturn(0);
  576. }
  577. }
  578. if (w == PETSC_DECIDE) w = draw->w = 300;
  579. if (h == PETSC_DECIDE) h = draw->h = 300;
  580. switch (w) {
  581. case PETSC_DRAW_FULL_SIZE: w = draw->w = xmax - 10;
  582. break;
  583. case PETSC_DRAW_HALF_SIZE: w = draw->w = (xmax - 20)/2;
  584. break;
  585. case PETSC_DRAW_THIRD_SIZE: w = draw->w = (xmax - 30)/3;
  586. break;
  587. case PETSC_DRAW_QUARTER_SIZE: w = draw->w = (xmax - 40)/4;
  588. break;
  589. }
  590. switch (h) {
  591. case PETSC_DRAW_FULL_SIZE: h = draw->h = ymax - 10;
  592. break;
  593. case PETSC_DRAW_HALF_SIZE: h = draw->h = (ymax - 20)/2;
  594. break;
  595. case PETSC_DRAW_THIRD_SIZE: h = draw->h = (ymax - 30)/3;
  596. break;
  597. case PETSC_DRAW_QUARTER_SIZE: h = draw->h = (ymax - 40)/4;
  598. break;
  599. }
  600. /* allow user to set location and size of window */
  601. xywh[0] = x; xywh[1] = y; xywh[2] = w; xywh[3] = h;
  602. ierr = PetscOptionsGetIntArray(PETSC_NULL,"-geometry",xywh,&osize,PETSC_NULL);CHKERRQ(ierr);
  603. x = (int) xywh[0]; y = (int) xywh[1]; w = (int) xywh[2]; h = (int) xywh[3];
  604. if (draw->x == PETSC_DECIDE || draw->y == PETSC_DECIDE) {
  605. /*
  606. PETSc tries to place windows starting in the upper left corner and
  607. moving across to the right.
  608. --------------------------------------------
  609. | Region used so far +xavailable,yavailable |
  610. | + |
  611. | + |
  612. |++++++++++++++++++++++ybottom |
  613. | |
  614. | |
  615. |--------------------------------------------|
  616. */
  617. /* First: can we add it to the right? */
  618. if (xavailable+w+10 <= xmax) {
  619. x = xavailable;
  620. y = yavailable;
  621. ybottom = PetscMax(ybottom,y + h + 30);
  622. } else {
  623. /* No, so add it below on the left */
  624. xavailable = 0;
  625. x = 0;
  626. yavailable = ybottom;
  627. y = ybottom;
  628. ybottom = ybottom + h + 30;
  629. }
  630. }
  631. /* update available region */
  632. xavailable = PetscMax(xavailable,x + w + 10);
  633. if (xavailable >= xmax) {
  634. xavailable = 0;
  635. yavailable = yavailable + h + 30;
  636. ybottom = yavailable;
  637. }
  638. if (yavailable >= ymax) {
  639. y = 0;
  640. yavailable = 0;
  641. ybottom = 0;
  642. }
  643. ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
  644. /* actually create and open the window */
  645. ierr = PetscNew(PetscDraw_X,&Xwin);CHKERRQ(ierr);
  646. ierr = PetscLogObjectMemory(draw,sizeof(PetscDraw_X)+sizeof(struct _p_PetscDraw));CHKERRQ(ierr);
  647. ierr = MPI_Comm_rank(draw->comm,&rank);CHKERRQ(ierr);
  648. if (!rank) {
  649. if (x < 0 || y < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative corner of window");
  650. if (w <= 0 || h <= 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Negative window width or height");
  651. ierr = XiQuickWindow(Xwin,draw->display,draw->title,x,y,w,h);CHKERRQ(ierr);
  652. ierr = MPI_Bcast(&Xwin->win,1,MPI_UNSIGNED_LONG,0,draw->comm);CHKERRQ(ierr);
  653. } else {
  654. unsigned long win = 0;
  655. ierr = MPI_Bcast(&win,1,MPI_UNSIGNED_LONG,0,draw->comm);CHKERRQ(ierr);
  656. ierr = XiQuickWindowFromWindow(Xwin,draw->display,win);CHKERRQ(ierr);
  657. }
  658. Xwin->x = x;
  659. Xwin->y = y;
  660. Xwin->w = w;
  661. Xwin->h = h;
  662. draw->data = (void*)Xwin;
  663. /*
  664. Need barrier here so processor 0 does not destroy the window before other
  665. processors have completed XiQuickWindow()
  666. */
  667. ierr = PetscDrawClear(draw);CHKERRQ(ierr);
  668. ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
  669. ierr = PetscOptionsHasName(PETSC_NULL,"-draw_double_buffer",&flg);CHKERRQ(ierr);
  670. if (flg) {
  671. ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
  672. }
  673. PetscFunctionReturn(0);
  674. }
  675. EXTERN_C_END