PageRenderTime 61ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/ESPS/general/src/libxv/xp_pw.c

https://github.com/jeremysalwen/ESPS
C | 682 lines | 519 code | 72 blank | 91 comment | 126 complexity | e9fda84743dcb8fb269ec8f3007655ed MD5 | raw file
  1. /*
  2. * This material contains unpublished, proprietary software of
  3. * Entropic Research Laboratory, Inc. Any reproduction, distribution,
  4. * or publication of this work must be authorized in writing by Entropic
  5. * Research Laboratory, Inc., and must bear the notice:
  6. *
  7. * "Copyright (c) 1990-1993 Entropic Research Laboratory, Inc.
  8. * All rights reserved"
  9. *
  10. * The copyright notice above does not evidence any actual or intended
  11. * publication of this source code.
  12. *
  13. * Written by:
  14. * Checked by:
  15. * Revised by:
  16. *
  17. * Brief description:
  18. * selected pw (xv) calls with hook for xprinter
  19. *
  20. */
  21. static char *sccs_id = "@(#)xp_pw.c 1.1 6/21/93 ERL";
  22. #include <xview_private/pw_impl.h>
  23. #include <X11/Xlib.h>
  24. #include <X11/Xutil.h>
  25. #define _NO_PROTO
  26. #include <Xp.h>
  27. #include <XpMacros.h>
  28. Display *global_display = (Display *)NULL;
  29. Pkg_private GC Xp_xv_find_proper_gc();
  30. Xv_private int Xp_xv_rop_mpr_internal();
  31. Xv_private void Xp_xv_set_gc_op();
  32. void
  33. set_pw_display(display)
  34. Display *display;
  35. {
  36. global_display = display;
  37. }
  38. Xp_xv_vector(window, x0, y0, x1, y1, op, cms_index)
  39. Xv_opaque window;
  40. int op;
  41. register int x0, y0, x1, y1;
  42. int cms_index;
  43. {
  44. Xv_Drawable_info *info;
  45. Display *display;
  46. Drawable d;
  47. GC gc;
  48. XGCValues gcv;
  49. if(global_display == (Display *)NULL)
  50. /* call real xv_vector function */
  51. return(xv_vector(window, x0, y0, x1, y1, op, cms_index));
  52. DRAWABLE_INFO_MACRO(window, info);
  53. display = global_display;
  54. d = 0;
  55. gc = XpCreateGC(display, 0, 0, &gcv);
  56. if (op == PIX_NOT(PIX_DST)) {
  57. Xp_xv_set_gc_op(display, info, gc, op, XV_USE_CMS_FG, XV_DEFAULT_FG_BG);
  58. } else {
  59. if (!PIX_OPCOLOR(op)) {
  60. op |= PIX_COLOR(cms_index);
  61. }
  62. Xp_xv_set_gc_op(display, info, gc, op, XV_USE_OP_FG, XV_DEFAULT_FG_BG);
  63. }
  64. XDrawLine(display, d, gc, x0, y0, x1, y1);
  65. XpFreeGC(display, gc);
  66. }
  67. #include <xview/window.h>
  68. #include <pixrect/pixfont.h>
  69. PIXFONT *xv_pf_sys;
  70. extern xv_pf_ttext(), xv_pf_text();
  71. extern struct pr_size xv_pf_textwidth();
  72. Xp_xv_ttext(window, xbasew, ybasew, op, pixfont, str)
  73. Xv_opaque window;
  74. int op;
  75. register int xbasew, ybasew;
  76. Xv_opaque pixfont;
  77. char *str;
  78. {
  79. Xv_Drawable_info *info;
  80. Display *display;
  81. Drawable d;
  82. GC gc;
  83. XID font;
  84. int len;
  85. XGCValues gcv;
  86. fprintf(stderr,"called Xp_xv_ttext\n");
  87. exit(1);
  88. if ((len = strlen(str)) == 0) {
  89. return;
  90. }
  91. DRAWABLE_INFO_MACRO(window, info);
  92. if(global_display == (Display *)NULL) {
  93. display = xv_display(info);
  94. d = xv_xid(info);
  95. gc = Xp_xv_find_proper_gc(display, info, PW_TEXT);
  96. } else {
  97. display = global_display;
  98. d = 0;
  99. gc = XpCreateGC(display, 0, 0, &gcv);
  100. }
  101. /* SunView1.X incompatibility: NULL pixfont meant use system_font. */
  102. if (pixfont == 0) {
  103. pixfont = xv_get(window, WIN_FONT);
  104. }
  105. /*
  106. * Since this is transparent text, we always paint it with the background
  107. * color.
  108. */
  109. Xp_xv_set_gc_op(display, info, gc, op, XV_USE_CMS_FG,
  110. XV_INVERTED_FG_BG);
  111. font = (XID) xv_get(pixfont, XV_XID);
  112. XSetFont(display, gc, font);
  113. XDrawString(display, d, gc, xbasew, ybasew, str, len);
  114. XpFreeGC(display, gc);
  115. }
  116. Xp_xv_text(window, xbasew, ybasew, op, pixfont, str)
  117. Xv_opaque window;
  118. int op;
  119. register int xbasew, ybasew;
  120. Xv_opaque pixfont;
  121. char *str;
  122. {
  123. Xv_Drawable_info *info;
  124. Display *display;
  125. Drawable d;
  126. GC gc;
  127. XID font;
  128. int len;
  129. XGCValues gcv;
  130. XFontStruct *Xpxfs=NULL;
  131. if(global_display == (Display *)NULL)
  132. /* call real xv_text function */
  133. return(xv_text(window, xbasew, ybasew, op, pixfont, str));
  134. DRAWABLE_INFO_MACRO(window, info);
  135. display = global_display;
  136. d = 0;
  137. gc = XpCreateGC(display, 0, 0, &gcv);
  138. Xpxfs = XpLoadQueryFont(display,
  139. "-adobe-helvetica-medium-r-normal--*-0-300-300-p-*-iso8859-1");
  140. if(Xpxfs)
  141. XpSetFont(display,gc,Xpxfs->fid);
  142. else
  143. fprintf(stderr,"cannot get font for graphic export\n");
  144. if ((len = strlen(str)) == 0) {
  145. return;
  146. }
  147. /* SunView1.X incompatibility: NULL pixfont meant use system_font. */
  148. if (pixfont == 0) {
  149. pixfont = xv_get(window, WIN_FONT);
  150. }
  151. if (PIX_OP(op) == PIX_NOT(PIX_SRC)) {
  152. Xp_xv_set_gc_op(display, info, gc, op,
  153. PIX_OPCOLOR(op) ? XV_USE_OP_FG : XV_USE_CMS_FG,
  154. XV_INVERTED_FG_BG);
  155. } else {
  156. Xp_xv_set_gc_op(display, info, gc, op,
  157. PIX_OPCOLOR(op) ? XV_USE_OP_FG : XV_USE_CMS_FG,
  158. XV_DEFAULT_FG_BG);
  159. }
  160. XDrawString(display, d, gc, xbasew, ybasew, str, len);
  161. XpFreeGC(display, gc);
  162. }
  163. Xv_public
  164. Xp_xv_rop(window, x, y, width, height, op, pr, xr, yr)
  165. Xv_opaque window;
  166. int op, x, y, width, height;
  167. Pixrect *pr;
  168. int xr, yr;
  169. {
  170. register Xv_Drawable_info *info;
  171. Display *display;
  172. Drawable d;
  173. GC gc;
  174. XGCValues gcv;
  175. if(global_display == (Display *)NULL)
  176. /* call real xv_rop function */
  177. return(xv_rop(window, x, y, width, height, op, pr, xr, yr));
  178. DRAWABLE_INFO_MACRO(window, info);
  179. display = global_display;
  180. d = 0;
  181. gc = XpCreateGC(display, 0, 0, &gcv);
  182. if (pr == NULL) {
  183. Xp_xv_set_gc_op(display, info, gc, op, XV_USE_OP_FG,
  184. XV_DEFAULT_FG_BG);
  185. XFillRectangle(display, d, gc, x, y, width, height);
  186. } else {
  187. Xp_xv_set_gc_op(display, info, gc, op,
  188. PIX_OPCOLOR(op) ? XV_USE_OP_FG : XV_USE_CMS_FG,
  189. XV_DEFAULT_FG_BG);
  190. if (Xp_xv_rop_internal(display, d, gc, x, y, width, height,
  191. (Xv_opaque) pr, xr, yr, info) == XV_ERROR) {
  192. xv_error(NULL,
  193. ERROR_STRING,
  194. "xv_rop: xv_rop_internal failed",
  195. 0);
  196. }
  197. }
  198. XpFreeGC(display, gc);
  199. }
  200. #ifdef __STDC__
  201. #ifndef CAT
  202. #define CAT(a,b) a ## b
  203. #endif
  204. #endif
  205. #include <pixrect/memvar.h>
  206. #include <xview_private/cms_impl.h>
  207. #include <xview_private/svrim_impl.h>
  208. #include <xview_private/i18n_impl.h>
  209. int GC_CHAIN_KEY;
  210. #include <xview/xv_xrect.h>
  211. #define INVALID_XID 0
  212. extern Xv_xrectlist *screen_get_clip_rects();
  213. Xv_private void
  214. Xp_xv_set_gc_op(display, info, gc, op, fg_mode, fg_bg)
  215. Display *display;
  216. Xv_Drawable_info *info;
  217. GC gc;
  218. int op;
  219. short fg_mode;
  220. int fg_bg;
  221. {
  222. unsigned long value_mask;
  223. XGCValues val;
  224. Cms_info *cms = CMS_PRIVATE(xv_cms(info));
  225. val.function = XV_TO_XOP(op);
  226. value_mask = GCForeground | GCBackground | GCFunction | GCPlaneMask;
  227. val.plane_mask = xv_plane_mask(info);
  228. if (info->is_bitmap) { /* restrict bitmap colors to 1 and 0 */
  229. val.foreground = (fg_bg == XV_DEFAULT_FG_BG) ? 1 : 0;
  230. val.background = (fg_bg == XV_DEFAULT_FG_BG) ? 0 : 1;
  231. } else if (fg_mode == XV_USE_OP_FG) {
  232. if (fg_bg == XV_DEFAULT_FG_BG) {
  233. val.foreground = XV_TO_X_PIXEL(PIX_OPCOLOR(op), cms);
  234. val.background = xv_bg(info);
  235. } else {
  236. val.background = XV_TO_X_PIXEL(PIX_OPCOLOR(op), cms);
  237. val.foreground = xv_bg(info);
  238. }
  239. } else {
  240. if (fg_bg == XV_DEFAULT_FG_BG) {
  241. val.foreground = xv_fg(info);
  242. val.background = xv_bg(info);
  243. } else {
  244. val.background = xv_fg(info);
  245. val.foreground = xv_bg(info);
  246. }
  247. }
  248. switch (val.function) {
  249. case GXclear:
  250. val.foreground = val.background;
  251. val.function = GXcopy;
  252. break;
  253. case GXset:
  254. val.foreground = xv_fg(info);
  255. val.function = GXcopy;
  256. break;
  257. case GXxor:
  258. val.foreground = val.foreground ^ val.background;
  259. val.background = 0;
  260. break;
  261. case GXinvert:
  262. if (val.foreground == val.background) {
  263. val.foreground = xv_fg(info);
  264. val.background = xv_bg(info);
  265. }
  266. val.plane_mask = val.foreground ^ val.background;
  267. break;
  268. }
  269. XChangeGC(display, gc, value_mask, &val);
  270. }
  271. Xv_private int
  272. Xp_xv_rop_internal(display, d, gc, x, y, width, height, src, xr, yr, dest_info)
  273. Display *display;
  274. Drawable d;
  275. GC gc;
  276. int x, y, width, height;
  277. Xv_opaque src;
  278. int xr, yr;
  279. Xv_Drawable_info *dest_info;
  280. {
  281. Xv_Drawable_info *src_info;
  282. Drawable src_d;
  283. XGCValues changes;
  284. unsigned long changes_mask = 0;
  285. if (width == 0 || height == 0 || !src) {
  286. return (XV_ERROR);
  287. }
  288. /*
  289. * If src is not a client pixrect, it can either be a window or a
  290. * server_image.
  291. */
  292. if (PR_NOT_MPR(((Pixrect *) src))) {
  293. DRAWABLE_INFO_MACRO(src, src_info);
  294. src_d = (Drawable) xv_xid(src_info);
  295. if (PR_IS_SERVER_IMAGE((Pixrect *) src)) {
  296. /*
  297. * Since src is a server image, avoid the overhead of NoExpose
  298. * events by doing stippling/tiling.
  299. */
  300. changes.ts_x_origin = x;
  301. changes.ts_y_origin = y;
  302. changes_mask = GCTileStipXOrigin | GCTileStipYOrigin;
  303. /* clip to source dimensions */
  304. width = (width > ((Pixrect *) src)->pr_size.x) ?
  305. ((Pixrect *) src)->pr_size.x : width;
  306. height = (height > ((Pixrect *) src)->pr_size.y) ?
  307. ((Pixrect *) src)->pr_size.y : height;
  308. if (xv_depth(dest_info) == xv_depth(src_info)) {
  309. if (xv_depth(dest_info) == 1) {
  310. changes.stipple = xv_xid(src_info);
  311. changes.fill_style = FillOpaqueStippled;
  312. changes_mask |= GCFillStyle | GCStipple;
  313. } else {
  314. changes.tile = xv_xid(src_info);
  315. changes.fill_style = FillTiled;
  316. changes_mask |= GCTile | GCFillStyle;
  317. }
  318. } else if (xv_depth(dest_info) > xv_depth(src_info)) {
  319. changes.stipple = xv_xid(src_info);
  320. changes.fill_style = FillOpaqueStippled;
  321. changes_mask |= GCStipple | GCFillStyle;
  322. } else {
  323. xv_error(NULL,
  324. ERROR_STRING,
  325. XV_MSG("xv_rop: can't handle drawables of different depth"),
  326. 0);
  327. return (XV_ERROR);
  328. }
  329. if (changes_mask)
  330. XChangeGC(display, gc, changes_mask, &changes);
  331. XFillRectangle(display, d, gc, x, y, width, height);
  332. } else {
  333. /* src is a window */
  334. if (xv_depth(dest_info) == xv_depth(src_info)) {
  335. XCopyArea(display, src_d, d, gc, xr, yr, width, height, x, y);
  336. } else {
  337. xv_error(NULL,
  338. ERROR_STRING,
  339. XV_MSG("xv_rop: Windows of different depth, can't rop"),
  340. 0);
  341. return (XV_ERROR);
  342. }
  343. }
  344. } else {
  345. if (Xp_xv_rop_mpr_internal(display, d, gc, x, y, width, height, src,
  346. xr, yr, dest_info, TRUE) == XV_ERROR)
  347. return(XV_ERROR);
  348. }
  349. return(XV_OK);
  350. }
  351. Xv_private int
  352. Xp_xv_rop_mpr_internal(display, d, gc, x, y, width, height, src, xr, yr,
  353. dest_info, mpr_bits)
  354. Display *display;
  355. Drawable d;
  356. GC gc;
  357. int x, y, width, height;
  358. Xv_opaque src;
  359. int xr, yr;
  360. Xv_Drawable_info *dest_info;
  361. short mpr_bits;
  362. {
  363. int src_depth;
  364. XImage *ximage;
  365. Cms_info *cms = CMS_PRIVATE(xv_cms(dest_info));
  366. static unsigned char *data = (unsigned char *)NULL;
  367. static unsigned int last_size = 0;
  368. src_depth = ((Pixrect *) src)->pr_depth;
  369. /*
  370. * In Sunview, this case is handled by setting all non-zero color values
  371. * to 1's. This is currently a NO-OP in XView. This case must be
  372. * handled by creating a separate array of data bits of setting non-zero
  373. * pixel values to 1's.
  374. */
  375. if ((xv_depth(dest_info) == 1) && (src_depth > 1)) {
  376. return(XV_ERROR);
  377. }
  378. if (src_depth == 1) {
  379. if (!(ximage = xv_image_bitmap(dest_info))) {
  380. Screen_visual *visual;
  381. visual = (Screen_visual *)xv_get(xv_screen(dest_info), SCREEN_DEFAULT_VISUAL);
  382. xv_image_bitmap(dest_info) = ximage =
  383. (XImage *) XCreateImage(display, visual->vinfo->visual,
  384. 1, XYBitmap, 0,
  385. (char *) mpr_d(((Pixrect *) src))->md_image,
  386. 0, 0, MPR_LINEBITPAD,
  387. mpr_d(((Pixrect *) src))->md_linebytes);
  388. if (!ximage) {
  389. return (XV_ERROR);
  390. }
  391. }
  392. } else if ((src_depth == 8) && (xv_depth(dest_info) == 8)) {
  393. if (!(ximage = xv_image_pixmap(dest_info))) {
  394. Screen_visual *visual;
  395. visual = (Screen_visual *)xv_get(xv_screen(dest_info), SCREEN_DEFAULT_VISUAL);
  396. xv_image_pixmap(dest_info) = ximage =
  397. (XImage *) XCreateImage(display, visual->vinfo->visual,
  398. 8, ZPixmap, 0,
  399. (char *) mpr_d(((Pixrect *) src))->md_image,
  400. 0, 0, MPR_LINEBITPAD,
  401. mpr_d(((Pixrect *) src))->md_linebytes);
  402. if (!ximage) {
  403. return (XV_ERROR);
  404. }
  405. }
  406. } else {
  407. return (XV_ERROR);
  408. }
  409. ximage->bitmap_unit = MPR_LINEBITPAD;
  410. ximage->bitmap_pad = MPR_LINEBITPAD;
  411. ximage->height = ((Pixrect *) src)->pr_height;
  412. ximage->width = ((Pixrect *) src)->pr_width;
  413. ximage->bytes_per_line = mpr_d(((Pixrect *) src))->md_linebytes;
  414. ximage->data = (char *) mpr_d(((Pixrect *) src))->md_image;
  415. /*
  416. * The bitmap data being passed in might be in either of 2 formats:
  417. * 1. memory pixrect format.
  418. * 2. Xlib bitmap format.
  419. */
  420. if (mpr_bits == TRUE) {
  421. /* bitmap data is in memory pixrect format */
  422. #ifdef i386
  423. ximage->byte_order = LSBFirst;
  424. /*
  425. * Check to see if the pixrect data was set by mpr_static(), or by
  426. * actually creating the pixrect with mem_create() and drawing into
  427. * it.
  428. */
  429. if (mpr_d((Pixrect *) src)->md_flags & MP_I386)
  430. ximage->bitmap_bit_order = LSBFirst;
  431. else
  432. ximage->bitmap_bit_order = MSBFirst;
  433. #else
  434. #ifdef ultrix
  435. ximage->byte_order = LSBFirst;
  436. ximage->bitmap_bit_order = MSBFirst;
  437. #else
  438. ximage->byte_order = MSBFirst;
  439. ximage->bitmap_bit_order = MSBFirst;
  440. #endif /* ~VAX */
  441. #endif /* ~i386 */
  442. } else {
  443. /* bitmap data is in Xlib bitmap format */
  444. ximage->byte_order = LSBFirst;
  445. ximage->bitmap_bit_order = LSBFirst;
  446. if (src_depth == 1)
  447. ximage->bytes_per_line = (width + 7) >> 3;
  448. }
  449. if (src_depth == 1) {
  450. XPutImage(display, d, gc, ximage, xr, yr, x, y,
  451. MIN(width, ximage->width), MIN(height, ximage->height));
  452. } else {
  453. register int i, j;
  454. unsigned long index;
  455. unsigned int size;
  456. char *image_data;
  457. /*
  458. * Create any space needed to convert the image data to pixel values
  459. */
  460. size = ximage->height * ximage->bytes_per_line;
  461. if (size > last_size) {
  462. if (data)
  463. xv_free(data);
  464. data = (unsigned char *)xv_malloc(size);
  465. last_size = size;
  466. }
  467. /*
  468. * convert image from cms indices to X pixel values.
  469. */
  470. image_data = ximage->data;
  471. for (i = 0; i < ximage->height; i++) {
  472. for (j = 0; j < ximage->bytes_per_line; j++) {
  473. index = j + i * ximage->bytes_per_line;
  474. data[index] = cms->index_table[(unsigned char)image_data[index]];
  475. }
  476. }
  477. ximage->data = (char *)data;
  478. XPutImage(display, d, gc, ximage, xr, yr, x, y,
  479. MIN(width, ximage->width), MIN(height, ximage->height));
  480. ximage->data = image_data;
  481. }
  482. return (XV_OK);
  483. }
  484. Pkg_private GC
  485. Xp_xv_find_proper_gc(display, info, op)
  486. Display *display;
  487. Xv_Drawable_info *info;
  488. int op;
  489. {
  490. int depth = xv_depth(info), i;
  491. Drawable xid = xv_xid(info);
  492. XGCValues gv;
  493. Xv_Screen screen = xv_screen(info);
  494. Xv_xrectlist *clip_xrects = screen_get_clip_rects(screen);
  495. short xv_in_fullscreen = server_get_fullscreen(xv_server(info));
  496. struct gc_chain *gcs, *gc_list, **ops_private_gcs;
  497. if (!GC_CHAIN_KEY)
  498. GC_CHAIN_KEY = xv_unique_key();
  499. ops_private_gcs = (struct gc_chain **) xv_get( screen, XV_KEY_DATA, GC_CHAIN_KEY );
  500. if (!ops_private_gcs) {
  501. ops_private_gcs = (struct gc_chain **) xv_calloc((PW_NUM_OPS+1),sizeof(struct gc_chain));
  502. xv_set( screen, XV_KEY_DATA, GC_CHAIN_KEY, ops_private_gcs, 0 );
  503. }
  504. gc_list = ops_private_gcs[op];
  505. /*
  506. * If a new clipping rectangle has been set for this drawable since the
  507. * last invocation of this function, set all xid's in the gc list to an
  508. * invalid xid.
  509. */
  510. if (info->new_clipping) {
  511. #ifndef SVR4
  512. for (i = 0; i < PW_NUM_OPS; i++)
  513. #else SVR4
  514. for (i = 0; i <= PW_NUM_OPS; i++)
  515. #endif SVR4
  516. for (gcs = ops_private_gcs[i]; gcs != NULL; gcs = gcs->next)
  517. gcs->xid = INVALID_XID;
  518. info->new_clipping = FALSE;
  519. }
  520. if (!gc_list) {
  521. gc_list = ops_private_gcs[op] =
  522. (struct gc_chain *) xv_calloc(1, sizeof(struct gc_chain));
  523. if (xv_in_fullscreen) {
  524. gv.subwindow_mode = IncludeInferiors;
  525. gc_list->gc = XCreateGC(display, xid, GCSubwindowMode, &gv);
  526. } else {
  527. gc_list->gc = XCreateGC(display, xid, 0, 0);
  528. }
  529. gc_list->clipping_set = FALSE;
  530. gc_list->depth = depth;
  531. gc_list->next = NULL;
  532. /*
  533. * Newly created GC. If clipping is enabled on the drawable, set the
  534. * GCClipMask for the GC.
  535. */
  536. if (clip_xrects->count) {
  537. XSetClipRectangles(display, gc_list->gc, 0, 0,
  538. clip_xrects->rect_array, clip_xrects->count, Unsorted);
  539. gc_list->clipping_set = TRUE;
  540. }
  541. gc_list->xid = xid;
  542. return (gc_list->gc);
  543. } else {
  544. gcs = gc_list;
  545. while (gcs) {
  546. if (gcs->depth == depth) {
  547. if (xv_in_fullscreen) {
  548. gv.subwindow_mode = IncludeInferiors;
  549. } else {
  550. gv.subwindow_mode = ClipByChildren;
  551. }
  552. /*
  553. * The clipping_set field is redundant. A bug in XChangeGC
  554. * (in Xlib) needs to fixed. If the current clip_mask and the
  555. * cached clip_mask are both None, the cache need not be
  556. * flushed. Remove clipping_set field when this gets fixed.
  557. */
  558. if (gcs->clipping_set && !clip_xrects->count) {
  559. gcs->clipping_set = FALSE;
  560. gv.clip_mask = None;
  561. XChangeGC(display, gcs->gc, GCSubwindowMode | GCClipMask, &gv);
  562. } else {
  563. XChangeGC(display, gcs->gc, GCSubwindowMode, &gv);
  564. }
  565. /*
  566. * If this is a different drawable since the last invocation
  567. * and it has a clipping rectangle enabled, or, the clipping
  568. * for the same drawable has changed since the last
  569. * invocation, reset the clipping.
  570. */
  571. if (clip_xrects->count && (gcs->xid != xid)) {
  572. XSetClipRectangles(display, gcs->gc, 0, 0,
  573. clip_xrects->rect_array, clip_xrects->count, Unsorted);
  574. gcs->clipping_set = TRUE;
  575. }
  576. gcs->xid = xid;
  577. return (gcs->gc);
  578. } else {
  579. if (gcs->next) {
  580. gcs = gcs->next;
  581. } else {
  582. struct gc_chain *new;
  583. /*
  584. * no gc of the same depth, need to create a new gc
  585. */
  586. gcs->next = new = (struct gc_chain *) xv_malloc(sizeof(struct gc_chain));
  587. if (xv_in_fullscreen) {
  588. gv.subwindow_mode = IncludeInferiors;
  589. new->gc = XCreateGC(display, xid, GCSubwindowMode, &gv);
  590. } else {
  591. new->gc = XCreateGC(display, xid, 0, 0);
  592. }
  593. new->depth = depth;
  594. new->next = NULL;
  595. /*
  596. * Newly created GC. If clipping is enabled on the
  597. * window, set the GC.
  598. */
  599. if (clip_xrects->count) {
  600. XSetClipRectangles(display, new->gc, 0, 0,
  601. clip_xrects->rect_array, clip_xrects->count, Unsorted);
  602. new->clipping_set = TRUE;
  603. }
  604. new->xid = xid;
  605. return (new->gc);
  606. }
  607. }
  608. }
  609. }
  610. }