2 * Command line: opannotate --source
4 * Interpretation of command line:
5 * Output annotated source file with samples
8 * CPU: Core 2, speed 2133.49 MHz (estimated)
9 * Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000
12 * Total samples for file : "/home/cworth/src/xorg/driver/xf86-video-intel/src/i830_accel.c"
19 : * XXX So far, for GXxor this is about 40% of the speed of SW, but CPU
20 : * utilisation falls from 95% to < 5%.
27 :/**************************************************************************
29 :Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
32 :Permission is hereby granted, free of charge, to any person obtaining a
33 :copy of this software and associated documentation files (the
34 :"Software"), to deal in the Software without restriction, including
35 :without limitation the rights to use, copy, modify, merge, publish,
36 :distribute, sub license, and/or sell copies of the Software, and to
37 :permit persons to whom the Software is furnished to do so, subject to
38 :the following conditions:
40 :The above copyright notice and this permission notice (including the
41 :next paragraph) shall be included in all copies or substantial portions
44 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
45 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
47 :IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
48 :ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
49 :TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
50 :SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 :**************************************************************************/
53 :/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_accel.c,v 1.8 2003/04/24 18:00:24 eich Exp $ */
56 : * Reformatted with GNU indent (2.2.8), using the following options:
58 : * -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
59 : * -lp -npcs -psl -sob -ss -br -ce -sc -hnl
61 : * This provides a good match with the original i810 code and preferred
62 : * XFree86 formatting conventions.
64 : * When editing this driver, please follow the existing formatting, and edit
65 : * with <TAB> characters expanded at 8-column intervals.
70 : * Keith Whitwell <keith@tungstengraphics.com>
77 :#include "i810_reg.h"
78 :#include "i830_debug.h"
81 :intel_get_pixmap_offset(PixmapPtr pPix)
82 15 0.0163 :{ /* intel_get_pixmap_offset total: 77 0.0839 */
83 : ScreenPtr pScreen = pPix->drawable.pScreen;
84 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
85 27 0.0294 : I830Ptr pI830 = I830PTR(pScrn);
88 24 0.0261 : if (pI830->useEXA)
89 4 0.0044 : return exaGetPixmapOffset(pPix);
91 : return (unsigned long)pPix->devPrivate.ptr - (unsigned long)pI830->FbBase;
95 :intel_get_pixmap_pitch(PixmapPtr pPix)
96 12 0.0131 :{ /* intel_get_pixmap_pitch total: 83 0.0904 */
97 : ScreenPtr pScreen = pPix->drawable.pScreen;
98 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
99 : I830Ptr pI830 = I830PTR(pScrn);
102 57 0.0621 : if (pI830->useEXA)
103 4 0.0044 : return exaGetPixmapPitch(pPix);
106 : return (unsigned long)pPix->devKind;
111 :I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
112 10 0.0109 :{ /* I830WaitLpRing total: 31130 33.9125 */
113 2 0.0022 : I830Ptr pI830 = I830PTR(pScrn);
114 1 0.0011 : I830RingBuffer *ring = pI830->LpRing;
116 : unsigned int start = 0;
117 : unsigned int now = 0;
119 : unsigned int first = 0;
121 : /* If your system hasn't moved the head pointer in 2 seconds, I'm going to
124 : if (timeout_millis == 0)
125 : timeout_millis = 2000;
127 : if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) {
128 : ErrorF("I830WaitLpRing %d\n", n);
129 : first = GetTimeInMillis();
132 383 0.4172 : while (ring->space < n) {
133 217 0.2364 : ring->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
134 30204 32.9038 : ring->space = ring->head - (ring->tail + 8);
136 : if (ring->space < 0)
137 145 0.1580 : ring->space += ring->mem->size;
140 : if ((iters & 0xfff) == 0) {
141 : now = GetTimeInMillis();
142 : if (start == 0 || now < start || ring->head != last_head) {
143 : if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
145 : ErrorF("space: %d wanted %d\n", ring->space, n);
147 : last_head = ring->head;
148 : } else if (now - start > timeout_millis) {
149 : ErrorF("Error in I830WaitLpRing(), timeout for %d seconds\n",
150 : timeout_millis/1000);
151 : if (IS_I965G(pI830))
152 : i965_dump_error_state(pScrn);
154 : i830_dump_error_state(pScrn);
155 : ErrorF("space: %d wanted %d\n", ring->space, n);
157 : if (pI830->directRenderingEnabled) {
158 : DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
159 : DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]);
163 : pI830->AccelInfoRec = NULL; /* Stops recursive behavior */
166 : pI830->EXADriverPtr = NULL;
168 1 0.0011 : FatalError("lockup\n");
174 : if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) {
175 : now = GetTimeInMillis();
177 : ErrorF("Elapsed %u ms\n", now - first);
178 : ErrorF("space: %d wanted %d\n", ring->space, n);
186 :I830Sync(ScrnInfoPtr pScrn)
187 6 0.0065 :{ /* I830Sync total: 272 0.2963 */
188 2 0.0022 : I830Ptr pI830 = I830PTR(pScrn);
189 : int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
191 : if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC))
192 : ErrorF("I830Sync\n");
195 : /* VT switching tries to do this.
197 : if (!pI830->LockHeld && pI830->directRenderingEnabled) {
202 1 0.0011 : if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning) return;
204 6 0.0065 : if (IS_I965G(pI830))
207 : /* Send a flush instruction and then wait till the ring is empty.
208 : * This is stronger than waiting for the blitter to finish as it also
209 : * flushes the internal graphics caches.
213 3 0.0033 : BEGIN_LP_RING(2);
214 11 0.0120 : OUT_RING(MI_FLUSH | flags);
215 11 0.0120 : OUT_RING(MI_NOOP); /* pad to quadword */
216 17 0.0185 : ADVANCE_LP_RING();
219 168 0.1830 : I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0);
221 37 0.0403 : pI830->LpRing->space = pI830->LpRing->mem->size - 8;
222 1 0.0011 : pI830->nextColorExpandBuf = 0;
226 :I830EmitFlush(ScrnInfoPtr pScrn)
228 : I830Ptr pI830 = I830PTR(pScrn);
229 : int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
231 : if (IS_I965G(pI830))
236 : OUT_RING(MI_FLUSH | flags);
237 : OUT_RING(MI_NOOP); /* pad to quadword */
243 :I830SelectBuffer(ScrnInfoPtr pScrn, int buffer)
245 : I830Ptr pI830 = I830PTR(pScrn);
249 : case I830_SELECT_BACK:
250 : pI830->bufferOffset = pI830->back_buffer->offset;
252 : case I830_SELECT_THIRD:
253 : pI830->bufferOffset = pI830->third_buffer->offset;
255 : case I830_SELECT_DEPTH:
256 : pI830->bufferOffset = pI830->depth_buffer->offset;
260 : case I830_SELECT_FRONT:
261 : pI830->bufferOffset = pScrn->fbOffset;
265 : if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
266 : ErrorF("I830SelectBuffer %d --> offset %x\n",
267 : buffer, pI830->bufferOffset);
271 :I830RefreshRing(ScrnInfoPtr pScrn)
273 : I830Ptr pI830 = I830PTR(pScrn);
275 : pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
276 : pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
277 : pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
278 : if (pI830->LpRing->space < 0)
279 : pI830->LpRing->space += pI830->LpRing->mem->size;
280 : i830MarkSync(pScrn);
283 :/* The following function sets up the supported acceleration. Call it
284 : * from the FbInit() function in the SVGA driver, or before ScreenInit
285 : * in a monolithic server.
288 :I830AccelInit(ScreenPtr pScreen)
291 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
292 : I830Ptr pI830 = I830PTR(pScrn);
295 : return I830EXAInit(pScreen);
298 : return I830XAAInit(pScreen);
303 * Total samples for file : "/home/cworth/src/xorg/driver/xf86-video-intel/src/i965_render.c"
310 : * Copyright © 2006 Intel Corporation
312 : * Permission is hereby granted, free of charge, to any person obtaining a
313 : * copy of this software and associated documentation files (the "Software"),
314 : * to deal in the Software without restriction, including without limitation
315 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
316 : * and/or sell copies of the Software, and to permit persons to whom the
317 : * Software is furnished to do so, subject to the following conditions:
319 : * The above copyright notice and this permission notice (including the next
320 : * paragraph) shall be included in all copies or substantial portions of the
323 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
324 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
325 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
326 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
327 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
328 : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
332 : * Wang Zhenyu <zhenyu.z.wang@intel.com>
333 : * Eric Anholt <eric@anholt.net>
337 :#ifdef HAVE_CONFIG_H
344 :#include "i915_reg.h"
346 :/* bring in brw structs */
347 :#include "brw_defines.h"
348 :#include "brw_structs.h"
351 :#define DEBUG_I830FALLBACK 1
354 :#ifdef DEBUG_I830FALLBACK
355 :#define I830FALLBACK(s, arg...) \
357 : DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
361 :#define I830FALLBACK(s, arg...) \
379 :// refer vol2, 3d rasterization 3.8.1
381 :/* defined in brw_defines.h */
382 :static struct blendinfo i965_blend_op[] = {
384 : {0, 0, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_ZERO},
386 : {0, 0, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_ZERO},
388 : {0, 0, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_ONE},
390 : {0, 1, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_INV_SRC_ALPHA},
392 : {1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ONE},
394 : {1, 0, BRW_BLENDFACTOR_DST_ALPHA, BRW_BLENDFACTOR_ZERO},
396 : {0, 1, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_SRC_ALPHA},
398 : {1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ZERO},
400 : {0, 1, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_INV_SRC_ALPHA},
402 : {1, 1, BRW_BLENDFACTOR_DST_ALPHA, BRW_BLENDFACTOR_INV_SRC_ALPHA},
404 : {1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_SRC_ALPHA},
406 : {1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_INV_SRC_ALPHA},
408 : {0, 0, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_ONE},
411 :/* FIXME: surface format defined in brw_defines.h, shared Sampling engine
414 :static struct formatinfo i965_tex_formats[] = {
415 : {PICT_a8r8g8b8, BRW_SURFACEFORMAT_B8G8R8A8_UNORM },
416 : {PICT_x8r8g8b8, BRW_SURFACEFORMAT_B8G8R8X8_UNORM },
417 : {PICT_a8b8g8r8, BRW_SURFACEFORMAT_R8G8B8A8_UNORM },
418 : {PICT_x8b8g8r8, BRW_SURFACEFORMAT_R8G8B8X8_UNORM },
419 : {PICT_r5g6b5, BRW_SURFACEFORMAT_B5G6R5_UNORM },
420 : {PICT_a1r5g5b5, BRW_SURFACEFORMAT_B5G5R5A1_UNORM },
421 : {PICT_a8, BRW_SURFACEFORMAT_A8_UNORM },
424 :static void i965_get_blend_cntl(int op, PicturePtr pMask, CARD32 dst_format,
425 : CARD32 *sblend, CARD32 *dblend)
428 : *sblend = i965_blend_op[op].src_blend;
429 : *dblend = i965_blend_op[op].dst_blend;
431 : /* If there's no dst alpha channel, adjust the blend op so that we'll treat
434 : if (PICT_FORMAT_A(dst_format) == 0 && i965_blend_op[op].dst_alpha) {
435 : if (*sblend == BRW_BLENDFACTOR_DST_ALPHA)
436 : *sblend = BRW_BLENDFACTOR_ONE;
437 : else if (*sblend == BRW_BLENDFACTOR_INV_DST_ALPHA)
438 : *sblend = BRW_BLENDFACTOR_ZERO;
441 : /* If the source alpha is being used, then we should only be in a case where
442 : * the source blend factor is 0, and the source blend value is the mask
443 : * channels multiplied by the source picture's alpha.
445 : if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format)
446 : && i965_blend_op[op].src_alpha) {
447 : if (*dblend == BRW_BLENDFACTOR_SRC_ALPHA) {
448 : *dblend = BRW_BLENDFACTOR_SRC_COLOR;
449 : } else if (*dblend == BRW_BLENDFACTOR_INV_SRC_ALPHA) {
450 : *dblend = BRW_BLENDFACTOR_INV_SRC_COLOR;
456 :static Bool i965_get_dest_format(PicturePtr pDstPicture, CARD32 *dst_format)
457 8 0.0087 :{ /* i965_get_dest_format total: 28 0.0305 */
458 10 0.0109 : switch (pDstPicture->format) {
459 : case PICT_a8r8g8b8:
460 : case PICT_x8r8g8b8:
461 1 0.0011 : *dst_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
464 : *dst_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
466 : case PICT_a1r5g5b5:
467 : *dst_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
469 : case PICT_x1r5g5b5:
470 : *dst_format = BRW_SURFACEFORMAT_B5G5R5X1_UNORM;
472 : /* COLR_BUF_8BIT is special for YUV surfaces. While we may end up being
473 : * able to use it depending on how the hardware implements it, disable it
474 : * for now while we don't know what exactly it does (what channel does it
479 : *dst_format = COLR_BUF_8BIT;
482 : case PICT_a4r4g4b4:
483 : case PICT_x4r4g4b4:
484 : *dst_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
487 : I830FALLBACK("Unsupported dest format 0x%x\n",
488 : (int)pDstPicture->format);
494 :static Bool i965_check_composite_texture(PicturePtr pPict, int unit)
495 28 0.0305 :{ /* i965_check_composite_texture total: 73 0.0795 */
496 3 0.0033 : int w = pPict->pDrawable->width;
497 : int h = pPict->pDrawable->height;
500 15 0.0163 : if ((w > 0x7ff) || (h > 0x7ff))
501 : I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
503 : for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
506 9 0.0098 : if (i965_tex_formats[i].fmt == pPict->format)
509 7 0.0076 : if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
510 : I830FALLBACK("Unsupported picture format 0x%x\n",
511 : (int)pPict->format);
513 4 0.0044 : if (pPict->repeat && pPict->repeatType != RepeatNormal)
514 : I830FALLBACK("extended repeat (%d) not supported\n",
515 : pPict->repeatType);
517 : if (pPict->filter != PictFilterNearest &&
518 : pPict->filter != PictFilterBilinear)
520 : I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
527 :i965_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
528 : PicturePtr pDstPicture)
529 9 0.0098 :{ /* i965_check_composite total: 54 0.0588 */
532 : /* Check for unsupported compositing operations. */
533 : if (op >= sizeof(i965_blend_op) / sizeof(i965_blend_op[0]))
534 : I830FALLBACK("Unsupported Composite op 0x%x\n", op);
536 4 0.0044 : if (pMaskPicture && pMaskPicture->componentAlpha &&
537 : PICT_FORMAT_RGB(pMaskPicture->format)) {
538 : /* Check if it's component alpha that relies on a source alpha and on
539 : * the source value. We can only get one of those into the single
540 : * source value that we get to blend with.
542 11 0.0120 : if (i965_blend_op[op].src_alpha &&
543 : (i965_blend_op[op].src_blend != BRW_BLENDFACTOR_ZERO))
545 : I830FALLBACK("Component alpha not supported with source "
546 : "alpha and source value blending.\n");
550 9 0.0098 : if (!i965_check_composite_texture(pSrcPicture, 0))
551 : I830FALLBACK("Check Src picture texture\n");
552 2 0.0022 : if (pMaskPicture != NULL && !i965_check_composite_texture(pMaskPicture, 1))
553 : I830FALLBACK("Check Mask picture texture\n");
555 9 0.0098 : if (!i965_get_dest_format(pDstPicture, &tmp1))
556 : I830FALLBACK("Get Color buffer format\n");
562 :#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
563 :#define MIN(a,b) ((a) < (b) ? (a) : (b))
564 :#define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1)
566 :static int urb_vs_start, urb_vs_size;
567 :static int urb_gs_start, urb_gs_size;
568 :static int urb_clip_start, urb_clip_size;
569 :static int urb_sf_start, urb_sf_size;
570 :static int urb_cs_start, urb_cs_size;
572 :static struct brw_surface_state *dest_surf_state, dest_surf_state_local;
573 :static struct brw_surface_state *src_surf_state, src_surf_state_local;
574 :static struct brw_surface_state *mask_surf_state, mask_surf_state_local;
575 :static struct brw_sampler_state *src_sampler_state, src_sampler_state_local;
576 :static struct brw_sampler_state *mask_sampler_state, mask_sampler_state_local;
577 :static struct brw_sampler_default_color *default_color_state;
579 :static struct brw_vs_unit_state *vs_state, vs_state_local;
580 :static struct brw_sf_unit_state *sf_state, sf_state_local;
581 :static struct brw_wm_unit_state *wm_state, wm_state_local;
582 :static struct brw_cc_unit_state *cc_state, cc_state_local;
583 :static struct brw_cc_viewport *cc_viewport;
585 :static struct brw_instruction *sf_kernel;
586 :static struct brw_instruction *ps_kernel;
587 :static struct brw_instruction *sip_kernel;
589 :static CARD32 *binding_table;
590 :static int binding_table_entries;
592 :static int dest_surf_offset, src_surf_offset, mask_surf_offset;
593 :static int src_sampler_offset, mask_sampler_offset,vs_offset;
594 :static int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
595 :static int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
596 :static int wm_scratch_offset;
597 :static int binding_table_offset;
598 :static int default_color_offset;
599 :static int next_offset, total_state_size;
600 :static char *state_base;
601 :static int state_base_offset;
603 :static int vb_size = (4 * 4) * 4 ; /* 4 DWORDS per vertex*/
605 :static CARD32 src_blend, dst_blend;
607 :static const CARD32 sip_kernel_static[][4] = {
608 :/* wait (1) a0<1>UW a145<0,1,0>UW { align1 + } */
609 : { 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
610 :/* nop (4) g0<1>UD { align1 + } */
611 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
612 :/* nop (4) g0<1>UD { align1 + } */
613 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
614 :/* nop (4) g0<1>UD { align1 + } */
615 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
616 :/* nop (4) g0<1>UD { align1 + } */
617 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
618 :/* nop (4) g0<1>UD { align1 + } */
619 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
620 :/* nop (4) g0<1>UD { align1 + } */
621 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
622 :/* nop (4) g0<1>UD { align1 + } */
623 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
624 :/* nop (4) g0<1>UD { align1 + } */
625 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
626 :/* nop (4) g0<1>UD { align1 + } */
627 : { 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
631 : * this program computes dA/dx and dA/dy for the texture coordinates along
632 : * with the base texture coordinate. It was extracted from the Mesa driver
635 :#define SF_KERNEL_NUM_GRF 16
636 :#define SF_MAX_THREADS 1
638 :static const CARD32 sf_kernel_static[][4] = {
639 :#include "exa_sf_prog.h"
642 :static const CARD32 sf_kernel_static_mask[][4] = {
643 :#include "exa_sf_mask_prog.h"
646 :static const CARD32 sf_kernel_static_rotation[][4] = {
647 :#include "exa_sf_rotation_prog.h"
651 :#define PS_KERNEL_NUM_GRF 32
652 :#define PS_MAX_THREADS 32
654 :static const CARD32 ps_kernel_static_nomask [][4] = {
655 :#include "exa_wm_nomask_prog.h"
658 :static const CARD32 ps_kernel_static_maskca [][4] = {
659 :#include "exa_wm_maskca_prog.h"
662 :static const CARD32 ps_kernel_static_maskca_srcalpha [][4] = {
663 :#include "exa_wm_maskca_srcalpha_prog.h"
666 :static const CARD32 ps_kernel_static_masknoca [][4] = {
667 :#include "exa_wm_masknoca_prog.h"
670 :static const CARD32 ps_kernel_static_rotation [][4] = {
671 :#include "exa_wm_rotation_prog.h"
675 :i965_get_card_format(PicturePtr pPict)
676 27 0.0294 :{ /* i965_get_card_format total: 32 0.0349 */
679 4 0.0044 : for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
682 1 0.0011 : if (i965_tex_formats[i].fmt == pPict->format)
685 : return i965_tex_formats[i].card_fmt;
689 :i965_check_rotation_transform(PictTransformPtr t)
691 : /* XXX this is arbitrary */
693 : a = xFixedToInt(t->matrix[0][1]);
694 : b = xFixedToInt(t->matrix[1][0]);
695 : if (a == -1 && b == 1)
697 : else if (a == 1 && b == -1)
704 :i965_prepare_composite(int op, PicturePtr pSrcPicture,
705 : PicturePtr pMaskPicture, PicturePtr pDstPicture,
706 : PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
707 3 0.0033 :{ /* i965_prepare_composite total: 9782 10.6564 */
708 29 0.0316 : ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
709 7 0.0076 : I830Ptr pI830 = I830PTR(pScrn);
710 : CARD32 src_offset, src_pitch;
711 : CARD32 mask_offset = 0, mask_pitch = 0;
712 : CARD32 dst_format, dst_offset, dst_pitch;
713 : Bool rotation_program = FALSE;
715 : IntelEmitInvarientState(pScrn);
716 6 0.0065 : *pI830->last_3d = LAST_3D_RENDER;
718 6 0.0065 : src_offset = intel_get_pixmap_offset(pSrc);
719 : src_pitch = intel_get_pixmap_pitch(pSrc);
720 2 0.0022 : dst_offset = intel_get_pixmap_offset(pDst);
721 3 0.0033 : dst_pitch = intel_get_pixmap_pitch(pDst);
723 2 0.0022 : mask_offset = intel_get_pixmap_offset(pMask);
724 6 0.0065 : mask_pitch = intel_get_pixmap_pitch(pMask);
726 8 0.0087 : pI830->scale_units[0][0] = pSrc->drawable.width;
727 24 0.0261 : pI830->scale_units[0][1] = pSrc->drawable.height;
729 1 0.0011 : pI830->transform[0] = pSrcPicture->transform;
732 : pI830->transform[1] = NULL;
733 : pI830->scale_units[1][0] = -1;
734 : pI830->scale_units[1][1] = -1;
735 : if (pI830->transform[0] &&
736 : i965_check_rotation_transform(pI830->transform[0]))
737 : rotation_program = TRUE;
739 : pI830->transform[1] = pMaskPicture->transform;
740 : if (pI830->transform[1])
741 : I830FALLBACK("i965 mask transform not implemented!\n");
742 3 0.0033 : pI830->scale_units[1][0] = pMask->drawable.width;
743 3 0.0033 : pI830->scale_units[1][1] = pMask->drawable.height;
746 : /* setup 3d pipeline state */
748 1 0.0011 : binding_table_entries = 2; /* default no mask */
750 : /* Set up our layout of state in framebuffer. First the general state: */
752 1 0.0011 : vs_offset = ALIGN(next_offset, 64);
753 : next_offset = vs_offset + sizeof(*vs_state);
755 : sf_offset = ALIGN(next_offset, 32);
756 : next_offset = sf_offset + sizeof(*sf_state);
758 : wm_offset = ALIGN(next_offset, 32);
759 : next_offset = wm_offset + sizeof(*wm_state);
761 : wm_scratch_offset = ALIGN(next_offset, 1024);
762 : next_offset = wm_scratch_offset + 1024 * PS_MAX_THREADS;
764 : cc_offset = ALIGN(next_offset, 32);
765 : next_offset = cc_offset + sizeof(*cc_state);
767 : /* keep current sf_kernel, which will send one setup urb entry to
770 1 0.0011 : sf_kernel_offset = ALIGN(next_offset, 64);
772 : next_offset = sf_kernel_offset + sizeof (sf_kernel_static_mask);
773 : else if (rotation_program)
774 : next_offset = sf_kernel_offset + sizeof (sf_kernel_static_rotation);
776 : next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
778 : ps_kernel_offset = ALIGN(next_offset, 64);
780 : if (pMaskPicture->componentAlpha &&
781 : PICT_FORMAT_RGB(pMaskPicture->format)) {
782 : if (i965_blend_op[op].src_alpha) {
783 : next_offset = ps_kernel_offset +
784 : sizeof(ps_kernel_static_maskca_srcalpha);
786 : next_offset = ps_kernel_offset +
787 : sizeof(ps_kernel_static_maskca);
790 1 0.0011 : next_offset = ps_kernel_offset +
791 : sizeof(ps_kernel_static_masknoca);
792 : } else if (rotation_program) {
793 : next_offset = ps_kernel_offset + sizeof (ps_kernel_static_rotation);
795 1 0.0011 : next_offset = ps_kernel_offset + sizeof (ps_kernel_static_nomask);
798 13 0.0142 : sip_kernel_offset = ALIGN(next_offset, 64);
799 : next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
802 3 0.0033 : cc_viewport_offset = ALIGN(next_offset, 32);
803 : next_offset = cc_viewport_offset + sizeof(*cc_viewport);
805 : /* for texture sampler */
806 3 0.0033 : src_sampler_offset = ALIGN(next_offset, 32);
807 2 0.0022 : next_offset = src_sampler_offset + sizeof(*src_sampler_state);
809 3 0.0033 : if (pMask) {
810 : mask_sampler_offset = ALIGN(next_offset, 32);
811 1 0.0011 : next_offset = mask_sampler_offset + sizeof(*mask_sampler_state);
813 : /* Align VB to native size of elements, for safety */
814 10 0.0109 : vb_offset = ALIGN(next_offset, 8);
815 : next_offset = vb_offset + vb_size;
817 : /* And then the general state: */
818 2 0.0022 : dest_surf_offset = ALIGN(next_offset, 32);
819 : next_offset = dest_surf_offset + sizeof(*dest_surf_state);
821 2 0.0022 : src_surf_offset = ALIGN(next_offset, 32);
822 1 0.0011 : next_offset = src_surf_offset + sizeof(*src_surf_state);
824 1 0.0011 : if (pMask) {
825 1 0.0011 : mask_surf_offset = ALIGN(next_offset, 32);
826 : next_offset = mask_surf_offset + sizeof(*mask_surf_state);
827 3 0.0033 : binding_table_entries = 3;
830 3 0.0033 : binding_table_offset = ALIGN(next_offset, 32);
831 : next_offset = binding_table_offset + (binding_table_entries * 4);
833 4 0.0044 : default_color_offset = ALIGN(next_offset, 32);
834 2 0.0022 : next_offset = default_color_offset + sizeof(*default_color_state);
836 3 0.0033 : total_state_size = next_offset;
837 : assert(total_state_size < pI830->exa_965_state->size);
839 3 0.0033 : state_base_offset = pI830->exa_965_state->offset;
840 9 0.0098 : state_base_offset = ALIGN(state_base_offset, 64);
841 : state_base = (char *)(pI830->FbBase + state_base_offset);
843 : sf_kernel = (void *)(state_base + sf_kernel_offset);
844 1 0.0011 : ps_kernel = (void *)(state_base + ps_kernel_offset);
845 : sip_kernel = (void *)(state_base + sip_kernel_offset);
847 1 0.0011 : cc_viewport = (void *)(state_base + cc_viewport_offset);
849 1 0.0011 : binding_table = (void *)(state_base + binding_table_offset);
851 2 0.0022 : vb = (void *)(state_base + vb_offset);
853 5 0.0054 : default_color_state = (void*)(state_base + default_color_offset);
855 : /* Set up a default static partitioning of the URB, which is supposed to
856 : * allow anything we would want to do, at potentially lower performance.
858 :#define URB_CS_ENTRY_SIZE 0
859 :#define URB_CS_ENTRIES 0
861 :#define URB_VS_ENTRY_SIZE 1 // each 512-bit row
862 :#define URB_VS_ENTRIES 8 // we needs at least 8 entries
864 :#define URB_GS_ENTRY_SIZE 0
865 :#define URB_GS_ENTRIES 0
867 :#define URB_CLIP_ENTRY_SIZE 0
868 :#define URB_CLIP_ENTRIES 0
870 :#define URB_SF_ENTRY_SIZE 2
871 :#define URB_SF_ENTRIES 1
874 1 0.0011 : urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
875 : urb_gs_start = urb_vs_start + urb_vs_size;
876 : urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
877 : urb_clip_start = urb_gs_start + urb_gs_size;
878 : urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
879 1 0.0011 : urb_sf_start = urb_clip_start + urb_clip_size;
880 : urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
881 2 0.0022 : urb_cs_start = urb_sf_start + urb_sf_size;
882 1 0.0011 : urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
884 : /* Because we only have a single static buffer for our state currently,
885 : * we have to sync before updating it every time.
887 3 0.0033 : i830WaitSync(pScrn);
889 17 0.0185 : memset (cc_viewport, 0, sizeof (*cc_viewport));
890 17 0.0185 : cc_viewport->min_depth = -1.e35;
891 19 0.0207 : cc_viewport->max_depth = 1.e35;
893 : /* Color calculator state */
894 7 0.0076 : cc_state = &cc_state_local;
895 32 0.0349 : memset(cc_state, 0, sizeof(*cc_state));
896 34 0.0370 : cc_state->cc0.stencil_enable = 0; /* disable stencil */
897 : cc_state->cc2.depth_test = 0; /* disable depth test */
898 : cc_state->cc2.logicop_enable = 0; /* disable logic op */
899 : cc_state->cc3.ia_blend_enable = 1; /* blend alpha just like colors */
900 : cc_state->cc3.blend_enable = 1; /* enable color blend */
901 6 0.0065 : cc_state->cc3.alpha_test = 0; /* disable alpha test */
902 12 0.0131 : cc_state->cc4.cc_viewport_state_offset = (state_base_offset +
903 : cc_viewport_offset) >> 5;
904 : cc_state->cc5.dither_enable = 0; /* disable dither */
905 2 0.0022 : cc_state->cc5.logicop_func = 0xc; /* COPY */
906 : cc_state->cc5.statistics_enable = 1;
907 1 0.0011 : cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
908 38 0.0414 : i965_get_blend_cntl(op, pMaskPicture, pDstPicture->format,
909 : &src_blend, &dst_blend);
910 : /* XXX: alpha blend factor should be same as color, but check
911 : * for CA case in future
913 24 0.0261 : cc_state->cc5.ia_src_blend_factor = src_blend;
914 9 0.0098 : cc_state->cc5.ia_dest_blend_factor = dst_blend;
915 : cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD;
916 6 0.0065 : cc_state->cc6.src_blend_factor = src_blend;
917 10 0.0109 : cc_state->cc6.dest_blend_factor = dst_blend;
918 : cc_state->cc6.clamp_post_alpha_blend = 1;
919 4 0.0044 : cc_state->cc6.clamp_pre_alpha_blend = 1;
920 1 0.0011 : cc_state->cc6.clamp_range = 0; /* clamp range [0,1] */
922 1 0.0011 : cc_state = (void *)(state_base + cc_offset);
923 51 0.0556 : memcpy (cc_state, &cc_state_local, sizeof (cc_state_local));
925 : /* Upload system kernel */
926 10 0.0109 : memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
928 : /* Set up the state buffer for the destination surface */
929 8 0.0087 : dest_surf_state = &dest_surf_state_local;
930 42 0.0458 : memset(dest_surf_state, 0, sizeof(*dest_surf_state));
931 1 0.0011 : dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
932 8 0.0087 : dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
933 4 0.0044 : i965_get_dest_format(pDstPicture, &dst_format);
934 34 0.0370 : dest_surf_state->ss0.surface_format = dst_format;
936 : dest_surf_state->ss0.writedisable_alpha = 0;
937 : dest_surf_state->ss0.writedisable_red = 0;
938 : dest_surf_state->ss0.writedisable_green = 0;
939 : dest_surf_state->ss0.writedisable_blue = 0;
940 27 0.0294 : dest_surf_state->ss0.color_blend = 1;
941 : dest_surf_state->ss0.vert_line_stride = 0;
942 : dest_surf_state->ss0.vert_line_stride_ofs = 0;
943 : dest_surf_state->ss0.mipmap_layout_mode = 0;
944 : dest_surf_state->ss0.render_cache_read_mode = 0;
946 : dest_surf_state->ss1.base_addr = dst_offset;
947 4 0.0044 : dest_surf_state->ss2.height = pDst->drawable.height - 1;
948 40 0.0436 : dest_surf_state->ss2.width = pDst->drawable.width - 1;
949 : dest_surf_state->ss2.mip_count = 0;
950 : dest_surf_state->ss2.render_target_rotation = 0;
951 23 0.0251 : dest_surf_state->ss3.pitch = dst_pitch - 1;
953 1 0.0011 : dest_surf_state = (void *)(state_base + dest_surf_offset);
954 31 0.0338 : memcpy (dest_surf_state, &dest_surf_state_local, sizeof (dest_surf_state_local));
956 : /* Set up the source surface state buffer */
957 : src_surf_state = &src_surf_state_local;
958 48 0.0523 : memset(src_surf_state, 0, sizeof(*src_surf_state));
959 5 0.0054 : src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
960 20 0.0218 : src_surf_state->ss0.surface_format = i965_get_card_format(pSrcPicture);
962 : src_surf_state->ss0.writedisable_alpha = 0;
963 3 0.0033 : src_surf_state->ss0.writedisable_red = 0;
964 : src_surf_state->ss0.writedisable_green = 0;
965 : src_surf_state->ss0.writedisable_blue = 0;
966 31 0.0338 : src_surf_state->ss0.color_blend = 1;
967 : src_surf_state->ss0.vert_line_stride = 0;
968 : src_surf_state->ss0.vert_line_stride_ofs = 0;
969 : src_surf_state->ss0.mipmap_layout_mode = 0;
970 : src_surf_state->ss0.render_cache_read_mode = 0;
972 3 0.0033 : src_surf_state->ss1.base_addr = src_offset;
973 7 0.0076 : src_surf_state->ss2.width = pSrc->drawable.width - 1;
974 6 0.0065 : src_surf_state->ss2.height = pSrc->drawable.height - 1;
975 : src_surf_state->ss2.mip_count = 0;
976 30 0.0327 : src_surf_state->ss2.render_target_rotation = 0;
977 15 0.0163 : src_surf_state->ss3.pitch = src_pitch - 1;
979 : src_surf_state = (void *)(state_base + src_surf_offset);
980 28 0.0305 : memcpy (src_surf_state, &src_surf_state_local, sizeof (src_surf_state_local));
982 : /* setup mask surface */
983 1 0.0011 : if (pMask) {
984 : mask_surf_state = &mask_surf_state_local;
985 35 0.0381 : memset(mask_surf_state, 0, sizeof(*mask_surf_state));
986 6 0.0065 : mask_surf_state->ss0.surface_type = BRW_SURFACE_2D;
987 18 0.0196 : mask_surf_state->ss0.surface_format =
988 : i965_get_card_format(pMaskPicture);
990 : mask_surf_state->ss0.writedisable_alpha = 0;
991 8 0.0087 : mask_surf_state->ss0.writedisable_red = 0;
992 : mask_surf_state->ss0.writedisable_green = 0;
993 : mask_surf_state->ss0.writedisable_blue = 0;
994 20 0.0218 : mask_surf_state->ss0.color_blend = 1;
995 : mask_surf_state->ss0.vert_line_stride = 0;
996 : mask_surf_state->ss0.vert_line_stride_ofs = 0;
997 : mask_surf_state->ss0.mipmap_layout_mode = 0;
998 : mask_surf_state->ss0.render_cache_read_mode = 0;
1000 : mask_surf_state->ss1.base_addr = mask_offset;
1001 11 0.0120 : mask_surf_state->ss2.width = pMask->drawable.width - 1;
1002 4 0.0044 : mask_surf_state->ss2.height = pMask->drawable.height - 1;
1003 : mask_surf_state->ss2.mip_count = 0;
1004 31 0.0338 : mask_surf_state->ss2.render_target_rotation = 0;
1005 8 0.0087 : mask_surf_state->ss3.pitch = mask_pitch - 1;
1007 : mask_surf_state = (void *)(state_base + mask_surf_offset);
1008 38 0.0414 : memcpy (mask_surf_state, &mask_surf_state_local, sizeof (mask_surf_state_local));
1011 : /* Set up a binding table for our surfaces. Only the PS will use it */
1012 8 0.0087 : binding_table[0] = state_base_offset + dest_surf_offset;
1013 1 0.0011 : binding_table[1] = state_base_offset + src_surf_offset;
1015 3 0.0033 : binding_table[2] = state_base_offset + mask_surf_offset;
1017 : /* PS kernel use this sampler */
1018 : src_sampler_state = &src_sampler_state_local;
1019 3 0.0033 : memset(src_sampler_state, 0, sizeof(*src_sampler_state));
1020 : src_sampler_state->ss0.lod_preclamp = 1; /* GL mode */
1021 58 0.0632 : switch(pSrcPicture->filter) {
1022 : case PictFilterNearest:
1023 4 0.0044 : src_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST;
1024 38 0.0414 : src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
1026 : case PictFilterBilinear:
1027 : src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
1028 : src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
1031 : I830FALLBACK("Bad filter 0x%x\n", pSrcPicture->filter);
1034 40 0.0436 : memset(default_color_state, 0, sizeof(*default_color_state));
1035 1 0.0011 : default_color_state->color[0] = 0.0; /* R */
1036 4 0.0044 : default_color_state->color[1] = 0.0; /* G */
1037 : default_color_state->color[2] = 0.0; /* B */
1038 : default_color_state->color[3] = 0.0; /* A */
1040 3 0.0033 : src_sampler_state->ss0.default_color_mode = 0; /* GL mode */
1042 3 0.0033 : if (!pSrcPicture->repeat) {
1043 : src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
1044 1 0.0011 : src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
1045 : src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER;
1046 : src_sampler_state->ss2.default_color_pointer =
1047 : (state_base_offset + default_color_offset) >> 5;
1049 8 0.0087 : src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP;
1050 : src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
1051 85 0.0926 : src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
1053 3 0.0033 : src_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
1055 6 0.0065 : src_sampler_state = (void *)(state_base + src_sampler_offset);
1056 32 0.0349 : memcpy (src_sampler_state, &src_sampler_state_local, sizeof (src_sampler_state_local));
1058 3 0.0033 : if (pMask) {
1059 : mask_sampler_state = &mask_sampler_state_local;
1060 : memset(mask_sampler_state, 0, sizeof(*mask_sampler_state));
1061 3 0.0033 : mask_sampler_state->ss0.lod_preclamp = 1; /* GL mode */
1062 45 0.0490 : switch(pMaskPicture->filter) {
1063 : case PictFilterNearest:
1064 5 0.0054 : mask_sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST;
1065 41 0.0447 : mask_sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST;
1067 : case PictFilterBilinear:
1068 : mask_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
1069 : mask_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
1072 : I830FALLBACK("Bad filter 0x%x\n", pMaskPicture->filter);
1075 34 0.0370 : if (!pMaskPicture->repeat) {
1076 3 0.0033 : mask_sampler_state->ss1.r_wrap_mode =
1077 : BRW_TEXCOORDMODE_CLAMP_BORDER;
1078 40 0.0436 : mask_sampler_state->ss1.s_wrap_mode =
1079 : BRW_TEXCOORDMODE_CLAMP_BORDER;
1080 22 0.0240 : mask_sampler_state->ss1.t_wrap_mode =
1081 : BRW_TEXCOORDMODE_CLAMP_BORDER;
1082 7 0.0076 : mask_sampler_state->ss2.default_color_pointer =
1083 : (state_base_offset + default_color_offset)>>5;
1085 : mask_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP;
1086 : mask_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP;
1087 : mask_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
1089 : mask_sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */
1091 5 0.0054 : mask_sampler_state = (void *)(state_base + mask_sampler_offset);
1092 27 0.0294 : memcpy (mask_sampler_state, &mask_sampler_state_local, sizeof (mask_sampler_state_local));
1095 : /* Set up the vertex shader to be disabled (passthrough) */
1096 4 0.0044 : vs_state = &vs_state_local;
1097 8 0.0087 : memset(vs_state, 0, sizeof(*vs_state));
1098 1 0.0011 : vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
1099 1 0.0011 : vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
1100 46 0.0501 : vs_state->vs6.vs_enable = 0;
1101 : vs_state->vs6.vert_cache_disable = 1;
1103 6 0.0065 : vs_state = (void *)(state_base + vs_offset);
1104 22 0.0240 : memcpy (vs_state, &vs_state_local, sizeof (vs_state_local));
1106 : /* Set up the SF kernel to do coord interp: for each attribute,
1107 : * calculate dA/dx and dA/dy. Hand these interpolation coefficients
1108 : * back to SF which then hands pixels off to WM.
1110 4 0.0044 : if (pMask)
1111 5 0.0054 : memcpy(sf_kernel, sf_kernel_static_mask, sizeof (sf_kernel_static));
1112 : else if (rotation_program)
1113 : memcpy(sf_kernel, sf_kernel_static_rotation,
1114 : sizeof (sf_kernel_static_rotation));
1116 : memcpy(sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
1118 3 0.0033 : sf_state = &sf_state_local;
1119 45 0.0490 : memset(sf_state, 0, sizeof(*sf_state));
1120 102 0.1111 : sf_state->thread0.kernel_start_pointer =
1121 : (state_base_offset + sf_kernel_offset) >> 6;
1122 1 0.0011 : sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
1123 50 0.0545 : sf_state->sf1.single_program_flow = 1;
1124 : sf_state->sf1.binding_table_entry_count = 0;
1125 : sf_state->sf1.thread_priority = 0;
1126 : sf_state->sf1.floating_point_mode = 0; /* Mesa does this */
1127 : sf_state->sf1.illegal_op_exception_enable = 1;
1128 7 0.0076 : sf_state->sf1.mask_stack_exception_enable = 1;
1129 : sf_state->sf1.sw_exception_enable = 1;
1130 45 0.0490 : sf_state->thread2.per_thread_scratch_space = 0;
1131 : /* scratch space is not used in our kernel */
1132 4 0.0044 : sf_state->thread2.scratch_space_base_pointer = 0;
1133 3 0.0033 : sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */
1134 8 0.0087 : sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */
1135 9 0.0098 : sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
1136 : /* don't smash vertex header, read start from dw8 */
1137 4 0.0044 : sf_state->thread3.urb_entry_read_offset = 1;
1138 3 0.0033 : sf_state->thread3.dispatch_grf_start_reg = 3;
1139 10 0.0109 : sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
1140 1 0.0011 : sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
1141 6 0.0065 : sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
1142 : sf_state->thread4.stats_enable = 1;
1143 : sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
1144 32 0.0349 : sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
1145 40 0.0436 : sf_state->sf6.scissor = 0;
1146 5 0.0054 : sf_state->sf7.trifan_pv = 2;
1147 5 0.0054 : sf_state->sf6.dest_org_vbias = 0x8;
1148 54 0.0588 : sf_state->sf6.dest_org_hbias = 0x8;
1150 3 0.0033 : sf_state = (void *)(state_base + sf_offset);
1151 14 0.0153 : memcpy (sf_state, &sf_state_local, sizeof (sf_state_local));
1153 : /* Set up the PS kernel (dispatched by WM) */
1155 5 0.0054 : if (pMaskPicture->componentAlpha &&
1156 : PICT_FORMAT_RGB(pMaskPicture->format)) {
1157 3 0.0033 : if (i965_blend_op[op].src_alpha)
1158 3 0.0033 : memcpy(ps_kernel, ps_kernel_static_maskca_srcalpha,
1159 : sizeof (ps_kernel_static_maskca_srcalpha));
1161 2 0.0022 : memcpy(ps_kernel, ps_kernel_static_maskca,
1162 : sizeof (ps_kernel_static_maskca));
1164 8 0.0087 : memcpy(ps_kernel, ps_kernel_static_masknoca,
1165 : sizeof (ps_kernel_static_masknoca));
1166 : } else if (rotation_program) {
1167 1 0.0011 : memcpy(ps_kernel, ps_kernel_static_rotation,
1168 : sizeof (ps_kernel_static_rotation));
1170 1 0.0011 : memcpy(ps_kernel, ps_kernel_static_nomask,
1171 : sizeof (ps_kernel_static_nomask));
1174 13 0.0142 : wm_state = &wm_state_local;
1175 90 0.0980 : memset(wm_state, 0, sizeof (*wm_state));
1176 90 0.0980 : wm_state->thread0.kernel_start_pointer =
1177 : (state_base_offset + ps_kernel_offset) >> 6;
1178 21 0.0229 : wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
1179 : wm_state->thread1.single_program_flow = 1;
1181 1 0.0011 : wm_state->thread1.binding_table_entry_count = 2; /* 1 tex and fb */
1183 18 0.0196 : wm_state->thread1.binding_table_entry_count = 3; /* 2 tex and fb */
1185 6 0.0065 : wm_state->thread2.scratch_space_base_pointer = (state_base_offset +
1186 : wm_scratch_offset)>>10;
1187 33 0.0359 : wm_state->thread2.per_thread_scratch_space = 0;
1188 : wm_state->thread3.const_urb_entry_read_length = 0;
1189 1 0.0011 : wm_state->thread3.const_urb_entry_read_offset = 0;
1190 : /* Each pair of attributes (src/mask coords) is one URB entry */
1192 7 0.0076 : wm_state->thread3.urb_entry_read_length = 2;
1194 2 0.0022 : wm_state->thread3.urb_entry_read_length = 1;
1195 4 0.0044 : wm_state->thread3.urb_entry_read_offset = 0;
1196 : /* wm kernel use urb from 3, see wm_program in compiler module */
1197 19 0.0207 : wm_state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */
1199 10 0.0109 : wm_state->wm4.stats_enable = 1; /* statistic */
1200 7 0.0076 : wm_state->wm4.sampler_state_pointer = (state_base_offset +
1201 : src_sampler_offset) >> 5;
1202 19 0.0207 : wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
1203 6 0.0065 : wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
1204 : wm_state->wm5.thread_dispatch_enable = 1;
1205 : /* just use 16-pixel dispatch (4 subspans), don't need to change kernel
1208 2 0.0022 : wm_state->wm5.enable_16_pix = 1;
1209 : wm_state->wm5.enable_8_pix = 0;
1210 20 0.0218 : wm_state->wm5.early_depth_test = 1;
1212 3 0.0033 : wm_state = (void *)(state_base + wm_offset);
1213 35 0.0381 : memcpy (wm_state, &wm_state_local, sizeof (wm_state_local));
1215 : /* Begin the long sequence of commands needed to set up the 3D
1219 2 0.0022 : BEGIN_LP_RING(2);
1220 3 0.0033 : OUT_RING(MI_FLUSH |
1221 : MI_STATE_INSTRUCTION_CACHE_FLUSH |
1222 : BRW_MI_GLOBAL_SNAPSHOT_RESET);
1223 4 0.0044 : OUT_RING(MI_NOOP);
1224 37 0.0403 : ADVANCE_LP_RING();
1227 2751 2.9969 : BEGIN_LP_RING(12);
1229 : /* Match Mesa driver setup */
1230 5 0.0054 : OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
1232 10 0.0109 : OUT_RING(BRW_CS_URB_STATE | 0);
1233 5 0.0054 : OUT_RING((0 << 4) | /* URB Entry Allocation Size */
1234 : (0 << 0)); /* Number of URB Entries */
1236 : /* Zero out the two base address registers so all offsets are
1239 4 0.0044 : OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
1240 1 0.0011 : OUT_RING(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */
1241 2 0.0022 : OUT_RING(0 | BASE_ADDRESS_MODIFY); /* Surface state base address */
1242 5 0.0054 : OUT_RING(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */
1243 : /* general state max addr, disabled */
1244 4 0.0044 : OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);
1245 : /* media object state max addr, disabled */
1246 7 0.0076 : OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);
1248 : /* Set system instruction pointer */
1249 4 0.0044 : OUT_RING(BRW_STATE_SIP | 0);
1250 13 0.0142 : OUT_RING(state_base_offset + sip_kernel_offset);
1251 8 0.0087 : OUT_RING(MI_NOOP);
1252 106 0.1155 : ADVANCE_LP_RING();
1255 1204 1.3116 : BEGIN_LP_RING(26);
1256 : /* Pipe control */
1257 2 0.0022 : OUT_RING(BRW_PIPE_CONTROL |
1258 : BRW_PIPE_CONTROL_NOWRITE |
1259 : BRW_PIPE_CONTROL_IS_FLUSH |
1261 15 0.0163 : OUT_RING(0); /* Destination address */
1262 6 0.0065 : OUT_RING(0); /* Immediate data low DW */
1263 3 0.0033 : OUT_RING(0); /* Immediate data high DW */
1265 : /* Binding table pointers */
1266 3 0.0033 : OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
1267 6 0.0065 : OUT_RING(0); /* vs */
1268 5 0.0054 : OUT_RING(0); /* gs */
1269 5 0.0054 : OUT_RING(0); /* clip */
1270 10 0.0109 : OUT_RING(0); /* sf */
1271 : /* Only the PS uses the binding table */
1272 16 0.0174 : OUT_RING(state_base_offset + binding_table_offset); /* ps */
1274 : /* The drawing rectangle clipping is always on. Set it to values that
1275 : * shouldn't do any clipping.
1277 22 0.0240 : OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2); /* XXX 3 for BLC or CTG */
1278 12 0.0131 : OUT_RING(0x00000000); /* ymin, xmin */
1279 61 0.0665 : OUT_RING(DRAW_YMAX(pDst->drawable.height - 1) |
1280 : DRAW_XMAX(pDst->drawable.width - 1)); /* ymax, xmax */
1281 41 0.0447 : OUT_RING(0x00000000); /* yorigin, xorigin */
1283 : /* skip the depth buffer */
1284 : /* skip the polygon stipple */
1285 : /* skip the polygon stipple offset */
1286 : /* skip the line stipple */
1288 : /* Set the pointers to the 3d pipeline state */
1289 : OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
1290 29 0.0316 : OUT_RING(state_base_offset + vs_offset); /* 32 byte aligned */
1291 11 0.0120 : OUT_RING(BRW_GS_DISABLE); /* disable GS, resulting in passthrough */
1292 102 0.1111 : OUT_RING(BRW_CLIP_DISABLE); /* disable CLIP, resulting in passthrough */
1293 383 0.4172 : OUT_RING(state_base_offset + sf_offset); /* 32 byte aligned */
1294 26 0.0283 : OUT_RING(state_base_offset + wm_offset); /* 32 byte aligned */
1295 17 0.0185 : OUT_RING(state_base_offset + cc_offset); /* 64 byte aligned */
1298 : OUT_RING(BRW_URB_FENCE |
1301 : UF0_CLIP_REALLOC |
1305 39 0.0425 : OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
1306 : ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
1307 : ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
1308 28 0.0305 : OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
1309 : ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
1311 : /* Constant buffer state */
1312 11 0.0120 : OUT_RING(BRW_CS_URB_STATE | 0);
1313 3 0.0033 : OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) |
1314 : (URB_CS_ENTRIES << 0));
1315 62 0.0675 : ADVANCE_LP_RING();
1318 702 0.7647 : int nelem = pMask ? 3: 2;
1319 12 0.0131 : BEGIN_LP_RING(pMask?12:10);
1320 : /* Set up the pointer to our vertex buffer */
1321 4 0.0044 : OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 3);
1322 2 0.0022 : OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
1324 : ((4 * 2 * nelem) << VB0_BUFFER_PITCH_SHIFT));
1325 10 0.0109 : OUT_RING(state_base_offset + vb_offset);
1326 2 0.0022 : OUT_RING(3);
1327 7 0.0076 : OUT_RING(0); // ignore for VERTEXDATA, but still there
1329 : /* Set up our vertex elements, sourced from the single vertex buffer.
1331 9 0.0098 : OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * nelem) - 1));
1332 : /* vertex coordinates */
1333 5 0.0054 : OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
1335 : (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
1336 : (0 << VE0_OFFSET_SHIFT));
1337 2 0.0022 : OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1338 : (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1339 : (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
1340 : (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
1341 : (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
1343 2 0.0022 : OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
1345 : (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
1346 : (8 << VE0_OFFSET_SHIFT)); /* offset vb in bytes */
1347 14 0.0153 : OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1348 : (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1349 : (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_2_SHIFT) |
1350 : (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_3_SHIFT) |
1351 : (8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); /* VUE offset in dwords */
1353 1 0.0011 : if (pMask) {
1354 4 0.0044 : OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
1356 : (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
1357 : (16 << VE0_OFFSET_SHIFT));
1358 1 0.0011 : OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1359 : (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1360 : (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_2_SHIFT) |
1361 : (BRW_VFCOMPONENT_NOSTORE << VE1_VFCOMPONENT_3_SHIFT) |
1362 : (10 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
1365 66 0.0719 : ADVANCE_LP_RING();
1369 : ErrorF("try to sync to show any errors...");
1376 :i965_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
1377 : int dstX, int dstY, int w, int h)
1378 707 0.7702 :{ /* i965_composite total: 2800 3.0503 */
1379 38 0.0414 : ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
1380 3 0.0033 : I830Ptr pI830 = I830PTR(pScrn);
1382 : float src_x[3], src_y[3], mask_x[3], mask_y[3];
1385 22 0.0240 : i830_get_transformed_coordinates(srcX, srcY,
1386 : pI830->transform[0],
1387 : &src_x[0], &src_y[0]);
1388 5 0.0054 : i830_get_transformed_coordinates(srcX, srcY + h,
1389 : pI830->transform[0],
1390 : &src_x[1], &src_y[1]);
1391 15 0.0163 : i830_get_transformed_coordinates(srcX + w, srcY + h,
1392 : pI830->transform[0],
1393 : &src_x[2], &src_y[2]);
1395 18 0.0196 : if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) {
1399 1 0.0011 : i830_get_transformed_coordinates(maskX, maskY,
1400 : pI830->transform[1],
1401 : &mask_x[0], &mask_y[0]);
1402 8 0.0087 : i830_get_transformed_coordinates(maskX, maskY + h,
1403 : pI830->transform[1],
1404 : &mask_x[1], &mask_y[1]);
1405 33 0.0359 : i830_get_transformed_coordinates(maskX + w, maskY + h,
1406 : pI830->transform[1],
1407 : &mask_x[2], &mask_y[2]);
1410 : /* Wait for any existing composite rectangles to land before we overwrite
1411 : * the VB with the next one.
1413 7 0.0076 : i830WaitSync(pScrn);
1416 : /* rect (x2,y2) */
1417 6 0.0065 : vb[i++] = (float)(dstX + w);
1418 7 0.0076 : vb[i++] = (float)(dstY + h);
1419 4 0.0044 : vb[i++] = src_x[2] / pI830->scale_units[0][0];
1420 8 0.0087 : vb[i++] = src_y[2] / pI830->scale_units[0][1];
1422 77 0.0839 : vb[i++] = mask_x[2] / pI830->scale_units[1][0];
1423 88 0.0959 : vb[i++] = mask_y[2] / pI830->scale_units[1][1];
1426 : /* rect (x1,y2) */
1427 2 0.0022 : vb[i++] = (float)dstX;
1428 1 0.0011 : vb[i++] = (float)(dstY + h);
1429 3 0.0033 : vb[i++] = src_x[1] / pI830->scale_units[0][0];
1430 14 0.0153 : vb[i++] = src_y[1] / pI830->scale_units[0][1];
1431 2 0.0022 : if (has_mask) {
1432 7 0.0076 : vb[i++] = mask_x[1] / pI830->scale_units[1][0];
1433 72 0.0784 : vb[i++] = mask_y[1] / pI830->scale_units[1][1];
1436 : /* rect (x1,y1) */
1437 2 0.0022 : vb[i++] = (float)dstX;
1438 3 0.0033 : vb[i++] = (float)dstY;
1439 3 0.0033 : vb[i++] = src_x[0] / pI830->scale_units[0][0];
1440 5 0.0054 : vb[i++] = src_y[0] / pI830->scale_units[0][1];
1442 7 0.0076 : vb[i++] = mask_x[0] / pI830->scale_units[1][0];
1443 11 0.0120 : vb[i++] = mask_y[0] / pI830->scale_units[1][1];
1447 2 0.0022 : BEGIN_LP_RING(6);
1448 3 0.0033 : OUT_RING(BRW_3DPRIMITIVE |
1449 : BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
1450 : (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
1451 : (0 << 9) | /* CTG - indirect vertex count */
1453 4 0.0044 : OUT_RING(3); /* vertex count per instance */
1454 : OUT_RING(0); /* start vertex offset */
1455 3 0.0033 : OUT_RING(1); /* single instance */
1456 4 0.0044 : OUT_RING(0); /* start instance location */
1457 3 0.0033 : OUT_RING(0); /* index buffer offset, ignored */
1458 4 0.0044 : ADVANCE_LP_RING();
1461 : ErrorF("sync after 3dprimitive");
1464 : /* we must be sure that the pipeline is flushed before next exa draw,
1465 : because that will be new state, binding state and instructions*/
1467 804 0.8759 : BEGIN_LP_RING(4);
1468 : OUT_RING(BRW_PIPE_CONTROL |
1469 : BRW_PIPE_CONTROL_NOWRITE |
1470 : BRW_PIPE_CONTROL_WC_FLUSH |
1471 : BRW_PIPE_CONTROL_IS_FLUSH |
1472 : (1 << 10) | /* XXX texture cache flush for BLC/CTG */
1474 2 0.0022 : OUT_RING(0); /* Destination address */
1475 5 0.0054 : OUT_RING(0); /* Immediate data low DW */
1476 5 0.0054 : OUT_RING(0); /* Immediate data high DW */
1477 7 0.0076 : ADVANCE_LP_RING();
1480 : /* Mark sync so we can wait for it before setting up the VB on the next
1483 773 0.8421 : i830MarkSync(pScrn);
1486 * Total samples for file : "/home/cworth/src/xorg/xserver/exa/exa.c"
1493 : * Copyright © 2001 Keith Packard
1495 : * Partly based on code that is Copyright © The XFree86 Project Inc.
1497 : * Permission to use, copy, modify, distribute, and sell this software and its
1498 : * documentation for any purpose is hereby granted without fee, provided that
1499 : * the above copyright notice appear in all copies and that both that
1500 : * copyright notice and this permission notice appear in supporting
1501 : * documentation, and that the name of Keith Packard not be used in
1502 : * advertising or publicity pertaining to distribution of the software without
1503 : * specific, written prior permission. Keith Packard makes no
1504 : * representations about the suitability of this software for any purpose. It
1505 : * is provided "as is" without express or implied warranty.
1507 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1508 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1509 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1510 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1511 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1512 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1513 : * PERFORMANCE OF THIS SOFTWARE.
1517 : * This file covers the initialization and teardown of EXA, and has various
1518 : * functions not responsible for performing rendering, pixmap migration, or
1519 : * memory management.
1522 :#ifdef HAVE_DIX_CONFIG_H
1523 :#include <dix-config.h>
1527 :#include "shmint.h"
1530 :#include <stdlib.h>
1532 :#include "exa_priv.h"
1533 :#include <X11/fonts/fontstruct.h>
1534 :#include "dixfontstr.h"
1538 :static int exaGeneration;
1539 :int exaScreenPrivateIndex;
1540 :int exaPixmapPrivateIndex;
1543 : * exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
1544 : * the beginning of the given pixmap.
1546 : * Note that drivers are free to, and often do, munge this offset as necessary
1547 : * for handing to the hardware -- for example, translating it into a different
1548 : * aperture. This function may need to be extended in the future if we grow
1549 : * support for having multiple card-accessible offscreen, such as an AGP memory
1550 : * pool alongside the framebuffer pool.
1553 :exaGetPixmapOffset(PixmapPtr pPix)
1554 11 0.0120 :{ /* exaGetPixmapOffset total: 35 0.0381 */
1555 3 0.0033 : ExaScreenPriv (pPix->drawable.pScreen);
1556 6 0.0065 : ExaPixmapPriv (pPix);
1559 : /* Return the offscreen pointer if we've hidden the data. */
1560 5 0.0054 : if (pPix->devPrivate.ptr == NULL)
1561 : ptr = pExaPixmap->fb_ptr;
1563 : ptr = pPix->devPrivate.ptr;
1565 : return ((unsigned long)ptr - (unsigned long)pExaScr->info->memoryBase);
1569 : * exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap.
1571 : * This is a helper to make driver code more obvious, due to the rather obscure
1572 : * naming of the pitch field in the pixmap.
1575 :exaGetPixmapPitch(PixmapPtr pPix)
1576 2 0.0022 :{ /* exaGetPixmapPitch total: 7 0.0076 */
1577 : return pPix->devKind;
1581 : * exaGetPixmapSize() returns the size in bytes of the given pixmap in video
1582 : * memory. Only valid when the pixmap is currently in framebuffer.
1585 :exaGetPixmapSize(PixmapPtr pPix)
1587 : ExaPixmapPrivPtr pExaPixmap;
1589 : pExaPixmap = ExaGetPixmapPriv(pPix);
1590 : if (pExaPixmap != NULL)
1591 : return pExaPixmap->fb_size;
1596 : * exaGetDrawablePixmap() returns a backing pixmap for a given drawable.
1598 : * @param pDrawable the drawable being requested.
1600 : * This function returns the backing pixmap for a drawable, whether it is a
1601 : * redirected window, unredirected window, or already a pixmap. Note that
1602 : * coordinate translation is needed when drawing to the backing pixmap of a
1603 : * redirected window, and the translation coordinates are provided by calling
1604 : * exaGetOffscreenPixmap() on the drawable.
1607 :exaGetDrawablePixmap(DrawablePtr pDrawable)
1608 53 0.0577 :{ /* exaGetDrawablePixmap total: 111 0.1209 */
1609 5 0.0054 : if (pDrawable->type == DRAWABLE_WINDOW)
1610 : return pDrawable->pScreen->GetWindowPixmap ((WindowPtr) pDrawable);
1612 30 0.0327 : return (PixmapPtr) pDrawable;
1616 : * Sets the offsets to add to coordinates to make them address the same bits in
1617 : * the backing drawable. These coordinates are nonzero only for redirected
1621 :exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
1623 8 0.0087 :{ /* exaGetDrawableDeltas total: 52 0.0566 */
1625 21 0.0229 : if (pDrawable->type == DRAWABLE_WINDOW) {
1626 : *xp = -pPixmap->screen_x;
1627 : *yp = -pPixmap->screen_y;
1637 : * exaPixmapDirty() marks a pixmap as dirty, allowing for
1638 : * optimizations in pixmap migration when no changes have occurred.
1641 :exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
1642 20 0.0218 :{ /* exaPixmapDirty total: 90 0.0980 */
1643 6 0.0065 : ExaPixmapPriv(pPix);
1645 : RegionPtr pDamageReg;
1648 11 0.0120 : if (!pExaPixmap)
1651 3 0.0033 : box.x1 = max(x1, 0);
1652 : box.y1 = max(y1, 0);
1653 6 0.0065 : box.x2 = min(x2, pPix->drawable.width);
1654 13 0.0142 : box.y2 = min(y2, pPix->drawable.height);
1656 4 0.0044 : if (box.x1 >= box.x2 || box.y1 >= box.y2)
1659 4 0.0044 : pDamageReg = DamageRegion(pExaPixmap->pDamage);
1661 5 0.0054 : REGION_INIT(pScreen, ®ion, &box, 1);
1662 6 0.0065 : REGION_UNION(pScreen, pDamageReg, pDamageReg, ®ion);
1663 4 0.0044 : REGION_UNINIT(pScreen, ®ion);
1667 :exaDestroyPixmap (PixmapPtr pPixmap)
1668 3 0.0033 :{ /* exaDestroyPixmap total: 4 0.0044 */
1669 : if (pPixmap->refcnt == 1)
1671 : ExaPixmapPriv (pPixmap);
1672 : if (pExaPixmap->area)
1674 : DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
1675 : (void*)pPixmap->drawable.id,
1676 : ExaGetPixmapPriv(pPixmap)->area->offset,
1677 : pPixmap->drawable.width,
1678 : pPixmap->drawable.height));
1679 : /* Free the offscreen area */
1680 : exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area);
1681 1 0.0011 : pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
1682 : pPixmap->devKind = pExaPixmap->sys_pitch;
1684 : REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validReg);
1686 : return fbDestroyPixmap (pPixmap);
1696 : for (bits = 0; val != 0; bits++)
1702 : * exaCreatePixmap() creates a new pixmap.
1704 : * If width and height are 0, this won't be a full-fledged pixmap and it will
1705 : * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because
1706 : * ModifyPixmapHeader() would break migration. These types of pixmaps are used
1707 : * for scratch pixmaps, or to represent the visible screen.
1710 :exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
1711 4 0.0044 :{ /* exaCreatePixmap total: 19 0.0207 */
1712 : PixmapPtr pPixmap;
1713 : ExaPixmapPrivPtr pExaPixmap;
1715 1 0.0011 : ExaScreenPriv(pScreen);
1717 : if (w > 32767 || h > 32767)
1718 : return NullPixmap;
1720 3 0.0033 : pPixmap = fbCreatePixmap (pScreen, w, h, depth);
1723 1 0.0011 : pExaPixmap = ExaGetPixmapPriv(pPixmap);
1725 : bpp = pPixmap->drawable.bitsPerPixel;
1727 : /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
1728 1 0.0011 : if (!w || !h)
1729 : pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
1731 2 0.0022 : pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
1733 : pExaPixmap->area = NULL;
1735 : pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
1736 : pExaPixmap->sys_pitch = pPixmap->devKind;
1738 : pExaPixmap->fb_ptr = NULL;
1739 1 0.0011 : if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
1740 : pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
1742 1 0.0011 : pExaPixmap->fb_pitch = w * bpp / 8;
1743 4 0.0044 : pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
1744 : pExaScr->info->pixmapPitchAlign);
1745 : pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
1747 : if (pExaPixmap->fb_pitch > 32767) {
1748 : fbDestroyPixmap(pPixmap);
1752 : /* Set up damage tracking */
1753 : pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE,
1754 : pScreen, pPixmap);
1756 : if (pExaPixmap->pDamage == NULL) {
1757 : fbDestroyPixmap (pPixmap);
1761 : DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
1762 : DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
1764 : /* None of the pixmap bits are valid initially */
1765 1 0.0011 : REGION_NULL(pScreen, &pExaPixmap->validReg);
1771 : * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
1772 : * memory, meaning that acceleration could probably be done to it, and that it
1773 : * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
1776 : * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly
1777 : * deal with moving pixmaps in and out of system memory), EXA will give drivers
1778 : * pixmaps as arguments for which exaPixmapIsOffscreen() is TRUE.
1780 : * @return TRUE if the given drawable is in framebuffer memory.
1783 :exaPixmapIsOffscreen(PixmapPtr p)
1784 44 0.0479 :{ /* exaPixmapIsOffscreen total: 267 0.2909 */
1785 : ScreenPtr pScreen = p->drawable.pScreen;
1786 53 0.0577 : ExaScreenPriv(pScreen);
1788 : /* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
1790 36 0.0392 : if (p->devPrivate.ptr == NULL)
1793 80 0.0872 : if (pExaScr->info->PixmapIsOffscreen)
1794 : return pExaScr->info->PixmapIsOffscreen(p);
1796 27 0.0294 : return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
1797 : (CARD8 *) pExaScr->info->memoryBase) <
1798 : pExaScr->info->memorySize);
1802 : * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapIsOffscreen().
1805 :exaDrawableIsOffscreen (DrawablePtr pDrawable)
1807 : return exaPixmapIsOffscreen (exaGetDrawablePixmap (pDrawable));
1811 : * Returns the pixmap which backs a drawable, and the offsets to add to
1812 : * coordinates to make them address the same bits in the backing drawable.
1815 :exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
1816 17 0.0185 :{ /* exaGetOffscreenPixmap total: 69 0.0752 */
1817 6 0.0065 : PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
1819 16 0.0174 : exaGetDrawableDeltas (pDrawable, pPixmap, xp, yp);
1821 15 0.0163 : if (exaPixmapIsOffscreen (pPixmap))
1828 : * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
1830 : * It deals with waiting for synchronization with the card, determining if
1831 : * PrepareAccess() is necessary, and working around PrepareAccess() failure.
1834 :exaPrepareAccess(DrawablePtr pDrawable, int index)
1835 :{ /* exaPrepareAccess total: 1 0.0011 */
1836 : ScreenPtr pScreen = pDrawable->pScreen;
1837 : ExaScreenPriv (pScreen);
1838 : PixmapPtr pPixmap;
1840 : pPixmap = exaGetDrawablePixmap (pDrawable);
1842 : if (exaPixmapIsOffscreen (pPixmap))
1843 : exaWaitSync (pDrawable->pScreen);
1847 : /* Unhide pixmap pointer */
1848 : if (pPixmap->devPrivate.ptr == NULL) {
1849 : ExaPixmapPriv (pPixmap);
1851 : pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
1854 1 0.0011 : if (pExaScr->info->PrepareAccess == NULL)
1857 : if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
1858 : ExaPixmapPriv (pPixmap);
1859 : if (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED)
1860 : FatalError("Driver failed PrepareAccess on a pinned pixmap\n");
1861 : exaMoveOutPixmap (pPixmap);
1866 : * exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler.
1868 : * It deals with calling the driver's FinishAccess() only if necessary.
1871 :exaFinishAccess(DrawablePtr pDrawable, int index)
1872 :{ /* exaFinishAccess total: 1 0.0011 */
1873 : ScreenPtr pScreen = pDrawable->pScreen;
1874 1 0.0011 : ExaScreenPriv (pScreen);
1875 : PixmapPtr pPixmap;
1876 : ExaPixmapPrivPtr pExaPixmap;
1878 : pPixmap = exaGetDrawablePixmap (pDrawable);
1880 : pExaPixmap = ExaGetPixmapPriv(pPixmap);
1882 : /* Rehide pixmap pointer if we're doing that. */
1883 : if (pExaPixmap != NULL && pExaScr->hideOffscreenPixmapData &&
1884 : pExaPixmap->fb_ptr == pPixmap->devPrivate.ptr)
1886 : pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
1889 : if (pExaScr->info->FinishAccess == NULL)
1892 : if (!exaPixmapIsOffscreen (pPixmap))
1895 : (*pExaScr->info->FinishAccess) (pPixmap, index);
1899 : * exaValidateGC() sets the ops to EXA's implementations, which may be
1900 : * accelerated or may sync the card and fall back to fb.
1903 :exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
1904 2 0.0022 :{ /* exaValidateGC total: 8 0.0087 */
1905 : /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
1906 : * Preempt fbValidateGC by doing its work and masking the change out, so
1907 : * that we can do the Prepare/FinishAccess.
1910 1 0.0011 : if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) {
1911 : (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
1912 : fbGetRotatedPixmap(pGC) = 0;
1915 : if (pGC->fillStyle == FillTiled) {
1916 : PixmapPtr pOldTile, pNewTile;
1918 : pOldTile = pGC->tile.pixmap;
1919 : if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
1921 : pNewTile = fbGetRotatedPixmap(pGC);
1923 : pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
1926 : (*pGC->pScreen->DestroyPixmap) (pNewTile);
1927 : /* fb24_32ReformatTile will do direct access of a newly-
1928 : * allocated pixmap. This isn't a problem yet, since we don't
1929 : * put pixmaps in FB until at least one accelerated EXA op.
1931 : exaPrepareAccess(&pOldTile->drawable, EXA_PREPARE_SRC);
1932 : pNewTile = fb24_32ReformatTile (pOldTile,
1933 : pDrawable->bitsPerPixel);
1934 : exaPixmapDirty(pNewTile, 0, 0, pNewTile->drawable.width, pNewTile->drawable.height);
1935 : exaFinishAccess(&pOldTile->drawable, EXA_PREPARE_SRC);
1939 : fbGetRotatedPixmap(pGC) = pOldTile;
1940 : pGC->tile.pixmap = pNewTile;
1941 : changes |= GCTile;
1946 : if (changes & GCTile) {
1947 : if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width *
1948 : pDrawable->bitsPerPixel))
1950 : /* XXX This fixes corruption with tiled pixmaps, but may just be a
1951 : * workaround for broken drivers
1953 : exaMoveOutPixmap(pGC->tile.pixmap);
1954 : fbPadPixmap (pGC->tile.pixmap);
1955 : exaPixmapDirty(pGC->tile.pixmap, 0, 0,
1956 : pGC->tile.pixmap->drawable.width,
1957 : pGC->tile.pixmap->drawable.height);
1959 : /* Mask out the GCTile change notification, now that we've done FB's
1962 : changes &= ~GCTile;
1965 1 0.0011 : fbValidateGC (pGC, changes, pDrawable);
1967 1 0.0011 : pGC->ops = (GCOps *) &exaOps;
1970 :static GCFuncs exaGCFuncs = {
1981 : * exaCreateGC makes a new GC and hooks up its funcs handler, so that
1982 : * exaValidateGC() will get called.
1985 :exaCreateGC (GCPtr pGC)
1987 : if (!fbCreateGC (pGC))
1990 : pGC->funcs = &exaGCFuncs;
1996 : * exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's
1997 : * screen private, before calling down to the next CloseSccreen.
2000 :exaCloseScreen(int i, ScreenPtr pScreen)
2002 : ExaScreenPriv(pScreen);
2004 : PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
2007 : pScreen->CreateGC = pExaScr->SavedCreateGC;
2008 : pScreen->CloseScreen = pExaScr->SavedCloseScreen;
2009 : pScreen->GetImage = pExaScr->SavedGetImage;
2010 : pScreen->GetSpans = pExaScr->SavedGetSpans;
2011 : pScreen->PaintWindowBackground = pExaScr->SavedPaintWindowBackground;
2012 : pScreen->PaintWindowBorder = pExaScr->SavedPaintWindowBorder;
2013 : pScreen->CreatePixmap = pExaScr->SavedCreatePixmap;
2014 : pScreen->DestroyPixmap = pExaScr->SavedDestroyPixmap;
2015 : pScreen->CopyWindow = pExaScr->SavedCopyWindow;
2018 : ps->Composite = pExaScr->SavedComposite;
2019 : ps->Glyphs = pExaScr->SavedGlyphs;
2025 : return (*pScreen->CloseScreen) (i, pScreen);
2029 : * This function allocates a driver structure for EXA drivers to fill in. By
2030 : * having EXA allocate the structure, the driver structure can be extended
2031 : * without breaking ABI between EXA and the drivers. The driver's
2032 : * responsibility is to check beforehand that the EXA module has a matching
2033 : * major number and sufficient minor. Drivers are responsible for freeing the
2034 : * driver structure using xfree().
2036 : * @return a newly allocated, zero-filled driver structure
2039 :exaDriverAlloc(void)
2041 : return xcalloc(1, sizeof(ExaDriverRec));
2045 : * @param pScreen screen being initialized
2046 : * @param pScreenInfo EXA driver record
2048 : * exaDriverInit sets up EXA given a driver record filled in by the driver.
2049 : * pScreenInfo should have been allocated by exaDriverAlloc(). See the
2050 : * comments in _ExaDriver for what must be filled in and what is optional.
2052 : * @return TRUE if EXA was successfully initialized.
2055 :exaDriverInit (ScreenPtr pScreen,
2056 : ExaDriverPtr pScreenInfo)
2058 : ExaScreenPrivPtr pExaScr;
2060 : PictureScreenPtr ps;
2063 : if (pScreenInfo->exa_major != EXA_VERSION_MAJOR ||
2064 : pScreenInfo->exa_minor > EXA_VERSION_MINOR)
2066 : LogMessage(X_ERROR, "EXA(%d): driver's EXA version requirements "
2067 : "(%d.%d) are incompatible with EXA version (%d.%d)\n",
2069 : pScreenInfo->exa_major, pScreenInfo->exa_minor,
2070 : EXA_VERSION_MAJOR, EXA_VERSION_MINOR);
2075 : ps = GetPictureScreenIfSet(pScreen);
2077 : if (exaGeneration != serverGeneration)
2079 : exaScreenPrivateIndex = AllocateScreenPrivateIndex();
2080 : exaPixmapPrivateIndex = AllocatePixmapPrivateIndex();
2081 : exaGeneration = serverGeneration;
2084 : pExaScr = xcalloc (sizeof (ExaScreenPrivRec), 1);
2087 : LogMessage(X_WARNING, "EXA(%d): Failed to allocate screen private\n",
2092 : pExaScr->info = pScreenInfo;
2094 : pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr;
2096 : pExaScr->migration = ExaMigrationAlways;
2098 : exaDDXDriverInit(pScreen);
2101 : * Replace various fb screen functions
2103 : pExaScr->SavedCloseScreen = pScreen->CloseScreen;
2104 : pScreen->CloseScreen = exaCloseScreen;
2106 : pExaScr->SavedCreateGC = pScreen->CreateGC;
2107 : pScreen->CreateGC = exaCreateGC;
2109 : pExaScr->SavedGetImage = pScreen->GetImage;
2110 : pScreen->GetImage = exaGetImage;
2112 : pExaScr->SavedGetSpans = pScreen->GetSpans;
2113 : pScreen->GetSpans = exaGetSpans;
2115 : pExaScr->SavedCopyWindow = pScreen->CopyWindow;
2116 : pScreen->CopyWindow = exaCopyWindow;
2118 : pExaScr->SavedPaintWindowBackground = pScreen->PaintWindowBackground;
2119 : pScreen->PaintWindowBackground = exaPaintWindow;
2121 : pExaScr->SavedPaintWindowBorder = pScreen->PaintWindowBorder;
2122 : pScreen->PaintWindowBorder = exaPaintWindow;
2124 : pScreen->BackingStoreFuncs.SaveAreas = ExaCheckSaveAreas;
2125 : pScreen->BackingStoreFuncs.RestoreAreas = ExaCheckRestoreAreas;
2128 : pExaScr->SavedComposite = ps->Composite;
2129 : ps->Composite = exaComposite;
2131 : pExaScr->SavedRasterizeTrapezoid = ps->RasterizeTrapezoid;
2132 : ps->RasterizeTrapezoid = exaRasterizeTrapezoid;
2134 : pExaScr->SavedAddTriangles = ps->AddTriangles;
2135 : ps->AddTriangles = exaAddTriangles;
2137 : pExaScr->SavedGlyphs = ps->Glyphs;
2138 : ps->Glyphs = exaGlyphs;
2143 : /* Re-register with the MI funcs, which don't allow shared pixmaps.
2144 : * Shared pixmaps are almost always a performance loss for us, but this
2145 : * still allows for SHM PutImage.
2147 : ShmRegisterFuncs(pScreen, NULL);
2150 : * Hookup offscreen pixmaps
2152 : if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
2153 : pExaScr->info->offScreenBase < pExaScr->info->memorySize)
2155 : if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex,
2156 : sizeof (ExaPixmapPrivRec))) {
2157 : LogMessage(X_WARNING,
2158 : "EXA(%d): Failed to allocate pixmap private\n",
2162 : pExaScr->SavedCreatePixmap = pScreen->CreatePixmap;
2163 : pScreen->CreatePixmap = exaCreatePixmap;
2165 : pExaScr->SavedDestroyPixmap = pScreen->DestroyPixmap;
2166 : pScreen->DestroyPixmap = exaDestroyPixmap;
2168 : LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
2170 : pExaScr->info->memorySize - pExaScr->info->offScreenBase);
2174 : LogMessage(X_INFO, "EXA(%d): No offscreen pixmaps\n", pScreen->myNum);
2175 : if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex, 0))
2179 : DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
2180 : pExaScr->info->memorySize));
2181 : if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
2182 : if (!exaOffscreenInit (pScreen)) {
2183 : LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
2189 : LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"
2190 : " operations:\n", pScreen->myNum);
2191 : assert(pScreenInfo->PrepareSolid != NULL);
2192 : LogMessage(X_INFO, " Solid\n");
2193 : assert(pScreenInfo->PrepareCopy != NULL);
2194 : LogMessage(X_INFO, " Copy\n");
2195 : if (pScreenInfo->PrepareComposite != NULL) {
2196 : LogMessage(X_INFO, " Composite (RENDER acceleration)\n");
2198 : if (pScreenInfo->UploadToScreen != NULL) {
2199 : LogMessage(X_INFO, " UploadToScreen\n");
2201 : if (pScreenInfo->DownloadFromScreen != NULL) {
2202 : LogMessage(X_INFO, " DownloadFromScreen\n");
2209 : * exaDriverFini tears down EXA on a given screen.
2211 : * @param pScreen screen being torn down.
2214 :exaDriverFini (ScreenPtr pScreen)
2216 : /*right now does nothing*/
2220 : * exaMarkSync() should be called after any asynchronous drawing by the hardware.
2222 : * @param pScreen screen which drawing occurred on
2224 : * exaMarkSync() sets a flag to indicate that some asynchronous drawing has
2225 : * happened and a WaitSync() will be necessary before relying on the contents of
2226 : * offscreen memory from the CPU's perspective. It also calls an optional
2227 : * driver MarkSync() callback, the return value of which may be used to do partial
2228 : * synchronization with the hardware in the future.
2230 :void exaMarkSync(ScreenPtr pScreen)
2231 22 0.0240 :{ /* exaMarkSync total: 88 0.0959 */
2232 10 0.0109 : ExaScreenPriv(pScreen);
2234 13 0.0142 : pExaScr->info->needsSync = TRUE;
2235 34 0.0370 : if (pExaScr->info->MarkSync != NULL) {
2236 : pExaScr->info->lastMarker = (*pExaScr->info->MarkSync)(pScreen);
2241 : * exaWaitSync() ensures that all drawing has been completed.
2243 : * @param pScreen screen being synchronized.
2245 : * Calls down into the driver to ensure that all previous drawing has completed.
2246 : * It should always be called before relying on the framebuffer contents
2247 : * reflecting previous drawing, from a CPU perspective.
2249 :void exaWaitSync(ScreenPtr pScreen)
2250 9 0.0098 :{ /* exaWaitSync total: 102 0.1111 */
2251 5 0.0054 : ExaScreenPriv(pScreen);
2253 45 0.0490 : if (pExaScr->info->needsSync && !pExaScr->swappedOut) {
2254 4 0.0044 : (*pExaScr->info->WaitMarker)(pScreen, pExaScr->info->lastMarker);
2255 22 0.0240 : pExaScr->info->needsSync = FALSE;
2259 * Total samples for file : "/home/cworth/src/xorg/xserver/exa/exa_render.c"
2266 : * Copyright © 2001 Keith Packard
2268 : * Partly based on code that is Copyright © The XFree86 Project Inc.
2270 : * Permission to use, copy, modify, distribute, and sell this software and its
2271 : * documentation for any purpose is hereby granted without fee, provided that
2272 : * the above copyright notice appear in all copies and that both that
2273 : * copyright notice and this permission notice appear in supporting
2274 : * documentation, and that the name of Keith Packard not be used in
2275 : * advertising or publicity pertaining to distribution of the software without
2276 : * specific, written prior permission. Keith Packard makes no
2277 : * representations about the suitability of this software for any purpose. It
2278 : * is provided "as is" without express or implied warranty.
2280 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
2281 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
2282 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
2283 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2284 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
2285 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2286 : * PERFORMANCE OF THIS SOFTWARE.
2289 :#ifdef HAVE_DIX_CONFIG_H
2290 :#include <dix-config.h>
2293 :#include <stdlib.h>
2295 :#include "exa_priv.h"
2298 :#include "mipict.h"
2300 :#if DEBUG_TRACE_FALL
2301 :static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
2309 : snprintf(string, n, "None");
2313 : switch (pict->format)
2315 : case PICT_a8r8g8b8:
2316 : snprintf(format, 20, "ARGB8888");
2319 : snprintf(format, 20, "RGB565 ");
2321 : case PICT_x1r5g5b5:
2322 : snprintf(format, 20, "RGB555 ");
2325 : snprintf(format, 20, "A8 ");
2328 : snprintf(format, 20, "A1 ");
2331 : snprintf(format, 20, "0x%x", (int)pict->format);
2335 : loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
2337 : snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
2338 : pict->pDrawable->height, pict->repeat ?
2341 : snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format, size);
2345 :exaPrintCompositeFallback(CARD8 op,
2351 : char srcdesc[40], maskdesc[40], dstdesc[40];
2356 : sprintf(sop, "Src");
2359 : sprintf(sop, "Over");
2362 : sprintf(sop, "0x%x", (int)op);
2366 : exaCompositeFallbackPictDesc(pSrc, srcdesc, 40);
2367 : exaCompositeFallbackPictDesc(pMask, maskdesc, 40);
2368 : exaCompositeFallbackPictDesc(pDst, dstdesc, 40);
2370 : ErrorF("Composite fallback: op %s, \n"
2374 : sop, srcdesc, maskdesc, dstdesc);
2376 :#endif /* DEBUG_TRACE_FALL */
2379 :exaOpReadsDestination (CARD8 op)
2380 1 0.0011 :{ /* exaOpReadsDestination total: 4 0.0044 */
2381 : /* FALSE (does not read destination) is the list of ops in the protocol
2382 : * document with "0" in the "Fb" column and no "Ab" in the "Fa" column.
2383 : * That's just Clear and Src. ReduceCompositeOp() will already have
2384 : * converted con/disjoint clear/src to Clear or Src.
2386 3 0.0033 : switch (op) {
2397 :exaGetPixelFromRGBA(CARD32 *pixel,
2404 : int rbits, bbits, gbits, abits;
2405 : int rshift, bshift, gshift, ashift;
2409 : if (!PICT_FORMAT_COLOR(format))
2412 : rbits = PICT_FORMAT_R(format);
2413 : gbits = PICT_FORMAT_G(format);
2414 : bbits = PICT_FORMAT_B(format);
2415 : abits = PICT_FORMAT_A(format);
2417 : if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
2420 : rshift = gshift + gbits;
2421 : ashift = rshift + rbits;
2422 : } else { /* PICT_TYPE_ABGR */
2425 : bshift = gshift + gbits;
2426 : ashift = bshift + bbits;
2429 : *pixel |= ( blue >> (16 - bbits)) << bshift;
2430 : *pixel |= ( red >> (16 - rbits)) << rshift;
2431 : *pixel |= (green >> (16 - gbits)) << gshift;
2432 : *pixel |= (alpha >> (16 - abits)) << ashift;
2438 :exaGetRGBAFromPixel(CARD32 pixel,
2445 : int rbits, bbits, gbits, abits;
2446 : int rshift, bshift, gshift, ashift;
2448 : if (!PICT_FORMAT_COLOR(format))
2451 : rbits = PICT_FORMAT_R(format);
2452 : gbits = PICT_FORMAT_G(format);
2453 : bbits = PICT_FORMAT_B(format);
2454 : abits = PICT_FORMAT_A(format);
2456 : if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
2459 : rshift = gshift + gbits;
2460 : ashift = rshift + rbits;
2461 : } else { /* PICT_TYPE_ABGR */
2464 : bshift = gshift + gbits;
2465 : ashift = bshift + bbits;
2468 : *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
2469 : while (rbits < 16) {
2470 : *red |= *red >> rbits;
2474 : *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
2475 : while (gbits < 16) {
2476 : *green |= *green >> gbits;
2480 : *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
2481 : while (bbits < 16) {
2482 : *blue |= *blue >> bbits;
2487 : *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
2488 : while (abits < 16) {
2489 : *alpha |= *alpha >> abits;
2499 :exaTryDriverSolidFill(PicturePtr pSrc,
2508 : ExaScreenPriv (pDst->pDrawable->pScreen);
2512 : int dst_off_x, dst_off_y;
2513 : PixmapPtr pSrcPix, pDstPix;
2515 : CARD16 red, green, blue, alpha;
2516 : ExaMigrationRec pixmaps[1];
2518 : xDst += pDst->pDrawable->x;
2519 : yDst += pDst->pDrawable->y;
2520 : xSrc += pSrc->pDrawable->x;
2521 : ySrc += pSrc->pDrawable->y;
2523 : if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst,
2524 : xSrc, ySrc, 0, 0, xDst, yDst,
2528 : pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
2529 : pixel = exaGetPixmapFirstPixel (pSrcPix);
2531 : pixmaps[0].as_dst = TRUE;
2532 : pixmaps[0].as_src = FALSE;
2533 : pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
2534 : exaDoMigration(pixmaps, 1, TRUE);
2536 : pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
2538 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2542 : if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
2545 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2549 : if (!exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
2552 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2556 : if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
2558 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2562 : nbox = REGION_NUM_RECTS(®ion);
2563 : pbox = REGION_RECTS(®ion);
2567 : (*pExaScr->info->Solid) (pDstPix,
2568 : pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
2569 : pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
2573 : (*pExaScr->info->DoneSolid) (pDstPix);
2574 : exaMarkSync(pDst->pDrawable->pScreen);
2576 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2581 :exaTryDriverComposite(CARD8 op,
2593 49 0.0534 :{ /* exaTryDriverComposite total: 348 0.3791 */
2594 23 0.0251 : ExaScreenPriv (pDst->pDrawable->pScreen);
2598 : int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
2599 : PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
2600 : struct _Pixmap scratch;
2601 : ExaMigrationRec pixmaps[3];
2603 10 0.0109 : pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
2604 5 0.0054 : pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
2605 2 0.0022 : if (pMask)
2606 2 0.0022 : pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
2608 : /* Bail if we might exceed coord limits by rendering from/to these. We
2609 : * should really be making some scratch pixmaps with offsets and coords
2610 : * adjusted to deal with this, but it hasn't been done yet.
2612 24 0.0261 : if (pSrcPix->drawable.width > pExaScr->info->maxX ||
2613 : pSrcPix->drawable.height > pExaScr->info->maxY ||
2614 : pDstPix->drawable.width > pExaScr->info->maxX ||
2615 : pDstPix->drawable.height > pExaScr->info->maxY ||
2616 : (pMask && (pMaskPix->drawable.width > pExaScr->info->maxX ||
2617 : pMaskPix->drawable.height > pExaScr->info->maxY)))
2622 14 0.0153 : xDst += pDst->pDrawable->x;
2623 2 0.0022 : yDst += pDst->pDrawable->y;
2626 7 0.0076 : xMask += pMask->pDrawable->x;
2627 10 0.0109 : yMask += pMask->pDrawable->y;
2630 9 0.0098 : xSrc += pSrc->pDrawable->x;
2631 2 0.0022 : ySrc += pSrc->pDrawable->y;
2633 23 0.0251 : if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
2634 : xSrc, ySrc, xMask, yMask, xDst, yDst,
2638 38 0.0414 : if (pExaScr->info->CheckComposite &&
2639 : !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
2641 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2645 : pixmaps[0].as_dst = TRUE;
2646 : pixmaps[0].as_src = exaOpReadsDestination(op);
2647 1 0.0011 : pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
2648 : pixmaps[1].as_dst = FALSE;
2649 : pixmaps[1].as_src = TRUE;
2650 3 0.0033 : pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
2652 : pixmaps[2].as_dst = FALSE;
2653 : pixmaps[2].as_src = TRUE;
2654 6 0.0065 : pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
2655 2 0.0022 : exaDoMigration(pixmaps, 3, TRUE);
2657 2 0.0022 : exaDoMigration(pixmaps, 2, TRUE);
2660 4 0.0044 : pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
2662 3 0.0033 : pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
2664 2 0.0022 : pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
2667 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2671 1 0.0011 : if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->UploadToScratch) {
2672 : pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
2673 : if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
2674 : pSrcPix = &scratch;
2675 : } else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->UploadToScratch) {
2676 : pMaskPix = exaGetDrawablePixmap (pMask->pDrawable);
2677 : if ((*pExaScr->info->UploadToScratch) (pMaskPix, &scratch))
2678 : pMaskPix = &scratch;
2681 2 0.0022 : if (!pSrcPix || (pMask && !pMaskPix)) {
2682 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2686 9 0.0098 : if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
2687 : pMaskPix, pDstPix))
2689 5 0.0054 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2693 1 0.0011 : nbox = REGION_NUM_RECTS(®ion);
2694 : pbox = REGION_RECTS(®ion);
2697 16 0.0174 : yMask -= yDst;
2702 5 0.0054 : while (nbox--)
2704 26 0.0283 : (*pExaScr->info->Composite) (pDstPix,
2705 : pbox->x1 + xSrc + src_off_x,
2706 : pbox->y1 + ySrc + src_off_y,
2707 : pbox->x1 + xMask + mask_off_x,
2708 : pbox->y1 + yMask + mask_off_y,
2709 : pbox->x1 + dst_off_x,
2710 : pbox->y1 + dst_off_y,
2711 : pbox->x2 - pbox->x1,
2712 : pbox->y2 - pbox->y1);
2715 3 0.0033 : (*pExaScr->info->DoneComposite) (pDstPix);
2716 12 0.0131 : exaMarkSync(pDst->pDrawable->pScreen);
2718 7 0.0076 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2723 : * exaTryMagicTwoPassCompositeHelper implements PictOpOver using two passes of
2724 : * simpler operations PictOpOutReverse and PictOpAdd. Mainly used for component
2725 : * alpha and limited 1-tmu cards.
2727 : * From http://anholt.livejournal.com/32058.html:
2729 : * The trouble is that component-alpha rendering requires two different sources
2730 : * for blending: one for the source value to the blender, which is the
2731 : * per-channel multiplication of source and mask, and one for the source alpha
2732 : * for multiplying with the destination channels, which is the multiplication
2733 : * of the source channels by the mask alpha. So the equation for Over is:
2735 : * dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A
2736 : * dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R
2737 : * dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G
2738 : * dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B
2740 : * But we can do some simpler operations, right? How about PictOpOutReverse,
2741 : * which has a source factor of 0 and dest factor of (1 - source alpha). We
2742 : * can get the source alpha value (srca.X = src.A * mask.X) out of the texture
2743 : * blenders pretty easily. So we can do a component-alpha OutReverse, which
2746 : * dst.A = 0 + (1 - (src.A * mask.A)) * dst.A
2747 : * dst.R = 0 + (1 - (src.A * mask.R)) * dst.R
2748 : * dst.G = 0 + (1 - (src.A * mask.G)) * dst.G
2749 : * dst.B = 0 + (1 - (src.A * mask.B)) * dst.B
2751 : * OK. And if an op doesn't use the source alpha value for the destination
2752 : * factor, then we can do the channel multiplication in the texture blenders
2753 : * to get the source value, and ignore the source alpha that we wouldn't use.
2754 : * We've supported this in the Radeon driver for a long time. An example would
2755 : * be PictOpAdd, which does:
2757 : * dst.A = src.A * mask.A + dst.A
2758 : * dst.R = src.R * mask.R + dst.R
2759 : * dst.G = src.G * mask.G + dst.G
2760 : * dst.B = src.B * mask.B + dst.B
2762 : * Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right
2763 : * after it, we get:
2765 : * dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A)
2766 : * dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R)
2767 : * dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G)
2768 : * dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B)
2772 :exaTryMagicTwoPassCompositeHelper(CARD8 op,
2785 : ExaScreenPriv (pDst->pDrawable->pScreen);
2786 : DrawablePtr pDstDraw = pDst->pDrawable;
2787 : PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDstDraw);
2790 : assert(op == PictOpOver);
2792 : if (pExaScr->info->CheckComposite &&
2793 : (!(*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
2795 : !(*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))
2800 : /* Now, we think we should be able to accelerate this operation. First,
2801 : * composite the destination to be the destination times the source alpha
2804 : exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
2805 : xDst, yDst, width, height);
2807 : exaGetDrawableDeltas(pDstDraw, pDstPixmap, &xoff, &yoff);
2808 : xoff += pDstDraw->x;
2809 : yoff += pDstDraw->y;
2810 : exaPixmapDirty(pDstPixmap, xDst + xoff, yDst + yoff, xDst + xoff + width,
2811 : yDst + yoff + height);
2813 : /* Then, add in the source value times the destination alpha factors (1.0).
2815 : exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
2816 : xDst, yDst, width, height);
2822 :exaComposite(CARD8 op,
2834 48 0.0523 :{ /* exaComposite total: 354 0.3856 */
2835 39 0.0425 : ExaScreenPriv (pDst->pDrawable->pScreen);
2837 5 0.0054 : Bool saveSrcRepeat = pSrc->repeat;
2838 3 0.0033 : Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
2839 : ExaMigrationRec pixmaps[3];
2841 : PixmapPtr pSrcPixmap = NULL;
2843 : pixmaps[0].as_dst = TRUE;
2844 : pixmaps[0].as_src = exaOpReadsDestination(op);
2845 2 0.0022 : pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
2847 4 0.0044 : if (pSrc->pDrawable) {
2848 3 0.0033 : pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
2849 : pixmaps[npixmaps].as_dst = FALSE;
2850 : pixmaps[npixmaps].as_src = TRUE;
2851 : pixmaps[npixmaps].pPix = pSrcPixmap;
2855 1 0.0011 : if (pMask && pMask->pDrawable) {
2856 : pixmaps[npixmaps].as_dst = FALSE;
2857 : pixmaps[npixmaps].as_src = TRUE;
2858 : pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
2862 : /* We currently don't support acceleration of gradients, or other pictures
2863 : * with a NULL pDrawable.
2865 14 0.0153 : if (pExaScr->swappedOut ||
2866 : pSrc->pDrawable == NULL || (pMask != NULL && pMask->pDrawable == NULL))
2871 : /* Remove repeat in source if useless */
2872 18 0.0196 : if (pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
2873 : (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
2874 : (ySrc + height) <= pSrc->pDrawable->height)
2877 3 0.0033 : if (!pMask)
2879 3 0.0033 : if ((op == PictOpSrc &&
2880 : ((pSrc->format == pDst->format) ||
2881 : (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
2882 : (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
2883 : (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
2884 : pSrc->format == pDst->format &&
2885 : (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8)))
2887 : if (pSrc->pDrawable->width == 1 &&
2888 : pSrc->pDrawable->height == 1 &&
2891 : ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
2896 : else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform)
2900 : xDst += pDst->pDrawable->x;
2901 : yDst += pDst->pDrawable->y;
2902 : xSrc += pSrc->pDrawable->x;
2903 : ySrc += pSrc->pDrawable->y;
2905 : if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
2906 : xSrc, ySrc, xMask, yMask, xDst,
2907 : yDst, width, height))
2911 : exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
2912 : REGION_RECTS(®ion), REGION_NUM_RECTS(®ion),
2913 : xSrc - xDst, ySrc - yDst,
2914 : FALSE, FALSE, 0, NULL);
2915 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2918 : else if (pSrcPixmap && !pSrc->transform &&
2919 : pSrc->repeatType == RepeatNormal)
2922 : DDXPointRec srcOrg;
2924 : /* Let's see if the driver can do the repeat in one go */
2925 : if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
2928 : ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
2929 : ySrc, xMask, yMask, xDst, yDst,
2935 : /* Now see if we can use exaFillRegionTiled() */
2936 : xDst += pDst->pDrawable->x;
2937 : yDst += pDst->pDrawable->y;
2938 : xSrc += pSrc->pDrawable->x;
2939 : ySrc += pSrc->pDrawable->y;
2941 : if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc,
2942 : ySrc, xMask, yMask, xDst, yDst,
2946 : srcOrg.x = (xSrc - xDst) % pSrcPixmap->drawable.width;
2947 : srcOrg.y = (ySrc - yDst) % pSrcPixmap->drawable.height;
2949 : ret = exaFillRegionTiled(pDst->pDrawable, ®ion, pSrcPixmap,
2950 : &srcOrg, FB_ALLONES, GXcopy);
2952 : REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
2960 : /* Remove repeat in mask if useless */
2961 12 0.0131 : if (pMask && pMask->repeat && !pMask->transform && xMask >= 0 &&
2962 : (xMask + width) <= pMask->pDrawable->width && yMask >= 0 &&
2963 : (yMask + height) <= pMask->pDrawable->height)
2964 : pMask->repeat = 0;
2966 37 0.0403 : if (pExaScr->info->PrepareComposite &&
2967 : (!pSrc->repeat || pSrc->repeatType == RepeatNormal) &&
2968 : (!pMask || !pMask->repeat || pMask->repeatType == RepeatNormal) &&
2969 : !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
2973 59 0.0643 : ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
2974 : yMask, xDst, yDst, width, height);
2975 3 0.0033 : if (ret == 1)
2978 : /* For generic masks and solid src pictures, mach64 can do Over in two
2979 : * passes, similar to the component-alpha case.
2981 8 0.0087 : isSrcSolid = pSrc->pDrawable->width == 1 &&
2982 : pSrc->pDrawable->height == 1 &&
2985 : /* If we couldn't do the Composite in a single pass, and it was a
2986 : * component-alpha Over, see if we can do it in two passes with
2987 : * an OutReverse and then an Add.
2989 2 0.0022 : if (ret == -1 && op == PictOpOver && pMask &&
2990 : (pMask->componentAlpha || isSrcSolid)) {
2991 : ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst,
2993 : xMask, yMask, xDst, yDst,
3002 :#if DEBUG_TRACE_FALL
3003 : exaPrintCompositeFallback (op, pSrc, pMask, pDst);
3006 : exaDoMigration(pixmaps, npixmaps, FALSE);
3007 : ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
3008 : xMask, yMask, xDst, yDst, width, height);
3011 15 0.0163 : pSrc->repeat = saveSrcRepeat;
3012 3 0.0033 : if (pMask)
3013 18 0.0196 : pMask->repeat = saveMaskRepeat;
3017 :#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
3020 : * exaRasterizeTrapezoid is just a wrapper around the software implementation.
3022 : * The trapezoid specification is basically too hard to be done in hardware (at
3023 : * the very least, without programmability), so we just do the appropriate
3024 : * Prepare/FinishAccess for it before using fbtrap.c.
3027 :exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
3028 : int x_off, int y_off)
3029 :{ /* exaRasterizeTrapezoid total: 2 0.0022 */
3030 : DrawablePtr pDraw = pPicture->pDrawable;
3031 : ExaMigrationRec pixmaps[1];
3034 : pixmaps[0].as_dst = TRUE;
3035 : pixmaps[0].as_src = TRUE;
3036 1 0.0011 : pixmaps[0].pPix = exaGetDrawablePixmap (pDraw);
3037 1 0.0011 : exaDoMigration(pixmaps, 1, FALSE);
3039 : exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
3040 : fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
3041 : exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
3042 : exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
3043 : pDraw->x + xoff + pDraw->width,
3044 : pDraw->y + yoff + pDraw->height);
3045 : exaFinishAccess(pDraw, EXA_PREPARE_DEST);
3049 : * exaAddTriangles does migration and syncing before dumping down to the
3050 : * software implementation.
3053 :exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
3056 : DrawablePtr pDraw = pPicture->pDrawable;
3057 : ExaMigrationRec pixmaps[1];
3060 : pixmaps[0].as_dst = TRUE;
3061 : pixmaps[0].as_src = TRUE;
3062 : pixmaps[0].pPix = exaGetDrawablePixmap (pDraw);
3063 : exaDoMigration(pixmaps, 1, FALSE);
3065 : exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
3066 : fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
3067 : exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
3068 : exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
3069 : pDraw->x + xoff + pDraw->width,
3070 : pDraw->y + yoff + pDraw->height);
3071 : exaFinishAccess(pDraw, EXA_PREPARE_DEST);
3075 : * Returns TRUE if the glyphs in the lists intersect. Only checks based on
3076 : * bounding box, which appears to be good enough to catch most cases at least.
3079 :exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
3081 : int x1, x2, y1, y2;
3086 : Bool first = TRUE;
3096 : glyph = *glyphs++;
3098 : if (glyph->info.width == 0 || glyph->info.height == 0) {
3099 : x += glyph->info.xOff;
3100 : y += glyph->info.yOff;
3104 : x1 = x - glyph->info.x;
3105 : if (x1 < MINSHORT)
3107 : y1 = y - glyph->info.y;
3108 : if (y1 < MINSHORT)
3110 : x2 = x1 + glyph->info.width;
3111 : if (x2 > MAXSHORT)
3113 : y2 = y1 + glyph->info.height;
3114 : if (y2 > MAXSHORT)
3124 : if (x1 < extents.x2 && x2 > extents.x1 &&
3125 : y1 < extents.y2 && y2 > extents.y1)
3130 : if (x1 < extents.x1)
3132 : if (x2 > extents.x2)
3134 : if (y1 < extents.y1)
3136 : if (y2 > extents.y2)
3139 : x += glyph->info.xOff;
3140 : y += glyph->info.yOff;
3147 :/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
3148 : * issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
3149 : * migrate these pixmaps. So, instead we create a pixmap at the beginning of
3150 : * the loop and upload each glyph into the pixmap before compositing.
3153 :exaGlyphs (CARD8 op,
3156 : PictFormatPtr maskFormat,
3160 : GlyphListPtr list,
3162 1 0.0011 :{ /* exaGlyphs total: 185 0.2015 */
3163 : ExaScreenPriv (pDst->pDrawable->pScreen);
3164 : PixmapPtr pPixmap = NULL;
3165 : PicturePtr pPicture;
3166 : PixmapPtr pMaskPixmap = NULL;
3167 1 0.0011 : PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
3169 : ScreenPtr pScreen = pDst->pDrawable->pScreen;
3170 : int width = 0, height = 0;
3171 : int x, y, x1, y1, xoff, yoff;
3172 1 0.0011 : int xDst = list->xOff, yDst = list->yOff;
3176 : CARD32 component_alpha;
3178 : /* If we have a mask format but it's the same as all the glyphs and
3179 : * the glyphs don't intersect, we can avoid accumulating the glyphs in the
3180 : * temporary picture.
3182 : if (maskFormat != NULL) {
3183 : Bool sameFormat = TRUE;
3186 1 0.0011 : for (i = 0; i < nlist; i++) {
3187 : if (maskFormat->format != list[i].format->format) {
3188 : sameFormat = FALSE;
3193 : if (!exaGlyphsIntersect(nlist, list, glyphs)) {
3194 : maskFormat = NULL;
3199 : /* If the driver doesn't support accelerated composite, there's no point in
3200 : * going to this extra work. Assume that any driver that supports Composite
3201 : * will be able to support component alpha using the two-pass helper.
3203 : if (!pExaScr->info->PrepareComposite)
3205 : miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
3214 1 0.0011 : miGlyphExtents (nlist, list, glyphs, &extents);
3216 : extents.x1 = max(extents.x1, 0);
3217 : extents.y1 = max(extents.y1, 0);
3218 : extents.x2 = min(extents.x2, pDst->pDrawable->width);
3219 1 0.0011 : extents.y2 = min(extents.y2, pDst->pDrawable->height);
3221 : if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
3223 : width = extents.x2 - extents.x1;
3224 : height = extents.y2 - extents.y1;
3225 : pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
3226 : maskFormat->depth);
3229 : component_alpha = NeedsComponent(maskFormat->format);
3230 1 0.0011 : pMask = CreatePicture (0, &pMaskPixmap->drawable,
3231 : maskFormat, CPComponentAlpha, &component_alpha,
3232 : serverClient, &error);
3235 : (*pScreen->DestroyPixmap) (pMaskPixmap);
3238 : ValidatePicture(pMask);
3239 : pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
3240 : ValidateGC (&pMaskPixmap->drawable, pGC);
3243 : rect.width = width;
3244 : rect.height = height;
3245 1 0.0011 : (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
3246 : exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
3247 : FreeScratchGC (pGC);
3258 : exaGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &xoff, &yoff);
3263 : int maxwidth = 0, maxheight = 0, i;
3264 : ExaMigrationRec pixmaps[1];
3265 : PixmapPtr pScratchPixmap = NULL;
3270 : for (i = 0; i < n; i++) {
3271 14 0.0153 : if (glyphs[i]->info.width > maxwidth)
3272 : maxwidth = glyphs[i]->info.width;
3273 : if (glyphs[i]->info.height > maxheight)
3274 : maxheight = glyphs[i]->info.height;
3276 1 0.0011 : if (maxwidth == 0 || maxheight == 0) {
3281 : glyph = *glyphs++;
3282 : x += glyph->info.xOff;
3283 : y += glyph->info.yOff;
3289 : /* Create the (real) temporary pixmap to store the current glyph in */
3290 1 0.0011 : pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight,
3291 : list->format->depth);
3295 : /* Create a temporary picture to wrap the temporary pixmap, so it can be
3296 : * used as a source for Composite.
3298 : component_alpha = NeedsComponent(list->format->format);
3299 : pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
3300 : CPComponentAlpha, &component_alpha,
3301 : serverClient, &error);
3303 : (*pScreen->DestroyPixmap) (pPixmap);
3306 : ValidatePicture(pPicture);
3308 : /* Give the temporary pixmap an initial kick towards the screen, so
3309 : * it'll stick there.
3311 : pixmaps[0].as_dst = TRUE;
3312 : pixmaps[0].as_src = TRUE;
3313 : pixmaps[0].pPix = pPixmap;
3314 : exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
3316 1 0.0011 : while (n--)
3318 1 0.0011 : GlyphPtr glyph = *glyphs++;
3319 : pointer glyphdata = (pointer) (glyph + 1);
3320 5 0.0054 : DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
3322 : x1 = x - glyph->info.x;
3323 8 0.0087 : y1 = y - glyph->info.y;
3325 7 0.0076 : if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
3326 : (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
3329 2 0.0022 : (*pScreen->ModifyPixmapHeader) (pScratchPixmap,
3330 : glyph->info.width,
3331 : glyph->info.height,
3332 : 0, 0, -1, glyphdata);
3334 : /* Copy the glyph data into the proper pixmap instead of a fake.
3335 : * First we try to use UploadToScreen, if we can, then we fall back
3336 : * to a plain exaCopyArea in case of failure.
3338 5 0.0054 : if (pExaScr->info->UploadToScreen &&
3339 : exaPixmapIsOffscreen(pPixmap) &&
3340 : (*pExaScr->info->UploadToScreen) (pPixmap, 0, 0,
3341 : glyph->info.width,
3342 : glyph->info.height,
3344 : PixmapBytePad(glyph->info.width,
3345 : list->format->depth)))
3347 : exaMarkSync (pScreen);
3349 : /* Set up the scratch pixmap/GC for doing a CopyArea. */
3350 : if (pScratchPixmap == NULL) {
3351 : /* Get a scratch pixmap to wrap the original glyph data */
3352 2 0.0022 : pScratchPixmap = GetScratchPixmapHeader (pScreen,
3353 : glyph->info.width,
3354 : glyph->info.height,
3355 : list->format->depth,
3356 : list->format->depth,
3358 : if (!pScratchPixmap) {
3359 : FreePicture(pPicture, 0);
3360 : (*pScreen->DestroyPixmap) (pPixmap);
3364 : /* Get a scratch GC with which to copy the glyph data from
3365 : * scratch to temporary
3367 : pGC = GetScratchGC (list->format->depth, pScreen);
3368 1 0.0011 : ValidateGC (&pPixmap->drawable, pGC);
3370 2 0.0022 : (*pScreen->ModifyPixmapHeader) (pScratchPixmap,
3371 : glyph->info.width,
3372 : glyph->info.height,
3373 : 0, 0, -1, glyphdata);
3374 5 0.0054 : pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
3377 7 0.0076 : exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
3378 : 0, 0, glyph->info.width, glyph->info.height, 0, 0);
3381 5 0.0054 : exaPixmapDirty (pPixmap, 0, 0,
3382 : glyph->info.width, glyph->info.height);
3384 5 0.0054 : if (maskFormat)
3386 4 0.0044 : exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
3387 : x1, y1, glyph->info.width, glyph->info.height);
3388 2 0.0022 : exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width,
3389 : y1 + glyph->info.height);
3393 13 0.0142 : exaComposite (op, pSrc, pPicture, pDst,
3394 : xSrc + x1 - xDst, ySrc + y1 - yDst,
3395 : 0, 0, x1, y1, glyph->info.width,
3396 : glyph->info.height);
3397 11 0.0120 : x1 += pDst->pDrawable->x + xoff;
3398 5 0.0054 : y1 += pDst->pDrawable->y + yoff;
3399 3 0.0033 : exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
3400 : y1 + glyph->info.height);
3403 3 0.0033 : x += glyph->info.xOff;
3404 2 0.0022 : y += glyph->info.yOff;
3408 : FreeScratchGC (pGC);
3409 1 0.0011 : FreePicture ((pointer) pPicture, 0);
3410 : (*pScreen->DestroyPixmap) (pPixmap);
3411 : if (pScratchPixmap != NULL)
3412 : FreeScratchPixmapHeader (pScratchPixmap);
3418 1 0.0011 : exaComposite (op, pSrc, pMask, pDst, xSrc + x - xDst, ySrc + y - yDst,
3419 : 0, 0, x, y, width, height);
3420 : FreePicture ((pointer) pMask, (XID) 0);
3421 : (*pScreen->DestroyPixmap) (pMaskPixmap);
3425 * Total samples for file : "interp.c"
3430 <credited to line zero> 753 0.8203 :
3431 /* __i686.get_pc_thunk.cx total: 1 0.0011 */
3432 /* __i686.get_pc_thunk.bx total: 44 0.0479 */
3433 /* _nl_load_locale_from_archive total: 1 0.0011 */
3434 /* _itoa_word total: 1 0.0011 */
3435 /* __find_specmb total: 2 0.0022 */
3436 /* _IO_old_init total: 1 0.0011 */
3437 /* _IO_str_init_static_internal total: 1 0.0011 */
3438 /* _int_free total: 227 0.2473 */
3439 /* _int_malloc total: 460 0.5011 */
3440 /* _int_realloc total: 10 0.0109 */
3441 /* __close_nocancel total: 1 0.0011 */
3442 /* __read_nocancel total: 3 0.0033 */
3443 /* __xstat32_conv total: 1 0.0011 */
3445 * Total samples for file : "exa_unaccel.c"
3450 <credited to line zero> 590 0.6427 :
3451 /* __i686.get_pc_thunk.cx total: 14 0.0153 */
3452 /* __i686.get_pc_thunk.bx total: 576 0.6275 */
3454 * Total samples for file : "/home/cworth/src/xorg/xserver/exa/exa_offscreen.c"
3461 : * Copyright © 2003 Anders Carlsson
3463 : * Permission to use, copy, modify, distribute, and sell this software and its
3464 : * documentation for any purpose is hereby granted without fee, provided that
3465 : * the above copyright notice appear in all copies and that both that
3466 : * copyright notice and this permission notice appear in supporting
3467 : * documentation, and that the name of Anders Carlsson not be used in
3468 : * advertising or publicity pertaining to distribution of the software without
3469 : * specific, written prior permission. Anders Carlsson makes no
3470 : * representations about the suitability of this software for any purpose. It
3471 : * is provided "as is" without express or implied warranty.
3473 : * ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
3474 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
3475 : * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
3476 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
3477 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
3478 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
3479 : * PERFORMANCE OF THIS SOFTWARE.
3483 : * This allocator allocates blocks of memory by maintaining a list of areas
3484 : * and a score for each area. As an area is marked used, its score is
3485 : * incremented, and periodically all of the areas have their scores decayed by
3486 : * a fraction. When allocating, the contiguous block of areas with the minimum
3487 : * score is found and evicted in order to make room for the new allocation.
3490 :#include "exa_priv.h"
3492 :#include <limits.h>
3493 :#include <assert.h>
3494 :#include <stdlib.h>
3496 :#if DEBUG_OFFSCREEN
3497 :#define DBG_OFFSCREEN(a) ErrorF a
3499 :#define DBG_OFFSCREEN(a)
3502 :#if DEBUG_OFFSCREEN
3504 :ExaOffscreenValidate (ScreenPtr pScreen)
3506 : ExaScreenPriv (pScreen);
3507 : ExaOffscreenArea *prev = 0, *area;
3509 : assert (pExaScr->info->offScreenAreas->base_offset ==
3510 : pExaScr->info->offScreenBase);
3511 : for (area = pExaScr->info->offScreenAreas; area; area = area->next)
3513 : assert (area->offset >= area->base_offset &&
3514 : area->offset < (area->base_offset + area->size));
3516 : assert (prev->base_offset + prev->size == area->base_offset);
3519 : assert (prev->base_offset + prev->size == pExaScr->info->memorySize);
3522 :#define ExaOffscreenValidate(s)
3525 :static ExaOffscreenArea *
3526 :ExaOffscreenKickOut (ScreenPtr pScreen, ExaOffscreenArea *area)
3529 : (*area->save) (pScreen, area);
3530 : return exaOffscreenFree (pScreen, area);
3534 : * exaOffscreenAlloc allocates offscreen memory
3536 : * @param pScreen current screen
3537 : * @param size size in bytes of the allocation
3538 : * @param align byte alignment requirement for the offset of the allocated area
3539 : * @param locked whether the allocated area is locked and can't be kicked out
3540 : * @param save callback for when the area is evicted from memory
3541 : * @param privdata private data for the save callback.
3543 : * Allocates offscreen memory from the device associated with pScreen. size
3544 : * and align deteremine where and how large the allocated area is, and locked
3545 : * will mark whether it should be held in card memory. privdata may be any
3546 : * pointer for the save callback when the area is removed.
3548 : * Note that locked areas do get evicted on VT switch unless the driver
3549 : * requested version 2.1 or newer behavior. In that case, the save callback is
3553 :exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
3555 : ExaOffscreenSaveProc save,
3557 2 0.0022 :{ /* exaOffscreenAlloc total: 68 0.0741 */
3558 : ExaOffscreenArea *area, *begin, *best;
3559 1 0.0011 : ExaScreenPriv (pScreen);
3560 : int tmp, real_size = 0, best_score;
3561 :#if DEBUG_OFFSCREEN
3562 : static int number = 0;
3563 : ErrorF("================= ============ allocating a new pixmap %d\n", ++number);
3566 : ExaOffscreenValidate (pScreen);
3567 1 0.0011 : if (!align)
3572 : DBG_OFFSCREEN (("Alloc 0x%x -> EMPTY\n", size));
3576 : /* throw out requests that cannot fit */
3577 2 0.0022 : if (size > (pExaScr->info->memorySize - pExaScr->info->offScreenBase))
3579 : DBG_OFFSCREEN (("Alloc 0x%x vs (0x%lx) -> TOBIG\n", size,
3580 : pExaScr->info->memorySize -
3581 : pExaScr->info->offScreenBase));
3585 : /* Try to find a free space that'll fit. */
3586 11 0.0120 : for (area = pExaScr->info->offScreenAreas; area; area = area->next)
3588 : /* skip allocated areas */
3589 11 0.0120 : if (area->state != ExaOffscreenAvail)
3592 : /* adjust size to match alignment requirement */
3594 2 0.0022 : tmp = area->base_offset % align;
3595 31 0.0338 : if (tmp)
3596 : real_size += (align - tmp);
3598 : /* does it fit? */
3599 : if (real_size <= area->size)
3606 : * Kick out existing users to make space.
3608 : * First, locate a region which can hold the desired object.
3611 : /* prev points at the first object to boot */
3613 : best_score = INT_MAX;
3614 : for (begin = pExaScr->info->offScreenAreas; begin != NULL;
3615 : begin = begin->next)
3618 : ExaOffscreenArea *scan;
3620 : if (begin->state == ExaOffscreenLocked)
3623 : /* adjust size needed to account for alignment loss for this area */
3625 : tmp = begin->base_offset % align;
3627 : real_size += (align - tmp);
3631 : /* now see if we can make room here, and how "costly" it'll be. */
3632 : for (scan = begin; scan != NULL; scan = scan->next)
3634 : if (scan->state == ExaOffscreenLocked) {
3635 : /* Can't make room here, start after this locked area. */
3639 : /* Score should only be non-zero for ExaOffscreenRemovable */
3640 : score += scan->score;
3641 : avail += scan->size;
3642 : if (avail >= real_size)
3645 : /* Is it the best option we've found so far? */
3646 : if (avail >= real_size && score < best_score) {
3648 : best_score = score;
3654 : DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size));
3655 : /* Could not allocate memory */
3656 : ExaOffscreenValidate (pScreen);
3660 : /* adjust size needed to account for alignment loss for this area */
3662 : tmp = area->base_offset % align;
3664 : real_size += (align - tmp);
3667 : * Kick out first area if in use
3669 : if (area->state != ExaOffscreenAvail)
3670 : area = ExaOffscreenKickOut (pScreen, area);
3672 : * Now get the system to merge the other needed areas together
3674 : while (area->size < real_size)
3676 : assert (area->next && area->next->state == ExaOffscreenRemovable);
3677 : (void) ExaOffscreenKickOut (pScreen, area->next);
3681 : /* save extra space in new area */
3682 1 0.0011 : if (real_size < area->size)
3684 : ExaOffscreenArea *new_area = xalloc (sizeof (ExaOffscreenArea));
3687 : new_area->base_offset = area->base_offset + real_size;
3688 : new_area->offset = new_area->base_offset;
3689 : new_area->size = area->size - real_size;
3690 : new_area->state = ExaOffscreenAvail;
3691 : new_area->save = NULL;
3692 : new_area->score = 0;
3693 : new_area->next = area->next;
3694 1 0.0011 : area->next = new_area;
3695 : area->size = real_size;
3698 : * Mark this area as in use
3701 : area->state = ExaOffscreenLocked;
3703 : area->state = ExaOffscreenRemovable;
3704 : area->privData = privData;
3705 : area->save = save;
3707 : area->offset = (area->base_offset + align - 1);
3708 5 0.0054 : area->offset -= area->offset % align;
3710 : ExaOffscreenValidate (pScreen);
3712 : DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x (0x%x)\n", size,
3713 : area->base_offset, area->offset));
3718 : * Ejects all offscreen areas, and uninitializes the offscreen memory manager.
3721 :ExaOffscreenSwapOut (ScreenPtr pScreen)
3723 : ExaScreenPriv (pScreen);
3725 : ExaOffscreenValidate (pScreen);
3726 : /* loop until a single free area spans the space */
3729 : ExaOffscreenArea *area = pExaScr->info->offScreenAreas;
3733 : if (area->state == ExaOffscreenAvail)
3735 : area = area->next;
3739 : assert (area->state != ExaOffscreenAvail);
3740 : (void) ExaOffscreenKickOut (pScreen, area);
3741 : ExaOffscreenValidate (pScreen);
3743 : ExaOffscreenValidate (pScreen);
3744 : ExaOffscreenFini (pScreen);
3747 :/** Ejects all pixmaps managed by EXA. */
3749 :ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
3751 : ExaScreenPriv (pScreen);
3753 : ExaOffscreenValidate (pScreen);
3754 : /* loop until a single free area spans the space */
3757 : ExaOffscreenArea *area;
3759 : for (area = pExaScr->info->offScreenAreas; area != NULL;
3760 : area = area->next)
3762 : if (area->state == ExaOffscreenRemovable &&
3763 : area->save == exaPixmapSave)
3765 : (void) ExaOffscreenKickOut (pScreen, area);
3766 : ExaOffscreenValidate (pScreen);
3773 : ExaOffscreenValidate (pScreen);
3777 :ExaOffscreenSwapIn (ScreenPtr pScreen)
3779 : exaOffscreenInit (pScreen);
3783 : * Prepares EXA for disabling of FB access, or restoring it.
3785 : * In version 2.1, the disabling results in pixmaps being ejected, while other
3786 : * allocations remain. With this plus the prevention of migration while
3787 : * swappedOut is set, EXA by itself should not cause any access of the
3788 : * framebuffer to occur while swapped out. Any remaining issues are the
3789 : * responsibility of the driver.
3791 : * Prior to version 2.1, all allocations, including locked ones, are ejected
3792 : * when access is disabled, and the allocator is torn down while swappedOut
3793 : * is set. This is more drastic, and caused implementation difficulties for
3794 : * many drivers that could otherwise handle the lack of FB access while
3798 :exaEnableDisableFBAccess (int index, Bool enable)
3800 : ScreenPtr pScreen = screenInfo.screens[index];
3801 : ExaScreenPriv (pScreen);
3803 : if (!enable && pExaScr->disableFbCount++ == 0) {
3804 : if (pExaScr->info->exa_minor < 1)
3805 : ExaOffscreenSwapOut (pScreen);
3807 : ExaOffscreenEjectPixmaps (pScreen);
3808 : pExaScr->swappedOut = TRUE;
3811 : if (enable && --pExaScr->disableFbCount == 0) {
3812 : if (pExaScr->info->exa_minor < 1)
3813 : ExaOffscreenSwapIn (pScreen);
3814 : pExaScr->swappedOut = FALSE;
3818 :/* merge the next free area into this one */
3820 :ExaOffscreenMerge (ExaOffscreenArea *area)
3821 1 0.0011 :{ /* ExaOffscreenMerge total: 3 0.0033 */
3822 : ExaOffscreenArea *next = area->next;
3824 : /* account for space */
3825 : area->size += next->size;
3826 : /* frob pointer */
3827 1 0.0011 : area->next = next->next;
3832 : * exaOffscreenFree frees an allocation.
3834 : * @param pScreen current screen
3835 : * @param area offscreen area to free
3837 : * exaOffscreenFree frees an allocation created by exaOffscreenAlloc. Note that
3838 : * the save callback of the area is not called, and it is up to the driver to
3839 : * do any cleanup necessary as a result.
3841 : * @return pointer to the newly freed area. This behavior should not be relied
3845 :exaOffscreenFree (ScreenPtr pScreen, ExaOffscreenArea *area)
3846 :{ /* exaOffscreenFree total: 11 0.0120 */
3847 : ExaScreenPriv(pScreen);
3848 : ExaOffscreenArea *next = area->next;
3849 : ExaOffscreenArea *prev;
3851 : DBG_OFFSCREEN (("Free 0x%x -> 0x%x (0x%x)\n", area->size,
3852 : area->base_offset, area->offset));
3853 : ExaOffscreenValidate (pScreen);
3855 : area->state = ExaOffscreenAvail;
3856 : area->save = NULL;
3859 : * Find previous area
3861 : if (area == pExaScr->info->offScreenAreas)
3864 2 0.0022 : for (prev = pExaScr->info->offScreenAreas; prev; prev = prev->next)
3865 8 0.0087 : if (prev->next == area)
3868 : /* link with next area if free */
3869 : if (next && next->state == ExaOffscreenAvail)
3870 1 0.0011 : ExaOffscreenMerge (area);
3872 : /* link with prev area if free */
3873 : if (prev && prev->state == ExaOffscreenAvail)
3876 : ExaOffscreenMerge (area);
3879 : ExaOffscreenValidate (pScreen);
3880 : DBG_OFFSCREEN(("\tdone freeing\n"));
3885 :ExaOffscreenMarkUsed (PixmapPtr pPixmap)
3886 11 0.0120 :{ /* ExaOffscreenMarkUsed total: 452 0.4924 */
3887 4 0.0044 : ExaPixmapPriv (pPixmap);
3888 17 0.0185 : ExaScreenPriv (pPixmap->drawable.pScreen);
3889 : static int iter = 0;
3891 9 0.0098 : if (!pExaPixmap || !pExaPixmap->area)
3894 : /* The numbers here are arbitrary. We may want to tune these. */
3895 : pExaPixmap->area->score += 100;
3896 19 0.0207 : if (++iter == 10) {
3897 : ExaOffscreenArea *area;
3898 79 0.0861 : for (area = pExaScr->info->offScreenAreas; area != NULL;
3899 27 0.0294 : area = area->next)
3901 77 0.0839 : if (area->state == ExaOffscreenRemovable)
3902 198 0.2157 : area->score = (area->score * 7) / 8;
3909 : * exaOffscreenInit initializes the offscreen memory manager.
3911 : * @param pScreen current screen
3913 : * exaOffscreenInit is called by exaDriverInit to set up the memory manager for
3914 : * the screen, if any offscreen memory is available.
3917 :exaOffscreenInit (ScreenPtr pScreen)
3919 : ExaScreenPriv (pScreen);
3920 : ExaOffscreenArea *area;
3922 : /* Allocate a big free area */
3923 : area = xalloc (sizeof (ExaOffscreenArea));
3928 : area->state = ExaOffscreenAvail;
3929 : area->base_offset = pExaScr->info->offScreenBase;
3930 : area->offset = area->base_offset;
3931 : area->size = pExaScr->info->memorySize - area->base_offset;
3932 : area->save = NULL;
3933 : area->next = NULL;
3936 : /* Add it to the free areas */
3937 : pExaScr->info->offScreenAreas = area;
3939 : ExaOffscreenValidate (pScreen);
3945 :ExaOffscreenFini (ScreenPtr pScreen)
3947 : ExaScreenPriv (pScreen);
3948 : ExaOffscreenArea *area;
3950 : /* just free all of the area records */
3951 : while ((area = pExaScr->info->offScreenAreas))
3953 : pExaScr->info->offScreenAreas = area->next;
3958 * Total samples for file : "/home/cworth/src/pixman/pixman/pixman-region.c"
3964 :/***********************************************************
3966 :Copyright 1987, 1988, 1989, 1998 The Open Group
3968 :Permission to use, copy, modify, distribute, and sell this software and its
3969 :documentation for any purpose is hereby granted without fee, provided that
3970 :the above copyright notice appear in all copies and that both that
3971 :copyright notice and this permission notice appear in supporting
3974 :The above copyright notice and this permission notice shall be included in
3975 :all copies or substantial portions of the Software.
3977 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3978 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3979 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3980 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
3981 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3982 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3984 :Except as contained in this notice, the name of The Open Group shall not be
3985 :used in advertising or otherwise to promote the sale, use or other dealings
3986 :in this Software without prior written authorization from The Open Group.
3988 :Copyright 1987, 1988, 1989 by
3989 :Digital Equipment Corporation, Maynard, Massachusetts.
3991 : All Rights Reserved
3993 :Permission to use, copy, modify, and distribute this software and its
3994 :documentation for any purpose and without fee is hereby granted,
3995 :provided that the above copyright notice appear in all copies and that
3996 :both that copyright notice and this permission notice appear in
3997 :supporting documentation, and that the name of Digital not be
3998 :used in advertising or publicity pertaining to distribution of the
3999 :software without specific, written prior permission.
4001 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
4002 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
4003 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
4004 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
4005 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
4006 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4009 :******************************************************************/
4011 :#include <config.h>
4012 :#include <stdlib.h>
4013 :#include <limits.h>
4014 :#include <string.h>
4017 :#include "pixman-private.h"
4018 :#include "pixman.h"
4020 :typedef struct pixman_region16_point {
4022 :} pixman_region16_point_t;
4024 :#define PIXREGION_NIL(reg) ((reg)->data && !(reg)->data->numRects)
4026 :#define PIXREGION_NAR(reg) ((reg)->data == pixman_brokendata)
4027 :#define PIXREGION_NUM_RECTS(reg) ((reg)->data ? (reg)->data->numRects : 1)
4028 :#define PIXREGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0)
4029 :#define PIXREGION_RECTS(reg) ((reg)->data ? (pixman_box16_t *)((reg)->data + 1) \
4030 : : &(reg)->extents)
4031 :#define PIXREGION_BOXPTR(reg) ((pixman_box16_t *)((reg)->data + 1))
4032 :#define PIXREGION_BOX(reg,i) (&PIXREGION_BOXPTR(reg)[i])
4033 :#define PIXREGION_TOP(reg) PIXREGION_BOX(reg, (reg)->data->numRects)
4034 :#define PIXREGION_END(reg) PIXREGION_BOX(reg, (reg)->data->numRects - 1)
4035 :#define PIXREGION_SZOF(n) (sizeof(pixman_region16_data_t) + ((n) * sizeof(pixman_box16_t)))
4039 :#ifdef DEBUG_PIXREGION
4040 :#define assert(expr) {if (!(expr)) \
4041 : FatalError("Assertion failed file %s, line %d: expr\n", \
4042 : __FILE__, __LINE__); }
4044 :#define assert(expr)
4047 :#define good(reg) assert(pixman_region_selfcheck(reg))
4050 :#define MIN(a,b) ((a) < (b) ? (a) : (b))
4052 :#define MAX(a,b) ((a) > (b) ? (a) : (b))
4054 :static const pixman_box16_t _pixman_region_emptyBox = {0, 0, 0, 0};
4055 :static const pixman_region16_data_t _pixman_region_emptyData = {0, 0};
4056 :static const pixman_region16_data_t _pixman_brokendata = {0, 0};
4058 :static pixman_box16_t *pixman_region_emptyBox = (pixman_box16_t *)&_pixman_region_emptyBox;
4059 :static pixman_region16_data_t *pixman_region_emptyData = (pixman_region16_data_t *)&_pixman_region_emptyData;
4060 :static pixman_region16_data_t *pixman_brokendata = (pixman_region16_data_t *)&_pixman_brokendata;
4062 :/* This function exists only to make it possible to preserve the X ABI - it should
4063 : * go away at first opportunity.
4065 : * The problem is that the X ABI exports the three structs and has used
4066 : * them through macros. So the X server calls this function with
4067 : * the addresses of those structs which makes the existing code continue to
4071 :pixman_region_set_static_pointers (pixman_box16_t *empty_box,
4072 : pixman_region16_data_t *empty_data,
4073 : pixman_region16_data_t *broken_data)
4075 : pixman_region_emptyBox = empty_box;
4076 : pixman_region_emptyData = empty_data;
4077 : pixman_brokendata = broken_data;
4080 :static pixman_bool_t
4081 :pixman_break (pixman_region16_t *pReg);
4084 : * The functions in this file implement the Region abstraction used extensively
4085 : * throughout the X11 sample server. A Region is simply a set of disjoint
4086 : * (non-overlapping) rectangles, plus an "extent" rectangle which is the
4087 : * smallest single rectangle that contains all the non-overlapping rectangles.
4089 : * A Region is implemented as a "y-x-banded" array of rectangles. This array
4090 : * imposes two degrees of order. First, all rectangles are sorted by top side
4091 : * y coordinate first (y1), and then by left side x coordinate (x1).
4093 : * Furthermore, the rectangles are grouped into "bands". Each rectangle in a
4094 : * band has the same top y coordinate (y1), and each has the same bottom y
4095 : * coordinate (y2). Thus all rectangles in a band differ only in their left
4096 : * and right side (x1 and x2). Bands are implicit in the array of rectangles:
4097 : * there is no separate list of band start pointers.
4099 : * The y-x band representation does not minimize rectangles. In particular,
4100 : * if a rectangle vertically crosses a band (the rectangle has scanlines in
4101 : * the y1 to y2 area spanned by the band), then the rectangle may be broken
4102 : * down into two or more smaller rectangles stacked one atop the other.
4104 : * ----------- -----------
4106 : * | | -------- ----------- --------
4107 : * | | | | in y-x banded | | | | band 1
4108 : * | | | | form is | | | |
4109 : * ----------- | | ----------- --------
4111 : * -------- --------
4113 : * An added constraint on the rectangles is that they must cover as much
4114 : * horizontal area as possible: no two rectangles within a band are allowed
4117 : * Whenever possible, bands will be merged together to cover a greater vertical
4118 : * distance (and thus reduce the number of rectangles). Two bands can be merged
4119 : * only if the bottom of one touches the top of the other and they have
4120 : * rectangles in the same places (of the same width, of course).
4122 : * Adam de Boor wrote most of the original region code. Joel McCormack
4123 : * substantially modified or rewrote most of the core arithmetic routines, and
4124 : * added pixman_region_validate in order to support several speed improvements to
4125 : * pixman_region_validateTree. Bob Scheifler changed the representation to be more
4126 : * compact when empty or a single rectangle, and did a bunch of gratuitous
4127 : * reformatting. Carl Worth did further gratuitous reformatting while re-merging
4128 : * the server and client region code into libpixregion.
4131 :/* true iff two Boxes overlap */
4132 :#define EXTENTCHECK(r1,r2) \
4133 : (!( ((r1)->x2 <= (r2)->x1) || \
4134 : ((r1)->x1 >= (r2)->x2) || \
4135 : ((r1)->y2 <= (r2)->y1) || \
4136 : ((r1)->y1 >= (r2)->y2) ) )
4138 :/* true iff (x,y) is in Box */
4139 :#define INBOX(r,x,y) \
4140 : ( ((r)->x2 > x) && \
4141 : ((r)->x1 <= x) && \
4142 : ((r)->y2 > y) && \
4145 :/* true iff Box r1 contains Box r2 */
4146 :#define SUBSUMES(r1,r2) \
4147 : ( ((r1)->x1 <= (r2)->x1) && \
4148 : ((r1)->x2 >= (r2)->x2) && \
4149 : ((r1)->y1 <= (r2)->y1) && \
4150 : ((r1)->y2 >= (r2)->y2) )
4152 :#define allocData(n) malloc(PIXREGION_SZOF(n))
4153 :#define freeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
4155 :#define RECTALLOC_BAIL(pReg,n,bail) \
4156 :if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
4157 : if (!pixman_rect_alloc(pReg, n)) { goto bail; }
4159 :#define RECTALLOC(pReg,n) \
4160 :if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
4161 : if (!pixman_rect_alloc(pReg, n)) { return FALSE; }
4163 :#define ADDRECT(pNextRect,nx1,ny1,nx2,ny2) \
4165 : pNextRect->x1 = nx1; \
4166 : pNextRect->y1 = ny1; \
4167 : pNextRect->x2 = nx2; \
4168 : pNextRect->y2 = ny2; \
4172 :#define NEWRECT(pReg,pNextRect,nx1,ny1,nx2,ny2) \
4174 : if (!(pReg)->data || ((pReg)->data->numRects == (pReg)->data->size))\
4176 : if (!pixman_rect_alloc(pReg, 1)) \
4178 : pNextRect = PIXREGION_TOP(pReg); \
4180 : ADDRECT(pNextRect,nx1,ny1,nx2,ny2); \
4181 : pReg->data->numRects++; \
4182 : assert(pReg->data->numRects<=pReg->data->size); \
4185 :#define DOWNSIZE(reg,numRects) \
4186 :if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
4188 : pixman_region16_data_t * NewData; \
4189 : NewData = (pixman_region16_data_t *)realloc((reg)->data, PIXREGION_SZOF(numRects)); \
4192 : NewData->size = (numRects); \
4193 : (reg)->data = NewData; \
4198 :pixman_region_equal(reg1, reg2)
4199 : pixman_region16_t * reg1;
4200 : pixman_region16_t * reg2;
4203 : pixman_box16_t *rects1;
4204 : pixman_box16_t *rects2;
4206 : if (reg1->extents.x1 != reg2->extents.x1) return FALSE;
4207 : if (reg1->extents.x2 != reg2->extents.x2) return FALSE;
4208 : if (reg1->extents.y1 != reg2->extents.y1) return FALSE;
4209 : if (reg1->extents.y2 != reg2->extents.y2) return FALSE;
4210 : if (PIXREGION_NUM_RECTS(reg1) != PIXREGION_NUM_RECTS(reg2)) return FALSE;
4212 : rects1 = PIXREGION_RECTS(reg1);
4213 : rects2 = PIXREGION_RECTS(reg2);
4214 : for (i = 0; i != PIXREGION_NUM_RECTS(reg1); i++) {
4215 : if (rects1[i].x1 != rects2[i].x1) return FALSE;
4216 : if (rects1[i].x2 != rects2[i].x2) return FALSE;
4217 : if (rects1[i].y1 != rects2[i].y1) return FALSE;
4218 : if (rects1[i].y2 != rects2[i].y2) return FALSE;
4224 :pixman_region16_print(rgn)
4225 : pixman_region16_t * rgn;
4229 : pixman_box16_t * rects;
4231 : num = PIXREGION_NUM_RECTS(rgn);
4232 : size = PIXREGION_SIZE(rgn);
4233 : rects = PIXREGION_RECTS(rgn);
4234 : fprintf(stderr, "num: %d size: %d\n", num, size);
4235 : fprintf(stderr, "extents: %d %d %d %d\n",
4236 : rgn->extents.x1, rgn->extents.y1, rgn->extents.x2, rgn->extents.y2);
4237 : for (i = 0; i < num; i++)
4238 : fprintf(stderr, "%d %d %d %d \n",
4239 : rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
4240 : fprintf(stderr, "\n");
4246 :pixman_region_init (pixman_region16_t *region)
4247 8 0.0087 :{ /* pixman_region_init total: 13 0.0142 */
4248 3 0.0033 : region->extents = *pixman_region_emptyBox;
4249 : region->data = pixman_region_emptyData;
4253 :pixman_region_init_rect (pixman_region16_t *region,
4254 : int x, int y, unsigned int width, unsigned int height)
4255 2 0.0022 :{ /* pixman_region_init_rect total: 3 0.0033 */
4256 : region->extents.x1 = x;
4257 : region->extents.y1 = y;
4258 : region->extents.x2 = x + width;
4259 1 0.0011 : region->extents.y2 = y + height;
4260 : region->data = NULL;
4264 :pixman_region_init_with_extents (pixman_region16_t *region, pixman_box16_t *extents)
4265 1 0.0011 :{ /* pixman_region_init_with_extents total: 2 0.0022 */
4266 1 0.0011 : region->extents = *extents;
4267 : region->data = NULL;
4271 :pixman_region_fini (pixman_region16_t *region)
4272 41 0.0447 :{ /* pixman_region_fini total: 44 0.0479 */
4274 1 0.0011 : freeData (region);
4278 :pixman_region_n_rects (pixman_region16_t *region)
4279 14 0.0153 :{ /* pixman_region_n_rects total: 38 0.0414 */
4280 16 0.0174 : return PIXREGION_NUM_RECTS (region);
4284 :pixman_region_rects (pixman_region16_t *region)
4286 : return PIXREGION_RECTS (region);
4290 :pixman_region_rectangles (pixman_region16_t *region,
4292 41 0.0447 :{ /* pixman_region_rectangles total: 82 0.0893 */
4294 : *n_rects = PIXREGION_NUM_RECTS (region);
4296 17 0.0185 : return PIXREGION_RECTS (region);
4299 :static pixman_bool_t
4300 :pixman_break (pixman_region16_t *region)
4302 : freeData (region);
4303 : region->extents = *pixman_region_emptyBox;
4304 : region->data = pixman_brokendata;
4308 :static pixman_bool_t
4309 :pixman_rect_alloc (pixman_region16_t * region, int n)
4310 7 0.0076 :{ /* pixman_rect_alloc total: 16 0.0174 */
4311 : pixman_region16_data_t *data;
4313 : if (!region->data)
4316 : region->data = allocData(n);
4317 : if (!region->data)
4318 : return pixman_break (region);
4319 : region->data->numRects = 1;
4320 : *PIXREGION_BOXPTR(region) = region->extents;
4322 1 0.0011 : else if (!region->data->size)
4324 4 0.0044 : region->data = allocData(n);
4325 1 0.0011 : if (!region->data)
4326 : return pixman_break (region);
4327 1 0.0011 : region->data->numRects = 0;
4333 : n = region->data->numRects;
4334 : if (n > 500) /* XXX pick numbers out of a hat */
4337 : n += region->data->numRects;
4338 : data = (pixman_region16_data_t *)realloc(region->data, PIXREGION_SZOF(n));
4340 : return pixman_break (region);
4341 : region->data = data;
4343 : region->data->size = n;
4348 :pixman_region_copy (pixman_region16_t *dst, pixman_region16_t *src)
4349 4 0.0044 :{ /* pixman_region_copy total: 15 0.0163 */
4354 2 0.0022 : dst->extents = src->extents;
4355 1 0.0011 : if (!src->data || !src->data->size)
4357 6 0.0065 : freeData(dst);
4358 1 0.0011 : dst->data = src->data;
4361 : if (!dst->data || (dst->data->size < src->data->numRects))
4364 : dst->data = allocData(src->data->numRects);
4366 : return pixman_break (dst);
4367 : dst->data->size = src->data->numRects;
4369 : dst->data->numRects = src->data->numRects;
4370 : memmove((char *)PIXREGION_BOXPTR(dst),(char *)PIXREGION_BOXPTR(src),
4371 : dst->data->numRects * sizeof(pixman_box16_t));
4375 :/*======================================================================
4376 : * Generic Region Operator
4377 : *====================================================================*/
4380 : *-----------------------------------------------------------------------
4381 : * pixman_coalesce --
4382 : * Attempt to merge the boxes in the current band with those in the
4383 : * previous one. We are guaranteed that the current band extends to
4384 : * the end of the rects array. Used only by pixman_op.
4387 : * The new index for the previous band.
4390 : * If coalescing takes place:
4391 : * - rectangles in the previous band will have their y2 fields
4393 : * - region->data->numRects will be decreased.
4395 : *-----------------------------------------------------------------------
4399 : pixman_region16_t * region, /* Region to coalesce */
4400 : int prevStart, /* Index of start of previous band */
4401 : int curStart) /* Index of start of current band */
4403 : pixman_box16_t * pPrevBox; /* Current box in previous band */
4404 : pixman_box16_t * pCurBox; /* Current box in current band */
4405 : int numRects; /* Number rectangles in both bands */
4406 : int y2; /* Bottom of current band */
4408 : * Figure out how many rectangles are in the band.
4410 : numRects = curStart - prevStart;
4411 : assert(numRects == region->data->numRects - curStart);
4413 : if (!numRects) return curStart;
4416 : * The bands may only be coalesced if the bottom of the previous
4417 : * matches the top scanline of the current.
4419 : pPrevBox = PIXREGION_BOX(region, prevStart);
4420 : pCurBox = PIXREGION_BOX(region, curStart);
4421 : if (pPrevBox->y2 != pCurBox->y1) return curStart;
4424 : * Make sure the bands have boxes in the same places. This
4425 : * assumes that boxes have been added in such a way that they
4426 : * cover the most area possible. I.e. two boxes in a band must
4427 : * have some horizontal space between them.
4432 : if ((pPrevBox->x1 != pCurBox->x1) || (pPrevBox->x2 != pCurBox->x2)) {
4433 : return (curStart);
4438 : } while (numRects);
4441 : * The bands may be merged, so set the bottom y of each box
4442 : * in the previous band to the bottom y of the current band.
4444 : numRects = curStart - prevStart;
4445 : region->data->numRects -= numRects;
4448 : pPrevBox->y2 = y2;
4450 : } while (numRects);
4454 :/* Quicky macro to avoid trivial reject procedure calls to pixman_coalesce */
4456 :#define Coalesce(newReg, prevBand, curBand) \
4457 : if (curBand - prevBand == newReg->data->numRects - curBand) { \
4458 : prevBand = pixman_coalesce(newReg, prevBand, curBand); \
4460 : prevBand = curBand; \
4464 : *-----------------------------------------------------------------------
4465 : * pixman_region_appendNonO --
4466 : * Handle a non-overlapping band for the union and subtract operations.
4467 : * Just adds the (top/bottom-clipped) rectangles into the region.
4468 : * Doesn't have to check for subsumption or anything.
4474 : * region->data->numRects is incremented and the rectangles overwritten
4475 : * with the rectangles we're passed.
4477 : *-----------------------------------------------------------------------
4480 :static inline pixman_bool_t
4481 :pixman_region_appendNonO (
4482 : pixman_region16_t * region,
4483 : pixman_box16_t * r,
4484 : pixman_box16_t * rEnd,
4488 : pixman_box16_t * pNextRect;
4491 : newRects = rEnd - r;
4494 : assert(newRects != 0);
4496 : /* Make sure we have enough space for all rectangles to be added */
4497 : RECTALLOC(region, newRects);
4498 : pNextRect = PIXREGION_TOP(region);
4499 : region->data->numRects += newRects;
4501 : assert(r->x1 < r->x2);
4502 : ADDRECT(pNextRect, r->x1, y1, r->x2, y2);
4504 : } while (r != rEnd);
4509 :#define FindBand(r, rBandEnd, rEnd, ry1) \
4513 : while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) { \
4518 :#define AppendRegions(newReg, r, rEnd) \
4521 : if ((newRects = rEnd - r)) { \
4522 : RECTALLOC(newReg, newRects); \
4523 : memmove((char *)PIXREGION_TOP(newReg),(char *)r, \
4524 : newRects * sizeof(pixman_box16_t)); \
4525 : newReg->data->numRects += newRects; \
4530 : *-----------------------------------------------------------------------
4532 : * Apply an operation to two regions. Called by pixman_region_union, pixman_region_inverse,
4533 : * pixman_region_subtract, pixman_region_intersect.... Both regions MUST have at least one
4534 : * rectangle, and cannot be the same object.
4537 : * TRUE if successful.
4540 : * The new region is overwritten.
4541 : * pOverlap set to TRUE if overlapFunc ever returns TRUE.
4544 : * The idea behind this function is to view the two regions as sets.
4545 : * Together they cover a rectangle of area that this function divides
4546 : * into horizontal bands where points are covered only by one region
4547 : * or by both. For the first case, the nonOverlapFunc is called with
4548 : * each the band and the band's upper and lower extents. For the
4549 : * second, the overlapFunc is called to process the entire band. It
4550 : * is responsible for clipping the rectangles in the band, though
4551 : * this function provides the boundaries.
4552 : * At the end of each band, the new region is coalesced, if possible,
4553 : * to reduce the number of rectangles in the region.
4555 : *-----------------------------------------------------------------------
4558 :typedef pixman_bool_t (*OverlapProcPtr)(
4559 : pixman_region16_t *region,
4560 : pixman_box16_t *r1,
4561 : pixman_box16_t *r1End,
4562 : pixman_box16_t *r2,
4563 : pixman_box16_t *r2End,
4568 :static pixman_bool_t
4570 : pixman_region16_t *newReg, /* Place to store result */
4571 : pixman_region16_t * reg1, /* First region in operation */
4572 : pixman_region16_t * reg2, /* 2d region in operation */
4573 : OverlapProcPtr overlapFunc, /* Function to call for over-
4574 : * lapping bands */
4575 : int appendNon1, /* Append non-overlapping bands */
4576 : /* in region 1 ? */
4577 : int appendNon2, /* Append non-overlapping bands */
4578 : /* in region 2 ? */
4580 7 0.0076 :{ /* pixman_op total: 146 0.1591 */
4581 : pixman_box16_t * r1; /* Pointer into first region */
4582 : pixman_box16_t * r2; /* Pointer into 2d region */
4583 : pixman_box16_t * r1End; /* End of 1st region */
4584 : pixman_box16_t * r2End; /* End of 2d region */
4585 : short ybot; /* Bottom of intersection */
4586 : short ytop; /* Top of intersection */
4587 : pixman_region16_data_t * oldData; /* Old data for newReg */
4588 : int prevBand; /* Index of start of
4589 : * previous band in newReg */
4590 : int curBand; /* Index of start of current
4591 : * band in newReg */
4592 : pixman_box16_t * r1BandEnd; /* End of current band in r1 */
4593 : pixman_box16_t * r2BandEnd; /* End of current band in r2 */
4594 : short top; /* Top of non-overlapping band */
4595 : short bot; /* Bottom of non-overlapping band*/
4596 : int r1y1; /* Temps for r1->y1 and r2->y1 */
4602 : * Break any region computed from a broken region
4604 3 0.0033 : if (PIXREGION_NAR (reg1) || PIXREGION_NAR(reg2))
4605 : return pixman_break (newReg);
4609 : * set r1, r2, r1End and r2End appropriately, save the rectangles
4610 : * of the destination region until the end in case it's one of
4611 : * the two source regions, then mark the "new" region empty, allocating
4612 : * another array of rectangles for it to use.
4615 3 0.0033 : r1 = PIXREGION_RECTS(reg1);
4616 2 0.0022 : newSize = PIXREGION_NUM_RECTS(reg1);
4617 : r1End = r1 + newSize;
4618 4 0.0044 : numRects = PIXREGION_NUM_RECTS(reg2);
4619 1 0.0011 : r2 = PIXREGION_RECTS(reg2);
4620 : r2End = r2 + numRects;
4621 : assert(r1 != r1End);
4622 : assert(r2 != r2End);
4624 : oldData = (pixman_region16_data_t *)NULL;
4625 1 0.0011 : if (((newReg == reg1) && (newSize > 1)) ||
4626 : ((newReg == reg2) && (numRects > 1)))
4628 1 0.0011 : oldData = newReg->data;
4629 1 0.0011 : newReg->data = pixman_region_emptyData;
4631 : /* guess at new size */
4632 : if (numRects > newSize)
4633 : newSize = numRects;
4635 1 0.0011 : if (!newReg->data)
4636 2 0.0022 : newReg->data = pixman_region_emptyData;
4637 : else if (newReg->data->size)
4638 : newReg->data->numRects = 0;
4639 : if (newSize > newReg->data->size) {
4640 : if (!pixman_rect_alloc(newReg, newSize)) {
4648 : * Initialize ybot.
4649 : * In the upcoming loop, ybot and ytop serve different functions depending
4650 : * on whether the band being handled is an overlapping or non-overlapping
4652 : * In the case of a non-overlapping band (only one of the regions
4653 : * has points in the band), ybot is the bottom of the most recent
4654 : * intersection and thus clips the top of the rectangles in that band.
4655 : * ytop is the top of the next intersection between the two regions and
4656 : * serves to clip the bottom of the rectangles in the current band.
4657 : * For an overlapping band (where the two regions intersect), ytop clips
4658 : * the top of the rectangles of both regions and ybot clips the bottoms.
4661 2 0.0022 : ybot = MIN(r1->y1, r2->y1);
4664 : * prevBand serves to mark the start of the previous band so rectangles
4665 : * can be coalesced into larger rectangles. qv. pixman_coalesce, above.
4666 : * In the beginning, there is no previous band, so prevBand == curBand
4667 : * (curBand is set later on, of course, but the first band will always
4668 : * start at index 0). prevBand and curBand must be indices because of
4669 : * the possible expansion, and resultant moving, of the new region's
4670 : * array of rectangles.
4676 : * This algorithm proceeds one source-band (as opposed to a
4677 : * destination band, which is determined by where the two regions
4678 : * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
4679 : * rectangle after the last one in the current band for their
4680 : * respective regions.
4682 : assert(r1 != r1End);
4683 : assert(r2 != r2End);
4685 2 0.0022 : FindBand(r1, r1BandEnd, r1End, r1y1);
4686 9 0.0098 : FindBand(r2, r2BandEnd, r2End, r2y1);
4689 : * First handle the band that doesn't intersect, if any.
4691 : * Note that attention is restricted to one band in the
4692 : * non-intersecting region at once, so if a region has n
4693 : * bands between the current position and the next place it overlaps
4694 : * the other, this entire loop will be passed through n times.
4696 3 0.0033 : if (r1y1 < r2y1) {
4698 : top = MAX(r1y1, ybot);
4699 : bot = MIN(r1->y2, r2y1);
4701 : curBand = newReg->data->numRects;
4702 : pixman_region_appendNonO(newReg, r1, r1BandEnd, top, bot);
4703 : Coalesce(newReg, prevBand, curBand);
4707 : } else if (r2y1 < r1y1) {
4708 1 0.0011 : if (appendNon2) {
4709 1 0.0011 : top = MAX(r2y1, ybot);
4710 : bot = MIN(r2->y2, r1y1);
4712 : curBand = newReg->data->numRects;
4713 : pixman_region_appendNonO(newReg, r2, r2BandEnd, top, bot);
4714 : Coalesce(newReg, prevBand, curBand);
4723 : * Now see if we've hit an intersecting band. The two bands only
4724 : * intersect if ybot > ytop
4726 2 0.0022 : ybot = MIN(r1->y2, r2->y2);
4727 6 0.0065 : if (ybot > ytop) {
4728 4 0.0044 : curBand = newReg->data->numRects;
4729 4 0.0044 : (* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot,
4731 9 0.0098 : Coalesce(newReg, prevBand, curBand);
4735 : * If we've finished with a band (y2 == ybot) we skip forward
4736 : * in the region to the next band.
4738 1 0.0011 : if (r1->y2 == ybot) r1 = r1BandEnd;
4739 3 0.0033 : if (r2->y2 == ybot) r2 = r2BandEnd;
4741 5 0.0054 : } while (r1 != r1End && r2 != r2End);
4744 : * Deal with whichever region (if any) still has rectangles left.
4746 : * We only need to worry about banding and coalescing for the very first
4747 : * band left. After that, we can just group all remaining boxes,
4748 : * regardless of how many bands, into one final append to the list.
4751 : if ((r1 != r1End) && appendNon1) {
4752 : /* Do first nonOverlap1Func call, which may be able to coalesce */
4753 1 0.0011 : FindBand(r1, r1BandEnd, r1End, r1y1);
4754 : curBand = newReg->data->numRects;
4755 2 0.0022 : pixman_region_appendNonO(newReg, r1, r1BandEnd, MAX(r1y1, ybot), r1->y2);
4756 3 0.0033 : Coalesce(newReg, prevBand, curBand);
4757 : /* Just append the rest of the boxes */
4758 1 0.0011 : AppendRegions(newReg, r1BandEnd, r1End);
4760 : } else if ((r2 != r2End) && appendNon2) {
4761 : /* Do first nonOverlap2Func call, which may be able to coalesce */
4762 : FindBand(r2, r2BandEnd, r2End, r2y1);
4763 : curBand = newReg->data->numRects;
4764 : pixman_region_appendNonO(newReg, r2, r2BandEnd, MAX(r2y1, ybot), r2->y2);
4765 : Coalesce(newReg, prevBand, curBand);
4766 : /* Append rest of boxes */
4767 7 0.0076 : AppendRegions(newReg, r2BandEnd, r2End);
4770 2 0.0022 : if (oldData)
4773 8 0.0087 : if (!(numRects = newReg->data->numRects))
4776 : newReg->data = pixman_region_emptyData;
4778 1 0.0011 : else if (numRects == 1)
4780 : newReg->extents = *PIXREGION_BOXPTR(newReg);
4782 : newReg->data = (pixman_region16_data_t *)NULL;
4786 1 0.0011 : DOWNSIZE(newReg, numRects);
4793 : *-----------------------------------------------------------------------
4794 : * pixman_set_extents --
4795 : * Reset the extents of a region to what they should be. Called by
4796 : * pixman_region_subtract and pixman_region_intersect as they can't figure it out along the
4797 : * way or do so easily, as pixman_region_union can.
4803 : * The region's 'extents' structure is overwritten.
4805 : *-----------------------------------------------------------------------
4808 :pixman_set_extents (pixman_region16_t *region)
4810 : pixman_box16_t *box, *boxEnd;
4812 : if (!region->data)
4814 : if (!region->data->size)
4816 : region->extents.x2 = region->extents.x1;
4817 : region->extents.y2 = region->extents.y1;
4821 : box = PIXREGION_BOXPTR(region);
4822 : boxEnd = PIXREGION_END(region);
4825 : * Since box is the first rectangle in the region, it must have the
4826 : * smallest y1 and since boxEnd is the last rectangle in the region,
4827 : * it must have the largest y2, because of banding. Initialize x1 and
4828 : * x2 from box and boxEnd, resp., as good things to initialize them
4831 : region->extents.x1 = box->x1;
4832 : region->extents.y1 = box->y1;
4833 : region->extents.x2 = boxEnd->x2;
4834 : region->extents.y2 = boxEnd->y2;
4836 : assert(region->extents.y1 < region->extents.y2);
4837 : while (box <= boxEnd) {
4838 : if (box->x1 < region->extents.x1)
4839 : region->extents.x1 = box->x1;
4840 : if (box->x2 > region->extents.x2)
4841 : region->extents.x2 = box->x2;
4845 : assert(region->extents.x1 < region->extents.x2);
4848 :/*======================================================================
4849 : * Region Intersection
4850 : *====================================================================*/
4852 : *-----------------------------------------------------------------------
4853 : * pixman_region_intersectO --
4854 : * Handle an overlapping band for pixman_region_intersect.
4857 : * TRUE if successful.
4860 : * Rectangles may be added to the region.
4862 : *-----------------------------------------------------------------------
4865 :static pixman_bool_t
4866 :pixman_region_intersectO (pixman_region16_t *region,
4867 : pixman_box16_t *r1,
4868 : pixman_box16_t *r1End,
4869 : pixman_box16_t *r2,
4870 : pixman_box16_t *r2End,
4877 : pixman_box16_t * pNextRect;
4879 : pNextRect = PIXREGION_TOP(region);
4882 : assert(r1 != r1End && r2 != r2End);
4885 : x1 = MAX(r1->x1, r2->x1);
4886 : x2 = MIN(r1->x2, r2->x2);
4889 : * If there's any overlap between the two rectangles, add that
4890 : * overlap to the new region.
4893 : NEWRECT(region, pNextRect, x1, y1, x2, y2);
4896 : * Advance the pointer(s) with the leftmost right side, since the next
4897 : * rectangle on that list may still overlap the other region's
4898 : * current rectangle.
4900 : if (r1->x2 == x2) {
4903 : if (r2->x2 == x2) {
4906 : } while ((r1 != r1End) && (r2 != r2End));
4912 :pixman_region_intersect (pixman_region16_t * newReg,
4913 : pixman_region16_t * reg1,
4914 : pixman_region16_t * reg2)
4915 4 0.0044 :{ /* pixman_region_intersect total: 13 0.0142 */
4919 : /* check for trivial reject */
4920 4 0.0044 : if (PIXREGION_NIL(reg1) || PIXREGION_NIL(reg2) ||
4921 : !EXTENTCHECK(®1->extents, ®2->extents))
4923 : /* Covers about 20% of all cases */
4925 : newReg->extents.x2 = newReg->extents.x1;
4926 : newReg->extents.y2 = newReg->extents.y1;
4927 : if (PIXREGION_NAR(reg1) || PIXREGION_NAR(reg2))
4929 : newReg->data = pixman_brokendata;
4933 : newReg->data = pixman_region_emptyData;
4935 : else if (!reg1->data && !reg2->data)
4937 : /* Covers about 80% of cases that aren't trivially rejected */
4938 1 0.0011 : newReg->extents.x1 = MAX(reg1->extents.x1, reg2->extents.x1);
4939 1 0.0011 : newReg->extents.y1 = MAX(reg1->extents.y1, reg2->extents.y1);
4940 1 0.0011 : newReg->extents.x2 = MIN(reg1->extents.x2, reg2->extents.x2);
4941 : newReg->extents.y2 = MIN(reg1->extents.y2, reg2->extents.y2);
4943 : newReg->data = (pixman_region16_data_t *)NULL;
4945 : else if (!reg2->data && SUBSUMES(®2->extents, ®1->extents))
4947 : return pixman_region_copy(newReg, reg1);
4949 : else if (!reg1->data && SUBSUMES(®1->extents, ®2->extents))
4951 : return pixman_region_copy(newReg, reg2);
4953 : else if (reg1 == reg2)
4955 : return pixman_region_copy(newReg, reg1);
4959 : /* General purpose intersection */
4960 : int overlap; /* result ignored */
4961 : if (!pixman_op(newReg, reg1, reg2, pixman_region_intersectO, FALSE, FALSE,
4964 : pixman_set_extents(newReg);
4971 :#define MERGERECT(r) \
4973 : if (r->x1 <= x2) { \
4974 : /* Merge with current rectangle */ \
4975 : if (r->x1 < x2) *pOverlap = TRUE; \
4976 : if (x2 < r->x2) x2 = r->x2; \
4978 : /* Add current rectangle, start new one */ \
4979 : NEWRECT(region, pNextRect, x1, y1, x2, y2); \
4986 :/*======================================================================
4988 : *====================================================================*/
4991 : *-----------------------------------------------------------------------
4992 : * pixman_region_unionO --
4993 : * Handle an overlapping band for the union operation. Picks the
4994 : * left-most rectangle each time and merges it into the region.
4997 : * TRUE if successful.
5000 : * region is overwritten.
5001 : * pOverlap is set to TRUE if any boxes overlap.
5003 : *-----------------------------------------------------------------------
5005 :static pixman_bool_t
5006 :pixman_region_unionO (
5007 : pixman_region16_t *region,
5008 : pixman_box16_t *r1,
5009 : pixman_box16_t *r1End,
5010 : pixman_box16_t *r2,
5011 : pixman_box16_t *r2End,
5015 11 0.0120 :{ /* pixman_region_unionO total: 39 0.0425 */
5016 : pixman_box16_t * pNextRect;
5017 : int x1; /* left and right side of current union */
5021 : assert(r1 != r1End && r2 != r2End);
5023 6 0.0065 : pNextRect = PIXREGION_TOP(region);
5025 : /* Start off current rectangle */
5026 : if (r1->x1 < r2->x1)
5034 1 0.0011 : x1 = r2->x1;
5035 2 0.0022 : x2 = r2->x2;
5038 3 0.0033 : while (r1 != r1End && r2 != r2End)
5040 : if (r1->x1 < r2->x1) MERGERECT(r1) else MERGERECT(r2);
5043 : /* Finish off whoever (if any) is left */
5048 8 0.0087 : MERGERECT(r1);
5049 2 0.0022 : } while (r1 != r1End);
5051 : else if (r2 != r2End)
5056 : } while (r2 != r2End);
5059 : /* Add current rectangle */
5060 4 0.0044 : NEWRECT(region, pNextRect, x1, y1, x2, y2);
5065 :/* Convenience function for performing union of region with a
5066 : * single rectangle
5069 :pixman_region_union_rect (pixman_region16_t *dest,
5070 : pixman_region16_t *source,
5072 : unsigned int width, unsigned int height)
5074 : pixman_region16_t region;
5076 : if (!width || !height)
5077 : return pixman_region_copy (dest, source);
5078 : region.data = NULL;
5079 : region.extents.x1 = x;
5080 : region.extents.y1 = y;
5081 : region.extents.x2 = x + width;
5082 : region.extents.y2 = y + height;
5084 : return pixman_region_union (dest, source, ®ion);
5088 :pixman_region_union (pixman_region16_t *newReg,
5089 : pixman_region16_t *reg1,
5090 : pixman_region16_t *reg2)
5091 17 0.0185 :{ /* pixman_region_union total: 87 0.0948 */
5092 : int overlap; /* result ignored */
5094 : /* Return TRUE if some overlap
5095 : * between reg1, reg2
5100 : /* checks all the simple cases */
5103 : * Region 1 and 2 are the same
5107 : return pixman_region_copy(newReg, reg1);
5111 : * Region 1 is empty
5113 7 0.0076 : if (PIXREGION_NIL(reg1))
5115 : if (PIXREGION_NAR(reg1))
5116 : return pixman_break (newReg);
5117 1 0.0011 : if (newReg != reg2)
5118 1 0.0011 : return pixman_region_copy(newReg, reg2);
5123 : * Region 2 is empty
5125 9 0.0098 : if (PIXREGION_NIL(reg2))
5127 : if (PIXREGION_NAR(reg2))
5128 : return pixman_break (newReg);
5129 : if (newReg != reg1)
5130 : return pixman_region_copy(newReg, reg1);
5135 : * Region 1 completely subsumes region 2
5137 8 0.0087 : if (!reg1->data && SUBSUMES(®1->extents, ®2->extents))
5139 7 0.0076 : if (newReg != reg1)
5140 : return pixman_region_copy(newReg, reg1);
5145 : * Region 2 completely subsumes region 1
5147 2 0.0022 : if (!reg2->data && SUBSUMES(®2->extents, ®1->extents))
5149 : if (newReg != reg2)
5150 1 0.0011 : return pixman_region_copy(newReg, reg2);
5154 3 0.0033 : if (!pixman_op(newReg, reg1, reg2, pixman_region_unionO, TRUE, TRUE, &overlap))
5157 1 0.0011 : newReg->extents.x1 = MIN(reg1->extents.x1, reg2->extents.x1);
5158 3 0.0033 : newReg->extents.y1 = MIN(reg1->extents.y1, reg2->extents.y1);
5159 7 0.0076 : newReg->extents.x2 = MAX(reg1->extents.x2, reg2->extents.x2);
5160 8 0.0087 : newReg->extents.y2 = MAX(reg1->extents.y2, reg2->extents.y2);
5162 5 0.0054 : return TRUE;
5165 :/*======================================================================
5166 : * Batch Rectangle Union
5167 : *====================================================================*/
5170 : *-----------------------------------------------------------------------
5171 : * pixman_region_append --
5173 : * "Append" the rgn rectangles onto the end of dstrgn, maintaining
5174 : * knowledge of YX-banding when it's easy. Otherwise, dstrgn just
5175 : * becomes a non-y-x-banded random collection of rectangles, and not
5176 : * yet a true region. After a sequence of appends, the caller must
5177 : * call pixman_region_validate to ensure that a valid region is
5181 : * TRUE if successful.
5184 : * dstrgn is modified if rgn has rectangles.
5188 :pixman_region_append (pixman_region16_t * dstrgn,
5189 : pixman_region16_t * rgn)
5191 : int numRects, dnumRects, size;
5192 : pixman_box16_t *new, *old;
5195 : if (PIXREGION_NAR(rgn))
5196 : return pixman_break (dstrgn);
5198 : if (!rgn->data && (dstrgn->data == pixman_region_emptyData))
5200 : dstrgn->extents = rgn->extents;
5201 : dstrgn->data = (pixman_region16_data_t *)NULL;
5205 : numRects = PIXREGION_NUM_RECTS(rgn);
5210 : dnumRects = PIXREGION_NUM_RECTS(dstrgn);
5211 : if (!dnumRects && (size < 200))
5212 : size = 200; /* XXX pick numbers out of a hat */
5213 : RECTALLOC(dstrgn, size);
5214 : old = PIXREGION_RECTS(rgn);
5216 : dstrgn->extents = rgn->extents;
5217 : else if (dstrgn->extents.x2 > dstrgn->extents.x1)
5219 : pixman_box16_t *first, *last;
5222 : last = PIXREGION_BOXPTR(dstrgn) + (dnumRects - 1);
5223 : if ((first->y1 > last->y2) ||
5224 : ((first->y1 == last->y1) && (first->y2 == last->y2) &&
5225 : (first->x1 > last->x2)))
5227 : if (rgn->extents.x1 < dstrgn->extents.x1)
5228 : dstrgn->extents.x1 = rgn->extents.x1;
5229 : if (rgn->extents.x2 > dstrgn->extents.x2)
5230 : dstrgn->extents.x2 = rgn->extents.x2;
5231 : dstrgn->extents.y2 = rgn->extents.y2;
5235 : first = PIXREGION_BOXPTR(dstrgn);
5236 : last = old + (numRects - 1);
5237 : if ((first->y1 > last->y2) ||
5238 : ((first->y1 == last->y1) && (first->y2 == last->y2) &&
5239 : (first->x1 > last->x2)))
5242 : if (rgn->extents.x1 < dstrgn->extents.x1)
5243 : dstrgn->extents.x1 = rgn->extents.x1;
5244 : if (rgn->extents.x2 > dstrgn->extents.x2)
5245 : dstrgn->extents.x2 = rgn->extents.x2;
5246 : dstrgn->extents.y1 = rgn->extents.y1;
5249 : dstrgn->extents.x2 = dstrgn->extents.x1;
5254 : new = PIXREGION_BOX(dstrgn, numRects);
5255 : if (dnumRects == 1)
5256 : *new = *PIXREGION_BOXPTR(dstrgn);
5258 : memmove((char *)new,(char *)PIXREGION_BOXPTR(dstrgn),
5259 : dnumRects * sizeof(pixman_box16_t));
5260 : new = PIXREGION_BOXPTR(dstrgn);
5263 : new = PIXREGION_BOXPTR(dstrgn) + dnumRects;
5264 : if (numRects == 1)
5267 : memmove((char *)new, (char *)old, numRects * sizeof(pixman_box16_t));
5268 : dstrgn->data->numRects += numRects;
5272 :#define ExchangeRects(a, b) \
5274 : pixman_box16_t t; \
5276 : rects[a] = rects[b]; \
5282 : pixman_box16_t rects[],
5288 : pixman_box16_t *r;
5290 : /* Always called with numRects > 1 */
5294 : if (numRects == 2)
5296 : if (rects[0].y1 > rects[1].y1 ||
5297 : (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1))
5298 : ExchangeRects(0, 1);
5302 : /* Choose partition element, stick in location 0 */
5303 : ExchangeRects(0, numRects >> 1);
5307 : /* Partition array */
5317 : } while (i != numRects &&
5318 : (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1)));
5324 : } while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1));
5326 : ExchangeRects(i, j);
5329 : /* Move partition element back to middle */
5330 : ExchangeRects(0, j);
5333 : if (numRects-j-1 > 1)
5334 : QuickSortRects(&rects[j+1], numRects-j-1);
5336 : } while (numRects > 1);
5340 : *-----------------------------------------------------------------------
5341 : * pixman_region_validate --
5343 : * Take a ``region'' which is a non-y-x-banded random collection of
5344 : * rectangles, and compute a nice region which is the union of all the
5348 : * TRUE if successful.
5351 : * The passed-in ``region'' may be modified.
5352 : * pOverlap set to TRUE if any retangles overlapped,
5356 : * Step 1. Sort the rectangles into ascending order with primary key y1
5357 : * and secondary key x1.
5359 : * Step 2. Split the rectangles into the minimum number of proper y-x
5360 : * banded regions. This may require horizontally merging
5361 : * rectangles, and vertically coalescing bands. With any luck,
5362 : * this step in an identity transformation (ala the Box widget),
5363 : * or a coalescing into 1 box (ala Menus).
5365 : * Step 3. Merge the separate regions down to a single region by calling
5366 : * pixman_region_union. Maximize the work each pixman_region_union call does by using
5369 : *-----------------------------------------------------------------------
5373 :pixman_region_validate(pixman_region16_t * badreg,
5376 : /* Descriptor for regions under construction in Step 2. */
5378 : pixman_region16_t reg;
5383 : int numRects; /* Original numRects for badreg */
5384 : RegionInfo *ri; /* Array of current regions */
5385 : int numRI; /* Number of entries used in ri */
5386 : int sizeRI; /* Number of entries available in ri */
5387 : int i; /* Index into rects */
5388 : int j; /* Index into ri */
5389 : RegionInfo *rit; /* &ri[j] */
5390 : pixman_region16_t * reg; /* ri[j].reg */
5391 : pixman_box16_t * box; /* Current box in rects */
5392 : pixman_box16_t * riBox; /* Last box in ri[j].reg */
5393 : pixman_region16_t * hreg; /* ri[j_half].reg */
5394 : pixman_bool_t ret = TRUE;
5396 : *pOverlap = FALSE;
5397 : if (!badreg->data)
5402 : numRects = badreg->data->numRects;
5405 : if (PIXREGION_NAR(badreg))
5410 : if (badreg->extents.x1 < badreg->extents.x2)
5412 : if ((numRects) == 1)
5415 : badreg->data = (pixman_region16_data_t *) NULL;
5419 : DOWNSIZE(badreg, numRects);
5425 : /* Step 1: Sort the rects array into ascending (y1, x1) order */
5426 : QuickSortRects(PIXREGION_BOXPTR(badreg), numRects);
5428 : /* Step 2: Scatter the sorted array into the minimum number of regions */
5430 : /* Set up the first region to be the first rectangle in badreg */
5431 : /* Note that step 2 code will never overflow the ri[0].reg rects array */
5432 : ri = (RegionInfo *) malloc(4 * sizeof(RegionInfo));
5434 : return pixman_break (badreg);
5437 : ri[0].prevBand = 0;
5438 : ri[0].curBand = 0;
5439 : ri[0].reg = *badreg;
5440 : box = PIXREGION_BOXPTR(&ri[0].reg);
5441 : ri[0].reg.extents = *box;
5442 : ri[0].reg.data->numRects = 1;
5444 : /* Now scatter rectangles into the minimum set of valid regions. If the
5445 : next rectangle to be added to a region would force an existing rectangle
5446 : in the region to be split up in order to maintain y-x banding, just
5447 : forget it. Try the next region. If it doesn't fit cleanly into any
5448 : region, make a new one. */
5450 : for (i = numRects; --i > 0;)
5453 : /* Look for a region to append box to */
5454 : for (j = numRI, rit = ri; --j >= 0; rit++)
5457 : riBox = PIXREGION_END(reg);
5459 : if (box->y1 == riBox->y1 && box->y2 == riBox->y2)
5461 : /* box is in same band as riBox. Merge or append it */
5462 : if (box->x1 <= riBox->x2)
5464 : /* Merge it with riBox */
5465 : if (box->x1 < riBox->x2) *pOverlap = TRUE;
5466 : if (box->x2 > riBox->x2) riBox->x2 = box->x2;
5470 : RECTALLOC_BAIL(reg, 1, bail);
5471 : *PIXREGION_TOP(reg) = *box;
5472 : reg->data->numRects++;
5474 : goto NextRect; /* So sue me */
5476 : else if (box->y1 >= riBox->y2)
5478 : /* Put box into new band */
5479 : if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
5480 : if (reg->extents.x1 > box->x1) reg->extents.x1 = box->x1;
5481 : Coalesce(reg, rit->prevBand, rit->curBand);
5482 : rit->curBand = reg->data->numRects;
5483 : RECTALLOC_BAIL(reg, 1, bail);
5484 : *PIXREGION_TOP(reg) = *box;
5485 : reg->data->numRects++;
5488 : /* Well, this region was inappropriate. Try the next one. */
5491 : /* Uh-oh. No regions were appropriate. Create a new one. */
5492 : if (sizeRI == numRI)
5494 : /* Oops, allocate space for new region information */
5496 : rit = (RegionInfo *) realloc(ri, sizeRI * sizeof(RegionInfo));
5503 : rit->prevBand = 0;
5505 : rit->reg.extents = *box;
5506 : rit->reg.data = (pixman_region16_data_t *)NULL;
5507 : if (!pixman_rect_alloc(&rit->reg, (i+numRI) / numRI)) /* MUST force allocation */
5512 : /* Make a final pass over each region in order to Coalesce and set
5513 : extents.x2 and extents.y2 */
5515 : for (j = numRI, rit = ri; --j >= 0; rit++)
5518 : riBox = PIXREGION_END(reg);
5519 : reg->extents.y2 = riBox->y2;
5520 : if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
5521 : Coalesce(reg, rit->prevBand, rit->curBand);
5522 : if (reg->data->numRects == 1) /* keep unions happy below */
5525 : reg->data = (pixman_region16_data_t *)NULL;
5529 : /* Step 3: Union all regions into a single region */
5532 : int half = numRI/2;
5533 : for (j = numRI & 1; j < (half + (numRI & 1)); j++)
5536 : hreg = &ri[j+half].reg;
5537 : if (!pixman_op(reg, reg, hreg, pixman_region_unionO, TRUE, TRUE, pOverlap))
5539 : if (hreg->extents.x1 < reg->extents.x1)
5540 : reg->extents.x1 = hreg->extents.x1;
5541 : if (hreg->extents.y1 < reg->extents.y1)
5542 : reg->extents.y1 = hreg->extents.y1;
5543 : if (hreg->extents.x2 > reg->extents.x2)
5544 : reg->extents.x2 = hreg->extents.x2;
5545 : if (hreg->extents.y2 > reg->extents.y2)
5546 : reg->extents.y2 = hreg->extents.y2;
5551 : *badreg = ri[0].reg;
5556 : for (i = 0; i < numRI; i++)
5557 : freeData(&ri[i].reg);
5559 : return pixman_break (badreg);
5562 :/*======================================================================
5563 : * Region Subtraction
5564 : *====================================================================*/
5567 : *-----------------------------------------------------------------------
5568 : * pixman_region_subtractO --
5569 : * Overlapping band subtraction. x1 is the left-most point not yet
5573 : * TRUE if successful.
5576 : * region may have rectangles added to it.
5578 : *-----------------------------------------------------------------------
5581 :static pixman_bool_t
5582 :pixman_region_subtractO (
5583 : pixman_region16_t * region,
5584 : pixman_box16_t * r1,
5585 : pixman_box16_t * r1End,
5586 : pixman_box16_t * r2,
5587 : pixman_box16_t * r2End,
5592 : pixman_box16_t * pNextRect;
5598 : assert(r1 != r1End && r2 != r2End);
5600 : pNextRect = PIXREGION_TOP(region);
5607 : * Subtrahend entirely to left of minuend: go to next subtrahend.
5611 : else if (r2->x1 <= x1)
5614 : * Subtrahend preceeds minuend: nuke left edge of minuend.
5620 : * Minuend completely covered: advance to next minuend and
5621 : * reset left fence to edge of new minuend.
5630 : * Subtrahend now used up since it doesn't extend beyond
5636 : else if (r2->x1 < r1->x2)
5639 : * Left part of subtrahend covers part of minuend: add uncovered
5640 : * part of minuend to region and skip to next subtrahend.
5642 : assert(x1<r2->x1);
5643 : NEWRECT(region, pNextRect, x1, y1, r2->x1, y2);
5649 : * Minuend used up: advance to new...
5658 : * Subtrahend used up
5666 : * Minuend used up: add any remaining piece before advancing.
5669 : NEWRECT(region, pNextRect, x1, y1, r1->x2, y2);
5674 : } while ((r1 != r1End) && (r2 != r2End));
5677 : * Add remaining minuend rectangles to region.
5679 : while (r1 != r1End)
5681 : assert(x1<r1->x2);
5682 : NEWRECT(region, pNextRect, x1, y1, r1->x2, y2);
5691 : *-----------------------------------------------------------------------
5692 : * pixman_region_subtract --
5693 : * Subtract regS from regM and leave the result in regD.
5694 : * S stands for subtrahend, M for minuend and D for difference.
5697 : * TRUE if successful.
5700 : * regD is overwritten.
5702 : *-----------------------------------------------------------------------
5705 :pixman_region_subtract(pixman_region16_t * regD,
5706 : pixman_region16_t * regM,
5707 : pixman_region16_t * regS)
5709 : int overlap; /* result ignored */
5714 : /* check for trivial rejects */
5715 : if (PIXREGION_NIL(regM) || PIXREGION_NIL(regS) ||
5716 : !EXTENTCHECK(®M->extents, ®S->extents))
5718 : if (PIXREGION_NAR (regS))
5719 : return pixman_break (regD);
5720 : return pixman_region_copy(regD, regM);
5722 : else if (regM == regS)
5725 : regD->extents.x2 = regD->extents.x1;
5726 : regD->extents.y2 = regD->extents.y1;
5727 : regD->data = pixman_region_emptyData;
5731 : /* Add those rectangles in region 1 that aren't in region 2,
5732 : do yucky substraction for overlaps, and
5733 : just throw away rectangles in region 2 that aren't in region 1 */
5734 : if (!pixman_op(regD, regM, regS, pixman_region_subtractO, TRUE, FALSE, &overlap))
5738 : * Can't alter RegD's extents before we call pixman_op because
5739 : * it might be one of the source regions and pixman_op depends
5740 : * on the extents of those regions being unaltered. Besides, this
5741 : * way there's no checking against rectangles that will be nuked
5742 : * due to coalescing, so we have to examine fewer rectangles.
5744 : pixman_set_extents(regD);
5749 :/*======================================================================
5750 : * Region Inversion
5751 : *====================================================================*/
5754 : *-----------------------------------------------------------------------
5755 : * pixman_region_inverse --
5756 : * Take a region and a box and return a region that is everything
5757 : * in the box but not in the region. The careful reader will note
5758 : * that this is the same as subtracting the region from the box...
5764 : * newReg is overwritten.
5766 : *-----------------------------------------------------------------------
5769 :pixman_region_inverse(pixman_region16_t * newReg, /* Destination region */
5770 : pixman_region16_t * reg1, /* Region to invert */
5771 : pixman_box16_t * invRect) /* Bounding box for inversion */
5773 : pixman_region16_t invReg; /* Quick and dirty region made from the
5775 : int overlap; /* result ignored */
5779 : /* check for trivial rejects */
5780 : if (PIXREGION_NIL(reg1) || !EXTENTCHECK(invRect, ®1->extents))
5782 : if (PIXREGION_NAR(reg1))
5783 : return pixman_break (newReg);
5784 : newReg->extents = *invRect;
5786 : newReg->data = (pixman_region16_data_t *)NULL;
5790 : /* Add those rectangles in region 1 that aren't in region 2,
5791 : do yucky substraction for overlaps, and
5792 : just throw away rectangles in region 2 that aren't in region 1 */
5793 : invReg.extents = *invRect;
5794 : invReg.data = (pixman_region16_data_t *)NULL;
5795 : if (!pixman_op(newReg, &invReg, reg1, pixman_region_subtractO, TRUE, FALSE, &overlap))
5799 : * Can't alter newReg's extents before we call pixman_op because
5800 : * it might be one of the source regions and pixman_op depends
5801 : * on the extents of those regions being unaltered. Besides, this
5802 : * way there's no checking against rectangles that will be nuked
5803 : * due to coalescing, so we have to examine fewer rectangles.
5805 : pixman_set_extents(newReg);
5811 : * RectIn(region, rect)
5812 : * This routine takes a pointer to a region and a pointer to a box
5813 : * and determines if the box is outside/inside/partly inside the region.
5815 : * The idea is to travel through the list of rectangles trying to cover the
5816 : * passed box with them. Anytime a piece of the rectangle isn't covered
5817 : * by a band of rectangles, partOut is set TRUE. Any time a rectangle in
5818 : * the region covers part of the box, partIn is set TRUE. The process ends
5819 : * when either the box has been completely covered (we reached a band that
5820 : * doesn't overlap the box, partIn is TRUE and partOut is false), the
5821 : * box has been partially covered (partIn == partOut == TRUE -- because of
5822 : * the banding, the first time this is true we know the box is only
5823 : * partially in the region) or is outside the region (we reached a band
5824 : * that doesn't overlap the box at all and partIn is false)
5827 :pixman_region_overlap_t
5828 :pixman_region_contains_rectangle(pixman_region16_t * region,
5829 : pixman_box16_t * prect)
5833 : pixman_box16_t * pbox;
5834 : pixman_box16_t * pboxEnd;
5835 : int partIn, partOut;
5839 : numRects = PIXREGION_NUM_RECTS(region);
5840 : /* useful optimization */
5841 : if (!numRects || !EXTENTCHECK(®ion->extents, prect))
5842 : return(PIXMAN_REGION_OUT);
5844 : if (numRects == 1)
5846 : /* We know that it must be PIXMAN_REGION_IN or PIXMAN_REGION_PART */
5847 : if (SUBSUMES(®ion->extents, prect))
5848 : return(PIXMAN_REGION_IN);
5850 : return(PIXMAN_REGION_PART);
5856 : /* (x,y) starts at upper left of rect, moving to the right and down */
5860 : /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
5861 : for (pbox = PIXREGION_BOXPTR(region), pboxEnd = pbox + numRects;
5866 : if (pbox->y2 <= y)
5867 : continue; /* getting up to speed or skipping remainder of band */
5871 : partOut = TRUE; /* missed part of rectangle above */
5872 : if (partIn || (pbox->y1 >= prect->y2))
5874 : y = pbox->y1; /* x guaranteed to be == prect->x1 */
5877 : if (pbox->x2 <= x)
5878 : continue; /* not far enough over yet */
5882 : partOut = TRUE; /* missed part of rectangle to left */
5887 : if (pbox->x1 < prect->x2)
5889 : partIn = TRUE; /* definitely overlap */
5894 : if (pbox->x2 >= prect->x2)
5896 : y = pbox->y2; /* finished with this band */
5897 : if (y >= prect->y2)
5899 : x = prect->x1; /* reset x out to left again */
5904 : * Because boxes in a band are maximal width, if the first box
5905 : * to overlap the rectangle doesn't completely cover it in that
5906 : * band, the rectangle must be partially out, since some of it
5907 : * will be uncovered in that band. partIn will have been set true
5917 : if (y < prect->y2)
5918 : return PIXMAN_REGION_PART;
5920 : return PIXMAN_REGION_IN;
5924 : return PIXMAN_REGION_OUT;
5928 :/* pixman_region_translate (region, x, y)
5929 : translates in place
5933 :pixman_region_translate (pixman_region16_t * region, int x, int y)
5934 1 0.0011 :{ /* pixman_region_translate total: 7 0.0076 */
5935 : int x1, x2, y1, y2;
5937 : pixman_box16_t * pbox;
5940 : region->extents.x1 = x1 = region->extents.x1 + x;
5941 1 0.0011 : region->extents.y1 = y1 = region->extents.y1 + y;
5942 : region->extents.x2 = x2 = region->extents.x2 + x;
5943 1 0.0011 : region->extents.y2 = y2 = region->extents.y2 + y;
5944 1 0.0011 : if (((x1 - SHRT_MIN)|(y1 - SHRT_MIN)|(SHRT_MAX - x2)|(SHRT_MAX - y2)) >= 0)
5946 1 0.0011 : if (region->data && (nbox = region->data->numRects))
5948 : for (pbox = PIXREGION_BOXPTR(region); nbox--; pbox++)
5958 : if (((x2 - SHRT_MIN)|(y2 - SHRT_MIN)|(SHRT_MAX - x1)|(SHRT_MAX - y1)) <= 0)
5960 : region->extents.x2 = region->extents.x1;
5961 : region->extents.y2 = region->extents.y1;
5963 : region->data = pixman_region_emptyData;
5966 : if (x1 < SHRT_MIN)
5967 : region->extents.x1 = SHRT_MIN;
5968 : else if (x2 > SHRT_MAX)
5969 : region->extents.x2 = SHRT_MAX;
5970 : if (y1 < SHRT_MIN)
5971 : region->extents.y1 = SHRT_MIN;
5972 : else if (y2 > SHRT_MAX)
5973 : region->extents.y2 = SHRT_MAX;
5974 : if (region->data && (nbox = region->data->numRects))
5976 : pixman_box16_t * pboxout;
5978 : for (pboxout = pbox = PIXREGION_BOXPTR(region); nbox--; pbox++)
5980 : pboxout->x1 = x1 = pbox->x1 + x;
5981 : pboxout->y1 = y1 = pbox->y1 + y;
5982 : pboxout->x2 = x2 = pbox->x2 + x;
5983 : pboxout->y2 = y2 = pbox->y2 + y;
5984 : if (((x2 - SHRT_MIN)|(y2 - SHRT_MIN)|
5985 : (SHRT_MAX - x1)|(SHRT_MAX - y1)) <= 0)
5987 : region->data->numRects--;
5990 : if (x1 < SHRT_MIN)
5991 : pboxout->x1 = SHRT_MIN;
5992 : else if (x2 > SHRT_MAX)
5993 : pboxout->x2 = SHRT_MAX;
5994 : if (y1 < SHRT_MIN)
5995 : pboxout->y1 = SHRT_MIN;
5996 : else if (y2 > SHRT_MAX)
5997 : pboxout->y2 = SHRT_MAX;
6000 : if (pboxout != pbox)
6002 : if (region->data->numRects == 1)
6004 : region->extents = *PIXREGION_BOXPTR(region);
6006 : region->data = (pixman_region16_data_t *)NULL;
6009 : pixman_set_extents(region);
6014 :/* XXX: Do we need this?
6015 :static pixman_bool_t
6016 :pixman_region16_data_copy(pixman_region16_t * dst, pixman_region16_t * src)
6024 : if (!src->data || !src->data->size)
6027 : dst->data = (pixman_region16_data_t *)NULL;
6030 : if (!dst->data || (dst->data->size < src->data->numRects))
6033 : dst->data = allocData(src->data->numRects);
6035 : return pixman_break (dst);
6037 : dst->data->size = src->data->size;
6038 : dst->data->numRects = src->data->numRects;
6044 :pixman_region_reset(pixman_region16_t *region, pixman_box16_t *box)
6047 : assert(box->x1<=box->x2);
6048 : assert(box->y1<=box->y2);
6049 : region->extents = *box;
6051 : region->data = (pixman_region16_data_t *)NULL;
6054 :/* box is "return" value */
6056 :pixman_region_contains_point(pixman_region16_t * region,
6058 : pixman_box16_t * box)
6060 : pixman_box16_t *pbox, *pboxEnd;
6064 : numRects = PIXREGION_NUM_RECTS(region);
6065 : if (!numRects || !INBOX(®ion->extents, x, y))
6067 : if (numRects == 1)
6069 : *box = region->extents;
6072 : for (pbox = PIXREGION_BOXPTR(region), pboxEnd = pbox + numRects;
6076 : if (y >= pbox->y2)
6077 : continue; /* not there yet */
6078 : if ((y < pbox->y1) || (x < pbox->x1))
6079 : break; /* missed it */
6080 : if (x >= pbox->x2)
6081 : continue; /* not there yet */
6089 :pixman_region_not_empty(pixman_region16_t * region)
6090 9 0.0098 :{ /* pixman_region_not_empty total: 17 0.0185 */
6092 5 0.0054 : return(!PIXREGION_NIL(region));
6095 :/* XXX: Do we need this?
6097 :pixman_region16_broken(pixman_region16_t * region)
6100 : return (PIXREGION_NAR(region));
6105 :pixman_region_empty(pixman_region16_t * region)
6109 : region->extents.x2 = region->extents.x1;
6110 : region->extents.y2 = region->extents.y1;
6111 : region->data = pixman_region_emptyData;
6115 :pixman_region_extents(pixman_region16_t * region)
6118 : return(®ion->extents);
6121 :#define ExchangeSpans(a, b) \
6123 : pixman_region16_point_t tpt; \
6126 : tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
6127 : tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
6130 :/* ||| I should apply the merge sort code to rectangle sorting above, and see
6131 : if mapping time can be improved. But right now I've been at work 12 hours,
6135 :static void QuickSortSpans(
6136 : pixman_region16_point_t spans[],
6142 : pixman_region16_point_t *r;
6144 : /* Always called with numSpans > 1 */
6145 : /* Sorts only by y, doesn't bother to sort by x */
6151 : /* Do insertion sort */
6154 : yprev = spans[0].y;
6157 : { /* while i != numSpans */
6161 : /* spans[i] is out of order. Move into proper location. */
6162 : pixman_region16_point_t tpt;
6165 : for (j = 0; y >= spans[j].y; j++) {}
6168 : for (k = i; k != j; k--)
6170 : spans[k] = spans[k-1];
6171 : widths[k] = widths[k-1];
6176 : } /* if out of order */
6179 : } while (i != numSpans);
6183 : /* Choose partition element, stick in location 0 */
6185 : if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
6186 : if (spans[m].y > spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
6187 : if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
6190 : /* Partition array */
6200 : } while (i != numSpans && r->y < y);
6206 : } while (y < r->y);
6208 : ExchangeSpans(i, j);
6211 : /* Move partition element back to middle */
6212 : ExchangeSpans(0, j);
6215 : if (numSpans-j-1 > 1)
6216 : QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
6218 : } while (numSpans > 1);
6221 :#define NextBand() \
6223 : clipy1 = pboxBandStart->y1; \
6224 : clipy2 = pboxBandStart->y2; \
6225 : pboxBandEnd = pboxBandStart + 1; \
6226 : while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) { \
6229 : for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
6233 : Clip a list of scanlines to a region. The caller has allocated the
6234 : space. FSorted is non-zero if the scanline origins are in ascending
6236 : returns the number of new, clipped scanlines.
6239 :#ifdef XXX_DO_WE_NEED_THIS
6241 :pixman_region16_clip_spans(
6242 : pixman_region16_t *prgnDst,
6243 : pixman_region16_point_t *ppt,
6246 : pixman_region16_point_t *pptNew,
6250 : pixman_region16_point_t *pptLast;
6251 : int *pwidthNewStart; /* the vengeance of Xerox! */
6256 : pptLast = ppt + nspans;
6257 : pwidthNewStart = pwidthNew;
6259 : if (!prgnDst->data)
6261 : /* Do special fast code with clip boundaries in registers(?) */
6262 : /* It doesn't pay much to make use of fSorted in this case,
6263 : so we lump everything together. */
6265 : int clipx1, clipx2, clipy1, clipy2;
6267 : clipx1 = prgnDst->extents.x1;
6268 : clipy1 = prgnDst->extents.y1;
6269 : clipx2 = prgnDst->extents.x2;
6270 : clipy2 = prgnDst->extents.y2;
6272 : for (; ppt != pptLast; ppt++, pwidth++)
6276 : if (clipy1 <= y && y < clipy2)
6278 : x2 = x1 + *pwidth;
6279 : if (x1 < clipx1) x1 = clipx1;
6280 : if (x2 > clipx2) x2 = clipx2;
6283 : /* part of span in clip rectangle */
6286 : *pwidthNew = x2 - x1;
6294 : else if ((numRects = prgnDst->data->numRects))
6296 : /* Have to clip against many boxes */
6297 : pixman_box16_t *pboxBandStart, *pboxBandEnd;
6298 : pixman_box16_t *pbox;
6299 : pixman_box16_t *pboxLast;
6300 : int clipy1, clipy2;
6302 : /* In this case, taking advantage of sorted spans gains more than
6303 : the sorting costs. */
6304 : if ((! fSorted) && (nspans > 1))
6305 : QuickSortSpans(ppt, pwidth, nspans);
6307 : pboxBandStart = PIXREGION_BOXPTR(prgnDst);
6308 : pboxLast = pboxBandStart + numRects;
6312 : for (; ppt != pptLast; )
6317 : /* span is in the current band */
6318 : pbox = pboxBandStart;
6320 : x2 = x1 + *pwidth;
6322 : { /* For each box in band */
6327 : if (newx1 < pbox->x1) newx1 = pbox->x1;
6328 : if (newx2 > pbox->x2) newx2 = pbox->x2;
6329 : if (newx1 < newx2)
6331 : /* Part of span in clip rectangle */
6332 : pptNew->x = newx1;
6334 : *pwidthNew = newx2 - newx1;
6339 : } while (pbox != pboxBandEnd);
6345 : /* Move to next band, adjust ppt as needed */
6346 : pboxBandStart = pboxBandEnd;
6347 : if (pboxBandStart == pboxLast)
6348 : break; /* We're completely done */
6353 : return (pwidthNew - pwidthNewStart);
6356 :/* find the band in a region with the most rectangles */
6358 :pixman_region16_find_max_band(pixman_region16_t * prgn)
6361 : pixman_box16_t * pbox;
6367 : nbox = PIXREGION_NUM_RECTS(prgn);
6368 : pbox = PIXREGION_RECTS(prgn);
6372 : yThisBand = pbox->y1;
6374 : while((nbox > 0) && (pbox->y1 == yThisBand))
6380 : if (nThisBand > nMaxBand)
6381 : nMaxBand = nThisBand;
6383 : return (nMaxBand);
6385 :#endif /* XXX_DO_WE_NEED_THIS */
6389 :pixman_region_selfcheck (reg)
6390 : pixman_region16_t * reg;
6394 : if ((reg->extents.x1 > reg->extents.x2) ||
6395 : (reg->extents.y1 > reg->extents.y2))
6397 : numRects = PIXREGION_NUM_RECTS(reg);
6399 : return ((reg->extents.x1 == reg->extents.x2) &&
6400 : (reg->extents.y1 == reg->extents.y2) &&
6401 : (reg->data->size || (reg->data == pixman_region_emptyData)));
6402 : else if (numRects == 1)
6403 : return (!reg->data);
6406 : pixman_box16_t * pboxP, * pboxN;
6407 : pixman_box16_t box;
6409 : pboxP = PIXREGION_RECTS(reg);
6411 : box.y2 = pboxP[numRects-1].y2;
6412 : pboxN = pboxP + 1;
6413 : for (i = numRects; --i > 0; pboxP++, pboxN++)
6415 : if ((pboxN->x1 >= pboxN->x2) ||
6416 : (pboxN->y1 >= pboxN->y2))
6418 : if (pboxN->x1 < box.x1)
6419 : box.x1 = pboxN->x1;
6420 : if (pboxN->x2 > box.x2)
6421 : box.x2 = pboxN->x2;
6422 : if ((pboxN->y1 < pboxP->y1) ||
6423 : ((pboxN->y1 == pboxP->y1) &&
6424 : ((pboxN->x1 < pboxP->x2) || (pboxN->y2 != pboxP->y2))))
6427 : return ((box.x1 == reg->extents.x1) &&
6428 : (box.x2 == reg->extents.x2) &&
6429 : (box.y1 == reg->extents.y1) &&
6430 : (box.y2 == reg->extents.y2));
6435 :pixman_region_init_rects (pixman_region16_t *region,
6436 : pixman_box16_t *boxes, int count)
6441 : pixman_region_init_rect(region,
6444 : boxes[0].x2 - boxes[0].x1,
6445 : boxes[0].y2 - boxes[0].y1);
6449 : pixman_region_init(region);
6450 : if (!pixman_rect_alloc(region, count))
6453 : /* Copy in the rects */
6454 : memcpy (PIXREGION_RECTS(region), boxes, sizeof(pixman_box16_t) * count);
6455 : region->data->numRects = count;
6458 : region->extents.x1 = region->extents.x2 = 0;
6459 : return pixman_region_validate (region, &overlap);
6462 * Total samples for file : "/home/cworth/src/xorg/xserver/exa/exa_migration.c"
6469 : * Copyright © 2006 Intel Corporation
6471 : * Permission is hereby granted, free of charge, to any person obtaining a
6472 : * copy of this software and associated documentation files (the "Software"),
6473 : * to deal in the Software without restriction, including without limitation
6474 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
6475 : * and/or sell copies of the Software, and to permit persons to whom the
6476 : * Software is furnished to do so, subject to the following conditions:
6478 : * The above copyright notice and this permission notice (including the next
6479 : * paragraph) shall be included in all copies or substantial portions of the
6482 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6483 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6484 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
6485 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6486 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6487 : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
6491 : * Eric Anholt <eric@anholt.net>
6492 : * Michel Dänzer <michel@tungstengraphics.com>
6496 :#ifdef HAVE_DIX_CONFIG_H
6497 :#include <dix-config.h>
6500 :#include <string.h>
6502 :#include "exa_priv.h"
6503 :#include <X11/fonts/fontstruct.h>
6504 :#include "dixfontstr.h"
6509 :#define DBG_MIGRATE(a) ErrorF a
6511 :#define DBG_MIGRATE(a)
6515 : * Returns TRUE if the pixmap is not movable. This is the case where it's a
6516 : * fake pixmap for the frontbuffer (no pixmap private) or it's a scratch
6517 : * pixmap created by some other X Server internals (the score says it's
6521 :exaPixmapIsPinned (PixmapPtr pPix)
6522 11 0.0120 :{ /* exaPixmapIsPinned total: 45 0.0490 */
6523 7 0.0076 : ExaPixmapPriv (pPix);
6525 25 0.0272 : return pExaPixmap == NULL || pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED;
6529 : * The fallback path for UTS/DFS failing is to just memcpy. exaCopyDirtyToSys
6530 : * and exaCopyDirtyToFb both needed to do this loop.
6533 :exaMemcpyBox (PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
6534 : CARD8 *dst, int dst_pitch)
6536 : int i, cpp = pPixmap->drawable.bitsPerPixel / 8;
6537 : int bytes = (pbox->x2 - pbox->x1) * cpp;
6539 : src += pbox->y1 * src_pitch + pbox->x1 * cpp;
6540 : dst += pbox->y1 * dst_pitch + pbox->x1 * cpp;
6542 : for (i = pbox->y2 - pbox->y1; i; i--) {
6543 : memcpy (dst, src, bytes);
6550 : * Returns TRUE if the pixmap is dirty (has been modified in its current
6551 : * location compared to the other), or lacks a private for tracking
6555 :exaPixmapIsDirty (PixmapPtr pPix)
6557 : ExaPixmapPriv (pPix);
6559 : return pExaPixmap == NULL ||
6560 : REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage));
6564 : * Returns TRUE if the pixmap is either pinned in FB, or has a sufficient score
6565 : * to be considered "should be in framebuffer". That's just anything that has
6566 : * had more acceleration than fallbacks, or has no score yet.
6568 : * Only valid if using a migration scheme that tracks score.
6571 :exaPixmapShouldBeInFB (PixmapPtr pPix)
6573 : ExaPixmapPriv (pPix);
6575 : if (exaPixmapIsPinned (pPix))
6578 : return pExaPixmap->score >= 0;
6582 : * If the pixmap is currently dirty, this copies at least the dirty area from
6583 : * the framebuffer memory copy to the system memory copy. Both areas must be
6587 :exaCopyDirtyToSys (PixmapPtr pPixmap)
6589 : ExaScreenPriv (pPixmap->drawable.pScreen);
6590 : ExaPixmapPriv (pPixmap);
6591 : RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
6594 : BoxPtr pBox = REGION_RECTS(pRegion);
6595 : int nbox = REGION_NUM_RECTS(pRegion);
6596 : Bool do_sync = FALSE;
6598 : save_ptr = pPixmap->devPrivate.ptr;
6599 : save_pitch = pPixmap->devKind;
6600 : pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
6601 : pPixmap->devKind = pExaPixmap->fb_pitch;
6604 : pBox->x1 = max(pBox->x1, 0);
6605 : pBox->y1 = max(pBox->y1, 0);
6606 : pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
6607 : pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
6609 : if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
6612 : if (pExaScr->info->DownloadFromScreen == NULL ||
6613 : !pExaScr->info->DownloadFromScreen (pPixmap,
6614 : pBox->x1, pBox->y1,
6615 : pBox->x2 - pBox->x1,
6616 : pBox->y2 - pBox->y1,
6617 : pExaPixmap->sys_ptr
6618 : + pBox->y1 * pExaPixmap->sys_pitch
6619 : + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
6620 : pExaPixmap->sys_pitch))
6622 : exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
6623 : exaMemcpyBox (pPixmap, pBox,
6624 : pExaPixmap->fb_ptr, pExaPixmap->fb_pitch,
6625 : pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
6626 : exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
6634 : /* Make sure the bits have actually landed, since we don't necessarily sync
6635 : * when accessing pixmaps in system memory.
6638 : exaWaitSync (pPixmap->drawable.pScreen);
6640 : pPixmap->devPrivate.ptr = save_ptr;
6641 : pPixmap->devKind = save_pitch;
6643 : /* The previously damaged bits are now no longer damaged but valid */
6644 : REGION_UNION(pPixmap->drawable.pScreen,
6645 : &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
6646 : DamageEmpty (pExaPixmap->pDamage);
6650 : * If the pixmap is currently dirty, this copies at least the dirty area from
6651 : * the system memory copy to the framebuffer memory copy. Both areas must be
6655 :exaCopyDirtyToFb (PixmapPtr pPixmap)
6657 : ExaScreenPriv (pPixmap->drawable.pScreen);
6658 : ExaPixmapPriv (pPixmap);
6659 : RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
6662 : BoxPtr pBox = REGION_RECTS(pRegion);
6663 : int nbox = REGION_NUM_RECTS(pRegion);
6664 : Bool do_sync = FALSE;
6666 : save_ptr = pPixmap->devPrivate.ptr;
6667 : save_pitch = pPixmap->devKind;
6668 : pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
6669 : pPixmap->devKind = pExaPixmap->fb_pitch;
6672 : pBox->x1 = max(pBox->x1, 0);
6673 : pBox->y1 = max(pBox->y1, 0);
6674 : pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
6675 : pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
6677 : if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
6680 : if (pExaScr->info->UploadToScreen == NULL ||
6681 : !pExaScr->info->UploadToScreen (pPixmap,
6682 : pBox->x1, pBox->y1,
6683 : pBox->x2 - pBox->x1,
6684 : pBox->y2 - pBox->y1,
6685 : pExaPixmap->sys_ptr
6686 : + pBox->y1 * pExaPixmap->sys_pitch
6687 : + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
6688 : pExaPixmap->sys_pitch))
6690 : exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
6691 : exaMemcpyBox (pPixmap, pBox,
6692 : pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
6693 : pExaPixmap->fb_ptr, pExaPixmap->fb_pitch);
6694 : exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
6703 : exaMarkSync (pPixmap->drawable.pScreen);
6705 : pPixmap->devPrivate.ptr = save_ptr;
6706 : pPixmap->devKind = save_pitch;
6708 : /* The previously damaged bits are now no longer damaged but valid */
6709 : REGION_UNION(pPixmap->drawable.pScreen,
6710 : &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
6711 : DamageEmpty (pExaPixmap->pDamage);
6715 : * Copies out important pixmap data and removes references to framebuffer area.
6716 : * Called when the memory manager decides it's time to kick the pixmap out of
6717 : * framebuffer entirely.
6720 :exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
6722 : PixmapPtr pPixmap = area->privData;
6723 : ExaPixmapPriv(pPixmap);
6724 : RegionPtr pDamageReg = DamageRegion(pExaPixmap->pDamage);
6726 : DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap,
6727 : (void*)(ExaGetPixmapPriv(pPixmap)->area ?
6728 : ExaGetPixmapPriv(pPixmap)->area->offset : 0),
6729 : pPixmap->drawable.width,
6730 : pPixmap->drawable.height,
6731 : exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
6733 : if (exaPixmapIsOffscreen(pPixmap)) {
6734 : exaCopyDirtyToSys (pPixmap);
6735 : pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
6736 : pPixmap->devKind = pExaPixmap->sys_pitch;
6737 : pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
6740 : pExaPixmap->fb_ptr = NULL;
6741 : pExaPixmap->area = NULL;
6743 : /* Mark all valid bits as damaged, so they'll get copied to FB next time */
6744 : REGION_UNION(pPixmap->drawable.pScreen, pDamageReg, pDamageReg,
6745 : &pExaPixmap->validReg);
6749 : * Allocates a framebuffer copy of the pixmap if necessary, and then copies
6750 : * any necessary pixmap data into the framebuffer copy and points the pixmap at
6753 : * Note that when first allocated, a pixmap will have FALSE dirty flag.
6754 : * This is intentional because pixmap data starts out undefined. So if we move
6755 : * it in due to the first operation against it being accelerated, it will have
6756 : * undefined framebuffer contents that we didn't have to upload. If we do
6757 : * moveouts (and moveins) after the first movein, then we will only have to copy
6758 : * back and forth if the pixmap was written to after the last synchronization of
6759 : * the two copies. Then, at exaPixmapSave (when the framebuffer copy goes away)
6760 : * we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
6761 : * all the data, since it's almost surely all valid now.
6764 :exaMoveInPixmap (PixmapPtr pPixmap)
6765 30 0.0327 :{ /* exaMoveInPixmap total: 133 0.1449 */
6766 4 0.0044 : ScreenPtr pScreen = pPixmap->drawable.pScreen;
6767 23 0.0251 : ExaScreenPriv (pScreen);
6768 23 0.0251 : ExaPixmapPriv (pPixmap);
6770 : /* If we're VT-switched away, no touching card memory allowed. */
6771 16 0.0174 : if (pExaScr->swappedOut)
6774 : /* If we're already in FB, our work is done. */
6775 12 0.0131 : if (exaPixmapIsOffscreen(pPixmap))
6778 : /* If we're not allowed to move, then fail. */
6779 : if (exaPixmapIsPinned(pPixmap))
6782 : /* Don't migrate in pixmaps which are less than 8bpp. This avoids a lot of
6783 : * fragility in EXA, and <8bpp is probably not used enough any more to care
6784 : * (at least, not in acceleratd paths).
6786 1 0.0011 : if (pPixmap->drawable.bitsPerPixel < 8)
6789 : if (pExaPixmap->area == NULL) {
6790 2 0.0022 : pExaPixmap->area =
6791 : exaOffscreenAlloc (pScreen, pExaPixmap->fb_size,
6792 : pExaScr->info->pixmapOffsetAlign, FALSE,
6793 : exaPixmapSave, (pointer) pPixmap);
6794 : if (pExaPixmap->area == NULL)
6797 : pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase +
6798 : pExaPixmap->area->offset;
6801 : DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
6802 : (ExaGetPixmapPriv(pPixmap)->area ?
6803 : ExaGetPixmapPriv(pPixmap)->area->offset : 0),
6804 : pPixmap->drawable.width,
6805 : pPixmap->drawable.height,
6806 : exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
6808 : exaCopyDirtyToFb (pPixmap);
6810 : if (pExaScr->hideOffscreenPixmapData)
6811 : pPixmap->devPrivate.ptr = NULL;
6813 1 0.0011 : pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
6814 1 0.0011 : pPixmap->devKind = pExaPixmap->fb_pitch;
6815 2 0.0022 : pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
6819 : * Switches the current active location of the pixmap to system memory, copying
6820 : * updated data out if necessary.
6823 :exaMoveOutPixmap (PixmapPtr pPixmap)
6825 : ExaPixmapPriv (pPixmap);
6827 : if (exaPixmapIsPinned(pPixmap))
6830 : if (exaPixmapIsOffscreen(pPixmap)) {
6832 : DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
6833 : (void*)(ExaGetPixmapPriv(pPixmap)->area ?
6834 : ExaGetPixmapPriv(pPixmap)->area->offset : 0),
6835 : pPixmap->drawable.width,
6836 : pPixmap->drawable.height,
6837 : exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
6839 : exaCopyDirtyToSys (pPixmap);
6841 : pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
6842 : pPixmap->devKind = pExaPixmap->sys_pitch;
6843 : pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
6848 : * For the "greedy" migration scheme, pushes the pixmap toward being located in
6849 : * framebuffer memory.
6852 :exaMigrateTowardFb (PixmapPtr pPixmap)
6854 : ExaPixmapPriv (pPixmap);
6856 : if (pExaPixmap == NULL) {
6857 : DBG_MIGRATE(("UseScreen: ignoring exa-uncontrolled pixmap %p (%s)\n",
6859 : exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
6863 : if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
6864 : DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
6865 : (pointer)pPixmap));
6869 : DBG_MIGRATE(("UseScreen %p score %d\n",
6870 : (pointer)pPixmap, pExaPixmap->score));
6872 : if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
6873 : exaMoveInPixmap(pPixmap);
6874 : pExaPixmap->score = 0;
6877 : if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX)
6878 : pExaPixmap->score++;
6880 : if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
6881 : !exaPixmapIsOffscreen(pPixmap))
6883 : exaMoveInPixmap (pPixmap);
6886 : ExaOffscreenMarkUsed (pPixmap);
6890 : * For the "greedy" migration scheme, pushes the pixmap toward being located in
6894 :exaMigrateTowardSys (PixmapPtr pPixmap)
6896 : ExaPixmapPriv (pPixmap);
6898 : if (pExaPixmap == NULL) {
6899 : DBG_MIGRATE(("UseMem: ignoring exa-uncontrolled pixmap %p (%s)\n",
6901 : exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
6905 : DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)pPixmap, pExaPixmap->score));
6907 : if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
6910 : if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT)
6911 : pExaPixmap->score = 0;
6913 : if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN)
6914 : pExaPixmap->score--;
6916 : if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
6917 : exaMoveOutPixmap (pPixmap);
6921 : * If the pixmap has both a framebuffer and system memory copy, this function
6922 : * asserts that both of them are the same.
6925 :exaAssertNotDirty (PixmapPtr pPixmap)
6927 : ExaPixmapPriv (pPixmap);
6929 : RegionPtr pValidReg = &pExaPixmap->validReg;
6930 : int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg);
6931 : BoxPtr pBox = REGION_RECTS(pValidReg);
6934 : if (!nbox || exaPixmapIsPinned(pPixmap) || pExaPixmap->fb_ptr == NULL)
6937 : dst_pitch = pExaPixmap->sys_pitch;
6938 : src_pitch = pExaPixmap->fb_pitch;
6939 : cpp = pPixmap->drawable.bitsPerPixel / 8;
6941 : exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
6945 : pBox->x1 = max(pBox->x1, 0);
6946 : pBox->y1 = max(pBox->y1, 0);
6947 : pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
6948 : pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
6950 : if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
6953 : rowbytes = (pBox->x2 - pBox->x1) * cpp;
6954 : src = pExaPixmap->fb_ptr + pBox->y1 * src_pitch + pBox->x1 * cpp;
6955 : dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
6957 : for (y = pBox->y1; y < pBox->y2;
6958 : y++, src += src_pitch, dst += dst_pitch) {
6959 : if (memcmp(dst, src, rowbytes) != 0) {
6961 : exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
6967 : exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
6973 : * Performs migration of the pixmaps according to the operation information
6974 : * provided in pixmaps and can_accel and the migration scheme chosen in the
6978 :exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
6979 12 0.0131 :{ /* exaDoMigration total: 166 0.1808 */
6980 : ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
6981 17 0.0185 : ExaScreenPriv(pScreen);
6984 3 0.0033 : if (! can_accel)
6987 : /* If this debugging flag is set, check each pixmap for whether it is marked
6988 : * as clean, and if so, actually check if that's the case. This should help
6989 : * catch issues with failing to mark a drawable as dirty. While it will
6990 : * catch them late (after the operation happened), it at least explains what
6991 : * went wrong, and instrumenting the code to find what operation happened
6992 : * to the pixmap last shouldn't be hard.
6994 9 0.0098 : if (pExaScr->checkDirtyCorrectness) {
6995 1 0.0011 : for (i = 0; i < npixmaps; i++) {
6996 : if (!exaPixmapIsDirty (pixmaps[i].pPix) &&
6997 : !exaAssertNotDirty (pixmaps[i].pPix))
6998 : ErrorF("%s: Pixmap %d dirty but not marked as such!\n", __func__, i);
7001 : /* If anything is pinned in system memory, we won't be able to
7004 16 0.0174 : for (i = 0; i < npixmaps; i++) {
7005 22 0.0240 : if (exaPixmapIsPinned (pixmaps[i].pPix) &&
7006 : !exaPixmapIsOffscreen (pixmaps[i].pPix))
7009 : EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix,
7010 : pixmaps[i].pPix->drawable.width,
7011 : pixmaps[i].pPix->drawable.height));
7012 : can_accel = FALSE;
7017 2 0.0022 : if (pExaScr->migration == ExaMigrationSmart) {
7018 : /* If we've got something as a destination that we shouldn't cause to
7019 : * become newly dirtied, take the unaccelerated route.
7021 : for (i = 0; i < npixmaps; i++) {
7022 : if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB (pixmaps[i].pPix) &&
7023 : !exaPixmapIsDirty (pixmaps[i].pPix))
7025 : for (i = 0; i < npixmaps; i++) {
7026 : if (!exaPixmapIsDirty (pixmaps[i].pPix))
7027 : exaMoveOutPixmap (pixmaps[i].pPix);
7033 : /* If we aren't going to accelerate, then we migrate everybody toward
7034 : * system memory, and kick out if it's free.
7037 : for (i = 0; i < npixmaps; i++) {
7038 : exaMigrateTowardSys (pixmaps[i].pPix);
7039 : if (!exaPixmapIsDirty (pixmaps[i].pPix))
7040 : exaMoveOutPixmap (pixmaps[i].pPix);
7045 : /* Finally, the acceleration path. Move them all in. */
7046 : for (i = 0; i < npixmaps; i++) {
7047 : exaMigrateTowardFb(pixmaps[i].pPix);
7048 : exaMoveInPixmap(pixmaps[i].pPix);
7050 : } else if (pExaScr->migration == ExaMigrationGreedy) {
7051 : /* If we can't accelerate, either because the driver can't or because one of
7052 : * the pixmaps is pinned in system memory, then we migrate everybody toward
7055 : * We also migrate toward system if all pixmaps involved are currently in
7056 : * system memory -- this can mitigate thrashing when there are significantly
7057 : * more pixmaps active than would fit in memory.
7059 : * If not, then we migrate toward FB so that hopefully acceleration can
7063 : for (i = 0; i < npixmaps; i++)
7064 : exaMigrateTowardSys (pixmaps[i].pPix);
7068 : for (i = 0; i < npixmaps; i++) {
7069 : if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
7070 : /* Found one in FB, so move all to FB. */
7071 : for (j = 0; j < npixmaps; j++)
7072 : exaMigrateTowardFb(pixmaps[j].pPix);
7077 : /* Nobody's in FB, so move all away from FB. */
7078 : for (i = 0; i < npixmaps; i++)
7079 : exaMigrateTowardSys(pixmaps[i].pPix);
7080 3 0.0033 : } else if (pExaScr->migration == ExaMigrationAlways) {
7081 : /* Always move the pixmaps out if we can't accelerate. If we can
7082 : * accelerate, try to move them all in. If that fails, then move them
7086 : for (i = 0; i < npixmaps; i++)
7087 : exaMoveOutPixmap(pixmaps[i].pPix);
7091 : /* Now, try to move them all into FB */
7092 21 0.0229 : for (i = 0; i < npixmaps; i++) {
7093 18 0.0196 : exaMoveInPixmap(pixmaps[i].pPix);
7094 11 0.0120 : ExaOffscreenMarkUsed (pixmaps[i].pPix);
7097 : /* If we couldn't fit everything in, then kick back out */
7098 6 0.0065 : for (i = 0; i < npixmaps; i++) {
7099 17 0.0185 : if (!exaPixmapIsOffscreen(pixmaps[i].pPix)) {
7101 : EXA_FALLBACK(("Pixmap %p (%dx%d) not in fb\n", pixmaps[i].pPix,
7102 : pixmaps[i].pPix->drawable.width,
7103 : pixmaps[i].pPix->drawable.height));
7104 : for (j = 0; j < npixmaps; j++)
7105 : exaMoveOutPixmap(pixmaps[j].pPix);
7112 * Total samples for file : "/home/cworth/src/xorg/xserver/render/mipict.c"
7120 : * Copyright © 1999 Keith Packard
7122 : * Permission to use, copy, modify, distribute, and sell this software and its
7123 : * documentation for any purpose is hereby granted without fee, provided that
7124 : * the above copyright notice appear in all copies and that both that
7125 : * copyright notice and this permission notice appear in supporting
7126 : * documentation, and that the name of Keith Packard not be used in
7127 : * advertising or publicity pertaining to distribution of the software without
7128 : * specific, written prior permission. Keith Packard makes no
7129 : * representations about the suitability of this software for any purpose. It
7130 : * is provided "as is" without express or implied warranty.
7132 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
7133 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
7134 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
7135 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
7136 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
7137 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
7138 : * PERFORMANCE OF THIS SOFTWARE.
7141 :#ifdef HAVE_DIX_CONFIG_H
7142 :#include <dix-config.h>
7145 :#include "scrnintstr.h"
7146 :#include "gcstruct.h"
7147 :#include "pixmapstr.h"
7148 :#include "windowstr.h"
7150 :#include "picturestr.h"
7151 :#include "mipict.h"
7158 :miCreatePicture (PicturePtr pPicture)
7159 1 0.0011 :{ /* miCreatePicture total: 2 0.0022 */
7164 :miDestroyPicture (PicturePtr pPicture)
7165 3 0.0033 :{ /* miDestroyPicture total: 4 0.0044 */
7166 : if (pPicture->freeCompClip)
7167 1 0.0011 : REGION_DESTROY(pPicture->pDrawable->pScreen, pPicture->pCompositeClip);
7171 :miDestroyPictureClip (PicturePtr pPicture)
7173 : switch (pPicture->clientClipType) {
7177 : (*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip));
7181 : * we know we'll never have a list of rectangles, since ChangeClip
7182 : * immediately turns them into a region
7184 : REGION_DESTROY(pPicture->pDrawable->pScreen, pPicture->clientClip);
7187 : pPicture->clientClip = NULL;
7188 : pPicture->clientClipType = CT_NONE;
7192 :miChangePictureClip (PicturePtr pPicture,
7196 :{ /* miChangePictureClip total: 1 0.0011 */
7197 : ScreenPtr pScreen = pPicture->pDrawable->pScreen;
7198 1 0.0011 : PictureScreenPtr ps = GetPictureScreen(pScreen);
7199 : pointer clientClip;
7200 : int clientClipType;
7204 : /* convert the pixmap to a region */
7205 : clientClip = (pointer) BITMAP_TO_REGION(pScreen, (PixmapPtr) value);
7208 : clientClipType = CT_REGION;
7209 : (*pScreen->DestroyPixmap) ((PixmapPtr) value);
7212 : clientClip = value;
7213 : clientClipType = CT_REGION;
7217 : clientClipType = CT_NONE;
7220 : clientClip = (pointer) RECTS_TO_REGION(pScreen, n,
7221 : (xRectangle *) value,
7225 : clientClipType = CT_REGION;
7229 : (*ps->DestroyPictureClip) (pPicture);
7230 : pPicture->clientClip = clientClip;
7231 : pPicture->clientClipType = clientClipType;
7232 : pPicture->stateChanges |= CPClipMask;
7237 :miChangePicture (PicturePtr pPicture,
7239 :{ /* miChangePicture total: 1 0.0011 */
7244 :miValidatePicture (PicturePtr pPicture,
7246 3 0.0033 :{ /* miValidatePicture total: 9 0.0098 */
7247 : DrawablePtr pDrawable = pPicture->pDrawable;
7249 : if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) ||
7250 : (pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS)))
7252 1 0.0011 : if (pDrawable->type == DRAWABLE_WINDOW)
7254 : WindowPtr pWin = (WindowPtr) pDrawable;
7255 : RegionPtr pregWin;
7256 : Bool freeTmpClip, freeCompClip;
7258 : if (pPicture->subWindowMode == IncludeInferiors)
7260 : pregWin = NotClippedByChildren(pWin);
7261 : freeTmpClip = TRUE;
7265 : pregWin = &pWin->clipList;
7266 : freeTmpClip = FALSE;
7268 : freeCompClip = pPicture->freeCompClip;
7271 : * if there is no client clip, we can get by with just keeping the
7272 : * pointer we got, and remembering whether or not should destroy
7273 : * (or maybe re-use) it later. this way, we avoid unnecessary
7274 : * copying of regions. (this wins especially if many clients clip
7275 : * by children and have no client clip.)
7277 : if (pPicture->clientClipType == CT_NONE)
7280 : REGION_DESTROY(pScreen, pPicture->pCompositeClip);
7281 : pPicture->pCompositeClip = pregWin;
7282 : pPicture->freeCompClip = freeTmpClip;
7287 : * we need one 'real' region to put into the composite clip. if
7288 : * pregWin the current composite clip are real, we can get rid of
7289 : * one. if pregWin is real and the current composite clip isn't,
7290 : * use pregWin for the composite clip. if the current composite
7291 : * clip is real and pregWin isn't, use the current composite
7292 : * clip. if neither is real, create a new region.
7295 : REGION_TRANSLATE(pScreen, pPicture->clientClip,
7296 : pDrawable->x + pPicture->clipOrigin.x,
7297 : pDrawable->y + pPicture->clipOrigin.y);
7301 : REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
7302 : pregWin, pPicture->clientClip);
7304 : REGION_DESTROY(pScreen, pregWin);
7306 : else if (freeTmpClip)
7308 : REGION_INTERSECT(pScreen, pregWin, pregWin, pPicture->clientClip);
7309 : pPicture->pCompositeClip = pregWin;
7313 : pPicture->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
7314 : REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
7315 : pregWin, pPicture->clientClip);
7317 : pPicture->freeCompClip = TRUE;
7318 : REGION_TRANSLATE(pScreen, pPicture->clientClip,
7319 : -(pDrawable->x + pPicture->clipOrigin.x),
7320 : -(pDrawable->y + pPicture->clipOrigin.y));
7322 : } /* end of composite clip for a window */
7327 : /* XXX should we translate by drawable.x/y here ? */
7328 : /* If you want pixmaps in offscreen memory, yes */
7329 1 0.0011 : pixbounds.x1 = pDrawable->x;
7330 : pixbounds.y1 = pDrawable->y;
7331 : pixbounds.x2 = pDrawable->x + pDrawable->width;
7332 : pixbounds.y2 = pDrawable->y + pDrawable->height;
7334 : if (pPicture->freeCompClip)
7336 : REGION_RESET(pScreen, pPicture->pCompositeClip, &pixbounds);
7340 : pPicture->freeCompClip = TRUE;
7341 3 0.0033 : pPicture->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
7344 : if (pPicture->clientClipType == CT_REGION)
7346 : if(pDrawable->x || pDrawable->y) {
7347 : REGION_TRANSLATE(pScreen, pPicture->clientClip,
7348 : pDrawable->x + pPicture->clipOrigin.x,
7349 : pDrawable->y + pPicture->clipOrigin.y);
7350 : REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
7351 : pPicture->pCompositeClip, pPicture->clientClip);
7352 : REGION_TRANSLATE(pScreen, pPicture->clientClip,
7353 : -(pDrawable->x + pPicture->clipOrigin.x),
7354 : -(pDrawable->y + pPicture->clipOrigin.y));
7356 : REGION_TRANSLATE(pScreen, pPicture->pCompositeClip,
7357 : -pPicture->clipOrigin.x, -pPicture->clipOrigin.y);
7358 : REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
7359 : pPicture->pCompositeClip, pPicture->clientClip);
7360 : REGION_TRANSLATE(pScreen, pPicture->pCompositeClip,
7361 : pPicture->clipOrigin.x, pPicture->clipOrigin.y);
7364 : } /* end of composite clip for pixmap */
7369 :miChangePictureTransform (PicturePtr pPicture,
7370 : PictTransform *transform)
7371 1 0.0011 :{ /* miChangePictureTransform total: 1 0.0011 */
7376 :miChangePictureFilter (PicturePtr pPicture,
7380 1 0.0011 :{ /* miChangePictureFilter total: 1 0.0011 */
7384 :#define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
7386 :static inline pixman_bool_t
7387 :miClipPictureReg (pixman_region16_t * pRegion,
7388 : pixman_region16_t * pClip,
7392 : if (pixman_region_n_rects(pRegion) == 1 &&
7393 : pixman_region_n_rects(pClip) == 1)
7395 : pixman_box16_t * pRbox = pixman_region_rectangles(pRegion, NULL);
7396 : pixman_box16_t * pCbox = pixman_region_rectangles(pClip, NULL);
7399 : if (pRbox->x1 < (v = pCbox->x1 + dx))
7400 : pRbox->x1 = BOUND(v);
7401 : if (pRbox->x2 > (v = pCbox->x2 + dx))
7402 : pRbox->x2 = BOUND(v);
7403 : if (pRbox->y1 < (v = pCbox->y1 + dy))
7404 : pRbox->y1 = BOUND(v);
7405 : if (pRbox->y2 > (v = pCbox->y2 + dy))
7406 : pRbox->y2 = BOUND(v);
7407 : if (pRbox->x1 >= pRbox->x2 ||
7408 : pRbox->y1 >= pRbox->y2)
7410 : pixman_region_init (pRegion);
7413 : else if (!pixman_region_not_empty (pClip))
7418 : pixman_region_translate (pRegion, -dx, -dy);
7419 : if (!pixman_region_intersect (pRegion, pRegion, pClip))
7422 : pixman_region_translate(pRegion, dx, dy);
7424 : return pixman_region_not_empty(pRegion);
7427 :static __inline Bool
7428 :miClipPictureSrc (RegionPtr pRegion,
7429 : PicturePtr pPicture,
7433 : /* XXX what to do with clipping from transformed pictures? */
7434 : if (pPicture->transform || !pPicture->pDrawable)
7436 : if (pPicture->repeat)
7438 : if (pPicture->clientClipType != CT_NONE)
7440 : pixman_region_translate ( pRegion,
7441 : dx - pPicture->clipOrigin.x,
7442 : dy - pPicture->clipOrigin.y);
7443 : if (!REGION_INTERSECT (pScreen, pRegion, pRegion,
7444 : (RegionPtr) pPicture->pCompositeClip)) // clientClip))
7446 : pixman_region_translate ( pRegion,
7447 : - (dx - pPicture->clipOrigin.x),
7448 : - (dy - pPicture->clipOrigin.y));
7454 : return miClipPictureReg (pRegion,
7455 : pPicture->pCompositeClip,
7462 :miCompositeSourceValidate (PicturePtr pPicture,
7467 31 0.0338 :{ /* miCompositeSourceValidate total: 106 0.1155 */
7468 8 0.0087 : DrawablePtr pDrawable = pPicture->pDrawable;
7469 : ScreenPtr pScreen;
7471 4 0.0044 : if (!pDrawable)
7474 11 0.0120 : pScreen = pDrawable->pScreen;
7476 18 0.0196 : if (pScreen->SourceValidate)
7478 : x -= pPicture->pDrawable->x;
7479 12 0.0131 : y -= pPicture->pDrawable->y;
7480 3 0.0033 : if (pPicture->transform)
7484 : int xmin, ymin, xmax, ymax;
7486 :#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; }
7487 : VectorSet (0, x, y);
7488 : VectorSet (1, x + width, y);
7489 : VectorSet (2, x, y + height);
7490 : VectorSet (3, x + width, y + height);
7491 : xmin = ymin = 32767;
7492 : xmax = ymax = -32737;
7493 : for (i = 0; i < 4; i++)
7496 : t.vector[0] = IntToxFixed (points[i].x);
7497 : t.vector[1] = IntToxFixed (points[i].y);
7498 : t.vector[2] = xFixed1;
7499 : if (PictureTransformPoint (pPicture->transform, &t))
7501 : int tx = xFixedToInt (t.vector[0]);
7502 : int ty = xFixedToInt (t.vector[1]);
7503 : if (tx < xmin) xmin = tx;
7504 : if (tx > xmax) xmax = tx;
7505 : if (ty < ymin) ymin = ty;
7506 : if (ty > ymax) ymax = ty;
7511 : width = xmax - xmin;
7512 : height = ymax - ymin;
7514 10 0.0109 : (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
7519 : * returns FALSE if the final region is empty. Indistinguishable from
7520 : * an allocation failure, but rendering ignores those anyways.
7524 :miComputeCompositeRegion (RegionPtr pRegion,
7536 28 0.0305 :{ /* miComputeCompositeRegion total: 296 0.3225 */
7540 2 0.0022 : pRegion->extents.x1 = xDst;
7541 9 0.0098 : v = xDst + width;
7542 10 0.0109 : pRegion->extents.x2 = BOUND(v);
7543 : pRegion->extents.y1 = yDst;
7544 4 0.0044 : v = yDst + height;
7545 9 0.0098 : pRegion->extents.y2 = BOUND(v);
7546 2 0.0022 : pRegion->data = 0;
7547 : /* Check for empty operation */
7548 8 0.0087 : if (pRegion->extents.x1 >= pRegion->extents.x2 ||
7549 : pRegion->extents.y1 >= pRegion->extents.y2)
7551 1 0.0011 : pixman_region_init (pRegion);
7554 : /* clip against dst */
7555 8 0.0087 : if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0))
7557 : pixman_region_fini (pRegion);
7560 : if (pDst->alphaMap)
7562 : if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip,
7563 : -pDst->alphaOrigin.x,
7564 : -pDst->alphaOrigin.y))
7566 : pixman_region_fini (pRegion);
7570 : /* clip against src */
7571 10 0.0109 : if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
7573 : pixman_region_fini (pRegion);
7576 5 0.0054 : if (pSrc->alphaMap)
7578 : if (!miClipPictureSrc (pRegion, pSrc->alphaMap,
7579 : xDst - (xSrc + pSrc->alphaOrigin.x),
7580 : yDst - (ySrc + pSrc->alphaOrigin.y)))
7582 : pixman_region_fini (pRegion);
7586 : /* clip against mask */
7587 5 0.0054 : if (pMask)
7589 2 0.0022 : if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
7591 : pixman_region_fini (pRegion);
7594 3 0.0033 : if (pMask->alphaMap)
7596 : if (!miClipPictureSrc (pRegion, pMask->alphaMap,
7597 : xDst - (xMask + pMask->alphaOrigin.x),
7598 : yDst - (yMask + pMask->alphaOrigin.y)))
7600 : pixman_region_fini (pRegion);
7607 23 0.0251 : miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
7609 7 0.0076 : miCompositeSourceValidate (pMask, xMask, yMask, width, height);
7615 :miRenderColorToPixel (PictFormatPtr format,
7616 : xRenderColor *color,
7618 :{ /* miRenderColorToPixel total: 5 0.0054 */
7619 : CARD32 r, g, b, a;
7620 : miIndexedPtr pIndexed;
7622 1 0.0011 : switch (format->type) {
7623 : case PictTypeDirect:
7624 1 0.0011 : r = color->red >> (16 - Ones (format->direct.redMask));
7625 1 0.0011 : g = color->green >> (16 - Ones (format->direct.greenMask));
7626 : b = color->blue >> (16 - Ones (format->direct.blueMask));
7627 : a = color->alpha >> (16 - Ones (format->direct.alphaMask));
7628 : r = r << format->direct.red;
7629 : g = g << format->direct.green;
7630 : b = b << format->direct.blue;
7631 : a = a << format->direct.alpha;
7632 2 0.0022 : *pixel = r|g|b|a;
7634 : case PictTypeIndexed:
7635 : pIndexed = (miIndexedPtr) (format->index.devPrivate);
7636 : if (pIndexed->color)
7638 : r = color->red >> 11;
7639 : g = color->green >> 11;
7640 : b = color->blue >> 11;
7641 : *pixel = miIndexToEnt15 (pIndexed, (r << 10) | (g << 5) | b);
7645 : r = color->red >> 8;
7646 : g = color->green >> 8;
7647 : b = color->blue >> 8;
7648 : *pixel = miIndexToEntY24 (pIndexed, (r << 16) | (g << 8) | b);
7655 :miFillColor (CARD32 pixel, int bits)
7659 : pixel |= pixel << bits;
7662 : return (CARD16) pixel;
7666 :miIsSolidAlpha (PicturePtr pSrc)
7668 : ScreenPtr pScreen;
7671 : if (!pSrc->pDrawable)
7674 : pScreen = pSrc->pDrawable->pScreen;
7677 : if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A)
7680 : if (!pSrc->repeat)
7683 : if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1)
7686 : (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, 1, 1, ZPixmap, ~0L, line);
7687 : switch (pSrc->pDrawable->bitsPerPixel) {
7689 : return (CARD8) line[0] == 1 || (CARD8) line[0] == 0x80;
7691 : return (CARD8) line[0] == 0xf || (CARD8) line[0] == 0xf0;
7693 : return (CARD8) line[0] == 0xff;
7700 :miRenderPixelToColor (PictFormatPtr format,
7702 : xRenderColor *color)
7704 : CARD32 r, g, b, a;
7705 : miIndexedPtr pIndexed;
7707 : switch (format->type) {
7708 : case PictTypeDirect:
7709 : r = (pixel >> format->direct.red) & format->direct.redMask;
7710 : g = (pixel >> format->direct.green) & format->direct.greenMask;
7711 : b = (pixel >> format->direct.blue) & format->direct.blueMask;
7712 : a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
7713 : color->red = miFillColor (r, Ones (format->direct.redMask));
7714 : color->green = miFillColor (g, Ones (format->direct.greenMask));
7715 : color->blue = miFillColor (b, Ones (format->direct.blueMask));
7716 : color->alpha = miFillColor (a, Ones (format->direct.alphaMask));
7718 : case PictTypeIndexed:
7719 : pIndexed = (miIndexedPtr) (format->index.devPrivate);
7720 : pixel = pIndexed->rgba[pixel & (MI_MAX_INDEXED-1)];
7721 : r = (pixel >> 16) & 0xff;
7722 : g = (pixel >> 8) & 0xff;
7723 : b = (pixel ) & 0xff;
7724 : color->red = miFillColor (r, 8);
7725 : color->green = miFillColor (g, 8);
7726 : color->blue = miFillColor (b, 8);
7727 : color->alpha = 0xffff;
7733 :miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
7735 : PictureScreenPtr ps;
7737 : if (!PictureInit (pScreen, formats, nformats))
7739 : ps = GetPictureScreen(pScreen);
7740 : ps->CreatePicture = miCreatePicture;
7741 : ps->DestroyPicture = miDestroyPicture;
7742 : ps->ChangePictureClip = miChangePictureClip;
7743 : ps->DestroyPictureClip = miDestroyPictureClip;
7744 : ps->ChangePicture = miChangePicture;
7745 : ps->ValidatePicture = miValidatePicture;
7746 : ps->InitIndexed = miInitIndexed;
7747 : ps->CloseIndexed = miCloseIndexed;
7748 : ps->UpdateIndexed = miUpdateIndexed;
7749 : ps->ChangePictureTransform = miChangePictureTransform;
7750 : ps->ChangePictureFilter = miChangePictureFilter;
7751 : ps->RealizeGlyph = miRealizeGlyph;
7752 : ps->UnrealizeGlyph = miUnrealizeGlyph;
7754 : /* MI rendering routines */
7755 : ps->Composite = 0; /* requires DDX support */
7756 : ps->Glyphs = miGlyphs;
7757 : ps->CompositeRects = miCompositeRects;
7758 : ps->Trapezoids = miTrapezoids;
7759 : ps->Triangles = miTriangles;
7760 : ps->TriStrip = miTriStrip;
7761 : ps->TriFan = miTriFan;
7763 : ps->RasterizeTrapezoid = 0; /* requires DDX support */
7764 : ps->AddTraps = 0; /* requires DDX support */
7765 : ps->AddTriangles = 0; /* requires DDX support */
7770 * Total samples for file : "/home/cworth/src/xorg/driver/xf86-video-intel/src/i830_exa.c"
7776 :/**************************************************************************
7778 :Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
7779 :All Rights Reserved.
7780 :Copyright (c) 2005 Jesse Barnes <jbarnes@virtuousgeek.org>
7781 : Based on code from i830_xaa.c.
7783 :Permission is hereby granted, free of charge, to any person obtaining a
7784 :copy of this software and associated documentation files (the
7785 :"Software"), to deal in the Software without restriction, including
7786 :without limitation the rights to use, copy, modify, merge, publish,
7787 :distribute, sub license, and/or sell copies of the Software, and to
7788 :permit persons to whom the Software is furnished to do so, subject to
7789 :the following conditions:
7791 :The above copyright notice and this permission notice (including the
7792 :next paragraph) shall be included in all copies or substantial portions
7795 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7796 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7797 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
7798 :IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
7799 :ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7800 :TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
7801 :SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7803 :**************************************************************************/
7805 :#ifdef HAVE_CONFIG_H
7806 :#include "config.h"
7810 :#include "xaarop.h"
7812 :#include "i810_reg.h"
7813 :#include "i830_reg.h"
7814 :#include <string.h>
7817 :#define DEBUG_I830FALLBACK 1
7820 :#define ALWAYS_SYNC 0
7822 :#ifdef DEBUG_I830FALLBACK
7823 :#define I830FALLBACK(s, arg...) \
7825 : DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
7829 :#define I830FALLBACK(s, arg...) \
7835 :const int I830CopyROP[16] =
7837 : ROP_0, /* GXclear */
7838 : ROP_DSa, /* GXand */
7839 : ROP_SDna, /* GXandReverse */
7840 : ROP_S, /* GXcopy */
7841 : ROP_DSna, /* GXandInverted */
7842 : ROP_D, /* GXnoop */
7843 : ROP_DSx, /* GXxor */
7844 : ROP_DSo, /* GXor */
7845 : ROP_DSon, /* GXnor */
7846 : ROP_DSxn, /* GXequiv */
7847 : ROP_Dn, /* GXinvert*/
7848 : ROP_SDno, /* GXorReverse */
7849 : ROP_Sn, /* GXcopyInverted */
7850 : ROP_DSno, /* GXorInverted */
7851 : ROP_DSan, /* GXnand */
7855 :const int I830PatternROP[16] =
7876 : * I830EXASync - wait for a command to finish
7877 : * @pScreen: current screen
7878 : * @marker: marker command to wait for
7880 : * Wait for the command specified by @marker to finish, then return. We don't
7881 : * actually do marker waits, though we might in the future. For now, just
7882 : * wait for a full idle.
7885 :I830EXASync(ScreenPtr pScreen, int marker)
7886 4 0.0044 :{ /* I830EXASync total: 19 0.0207 */
7887 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
7889 3 0.0033 : I830Sync(pScrn);
7893 : * I830EXAPrepareSolid - prepare for a Solid operation, if possible
7896 :I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
7897 :{ /* I830EXAPrepareSolid total: 10 0.0109 */
7898 : ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
7899 2 0.0022 : I830Ptr pI830 = I830PTR(pScrn);
7900 : unsigned long offset, pitch;
7902 1 0.0011 : if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planemask))
7903 : I830FALLBACK("planemask is not solid");
7905 : if (pPixmap->drawable.bitsPerPixel == 24)
7906 : I830FALLBACK("solid 24bpp unsupported!\n");
7908 : offset = exaGetPixmapOffset(pPixmap);
7909 : pitch = exaGetPixmapPitch(pPixmap);
7911 4 0.0044 : if ( offset % pI830->EXADriverPtr->pixmapOffsetAlign != 0)
7912 : I830FALLBACK("pixmap offset not aligned");
7913 1 0.0011 : if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0)
7914 : I830FALLBACK("pixmap pitch not aligned");
7916 1 0.0011 : pI830->BR[13] = (pitch & 0xffff);
7917 : switch (pPixmap->drawable.bitsPerPixel) {
7922 : pI830->BR[13] |= (1 << 24);
7926 1 0.0011 : pI830->BR[13] |= ((1 << 24) | (1 << 25));
7929 : pI830->BR[13] |= (I830PatternROP[alu] & 0xff) << 16 ;
7930 : pI830->BR[16] = fg;
7935 :I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
7936 2 0.0022 :{ /* I830EXASolid total: 38 0.0414 */
7937 : ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
7938 : I830Ptr pI830 = I830PTR(pScrn);
7939 : unsigned long offset;
7941 1 0.0011 : offset = exaGetPixmapOffset(pPixmap);
7944 1 0.0011 : BEGIN_LP_RING(6);
7945 : if (pPixmap->drawable.bitsPerPixel == 32)
7946 4 0.0044 : OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA
7947 : | XY_COLOR_BLT_WRITE_RGB);
7949 : OUT_RING(XY_COLOR_BLT_CMD);
7951 1 0.0011 : OUT_RING(pI830->BR[13]);
7952 3 0.0033 : OUT_RING((y1 << 16) | (x1 & 0xffff));
7953 : OUT_RING((y2 << 16) | (x2 & 0xffff));
7955 : OUT_RING(pI830->BR[16]);
7956 3 0.0033 : ADVANCE_LP_RING();
7961 :I830EXADoneSolid(PixmapPtr pPixmap)
7964 : ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
7972 : * - support planemask using FULL_BLT_CMD?
7975 :I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
7976 : int ydir, int alu, Pixel planemask)
7978 : ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
7979 : I830Ptr pI830 = I830PTR(pScrn);
7981 : if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planemask))
7982 : I830FALLBACK("planemask is not solid");
7984 : pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
7985 : pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
7987 : pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
7988 : pI830->BR[13] |= I830CopyROP[alu] << 16;
7990 : switch (pSrcPixmap->drawable.bitsPerPixel) {
7994 : pI830->BR[13] |= (1 << 24);
7997 : pI830->BR[13] |= ((1 << 25) | (1 << 24));
8004 :I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
8005 : int dst_y1, int w, int h)
8007 : ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
8008 : I830Ptr pI830 = I830PTR(pScrn);
8009 : int dst_x2, dst_y2;
8010 : unsigned int dst_off;
8012 : dst_x2 = dst_x1 + w;
8013 : dst_y2 = dst_y1 + h;
8015 : dst_off = exaGetPixmapOffset(pDstPixmap);
8020 : if (pDstPixmap->drawable.bitsPerPixel == 32)
8021 : OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
8022 : XY_SRC_COPY_BLT_WRITE_RGB);
8024 : OUT_RING(XY_SRC_COPY_BLT_CMD);
8026 : OUT_RING(pI830->BR[13]);
8027 : OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
8028 : OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
8029 : OUT_RING(dst_off);
8030 : OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
8031 : OUT_RING(pI830->copy_src_pitch);
8032 : OUT_RING(pI830->copy_src_off);
8034 : ADVANCE_LP_RING();
8039 :I830EXADoneCopy(PixmapPtr pDstPixmap)
8042 : ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
8048 :#define xFixedToFloat(val) \
8049 : ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0))
8052 : * Returns the floating-point coordinates transformed by the given transform.
8054 : * transform may be null.
8057 :i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
8058 : float *x_out, float *y_out)
8059 68 0.0741 :{ /* i830_get_transformed_coordinates total: 187 0.2037 */
8060 13 0.0142 : if (transform == NULL) {
8061 39 0.0425 : *x_out = x;
8062 35 0.0381 : *y_out = y;
8066 : v.vector[0] = IntToxFixed(x);
8067 : v.vector[1] = IntToxFixed(y);
8068 : v.vector[2] = xFixed1;
8069 : PictureTransformPoint(transform, &v);
8070 : *x_out = xFixedToFloat(v.vector[0]);
8071 : *y_out = xFixedToFloat(v.vector[1]);
8076 : * Uploads data from system memory to the framebuffer using a series of
8077 : * 8x8 pattern blits.
8080 :i830_upload_to_screen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
8083 : ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
8084 : I830Ptr pI830 = I830PTR(pScrn);
8085 : const int uts_width_max = 16, uts_height_max = 16;
8086 : int cpp = pDst->drawable.bitsPerPixel / 8;
8091 : if (w > uts_width_max || h > uts_height_max)
8092 : I830FALLBACK("too large for upload to screen (%d,%d)", w, h);
8094 : offset = exaGetPixmapOffset(pDst);
8096 : br13 = exaGetPixmapPitch(pDst);
8097 : br13 |= ((I830PatternROP[GXcopy] & 0xff) << 16);
8098 : switch (pDst->drawable.bitsPerPixel) {
8107 : for (sub_y = 0; sub_y < uts_height_max && sub_y < h; sub_y += 8) {
8110 : if (sub_y + 8 > h)
8111 : sub_height = h - sub_y;
8115 : for (sub_x = 0; sub_x < uts_width_max && sub_x < w; sub_x += 8) {
8116 : int sub_width, line;
8117 : char *src_line = src + sub_y * src_pitch + sub_x * cpp;
8119 : if (sub_x + 8 > w)
8120 : sub_width = w - sub_x;
8124 : BEGIN_LP_RING(6 + (cpp * 8 * 8 / 4));
8126 : /* XXX We may need a pattern offset here for {x,y} % 8 != 0*/
8127 : OUT_RING(XY_PAT_BLT_IMMEDIATE |
8128 : XY_SRC_COPY_BLT_WRITE_ALPHA |
8129 : XY_SRC_COPY_BLT_WRITE_RGB |
8130 : (3 + cpp * 8 * 8 / 4));
8132 : OUT_RING(((y + sub_y) << 16) | (x + sub_x));
8133 : OUT_RING(((y + sub_y + sub_height) << 16) |
8134 : (x + sub_x + sub_width));
8137 : /* Write out the lines with valid data, followed by any needed
8140 : for (line = 0; line < sub_height; line++) {
8141 : OUT_RING_COPY(sub_width * cpp, src_line);
8142 : src_line += src_pitch;
8143 : if (sub_width != 8)
8144 : OUT_RING_PAD((8 - sub_width) * cpp);
8146 : /* Write out any full padding lines to follow */
8147 : if (sub_height != 8)
8148 : OUT_RING_PAD(8 * cpp * (8 - sub_height));
8150 : OUT_RING(MI_NOOP);
8151 : ADVANCE_LP_RING();
8155 : exaMarkSync(pDst->drawable.pScreen);
8156 : /* exaWaitSync(pDst->drawable.pScreen); */
8167 :I830EXAInit(ScreenPtr pScreen)
8169 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
8170 : I830Ptr pI830 = I830PTR(pScrn);
8172 : pI830->EXADriverPtr = exaDriverAlloc();
8173 : if (pI830->EXADriverPtr == NULL) {
8174 : pI830->noAccel = TRUE;
8177 : memset(pI830->EXADriverPtr, 0, sizeof(*pI830->EXADriverPtr));
8179 : pI830->bufferOffset = 0;
8180 : pI830->EXADriverPtr->exa_major = 2;
8181 : pI830->EXADriverPtr->exa_minor = 1;
8182 : pI830->EXADriverPtr->memoryBase = pI830->FbBase;
8183 : pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
8184 : pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
8185 : pI830->exa_offscreen->size;
8186 : pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
8188 : DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
8189 : pI830->EXADriverPtr->memoryBase,
8190 : pI830->EXADriverPtr->memoryBase + pI830->EXADriverPtr->memorySize,
8191 : pI830->EXADriverPtr->offScreenBase,
8192 : pI830->EXADriverPtr->memorySize);
8195 : /* Limits are described in the BLT engine chapter under Graphics Data Size
8196 : * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO,
8197 : * 3DSTATE_DRAWING_RECTANGLE, 3DSTATE_MAP_INFO, and 3DSTATE_MAP_INFO.
8199 : * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768.
8201 : * i965 limits 3D surface to (2*element size)-aligned offset if un-tiled.
8202 : * i965 limits 3D surface to 4kB-aligned offset if tiled.
8203 : * i965 limits 3D surfaces to w,h of ?,8192.
8204 : * i965 limits 3D surface to pitch of 1B - 128kB.
8205 : * i965 limits 3D surface pitch alignment to 1 or 2 times the element size.
8206 : * i965 limits 3D surface pitch alignment to 512B if tiled.
8207 : * i965 limits 3D destination drawing rect to w,h of 8192,8192.
8209 : * i915 limits 3D textures to 4B-aligned offset if un-tiled.
8210 : * i915 limits 3D textures to ~4kB-aligned offset if tiled.
8211 : * i915 limits 3D textures to width,height of 2048,2048.
8212 : * i915 limits 3D textures to pitch of 16B - 8kB, in dwords.
8213 : * i915 limits 3D destination to ~4kB-aligned offset if tiled.
8214 : * i915 limits 3D destination to pitch of 16B - 8kB, in dwords, if un-tiled.
8215 : * i915 limits 3D destination to pitch of 512B - 8kB, in tiles, if tiled.
8216 : * i915 limits 3D destination to POT aligned pitch if tiled.
8217 : * i915 limits 3D destination drawing rect to w,h of 2048,2048.
8219 : * i845 limits 3D textures to 4B-aligned offset if un-tiled.
8220 : * i845 limits 3D textures to ~4kB-aligned offset if tiled.
8221 : * i845 limits 3D textures to width,height of 2048,2048.
8222 : * i845 limits 3D textures to pitch of 4B - 8kB, in dwords.
8223 : * i845 limits 3D destination to 4B-aligned offset if un-tiled.
8224 : * i845 limits 3D destination to ~4kB-aligned offset if tiled.
8225 : * i845 limits 3D destination to pitch of 8B - 8kB, in dwords.
8226 : * i845 limits 3D destination drawing rect to w,h of 2048,2048.
8228 : * For the tiled issues, the only tiled buffer we draw to should be
8229 : * the front, which will have an appropriate pitch/offset already set up,
8230 : * so EXA doesn't need to worry.
8232 : if (IS_I965G(pI830)) {
8233 : pI830->EXADriverPtr->pixmapOffsetAlign = 4 * 2;
8234 : pI830->EXADriverPtr->pixmapPitchAlign = 16;
8235 : pI830->EXADriverPtr->maxX = 8192;
8236 : pI830->EXADriverPtr->maxY = 8192;
8238 : pI830->EXADriverPtr->pixmapOffsetAlign = 4;
8239 : pI830->EXADriverPtr->pixmapPitchAlign = 16;
8240 : pI830->EXADriverPtr->maxX = 2048;
8241 : pI830->EXADriverPtr->maxY = 2048;
8245 : pI830->EXADriverPtr->WaitMarker = I830EXASync;
8248 : pI830->EXADriverPtr->PrepareSolid = I830EXAPrepareSolid;
8249 : pI830->EXADriverPtr->Solid = I830EXASolid;
8250 : pI830->EXADriverPtr->DoneSolid = I830EXADoneSolid;
8253 : pI830->EXADriverPtr->PrepareCopy = I830EXAPrepareCopy;
8254 : pI830->EXADriverPtr->Copy = I830EXACopy;
8255 : pI830->EXADriverPtr->DoneCopy = I830EXADoneCopy;
8258 : if (!IS_I9XX(pI830)) {
8259 : pI830->EXADriverPtr->CheckComposite = i830_check_composite;
8260 : pI830->EXADriverPtr->PrepareComposite = i830_prepare_composite;
8261 : pI830->EXADriverPtr->Composite = i830_composite;
8262 : pI830->EXADriverPtr->DoneComposite = i830_done_composite;
8263 : } else if (IS_I915G(pI830) || IS_I915GM(pI830) ||
8264 : IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
8266 : pI830->EXADriverPtr->CheckComposite = i915_check_composite;
8267 : pI830->EXADriverPtr->PrepareComposite = i915_prepare_composite;
8268 : pI830->EXADriverPtr->Composite = i830_composite;
8269 : pI830->EXADriverPtr->DoneComposite = i830_done_composite;
8271 : pI830->EXADriverPtr->CheckComposite = i965_check_composite;
8272 : pI830->EXADriverPtr->PrepareComposite = i965_prepare_composite;
8273 : pI830->EXADriverPtr->Composite = i965_composite;
8274 : pI830->EXADriverPtr->DoneComposite = i830_done_composite;
8277 : /* UploadToScreen/DownloadFromScreen */
8279 : pI830->EXADriverPtr->UploadToScreen = i830_upload_to_screen;
8281 : if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
8282 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
8283 : "EXA initialization failed; trying older version\n");
8284 : pI830->EXADriverPtr->exa_minor = 0;
8285 : if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
8286 : xfree(pI830->EXADriverPtr);
8287 : pI830->noAccel = TRUE;
8292 : I830SelectBuffer(pScrn, I830_SELECT_FRONT);
8299 :#ifndef ExaOffscreenMarkUsed
8300 :extern void ExaOffscreenMarkUsed(PixmapPtr);
8304 :I830TexOffsetStart(PixmapPtr pPix)
8306 : exaMoveInPixmap(pPix);
8307 : ExaOffscreenMarkUsed(pPix);
8309 : return exaGetPixmapOffset(pPix);
8313 * Total samples for file : "/home/cworth/src/xorg/xserver/miext/damage/damage.c"
8320 : * Copyright © 2003 Keith Packard
8322 : * Permission to use, copy, modify, distribute, and sell this software and its
8323 : * documentation for any purpose is hereby granted without fee, provided that
8324 : * the above copyright notice appear in all copies and that both that
8325 : * copyright notice and this permission notice appear in supporting
8326 : * documentation, and that the name of Keith Packard not be used in
8327 : * advertising or publicity pertaining to distribution of the software without
8328 : * specific, written prior permission. Keith Packard makes no
8329 : * representations about the suitability of this software for any purpose. It
8330 : * is provided "as is" without express or implied warranty.
8332 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
8333 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
8334 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
8335 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
8336 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
8337 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
8338 : * PERFORMANCE OF THIS SOFTWARE.
8341 :#ifdef HAVE_DIX_CONFIG_H
8342 :#include <dix-config.h>
8345 :#include <stdlib.h>
8348 :#include "scrnintstr.h"
8349 :#include "windowstr.h"
8350 :#include <X11/fonts/font.h>
8351 :#include "dixfontstr.h"
8352 :#include <X11/fonts/fontstruct.h>
8354 :#include "regionstr.h"
8355 :#include "globals.h"
8356 :#include "gcstruct.h"
8357 :#include "damage.h"
8358 :#include "damagestr.h"
8363 :#define wrap(priv, real, mem, func) {\
8364 : priv->mem = real->mem; \
8365 : real->mem = func; \
8368 :#define unwrap(priv, real, mem) {\
8369 : real->mem = priv->mem; \
8372 :#define BOX_SAME(a,b) \
8373 : ((a)->x1 == (b)->x1 && \
8374 : (a)->y1 == (b)->y1 && \
8375 : (a)->x2 == (b)->x2 && \
8376 : (a)->y2 == (b)->y2)
8378 :#define DAMAGE_VALIDATE_ENABLE 0
8379 :#define DAMAGE_DEBUG_ENABLE 0
8380 :#if DAMAGE_DEBUG_ENABLE
8381 :#define DAMAGE_DEBUG(x) ErrorF x
8383 :#define DAMAGE_DEBUG(x)
8386 :#define getPixmapDamageRef(pPixmap) \
8387 : ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
8389 :#define pixmapDamage(pPixmap) damagePixPriv(pPixmap)
8391 :static int damageScrPrivateIndex;
8392 :static int damagePixPrivateIndex;
8393 :static int damageGCPrivateIndex;
8394 :static int damageWinPrivateIndex;
8395 :static int damageGeneration;
8398 :getDrawableDamageRef (DrawablePtr pDrawable)
8399 2 0.0022 :{ /* getDrawableDamageRef total: 6 0.0065 */
8400 : PixmapPtr pPixmap;
8402 : if (pDrawable->type == DRAWABLE_WINDOW)
8404 : ScreenPtr pScreen = pDrawable->pScreen;
8407 : if (pScreen->GetWindowPixmap
8408 :#ifdef ROOTLESS_WORKAROUND
8409 : && ((WindowPtr)pDrawable)->viewable
8412 : pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
8416 : damageScrPriv(pScreen);
8418 : return &pScrPriv->pScreenDamage;
8422 : pPixmap = (PixmapPtr) pDrawable;
8423 : return getPixmapDamageRef (pPixmap);
8426 :#define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable))
8427 :#define getWindowDamage(pWin) getDrawableDamage(&(pWin)->drawable)
8429 :#define drawableDamage(pDrawable) \
8430 : DamagePtr pDamage = getDrawableDamage(pDrawable)
8432 :#define windowDamage(pWin) drawableDamage(&(pWin)->drawable)
8434 :#define winDamageRef(pWindow) \
8435 : DamagePtr *pPrev = (DamagePtr *) \
8436 : &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
8439 :DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion)
8440 1 0.0011 :{ /* DamageReportDamage total: 4 0.0044 */
8442 : RegionRec tmpRegion;
8445 : switch (pDamage->damageLevel) {
8446 : case DamageReportRawRegion:
8447 : (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
8449 : case DamageReportDeltaRegion:
8450 : REGION_NULL (pScreen, &tmpRegion);
8451 : REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
8452 : if (REGION_NOTEMPTY (pScreen, &tmpRegion)) {
8453 : REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
8455 : (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
8457 : REGION_UNINIT(pScreen, &tmpRegion);
8459 : case DamageReportBoundingBox:
8460 : tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
8461 : REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
8463 : if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage))) {
8464 : (*pDamage->damageReport) (pDamage, &pDamage->damage,
8465 : pDamage->closure);
8468 : case DamageReportNonEmpty:
8469 : was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
8470 1 0.0011 : REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
8472 : if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage)) {
8473 : (*pDamage->damageReport) (pDamage, &pDamage->damage,
8474 : pDamage->closure);
8477 : case DamageReportNone:
8478 : REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
8484 :#if DAMAGE_DEBUG_ENABLE
8486 :_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
8487 :#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
8490 :damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
8491 : int subWindowMode)
8493 1 0.0011 :{ /* damageDamageRegion total: 21 0.0229 */
8494 : ScreenPtr pScreen = pDrawable->pScreen;
8495 : damageScrPriv(pScreen);
8496 : drawableDamage(pDrawable);
8498 : RegionRec clippedRec;
8499 : RegionPtr pDamageRegion;
8500 : RegionRec pixClip;
8501 : int draw_x, draw_y;
8503 : int screen_x = 0, screen_y = 0;
8506 : /* short circuit for empty regions */
8507 1 0.0011 : if (!REGION_NOTEMPTY(pScreen, pRegion))
8512 : * When drawing to a pixmap which is storing window contents,
8513 : * the region presented is in pixmap relative coordinates which
8514 : * need to be converted to screen relative coordinates
8516 : if (pDrawable->type != DRAWABLE_WINDOW)
8518 : screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
8519 2 0.0022 : screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
8521 2 0.0022 : if (screen_x || screen_y)
8522 : REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);
8525 : if (pDrawable->type == DRAWABLE_WINDOW &&
8526 : ((WindowPtr)(pDrawable))->backingStore == NotUseful)
8528 : if (subWindowMode == ClipByChildren)
8530 : REGION_INTERSECT(pScreen, pRegion, pRegion,
8531 : &((WindowPtr)(pDrawable))->clipList);
8533 : else if (subWindowMode == IncludeInferiors)
8535 : RegionPtr pTempRegion =
8536 : NotClippedByChildren((WindowPtr)(pDrawable));
8537 : REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion);
8538 : REGION_DESTROY(pScreen, pTempRegion);
8540 : /* If subWindowMode is set to an invalid value, don't perform
8541 : * any drawable-based clipping. */
8545 2 0.0022 : REGION_NULL (pScreen, &clippedRec);
8546 1 0.0011 : for (; pDamage; pDamage = pNext)
8548 1 0.0011 : pNext = pDamage->pNext;
8550 : * Check for internal damage and don't send events
8552 1 0.0011 : if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
8554 : DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
8555 : pScrPriv->internalLevel));
8559 : * Check for unrealized windows
8561 1 0.0011 : if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
8562 : !((WindowPtr) (pDamage->pDrawable))->realized)
8565 : DAMAGE_DEBUG (("damage while window unrealized\n"));
8570 1 0.0011 : draw_x = pDamage->pDrawable->x;
8571 : draw_y = pDamage->pDrawable->y;
8574 : * Need to move everyone to screen coordinates
8575 : * XXX what about off-screen pixmaps with non-zero x/y?
8577 : if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
8579 : draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
8580 : draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
8585 : * Clip against border or pixmap bounds
8588 : pDamageRegion = pRegion;
8589 : if (clip || pDamage->pDrawable != pDrawable)
8591 : pDamageRegion = &clippedRec;
8592 : if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
8593 : REGION_INTERSECT (pScreen, pDamageRegion, pRegion,
8594 : &((WindowPtr)(pDamage->pDrawable))->borderClip);
8599 : box.x2 = draw_x + pDamage->pDrawable->width;
8600 : box.y2 = draw_y + pDamage->pDrawable->height;
8601 1 0.0011 : REGION_INIT(pScreen, &pixClip, &box, 1);
8602 : REGION_INTERSECT (pScreen, pDamageRegion, pRegion, &pixClip);
8603 2 0.0022 : REGION_UNINIT(pScreen, &pixClip);
8606 : * Short circuit empty results
8608 : if (!REGION_NOTEMPTY(pScreen, pDamageRegion))
8612 : DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
8614 : pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
8615 : pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
8616 : pDamageRegion->extents.x1, pDamageRegion->extents.y1,
8617 : pDrawable->id, pDamage->pDrawable->id));
8620 : * Move region to target coordinate space
8622 : if (draw_x || draw_y)
8623 : REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
8625 : /* If the damage rec has been flagged to report damage after the op has
8626 : * completed, then union it into the delayed damage region, which will
8627 : * be used for reporting after calling down, and skip the reporting
8629 1 0.0011 : if (!pDamage->reportAfter) {
8630 : DamageReportDamage (pDamage, pDamageRegion);
8632 1 0.0011 : REGION_UNION(pScreen, &pDamage->pendingDamage,
8633 : &pDamage->pendingDamage, pDamageRegion);
8637 : * translate original region back
8639 1 0.0011 : if (pDamageRegion == pRegion && (draw_x || draw_y))
8640 : REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);
8643 : if (screen_x || screen_y)
8644 : REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);
8647 : REGION_UNINIT (pScreen, &clippedRec);
8651 :damageReportPostOp (DrawablePtr pDrawable)
8652 :{ /* damageReportPostOp total: 3 0.0033 */
8653 : drawableDamage(pDrawable);
8655 : for (; pDamage != NULL; pDamage = pDamage->pNext)
8657 2 0.0022 : if (pDamage->reportAfter) {
8658 : DamageReportDamage (pDamage, &pDamage->pendingDamage);
8659 1 0.0011 : REGION_EMPTY (pScreen, &pDamage->pendingDamage);
8665 :#if DAMAGE_DEBUG_ENABLE
8666 :#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
8668 :_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
8671 :damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
8673 2 0.0022 :{ /* damageDamageBox total: 3 0.0033 */
8676 : REGION_INIT (pDrawable->pScreen, ®ion, pBox, 1);
8677 :#if DAMAGE_DEBUG_ENABLE
8678 : _damageDamageRegion (pDrawable, ®ion, TRUE, subWindowMode, where);
8680 1 0.0011 : damageDamageRegion (pDrawable, ®ion, TRUE, subWindowMode);
8682 : REGION_UNINIT (pDrawable->pScreen, ®ion);
8685 :static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
8686 :static void damageChangeGC(GCPtr, unsigned long);
8687 :static void damageCopyGC(GCPtr, unsigned long, GCPtr);
8688 :static void damageDestroyGC(GCPtr);
8689 :static void damageChangeClip(GCPtr, int, pointer, int);
8690 :static void damageDestroyClip(GCPtr);
8691 :static void damageCopyClip(GCPtr, GCPtr);
8693 :static GCFuncs damageGCFuncs = {
8694 : damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
8695 : damageChangeClip, damageDestroyClip, damageCopyClip
8698 :static GCOps damageGCOps;
8701 :damageCreateGC(GCPtr pGC)
8703 : ScreenPtr pScreen = pGC->pScreen;
8704 : damageScrPriv(pScreen);
8705 : damageGCPriv(pGC);
8708 : pGC->pCompositeClip = 0;
8709 : unwrap (pScrPriv, pScreen, CreateGC);
8710 : if((ret = (*pScreen->CreateGC) (pGC))) {
8711 : pGCPriv->ops = NULL;
8712 : pGCPriv->funcs = pGC->funcs;
8713 : pGC->funcs = &damageGCFuncs;
8715 : wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
8722 :damageWrapGC (GCPtr pGC)
8724 : damageGCPriv(pGC);
8726 : pGCPriv->ops = NULL;
8727 : pGCPriv->funcs = pGC->funcs;
8728 : pGC->funcs = &damageGCFuncs;
8732 :damageUnwrapGC (GCPtr pGC)
8734 : damageGCPriv(pGC);
8736 : pGC->funcs = pGCPriv->funcs;
8738 : pGC->ops = pGCPriv->ops;
8742 :#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
8743 : damageGCPriv(pGC); \
8744 : GCFuncs *oldFuncs = pGC->funcs; \
8745 : unwrap(pGCPriv, pGC, funcs); \
8746 : unwrap(pGCPriv, pGC, ops); \
8748 :#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
8749 : wrap(pGCPriv, pGC, funcs, oldFuncs); \
8750 : wrap(pGCPriv, pGC, ops, &damageGCOps)
8752 :#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
8753 : damageGCPriv(pGC); \
8754 : unwrap(pGCPriv, pGC, funcs); \
8755 : if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
8757 :#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
8758 : wrap(pGCPriv, pGC, funcs, &damageGCFuncs); \
8759 : if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
8762 :damageValidateGC(GCPtr pGC,
8763 : unsigned long changes,
8764 : DrawablePtr pDrawable)
8765 2 0.0022 :{ /* damageValidateGC total: 7 0.0076 */
8766 1 0.0011 : DAMAGE_GC_FUNC_PROLOGUE (pGC);
8767 1 0.0011 : (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
8768 : pGCPriv->ops = pGC->ops; /* just so it's not NULL */
8769 3 0.0033 : DAMAGE_GC_FUNC_EPILOGUE (pGC);
8773 :damageDestroyGC(GCPtr pGC)
8775 : DAMAGE_GC_FUNC_PROLOGUE (pGC);
8776 : (*pGC->funcs->DestroyGC)(pGC);
8777 : DAMAGE_GC_FUNC_EPILOGUE (pGC);
8781 :damageChangeGC (GCPtr pGC,
8782 : unsigned long mask)
8783 2 0.0022 :{ /* damageChangeGC total: 9 0.0098 */
8784 4 0.0044 : DAMAGE_GC_FUNC_PROLOGUE (pGC);
8785 1 0.0011 : (*pGC->funcs->ChangeGC) (pGC, mask);
8786 2 0.0022 : DAMAGE_GC_FUNC_EPILOGUE (pGC);
8790 :damageCopyGC (GCPtr pGCSrc,
8791 : unsigned long mask,
8794 : DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
8795 : (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
8796 : DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
8800 :damageChangeClip (GCPtr pGC,
8804 1 0.0011 :{ /* damageChangeClip total: 1 0.0011 */
8805 : DAMAGE_GC_FUNC_PROLOGUE (pGC);
8806 : (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
8807 : DAMAGE_GC_FUNC_EPILOGUE (pGC);
8811 :damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
8813 : DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
8814 : (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
8815 : DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
8819 :damageDestroyClip(GCPtr pGC)
8821 : DAMAGE_GC_FUNC_PROLOGUE (pGC);
8822 : (* pGC->funcs->DestroyClip)(pGC);
8823 : DAMAGE_GC_FUNC_EPILOGUE (pGC);
8826 :#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
8827 : BoxPtr extents = &pGC->pCompositeClip->extents;\
8828 : if(box.x1 < extents->x1) box.x1 = extents->x1; \
8829 : if(box.x2 > extents->x2) box.x2 = extents->x2; \
8830 : if(box.y1 < extents->y1) box.y1 = extents->y1; \
8831 : if(box.y2 > extents->y2) box.y2 = extents->y2; \
8834 :#define TRANSLATE_BOX(box, pDrawable) { \
8835 : box.x1 += pDrawable->x; \
8836 : box.x2 += pDrawable->x; \
8837 : box.y1 += pDrawable->y; \
8838 : box.y2 += pDrawable->y; \
8841 :#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
8842 : TRANSLATE_BOX(box, pDrawable); \
8843 : TRIM_BOX(box, pGC); \
8846 :#define BOX_NOT_EMPTY(box) \
8847 : (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
8849 :#define checkGCDamage(d,g) (getDrawableDamage(d) && \
8850 : (!g->pCompositeClip ||\
8851 : REGION_NOTEMPTY(d->pScreen, \
8852 : g->pCompositeClip)))
8856 :#define TRIM_PICTURE_BOX(box, pDst) { \
8857 : BoxPtr extents = &pDst->pCompositeClip->extents;\
8858 : if(box.x1 < extents->x1) box.x1 = extents->x1; \
8859 : if(box.x2 > extents->x2) box.x2 = extents->x2; \
8860 : if(box.y1 < extents->y1) box.y1 = extents->y1; \
8861 : if(box.y2 > extents->y2) box.y2 = extents->y2; \
8864 :#define checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \
8865 : REGION_NOTEMPTY(pScreen, p->pCompositeClip))
8868 :damageComposite (CARD8 op,
8880 1 0.0011 :{ /* damageComposite total: 6 0.0065 */
8881 : ScreenPtr pScreen = pDst->pDrawable->pScreen;
8882 : PictureScreenPtr ps = GetPictureScreen(pScreen);
8883 : damageScrPriv(pScreen);
8885 1 0.0011 : if (checkPictureDamage (pDst))
8889 : box.x1 = xDst + pDst->pDrawable->x;
8890 : box.y1 = yDst + pDst->pDrawable->y;
8891 : box.x2 = box.x1 + width;
8892 : box.y2 = box.y1 + height;
8893 : TRIM_PICTURE_BOX(box, pDst);
8894 : if (BOX_NOT_EMPTY(box))
8895 1 0.0011 : damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
8897 : unwrap (pScrPriv, ps, Composite);
8898 : (*ps->Composite) (op,
8910 3 0.0033 : damageReportPostOp (pDst->pDrawable);
8911 : wrap (pScrPriv, ps, Composite, damageComposite);
8915 :damageGlyphs (CARD8 op,
8918 : PictFormatPtr maskFormat,
8922 : GlyphListPtr list,
8924 :{ /* damageGlyphs total: 61 0.0665 */
8925 : ScreenPtr pScreen = pDst->pDrawable->pScreen;
8926 : PictureScreenPtr ps = GetPictureScreen(pScreen);
8927 : damageScrPriv(pScreen);
8929 : if (checkPictureDamage (pDst))
8931 : int nlistTmp = nlist;
8932 : GlyphListPtr listTmp = list;
8933 : GlyphPtr *glyphsTmp = glyphs;
8938 : int x1, y1, x2, y2;
8944 : x = pDst->pDrawable->x;
8945 : y = pDst->pDrawable->y;
8946 1 0.0011 : while (nlistTmp--)
8948 1 0.0011 : x += listTmp->xOff;
8949 : y += listTmp->yOff;
8951 1 0.0011 : while (n--)
8953 2 0.0022 : glyph = *glyphsTmp++;
8954 31 0.0338 : x1 = x - glyph->info.x;
8955 3 0.0033 : y1 = y - glyph->info.y;
8956 1 0.0011 : x2 = x1 + glyph->info.width;
8957 1 0.0011 : y2 = y1 + glyph->info.height;
8960 1 0.0011 : if (y1 < box.y1)
8962 5 0.0054 : if (x2 > box.x2)
8963 2 0.0022 : box.x2 = x2;
8964 2 0.0022 : if (y2 > box.y2)
8965 1 0.0011 : box.y2 = y2;
8966 2 0.0022 : x += glyph->info.xOff;
8967 2 0.0022 : y += glyph->info.yOff;
8971 1 0.0011 : TRIM_PICTURE_BOX (box, pDst);
8972 : if (BOX_NOT_EMPTY(box))
8973 1 0.0011 : damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
8975 1 0.0011 : unwrap (pScrPriv, ps, Glyphs);
8976 1 0.0011 : (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
8977 : damageReportPostOp (pDst->pDrawable);
8978 : wrap (pScrPriv, ps, Glyphs, damageGlyphs);
8982 :/**********************************************************/
8986 :damageFillSpans(DrawablePtr pDrawable,
8993 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
8995 : if (npt && checkGCDamage (pDrawable, pGC))
8998 : DDXPointPtr pptTmp = ppt;
8999 : int *pwidthTmp = pwidth;
9002 : box.x1 = pptTmp->x;
9003 : box.x2 = box.x1 + *pwidthTmp;
9004 : box.y2 = box.y1 = pptTmp->y;
9010 : if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
9011 : if(box.x2 < (pptTmp->x + *pwidthTmp))
9012 : box.x2 = pptTmp->x + *pwidthTmp;
9013 : if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
9014 : else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
9019 : if(!pGC->miTranslate) {
9020 : TRANSLATE_BOX(box, pDrawable);
9022 : TRIM_BOX(box, pGC);
9024 : if(BOX_NOT_EMPTY(box))
9025 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9028 : (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
9030 : damageReportPostOp (pDrawable);
9031 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9035 :damageSetSpans(DrawablePtr pDrawable,
9043 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9045 : if (npt && checkGCDamage (pDrawable, pGC))
9047 : DDXPointPtr pptTmp = ppt;
9048 : int *pwidthTmp = pwidth;
9052 : box.x1 = pptTmp->x;
9053 : box.x2 = box.x1 + *pwidthTmp;
9054 : box.y2 = box.y1 = pptTmp->y;
9060 : if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
9061 : if(box.x2 < (pptTmp->x + *pwidthTmp))
9062 : box.x2 = pptTmp->x + *pwidthTmp;
9063 : if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
9064 : else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
9069 : if(!pGC->miTranslate) {
9070 : TRANSLATE_BOX(box, pDrawable);
9072 : TRIM_BOX(box, pGC);
9074 : if(BOX_NOT_EMPTY(box))
9075 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9077 : (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
9078 : damageReportPostOp (pDrawable);
9079 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9083 :damagePutImage(DrawablePtr pDrawable,
9094 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9095 : if (checkGCDamage (pDrawable, pGC))
9099 : box.x1 = x + pDrawable->x;
9100 : box.x2 = box.x1 + w;
9101 : box.y1 = y + pDrawable->y;
9102 : box.y2 = box.y1 + h;
9104 : TRIM_BOX(box, pGC);
9105 : if(BOX_NOT_EMPTY(box))
9106 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9108 : (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
9109 : leftPad, format, pImage);
9110 : damageReportPostOp (pDrawable);
9111 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9115 :damageCopyArea(DrawablePtr pSrc,
9126 : DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
9128 : /* The driver will only call SourceValidate() when pSrc != pDst,
9129 : * but the software sprite (misprite.c) always need to know when a
9130 : * drawable is copied so it can remove the sprite. See #1030. */
9131 : if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
9132 : pSrc->type == DRAWABLE_WINDOW &&
9133 : ((WindowPtr)pSrc)->viewable)
9135 : (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
9138 : if (checkGCDamage (pDst, pGC))
9142 : box.x1 = dstx + pDst->x;
9143 : box.x2 = box.x1 + width;
9144 : box.y1 = dsty + pDst->y;
9145 : box.y2 = box.y1 + height;
9147 : TRIM_BOX(box, pGC);
9148 : if(BOX_NOT_EMPTY(box))
9149 : damageDamageBox (pDst, &box, pGC->subWindowMode);
9152 : ret = (*pGC->ops->CopyArea)(pSrc, pDst,
9153 : pGC, srcx, srcy, width, height, dstx, dsty);
9154 : damageReportPostOp (pDst);
9155 : DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
9160 :damageCopyPlane(DrawablePtr pSrc,
9169 : unsigned long bitPlane)
9172 : DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
9174 : /* The driver will only call SourceValidate() when pSrc != pDst,
9175 : * but the software sprite (misprite.c) always need to know when a
9176 : * drawable is copied so it can remove the sprite. See #1030. */
9177 : if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
9178 : pSrc->type == DRAWABLE_WINDOW &&
9179 : ((WindowPtr)pSrc)->viewable)
9181 : (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
9184 : if (checkGCDamage (pDst, pGC))
9188 : box.x1 = dstx + pDst->x;
9189 : box.x2 = box.x1 + width;
9190 : box.y1 = dsty + pDst->y;
9191 : box.y2 = box.y1 + height;
9193 : TRIM_BOX(box, pGC);
9194 : if(BOX_NOT_EMPTY(box))
9195 : damageDamageBox (pDst, &box, pGC->subWindowMode);
9198 : ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
9199 : pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
9200 : damageReportPostOp (pDst);
9201 : DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
9206 :damagePolyPoint(DrawablePtr pDrawable,
9212 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9214 : if (npt && checkGCDamage (pDrawable, pGC))
9218 : xPoint *pptTmp = ppt;
9220 : box.x2 = box.x1 = pptTmp->x;
9221 : box.y2 = box.y1 = pptTmp->y;
9223 : /* this could be slow if the points were spread out */
9228 : if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
9229 : else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
9230 : if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
9231 : else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
9237 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9238 : if(BOX_NOT_EMPTY(box))
9239 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9241 : (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
9242 : damageReportPostOp (pDrawable);
9243 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9247 :damagePolylines(DrawablePtr pDrawable,
9253 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9255 : if (npt && checkGCDamage (pDrawable, pGC))
9258 : DDXPointPtr pptTmp = ppt;
9260 : int extra = pGC->lineWidth >> 1;
9262 : box.x2 = box.x1 = pptTmp->x;
9263 : box.y2 = box.y1 = pptTmp->y;
9267 : if(pGC->joinStyle == JoinMiter)
9268 : extra = 6 * pGC->lineWidth;
9269 : else if(pGC->capStyle == CapProjecting)
9270 : extra = pGC->lineWidth;
9273 : if(mode == CoordModePrevious)
9282 : if(box.x1 > x) box.x1 = x;
9283 : else if(box.x2 < x) box.x2 = x;
9284 : if(box.y1 > y) box.y1 = y;
9285 : else if(box.y2 < y) box.y2 = y;
9293 : if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
9294 : else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
9295 : if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
9296 : else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
9311 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9312 : if(BOX_NOT_EMPTY(box))
9313 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9315 : (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
9316 : damageReportPostOp (pDrawable);
9317 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9321 :damagePolySegment(DrawablePtr pDrawable,
9325 :{ /* damagePolySegment total: 1 0.0011 */
9326 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9328 : if (nSeg && checkGCDamage (pDrawable, pGC))
9331 : int extra = pGC->lineWidth;
9332 : int nsegTmp = nSeg;
9333 : xSegment *pSegTmp = pSeg;
9335 : if(pGC->capStyle != CapProjecting)
9338 : if(pSegTmp->x2 > pSegTmp->x1) {
9339 : box.x1 = pSegTmp->x1;
9340 : box.x2 = pSegTmp->x2;
9342 : box.x2 = pSegTmp->x1;
9343 : box.x1 = pSegTmp->x2;
9346 : if(pSegTmp->y2 > pSegTmp->y1) {
9347 : box.y1 = pSegTmp->y1;
9348 : box.y2 = pSegTmp->y2;
9350 : box.y2 = pSegTmp->y1;
9351 : box.y1 = pSegTmp->y2;
9357 : if(pSegTmp->x2 > pSegTmp->x1)
9359 : if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
9360 : if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
9364 : if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
9365 : if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
9367 : if(pSegTmp->y2 > pSegTmp->y1)
9369 : if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
9370 : if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
9374 : if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
9375 : if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
9390 1 0.0011 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9391 : if(BOX_NOT_EMPTY(box))
9392 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9394 : (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
9395 : damageReportPostOp (pDrawable);
9396 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9400 :damagePolyRectangle(DrawablePtr pDrawable,
9403 : xRectangle *pRects)
9405 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9407 : if (nRects && checkGCDamage (pDrawable, pGC))
9410 : int offset1, offset2, offset3;
9411 : int nRectsTmp = nRects;
9412 : xRectangle *pRectsTmp = pRects;
9414 : offset2 = pGC->lineWidth;
9415 : if(!offset2) offset2 = 1;
9416 : offset1 = offset2 >> 1;
9417 : offset3 = offset2 - offset1;
9419 : while(nRectsTmp--)
9421 : box.x1 = pRectsTmp->x - offset1;
9422 : box.y1 = pRectsTmp->y - offset1;
9423 : box.x2 = box.x1 + pRectsTmp->width + offset2;
9424 : box.y2 = box.y1 + offset2;
9425 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9426 : if(BOX_NOT_EMPTY(box))
9427 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9429 : box.x1 = pRectsTmp->x - offset1;
9430 : box.y1 = pRectsTmp->y + offset3;
9431 : box.x2 = box.x1 + offset2;
9432 : box.y2 = box.y1 + pRectsTmp->height - offset2;
9433 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9434 : if(BOX_NOT_EMPTY(box))
9435 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9437 : box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
9438 : box.y1 = pRectsTmp->y + offset3;
9439 : box.x2 = box.x1 + offset2;
9440 : box.y2 = box.y1 + pRectsTmp->height - offset2;
9441 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9442 : if(BOX_NOT_EMPTY(box))
9443 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9445 : box.x1 = pRectsTmp->x - offset1;
9446 : box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
9447 : box.x2 = box.x1 + pRectsTmp->width + offset2;
9448 : box.y2 = box.y1 + offset2;
9449 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9450 : if(BOX_NOT_EMPTY(box))
9451 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9456 : (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
9457 : damageReportPostOp (pDrawable);
9458 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9462 :damagePolyArc(DrawablePtr pDrawable,
9467 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9469 : if (nArcs && checkGCDamage (pDrawable, pGC))
9471 : int extra = pGC->lineWidth >> 1;
9473 : int nArcsTmp = nArcs;
9474 : xArc *pArcsTmp = pArcs;
9476 : box.x1 = pArcsTmp->x;
9477 : box.x2 = box.x1 + pArcsTmp->width;
9478 : box.y1 = pArcsTmp->y;
9479 : box.y2 = box.y1 + pArcsTmp->height;
9484 : if(box.x1 > pArcsTmp->x)
9485 : box.x1 = pArcsTmp->x;
9486 : if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
9487 : box.x2 = pArcsTmp->x + pArcsTmp->width;
9488 : if(box.y1 > pArcsTmp->y)
9489 : box.y1 = pArcsTmp->y;
9490 : if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
9491 : box.y2 = pArcsTmp->y + pArcsTmp->height;
9505 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9506 : if(BOX_NOT_EMPTY(box))
9507 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9509 : (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
9510 : damageReportPostOp (pDrawable);
9511 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9515 :damageFillPolygon(DrawablePtr pDrawable,
9522 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9524 : if (npt > 2 && checkGCDamage (pDrawable, pGC))
9526 : DDXPointPtr pptTmp = ppt;
9530 : box.x2 = box.x1 = pptTmp->x;
9531 : box.y2 = box.y1 = pptTmp->y;
9533 : if(mode != CoordModeOrigin)
9542 : if(box.x1 > x) box.x1 = x;
9543 : else if(box.x2 < x) box.x2 = x;
9544 : if(box.y1 > y) box.y1 = y;
9545 : else if(box.y2 < y) box.y2 = y;
9553 : if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
9554 : else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
9555 : if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
9556 : else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
9563 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9564 : if(BOX_NOT_EMPTY(box))
9565 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9568 : (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
9569 : damageReportPostOp (pDrawable);
9570 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9575 :damagePolyFillRect(DrawablePtr pDrawable,
9578 : xRectangle *pRects)
9579 2 0.0022 :{ /* damagePolyFillRect total: 17 0.0185 */
9580 2 0.0022 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9581 2 0.0022 : if (nRects && checkGCDamage (pDrawable, pGC))
9584 : xRectangle *pRectsTmp = pRects;
9585 : int nRectsTmp = nRects;
9587 : box.x1 = pRectsTmp->x;
9588 : box.x2 = box.x1 + pRectsTmp->width;
9589 : box.y1 = pRectsTmp->y;
9590 : box.y2 = box.y1 + pRectsTmp->height;
9592 2 0.0022 : while(--nRectsTmp)
9595 : if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
9596 : if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
9597 : box.x2 = pRectsTmp->x + pRectsTmp->width;
9598 1 0.0011 : if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
9599 : if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
9600 : box.y2 = pRectsTmp->y + pRectsTmp->height;
9603 4 0.0044 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9604 1 0.0011 : if(BOX_NOT_EMPTY(box))
9605 1 0.0011 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9607 1 0.0011 : (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
9608 1 0.0011 : damageReportPostOp (pDrawable);
9609 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9614 :damagePolyFillArc(DrawablePtr pDrawable,
9619 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9621 : if (nArcs && checkGCDamage (pDrawable, pGC))
9624 : int nArcsTmp = nArcs;
9625 : xArc *pArcsTmp = pArcs;
9627 : box.x1 = pArcsTmp->x;
9628 : box.x2 = box.x1 + pArcsTmp->width;
9629 : box.y1 = pArcsTmp->y;
9630 : box.y2 = box.y1 + pArcsTmp->height;
9635 : if(box.x1 > pArcsTmp->x)
9636 : box.x1 = pArcsTmp->x;
9637 : if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
9638 : box.x2 = pArcsTmp->x + pArcsTmp->width;
9639 : if(box.y1 > pArcsTmp->y)
9640 : box.y1 = pArcsTmp->y;
9641 : if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
9642 : box.y2 = pArcsTmp->y + pArcsTmp->height;
9645 : TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
9646 : if(BOX_NOT_EMPTY(box))
9647 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9649 : (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
9650 : damageReportPostOp (pDrawable);
9651 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9655 : * general Poly/Image text function. Extract glyph information,
9656 : * compute bounding box and remove cursor if it is overlapped.
9660 :damageDamageChars (DrawablePtr pDrawable,
9665 : CharInfoPtr *charinfo,
9667 : int subWindowMode)
9669 : ExtentInfoRec extents;
9672 : QueryGlyphExtents(font, charinfo, n, &extents);
9675 : if (extents.overallWidth > extents.overallRight)
9676 : extents.overallRight = extents.overallWidth;
9677 : if (extents.overallWidth < extents.overallLeft)
9678 : extents.overallLeft = extents.overallWidth;
9679 : if (extents.overallLeft > 0)
9680 : extents.overallLeft = 0;
9681 : if (extents.fontAscent > extents.overallAscent)
9682 : extents.overallAscent = extents.fontAscent;
9683 : if (extents.fontDescent > extents.overallDescent)
9684 : extents.overallDescent = extents.fontDescent;
9686 : box.x1 = x + extents.overallLeft;
9687 : box.y1 = y - extents.overallAscent;
9688 : box.x2 = x + extents.overallRight;
9689 : box.y2 = y + extents.overallDescent;
9690 : damageDamageBox (pDrawable, &box, subWindowMode);
9694 : * values for textType:
9697 :#define TT_IMAGE8 1
9698 :#define TT_POLY16 2
9699 :#define TT_IMAGE16 3
9702 :damageText (DrawablePtr pDrawable,
9706 : unsigned long count,
9708 : FontEncoding fontEncoding,
9711 : CharInfoPtr *charinfo;
9712 : CharInfoPtr *info;
9718 : imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
9720 : charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
9724 : GetGlyphs(pGC->font, count, (unsigned char *)chars,
9725 : fontEncoding, &i, charinfo);
9726 : n = (unsigned int)i;
9729 : for (info = charinfo; i--; info++)
9730 : w += (*info)->metrics.characterWidth;
9733 : damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
9734 : charinfo, imageblt, pGC->subWindowMode);
9736 : (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
9737 : FONTGLYPHS(pGC->font));
9739 : (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
9740 : FONTGLYPHS(pGC->font));
9742 : DEALLOCATE_LOCAL(charinfo);
9747 :damagePolyText8(DrawablePtr pDrawable,
9754 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9756 : if (checkGCDamage (pDrawable, pGC))
9757 : x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
9758 : Linear8Bit, TT_POLY8);
9760 : x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
9761 : damageReportPostOp (pDrawable);
9762 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9767 :damagePolyText16(DrawablePtr pDrawable,
9772 : unsigned short *chars)
9774 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9776 : if (checkGCDamage (pDrawable, pGC))
9777 : x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
9778 : FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
9781 : x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
9782 : damageReportPostOp (pDrawable);
9783 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9788 :damageImageText8(DrawablePtr pDrawable,
9795 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9797 : if (checkGCDamage (pDrawable, pGC))
9798 : damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
9799 : Linear8Bit, TT_IMAGE8);
9801 : (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
9802 : damageReportPostOp (pDrawable);
9803 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9807 :damageImageText16(DrawablePtr pDrawable,
9812 : unsigned short *chars)
9814 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9816 : if (checkGCDamage (pDrawable, pGC))
9817 : damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
9818 : FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
9821 : (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
9822 : damageReportPostOp (pDrawable);
9823 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9828 :damageImageGlyphBlt(DrawablePtr pDrawable,
9832 : unsigned int nglyph,
9833 : CharInfoPtr *ppci,
9834 : pointer pglyphBase)
9836 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9837 : damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
9838 : nglyph, ppci, TRUE, pGC->subWindowMode);
9839 : (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
9840 : ppci, pglyphBase);
9841 : damageReportPostOp (pDrawable);
9842 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9846 :damagePolyGlyphBlt(DrawablePtr pDrawable,
9850 : unsigned int nglyph,
9851 : CharInfoPtr *ppci,
9852 : pointer pglyphBase)
9854 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9855 : damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
9856 : nglyph, ppci, FALSE, pGC->subWindowMode);
9857 : (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
9858 : ppci, pglyphBase);
9859 : damageReportPostOp (pDrawable);
9860 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9864 :damagePushPixels(GCPtr pGC,
9865 : PixmapPtr pBitMap,
9866 : DrawablePtr pDrawable,
9872 : DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
9873 : if(checkGCDamage (pDrawable, pGC))
9880 : if(!pGC->miTranslate) {
9881 : box.x1 += pDrawable->x;
9882 : box.y1 += pDrawable->y;
9885 : box.x2 = box.x1 + dx;
9886 : box.y2 = box.y1 + dy;
9888 : TRIM_BOX(box, pGC);
9889 : if(BOX_NOT_EMPTY(box))
9890 : damageDamageBox (pDrawable, &box, pGC->subWindowMode);
9892 : (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
9893 : damageReportPostOp (pDrawable);
9894 : DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
9898 :damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
9899 1 0.0011 :{ /* damageRemoveDamage total: 2 0.0022 */
9902 : if (*pPrev == pDamage)
9904 : *pPrev = pDamage->pNext;
9907 : pPrev = &(*pPrev)->pNext;
9909 :#if DAMAGE_VALIDATE_ENABLE
9910 : ErrorF ("Damage not on list\n");
9916 :damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
9917 1 0.0011 :{ /* damageInsertDamage total: 1 0.0011 */
9918 :#if DAMAGE_VALIDATE_ENABLE
9921 : for (pOld = *pPrev; pOld; pOld = pOld->pNext)
9922 : if (pOld == pDamage) {
9923 : ErrorF ("Damage already on list\n");
9927 : pDamage->pNext = *pPrev;
9932 :damageDestroyPixmap (PixmapPtr pPixmap)
9933 3 0.0033 :{ /* damageDestroyPixmap total: 15 0.0163 */
9934 : ScreenPtr pScreen = pPixmap->drawable.pScreen;
9935 2 0.0022 : damageScrPriv(pScreen);
9937 : if (pPixmap->refcnt == 1)
9939 1 0.0011 : DamagePtr *pPrev = getPixmapDamageRef (pPixmap);
9940 : DamagePtr pDamage;
9942 : while ((pDamage = *pPrev))
9944 : damageRemoveDamage (pPrev, pDamage);
9945 : if (!pDamage->isWindow)
9946 : DamageDestroy (pDamage);
9949 3 0.0033 : unwrap (pScrPriv, pScreen, DestroyPixmap);
9950 2 0.0022 : (*pScreen->DestroyPixmap) (pPixmap);
9951 3 0.0033 : wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
9956 :damagePaintWindow(WindowPtr pWindow,
9960 : ScreenPtr pScreen = pWindow->drawable.pScreen;
9961 : damageScrPriv(pScreen);
9964 : * Painting background none doesn't actually *do* anything, so
9965 : * no damage is recorded
9967 : if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
9968 : getWindowDamage (pWindow))
9969 : damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
9970 : if(what == PW_BACKGROUND) {
9971 : unwrap (pScrPriv, pScreen, PaintWindowBackground);
9972 : (*pScreen->PaintWindowBackground) (pWindow, prgn, what);
9973 : damageReportPostOp (&pWindow->drawable);
9974 : wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
9976 : unwrap (pScrPriv, pScreen, PaintWindowBorder);
9977 : (*pScreen->PaintWindowBorder) (pWindow, prgn, what);
9978 : damageReportPostOp (&pWindow->drawable);
9979 : wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
9985 :damageCopyWindow(WindowPtr pWindow,
9986 : DDXPointRec ptOldOrg,
9987 : RegionPtr prgnSrc)
9989 : ScreenPtr pScreen = pWindow->drawable.pScreen;
9990 : damageScrPriv(pScreen);
9992 : if (getWindowDamage (pWindow))
9994 : int dx = pWindow->drawable.x - ptOldOrg.x;
9995 : int dy = pWindow->drawable.y - ptOldOrg.y;
9998 : * The region comes in source relative, but the damage occurs
9999 : * at the destination location. Translate back and forth.
10001 : REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
10002 : damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
10003 : REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
10005 : unwrap (pScrPriv, pScreen, CopyWindow);
10006 : (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
10007 : damageReportPostOp (&pWindow->drawable);
10008 : wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
10011 :static GCOps damageGCOps = {
10012 : damageFillSpans, damageSetSpans,
10013 : damagePutImage, damageCopyArea,
10014 : damageCopyPlane, damagePolyPoint,
10015 : damagePolylines, damagePolySegment,
10016 : damagePolyRectangle, damagePolyArc,
10017 : damageFillPolygon, damagePolyFillRect,
10018 : damagePolyFillArc, damagePolyText8,
10019 : damagePolyText16, damageImageText8,
10020 : damageImageText16, damageImageGlyphBlt,
10021 : damagePolyGlyphBlt, damagePushPixels,
10022 : {NULL} /* devPrivate */
10026 :damageRestoreAreas (PixmapPtr pPixmap,
10030 : WindowPtr pWindow)
10032 : ScreenPtr pScreen = pWindow->drawable.pScreen;
10033 : damageScrPriv(pScreen);
10035 : damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
10036 : unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
10037 : (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
10038 : xorg, yorg, pWindow);
10039 : damageReportPostOp (&pWindow->drawable);
10040 : wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
10041 : damageRestoreAreas);
10045 :damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
10047 : DamagePtr pDamage;
10048 : ScreenPtr pScreen = pWindow->drawable.pScreen;
10049 : damageScrPriv(pScreen);
10051 : if ((pDamage = damageGetWinPriv(pWindow)))
10053 : PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
10054 : DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap);
10058 : damageRemoveDamage (pPrev, pDamage);
10059 : pDamage = pDamage->pNextWin;
10062 : unwrap (pScrPriv, pScreen, SetWindowPixmap);
10063 : (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
10064 : wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
10065 : if ((pDamage = damageGetWinPriv(pWindow)))
10067 : DamagePtr *pPrev = getPixmapDamageRef(pPixmap);
10071 : damageInsertDamage (pPrev, pDamage);
10072 : pDamage = pDamage->pNextWin;
10078 :damageDestroyWindow (WindowPtr pWindow)
10080 : DamagePtr pDamage;
10081 : ScreenPtr pScreen = pWindow->drawable.pScreen;
10083 : damageScrPriv(pScreen);
10085 : while ((pDamage = damageGetWinPriv(pWindow)))
10087 : DamageUnregister (&pWindow->drawable, pDamage);
10088 : DamageDestroy (pDamage);
10090 : unwrap (pScrPriv, pScreen, DestroyWindow);
10091 : ret = (*pScreen->DestroyWindow) (pWindow);
10092 : wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
10097 :damageCloseScreen (int i, ScreenPtr pScreen)
10099 : damageScrPriv(pScreen);
10101 : unwrap (pScrPriv, pScreen, DestroyPixmap);
10102 : unwrap (pScrPriv, pScreen, CreateGC);
10103 : unwrap (pScrPriv, pScreen, PaintWindowBackground);
10104 : unwrap (pScrPriv, pScreen, PaintWindowBorder);
10105 : unwrap (pScrPriv, pScreen, CopyWindow);
10106 : unwrap (pScrPriv, pScreen, CloseScreen);
10107 : unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
10108 : xfree (pScrPriv);
10109 : return (*pScreen->CloseScreen) (i, pScreen);
10113 :DamageSetup (ScreenPtr pScreen)
10115 : DamageScrPrivPtr pScrPriv;
10117 : PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
10120 : if (damageGeneration != serverGeneration)
10122 : damageScrPrivateIndex = AllocateScreenPrivateIndex ();
10123 : if (damageScrPrivateIndex == -1)
10125 : damageGCPrivateIndex = AllocateGCPrivateIndex ();
10126 : if (damageGCPrivateIndex == -1)
10128 : damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
10129 : if (damagePixPrivateIndex == -1)
10131 : damageWinPrivateIndex = AllocateWindowPrivateIndex ();
10132 : if (damageWinPrivateIndex == -1)
10134 : damageGeneration = serverGeneration;
10136 : if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
10139 : if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
10141 : if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
10143 : if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
10146 : pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
10150 : pScrPriv->internalLevel = 0;
10151 : pScrPriv->pScreenDamage = 0;
10153 : wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
10154 : wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
10155 : wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
10156 : wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
10157 : wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
10158 : wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
10159 : wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
10160 : wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
10161 : wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
10162 : damageRestoreAreas);
10165 : wrap (pScrPriv, ps, Glyphs, damageGlyphs);
10166 : wrap (pScrPriv, ps, Composite, damageComposite);
10170 : pScreen->devPrivates[damageScrPrivateIndex].ptr = (pointer) pScrPriv;
10175 :DamageCreate (DamageReportFunc damageReport,
10176 : DamageDestroyFunc damageDestroy,
10177 : DamageReportLevel damageLevel,
10179 : ScreenPtr pScreen,
10181 2 0.0022 :{ /* DamageCreate total: 12 0.0131 */
10182 : DamagePtr pDamage;
10184 4 0.0044 : pDamage = xalloc (sizeof (DamageRec));
10185 1 0.0011 : if (!pDamage)
10187 : pDamage->pNext = 0;
10188 : pDamage->pNextWin = 0;
10189 3 0.0033 : REGION_NULL(pScreen, &pDamage->damage);
10190 : REGION_NULL(pScreen, &pDamage->pendingDamage);
10192 : pDamage->damageLevel = damageLevel;
10193 1 0.0011 : pDamage->isInternal = isInternal;
10194 : pDamage->closure = closure;
10195 : pDamage->isWindow = FALSE;
10196 : pDamage->pDrawable = 0;
10197 : pDamage->reportAfter = FALSE;
10199 : pDamage->damageReport = damageReport;
10200 : pDamage->damageDestroy = damageDestroy;
10205 :DamageRegister (DrawablePtr pDrawable,
10206 : DamagePtr pDamage)
10207 1 0.0011 :{ /* DamageRegister total: 1 0.0011 */
10208 : if (pDrawable->type == DRAWABLE_WINDOW)
10210 : WindowPtr pWindow = (WindowPtr) pDrawable;
10211 : winDamageRef(pWindow);
10213 :#if DAMAGE_VALIDATE_ENABLE
10216 : for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
10217 : if (pOld == pDamage) {
10218 : ErrorF ("Damage already on window list\n");
10222 : pDamage->pNextWin = *pPrev;
10223 : *pPrev = pDamage;
10224 : pDamage->isWindow = TRUE;
10227 : pDamage->isWindow = FALSE;
10228 : pDamage->pDrawable = pDrawable;
10229 : damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
10233 :DamageDrawInternal (ScreenPtr pScreen, Bool enable)
10235 : damageScrPriv (pScreen);
10237 : pScrPriv->internalLevel += enable ? 1 : -1;
10241 :DamageUnregister (DrawablePtr pDrawable,
10242 : DamagePtr pDamage)
10244 : if (pDrawable->type == DRAWABLE_WINDOW)
10246 : WindowPtr pWindow = (WindowPtr) pDrawable;
10247 : winDamageRef (pWindow);
10248 :#if DAMAGE_VALIDATE_ENABLE
10254 : if (*pPrev == pDamage)
10256 : *pPrev = pDamage->pNextWin;
10257 :#if DAMAGE_VALIDATE_ENABLE
10262 : pPrev = &(*pPrev)->pNextWin;
10264 :#if DAMAGE_VALIDATE_ENABLE
10266 : ErrorF ("Damage not on window list\n");
10271 : pDamage->pDrawable = 0;
10272 : damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
10276 :DamageDestroy (DamagePtr pDamage)
10277 1 0.0011 :{ /* DamageDestroy total: 3 0.0033 */
10278 : if (pDamage->damageDestroy)
10279 : (*pDamage->damageDestroy) (pDamage, pDamage->closure);
10280 2 0.0022 : REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
10281 : REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->pendingDamage);
10286 :DamageSubtract (DamagePtr pDamage,
10287 : const RegionPtr pRegion)
10290 : RegionRec pixmapClip;
10291 : DrawablePtr pDrawable = pDamage->pDrawable;
10293 : REGION_SUBTRACT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pRegion);
10296 : if (pDrawable->type == DRAWABLE_WINDOW)
10297 : pClip = &((WindowPtr) pDrawable)->borderClip;
10302 : box.x1 = pDrawable->x;
10303 : box.y1 = pDrawable->y;
10304 : box.x2 = pDrawable->x + pDrawable->width;
10305 : box.y2 = pDrawable->y + pDrawable->height;
10306 : REGION_INIT (pDrawable->pScreen, &pixmapClip, &box, 1);
10307 : pClip = &pixmapClip;
10309 : REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
10310 : REGION_INTERSECT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pClip);
10311 : REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
10312 : if (pDrawable->type != DRAWABLE_WINDOW)
10313 : REGION_UNINIT(pDrawable->pScreen, &pixmapClip);
10315 : return REGION_NOTEMPTY (pDrawable->pScreen, &pDamage->damage);
10319 :DamageEmpty (DamagePtr pDamage)
10320 1 0.0011 :{ /* DamageEmpty total: 3 0.0033 */
10321 1 0.0011 : REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
10325 :DamageRegion (DamagePtr pDamage)
10326 7 0.0076 :{ /* DamageRegion total: 10 0.0109 */
10327 : return &pDamage->damage;
10331 :DamageDamageRegion (DrawablePtr pDrawable,
10332 : RegionPtr pRegion)
10334 : damageDamageRegion (pDrawable, pRegion, FALSE, -1);
10336 : /* Go back and report this damage for DamagePtrs with reportAfter set, since
10337 : * this call isn't part of an in-progress drawing op in the call chain and
10338 : * the DDX probably just wants to know about it right away.
10340 : damageReportPostOp (pDrawable);
10344 :DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter)
10345 4 0.0044 :{ /* DamageSetReportAfterOp total: 5 0.0054 */
10346 : pDamage->reportAfter = reportAfter;
10349 * Total samples for file : "/home/cworth/src/xorg/driver/xf86-video-intel/src/i830_driver.c"
10355 :/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c,v 1.50 2004/02/20 00:06:00 alanh Exp $ */
10356 :/**************************************************************************
10358 :Copyright 2001 VA Linux Systems Inc., Fremont, California.
10359 :Copyright © 2002 by David Dawes
10361 :All Rights Reserved.
10363 :Permission is hereby granted, free of charge, to any person obtaining a
10364 :copy of this software and associated documentation files (the "Software"),
10365 :to deal in the Software without restriction, including without limitation
10366 :on the rights to use, copy, modify, merge, publish, distribute, sub
10367 :license, and/or sell copies of the Software, and to permit persons to whom
10368 :the Software is furnished to do so, subject to the following conditions:
10370 :The above copyright notice and this permission notice (including the next
10371 :paragraph) shall be included in all copies or substantial portions of the
10374 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10375 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10376 :FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
10377 :THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
10378 :DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
10379 :OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
10380 :USE OR OTHER DEALINGS IN THE SOFTWARE.
10382 :**************************************************************************/
10385 : * Reformatted with GNU indent (2.2.8), using the following options:
10387 : * -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
10388 : * -lp -npcs -psl -sob -ss -br -ce -sc -hnl
10390 : * This provides a good match with the original i810 code and preferred
10391 : * XFree86 formatting conventions.
10393 : * When editing this driver, please follow the existing formatting, and edit
10394 : * with <TAB> characters expanded at 8-column intervals.
10398 : * Authors: Jeff Hartmann <jhartmann@valinux.com>
10399 : * Abraham van der Merwe <abraham@2d3d.co.za>
10400 : * David Dawes <dawes@xfree86.org>
10401 : * Alan Hourihane <alanh@tungstengraphics.com>
10405 : * Mode handling is based on the VESA driver written by:
10406 : * Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
10412 : * 23/08/2001 Abraham van der Merwe <abraham@2d3d.co.za>
10413 : * - Fixed display timing bug (mode information for some
10414 : * modes were not initialized correctly)
10415 : * - Added workarounds for GTT corruptions (I don't adjust
10416 : * the pitches for 1280x and 1600x modes so we don't
10417 : * need extra memory)
10418 : * - The code will now default to 60Hz if LFP is connected
10419 : * - Added different refresh rate setting code to work
10420 : * around 0x4f02 BIOS bug
10421 : * - BIOS workaround for some mode sets (I use legacy BIOS
10422 : * calls for setting those)
10423 : * - Removed 0x4f04, 0x01 (save state) BIOS call which causes
10424 : * LFP to malfunction (do some house keeping and restore
10425 : * modes ourselves instead - not perfect, but at least the
10426 : * LFP is working now)
10427 : * - Several other smaller bug fixes
10429 : * 06/09/2001 Abraham van der Merwe <abraham@2d3d.co.za>
10430 : * - Preliminary local memory support (works without agpgart)
10431 : * - DGA fixes (the code were still using i810 mode sets, etc.)
10432 : * - agpgart fixes
10435 : * - Proper local memory support (should work correctly now
10436 : * with/without agpgart module)
10437 : * - more agpgart fixes
10438 : * - got rid of incorrect GTT adjustments
10441 : * - Changed the DPRINTF() variadic macro to an ANSI C compatible
10445 : * - Fixed DPRINTF_stub(). I forgot the __...__ macros in there
10446 : * instead of the function arguments :P
10447 : * - Added a workaround for the 1600x1200 bug (Text mode corrupts
10448 : * when you exit from any 1600x1200 mode and 1280x1024@85Hz. I
10449 : * suspect this is a BIOS bug (hence the 1280x1024@85Hz case)).
10450 : * For now I'm switching to 800x600@60Hz then to 80x25 text mode
10451 : * and then restoring the registers - very ugly indeed.
10454 : * - Improved 1600x1200 mode set workaround. The previous workaround
10455 : * was causing mode set problems later on.
10458 : * - Fixed a bug in I830BIOSLeaveVT() which caused a bug when you
10462 : * 07/2002 David Dawes
10463 : * - Add Intel(R) 855GM/852GM support.
10466 : * 07/2002 David Dawes
10467 : * - Cleanup code formatting.
10468 : * - Improve VESA mode selection, and fix refresh rate selection.
10469 : * - Don't duplicate functions provided in 4.2 vbe modules.
10470 : * - Don't duplicate functions provided in the vgahw module.
10471 : * - Rewrite memory allocation.
10472 : * - Rewrite initialisation and save/restore state handling.
10473 : * - Decouple the i810 support from i830 and later.
10474 : * - Remove various unnecessary hacks and workarounds.
10475 : * - Fix an 845G problem with the ring buffer not in pre-allocated
10477 : * - Fix screen blanking.
10478 : * - Clear the screen at startup so you don't see the previous session.
10479 : * - Fix some HW cursor glitches, and turn HW cursor off at VT switch
10482 : * 08/2002 Keith Whitwell
10483 : * - Fix DRI initialisation.
10486 : * 08/2002 Alan Hourihane and David Dawes
10487 : * - Add XVideo support.
10490 : * 10/2002 David Dawes
10491 : * - Add Intel(R) 865G support.
10494 : * 01/2004 Alan Hourihane
10495 : * - Add Intel(R) 915G support.
10496 : * - Add Dual Head and Clone capabilities.
10497 : * - Add lid status checking
10498 : * - Fix Xvideo with high-res LFP's
10499 : * - Add ARGB HW cursor support
10501 : * 05/2005 Alan Hourihane
10502 : * - Add Intel(R) 945G support.
10504 : * 09/2005 Alan Hourihane
10505 : * - Add Intel(R) 945GM support.
10507 : * 10/2005 Alan Hourihane, Keith Whitwell, Brian Paul
10508 : * - Added Rotation support
10510 : * 12/2005 Alan Hourihane, Keith Whitwell
10511 : * - Add Intel(R) 965G support.
10514 :#ifdef HAVE_CONFIG_H
10515 :#include "config.h"
10518 :#ifndef PRINT_MODE_INFO
10519 :#define PRINT_MODE_INFO 0
10522 :#include <assert.h>
10523 :#include <string.h>
10524 :#include <stdio.h>
10525 :#include <unistd.h>
10526 :#include <stdlib.h>
10527 :#include <stdio.h>
10530 :#include "xf86_OSproc.h"
10531 :#include "xf86Resources.h"
10532 :#include "xf86RAC.h"
10533 :#include "xf86cmap.h"
10534 :#include "compiler.h"
10535 :#include "mibstore.h"
10536 :#include "vgaHW.h"
10537 :#include "mipointer.h"
10538 :#include "micmap.h"
10539 :#include "shadowfb.h"
10540 :#include <X11/extensions/randr.h>
10542 :#include "miscstruct.h"
10543 :#include "dixstruct.h"
10544 :#include "xf86xv.h"
10545 :#include <X11/extensions/Xv.h>
10547 :#include "shadow.h"
10549 :#include "i830_display.h"
10550 :#include "i830_debug.h"
10551 :#include "i830_bios.h"
10555 :#include <sys/ioctl.h>
10556 :#include <errno.h>
10559 :#ifdef I830_USE_EXA
10560 :const char *I830exaSymbols[] = {
10564 : "exaOffscreenAlloc",
10565 : "exaOffscreenFree",
10571 :#define BIT(x) (1 << (x))
10572 :#define MAX(a,b) ((a) > (b) ? (a) : (b))
10573 :#define NB_OF(x) (sizeof (x) / sizeof (*x))
10575 :/* *INDENT-OFF* */
10576 :static SymTabRec I830Chipsets[] = {
10577 : {PCI_CHIP_I830_M, "i830"},
10578 : {PCI_CHIP_845_G, "845G"},
10579 : {PCI_CHIP_I855_GM, "852GM/855GM"},
10580 : {PCI_CHIP_I865_G, "865G"},
10581 : {PCI_CHIP_I915_G, "915G"},
10582 : {PCI_CHIP_E7221_G, "E7221 (i915)"},
10583 : {PCI_CHIP_I915_GM, "915GM"},
10584 : {PCI_CHIP_I945_G, "945G"},
10585 : {PCI_CHIP_I945_GM, "945GM"},
10586 : {PCI_CHIP_I945_GME, "945GME"},
10587 : {PCI_CHIP_I965_G, "965G"},
10588 : {PCI_CHIP_I965_G_1, "965G"},
10589 : {PCI_CHIP_I965_Q, "965Q"},
10590 : {PCI_CHIP_I946_GZ, "946GZ"},
10591 : {PCI_CHIP_I965_GM, "965GM"},
10592 : {PCI_CHIP_I965_GME, "965GME/GLE"},
10593 : {PCI_CHIP_G33_G, "G33"},
10594 : {PCI_CHIP_Q35_G, "Q35"},
10595 : {PCI_CHIP_Q33_G, "Q33"},
10599 :static PciChipsets I830PciChipsets[] = {
10600 : {PCI_CHIP_I830_M, PCI_CHIP_I830_M, RES_SHARED_VGA},
10601 : {PCI_CHIP_845_G, PCI_CHIP_845_G, RES_SHARED_VGA},
10602 : {PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA},
10603 : {PCI_CHIP_I865_G, PCI_CHIP_I865_G, RES_SHARED_VGA},
10604 : {PCI_CHIP_I915_G, PCI_CHIP_I915_G, RES_SHARED_VGA},
10605 : {PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, RES_SHARED_VGA},
10606 : {PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA},
10607 : {PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA},
10608 : {PCI_CHIP_I945_GM, PCI_CHIP_I945_GM, RES_SHARED_VGA},
10609 : {PCI_CHIP_I945_GME, PCI_CHIP_I945_GME, RES_SHARED_VGA},
10610 : {PCI_CHIP_I965_G, PCI_CHIP_I965_G, RES_SHARED_VGA},
10611 : {PCI_CHIP_I965_G_1, PCI_CHIP_I965_G_1, RES_SHARED_VGA},
10612 : {PCI_CHIP_I965_Q, PCI_CHIP_I965_Q, RES_SHARED_VGA},
10613 : {PCI_CHIP_I946_GZ, PCI_CHIP_I946_GZ, RES_SHARED_VGA},
10614 : {PCI_CHIP_I965_GM, PCI_CHIP_I965_GM, RES_SHARED_VGA},
10615 : {PCI_CHIP_I965_GME, PCI_CHIP_I965_GME, RES_SHARED_VGA},
10616 : {PCI_CHIP_G33_G, PCI_CHIP_G33_G, RES_SHARED_VGA},
10617 : {PCI_CHIP_Q35_G, PCI_CHIP_Q35_G, RES_SHARED_VGA},
10618 : {PCI_CHIP_Q33_G, PCI_CHIP_Q33_G, RES_SHARED_VGA},
10619 : {-1, -1, RES_UNDEFINED}
10623 : * Note: "ColorKey" is provided for compatibility with the i810 driver.
10624 : * However, the correct option name is "VideoKey". "ColorKey" usually
10625 : * refers to the tranparency key for 8+24 overlays, not for video overlays.
10629 :#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
10630 : OPTION_ACCELMETHOD,
10633 : OPTION_SW_CURSOR,
10634 : OPTION_CACHE_LINES,
10638 : OPTION_VIDEO_KEY,
10639 : OPTION_COLOR_KEY,
10640 : OPTION_CHECKDEVICES,
10641 : OPTION_MODEDEBUG,
10643 : OPTION_INTELTEXPOOL,
10644 : OPTION_INTELMMSIZE,
10646 : OPTION_TRIPLEBUFFER,
10649 :static OptionInfoRec I830Options[] = {
10650 :#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
10651 : {OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE},
10653 : {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE},
10654 : {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
10655 : {OPTION_CACHE_LINES, "CacheLines", OPTV_INTEGER, {0}, FALSE},
10656 : {OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, TRUE},
10657 : {OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, FALSE},
10658 : {OPTION_XVIDEO, "XVideo", OPTV_BOOLEAN, {0}, TRUE},
10659 : {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE},
10660 : {OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE},
10661 : {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE},
10662 : {OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE},
10664 : {OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE},
10665 : {OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE},
10667 : {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE},
10668 : {-1, NULL, OPTV_NONE, {0}, FALSE}
10672 :const char *i830_output_type_names[] = {
10681 :static void i830AdjustFrame(int scrnIndex, int x, int y, int flags);
10682 :static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen);
10683 :static Bool I830EnterVT(int scrnIndex, int flags);
10684 :static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg);
10685 :static Bool SaveHWState(ScrnInfoPtr pScrn);
10686 :static Bool RestoreHWState(ScrnInfoPtr pScrn);
10689 :extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
10693 :I830DPRINTF_stub(const char *filename, int line, const char *function,
10694 : const char *fmt, ...)
10698 : ErrorF("\n##############################################\n"
10699 : "*** In function %s, on line %d, in file %s ***\n",
10700 : function, line, filename);
10701 : va_start(ap, fmt);
10702 : VErrorF(fmt, ap);
10704 : ErrorF("##############################################\n\n");
10706 :#else /* #ifdef I830DEBUG */
10708 :I830DPRINTF_stub(const char *filename, int line, const char *function,
10709 : const char *fmt, ...)
10713 :#endif /* #ifdef I830DEBUG */
10715 :/* Export I830 options to i830 driver where necessary */
10716 :const OptionInfoRec *
10717 :I830AvailableOptions(int chipid, int busid)
10721 : for (i = 0; I830PciChipsets[i].PCIid > 0; i++) {
10722 : if (chipid == I830PciChipsets[i].PCIid)
10723 : return I830Options;
10729 :I830GetRec(ScrnInfoPtr pScrn)
10733 : if (pScrn->driverPrivate)
10735 : pI830 = pScrn->driverPrivate = xnfcalloc(sizeof(I830Rec), 1);
10740 :I830FreeRec(ScrnInfoPtr pScrn)
10746 : if (!pScrn->driverPrivate)
10749 : pI830 = I830PTR(pScrn);
10751 : xfree(pScrn->driverPrivate);
10752 : pScrn->driverPrivate = NULL;
10756 :I830ProbeDDC(ScrnInfoPtr pScrn, int index)
10760 : /* The vbe module gets loaded in PreInit(), so no need to load it here. */
10762 : pVbe = VBEInit(NULL, index);
10763 : ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
10767 :I830DetectMemory(ScrnInfoPtr pScrn)
10769 : I830Ptr pI830 = I830PTR(pScrn);
10771 : CARD16 gmch_ctrl;
10772 : int memsize = 0, gtt_size;
10775 : VbeInfoBlock *vbeInfo;
10778 : bridge = pciTag(0, 0, 0); /* This is always the host bridge */
10779 : gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
10781 : if (IS_I965G(pI830)) {
10782 : /* The 965 may have a GTT that is actually larger than is necessary
10783 : * to cover the aperture, so check the hardware's reporting of the
10786 : switch (INREG(PGETBL_CTL) & PGETBL_SIZE_MASK) {
10787 : case PGETBL_SIZE_512KB:
10790 : case PGETBL_SIZE_256KB:
10793 : case PGETBL_SIZE_128KB:
10797 : FatalError("Unknown GTT size value: %08x\n", (int)INREG(PGETBL_CTL));
10799 : } else if (IS_G33CLASS(pI830)) {
10800 : /* G33's GTT size is detect in GMCH_CTRL */
10801 : switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
10802 : case G33_PGETBL_SIZE_1M:
10805 : case G33_PGETBL_SIZE_2M:
10809 : FatalError("Unknown GTT size value: %08x\n",
10810 : (int)(gmch_ctrl & G33_PGETBL_SIZE_MASK));
10813 : /* Older chipsets only had GTT appropriately sized for the aperture. */
10814 : gtt_size = pI830->FbMapSize / (1024*1024);
10817 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "detected %d kB GTT.\n", gtt_size);
10819 : /* The stolen memory has the GTT at the top, and the 4KB popup below that.
10820 : * Everything else can be freely used by the graphics driver.
10822 : range = gtt_size + 4;
10824 : if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
10825 : switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
10826 : case I855_GMCH_GMS_STOLEN_1M:
10827 : memsize = MB(1) - KB(range);
10829 : case I855_GMCH_GMS_STOLEN_4M:
10830 : memsize = MB(4) - KB(range);
10832 : case I855_GMCH_GMS_STOLEN_8M:
10833 : memsize = MB(8) - KB(range);
10835 : case I855_GMCH_GMS_STOLEN_16M:
10836 : memsize = MB(16) - KB(range);
10838 : case I855_GMCH_GMS_STOLEN_32M:
10839 : memsize = MB(32) - KB(range);
10841 : case I915G_GMCH_GMS_STOLEN_48M:
10842 : if (IS_I9XX(pI830))
10843 : memsize = MB(48) - KB(range);
10845 : case I915G_GMCH_GMS_STOLEN_64M:
10846 : if (IS_I9XX(pI830))
10847 : memsize = MB(64) - KB(range);
10849 : case G33_GMCH_GMS_STOLEN_128M:
10850 : if (IS_G33CLASS(pI830))
10851 : memsize = MB(128) - KB(range);
10853 : case G33_GMCH_GMS_STOLEN_256M:
10854 : if (IS_G33CLASS(pI830))
10855 : memsize = MB(256) - KB(range);
10859 : switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
10860 : case I830_GMCH_GMS_STOLEN_512:
10861 : memsize = KB(512) - KB(range);
10863 : case I830_GMCH_GMS_STOLEN_1024:
10864 : memsize = MB(1) - KB(range);
10866 : case I830_GMCH_GMS_STOLEN_8192:
10867 : memsize = MB(8) - KB(range);
10869 : case I830_GMCH_GMS_LOCAL:
10871 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
10872 : "Local memory found, but won't be used.\n");
10878 : /* And 64KB page aligned */
10879 : memsize &= ~0xFFFF;
10882 : if (memsize > 0) {
10883 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
10884 : "detected %d kB stolen memory.\n", memsize / 1024);
10886 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n");
10893 :I830MapMMIO(ScrnInfoPtr pScrn)
10896 : I830Ptr pI830 = I830PTR(pScrn);
10898 :#if !defined(__alpha__)
10899 : mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
10901 : mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
10904 : pI830->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
10906 : pI830->MMIOAddr, I810_REG_SIZE);
10907 : if (!pI830->MMIOBase)
10910 : /* Set up the GTT mapping for the various places it has been moved over
10913 : if (IS_I9XX(pI830)) {
10914 : if (IS_I965G(pI830)) {
10915 : pI830->GTTBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
10917 : pI830->MMIOAddr + (512 * 1024),
10919 : if (pI830->GTTBase == NULL)
10922 : CARD32 gttaddr = pI830->PciInfo->memBase[3] & 0xFFFFFF00;
10924 : pI830->GTTBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
10927 : pI830->FbMapSize / 1024);
10928 : if (pI830->GTTBase == NULL)
10932 : /* The GTT aperture on i830 is write-only. We could probably map the
10933 : * actual physical pages that back it, but leave it alone for now.
10935 : pI830->GTTBase = NULL;
10942 :I830MapMem(ScrnInfoPtr pScrn)
10944 : I830Ptr pI830 = I830PTR(pScrn);
10947 : for (i = 2; i < pI830->FbMapSize; i <<= 1) ;
10948 : pI830->FbMapSize = i;
10950 : if (!I830MapMMIO(pScrn))
10953 : pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
10955 : pI830->LinearAddr, pI830->FbMapSize);
10956 : if (!pI830->FbBase)
10959 : if (I830IsPrimary(pScrn) && pI830->LpRing->mem != NULL) {
10960 : pI830->LpRing->virtual_start =
10961 : pI830->FbBase + pI830->LpRing->mem->offset;
10968 :I830UnmapMMIO(ScrnInfoPtr pScrn)
10970 : I830Ptr pI830 = I830PTR(pScrn);
10972 : xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase,
10974 : pI830->MMIOBase = NULL;
10976 : if (IS_I9XX(pI830)) {
10977 : if (IS_I965G(pI830))
10978 : xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase, 512 * 1024);
10980 : xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase,
10981 : pI830->FbMapSize / 1024);
10987 :I830UnmapMem(ScrnInfoPtr pScrn)
10989 : I830Ptr pI830 = I830PTR(pScrn);
10991 : xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->FbBase,
10992 : pI830->FbMapSize);
10993 : pI830->FbBase = NULL;
10994 : I830UnmapMMIO(pScrn);
10999 :I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
11000 : LOCO * colors, VisualPtr pVisual)
11002 : xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
11005 : CARD16 lut_r[256], lut_g[256], lut_b[256];
11007 : DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
11009 : for(p = 0; p < xf86_config->num_crtc; p++) {
11010 : xf86CrtcPtr crtc = xf86_config->crtc[p];
11011 : I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
11013 : /* Initialize to the old lookup table values. */
11014 : for (i = 0; i < 256; i++) {
11015 : lut_r[i] = intel_crtc->lut_r[i] << 8;
11016 : lut_g[i] = intel_crtc->lut_g[i] << 8;
11017 : lut_b[i] = intel_crtc->lut_b[i] << 8;
11020 : switch(pScrn->depth) {
11022 : for (i = 0; i < numColors; i++) {
11023 : index = indices[i];
11024 : for (j = 0; j < 8; j++) {
11025 : lut_r[index * 8 + j] = colors[index].red << 8;
11026 : lut_g[index * 8 + j] = colors[index].green << 8;
11027 : lut_b[index * 8 + j] = colors[index].blue << 8;
11032 : for (i = 0; i < numColors; i++) {
11033 : index = indices[i];
11035 : if (index <= 31) {
11036 : for (j = 0; j < 8; j++) {
11037 : lut_r[index * 8 + j] = colors[index].red << 8;
11038 : lut_b[index * 8 + j] = colors[index].blue << 8;
11042 : for (j = 0; j < 4; j++) {
11043 : lut_g[index * 4 + j] = colors[index].green << 8;
11048 : for (i = 0; i < numColors; i++) {
11049 : index = indices[i];
11050 : lut_r[index] = colors[index].red << 8;
11051 : lut_g[index] = colors[index].green << 8;
11052 : lut_b[index] = colors[index].blue << 8;
11057 : /* Make the change through RandR */
11058 :#ifdef RANDR_12_INTERFACE
11059 : RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
11061 : crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
11067 :i830_output_clones (ScrnInfoPtr pScrn, int type_mask)
11069 : xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
11071 : int index_mask = 0;
11073 : for (o = 0; o < config->num_output; o++)
11075 : xf86OutputPtr output = config->output[o];
11076 : I830OutputPrivatePtr intel_output = output->driver_private;
11077 : if (type_mask & (1 << intel_output->type))
11078 : index_mask |= (1 << o);
11080 : return index_mask;
11084 : * Set up the outputs according to what type of chip we are.
11086 : * Some outputs may not initialize, due to allocation failure or because a
11087 : * controller chip isn't found.
11090 :I830SetupOutputs(ScrnInfoPtr pScrn)
11092 : xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
11093 : I830Ptr pI830 = I830PTR(pScrn);
11096 : /* everyone has at least a single analog output */
11097 : i830_crt_init(pScrn);
11099 : /* Set up integrated LVDS */
11100 : if (IS_MOBILE(pI830) && !IS_I830(pI830))
11101 : i830_lvds_init(pScrn);
11103 : if (IS_I9XX(pI830)) {
11104 : i830_sdvo_init(pScrn, SDVOB);
11105 : i830_sdvo_init(pScrn, SDVOC);
11107 : i830_dvo_init(pScrn);
11109 : if (IS_I9XX(pI830) && !IS_I915G(pI830))
11110 : i830_tv_init(pScrn);
11112 : for (o = 0; o < config->num_output; o++)
11114 : xf86OutputPtr output = config->output[o];
11115 : I830OutputPrivatePtr intel_output = output->driver_private;
11120 : for (c = 0; c < config->num_crtc; c++)
11122 : xf86CrtcPtr crtc = config->crtc[c];
11123 : I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
11125 : if (intel_output->pipe_mask & (1 << intel_crtc->pipe))
11126 : crtc_mask |= (1 << c);
11128 : output->possible_crtcs = crtc_mask;
11129 : output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask);
11134 : * Setup the CRTCs
11139 :I830PreInitDDC(ScrnInfoPtr pScrn)
11141 : I830Ptr pI830 = I830PTR(pScrn);
11143 : if (!xf86LoadSubModule(pScrn, "ddc")) {
11144 : pI830->ddc2 = FALSE;
11146 : xf86LoaderReqSymLists(I810ddcSymbols, NULL);
11147 : pI830->ddc2 = TRUE;
11150 : /* DDC can use I2C bus */
11151 : /* Load I2C if we have the code to use it */
11152 : if (pI830->ddc2) {
11153 : if (xf86LoadSubModule(pScrn, "i2c")) {
11154 : xf86LoaderReqSymLists(I810i2cSymbols, NULL);
11156 : pI830->ddc2 = TRUE;
11158 : pI830->ddc2 = FALSE;
11164 :PreInitCleanup(ScrnInfoPtr pScrn)
11166 : I830Ptr pI830 = I830PTR(pScrn);
11168 : if (I830IsPrimary(pScrn)) {
11169 : if (pI830->entityPrivate)
11170 : pI830->entityPrivate->pScrn_1 = NULL;
11172 : if (pI830->entityPrivate)
11173 : pI830->entityPrivate->pScrn_2 = NULL;
11175 : if (pI830->swfSaved) {
11176 : OUTREG(SWF0, pI830->saveSWF0);
11177 : OUTREG(SWF4, pI830->saveSWF4);
11179 : if (pI830->MMIOBase)
11180 : I830UnmapMMIO(pScrn);
11181 : I830FreeRec(pScrn);
11185 :I830IsPrimary(ScrnInfoPtr pScrn)
11187 : I830Ptr pI830 = I830PTR(pScrn);
11189 : if (xf86IsEntityShared(pScrn->entityList[0])) {
11190 : if (pI830->init == 0) return TRUE;
11191 : else return FALSE;
11198 :i830_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
11200 : scrn->virtualX = width;
11201 : scrn->virtualY = height;
11205 :static const xf86CrtcConfigFuncsRec i830_xf86crtc_config_funcs = {
11206 : i830_xf86crtc_resize
11209 :#define HOTKEY_BIOS_SWITCH 0
11210 :#define HOTKEY_DRIVER_NOTIFY 1
11213 : * Controls the BIOS's behavior on hotkey switch.
11215 : * If the mode is HOTKEY_BIOS_SWITCH, the BIOS will be set to do a mode switch
11216 : * on its own and update the state in the scratch register.
11217 : * If the mode is HOTKEY_DRIVER_NOTIFY, the BIOS won't do a mode switch and
11218 : * will just update the state to represent what it would have been switched to.
11221 :i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode)
11223 : I830Ptr pI830 = I830PTR(pScrn);
11226 : gr18 = pI830->readControl(pI830, GRX, 0x18);
11227 : if (mode == HOTKEY_BIOS_SWITCH)
11228 : gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK;
11230 : gr18 |= HOTKEY_VBIOS_SWITCH_BLOCK;
11231 : pI830->writeControl(pI830, GRX, 0x18, gr18);
11235 : * This is called per zaphod head (so usually just once) to do initialization
11236 : * before the Screen is created.
11238 : * This code generally covers probing, module loading, option handling
11239 : * card mapping, and RandR setup.
11242 :I830PreInit(ScrnInfoPtr pScrn, int flags)
11244 : xf86CrtcConfigPtr xf86_config;
11247 : MessageType from = X_PROBED;
11248 : rgb defaultWeight = { 0, 0, 0 };
11249 : EntityInfoPtr pEnt;
11250 : I830EntPtr pI830Ent = NULL;
11254 : pointer pVBEModule = NULL;
11255 : const char *chipname;
11257 : int max_width, max_height;
11259 : if (pScrn->numEntities != 1)
11262 : /* Load int10 module */
11263 : if (!xf86LoadSubModule(pScrn, "int10"))
11265 : xf86LoaderReqSymLists(I810int10Symbols, NULL);
11267 : /* Load vbe module */
11268 : if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe")))
11270 : xf86LoaderReqSymLists(I810vbeSymbols, NULL);
11272 : pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
11274 : if (flags & PROBE_DETECT) {
11275 : I830ProbeDDC(pScrn, pEnt->index);
11279 : /* The vgahw module should be loaded here when needed */
11280 : if (!xf86LoadSubModule(pScrn, "vgahw"))
11282 : xf86LoaderReqSymLists(I810vgahwSymbols, NULL);
11284 : /* Allocate a vgaHWRec */
11285 : if (!vgaHWGetHWRec(pScrn))
11288 : /* Allocate driverPrivate */
11289 : if (!I830GetRec(pScrn))
11292 : pI830 = I830PTR(pScrn);
11293 : pI830->SaveGeneration = -1;
11294 : pI830->pEnt = pEnt;
11296 : pScrn->displayWidth = 640; /* default it */
11298 : if (pI830->pEnt->location.type != BUS_PCI)
11301 : pI830->PciInfo = xf86GetPciInfoForEntity(pI830->pEnt->index);
11302 : pI830->PciTag = pciTag(pI830->PciInfo->bus, pI830->PciInfo->device,
11303 : pI830->PciInfo->func);
11305 : /* Allocate an entity private if necessary */
11306 : if (xf86IsEntityShared(pScrn->entityList[0])) {
11307 : pI830Ent = xf86GetEntityPrivate(pScrn->entityList[0],
11308 : I830EntityIndex)->ptr;
11309 : pI830->entityPrivate = pI830Ent;
11311 : pI830->entityPrivate = NULL;
11313 : if (xf86RegisterResources(pI830->pEnt->index, NULL, ResNone)) {
11314 : PreInitCleanup(pScrn);
11318 : if (xf86IsEntityShared(pScrn->entityList[0])) {
11319 : if (xf86IsPrimInitDone(pScrn->entityList[0])) {
11322 : if (!pI830Ent->pScrn_1) {
11323 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
11324 : "Failed to setup second head due to primary head failure.\n");
11328 : xf86SetPrimInitDone(pScrn->entityList[0]);
11333 : if (xf86IsEntityShared(pScrn->entityList[0])) {
11334 : if (!I830IsPrimary(pScrn)) {
11335 : pI830Ent->pScrn_2 = pScrn;
11337 : pI830Ent->pScrn_1 = pScrn;
11338 : pI830Ent->pScrn_2 = NULL;
11342 : pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
11343 : pScrn->monitor = pScrn->confScreen->monitor;
11344 : pScrn->progClock = TRUE;
11345 : pScrn->rgbBits = 8;
11347 : flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32;
11349 : if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24))
11352 : switch (pScrn->depth) {
11359 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
11360 : "Given depth (%d) is not supported by I830 driver\n",
11364 : xf86PrintDepthBpp(pScrn);
11366 : if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
11368 : if (!xf86SetDefaultVisual(pScrn, -1))
11371 : hwp = VGAHWPTR(pScrn);
11372 : pI830->cpp = pScrn->bitsPerPixel / 8;
11374 : pI830->preinit = TRUE;
11376 : /* Process the options */
11377 : xf86CollectOptions(pScrn, NULL);
11378 : if (!(pI830->Options = xalloc(sizeof(I830Options))))
11380 : memcpy(pI830->Options, I830Options, sizeof(I830Options));
11381 : xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options);
11383 : if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) {
11384 : pI830->debug_modes = TRUE;
11386 : pI830->debug_modes = FALSE;
11389 : /* We have to use PIO to probe, because we haven't mapped yet. */
11390 : I830SetPIOAccess(pI830);
11392 : switch (pI830->PciInfo->chipType) {
11393 : case PCI_CHIP_I830_M:
11394 : chipname = "830M";
11396 : case PCI_CHIP_845_G:
11397 : chipname = "845G";
11399 : case PCI_CHIP_I855_GM:
11400 : /* Check capid register to find the chipset variant */
11401 : pI830->variant = (pciReadLong(pI830->PciTag, I85X_CAPID)
11402 : >> I85X_VARIANT_SHIFT) & I85X_VARIANT_MASK;
11403 : switch (pI830->variant) {
11405 : chipname = "855GM";
11408 : chipname = "855GME";
11411 : chipname = "852GM";
11414 : chipname = "852GME";
11417 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
11418 : "Unknown 852GM/855GM variant: 0x%x)\n", pI830->variant);
11419 : chipname = "852GM/855GM (unknown variant)";
11423 : case PCI_CHIP_I865_G:
11424 : chipname = "865G";
11426 : case PCI_CHIP_I915_G:
11427 : chipname = "915G";
11429 : case PCI_CHIP_E7221_G:
11430 : chipname = "E7221 (i915)";
11432 : case PCI_CHIP_I915_GM:
11433 : chipname = "915GM";
11435 : case PCI_CHIP_I945_G:
11436 : chipname = "945G";
11438 : case PCI_CHIP_I945_GM:
11439 : chipname = "945GM";
11441 : case PCI_CHIP_I945_GME:
11442 : chipname = "945GME";
11444 : case PCI_CHIP_I965_G:
11445 : case PCI_CHIP_I965_G_1:
11446 : chipname = "965G";
11448 : case PCI_CHIP_I965_Q:
11449 : chipname = "965Q";
11451 : case PCI_CHIP_I946_GZ:
11452 : chipname = "946GZ";
11454 : case PCI_CHIP_I965_GM:
11455 : chipname = "965GM";
11457 : case PCI_CHIP_I965_GME:
11458 : chipname = "965GME/GLE";
11460 : case PCI_CHIP_G33_G:
11461 : chipname = "G33";
11463 : case PCI_CHIP_Q35_G:
11464 : chipname = "Q35";
11466 : case PCI_CHIP_Q33_G:
11467 : chipname = "Q33";
11470 : chipname = "unknown chipset";
11473 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
11474 : "Integrated Graphics Chipset: Intel(R) %s\n", chipname);
11476 : /* Set the Chipset and ChipRev, allowing config file entries to override. */
11477 : if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) {
11478 : pScrn->chipset = pI830->pEnt->device->chipset;
11480 : } else if (pI830->pEnt->device->chipID >= 0) {
11481 : pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
11482 : pI830->pEnt->device->chipID);
11484 : xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
11485 : pI830->pEnt->device->chipID);
11486 : pI830->PciInfo->chipType = pI830->pEnt->device->chipID;
11489 : pScrn->chipset = (char *)xf86TokenToString(I830Chipsets,
11490 : pI830->PciInfo->chipType);
11493 : if (pI830->pEnt->device->chipRev >= 0) {
11494 : xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
11495 : pI830->pEnt->device->chipRev);
11498 : xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n",
11499 : (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx");
11501 : if (pI830->pEnt->device->MemBase != 0) {
11502 : pI830->LinearAddr = pI830->pEnt->device->MemBase;
11505 : if (IS_I9XX(pI830)) {
11506 : pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xFF000000;
11508 : } else if (pI830->PciInfo->memBase[1] != 0) {
11509 : /* XXX Check mask. */
11510 : pI830->LinearAddr = pI830->PciInfo->memBase[0] & 0xFF000000;
11513 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
11514 : "No valid FB address in PCI config space\n");
11515 : PreInitCleanup(pScrn);
11520 : xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
11521 : (unsigned long)pI830->LinearAddr);
11523 : if (pI830->pEnt->device->IOBase != 0) {
11524 : pI830->MMIOAddr = pI830->pEnt->device->IOBase;
11527 : if (IS_I9XX(pI830)) {
11528 : pI830->MMIOAddr = pI830->PciInfo->memBase[0] & 0xFFF80000;
11530 : } else if (pI830->PciInfo->memBase[1]) {
11531 : pI830->MMIOAddr = pI830->PciInfo->memBase[1] & 0xFFF80000;
11534 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
11535 : "No valid MMIO address in PCI config space\n");
11536 : PreInitCleanup(pScrn);
11541 : xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
11542 : (unsigned long)pI830->MMIOAddr);
11544 : /* Allocate an xf86CrtcConfig */
11545 : xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs);
11546 : xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
11548 : /* See i830_exa.c comments for why we limit the framebuffer size like this.
11550 : if (IS_I965G(pI830)) {
11551 : max_width = 8192;
11552 : max_height = 8192;
11554 : max_width = 2048;
11555 : max_height = 2048;
11557 : xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
11559 : if (IS_I830(pI830) || IS_845G(pI830)) {
11561 : CARD16 gmch_ctrl;
11563 : bridge = pciTag(0, 0, 0); /* This is always the host bridge */
11564 : gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
11565 : if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
11566 : pI830->FbMapSize = 0x8000000;
11568 : pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
11571 : if (IS_I9XX(pI830)) {
11572 : pI830->FbMapSize = 1UL << pciGetBaseSize(pI830->PciTag, 2, TRUE,
11575 : /* 128MB aperture for later i8xx series. */
11576 : pI830->FbMapSize = 0x8000000;
11580 : /* Some of the probing needs MMIO access, so map it here. */
11581 : I830MapMMIO(pScrn);
11583 : if (pI830->debug_modes) {
11584 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state on X startup:\n");
11585 : i830DumpRegs (pScrn);
11588 : i830TakeRegSnapshot(pScrn);
11591 : pI830->saveSWF0 = INREG(SWF0);
11592 : pI830->saveSWF4 = INREG(SWF4);
11593 : pI830->swfSaved = TRUE;
11595 : /* Set "extended desktop" */
11596 : OUTREG(SWF0, pI830->saveSWF0 | (1 << 21));
11598 : /* Set "driver loaded", "OS unknown", "APM 1.2" */
11599 : OUTREG(SWF4, (pI830->saveSWF4 & ~((3 << 19) | (7 << 16))) |
11600 : (1 << 23) | (2 << 16));
11603 : if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
11606 : if (IS_MOBILE(pI830) || IS_I9XX(pI830))
11610 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
11611 : num_pipe, num_pipe > 1 ? "s" : "");
11613 : if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) {
11614 : pI830->noAccel = TRUE;
11618 : * The ugliness below:
11619 : * If either XAA or EXA (exclusive) is compiled in, default to it.
11621 : * If both are compiled in, and the user didn't specify noAccel, use the
11622 : * config option AccelMethod to determine which to use, defaulting to XAA
11623 : * if none is specified, or if the string was unrecognized.
11625 : * All this *could* go away if we removed XAA support from this driver,
11626 : * for example. :)
11628 : if (!pI830->noAccel) {
11629 :#if (defined(I830_USE_EXA) && defined(I830_USE_XAA)) || !defined(I830_USE_EXA)
11630 : pI830->useEXA = FALSE;
11632 : pI830->useEXA = TRUE;
11634 :#if defined(I830_USE_XAA) && defined(I830_USE_EXA)
11635 : int from = X_DEFAULT;
11636 : if ((s = (char *)xf86GetOptValString(pI830->Options,
11637 : OPTION_ACCELMETHOD))) {
11638 : if (!xf86NameCmp(s, "EXA")) {
11640 : pI830->useEXA = TRUE;
11642 : else if (!xf86NameCmp(s, "XAA")) {
11644 : pI830->useEXA = FALSE;
11648 : xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n",
11649 : pI830->useEXA ? "EXA" : "XAA");
11652 : if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) {
11653 : pI830->SWCursor = TRUE;
11656 : pI830->directRenderingDisabled =
11657 : !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE);
11660 : if (!pI830->directRenderingDisabled) {
11661 : if (pI830->noAccel || pI830->SWCursor) {
11662 : xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
11663 : "needs HW cursor and 2D acceleration.\n");
11664 : pI830->directRenderingDisabled = TRUE;
11665 : } else if (pScrn->depth != 16 && pScrn->depth != 24) {
11666 : xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it "
11667 : "runs only at depths 16 and 24.\n");
11668 : pI830->directRenderingDisabled = TRUE;
11671 : pI830->mmModeFlags = 0;
11673 : if (!pI830->directRenderingDisabled) {
11674 : pI830->mmModeFlags = I830_KERNEL_TEX;
11676 : Bool tmp = FALSE;
11678 : if (!IS_I965G(pI830))
11679 : pI830->mmModeFlags |= I830_KERNEL_MM;
11685 : if (xf86GetOptValBool(pI830->Options,
11686 : OPTION_INTELTEXPOOL, &tmp)) {
11689 : pI830->mmModeFlags |= I830_KERNEL_TEX;
11690 : pI830->mmModeFlags &= ~I830_KERNEL_MM;
11692 : pI830->mmModeFlags &= ~I830_KERNEL_TEX;
11693 : pI830->mmModeFlags |= I830_KERNEL_MM;
11698 : xf86DrvMsg(pScrn->scrnIndex, from,
11699 : "Will %stry to allocate texture pool "
11700 : "for old Mesa 3D driver.\n",
11701 : (pI830->mmModeFlags & I830_KERNEL_TEX) ?
11705 : pI830->mmSize = I830_MM_MAXSIZE;
11707 : if (xf86GetOptValInteger(pI830->Options, OPTION_INTELMMSIZE,
11708 : &(pI830->mmSize))) {
11711 : xf86DrvMsg(pScrn->scrnIndex, from,
11712 : "Will try to reserve %d kiB of AGP aperture space\n"
11713 : "\tfor the DRM memory manager.\n",
11721 : I830PreInitDDC(pScrn);
11722 : for (i = 0; i < num_pipe; i++) {
11723 : i830_crtc_init(pScrn, i);
11725 : I830SetupOutputs(pScrn);
11727 : SaveHWState(pScrn);
11728 : if (!xf86InitialConfiguration (pScrn, FALSE))
11730 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
11731 : RestoreHWState(pScrn);
11732 : PreInitCleanup(pScrn);
11735 : RestoreHWState(pScrn);
11737 : /* XXX This should go away, replaced by xf86Crtc.c support for it */
11738 : pI830->rotation = RR_Rotate_0;
11741 : * Let's setup the mobile systems to check the lid status
11743 : if (IS_MOBILE(pI830)) {
11744 : pI830->checkDevices = TRUE;
11746 : if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) {
11747 : pI830->checkDevices = FALSE;
11748 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
11750 : if (pI830->entityPrivate && !I830IsPrimary(pScrn) &&
11751 : !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) {
11752 : /* If checklid is off, on the primary head, then
11753 : * turn it off on the secondary*/
11754 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
11755 : pI830->checkDevices = FALSE;
11757 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n");
11759 : pI830->checkDevices = FALSE;
11761 : pI830->stolen_size = I830DetectMemory(pScrn);
11763 : pI830->XvDisabled =
11764 : !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE);
11767 : if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY,
11768 : &(pI830->colorKey))) {
11770 : } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY,
11771 : &(pI830->colorKey))) {
11774 : pI830->colorKey = (1 << pScrn->offset.red) |
11775 : (1 << pScrn->offset.green) |
11776 : (((pScrn->mask.blue >> pScrn->offset.blue) - 1) <<
11777 : pScrn->offset.blue);
11778 : from = X_DEFAULT;
11780 : xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n",
11781 : pI830->colorKey);
11785 : pI830->allowPageFlip = FALSE;
11786 : from = (!pI830->directRenderingDisabled &&
11787 : xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP,
11788 : &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT;
11790 : xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n",
11791 : pI830->allowPageFlip ? "" : " not");
11795 : pI830->TripleBuffer = FALSE;
11796 : from = (!pI830->directRenderingDisabled &&
11797 : xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER,
11798 : &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT;
11800 : xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n",
11801 : pI830->TripleBuffer ? "en" : "dis");
11805 : * If the driver can do gamma correction, it should call xf86SetGamma() here.
11809 : Gamma zeros = { 0.0, 0.0, 0.0 };
11811 : if (!xf86SetGamma(pScrn, zeros)) {
11812 : PreInitCleanup(pScrn);
11817 : /* Check if the HW cursor needs physical address. */
11818 : if (IS_MOBILE(pI830) || IS_I9XX(pI830))
11819 : pI830->CursorNeedsPhysical = TRUE;
11821 : pI830->CursorNeedsPhysical = FALSE;
11823 : if (IS_I965G(pI830) || IS_G33CLASS(pI830))
11824 : pI830->CursorNeedsPhysical = FALSE;
11827 : * XXX If we knew the pre-initialised GTT format for certain, we could
11828 : * probably figure out the physical address even in the StolenOnly case.
11830 : if (!I830IsPrimary(pScrn)) {
11831 : I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
11832 : if (!pI8301->SWCursor) {
11833 : xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
11834 : "Using HW Cursor because it's enabled on primary head.\n");
11835 : pI830->SWCursor = FALSE;
11838 : if (pI830->StolenOnly && pI830->CursorNeedsPhysical && !pI830->SWCursor) {
11839 : xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
11840 : "HW Cursor disabled because it needs agpgart memory.\n");
11841 : pI830->SWCursor = TRUE;
11844 : if (pScrn->modes == NULL) {
11845 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
11846 : PreInitCleanup(pScrn);
11849 : pScrn->currentMode = pScrn->modes;
11851 : if (!IS_I965G(pI830) && pScrn->virtualY > 2048) {
11852 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n");
11853 : pI830->noAccel = TRUE;
11856 : /* Don't need MMIO access anymore. */
11857 : if (pI830->swfSaved) {
11858 : OUTREG(SWF0, pI830->saveSWF0);
11859 : OUTREG(SWF4, pI830->saveSWF4);
11862 : /* Set display resolution */
11863 : xf86SetDpi(pScrn, 0, 0);
11865 : /* Load the required sub modules */
11866 : if (!xf86LoadSubModule(pScrn, "fb")) {
11867 : PreInitCleanup(pScrn);
11871 : xf86LoaderReqSymLists(I810fbSymbols, NULL);
11873 :#ifdef I830_USE_XAA
11874 : if (!pI830->noAccel && !pI830->useEXA) {
11875 : if (!xf86LoadSubModule(pScrn, "xaa")) {
11876 : PreInitCleanup(pScrn);
11879 : xf86LoaderReqSymLists(I810xaaSymbols, NULL);
11883 :#ifdef I830_USE_EXA
11884 : if (!pI830->noAccel && pI830->useEXA) {
11885 : XF86ModReqInfo req;
11886 : int errmaj, errmin;
11888 : memset(&req, 0, sizeof(req));
11889 : req.majorversion = 2;
11890 : req.minorversion = 1;
11891 : if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
11892 : &errmaj, &errmin)) {
11893 : LoaderErrorMsg(NULL, "exa", errmaj, errmin);
11894 : PreInitCleanup(pScrn);
11897 : xf86LoaderReqSymLists(I830exaSymbols, NULL);
11900 : if (!pI830->SWCursor) {
11901 : if (!xf86LoadSubModule(pScrn, "ramdac")) {
11902 : PreInitCleanup(pScrn);
11905 : xf86LoaderReqSymLists(I810ramdacSymbols, NULL);
11908 : i830CompareRegsToSnapshot(pScrn, "After PreInit");
11910 : I830UnmapMMIO(pScrn);
11912 : /* We won't be using the VGA access after the probe. */
11913 : I830SetMMIOAccess(pI830);
11914 : xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr);
11915 : xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr);
11918 : if (I830IsPrimary(pScrn)) {
11919 : vbeFree(pI830->pVbe);
11921 : pI830->pVbe = NULL;
11924 :#if defined(XF86DRI)
11925 : /* Load the dri module if requested. */
11926 : if (xf86ReturnOptValBool(pI830->Options, OPTION_DRI, FALSE) &&
11927 : !pI830->directRenderingDisabled) {
11928 : if (xf86LoadSubModule(pScrn, "dri")) {
11929 : xf86LoaderReqSymLists(I810driSymbols, I810drmSymbols, NULL);
11934 : pI830->preinit = FALSE;
11940 : * Reset registers that it doesn't make sense to save/restore to a sane state.
11941 : * This is basically the ring buffer and fence registers. Restoring these
11942 : * doesn't make sense without restoring GTT mappings. This is something that
11943 : * whoever gets control next should do.
11946 :ResetState(ScrnInfoPtr pScrn, Bool flush)
11948 : I830Ptr pI830 = I830PTR(pScrn);
11950 : unsigned long temp;
11952 : DPRINTF(PFX, "ResetState: flush is %s\n", BOOLTOSTRING(flush));
11954 : if (!I830IsPrimary(pScrn)) return;
11956 : if (pI830->entityPrivate)
11957 : pI830->entityPrivate->RingRunning = 0;
11959 : /* Reset the fence registers to 0 */
11960 : if (IS_I965G(pI830)) {
11961 : for (i = 0; i < FENCE_NEW_NR; i++) {
11962 : OUTREG(FENCE_NEW + i * 8, 0);
11963 : OUTREG(FENCE_NEW + 4 + i * 8, 0);
11966 : for (i = 0; i < FENCE_NR; i++)
11967 : OUTREG(FENCE + i * 4, 0);
11969 : /* Flush the ring buffer (if enabled), then disable it. */
11970 : /* God this is ugly */
11971 :#define flush_ring() do { \
11972 : temp = INREG(LP_RING + RING_LEN); \
11973 : if (temp & RING_VALID) { \
11974 : I830RefreshRing(pScrn); \
11975 : I830Sync(pScrn); \
11976 : DO_RING_IDLE(); \
11979 :#ifdef I830_USE_XAA
11980 : if (!pI830->useEXA && flush && pI830->AccelInfoRec)
11983 :#ifdef I830_USE_EXA
11984 : if (pI830->useEXA && flush && pI830->EXADriverPtr)
11988 : OUTREG(LP_RING + RING_LEN, 0);
11989 : OUTREG(LP_RING + RING_HEAD, 0);
11990 : OUTREG(LP_RING + RING_TAIL, 0);
11991 : OUTREG(LP_RING + RING_START, 0);
11993 : xf86_hide_cursors (pScrn);
11997 :SetFenceRegs(ScrnInfoPtr pScrn)
11999 : I830Ptr pI830 = I830PTR(pScrn);
12002 : DPRINTF(PFX, "SetFenceRegs\n");
12004 : if (!I830IsPrimary(pScrn)) return;
12006 : if (IS_I965G(pI830)) {
12007 : for (i = 0; i < FENCE_NEW_NR; i++) {
12008 : OUTREG(FENCE_NEW + i * 8, pI830->fence[i]);
12009 : OUTREG(FENCE_NEW + 4 + i * 8, pI830->fence[i+FENCE_NEW_NR]);
12010 : if (I810_DEBUG & DEBUG_VERBOSE_VGA) {
12011 : ErrorF("Fence Start Register : %x\n", pI830->fence[i]);
12012 : ErrorF("Fence End Register : %x\n", pI830->fence[i+FENCE_NEW_NR]);
12016 : for (i = 0; i < FENCE_NR; i++) {
12017 : OUTREG(FENCE + i * 4, pI830->fence[i]);
12018 : if (I810_DEBUG & DEBUG_VERBOSE_VGA)
12019 : ErrorF("Fence Register : %x\n", pI830->fence[i]);
12025 :SetRingRegs(ScrnInfoPtr pScrn)
12027 : I830Ptr pI830 = I830PTR(pScrn);
12028 : unsigned int itemp;
12030 : DPRINTF(PFX, "SetRingRegs\n");
12032 : if (pI830->noAccel)
12035 : if (!I830IsPrimary(pScrn)) return;
12037 : if (pI830->entityPrivate)
12038 : pI830->entityPrivate->RingRunning = 1;
12040 : OUTREG(LP_RING + RING_LEN, 0);
12041 : OUTREG(LP_RING + RING_TAIL, 0);
12042 : OUTREG(LP_RING + RING_HEAD, 0);
12044 : assert((pI830->LpRing->mem->offset & I830_RING_START_MASK) ==
12045 : pI830->LpRing->mem->offset);
12047 : /* Don't care about the old value. Reserved bits must be zero anyway. */
12048 : itemp = pI830->LpRing->mem->offset;
12049 : OUTREG(LP_RING + RING_START, itemp);
12051 : if (((pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES) !=
12052 : pI830->LpRing->mem->size - 4096) {
12053 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
12054 : "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
12055 : "mask (%x)\n", pI830->LpRing->mem->size - 4096,
12056 : I830_RING_NR_PAGES);
12058 : /* Don't care about the old value. Reserved bits must be zero anyway. */
12059 : itemp = (pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES;
12060 : itemp |= (RING_NO_REPORT | RING_VALID);
12061 : OUTREG(LP_RING + RING_LEN, itemp);
12062 : I830RefreshRing(pScrn);
12066 : * This should be called everytime the X server gains control of the screen,
12067 : * before any video modes are programmed (ScreenInit, EnterVT).
12070 :SetHWOperatingState(ScrnInfoPtr pScrn)
12072 : I830Ptr pI830 = I830PTR(pScrn);
12074 : DPRINTF(PFX, "SetHWOperatingState\n");
12076 : /* Disable clock gating reported to work incorrectly according to the specs.
12078 : if (IS_I965GM(pI830)) {
12079 : OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
12080 : } else if (IS_I965G(pI830)) {
12081 : OUTREG(RENCLK_GATE_D1,
12082 : I965_RCC_CLOCK_GATE_DISABLE | I965_ISC_CLOCK_GATE_DISABLE);
12083 : } else if (IS_I855(pI830) || IS_I865G(pI830)) {
12084 : OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
12085 : } else if (IS_I830(pI830)) {
12086 : OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
12089 : if (!pI830->noAccel)
12090 : SetRingRegs(pScrn);
12091 : SetFenceRegs(pScrn);
12092 : if (!pI830->SWCursor)
12093 : I830InitHWCursor(pScrn);
12097 :SaveHWState(ScrnInfoPtr pScrn)
12099 : xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
12100 : I830Ptr pI830 = I830PTR(pScrn);
12101 : vgaHWPtr hwp = VGAHWPTR(pScrn);
12102 : vgaRegPtr vgaReg = &hwp->SavedReg;
12105 : /* Save video mode information for native mode-setting. */
12106 : pI830->saveDSPACNTR = INREG(DSPACNTR);
12107 : pI830->savePIPEACONF = INREG(PIPEACONF);
12108 : pI830->savePIPEASRC = INREG(PIPEASRC);
12109 : pI830->saveFPA0 = INREG(FPA0);
12110 : pI830->saveFPA1 = INREG(FPA1);
12111 : pI830->saveDPLL_A = INREG(DPLL_A);
12112 : if (IS_I965G(pI830))
12113 : pI830->saveDPLL_A_MD = INREG(DPLL_A_MD);
12114 : pI830->saveHTOTAL_A = INREG(HTOTAL_A);
12115 : pI830->saveHBLANK_A = INREG(HBLANK_A);
12116 : pI830->saveHSYNC_A = INREG(HSYNC_A);
12117 : pI830->saveVTOTAL_A = INREG(VTOTAL_A);
12118 : pI830->saveVBLANK_A = INREG(VBLANK_A);
12119 : pI830->saveVSYNC_A = INREG(VSYNC_A);
12120 : pI830->saveBCLRPAT_A = INREG(BCLRPAT_A);
12121 : pI830->saveDSPASTRIDE = INREG(DSPASTRIDE);
12122 : pI830->saveDSPASIZE = INREG(DSPASIZE);
12123 : pI830->saveDSPAPOS = INREG(DSPAPOS);
12124 : pI830->saveDSPABASE = INREG(DSPABASE);
12126 : for(i= 0; i < 256; i++) {
12127 : pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2));
12130 : if(xf86_config->num_crtc == 2) {
12131 : pI830->savePIPEBCONF = INREG(PIPEBCONF);
12132 : pI830->savePIPEBSRC = INREG(PIPEBSRC);
12133 : pI830->saveDSPBCNTR = INREG(DSPBCNTR);
12134 : pI830->saveFPB0 = INREG(FPB0);
12135 : pI830->saveFPB1 = INREG(FPB1);
12136 : pI830->saveDPLL_B = INREG(DPLL_B);
12137 : if (IS_I965G(pI830))
12138 : pI830->saveDPLL_B_MD = INREG(DPLL_B_MD);
12139 : pI830->saveHTOTAL_B = INREG(HTOTAL_B);
12140 : pI830->saveHBLANK_B = INREG(HBLANK_B);
12141 : pI830->saveHSYNC_B = INREG(HSYNC_B);
12142 : pI830->saveVTOTAL_B = INREG(VTOTAL_B);
12143 : pI830->saveVBLANK_B = INREG(VBLANK_B);
12144 : pI830->saveVSYNC_B = INREG(VSYNC_B);
12145 : pI830->saveBCLRPAT_B = INREG(BCLRPAT_B);
12146 : pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE);
12147 : pI830->saveDSPBSIZE = INREG(DSPBSIZE);
12148 : pI830->saveDSPBPOS = INREG(DSPBPOS);
12149 : pI830->saveDSPBBASE = INREG(DSPBBASE);
12150 : for(i= 0; i < 256; i++) {
12151 : pI830->savePaletteB[i] = INREG(PALETTE_B + (i << 2));
12155 : if (IS_I965G(pI830)) {
12156 : pI830->saveDSPASURF = INREG(DSPASURF);
12157 : pI830->saveDSPBSURF = INREG(DSPBSURF);
12160 : pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0);
12161 : pI830->saveVCLK_DIVISOR_VGA1 = INREG(VCLK_DIVISOR_VGA1);
12162 : pI830->saveVCLK_POST_DIV = INREG(VCLK_POST_DIV);
12163 : pI830->saveVGACNTRL = INREG(VGACNTRL);
12165 : for(i = 0; i < 7; i++) {
12166 : pI830->saveSWF[i] = INREG(SWF0 + (i << 2));
12167 : pI830->saveSWF[i+7] = INREG(SWF00 + (i << 2));
12169 : pI830->saveSWF[14] = INREG(SWF30);
12170 : pI830->saveSWF[15] = INREG(SWF31);
12171 : pI830->saveSWF[16] = INREG(SWF32);
12173 : if (IS_MOBILE(pI830) && !IS_I830(pI830))
12174 : pI830->saveLVDS = INREG(LVDS);
12175 : pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
12177 : for (i = 0; i < xf86_config->num_output; i++) {
12178 : xf86OutputPtr output = xf86_config->output[i];
12179 : if (output->funcs->save)
12180 : (*output->funcs->save) (output);
12183 : vgaHWUnlock(hwp);
12184 : vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS);
12190 :RestoreHWState(ScrnInfoPtr pScrn)
12192 : xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
12193 : I830Ptr pI830 = I830PTR(pScrn);
12194 : vgaHWPtr hwp = VGAHWPTR(pScrn);
12195 : vgaRegPtr vgaReg = &hwp->SavedReg;
12198 : DPRINTF(PFX, "RestoreHWState\n");
12201 : I830DRISetVBlankInterrupt (pScrn, FALSE);
12203 : /* Disable outputs */
12204 : for (i = 0; i < xf86_config->num_output; i++) {
12205 : xf86OutputPtr output = xf86_config->output[i];
12206 : output->funcs->dpms(output, DPMSModeOff);
12208 : i830WaitForVblank(pScrn);
12210 : /* Disable pipes */
12211 : for (i = 0; i < xf86_config->num_crtc; i++) {
12212 : xf86CrtcPtr crtc = xf86_config->crtc[i];
12213 : crtc->funcs->dpms(crtc, DPMSModeOff);
12215 : i830WaitForVblank(pScrn);
12217 : if (IS_MOBILE(pI830) && !IS_I830(pI830))
12218 : OUTREG(LVDS, pI830->saveLVDS);
12220 : if (!IS_I830(pI830) && !IS_845G(pI830))
12221 : OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
12223 : if (pI830->saveDPLL_A & DPLL_VCO_ENABLE)
12225 : OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE);
12228 : OUTREG(FPA0, pI830->saveFPA0);
12229 : OUTREG(FPA1, pI830->saveFPA1);
12230 : OUTREG(DPLL_A, pI830->saveDPLL_A);
12232 : if (IS_I965G(pI830))
12233 : OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD);
12235 : OUTREG(DPLL_A, pI830->saveDPLL_A);
12238 : OUTREG(HTOTAL_A, pI830->saveHTOTAL_A);
12239 : OUTREG(HBLANK_A, pI830->saveHBLANK_A);
12240 : OUTREG(HSYNC_A, pI830->saveHSYNC_A);
12241 : OUTREG(VTOTAL_A, pI830->saveVTOTAL_A);
12242 : OUTREG(VBLANK_A, pI830->saveVBLANK_A);
12243 : OUTREG(VSYNC_A, pI830->saveVSYNC_A);
12244 : OUTREG(BCLRPAT_A, pI830->saveBCLRPAT_A);
12246 : OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE);
12247 : OUTREG(DSPASIZE, pI830->saveDSPASIZE);
12248 : OUTREG(DSPAPOS, pI830->saveDSPAPOS);
12249 : OUTREG(PIPEASRC, pI830->savePIPEASRC);
12250 : OUTREG(DSPABASE, pI830->saveDSPABASE);
12251 : if (IS_I965G(pI830))
12252 : OUTREG(DSPASURF, pI830->saveDSPASURF);
12253 : OUTREG(PIPEACONF, pI830->savePIPEACONF);
12254 : i830WaitForVblank(pScrn);
12255 : OUTREG(DSPACNTR, pI830->saveDSPACNTR);
12256 : OUTREG(DSPABASE, INREG(DSPABASE));
12257 : i830WaitForVblank(pScrn);
12259 : if(xf86_config->num_crtc == 2)
12261 : if (pI830->saveDPLL_B & DPLL_VCO_ENABLE)
12263 : OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE);
12266 : OUTREG(FPB0, pI830->saveFPB0);
12267 : OUTREG(FPB1, pI830->saveFPB1);
12268 : OUTREG(DPLL_B, pI830->saveDPLL_B);
12270 : if (IS_I965G(pI830))
12271 : OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
12273 : OUTREG(DPLL_B, pI830->saveDPLL_B);
12276 : OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
12277 : OUTREG(HBLANK_B, pI830->saveHBLANK_B);
12278 : OUTREG(HSYNC_B, pI830->saveHSYNC_B);
12279 : OUTREG(VTOTAL_B, pI830->saveVTOTAL_B);
12280 : OUTREG(VBLANK_B, pI830->saveVBLANK_B);
12281 : OUTREG(VSYNC_B, pI830->saveVSYNC_B);
12282 : OUTREG(BCLRPAT_B, pI830->saveBCLRPAT_B);
12283 : OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE);
12284 : OUTREG(DSPBSIZE, pI830->saveDSPBSIZE);
12285 : OUTREG(DSPBPOS, pI830->saveDSPBPOS);
12286 : OUTREG(PIPEBSRC, pI830->savePIPEBSRC);
12287 : OUTREG(DSPBBASE, pI830->saveDSPBBASE);
12288 : if (IS_I965G(pI830))
12289 : OUTREG(DSPBSURF, pI830->saveDSPBSURF);
12290 : OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
12291 : i830WaitForVblank(pScrn);
12292 : OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
12293 : OUTREG(DSPBBASE, INREG(DSPBBASE));
12294 : i830WaitForVblank(pScrn);
12297 : /* Restore outputs */
12298 : for (i = 0; i < xf86_config->num_output; i++) {
12299 : xf86OutputPtr output = xf86_config->output[i];
12300 : if (output->funcs->restore)
12301 : output->funcs->restore(output);
12304 : OUTREG(VGACNTRL, pI830->saveVGACNTRL);
12306 : OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
12307 : OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1);
12308 : OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV);
12310 : for(i = 0; i < 256; i++) {
12311 : OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
12314 : if(xf86_config->num_crtc == 2) {
12315 : for(i= 0; i < 256; i++) {
12316 : OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
12320 : for(i = 0; i < 7; i++) {
12321 : OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
12322 : OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
12325 : OUTREG(SWF30, pI830->saveSWF[14]);
12326 : OUTREG(SWF31, pI830->saveSWF[15]);
12327 : OUTREG(SWF32, pI830->saveSWF[16]);
12329 : vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
12336 :I830PointerMoved(int index, int x, int y)
12338 : ScrnInfoPtr pScrn = xf86Screens[index];
12339 : I830Ptr pI830 = I830PTR(pScrn);
12340 : int newX = x, newY = y;
12342 : switch (pI830->rotation) {
12343 : case RR_Rotate_0:
12345 : case RR_Rotate_90:
12347 : newY = pScrn->pScreen->width - x - 1;
12349 : case RR_Rotate_180:
12350 : newX = pScrn->pScreen->width - x - 1;
12351 : newY = pScrn->pScreen->height - y - 1;
12353 : case RR_Rotate_270:
12354 : newX = pScrn->pScreen->height - y - 1;
12359 : (*pI830->PointerMoved)(index, newX, newY);
12363 :I830InitFBManager(
12364 : ScreenPtr pScreen,
12367 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
12368 : RegionRec ScreenRegion;
12369 : RegionRec FullRegion;
12370 : BoxRec ScreenBox;
12373 : ScreenBox.x1 = 0;
12374 : ScreenBox.y1 = 0;
12375 : ScreenBox.x2 = pScrn->displayWidth;
12376 : if (pScrn->virtualX > pScrn->virtualY)
12377 : ScreenBox.y2 = pScrn->virtualX;
12379 : ScreenBox.y2 = pScrn->virtualY;
12381 : if((FullBox->x1 > ScreenBox.x1) || (FullBox->y1 > ScreenBox.y1) ||
12382 : (FullBox->x2 < ScreenBox.x2) || (FullBox->y2 < ScreenBox.y2)) {
12386 : if (FullBox->y2 < FullBox->y1) return FALSE;
12387 : if (FullBox->x2 < FullBox->x2) return FALSE;
12389 : REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1);
12390 : REGION_INIT(pScreen, &FullRegion, FullBox, 1);
12392 : REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion);
12394 : ret = xf86InitFBManagerRegion(pScreen, &FullRegion);
12396 : REGION_UNINIT(pScreen, &ScreenRegion);
12397 : REGION_UNINIT(pScreen, &FullRegion);
12403 : * Intialiazes the hardware for the 3D pipeline use in the 2D driver.
12405 : * Some state caching is performed to avoid redundant state emits. This
12406 : * function is also responsible for marking the state as clobbered for DRI
12410 :IntelEmitInvarientState(ScrnInfoPtr pScrn)
12411 3 0.0033 :{ /* IntelEmitInvarientState total: 36 0.0392 */
12412 3 0.0033 : I830Ptr pI830 = I830PTR(pScrn);
12415 2 0.0022 : if (pI830->noAccel)
12419 4 0.0044 : if (pI830->directRenderingEnabled) {
12420 4 0.0044 : drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn->pScreen);
12422 : /* Mark that the X Server was the last holder of the context */
12423 5 0.0054 : if (sarea)
12424 3 0.0033 : sarea->ctxOwner = DRIGetContext(pScrn->pScreen);
12428 : /* If we've emitted our state since the last clobber by another client,
12431 8 0.0087 : if (*pI830->last_3d != LAST_3D_OTHER)
12434 : ctx_addr = pI830->logical_context->offset;
12435 : assert((pI830->logical_context->offset & 2047) == 0);
12437 : BEGIN_LP_RING(2);
12438 : OUT_RING(MI_SET_CONTEXT);
12439 : OUT_RING(pI830->logical_context->offset |
12440 : CTXT_NO_RESTORE |
12441 : CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
12442 : ADVANCE_LP_RING();
12445 : if (!IS_I965G(pI830))
12447 : if (IS_I9XX(pI830))
12448 : I915EmitInvarientState(pScrn);
12450 : I830EmitInvarientState(pScrn);
12455 :#ifndef XSERVER_LIBDRM_MM
12458 :I830DrmMMInit(int drmFD, unsigned long pageOffs, unsigned long pageSize,
12459 : unsigned memType)
12462 : drm_mm_init_arg_t arg;
12465 : memset(&arg, 0, sizeof(arg));
12466 : arg.req.op = mm_init;
12467 : arg.req.p_offset = pageOffs;
12468 : arg.req.p_size = pageSize;
12469 : arg.req.mem_type = memType;
12471 : ret = ioctl(drmFD, DRM_IOCTL_MM_INIT, &arg);
12481 :I830DrmMMTakedown(int drmFD, unsigned memType)
12483 : drm_mm_init_arg_t arg;
12486 : memset(&arg, 0, sizeof(arg));
12487 : arg.req.op = mm_takedown;
12488 : arg.req.mem_type = memType;
12489 : if (ioctl(drmFD, DRM_IOCTL_MM_INIT, &arg)) {
12496 :static int I830DrmMMLock(int fd, unsigned memType)
12498 : drm_mm_init_arg_t arg;
12501 : memset(&arg, 0, sizeof(arg));
12502 : arg.req.op = mm_lock;
12503 : arg.req.mem_type = memType;
12506 : ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
12507 : } while (ret && errno == EAGAIN);
12512 :static int I830DrmMMUnlock(int fd, unsigned memType)
12514 : drm_mm_init_arg_t arg;
12517 : memset(&arg, 0, sizeof(arg));
12518 : arg.req.op = mm_unlock;
12519 : arg.req.mem_type = memType;
12522 : ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
12523 : } while (ret && errno == EAGAIN);
12529 :#endif /* XF86DRI_MM */
12532 :I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
12534 : ScrnInfoPtr pScrn;
12537 : VisualPtr visual;
12538 : I830Ptr pI8301 = NULL;
12539 : unsigned long sys_mem;
12541 : Bool allocation_done = FALSE;
12542 : MessageType from;
12544 : Bool driDisabled;
12546 : unsigned long savedMMSize;
12550 : pScrn = xf86Screens[pScreen->myNum];
12551 : pI830 = I830PTR(pScrn);
12552 : hwp = VGAHWPTR(pScrn);
12554 : pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
12557 : * The "VideoRam" config file parameter specifies the maximum amount of
12558 : * memory that will be used/allocated. When not present, we allow the
12559 : * driver to allocate as much memory as it wishes to satisfy its
12560 : * allocations, but if agpgart support isn't available, it gets limited
12561 : * to the amount of pre-allocated ("stolen") memory.
12563 : * Note that in using this value for allocator initialization, we're
12564 : * limiting aperture allocation to the VideoRam option, rather than limiting
12565 : * actual memory allocation, so alignment and things will cause less than
12566 : * VideoRam to be actually used.
12568 : if (pI830->pEnt->device->videoRam == 0) {
12569 : from = X_DEFAULT;
12570 : pScrn->videoRam = pI830->FbMapSize / KB(1);
12574 : pScrn->videoRam = pI830->pEnt->device->videoRam;
12576 : /* Disable VideoRam configuration, at least for now. Previously,
12577 : * VideoRam was necessary to avoid overly low limits on allocated
12578 : * memory, so users created larger, yet still small, fixed allocation
12579 : * limits in their config files. Now, the driver wants to allocate more,
12580 : * and the old intention of the VideoRam lines that had been entered is
12583 : from = X_DEFAULT;
12584 : pScrn->videoRam = pI830->FbMapSize / KB(1);
12586 : if (pScrn->videoRam != pI830->pEnt->device->videoRam) {
12587 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12588 : "VideoRam configuration found, which is no longer "
12589 : "recommended.\n");
12590 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
12591 : "Continuing with default %dkB VideoRam instead of %d "
12593 : pScrn->videoRam, pI830->pEnt->device->videoRam);
12598 : /* Limit videoRam to how much we might be able to allocate from AGP */
12599 : sys_mem = I830CheckAvailableMemory(pScrn);
12600 : if (sys_mem == -1) {
12601 : if (pScrn->videoRam > pI830->stolen_size / KB(1)) {
12602 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12603 : "/dev/agpgart is either not available, or no memory "
12604 : "is available\nfor allocation. "
12605 : "Using pre-allocated memory only.\n");
12606 : pScrn->videoRam = pI830->stolen_size / KB(1);
12608 : pI830->StolenOnly = TRUE;
12610 : if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) {
12611 : pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024);
12613 : if (sys_mem + (pI830->stolen_size / 1024) <
12614 : pI830->pEnt->device->videoRam)
12616 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12617 : "VideoRAM reduced to %d kByte "
12618 : "(limited to available sysmem)\n", pScrn->videoRam);
12623 : /* Limit video RAM to the actual aperture size */
12624 : if (pScrn->videoRam > pI830->FbMapSize / 1024) {
12625 : pScrn->videoRam = pI830->FbMapSize / 1024;
12626 : if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) {
12627 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12628 : "VideoRam reduced to %d kByte (limited to aperture "
12630 : pScrn->videoRam);
12634 : /* Make sure it's on a page boundary */
12635 : if (pScrn->videoRam & 3) {
12636 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB "
12637 : "(page aligned - was %d KB)\n",
12638 : pScrn->videoRam & ~3, pScrn->videoRam);
12639 : pScrn->videoRam &= ~3;
12642 : /* Set up our video memory allocator for the chosen videoRam */
12643 : if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) {
12644 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
12645 : "Couldn't initialize video memory allocator\n");
12646 : PreInitCleanup(pScrn);
12650 : xf86DrvMsg(pScrn->scrnIndex,
12651 : pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
12652 : "VideoRam: %d KB\n", pScrn->videoRam);
12654 : if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES,
12655 : &(pI830->CacheLines))) {
12656 : xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n",
12657 : pI830->CacheLines);
12659 : pI830->CacheLines = -1;
12662 : pI830->disableTiling = FALSE;
12664 : if (I830IsPrimary(pScrn)) {
12665 : /* Alloc our pointers for the primary head */
12666 : if (!pI830->LpRing)
12667 : pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer));
12668 : if (!pI830->overlayOn)
12669 : pI830->overlayOn = xalloc(sizeof(Bool));
12670 : if (!pI830->last_3d)
12671 : pI830->last_3d = xalloc(sizeof(enum last_3d));
12672 : if (!pI830->LpRing || !pI830->overlayOn || !pI830->last_3d) {
12673 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
12674 : "Could not allocate primary data structures.\n");
12677 : *pI830->last_3d = LAST_3D_OTHER;
12678 : *pI830->overlayOn = FALSE;
12679 : if (pI830->entityPrivate)
12680 : pI830->entityPrivate->XvInUse = -1;
12682 : /* Make our second head point to the first heads structures */
12683 : pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
12684 : pI830->LpRing = pI8301->LpRing;
12685 : pI830->overlay_regs = pI8301->overlay_regs;
12686 : pI830->overlayOn = pI8301->overlayOn;
12687 : pI830->last_3d = pI8301->last_3d;
12690 : /* Need MMIO mapped to do GTT lookups during memory allocation. */
12691 : I830MapMMIO(pScrn);
12693 :#if defined(XF86DRI)
12695 : * If DRI is potentially usable, check if there is enough memory available
12696 : * for it, and if there's also enough to allow tiling to be enabled.
12699 : if (!I830CheckDRIAvailable(pScrn)) {
12700 : pI830->directRenderingDisabled = TRUE;
12702 : pI830->mmSize = 0;
12708 : * Set this so that the overlay allocation is factored in when
12711 : pI830->XvEnabled = !pI830->XvDisabled;
12714 : if (!pI830->directRenderingDisabled) {
12715 : int savedDisplayWidth = pScrn->displayWidth;
12716 : Bool tiled = FALSE;
12718 : if (IS_I965G(pI830)) {
12719 : int tile_pixels = 512 / pI830->cpp;
12720 : pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
12721 : ~(tile_pixels - 1);
12724 : /* Good pitches to allow tiling. Don't care about pitches < 1024
12727 : static const int pitches[] = {
12735 : for (i = 0; pitches[i] != 0; i++) {
12736 : if (pitches[i] >= pScrn->displayWidth) {
12737 : pScrn->displayWidth = pitches[i];
12744 : /* Attempt several rounds of allocation to get 2d and 3d memory to fit:
12746 : * 0: tiled, large memory manager
12747 : * 1: tiled, small memory manager
12748 : * 2: untiled, large
12749 : * 3: untiled, small
12752 : pI830->disableTiling = FALSE;
12754 : savedMMSize = pI830->mmSize;
12755 :#define MM_TURNS 4
12757 :#define MM_TURNS 2
12759 : for (i = 0; i < MM_TURNS; i++) {
12760 : if (!tiled && i < 2)
12763 : if (i >= MM_TURNS/2) {
12764 : /* For further allocations, disable tiling */
12765 : pI830->disableTiling = TRUE;
12766 : pScrn->displayWidth = savedDisplayWidth;
12767 : if (pI830->allowPageFlip)
12768 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12769 : "Couldn't allocate tiled memory, page flipping "
12771 : pI830->allowPageFlip = FALSE;
12776 : /* For this allocation, switch to a smaller DRI memory manager
12779 : pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE / KB(1);
12781 : pI830->mmSize = savedMMSize;
12784 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
12785 : "Attempting memory allocation with %s buffers and \n"
12786 : "\t %s DRI memory manager reservation:\n",
12787 : (i & 2) ? "untiled" : "tiled",
12788 : (i & 1) ? "small" : "large");
12790 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
12791 : "Attempting memory allocation with %s buffers:\n",
12792 : (i & 1) ? "untiled" : "tiled");
12795 : if (i830_allocate_2d_memory(pScrn) &&
12796 : i830_allocate_3d_memory(pScrn))
12798 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n");
12799 : if (pScrn->displayWidth != savedDisplayWidth) {
12800 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
12801 : "Increasing the scanline pitch to allow tiling mode "
12803 : savedDisplayWidth, pScrn->displayWidth);
12805 : allocation_done = TRUE;
12809 : i830_reset_allocations(pScrn);
12812 : if (i == MM_TURNS) {
12813 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12814 : "Not enough video memory. Disabling DRI.\n");
12816 : pI830->mmSize = 0;
12818 : pI830->directRenderingDisabled = TRUE;
12822 : pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
12824 : if (!allocation_done) {
12825 : if (!i830_allocate_2d_memory(pScrn)) {
12826 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
12827 : "Couldn't allocate video memory\n");
12830 : allocation_done = TRUE;
12833 : I830UnmapMMIO(pScrn);
12835 : i830_describe_allocations(pScrn, 1, "");
12837 : if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
12838 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
12839 : "Cannot support DRI with frame buffer width > 2048.\n");
12840 : pI830->disableTiling = TRUE;
12841 : pI830->directRenderingDisabled = TRUE;
12844 : pScrn->displayWidth = pScrn->displayWidth;
12846 :#ifdef HAS_MTRR_SUPPORT
12849 : struct mtrr_gentry gentry;
12850 : struct mtrr_sentry sentry;
12852 : if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) != -1 ) {
12853 : for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
12854 : ++gentry.regnum) {
12856 : if (gentry.size < 1) {
12861 : /* Check the MTRR range is one we like and if not - remove it.
12862 : * The Xserver common layer will then setup the right range
12865 : if (gentry.base == pI830->LinearAddr &&
12866 : gentry.size < pI830->FbMapSize) {
12868 : xf86DrvMsg(pScrn->scrnIndex, X_INFO,
12869 : "Removing bad MTRR range (base 0x%lx, size 0x%x)\n",
12870 : gentry.base, gentry.size);
12872 : sentry.base = gentry.base;
12873 : sentry.size = gentry.size;
12874 : sentry.type = gentry.type;
12876 : if (ioctl (fd, MTRRIOC_DEL_ENTRY, &sentry) == -1) {
12877 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
12878 : "Failed to remove bad MTRR range\n");
12887 : pI830->starting = TRUE;
12889 : miClearVisualTypes();
12890 : if (!miSetVisualTypes(pScrn->depth,
12891 : miGetDefaultVisualMask(pScrn->depth),
12892 : pScrn->rgbBits, pScrn->defaultVisual))
12894 : if (!miSetPixmapDepths())
12898 : pI830->XvEnabled = !pI830->XvDisabled;
12899 : if (pI830->XvEnabled) {
12900 : if (!I830IsPrimary(pScrn)) {
12901 : if (!pI8301->XvEnabled || pI830->noAccel) {
12902 : pI830->XvEnabled = FALSE;
12903 : xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Xv is disabled.\n");
12906 : if (pI830->noAccel || pI830->StolenOnly) {
12907 : xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Xv is disabled because it "
12908 : "needs 2D accel and AGPGART.\n");
12909 : pI830->XvEnabled = FALSE;
12913 : pI830->XvEnabled = FALSE;
12916 : if (!pI830->noAccel) {
12917 : if (pI830->LpRing->mem->size == 0) {
12918 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12919 : "Disabling acceleration because the ring buffer "
12920 : "allocation failed.\n");
12921 : pI830->noAccel = TRUE;
12926 : if (pI830->XvEnabled) {
12927 : if (pI830->noAccel) {
12928 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling Xv because it "
12929 : "needs 2D acceleration.\n");
12930 : pI830->XvEnabled = FALSE;
12932 : if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL) {
12933 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
12934 : "Disabling Xv because the overlay register buffer "
12935 : "allocation failed.\n");
12936 : pI830->XvEnabled = FALSE;
12943 : * pI830->directRenderingDisabled is set once in PreInit. Reinitialise
12944 : * pI830->directRenderingEnabled based on it each generation.
12946 : pI830->directRenderingEnabled = !pI830->directRenderingDisabled;
12948 : * Setup DRI after visuals have been established, but before fbScreenInit
12949 : * is called. fbScreenInit will eventually call into the drivers
12950 : * InitGLXVisuals call back.
12953 : if (pI830->directRenderingEnabled) {
12954 : if (pI830->noAccel || pI830->SWCursor || (pI830->StolenOnly && I830IsPrimary(pScrn))) {
12955 : xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it "
12956 : "needs HW cursor, 2D accel and AGPGART.\n");
12957 : pI830->directRenderingEnabled = FALSE;
12958 : i830_free_3d_memory(pScrn);
12962 : driDisabled = !pI830->directRenderingEnabled;
12964 : if (pI830->directRenderingEnabled)
12965 : pI830->directRenderingEnabled = I830DRIScreenInit(pScreen);
12967 : if (!pI830->directRenderingEnabled) {
12968 : i830_free_3d_memory(pScrn);
12972 : pI830->directRenderingEnabled = FALSE;
12976 : if (pI830->directRenderingEnabled)
12977 : pI830->directRenderingEnabled = I830DRIDoMappings(pScreen);
12979 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n",
12980 : pI830->allowPageFlip ? "en" : "dis");
12983 : DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n");
12984 : if (!I830MapMem(pScrn))
12987 : pScrn->memPhysBase = (unsigned long)pI830->FbBase;
12989 : if (I830IsPrimary(pScrn)) {
12990 : pScrn->fbOffset = pI830->front_buffer->offset;
12992 : pScrn->fbOffset = pI8301->front_buffer_2->offset;
12995 : pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth;
12996 : pI830->yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth;
12998 : vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0);
12999 : vgaHWGetIOBase(hwp);
13000 : DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n");
13001 : if (!vgaHWMapMem(pScrn))
13004 : DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n");
13006 : if (!pI830->useEXA) {
13007 : if (I830IsPrimary(pScrn)) {
13008 : if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) {
13009 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13010 : "Failed to init memory manager\n");
13013 : if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
13014 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13015 : "Failed to init memory manager\n");
13020 : if (pScrn->virtualX > pScrn->displayWidth)
13021 : pScrn->displayWidth = pScrn->virtualX;
13023 : DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n");
13024 : if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset,
13025 : pScrn->virtualX, pScrn->virtualY,
13026 : pScrn->xDpi, pScrn->yDpi,
13027 : pScrn->displayWidth, pScrn->bitsPerPixel))
13030 : if (pScrn->bitsPerPixel > 8) {
13031 : /* Fixup RGB ordering */
13032 : visual = pScreen->visuals + pScreen->numVisuals;
13033 : while (--visual >= pScreen->visuals) {
13034 : if ((visual->class | DynamicClass) == DirectColor) {
13035 : visual->offsetRed = pScrn->offset.red;
13036 : visual->offsetGreen = pScrn->offset.green;
13037 : visual->offsetBlue = pScrn->offset.blue;
13038 : visual->redMask = pScrn->mask.red;
13039 : visual->greenMask = pScrn->mask.green;
13040 : visual->blueMask = pScrn->mask.blue;
13045 : fbPictureInit(pScreen, NULL, 0);
13047 : xf86SetBlackWhitePixels(pScreen);
13049 : xf86DiDGAInit (pScreen, pI830->LinearAddr + pScrn->fbOffset);
13052 : "assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n");
13054 : if (!pI830->noAccel) {
13055 : if (!I830AccelInit(pScreen)) {
13056 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13057 : "Hardware acceleration initialization failed\n");
13061 : miInitializeBackingStore(pScreen);
13062 : xf86SetBackingStore(pScreen);
13063 : xf86SetSilkenMouse(pScreen);
13064 : miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
13066 : if (!pI830->SWCursor) {
13067 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing HW Cursor\n");
13068 : if (!I830CursorInit(pScreen))
13069 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13070 : "Hardware cursor initialization failed\n");
13072 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing SW Cursor!\n");
13074 : if (!I830EnterVT(scrnIndex, 0))
13077 : DPRINTF(PFX, "assert( if(!miCreateDefColormap(pScreen)) )\n");
13078 : if (!miCreateDefColormap(pScreen))
13081 : DPRINTF(PFX, "assert( if(!xf86HandleColormaps(pScreen, ...)) )\n");
13082 : if (!xf86HandleColormaps(pScreen, 256, 8, I830LoadPalette, NULL,
13083 : CMAP_RELOAD_ON_MODE_SWITCH |
13084 : CMAP_PALETTED_TRUECOLOR)) {
13088 : xf86DPMSInit(pScreen, xf86DPMSSet, 0);
13092 : if (pI830->XvEnabled)
13093 : I830InitVideo(pScreen);
13097 : if (pI830->directRenderingEnabled) {
13098 : pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen);
13102 : /* Setup 3D engine, needed for rotation too */
13103 : IntelEmitInvarientState(pScrn);
13106 : if (pI830->directRenderingEnabled) {
13107 : pI830->directRenderingOpen = TRUE;
13108 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Enabled\n");
13111 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Disabled\n");
13113 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Failed\n");
13116 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering: Not available\n");
13119 : pScreen->SaveScreen = xf86SaveScreen;
13120 : pI830->CloseScreen = pScreen->CloseScreen;
13121 : pScreen->CloseScreen = I830CloseScreen;
13123 : if (!xf86CrtcScreenInit (pScreen))
13126 : /* Wrap pointer motion to flip touch screen around */
13127 : pI830->PointerMoved = pScrn->PointerMoved;
13128 : pScrn->PointerMoved = I830PointerMoved;
13130 : if (serverGeneration == 1)
13131 : xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
13133 : if (IS_I965G(pI830)) {
13134 : /* turn off clock gating */
13136 : OUTREG(0x6204, 0x70804000);
13137 : OUTREG(0x6208, 0x00000001);
13139 : OUTREG(0x6204, 0x70000000);
13141 : /* Enable DAP stateless accesses.
13142 : * Required for all i965 steppings.
13144 : OUTREG(SVG_WORK_CTL, 0x00000010);
13147 : pI830->starting = FALSE;
13148 : pI830->closing = FALSE;
13149 : pI830->suspended = FALSE;
13152 : if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM))
13154 : if (pI830->memory_manager == NULL) {
13155 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13156 : "Too little AGP aperture space for DRM memory manager.\n"
13157 : "\tPlease increase AGP aperture size from BIOS configuration screen.\n"
13158 : "\tDisabling DRI.\n");
13159 : pI830->directRenderingOpen = FALSE;
13160 : I830DRICloseScreen(pScreen);
13161 : pI830->directRenderingEnabled = FALSE;
13163 : unsigned long aperEnd = ROUND_DOWN_TO(pI830->memory_manager->offset +
13164 : pI830->memory_manager->size,
13165 : GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
13166 : unsigned long aperStart = ROUND_TO(pI830->memory_manager->offset,
13167 : GTT_PAGE_SIZE) / GTT_PAGE_SIZE;
13169 :#ifndef XSERVER_LIBDRM_MM
13170 : if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
13171 : DRM_BO_MEM_TT)) {
13173 : if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart,
13174 : DRM_BO_MEM_TT)) {
13176 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13177 : "Could not initialize the DRM memory manager.\n");
13179 : pI830->directRenderingOpen = FALSE;
13180 : I830DRICloseScreen(pScreen);
13181 : pI830->directRenderingEnabled = FALSE;
13185 :#endif /* XF86DRI_MM */
13191 :i830AdjustFrame(int scrnIndex, int x, int y, int flags)
13193 : ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
13194 : xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
13195 : I830Ptr pI830 = I830PTR(pScrn);
13196 : xf86OutputPtr output = config->output[config->compat_output];
13197 : xf86CrtcPtr crtc = output->crtc;
13199 : DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
13200 : x, pI830->xoffset, y, pI830->yoffset);
13202 : if (crtc && crtc->enabled)
13204 : /* Sync the engine before adjust frame */
13205 : i830WaitSync(pScrn);
13206 : i830PipeSetBase(crtc, crtc->desiredX + x, crtc->desiredY + y);
13207 : crtc->x = output->initial_x + x;
13208 : crtc->y = output->initial_y + y;
13213 :I830FreeScreen(int scrnIndex, int flags)
13215 : I830FreeRec(xf86Screens[scrnIndex]);
13216 : if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
13217 : vgaHWFreeHWRec(xf86Screens[scrnIndex]);
13221 :I830LeaveVT(int scrnIndex, int flags)
13223 : ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
13224 : I830Ptr pI830 = I830PTR(pScrn);
13226 : DPRINTF(PFX, "Leave VT\n");
13228 : pI830->leaving = TRUE;
13230 : if (pI830->devicesTimer)
13231 : TimerCancel(pI830->devicesTimer);
13232 : pI830->devicesTimer = NULL;
13234 : i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH);
13236 : if (!I830IsPrimary(pScrn)) {
13237 : I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
13238 : if (!pI8301->gtt_acquired) {
13244 : if (pI830->directRenderingOpen) {
13245 : DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
13247 : if (pI830->mmModeFlags & I830_KERNEL_MM) {
13248 :#ifndef XSERVER_LIBDRM_MM
13249 : I830DrmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT);
13251 : drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT);
13254 :#endif /* XF86DRI_MM */
13255 : I830DRISetVBlankInterrupt (pScrn, FALSE);
13257 : drmCtlUninstHandler(pI830->drmSubFD);
13261 : xf86_hide_cursors (pScrn);
13263 : ResetState(pScrn, TRUE);
13265 : RestoreHWState(pScrn);
13267 : if (pI830->debug_modes) {
13268 : i830CompareRegsToSnapshot(pScrn, "After LeaveVT");
13269 : i830DumpRegs (pScrn);
13272 : if (I830IsPrimary(pScrn))
13273 : i830_unbind_all_memory(pScrn);
13274 : if (pI830->AccelInfoRec)
13275 : pI830->AccelInfoRec->NeedToSync = FALSE;
13279 : * This gets called when gaining control of the VT, and from ScreenInit().
13282 :I830EnterVT(int scrnIndex, int flags)
13284 : ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
13285 : I830Ptr pI830 = I830PTR(pScrn);
13286 : xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
13289 : DPRINTF(PFX, "Enter VT\n");
13292 : * Only save state once per server generation since that's what most
13293 : * drivers do. Could change this to save state at each VT enter.
13295 : if (pI830->SaveGeneration != serverGeneration) {
13296 : pI830->SaveGeneration = serverGeneration;
13297 : SaveHWState(pScrn);
13300 : pI830->leaving = FALSE;
13302 : if (I830IsPrimary(pScrn))
13303 : if (!i830_bind_all_memory(pScrn))
13306 : if (i830_check_error_state(pScrn)) {
13307 : xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
13308 : "Existing errors found in hardware state.\n");
13311 : ResetState(pScrn, FALSE);
13312 : SetHWOperatingState(pScrn);
13314 : /* Clear the framebuffer */
13315 : memset(pI830->FbBase + pScrn->fbOffset, 0,
13316 : pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
13318 : for (o = 0; o < config->num_output; o++) {
13319 : xf86OutputPtr output = config->output[o];
13320 : output->funcs->dpms(output, DPMSModeOff);
13323 : if (!xf86SetDesiredModes (pScrn))
13326 : if (pI830->debug_modes) {
13327 : xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n");
13328 : i830DumpRegs (pScrn);
13330 : i830DescribeOutputConfiguration(pScrn);
13332 : ResetState(pScrn, TRUE);
13333 : SetHWOperatingState(pScrn);
13336 : if (pI830->directRenderingEnabled) {
13338 : I830DRISetVBlankInterrupt (pScrn, TRUE);
13340 : if (!pI830->starting) {
13341 : ScreenPtr pScreen = pScrn->pScreen;
13342 : drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
13345 : I830DRIResume(screenInfo.screens[scrnIndex]);
13347 : I830RefreshRing(pScrn);
13352 : for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++)
13353 : sarea->texList[i].age = sarea->texAge;
13356 : if (pI830->mmModeFlags & I830_KERNEL_MM) {
13357 :#ifndef XSERVER_LIBDRM_MM
13358 : I830DrmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT);
13360 : drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT);
13363 :#endif /* XF86DRI_MM */
13365 : DPRINTF(PFX, "calling dri unlock\n");
13366 : DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
13368 : pI830->LockHeld = 0;
13372 : /* Set the hotkey to just notify us. We can check its results periodically
13373 : * in the CheckDevicesTimer. Eventually we want the kernel to just hand us
13374 : * an input event when someone presses the button, but for now we just have
13377 : i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY);
13379 : if (pI830->checkDevices)
13380 : pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
13382 : /* Mark 3D state as being clobbered */
13383 : *pI830->last_3d = LAST_3D_OTHER;
13389 :I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
13391 : ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
13392 : I830Ptr pI830 = I830PTR(pScrn);
13394 : return xf86SetSingleMode (pScrn, mode, pI830->rotation);
13398 :I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
13400 : ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
13401 : I830Ptr pI830 = I830PTR(pScrn);
13402 :#ifdef I830_USE_XAA
13403 : XAAInfoRecPtr infoPtr = pI830->AccelInfoRec;
13406 : pI830->closing = TRUE;
13408 : if (pI830->directRenderingOpen) {
13410 : if (pI830->pDamage) {
13411 : PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
13413 : DamageUnregister(&pPix->drawable, pI830->pDamage);
13414 : DamageDestroy(pI830->pDamage);
13415 : pI830->pDamage = NULL;
13419 : if (pI830->mmModeFlags & I830_KERNEL_MM) {
13420 :#ifndef XSERVER_LIBDRM_MM
13421 : I830DrmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT);
13423 : drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT);
13426 :#endif /* XF86DRI_MM */
13427 : pI830->directRenderingOpen = FALSE;
13428 : I830DRICloseScreen(pScreen);
13432 : if (pScrn->vtSema == TRUE) {
13433 : I830LeaveVT(scrnIndex, 0);
13436 : if (pI830->devicesTimer)
13437 : TimerCancel(pI830->devicesTimer);
13438 : pI830->devicesTimer = NULL;
13440 : DPRINTF(PFX, "\nUnmapping memory\n");
13441 : I830UnmapMem(pScrn);
13442 : vgaHWUnmapMem(pScrn);
13444 : if (pI830->ScanlineColorExpandBuffers) {
13445 : xfree(pI830->ScanlineColorExpandBuffers);
13446 : pI830->ScanlineColorExpandBuffers = NULL;
13448 :#ifdef I830_USE_XAA
13450 : if (infoPtr->ScanlineColorExpandBuffers)
13451 : xfree(infoPtr->ScanlineColorExpandBuffers);
13452 : XAADestroyInfoRec(infoPtr);
13453 : pI830->AccelInfoRec = NULL;
13456 :#ifdef I830_USE_EXA
13457 : if (pI830->useEXA && pI830->EXADriverPtr) {
13458 : exaDriverFini(pScreen);
13459 : xfree(pI830->EXADriverPtr);
13460 : pI830->EXADriverPtr = NULL;
13463 : xf86_cursors_fini (pScreen);
13465 : i830_reset_allocations(pScrn);
13467 : if (I830IsPrimary(pScrn)) {
13468 : xf86GARTCloseScreen(scrnIndex);
13470 : xfree(pI830->LpRing);
13471 : pI830->LpRing = NULL;
13472 : xfree(pI830->overlayOn);
13473 : pI830->overlayOn = NULL;
13474 : xfree(pI830->last_3d);
13475 : pI830->last_3d = NULL;
13478 : pScrn->PointerMoved = pI830->PointerMoved;
13479 : pScrn->vtSema = FALSE;
13480 : pI830->closing = FALSE;
13481 : pScreen->CloseScreen = pI830->CloseScreen;
13482 : return (*pScreen->CloseScreen) (scrnIndex, pScreen);
13486 :I830ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
13488 : if (mode->Flags & V_INTERLACE) {
13490 : xf86DrvMsg(scrnIndex, X_PROBED,
13491 : "Removing interlaced mode \"%s\"\n", mode->name);
13498 :#ifndef SUSPEND_SLEEP
13499 :#define SUSPEND_SLEEP 0
13501 :#ifndef RESUME_SLEEP
13502 :#define RESUME_SLEEP 0
13506 : * This function is only required if we need to do anything differently from
13507 : * DoApmEvent() in common/xf86PM.c, including if we want to see events other
13508 : * than suspend/resume.
13511 :I830PMEvent(int scrnIndex, pmEvent event, Bool undo)
13513 : ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
13514 : I830Ptr pI830 = I830PTR(pScrn);
13516 : DPRINTF(PFX, "Enter VT, event %d, undo: %s\n", event, BOOLTOSTRING(undo));
13519 : case XF86_APM_SYS_SUSPEND:
13520 : case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend?*/
13521 : case XF86_APM_USER_SUSPEND:
13522 : case XF86_APM_SYS_STANDBY:
13523 : case XF86_APM_USER_STANDBY:
13524 : if (!undo && !pI830->suspended) {
13525 : pScrn->LeaveVT(scrnIndex, 0);
13526 : pI830->suspended = TRUE;
13527 : sleep(SUSPEND_SLEEP);
13528 : } else if (undo && pI830->suspended) {
13529 : sleep(RESUME_SLEEP);
13530 : pScrn->EnterVT(scrnIndex, 0);
13531 : pI830->suspended = FALSE;
13534 : case XF86_APM_STANDBY_RESUME:
13535 : case XF86_APM_NORMAL_RESUME:
13536 : case XF86_APM_CRITICAL_RESUME:
13537 : if (pI830->suspended) {
13538 : sleep(RESUME_SLEEP);
13539 : pScrn->EnterVT(scrnIndex, 0);
13540 : pI830->suspended = FALSE;
13542 : * Turn the screen saver off when resuming. This seems to be
13543 : * needed to stop xscreensaver kicking in (when used).
13545 : * XXX DoApmEvent() should probably call this just like
13546 : * xf86VTSwitch() does. Maybe do it here only in 4.2
13547 : * compatibility mode.
13549 : SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
13552 : /* This is currently used for ACPI */
13553 : case XF86_APM_CAPABILITY_CHANGED:
13555 : /* If we had status checking turned on, turn it off now */
13556 : if (pI830->checkDevices) {
13557 : if (pI830->devicesTimer)
13558 : TimerCancel(pI830->devicesTimer);
13559 : pI830->devicesTimer = NULL;
13560 : pI830->checkDevices = FALSE;
13563 : if (!I830IsPrimary(pScrn))
13566 : ErrorF("I830PMEvent: Capability change\n");
13568 : I830CheckDevicesTimer(NULL, 0, pScrn);
13569 : SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
13572 : ErrorF("I830PMEvent: received APM event %d\n", event);
13579 : * This function is used for testing of the screen detect functions from the
13580 : * periodic timer.
13583 :i830MonitorDetectDebugger(ScrnInfoPtr pScrn)
13586 : I830Ptr pI830 = I830PTR(pScrn);
13587 : int start, finish, i;
13589 : if (!pScrn->vtSema)
13592 : for (i = 0; i < xf86_config->num_output; i++) {
13593 : enum output_status ret;
13596 : start = GetTimeInMillis();
13597 : ret = pI830->output[i].detect(pScrn, &pI830->output[i]);
13598 : finish = GetTimeInMillis();
13600 : if (ret == OUTPUT_STATUS_CONNECTED)
13601 : result = "connected";
13602 : else if (ret == OUTPUT_STATUS_DISCONNECTED)
13603 : result = "disconnected";
13605 : result = "unknown";
13607 : xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected SDVO as %s in %dms\n",
13608 : result, finish - start);
13614 :I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
13616 : ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
13617 : I830Ptr pI830 = I830PTR(pScrn);
13620 : if (!pScrn->vtSema)
13624 : i830MonitorDetectDebugger(pScrn);
13627 : /* Check for a hotkey press report from the BIOS. */
13628 : gr18 = pI830->readControl(pI830, GRX, 0x18);
13629 : if ((gr18 & (HOTKEY_TOGGLE | HOTKEY_SWITCH)) != 0) {
13630 : /* The user has pressed the hotkey requesting a toggle or switch.
13631 : * Re-probe our connected displays and turn on whatever we find.
13633 : * In the future, we want the hotkey to dump down to a user app which
13634 : * implements a sensible policy using RandR-1.2. For now, all we get
13638 : xf86ProbeOutputModes (pScrn, 0, 0);
13639 : xf86SetScrnInfoModes (pScrn);
13640 : xf86DiDGAReInit (pScrn->pScreen);
13641 : xf86SwitchMode(pScrn->pScreen, pScrn->currentMode);
13643 : /* Clear the BIOS's hotkey press flags */
13644 : gr18 &= ~(HOTKEY_TOGGLE | HOTKEY_SWITCH);
13645 : pI830->writeControl(pI830, GRX, 0x18, gr18);
13652 :i830WaitSync(ScrnInfoPtr pScrn)
13653 31 0.0338 :{ /* i830WaitSync total: 103 0.1122 */
13654 1 0.0011 : I830Ptr pI830 = I830PTR(pScrn);
13656 :#ifdef I830_USE_XAA
13657 15 0.0163 : if (!pI830->noAccel && !pI830->useEXA && pI830->AccelInfoRec
13658 : && pI830->AccelInfoRec->NeedToSync) {
13659 : (*pI830->AccelInfoRec->Sync)(pScrn);
13660 : pI830->AccelInfoRec->NeedToSync = FALSE;
13663 :#ifdef I830_USE_EXA
13664 6 0.0065 : if (!pI830->noAccel && pI830->useEXA && pI830->EXADriverPtr) {
13665 : ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
13666 21 0.0229 : exaWaitSync(pScreen);
13672 :i830MarkSync(ScrnInfoPtr pScrn)
13673 7 0.0076 :{ /* i830MarkSync total: 15 0.0163 */
13674 : I830Ptr pI830 = I830PTR(pScrn);
13676 :#ifdef I830_USE_XAA
13677 : if (!pI830->useEXA && pI830->AccelInfoRec)
13678 : pI830->AccelInfoRec->NeedToSync = TRUE;
13680 :#ifdef I830_USE_EXA
13681 2 0.0022 : if (pI830->useEXA && pI830->EXADriverPtr) {
13682 : ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
13683 3 0.0033 : exaMarkSync(pScreen);
13689 :I830InitpScrn(ScrnInfoPtr pScrn)
13691 : pScrn->PreInit = I830PreInit;
13692 : pScrn->ScreenInit = I830ScreenInit;
13693 : pScrn->SwitchMode = I830SwitchMode;
13694 : pScrn->AdjustFrame = i830AdjustFrame;
13695 : pScrn->EnterVT = I830EnterVT;
13696 : pScrn->LeaveVT = I830LeaveVT;
13697 : pScrn->FreeScreen = I830FreeScreen;
13698 : pScrn->ValidMode = I830ValidMode;
13699 : pScrn->PMEvent = I830PMEvent;
13702 * Total samples for file : "/home/cworth/src/xorg/xserver/mi/misprite.c"
13711 : * machine independent software sprite routines
13717 :Copyright 1989, 1998 The Open Group
13719 :Permission to use, copy, modify, distribute, and sell this software and its
13720 :documentation for any purpose is hereby granted without fee, provided that
13721 :the above copyright notice appear in all copies and that both that
13722 :copyright notice and this permission notice appear in supporting
13725 :The above copyright notice and this permission notice shall be included in
13726 :all copies or substantial portions of the Software.
13728 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13729 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13730 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13731 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
13732 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
13733 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13735 :Except as contained in this notice, the name of The Open Group shall not be
13736 :used in advertising or otherwise to promote the sale, use or other dealings
13737 :in this Software without prior written authorization from The Open Group.
13740 :#ifdef HAVE_DIX_CONFIG_H
13741 :#include <dix-config.h>
13744 :# include <X11/X.h>
13745 :# include <X11/Xproto.h>
13746 :# include "misc.h"
13747 :# include "pixmapstr.h"
13748 :# include "input.h"
13750 :# include "cursorstr.h"
13751 :# include <X11/fonts/font.h>
13752 :# include "scrnintstr.h"
13753 :# include "colormapst.h"
13754 :# include "windowstr.h"
13755 :# include "gcstruct.h"
13756 :# include "mipointer.h"
13757 :# include "mispritest.h"
13758 :# include "dixfontstr.h"
13759 :# include <X11/fonts/fontstruct.h>
13762 :# include "mipict.h"
13764 :# include "damage.h"
13766 :#define SPRITE_DEBUG_ENABLE 0
13767 :#if SPRITE_DEBUG_ENABLE
13768 :#define SPRITE_DEBUG(x) ErrorF x
13770 :#define SPRITE_DEBUG(x)
13774 : * screen wrappers
13777 :static int miSpriteScreenIndex;
13778 :static unsigned long miSpriteGeneration = 0;
13780 :static Bool miSpriteCloseScreen(int i, ScreenPtr pScreen);
13781 :static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
13782 : int w, int h, unsigned int format,
13783 : unsigned long planemask, char *pdstLine);
13784 :static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax,
13785 : DDXPointPtr ppt, int *pwidth, int nspans,
13786 : char *pdstStart);
13787 :static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
13788 : int width, int height);
13789 :static void miSpriteCopyWindow (WindowPtr pWindow,
13790 : DDXPointRec ptOldOrg,
13791 : RegionPtr prgnSrc);
13792 :static void miSpriteBlockHandler(int i, pointer blockData,
13793 : pointer pTimeout,
13794 : pointer pReadMask);
13795 :static void miSpriteInstallColormap(ColormapPtr pMap);
13796 :static void miSpriteStoreColors(ColormapPtr pMap, int ndef,
13797 : xColorItem *pdef);
13799 :static void miSpriteSaveDoomedAreas(WindowPtr pWin,
13800 : RegionPtr pObscured, int dx,
13802 :static void miSpriteComputeSaved(ScreenPtr pScreen);
13804 :#define SCREEN_PROLOGUE(pScreen, field)\
13805 : ((pScreen)->field = \
13806 : ((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
13808 :#define SCREEN_EPILOGUE(pScreen, field)\
13809 : ((pScreen)->field = miSprite##field)
13812 : * pointer-sprite method table
13815 :static Bool miSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
13816 :static Bool miSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
13817 :static void miSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCursor,
13819 :static void miSpriteMoveCursor(ScreenPtr pScreen, int x, int y);
13821 :_X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = {
13822 : miSpriteRealizeCursor,
13823 : miSpriteUnrealizeCursor,
13824 : miSpriteSetCursor,
13825 : miSpriteMoveCursor,
13829 : * other misc functions
13832 :static void miSpriteRemoveCursor(ScreenPtr pScreen);
13833 :static void miSpriteRestoreCursor(ScreenPtr pScreen);
13836 :miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
13838 : ScreenPtr pScreen = closure;
13839 : miSpriteScreenPtr pScreenPriv;
13841 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
13843 : if (pScreenPriv->isUp &&
13844 : RECT_IN_REGION (pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
13846 : SPRITE_DEBUG(("Damage remove\n"));
13847 : miSpriteRemoveCursor (pScreen);
13852 : * miSpriteInitialize -- called from device-dependent screen
13853 : * initialization proc after all of the function pointers have
13854 : * been stored in the screen structure.
13858 :miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
13859 : ScreenPtr pScreen;
13860 : miSpriteCursorFuncPtr cursorFuncs;
13861 : miPointerScreenFuncPtr screenFuncs;
13863 : miSpriteScreenPtr pScreenPriv;
13864 : VisualPtr pVisual;
13866 : if (!DamageSetup (pScreen))
13869 : if (miSpriteGeneration != serverGeneration)
13871 : miSpriteScreenIndex = AllocateScreenPrivateIndex ();
13872 : if (miSpriteScreenIndex < 0)
13874 : miSpriteGeneration = serverGeneration;
13877 : pScreenPriv = (miSpriteScreenPtr) xalloc (sizeof (miSpriteScreenRec));
13878 : if (!pScreenPriv)
13881 : pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage,
13882 : (DamageDestroyFunc) 0,
13883 : DamageReportRawRegion,
13886 : (void *) pScreen);
13888 : if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
13890 : xfree ((pointer) pScreenPriv);
13893 : for (pVisual = pScreen->visuals;
13894 : pVisual->vid != pScreen->rootVisual;
13897 : pScreenPriv->pVisual = pVisual;
13898 : pScreenPriv->CloseScreen = pScreen->CloseScreen;
13899 : pScreenPriv->GetImage = pScreen->GetImage;
13900 : pScreenPriv->GetSpans = pScreen->GetSpans;
13901 : pScreenPriv->SourceValidate = pScreen->SourceValidate;
13903 : pScreenPriv->CopyWindow = pScreen->CopyWindow;
13905 : pScreenPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas;
13907 : pScreenPriv->InstallColormap = pScreen->InstallColormap;
13908 : pScreenPriv->StoreColors = pScreen->StoreColors;
13910 : pScreenPriv->BlockHandler = pScreen->BlockHandler;
13912 : pScreenPriv->pCursor = NULL;
13913 : pScreenPriv->x = 0;
13914 : pScreenPriv->y = 0;
13915 : pScreenPriv->isUp = FALSE;
13916 : pScreenPriv->shouldBeUp = FALSE;
13917 : pScreenPriv->pCacheWin = NullWindow;
13918 : pScreenPriv->isInCacheWin = FALSE;
13919 : pScreenPriv->checkPixels = TRUE;
13920 : pScreenPriv->pInstalledMap = NULL;
13921 : pScreenPriv->pColormap = NULL;
13922 : pScreenPriv->funcs = cursorFuncs;
13923 : pScreenPriv->colors[SOURCE_COLOR].red = 0;
13924 : pScreenPriv->colors[SOURCE_COLOR].green = 0;
13925 : pScreenPriv->colors[SOURCE_COLOR].blue = 0;
13926 : pScreenPriv->colors[MASK_COLOR].red = 0;
13927 : pScreenPriv->colors[MASK_COLOR].green = 0;
13928 : pScreenPriv->colors[MASK_COLOR].blue = 0;
13929 : pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pScreenPriv;
13931 : pScreen->CloseScreen = miSpriteCloseScreen;
13932 : pScreen->GetImage = miSpriteGetImage;
13933 : pScreen->GetSpans = miSpriteGetSpans;
13934 : pScreen->SourceValidate = miSpriteSourceValidate;
13936 : pScreen->CopyWindow = miSpriteCopyWindow;
13938 : pScreen->SaveDoomedAreas = miSpriteSaveDoomedAreas;
13940 : pScreen->InstallColormap = miSpriteInstallColormap;
13941 : pScreen->StoreColors = miSpriteStoreColors;
13943 : pScreen->BlockHandler = miSpriteBlockHandler;
13949 : * Screen wrappers
13953 : * CloseScreen wrapper -- unwrap everything, free the private data
13954 : * and call the wrapped function
13958 :miSpriteCloseScreen (i, pScreen)
13960 : ScreenPtr pScreen;
13962 : miSpriteScreenPtr pScreenPriv;
13964 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
13966 : pScreen->CloseScreen = pScreenPriv->CloseScreen;
13967 : pScreen->GetImage = pScreenPriv->GetImage;
13968 : pScreen->GetSpans = pScreenPriv->GetSpans;
13969 : pScreen->SourceValidate = pScreenPriv->SourceValidate;
13970 : pScreen->BlockHandler = pScreenPriv->BlockHandler;
13971 : pScreen->InstallColormap = pScreenPriv->InstallColormap;
13972 : pScreen->StoreColors = pScreenPriv->StoreColors;
13974 : pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
13975 : miSpriteIsUpFALSE (pScreen, pScreenPriv);
13976 : DamageDestroy (pScreenPriv->pDamage);
13978 : xfree ((pointer) pScreenPriv);
13980 : return (*pScreen->CloseScreen) (i, pScreen);
13984 :miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
13985 : DrawablePtr pDrawable;
13986 : int sx, sy, w, h;
13987 : unsigned int format;
13988 : unsigned long planemask;
13991 : ScreenPtr pScreen = pDrawable->pScreen;
13992 : miSpriteScreenPtr pScreenPriv;
13994 : SCREEN_PROLOGUE (pScreen, GetImage);
13996 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
13998 : if (pDrawable->type == DRAWABLE_WINDOW &&
13999 : pScreenPriv->isUp &&
14000 : ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
14002 : SPRITE_DEBUG (("GetImage remove\n"));
14003 : miSpriteRemoveCursor (pScreen);
14006 : (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
14007 : format, planemask, pdstLine);
14009 : SCREEN_EPILOGUE (pScreen, GetImage);
14013 :miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
14014 : DrawablePtr pDrawable;
14021 : ScreenPtr pScreen = pDrawable->pScreen;
14022 : miSpriteScreenPtr pScreenPriv;
14024 : SCREEN_PROLOGUE (pScreen, GetSpans);
14026 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14028 : if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
14036 : xorg = pDrawable->x;
14037 : yorg = pDrawable->y;
14039 : for (pts = ppt, widths = pwidth, nPts = nspans;
14043 : if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
14044 : pts->x+xorg,*widths))
14046 : SPRITE_DEBUG (("GetSpans remove\n"));
14047 : miSpriteRemoveCursor (pScreen);
14053 : (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
14055 : SCREEN_EPILOGUE (pScreen, GetSpans);
14059 :miSpriteSourceValidate (pDrawable, x, y, width, height)
14060 : DrawablePtr pDrawable;
14061 : int x, y, width, height;
14062 31 0.0338 :{ /* miSpriteSourceValidate total: 140 0.1525 */
14063 : ScreenPtr pScreen = pDrawable->pScreen;
14064 : miSpriteScreenPtr pScreenPriv;
14066 55 0.0599 : SCREEN_PROLOGUE (pScreen, SourceValidate);
14068 7 0.0076 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14070 : if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
14071 : ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
14072 : x, y, width, height))
14074 : SPRITE_DEBUG (("SourceValidate remove\n"));
14075 : miSpriteRemoveCursor (pScreen);
14078 26 0.0283 : if (pScreen->SourceValidate)
14079 : (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
14081 5 0.0054 : SCREEN_EPILOGUE (pScreen, SourceValidate);
14085 :miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
14087 : ScreenPtr pScreen = pWindow->drawable.pScreen;
14088 : miSpriteScreenPtr pScreenPriv;
14090 : SCREEN_PROLOGUE (pScreen, CopyWindow);
14092 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14094 : * Damage will take care of destination check
14096 : if (pScreenPriv->isUp &&
14097 : RECT_IN_REGION (pScreen, prgnSrc, &pScreenPriv->saved) != rgnOUT)
14099 : SPRITE_DEBUG (("CopyWindow remove\n"));
14100 : miSpriteRemoveCursor (pScreen);
14103 : (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
14104 : SCREEN_EPILOGUE (pScreen, CopyWindow);
14108 :miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
14110 : pointer blockData;
14111 : pointer pTimeout;
14112 : pointer pReadmask;
14114 : ScreenPtr pScreen = screenInfo.screens[i];
14115 : miSpriteScreenPtr pPriv;
14117 : pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14119 : SCREEN_PROLOGUE(pScreen, BlockHandler);
14121 : (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
14123 : SCREEN_EPILOGUE(pScreen, BlockHandler);
14125 : if (!pPriv->isUp && pPriv->shouldBeUp)
14127 : SPRITE_DEBUG (("BlockHandler restore\n"));
14128 : miSpriteRestoreCursor (pScreen);
14133 :miSpriteInstallColormap (pMap)
14134 : ColormapPtr pMap;
14136 : ScreenPtr pScreen = pMap->pScreen;
14137 : miSpriteScreenPtr pPriv;
14139 : pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14141 : SCREEN_PROLOGUE(pScreen, InstallColormap);
14143 : (*pScreen->InstallColormap) (pMap);
14145 : SCREEN_EPILOGUE(pScreen, InstallColormap);
14147 : pPriv->pInstalledMap = pMap;
14148 : if (pPriv->pColormap != pMap)
14150 : pPriv->checkPixels = TRUE;
14152 : miSpriteRemoveCursor (pScreen);
14157 :miSpriteStoreColors (pMap, ndef, pdef)
14158 : ColormapPtr pMap;
14160 : xColorItem *pdef;
14162 : ScreenPtr pScreen = pMap->pScreen;
14163 : miSpriteScreenPtr pPriv;
14166 : VisualPtr pVisual;
14168 : pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14170 : SCREEN_PROLOGUE(pScreen, StoreColors);
14172 : (*pScreen->StoreColors) (pMap, ndef, pdef);
14174 : SCREEN_EPILOGUE(pScreen, StoreColors);
14176 : if (pPriv->pColormap == pMap)
14179 : pVisual = pMap->pVisual;
14180 : if (pVisual->class == DirectColor)
14182 : /* Direct color - match on any of the subfields */
14184 :#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
14186 :#define UpdateDAC(plane,dac,mask) {\
14187 : if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
14188 : pPriv->colors[plane].dac = pdef[i].dac; \
14193 :#define CheckDirect(plane) \
14194 : UpdateDAC(plane,red,redMask) \
14195 : UpdateDAC(plane,green,greenMask) \
14196 : UpdateDAC(plane,blue,blueMask)
14198 : for (i = 0; i < ndef; i++)
14200 : CheckDirect (SOURCE_COLOR)
14201 : CheckDirect (MASK_COLOR)
14206 : /* PseudoColor/GrayScale - match on exact pixel */
14207 : for (i = 0; i < ndef; i++)
14209 : if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
14211 : pPriv->colors[SOURCE_COLOR] = pdef[i];
14212 : if (++updated == 2)
14215 : if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
14217 : pPriv->colors[MASK_COLOR] = pdef[i];
14218 : if (++updated == 2)
14225 : pPriv->checkPixels = TRUE;
14227 : miSpriteRemoveCursor (pScreen);
14233 :miSpriteFindColors (ScreenPtr pScreen)
14235 : miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr)
14236 : pScreen->devPrivates[miSpriteScreenIndex].ptr;
14237 : CursorPtr pCursor;
14238 : xColorItem *sourceColor, *maskColor;
14240 : pCursor = pScreenPriv->pCursor;
14241 : sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
14242 : maskColor = &pScreenPriv->colors[MASK_COLOR];
14243 : if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
14244 : !(pCursor->foreRed == sourceColor->red &&
14245 : pCursor->foreGreen == sourceColor->green &&
14246 : pCursor->foreBlue == sourceColor->blue &&
14247 : pCursor->backRed == maskColor->red &&
14248 : pCursor->backGreen == maskColor->green &&
14249 : pCursor->backBlue == maskColor->blue))
14251 : pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
14252 : sourceColor->red = pCursor->foreRed;
14253 : sourceColor->green = pCursor->foreGreen;
14254 : sourceColor->blue = pCursor->foreBlue;
14255 : FakeAllocColor (pScreenPriv->pColormap, sourceColor);
14256 : maskColor->red = pCursor->backRed;
14257 : maskColor->green = pCursor->backGreen;
14258 : maskColor->blue = pCursor->backBlue;
14259 : FakeAllocColor (pScreenPriv->pColormap, maskColor);
14260 : /* "free" the pixels right away, don't let this confuse you */
14261 : FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
14262 : FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
14264 : pScreenPriv->checkPixels = FALSE;
14268 : * BackingStore wrappers
14272 :miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
14274 : RegionPtr pObscured;
14277 : ScreenPtr pScreen;
14278 : miSpriteScreenPtr pScreenPriv;
14279 : BoxRec cursorBox;
14281 : pScreen = pWin->drawable.pScreen;
14283 : SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
14285 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14286 : if (pScreenPriv->isUp)
14288 : cursorBox = pScreenPriv->saved;
14292 : cursorBox.x1 += dx;
14293 : cursorBox.y1 += dy;
14294 : cursorBox.x2 += dx;
14295 : cursorBox.y2 += dy;
14297 : if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT)
14298 : miSpriteRemoveCursor (pScreen);
14301 : (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy);
14303 : SCREEN_EPILOGUE (pScreen, SaveDoomedAreas);
14307 : * miPointer interface routines
14310 :#define SPRITE_PAD 8
14313 :miSpriteRealizeCursor (pScreen, pCursor)
14314 : ScreenPtr pScreen;
14315 : CursorPtr pCursor;
14317 : miSpriteScreenPtr pScreenPriv;
14319 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14320 : if (pCursor == pScreenPriv->pCursor)
14321 : pScreenPriv->checkPixels = TRUE;
14322 : return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
14326 :miSpriteUnrealizeCursor (pScreen, pCursor)
14327 : ScreenPtr pScreen;
14328 : CursorPtr pCursor;
14330 : miSpriteScreenPtr pScreenPriv;
14332 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14333 : return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
14337 :miSpriteSetCursor (pScreen, pCursor, x, y)
14338 : ScreenPtr pScreen;
14339 : CursorPtr pCursor;
14343 : miSpriteScreenPtr pScreenPriv;
14345 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14348 : pScreenPriv->shouldBeUp = FALSE;
14349 : if (pScreenPriv->isUp)
14350 : miSpriteRemoveCursor (pScreen);
14351 : pScreenPriv->pCursor = 0;
14354 : pScreenPriv->shouldBeUp = TRUE;
14355 : if (pScreenPriv->x == x &&
14356 : pScreenPriv->y == y &&
14357 : pScreenPriv->pCursor == pCursor &&
14358 : !pScreenPriv->checkPixels)
14362 : pScreenPriv->x = x;
14363 : pScreenPriv->y = y;
14364 : pScreenPriv->pCacheWin = NullWindow;
14365 : if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor)
14367 : pScreenPriv->pCursor = pCursor;
14368 : miSpriteFindColors (pScreen);
14370 : if (pScreenPriv->isUp) {
14373 : * check to see if the old saved region
14374 : * encloses the new sprite, in which case we use
14375 : * the flicker-free MoveCursor primitive.
14377 : sx = pScreenPriv->x - (int)pCursor->bits->xhot;
14378 : sy = pScreenPriv->y - (int)pCursor->bits->yhot;
14379 : if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 &&
14380 : sx < pScreenPriv->saved.x2 &&
14381 : sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 &&
14382 : sy < pScreenPriv->saved.y2 &&
14383 : (int) pCursor->bits->width + (2 * SPRITE_PAD) ==
14384 : pScreenPriv->saved.x2 - pScreenPriv->saved.x1 &&
14385 : (int) pCursor->bits->height + (2 * SPRITE_PAD) ==
14386 : pScreenPriv->saved.y2 - pScreenPriv->saved.y1
14389 : DamageDrawInternal (pScreen, TRUE);
14390 : miSpriteIsUpFALSE (pScreen, pScreenPriv);
14391 : if (!(sx >= pScreenPriv->saved.x1 &&
14392 : sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 &&
14393 : sy >= pScreenPriv->saved.y1 &&
14394 : sy + (int)pCursor->bits->height < pScreenPriv->saved.y2))
14396 : int oldx1, oldy1, dx, dy;
14398 : oldx1 = pScreenPriv->saved.x1;
14399 : oldy1 = pScreenPriv->saved.y1;
14400 : dx = oldx1 - (sx - SPRITE_PAD);
14401 : dy = oldy1 - (sy - SPRITE_PAD);
14402 : pScreenPriv->saved.x1 -= dx;
14403 : pScreenPriv->saved.y1 -= dy;
14404 : pScreenPriv->saved.x2 -= dx;
14405 : pScreenPriv->saved.y2 -= dy;
14406 : (void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
14407 : pScreenPriv->saved.x1,
14408 : pScreenPriv->saved.y1,
14409 : pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
14410 : pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
14413 : (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
14414 : pScreenPriv->saved.x1,
14415 : pScreenPriv->saved.y1,
14416 : pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
14417 : pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
14418 : sx - pScreenPriv->saved.x1,
14419 : sy - pScreenPriv->saved.y1,
14420 : pScreenPriv->colors[SOURCE_COLOR].pixel,
14421 : pScreenPriv->colors[MASK_COLOR].pixel);
14422 : miSpriteIsUpTRUE (pScreen, pScreenPriv);
14423 : DamageDrawInternal (pScreen, FALSE);
14427 : SPRITE_DEBUG (("SetCursor remove\n"));
14428 : miSpriteRemoveCursor (pScreen);
14431 : if (!pScreenPriv->isUp && pScreenPriv->pCursor)
14433 : SPRITE_DEBUG (("SetCursor restore\n"));
14434 : miSpriteRestoreCursor (pScreen);
14439 :miSpriteMoveCursor (pScreen, x, y)
14440 : ScreenPtr pScreen;
14443 : miSpriteScreenPtr pScreenPriv;
14445 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14446 : miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
14450 : * undraw/draw cursor
14454 :miSpriteRemoveCursor (pScreen)
14455 : ScreenPtr pScreen;
14457 : miSpriteScreenPtr pScreenPriv;
14459 : DamageDrawInternal (pScreen, TRUE);
14460 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14461 : miSpriteIsUpFALSE (pScreen, pScreenPriv);
14462 : pScreenPriv->pCacheWin = NullWindow;
14463 : if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
14464 : pScreenPriv->saved.x1,
14465 : pScreenPriv->saved.y1,
14466 : pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
14467 : pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
14469 : miSpriteIsUpTRUE (pScreen, pScreenPriv);
14471 : DamageDrawInternal (pScreen, FALSE);
14475 : * Called from the block handler, restores the cursor
14476 : * before waiting for something to do.
14480 :miSpriteRestoreCursor (pScreen)
14481 : ScreenPtr pScreen;
14483 : miSpriteScreenPtr pScreenPriv;
14485 : CursorPtr pCursor;
14487 : DamageDrawInternal (pScreen, TRUE);
14488 : miSpriteComputeSaved (pScreen);
14489 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14490 : pCursor = pScreenPriv->pCursor;
14491 : x = pScreenPriv->x - (int)pCursor->bits->xhot;
14492 : y = pScreenPriv->y - (int)pCursor->bits->yhot;
14493 : if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
14494 : pScreenPriv->saved.x1,
14495 : pScreenPriv->saved.y1,
14496 : pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
14497 : pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
14499 : if (pScreenPriv->checkPixels)
14500 : miSpriteFindColors (pScreen);
14501 : if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
14502 : pScreenPriv->colors[SOURCE_COLOR].pixel,
14503 : pScreenPriv->colors[MASK_COLOR].pixel))
14505 : miSpriteIsUpTRUE (pScreen, pScreenPriv);
14508 : DamageDrawInternal (pScreen, FALSE);
14512 : * compute the desired area of the screen to save
14516 :miSpriteComputeSaved (pScreen)
14517 : ScreenPtr pScreen;
14519 : miSpriteScreenPtr pScreenPriv;
14522 : CursorPtr pCursor;
14524 : pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
14525 : pCursor = pScreenPriv->pCursor;
14526 : x = pScreenPriv->x - (int)pCursor->bits->xhot;
14527 : y = pScreenPriv->y - (int)pCursor->bits->yhot;
14528 : w = pCursor->bits->width;
14529 : h = pCursor->bits->height;
14530 : wpad = SPRITE_PAD;
14531 : hpad = SPRITE_PAD;
14532 : pScreenPriv->saved.x1 = x - wpad;
14533 : pScreenPriv->saved.y1 = y - hpad;
14534 : pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
14535 : pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
14538 * Total samples for file : "/home/cworth/src/xorg/xserver/fb/fbcopy.c"
14545 : * Copyright © 1998 Keith Packard
14547 : * Permission to use, copy, modify, distribute, and sell this software and its
14548 : * documentation for any purpose is hereby granted without fee, provided that
14549 : * the above copyright notice appear in all copies and that both that
14550 : * copyright notice and this permission notice appear in supporting
14551 : * documentation, and that the name of Keith Packard not be used in
14552 : * advertising or publicity pertaining to distribution of the software without
14553 : * specific, written prior permission. Keith Packard makes no
14554 : * representations about the suitability of this software for any purpose. It
14555 : * is provided "as is" without express or implied warranty.
14557 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
14558 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
14559 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
14560 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
14561 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14562 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14563 : * PERFORMANCE OF THIS SOFTWARE.
14566 :#ifdef HAVE_DIX_CONFIG_H
14567 :#include <dix-config.h>
14570 :#include <stdlib.h>
14575 :fbCopyNtoN (DrawablePtr pSrcDrawable,
14576 : DrawablePtr pDstDrawable,
14587 : CARD8 alu = pGC ? pGC->alu : GXcopy;
14588 : FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
14590 : FbStride srcStride;
14592 : int srcXoff, srcYoff;
14594 : FbStride dstStride;
14596 : int dstXoff, dstYoff;
14598 : fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
14599 : fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
14603 :#ifndef FB_ACCESS_WRAPPER /* pixman_blt() doesn't support accessors yet */
14604 : if (pm == FB_ALLONES && alu == GXcopy && !reverse &&
14607 : if (!pixman_blt ((uint32_t *)src, (uint32_t *)dst, srcStride, dstStride, srcBpp, dstBpp,
14608 : (pbox->x1 + dx + srcXoff),
14609 : (pbox->y1 + dy + srcYoff),
14610 : (pbox->x1 + srcXoff),
14611 : (pbox->y1 + srcYoff),
14612 : (pbox->x2 - pbox->x1),
14613 : (pbox->y2 - pbox->y1)))
14620 : fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
14622 : (pbox->x1 + dx + srcXoff) * srcBpp,
14624 : dst + (pbox->y1 + dstYoff) * dstStride,
14626 : (pbox->x1 + dstXoff) * dstBpp,
14628 : (pbox->x2 - pbox->x1) * dstBpp,
14629 : (pbox->y2 - pbox->y1),
14637 :#ifndef FB_ACCESS_WRAPPER
14642 : fbFinishAccess (pDstDrawable);
14643 : fbFinishAccess (pSrcDrawable);
14647 :fbCopy1toN (DrawablePtr pSrcDrawable,
14648 : DrawablePtr pDstDrawable,
14659 : FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
14661 : FbStride srcStride;
14663 : int srcXoff, srcYoff;
14665 : FbStride dstStride;
14667 : int dstXoff, dstYoff;
14669 : fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
14670 : fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
14676 : fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
14678 : (pbox->x1 + dx + srcXoff) * srcBpp,
14680 : dst + (pbox->y1 + dstYoff) * dstStride,
14682 : (pbox->x1 + dstXoff) * dstBpp,
14684 : (pbox->x2 - pbox->x1) * dstBpp,
14685 : (pbox->y2 - pbox->y1),
14687 : FbOpaqueStipple1Rop(pGC->alu,
14688 : pGC->fgPixel,pGC->bgPixel),
14697 : fbBltOne ((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
14698 : srcStride*(FB_UNIT/FB_STIP_UNIT),
14699 : (pbox->x1 + dx + srcXoff),
14701 : dst + (pbox->y1 + dstYoff) * dstStride,
14703 : (pbox->x1 + dstXoff) * dstBpp,
14706 : (pbox->x2 - pbox->x1) * dstBpp,
14707 : (pbox->y2 - pbox->y1),
14709 : pPriv->and, pPriv->xor,
14710 : pPriv->bgand, pPriv->bgxor);
14715 : fbFinishAccess (pDstDrawable);
14716 : fbFinishAccess (pSrcDrawable);
14720 :fbCopyNto1 (DrawablePtr pSrcDrawable,
14721 : DrawablePtr pDstDrawable,
14732 : FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
14736 : if (pDstDrawable->bitsPerPixel == 1)
14739 : FbStride srcStride;
14741 : int srcXoff, srcYoff;
14744 : FbStride dstStride;
14746 : int dstXoff, dstYoff;
14748 : fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
14749 : fbGetStipDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
14750 : fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride,
14752 : (pbox->x1 + dx + srcXoff) * srcBpp,
14755 : dst + (pbox->y1 + dstYoff) * dstStride,
14757 : (pbox->x1 + dstXoff) * dstBpp,
14759 : (pbox->x2 - pbox->x1) * srcBpp,
14760 : (pbox->y2 - pbox->y1),
14762 : (FbStip) pPriv->and, (FbStip) pPriv->xor,
14763 : (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor,
14765 : fbFinishAccess (pDstDrawable);
14766 : fbFinishAccess (pSrcDrawable);
14771 : FbStride srcStride;
14773 : int srcXoff, srcYoff;
14776 : FbStride dstStride;
14778 : int dstXoff, dstYoff;
14781 : FbStride tmpStride;
14782 : int width, height;
14784 : width = pbox->x2 - pbox->x1;
14785 : height = pbox->y2 - pbox->y1;
14787 : tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
14788 : tmp = xalloc (tmpStride * height * sizeof (FbStip));
14792 : fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
14793 : fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
14795 : fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride,
14797 : (pbox->x1 + dx + srcXoff) * srcBpp,
14807 : fbAndStip(GXcopy,FB_ALLONES,FB_ALLONES),
14808 : fbXorStip(GXcopy,FB_ALLONES,FB_ALLONES),
14809 : fbAndStip(GXcopy,0,FB_ALLONES),
14810 : fbXorStip(GXcopy,0,FB_ALLONES),
14816 : dst + (pbox->y1 + dstYoff) * dstStride,
14818 : (pbox->x1 + dstXoff) * dstBpp,
14824 : pPriv->and, pPriv->xor,
14825 : pPriv->bgand, pPriv->bgxor);
14828 : fbFinishAccess (pDstDrawable);
14829 : fbFinishAccess (pSrcDrawable);
14836 :fbCopyRegion (DrawablePtr pSrcDrawable,
14837 : DrawablePtr pDstDrawable,
14839 : RegionPtr pDstRegion,
14842 : fbCopyProc copyProc,
14845 4 0.0044 :{ /* fbCopyRegion total: 27 0.0294 */
14851 : BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
14853 8 0.0087 : pbox = REGION_RECTS(pDstRegion);
14854 : nbox = REGION_NUM_RECTS(pDstRegion);
14856 : /* XXX we have to err on the side of safety when both are windows,
14857 : * because we don't know if IncludeInferiors is being used.
14859 2 0.0022 : careful = ((pSrcDrawable == pDstDrawable) ||
14860 : ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
14861 : (pDstDrawable->type == DRAWABLE_WINDOW)));
14865 : if (careful && dy < 0)
14867 : upsidedown = TRUE;
14871 : /* keep ordering in each band, reverse order of bands */
14872 : pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
14875 : pboxBase = pboxNext = pbox+nbox-1;
14876 : while (pboxBase >= pbox)
14878 : while ((pboxNext >= pbox) &&
14879 : (pboxBase->y1 == pboxNext->y1))
14881 : pboxTmp = pboxNext+1;
14882 : while (pboxTmp <= pboxBase)
14884 : *pboxNew1++ = *pboxTmp++;
14886 : pboxBase = pboxNext;
14888 : pboxNew1 -= nbox;
14894 : /* walk source top to bottom */
14895 : upsidedown = FALSE;
14898 : if (careful && dx < 0)
14900 : /* walk source right to left */
14908 : /* reverse order of rects in each band */
14909 : pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
14913 : DEALLOCATE_LOCAL(pboxNew1);
14916 : pboxBase = pboxNext = pbox;
14917 : while (pboxBase < pbox+nbox)
14919 : while ((pboxNext < pbox+nbox) &&
14920 : (pboxNext->y1 == pboxBase->y1))
14922 : pboxTmp = pboxNext;
14923 : while (pboxTmp != pboxBase)
14925 : *pboxNew2++ = *--pboxTmp;
14927 : pboxBase = pboxNext;
14929 1 0.0011 : pboxNew2 -= nbox;
14935 : /* walk source left to right */
14939 8 0.0087 : (*copyProc) (pSrcDrawable,
14945 : reverse, upsidedown, bitPlane, closure);
14948 : DEALLOCATE_LOCAL (pboxNew1);
14950 : DEALLOCATE_LOCAL (pboxNew2);
14954 :fbDoCopy (DrawablePtr pSrcDrawable,
14955 : DrawablePtr pDstDrawable,
14963 : fbCopyProc copyProc,
14966 5 0.0054 :{ /* fbDoCopy total: 100 0.1089 */
14967 : RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
14968 : Bool freeSrcClip = FALSE;
14969 : RegionPtr prgnExposed = NULL;
14970 : RegionRec rgnDst;
14978 : Bool fastSrc = FALSE; /* for fast clipping with pixmap source */
14979 : Bool fastDst = FALSE; /* for fast clipping with one rect dest */
14980 : Bool fastExpose = FALSE; /* for fast exposures with pixmap source */
14982 : /* Short cut for unmapped windows */
14984 1 0.0011 : if (pDstDrawable->type == DRAWABLE_WINDOW &&
14985 : !((WindowPtr)pDstDrawable)->realized)
14990 8 0.0087 : if ((pSrcDrawable != pDstDrawable) &&
14991 : pSrcDrawable->pScreen->SourceValidate)
14993 1 0.0011 : (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc);
14996 : /* Compute source clip region */
14997 2 0.0022 : if (pSrcDrawable->type == DRAWABLE_PIXMAP)
14999 6 0.0065 : if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
15000 : prgnSrcClip = fbGetCompositeClip(pGC);
15006 : if (pGC->subWindowMode == IncludeInferiors)
15009 : * XFree86 DDX empties the border clip when the
15010 : * VT is inactive, make sure the region isn't empty
15012 : if (!((WindowPtr) pSrcDrawable)->parent &&
15013 : REGION_NOTEMPTY (pSrcDrawable->pScreen,
15014 : &((WindowPtr) pSrcDrawable)->borderClip))
15017 : * special case bitblt from root window in
15018 : * IncludeInferiors mode; just like from a pixmap
15022 : else if ((pSrcDrawable == pDstDrawable) &&
15023 : (pGC->clientClipType == CT_NONE))
15025 : prgnSrcClip = fbGetCompositeClip(pGC);
15029 : prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
15030 : freeSrcClip = TRUE;
15035 : prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
15039 : xIn += pSrcDrawable->x;
15040 2 0.0022 : yIn += pSrcDrawable->y;
15042 1 0.0011 : xOut += pDstDrawable->x;
15043 2 0.0022 : yOut += pDstDrawable->y;
15047 : box_x2 = xIn + widthSrc;
15048 2 0.0022 : box_y2 = yIn + heightSrc;
15050 2 0.0022 : dx = xIn - xOut;
15051 4 0.0044 : dy = yIn - yOut;
15053 : /* Don't create a source region if we are doing a fast clip */
15054 3 0.0033 : if (fastSrc)
15058 : fastExpose = TRUE;
15060 : * clip the source; if regions extend beyond the source size,
15061 : * make sure exposure events get sent
15063 4 0.0044 : if (box_x1 < pSrcDrawable->x)
15065 : box_x1 = pSrcDrawable->x;
15066 : fastExpose = FALSE;
15068 : if (box_y1 < pSrcDrawable->y)
15070 : box_y1 = pSrcDrawable->y;
15071 : fastExpose = FALSE;
15073 7 0.0076 : if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
15075 : box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
15076 : fastExpose = FALSE;
15078 4 0.0044 : if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
15080 : box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
15081 : fastExpose = FALSE;
15084 : /* Translate and clip the dst to the destination composite clip */
15087 1 0.0011 : box_y1 -= dy;
15088 1 0.0011 : box_y2 -= dy;
15090 : /* If the destination composite clip is one rectangle we can
15091 : do the clip directly. Otherwise we have to create a full
15092 : blown region and call intersect */
15094 1 0.0011 : cclip = fbGetCompositeClip(pGC);
15095 2 0.0022 : if (REGION_NUM_RECTS(cclip) == 1)
15097 9 0.0098 : BoxPtr pBox = REGION_RECTS(cclip);
15099 : if (box_x1 < pBox->x1) box_x1 = pBox->x1;
15100 : if (box_x2 > pBox->x2) box_x2 = pBox->x2;
15101 : if (box_y1 < pBox->y1) box_y1 = pBox->y1;
15102 1 0.0011 : if (box_y2 > pBox->y2) box_y2 = pBox->y2;
15107 : /* Check to see if the region is empty */
15108 2 0.0022 : if (box_x1 >= box_x2 || box_y1 >= box_y2)
15110 3 0.0033 : REGION_NULL(pGC->pScreen, &rgnDst);
15119 : REGION_INIT(pGC->pScreen, &rgnDst, &box, 1);
15122 : /* Clip against complex source if needed */
15123 2 0.0022 : if (!fastSrc)
15125 : REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
15126 : REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
15129 : /* Clip against complex dest if needed */
15130 1 0.0011 : if (!fastDst)
15132 : REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
15133 : fbGetCompositeClip(pGC));
15136 : /* Do bit blitting */
15137 : numRects = REGION_NUM_RECTS(&rgnDst);
15138 1 0.0011 : if (numRects && widthSrc && heightSrc)
15139 16 0.0174 : fbCopyRegion (pSrcDrawable, pDstDrawable, pGC,
15140 : &rgnDst, dx, dy, copyProc, bitPlane, closure);
15142 : /* Pixmap sources generate a NoExposed (we return NULL to do this) */
15143 : if (!fastExpose && pGC->fExpose)
15144 : prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
15145 : xIn - pSrcDrawable->x,
15146 : yIn - pSrcDrawable->y,
15147 : widthSrc, heightSrc,
15148 : xOut - pDstDrawable->x,
15149 : yOut - pDstDrawable->y,
15150 : (unsigned long) bitPlane);
15151 : REGION_UNINIT(pGC->pScreen, &rgnDst);
15152 1 0.0011 : if (freeSrcClip)
15153 : REGION_DESTROY(pGC->pScreen, prgnSrcClip);
15154 : fbValidateDrawable (pDstDrawable);
15155 : return prgnExposed;
15159 :fbCopyArea (DrawablePtr pSrcDrawable,
15160 : DrawablePtr pDstDrawable,
15171 :#ifdef FB_24_32BIT
15172 : if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
15173 : copy = fb24_32CopyMtoN;
15176 : copy = fbCopyNtoN;
15177 : return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
15178 : widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
15182 :fbCopyPlane (DrawablePtr pSrcDrawable,
15183 : DrawablePtr pDstDrawable,
15191 : unsigned long bitplane)
15193 : if (pSrcDrawable->bitsPerPixel > 1)
15194 : return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
15195 : xIn, yIn, widthSrc, heightSrc,
15196 : xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
15197 : else if (bitplane & 1)
15198 : return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
15199 : widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
15200 : (Pixel) bitplane, 0);
15202 : return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
15206 : xOut, yOut, bitplane);
15209 * Total samples for file : "msort.c"
15214 <credited to line zero> 125 0.1362 :
15215 /* msort_with_tmp total: 125 0.1362 */
15217 * Total samples for file : "i810_hwmc.c"
15222 <credited to line zero> 119 0.1296 :
15223 /* __i686.get_pc_thunk.bx total: 119 0.1296 */
15225 * Total samples for file : "/home/cworth/src/xorg/xserver/dix/resource.c"
15231 :/************************************************************
15233 :Copyright 1987, 1998 The Open Group
15235 :Permission to use, copy, modify, distribute, and sell this software and its
15236 :documentation for any purpose is hereby granted without fee, provided that
15237 :the above copyright notice appear in all copies and that both that
15238 :copyright notice and this permission notice appear in supporting
15241 :The above copyright notice and this permission notice shall be included in
15242 :all copies or substantial portions of the Software.
15244 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15245 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15246 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15247 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
15248 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15249 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15251 :Except as contained in this notice, the name of The Open Group shall not be
15252 :used in advertising or otherwise to promote the sale, use or other dealings
15253 :in this Software without prior written authorization from The Open Group.
15256 :Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
15258 : All Rights Reserved
15260 :Permission to use, copy, modify, and distribute this software and its
15261 :documentation for any purpose and without fee is hereby granted,
15262 :provided that the above copyright notice appear in all copies and that
15263 :both that copyright notice and this permission notice appear in
15264 :supporting documentation, and that the name of Digital not be
15265 :used in advertising or publicity pertaining to distribution of the
15266 :software without specific, written prior permission.
15268 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15269 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
15270 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
15271 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
15272 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
15273 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15276 :********************************************************/
15277 :/* The panoramix components contained the following notice */
15278 :/*****************************************************************
15280 :Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
15282 :Permission is hereby granted, free of charge, to any person obtaining a copy
15283 :of this software and associated documentation files (the "Software"), to deal
15284 :in the Software without restriction, including without limitation the rights
15285 :to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15286 :copies of the Software.
15288 :The above copyright notice and this permission notice shall be included in
15289 :all copies or substantial portions of the Software.
15291 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15292 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15293 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15294 :DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
15295 :BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
15296 :WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
15297 :IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15299 :Except as contained in this notice, the name of Digital Equipment Corporation
15300 :shall not be used in advertising or otherwise to promote the sale, use or other
15301 :dealings in this Software without prior written authorization from Digital
15302 :Equipment Corporation.
15304 :******************************************************************/
15305 :/* XSERVER_DTRACE additions:
15306 : * Copyright 2005-2006 Sun Microsystems, Inc. All rights reserved.
15308 : * Permission is hereby granted, free of charge, to any person obtaining a
15309 : * copy of this software and associated documentation files (the
15310 : * "Software"), to deal in the Software without restriction, including
15311 : * without limitation the rights to use, copy, modify, merge, publish,
15312 : * distribute, and/or sell copies of the Software, and to permit persons
15313 : * to whom the Software is furnished to do so, provided that the above
15314 : * copyright notice(s) and this permission notice appear in all copies of
15315 : * the Software and that both the above copyright notice(s) and this
15316 : * permission notice appear in supporting documentation.
15318 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15319 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15320 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
15321 : * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
15322 : * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
15323 : * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
15324 : * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15325 : * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15326 : * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15328 : * Except as contained in this notice, the name of a copyright holder
15329 : * shall not be used in advertising or otherwise to promote the sale, use
15330 : * or other dealings in this Software without prior written authorization
15331 : * of the copyright holder.
15334 :/* Routines to manage various kinds of resources:
15336 : * CreateNewResourceType, CreateNewResourceClass, InitClientResources,
15337 : * FakeClientID, AddResource, FreeResource, FreeClientResources,
15338 : * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
15342 : * A resource ID is a 32 bit quantity, the upper 2 bits of which are
15343 : * off-limits for client-visible resources. The next 8 bits are
15344 : * used as client ID, and the low 22 bits come from the client.
15345 : * A resource ID is "hashed" by extracting and xoring subfields
15346 : * (varying with the size of the hash table).
15348 : * It is sometimes necessary for the server to create an ID that looks
15349 : * like it belongs to a client. This ID, however, must not be one
15350 : * the client actually can create, or we have the potential for conflict.
15351 : * The 31st bit of the ID is reserved for the server's use for this
15352 : * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
15353 : * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
15354 : * resource "owned" by the client.
15357 :#define NEED_EVENTS
15358 :#ifdef HAVE_DIX_CONFIG_H
15359 :#include <dix-config.h>
15362 :#include <X11/X.h>
15365 :#include "resource.h"
15366 :#include "dixstruct.h"
15367 :#include "opaque.h"
15368 :#include "windowstr.h"
15369 :#include "dixfont.h"
15370 :#include "colormap.h"
15371 :#include "inputstr.h"
15372 :#include "dixevents.h"
15373 :#include "dixgrabs.h"
15374 :#include "cursor.h"
15376 :#include "panoramiX.h"
15377 :#include "panoramiXsrv.h"
15380 :#include <assert.h>
15382 :#ifdef XSERVER_DTRACE
15383 :#include <sys/types.h>
15384 :typedef const char *string;
15385 :#include "Xserver-dtrace.h"
15387 :#define TypeNameString(t) NameForAtom(ResourceNames[t & TypeMask])
15390 :static void RebuildTable(
15394 :#define SERVER_MINID 32
15396 :#define INITBUCKETS 64
15397 :#define INITHASHSIZE 6
15398 :#define MAXHASHSIZE 11
15400 :typedef struct _Resource {
15401 : struct _Resource *next;
15405 :} ResourceRec, *ResourcePtr;
15406 :#define NullResource ((ResourcePtr)NULL)
15408 :typedef struct _ClientResource {
15409 : ResourcePtr *resources;
15412 : int hashsize; /* log(2)(buckets) */
15416 :} ClientResourceRec;
15418 :_X_EXPORT RESTYPE lastResourceType;
15419 :static RESTYPE lastResourceClass;
15420 :_X_EXPORT RESTYPE TypeMask;
15422 :static DeleteType *DeleteFuncs = (DeleteType *)NULL;
15424 :#ifdef XResExtension
15426 :_X_EXPORT Atom * ResourceNames = NULL;
15428 :_X_EXPORT void RegisterResourceName (RESTYPE type, char *name)
15430 : ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
15436 :CreateNewResourceType(DeleteType deleteFunc)
15438 : RESTYPE next = lastResourceType + 1;
15439 : DeleteType *funcs;
15441 : if (next & lastResourceClass)
15443 : funcs = (DeleteType *)xrealloc(DeleteFuncs,
15444 : (next + 1) * sizeof(DeleteType));
15448 :#ifdef XResExtension
15451 : newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
15454 : ResourceNames = newnames;
15455 : ResourceNames[next] = 0;
15459 : lastResourceType = next;
15460 : DeleteFuncs = funcs;
15461 : DeleteFuncs[next] = deleteFunc;
15466 :CreateNewResourceClass(void)
15468 : RESTYPE next = lastResourceClass >> 1;
15470 : if (next & lastResourceType)
15472 : lastResourceClass = next;
15473 : TypeMask = next - 1;
15477 :static ClientResourceRec clientTable[MAXCLIENTS];
15479 :/*****************
15480 : * InitClientResources
15481 : * When a new client is created, call this to allocate space
15482 : * in resource table
15483 : *****************/
15486 :InitClientResources(ClientPtr client)
15490 : if (client == serverClient)
15492 : lastResourceType = RT_LASTPREDEF;
15493 : lastResourceClass = RC_LASTPREDEF;
15494 : TypeMask = RC_LASTPREDEF - 1;
15496 : xfree(DeleteFuncs);
15497 : DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
15498 : sizeof(DeleteType));
15499 : if (!DeleteFuncs)
15501 : DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
15502 : DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
15503 : DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
15504 : DeleteFuncs[RT_GC & TypeMask] = FreeGC;
15505 : DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
15506 : DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
15507 : DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
15508 : DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
15509 : DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
15510 : DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
15512 :#ifdef XResExtension
15513 : if(ResourceNames)
15514 : xfree(ResourceNames);
15515 : ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
15516 : if(!ResourceNames)
15520 : clientTable[i = client->index].resources =
15521 : (ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
15522 : if (!clientTable[i].resources)
15524 : clientTable[i].buckets = INITBUCKETS;
15525 : clientTable[i].elements = 0;
15526 : clientTable[i].hashsize = INITHASHSIZE;
15527 : /* Many IDs allocated from the server client are visible to clients,
15528 : * so we don't use the SERVER_BIT for them, but we have to start
15529 : * past the magic value constants used in the protocol. For normal
15530 : * clients, we can start from zero, with SERVER_BIT set.
15532 : clientTable[i].fakeID = client->clientAsMask |
15533 : (client->index ? SERVER_BIT : SERVER_MINID);
15534 : clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
15535 : clientTable[i].expectID = client->clientAsMask;
15536 : for (j=0; j<INITBUCKETS; j++)
15538 : clientTable[i].resources[j] = NullResource;
15545 :Hash(int client, XID id)
15546 7 0.0076 :{ /* Hash total: 27 0.0294 */
15547 3 0.0033 : id &= RESOURCE_ID_MASK;
15548 9 0.0098 : switch (clientTable[client].hashsize)
15551 2 0.0022 : return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
15553 6 0.0065 : return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
15555 : return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
15557 : return ((int)(0x1FF & (id ^ (id>>9))));
15559 : return ((int)(0x3FF & (id ^ (id>>10))));
15561 : return ((int)(0x7FF & (id ^ (id>>11))));
15575 : if ((goodid >= id) && (goodid <= maxid))
15577 : for (; id <= maxid; id++)
15579 : res = clientTable[client].resources[Hash(client, id)];
15580 : while (res && (res->id != id))
15589 :GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
15592 : ResourcePtr *resp;
15597 : id = (Mask)client << CLIENTOFFSET;
15599 : id |= client ? SERVER_BIT : SERVER_MINID;
15600 : maxid = id | RESOURCE_ID_MASK;
15602 : for (resp = clientTable[client].resources, i = clientTable[client].buckets;
15605 : for (res = *resp++; res; res = res->next)
15607 : if ((res->id < id) || (res->id > maxid))
15609 : if (((res->id - id) >= (maxid - res->id)) ?
15610 : (goodid = AvailableID(client, id, res->id - 1, goodid)) :
15611 : !(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
15612 : maxid = res->id - 1;
15614 : id = res->id + 1;
15624 : * GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
15625 : * This function tries to find count unused XIDs for the given client. It
15626 : * puts the IDs in the array pids and returns the number found, which should
15627 : * almost always be the number requested.
15629 : * The circumstances that lead to a call to this function are very rare.
15630 : * Xlib must run out of IDs while trying to generate a request that wants
15631 : * multiple ID's, like the Multi-buffering CreateImageBuffers request.
15633 : * No rocket science in the implementation; just iterate over all
15634 : * possible IDs for the given client and pick the first count IDs
15635 : * that aren't in use. A more efficient algorithm could probably be
15636 : * invented, but this will be used so rarely that this should suffice.
15639 :_X_EXPORT unsigned int
15640 :GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
15642 : unsigned int found = 0;
15643 : XID id = pClient->clientAsMask;
15646 : maxid = id | RESOURCE_ID_MASK;
15647 : while ( (found < count) && (id <= maxid) )
15649 : if (!LookupIDByClass(id, RC_ANY))
15651 : pids[found++] = id;
15659 : * Return the next usable fake client ID.
15661 : * Normally this is just the next one in line, but if we've used the last
15662 : * in the range, we need to find a new range of safe IDs to avoid
15663 : * over-running another client.
15667 :FakeClientID(int client)
15671 : id = clientTable[client].fakeID++;
15672 : if (id != clientTable[client].endFakeID)
15674 : GetXIDRange(client, TRUE, &id, &maxid);
15677 : FatalError("FakeClientID: server internal ids exhausted\n");
15678 : MarkClientException(clients[client]);
15679 : id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
15680 : maxid = id | RESOURCE_ID_MASK;
15682 : clientTable[client].fakeID = id + 1;
15683 : clientTable[client].endFakeID = maxid + 1;
15688 :AddResource(XID id, RESTYPE type, pointer value)
15689 2 0.0022 :{ /* AddResource total: 8 0.0087 */
15691 : ClientResourceRec *rrec;
15692 : ResourcePtr res, *head;
15694 :#ifdef XSERVER_DTRACE
15695 : XSERVER_RESOURCE_ALLOC(id, type, value, TypeNameString(type));
15697 : client = CLIENT_ID(id);
15698 1 0.0011 : rrec = &clientTable[client];
15699 1 0.0011 : if (!rrec->buckets)
15701 : ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
15702 : (unsigned long)id, type, (unsigned long)value, client);
15703 : FatalError("client not in use\n");
15705 : if ((rrec->elements >= 4*rrec->buckets) &&
15706 : (rrec->hashsize < MAXHASHSIZE))
15707 : RebuildTable(client);
15708 : head = &rrec->resources[Hash(client, id)];
15709 : res = (ResourcePtr)xalloc(sizeof(ResourceRec));
15712 : (*DeleteFuncs[type & TypeMask])(value, id);
15715 1 0.0011 : res->next = *head;
15717 : res->type = type;
15718 1 0.0011 : res->value = value;
15720 : rrec->elements++;
15721 2 0.0022 : if (!(id & SERVER_BIT) && (id >= rrec->expectID))
15722 : rrec->expectID = id + 1;
15727 :RebuildTable(int client)
15730 : ResourcePtr res, next;
15731 : ResourcePtr **tails, *resources;
15732 : ResourcePtr **tptr, *rptr;
15735 : * For now, preserve insertion order, since some ddx layers depend
15736 : * on resources being free in the opposite order they are added.
15739 : j = 2 * clientTable[client].buckets;
15740 : tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
15743 : resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
15746 : DEALLOCATE_LOCAL(tails);
15749 : for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
15751 : *rptr = NullResource;
15754 : clientTable[client].hashsize++;
15755 : for (j = clientTable[client].buckets,
15756 : rptr = clientTable[client].resources;
15760 : for (res = *rptr; res; res = next)
15762 : next = res->next;
15763 : res->next = NullResource;
15764 : tptr = &tails[Hash(client, res->id)];
15766 : *tptr = &res->next;
15769 : DEALLOCATE_LOCAL(tails);
15770 : clientTable[client].buckets *= 2;
15771 : xfree(clientTable[client].resources);
15772 : clientTable[client].resources = resources;
15776 :FreeResource(XID id, RESTYPE skipDeleteFuncType)
15777 1 0.0011 :{ /* FreeResource total: 27 0.0294 */
15780 : ResourcePtr *prev, *head;
15783 : Bool gotOne = FALSE;
15785 1 0.0011 : if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
15787 : head = &clientTable[cid].resources[Hash(cid, id)];
15788 : eltptr = &clientTable[cid].elements;
15791 2 0.0022 : while ( (res = *prev) )
15793 2 0.0022 : if (res->id == id)
15795 : RESTYPE rtype = res->type;
15797 :#ifdef XSERVER_DTRACE
15798 : XSERVER_RESOURCE_FREE(res->id, res->type,
15799 : res->value, TypeNameString(res->type));
15801 : *prev = res->next;
15802 : elements = --*eltptr;
15803 : if (rtype & RC_CACHED)
15804 1 0.0011 : FlushClientCaches(res->id);
15805 1 0.0011 : if (rtype != skipDeleteFuncType)
15806 6 0.0065 : (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
15807 1 0.0011 : xfree(res);
15808 : if (*eltptr != elements)
15809 : prev = head; /* prev may no longer be valid */
15813 11 0.0120 : prev = &res->next;
15815 1 0.0011 : if(clients[cid] && (id == clients[cid]->lastDrawableID))
15817 : clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
15818 : clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
15822 : ErrorF("Freeing resource id=%lX which isn't there.\n",
15823 : (unsigned long)id);
15828 :FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
15832 : ResourcePtr *prev, *head;
15833 : if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
15835 : head = &clientTable[cid].resources[Hash(cid, id)];
15838 : while ( (res = *prev) )
15840 : if (res->id == id && res->type == type)
15842 :#ifdef XSERVER_DTRACE
15843 : XSERVER_RESOURCE_FREE(res->id, res->type,
15844 : res->value, TypeNameString(res->type));
15846 : *prev = res->next;
15847 : if (type & RC_CACHED)
15848 : FlushClientCaches(res->id);
15850 : (*DeleteFuncs[type & TypeMask])(res->value, res->id);
15855 : prev = &res->next;
15857 : if(clients[cid] && (id == clients[cid]->lastDrawableID))
15859 : clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
15860 : clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
15866 : * Change the value associated with a resource id. Caller
15867 : * is responsible for "doing the right thing" with the old
15872 :ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
15877 : if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
15879 : res = clientTable[cid].resources[Hash(cid, id)];
15881 : for (; res; res = res->next)
15882 : if ((res->id == id) && (res->type == rtype))
15884 : if (rtype & RC_CACHED)
15885 : FlushClientCaches(res->id);
15886 : res->value = value;
15893 :/* Note: if func adds or deletes resources, then func can get called
15894 : * more than once for some resources. If func adds new resources,
15895 : * func might or might not get called for them. func cannot both
15896 : * add and delete an equal number of resources!
15900 :FindClientResourcesByType(
15901 : ClientPtr client,
15903 : FindResType func,
15906 : ResourcePtr *resources;
15907 : ResourcePtr this, next;
15912 : client = serverClient;
15914 : resources = clientTable[client->index].resources;
15915 : eltptr = &clientTable[client->index].elements;
15916 : for (i = 0; i < clientTable[client->index].buckets; i++)
15918 : for (this = resources[i]; this; this = next)
15920 : next = this->next;
15921 : if (!type || this->type == type) {
15922 : elements = *eltptr;
15923 : (*func)(this->value, this->id, cdata);
15924 : if (*eltptr != elements)
15925 : next = resources[i]; /* start over */
15932 :FindAllClientResources(
15933 : ClientPtr client,
15937 : ResourcePtr *resources;
15938 : ResourcePtr this, next;
15943 : client = serverClient;
15945 : resources = clientTable[client->index].resources;
15946 : eltptr = &clientTable[client->index].elements;
15947 : for (i = 0; i < clientTable[client->index].buckets; i++)
15949 : for (this = resources[i]; this; this = next)
15951 : next = this->next;
15952 : elements = *eltptr;
15953 : (*func)(this->value, this->id, this->type, cdata);
15954 : if (*eltptr != elements)
15955 : next = resources[i]; /* start over */
15962 :LookupClientResourceComplex(
15963 : ClientPtr client,
15965 : FindComplexResType func,
15968 : ResourcePtr *resources;
15969 : ResourcePtr this;
15973 : client = serverClient;
15975 : resources = clientTable[client->index].resources;
15976 : for (i = 0; i < clientTable[client->index].buckets; i++) {
15977 : for (this = resources[i]; this; this = this->next) {
15978 : if (!type || this->type == type) {
15979 : if((*func)(this->value, this->id, cdata))
15980 : return this->value;
15989 :FreeClientNeverRetainResources(ClientPtr client)
15991 : ResourcePtr *resources;
15992 : ResourcePtr this;
15993 : ResourcePtr *prev;
15999 : resources = clientTable[client->index].resources;
16000 : for (j=0; j < clientTable[client->index].buckets; j++)
16002 : prev = &resources[j];
16003 : while ( (this = *prev) )
16005 : RESTYPE rtype = this->type;
16006 : if (rtype & RC_NEVERRETAIN)
16008 :#ifdef XSERVER_DTRACE
16009 : XSERVER_RESOURCE_FREE(this->id, this->type,
16010 : this->value, TypeNameString(this->type));
16012 : *prev = this->next;
16013 : if (rtype & RC_CACHED)
16014 : FlushClientCaches(this->id);
16015 : (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
16019 : prev = &this->next;
16025 :FreeClientResources(ClientPtr client)
16027 : ResourcePtr *resources;
16028 : ResourcePtr this;
16031 : /* This routine shouldn't be called with a null client, but just in
16037 : HandleSaveSet(client);
16039 : resources = clientTable[client->index].resources;
16040 : for (j=0; j < clientTable[client->index].buckets; j++)
16042 : /* It may seem silly to update the head of this resource list as
16043 : we delete the members, since the entire list will be deleted any way,
16044 : but there are some resource deletion functions "FreeClientPixels" for
16045 : one which do a LookupID on another resource id (a Colormap id in this
16046 : case), so the resource list must be kept valid up to the point that
16047 : it is deleted, so every time we delete a resource, we must update the
16048 : head, just like in FreeResource. I hope that this doesn't slow down
16049 : mass deletion appreciably. PRH */
16051 : ResourcePtr *head;
16053 : head = &resources[j];
16055 : for (this = *head; this; this = *head)
16057 : RESTYPE rtype = this->type;
16058 :#ifdef XSERVER_DTRACE
16059 : XSERVER_RESOURCE_FREE(this->id, this->type,
16060 : this->value, TypeNameString(this->type));
16062 : *head = this->next;
16063 : if (rtype & RC_CACHED)
16064 : FlushClientCaches(this->id);
16065 : (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
16069 : xfree(clientTable[client->index].resources);
16070 : clientTable[client->index].resources = NULL;
16071 : clientTable[client->index].buckets = 0;
16075 :FreeAllResources(void)
16079 : for (i = currentMaxClients; --i >= 0; )
16081 : if (clientTable[i].buckets)
16082 : FreeClientResources(clients[i]);
16087 :LegalNewID(XID id, ClientPtr client)
16088 3 0.0033 :{ /* LegalNewID total: 7 0.0076 */
16091 : XID minid, maxid;
16093 2 0.0022 : if (!noPanoramiXExtension) {
16094 : minid = client->clientAsMask | (client->index ?
16095 : SERVER_BIT : SERVER_MINID);
16096 : maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
16097 : if ((id >= minid) && (id <= maxid))
16100 :#endif /* PANORAMIX */
16101 1 0.0011 : return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
16102 : ((clientTable[client->index].expectID <= id) ||
16103 : !LookupIDByClass(id, RC_ANY)));
16106 :/* SecurityLookupIDByType and SecurityLookupIDByClass:
16107 : * These are the heart of the resource ID security system. They take
16108 : * two additional arguments compared to the old LookupID functions:
16109 : * the client doing the lookup, and the access mode (see resource.h).
16110 : * The resource is returned if it exists and the client is allowed access,
16111 : * else NULL is returned.
16115 :SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
16116 8 0.0087 :{ /* SecurityLookupIDByType total: 40 0.0436 */
16119 : pointer retval = NULL;
16121 11 0.0120 : if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
16122 : clientTable[cid].buckets)
16124 2 0.0022 : res = clientTable[cid].resources[Hash(cid, id)];
16126 6 0.0065 : for (; res; res = res->next)
16127 7 0.0076 : if ((res->id == id) && (res->type == rtype))
16129 1 0.0011 : retval = res->value;
16133 4 0.0044 : if (retval && client &&
16134 : !XaceHook(XACE_RESOURCE_ACCESS, client, id, rtype, mode, retval))
16142 :SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
16143 3 0.0033 :{ /* SecurityLookupIDByClass total: 8 0.0087 */
16145 : ResourcePtr res = NULL;
16146 : pointer retval = NULL;
16148 1 0.0011 : if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
16149 : clientTable[cid].buckets)
16151 : res = clientTable[cid].resources[Hash(cid, id)];
16153 1 0.0011 : for (; res; res = res->next)
16154 2 0.0022 : if ((res->id == id) && (res->type & classes))
16156 : retval = res->value;
16160 : if (retval && client &&
16161 : !XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type, mode, retval))
16167 :/* We can't replace the LookupIDByType and LookupIDByClass functions with
16168 : * macros because of compatibility with loadable servers.
16172 :LookupIDByType(XID id, RESTYPE rtype)
16174 : return SecurityLookupIDByType(NullClient, id, rtype,
16175 : DixUnknownAccess);
16179 :LookupIDByClass(XID id, RESTYPE classes)
16181 : return SecurityLookupIDByClass(NullClient, id, classes,
16182 : DixUnknownAccess);
16185 * Total samples for file : "xkbKillSrv.c"
16190 <credited to line zero> 111 0.1209 :
16191 /* __i686.get_pc_thunk.cx total: 2 0.0022 */
16192 /* __i686.get_pc_thunk.bx total: 97 0.1057 */
16193 /* __divdi3 total: 12 0.0131 */
16195 * Total samples for file : "/home/cworth/src/xorg/xserver/exa/exa_accel.c"
16202 : * Copyright © 2001 Keith Packard
16204 : * Partly based on code that is Copyright © The XFree86 Project Inc.
16206 : * Permission to use, copy, modify, distribute, and sell this software and its
16207 : * documentation for any purpose is hereby granted without fee, provided that
16208 : * the above copyright notice appear in all copies and that both that
16209 : * copyright notice and this permission notice appear in supporting
16210 : * documentation, and that the name of Keith Packard not be used in
16211 : * advertising or publicity pertaining to distribution of the software without
16212 : * specific, written prior permission. Keith Packard makes no
16213 : * representations about the suitability of this software for any purpose. It
16214 : * is provided "as is" without express or implied warranty.
16216 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16217 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16218 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
16219 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
16220 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16221 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16222 : * PERFORMANCE OF THIS SOFTWARE.
16225 : * Eric Anholt <eric@anholt.net>
16226 : * Michel Dänzer <michel@tungstengraphics.com>
16230 :#ifdef HAVE_DIX_CONFIG_H
16231 :#include <dix-config.h>
16233 :#include "exa_priv.h"
16234 :#include <X11/fonts/fontstruct.h>
16235 :#include "dixfontstr.h"
16240 :exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
16241 : DDXPointPtr ppt, int *pwidth, int fSorted)
16243 : ScreenPtr pScreen = pDrawable->pScreen;
16244 : ExaScreenPriv (pScreen);
16245 : RegionPtr pClip = fbGetCompositeClip(pGC);
16246 : PixmapPtr pPixmap;
16247 : BoxPtr pextent, pbox;
16249 : int extentX1, extentX2, extentY1, extentY2;
16250 : int fullX1, fullX2, fullY1;
16251 : int partX1, partX2;
16252 : int off_x, off_y;
16253 : ExaMigrationRec pixmaps[1];
16255 : pixmaps[0].as_dst = TRUE;
16256 : pixmaps[0].as_src = FALSE;
16257 : pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
16259 : if (pExaScr->swappedOut ||
16260 : pGC->fillStyle != FillSolid ||
16261 : pPixmap->drawable.width > pExaScr->info->maxX ||
16262 : pPixmap->drawable.height > pExaScr->info->maxY)
16264 : exaDoMigration (pixmaps, 1, FALSE);
16265 : ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
16268 : exaDoMigration (pixmaps, 1, TRUE);
16271 : if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
16272 : !(*pExaScr->info->PrepareSolid) (pPixmap,
16277 : exaDoMigration (pixmaps, 1, FALSE);
16278 : ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
16282 : pextent = REGION_EXTENTS(pGC->pScreen, pClip);
16283 : extentX1 = pextent->x1;
16284 : extentY1 = pextent->y1;
16285 : extentX2 = pextent->x2;
16286 : extentY2 = pextent->y2;
16291 : fullX2 = fullX1 + (int) *pwidth;
16295 : if (fullY1 < extentY1 || extentY2 <= fullY1)
16298 : if (fullX1 < extentX1)
16299 : fullX1 = extentX1;
16301 : if (fullX2 > extentX2)
16302 : fullX2 = extentX2;
16304 : if (fullX1 >= fullX2)
16307 : nbox = REGION_NUM_RECTS (pClip);
16310 : (*pExaScr->info->Solid) (pPixmap,
16311 : fullX1 + off_x, fullY1 + off_y,
16312 : fullX2 + off_x, fullY1 + 1 + off_y);
16316 : pbox = REGION_RECTS(pClip);
16319 : if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
16321 : partX1 = pbox->x1;
16322 : if (partX1 < fullX1)
16324 : partX2 = pbox->x2;
16325 : if (partX2 > fullX2)
16327 : if (partX2 > partX1) {
16328 : (*pExaScr->info->Solid) (pPixmap,
16329 : partX1 + off_x, fullY1 + off_y,
16330 : partX2 + off_x, fullY1 + 1 + off_y);
16337 : (*pExaScr->info->DoneSolid) (pPixmap);
16338 : exaMarkSync(pScreen);
16342 :exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
16343 : int w, int h, int leftPad, int format, char *bits)
16345 : ExaScreenPriv (pDrawable->pScreen);
16347 : ExaMigrationRec pixmaps[1];
16352 : int src_stride, bpp = pDrawable->bitsPerPixel;
16354 : pixmaps[0].as_dst = TRUE;
16355 : pixmaps[0].as_src = FALSE;
16356 : pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
16358 : /* Don't bother with under 8bpp, XYPixmaps. */
16359 : if (format != ZPixmap || bpp < 8)
16360 : goto migrate_and_fallback;
16362 : /* Only accelerate copies: no rop or planemask. */
16363 : if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
16364 : goto migrate_and_fallback;
16366 : if (pExaScr->swappedOut)
16369 : exaDoMigration (pixmaps, 1, TRUE);
16371 : if (pExaScr->info->UploadToScreen == NULL)
16374 : pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
16376 : if (pPix == NULL)
16379 : x += pDrawable->x;
16380 : y += pDrawable->y;
16382 : pClip = fbGetCompositeClip(pGC);
16383 : src_stride = PixmapBytePad(w, pDrawable->depth);
16384 : for (nbox = REGION_NUM_RECTS(pClip),
16385 : pbox = REGION_RECTS(pClip);
16396 : if (x1 < pbox->x1)
16398 : if (y1 < pbox->y1)
16400 : if (x2 > pbox->x2)
16402 : if (y2 > pbox->y2)
16404 : if (x1 >= x2 || y1 >= y2)
16407 : src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
16408 : ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
16409 : x2 - x1, y2 - y1, src, src_stride);
16410 : /* If we fail to accelerate the upload, fall back to using unaccelerated
16415 : FbStride dst_stride;
16417 : int dstXoff, dstYoff;
16419 : exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
16421 : fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
16422 : dstXoff, dstYoff);
16424 : fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)),
16425 : src_stride / sizeof(FbStip),
16426 : (x1 - x) * dstBpp,
16427 : dst + (y1 + dstYoff) * dst_stride,
16429 : (x1 + dstXoff) * dstBpp,
16430 : (x2 - x1) * dstBpp,
16432 : GXcopy, FB_ALLONES, dstBpp);
16434 : exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
16437 : exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
16442 :migrate_and_fallback:
16443 : exaDoMigration (pixmaps, 1, FALSE);
16446 : ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
16449 :static Bool inline
16450 :exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
16451 : GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
16453 : ExaScreenPriv (pDstDrawable->pScreen);
16454 : PixmapPtr pSrcPixmap, pDstPixmap;
16455 : int src_off_x, src_off_y, dst_off_x, dst_off_y;
16458 : /* Need to get both pixmaps to call the driver routines */
16459 : pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y);
16460 : pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y);
16461 : if (!pSrcPixmap || !pDstPixmap)
16465 : * Now the case of a chip that only supports xdir = ydir = 1 or
16466 : * xdir = ydir = -1, but we have xdir != ydir.
16468 : dirsetup = 0; /* No direction set up yet. */
16469 : for (; nbox; pbox++, nbox--) {
16470 : if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
16471 : /* Do a xdir = ydir = -1 blit instead. */
16472 : if (dirsetup != -1) {
16473 : if (dirsetup != 0)
16474 : pExaScr->info->DoneCopy(pDstPixmap);
16476 : if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
16479 : pGC ? pGC->alu : GXcopy,
16480 : pGC ? pGC->planemask :
16484 : (*pExaScr->info->Copy)(pDstPixmap,
16485 : src_off_x + pbox->x1 + dx,
16486 : src_off_y + pbox->y1 + dy,
16487 : dst_off_x + pbox->x1,
16488 : dst_off_y + pbox->y1,
16489 : pbox->x2 - pbox->x1,
16490 : pbox->y2 - pbox->y1);
16491 : } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
16492 : /* Do a xdir = ydir = 1 blit instead. */
16493 : if (dirsetup != 1) {
16494 : if (dirsetup != 0)
16495 : pExaScr->info->DoneCopy(pDstPixmap);
16497 : if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
16500 : pGC ? pGC->alu : GXcopy,
16501 : pGC ? pGC->planemask :
16505 : (*pExaScr->info->Copy)(pDstPixmap,
16506 : src_off_x + pbox->x1 + dx,
16507 : src_off_y + pbox->y1 + dy,
16508 : dst_off_x + pbox->x1,
16509 : dst_off_y + pbox->y1,
16510 : pbox->x2 - pbox->x1,
16511 : pbox->y2 - pbox->y1);
16512 : } else if (dx >= 0) {
16514 : * xdir = 1, ydir = -1.
16515 : * Perform line-by-line xdir = ydir = 1 blits, going up.
16518 : if (dirsetup != 1) {
16519 : if (dirsetup != 0)
16520 : pExaScr->info->DoneCopy(pDstPixmap);
16522 : if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
16525 : pGC ? pGC->alu : GXcopy,
16526 : pGC ? pGC->planemask :
16530 : for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
16531 : (*pExaScr->info->Copy)(pDstPixmap,
16532 : src_off_x + pbox->x1 + dx,
16533 : src_off_y + pbox->y1 + dy + i,
16534 : dst_off_x + pbox->x1,
16535 : dst_off_y + pbox->y1 + i,
16536 : pbox->x2 - pbox->x1, 1);
16539 : * xdir = -1, ydir = 1.
16540 : * Perform line-by-line xdir = ydir = -1 blits, going down.
16543 : if (dirsetup != -1) {
16544 : if (dirsetup != 0)
16545 : pExaScr->info->DoneCopy(pDstPixmap);
16547 : if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
16550 : pGC ? pGC->alu : GXcopy,
16551 : pGC ? pGC->planemask :
16555 : for (i = 0; i < pbox->y2 - pbox->y1; i++)
16556 : (*pExaScr->info->Copy)(pDstPixmap,
16557 : src_off_x + pbox->x1 + dx,
16558 : src_off_y + pbox->y1 + dy + i,
16559 : dst_off_x + pbox->x1,
16560 : dst_off_y + pbox->y1 + i,
16561 : pbox->x2 - pbox->x1, 1);
16563 : exaPixmapDirty(pDstPixmap, dst_off_x + pbox->x1, dst_off_y + pbox->y1,
16564 : dst_off_x + pbox->x2, dst_off_y + pbox->y2);
16566 : if (dirsetup != 0)
16567 : pExaScr->info->DoneCopy(pDstPixmap);
16568 : exaMarkSync(pDstDrawable->pScreen);
16573 :exaCopyNtoN (DrawablePtr pSrcDrawable,
16574 : DrawablePtr pDstDrawable,
16584 3 0.0033 :{ /* exaCopyNtoN total: 47 0.0512 */
16585 6 0.0065 : ExaScreenPriv (pDstDrawable->pScreen);
16586 : PixmapPtr pSrcPixmap, pDstPixmap;
16587 : int src_off_x, src_off_y;
16588 : int dst_off_x, dst_off_y;
16589 : ExaMigrationRec pixmaps[2];
16590 : Bool fallback = FALSE;
16592 : pixmaps[0].as_dst = TRUE;
16593 : pixmaps[0].as_src = FALSE;
16594 5 0.0054 : pixmaps[0].pPix = pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
16595 3 0.0033 : pixmaps[1].as_dst = FALSE;
16596 1 0.0011 : pixmaps[1].as_src = TRUE;
16597 7 0.0076 : pixmaps[1].pPix = pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
16599 : /* Respect maxX/maxY in a trivial way: don't set up drawing when we might
16600 : * violate the limits. The proper solution would be a temporary pixmap
16601 : * adjusted so that the drawing happened within limits.
16603 11 0.0120 : if (pSrcPixmap->drawable.width > pExaScr->info->maxX ||
16604 : pSrcPixmap->drawable.height > pExaScr->info->maxY ||
16605 : pDstPixmap->drawable.width > pExaScr->info->maxX ||
16606 : pDstPixmap->drawable.height > pExaScr->info->maxY)
16610 1 0.0011 : exaDoMigration (pixmaps, 2, TRUE);
16613 : /* Mixed directions must be handled specially if the card is lame */
16614 2 0.0022 : if (!fallback && (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
16615 : reverse != upsidedown) {
16616 : if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
16622 2 0.0022 : pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
16623 : pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
16625 : exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
16626 4 0.0044 : exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
16628 : if (fallback || !exaPixmapIsOffscreen(pSrcPixmap) ||
16629 : !exaPixmapIsOffscreen(pDstPixmap) ||
16630 : !(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
16631 : upsidedown ? -1 : 1,
16632 : pGC ? pGC->alu : GXcopy,
16633 : pGC ? pGC->planemask : FB_ALLONES)) {
16636 : EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
16637 : exaDrawableLocation(pSrcDrawable),
16638 : exaDrawableLocation(pDstDrawable)));
16639 : exaDoMigration (pixmaps, 2, FALSE);
16640 : exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
16641 : exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
16642 : fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
16643 : pbox, nbox, dx, dy, reverse, upsidedown,
16644 : bitplane, closure);
16645 : exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
16646 : exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
16652 : (*pExaScr->info->Copy) (pDstPixmap,
16653 : pbox->x1 + dx + src_off_x,
16654 : pbox->y1 + dy + src_off_y,
16655 : pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
16656 : pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
16657 : exaPixmapDirty (pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
16658 : pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
16665 : (*pExaScr->info->DoneCopy) (pDstPixmap);
16666 : exaMarkSync (pDstDrawable->pScreen);
16670 :exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
16671 : int srcx, int srcy, int width, int height, int dstx, int dsty)
16672 5 0.0054 :{ /* exaCopyArea total: 33 0.0359 */
16673 : ExaScreenPriv (pDstDrawable->pScreen);
16675 9 0.0098 : if (pExaScr->swappedOut) {
16676 : return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
16677 : srcx, srcy, width, height, dstx, dsty);
16680 14 0.0153 : return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
16681 : srcx, srcy, width, height,
16682 : dstx, dsty, exaCopyNtoN, 0, NULL);
16686 :exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
16690 : xRectangle *prect;
16692 : /* If we can't reuse the current GC as is, don't bother accelerating the
16695 : if (pGC->fillStyle != FillSolid) {
16696 : ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
16700 : prect = ALLOCATE_LOCAL(sizeof(xRectangle) * npt);
16701 : for (i = 0; i < npt; i++) {
16702 : prect[i].x = ppt[i].x;
16703 : prect[i].y = ppt[i].y;
16704 : if (i > 0 && mode == CoordModePrevious) {
16705 : prect[i].x += prect[i - 1].x;
16706 : prect[i].y += prect[i - 1].y;
16708 : prect[i].width = 1;
16709 : prect[i].height = 1;
16711 : pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect);
16712 : DEALLOCATE_LOCAL(prect);
16716 : * exaPolylines() checks if it can accelerate the lines as a group of
16717 : * horizontal or vertical lines (rectangles), and uses existing rectangle fill
16718 : * acceleration if so.
16721 :exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
16724 : xRectangle *prect;
16725 : int x1, x2, y1, y2;
16728 : /* Don't try to do wide lines or non-solid fill style. */
16729 : if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
16730 : pGC->fillStyle != FillSolid) {
16731 : ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
16735 : prect = ALLOCATE_LOCAL(sizeof(xRectangle) * (npt - 1));
16738 : /* If we have any non-horizontal/vertical, fall back. */
16739 : for (i = 0; i < npt; i++) {
16740 : if (mode == CoordModePrevious) {
16741 : x2 = x1 + ppt[i + 1].x;
16742 : y2 = y1 + ppt[i + 1].y;
16744 : x2 = ppt[i + 1].x;
16745 : y2 = ppt[i + 1].y;
16748 : if (x1 != x2 && y1 != y2) {
16749 : DEALLOCATE_LOCAL(prect);
16750 : ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
16756 : prect[i].width = x2 - x1 + 1;
16759 : prect[i].width = x1 - x2 + 1;
16763 : prect[i].height = y2 - y1 + 1;
16766 : prect[i].height = y1 - y2 + 1;
16772 : pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect);
16773 : DEALLOCATE_LOCAL(prect);
16777 : * exaPolySegment() checks if it can accelerate the lines as a group of
16778 : * horizontal or vertical lines (rectangles), and uses existing rectangle fill
16779 : * acceleration if so.
16782 :exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
16784 1 0.0011 :{ /* exaPolySegment total: 3 0.0033 */
16785 : xRectangle *prect;
16788 : /* Don't try to do wide lines or non-solid fill style. */
16789 : if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
16790 : pGC->fillStyle != FillSolid)
16792 : ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
16796 : /* If we have any non-horizontal/vertical, fall back. */
16797 : for (i = 0; i < nseg; i++) {
16798 : if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
16799 : ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
16804 1 0.0011 : prect = ALLOCATE_LOCAL(sizeof(xRectangle) * nseg);
16805 : for (i = 0; i < nseg; i++) {
16806 : if (pSeg[i].x1 < pSeg[i].x2) {
16807 : prect[i].x = pSeg[i].x1;
16808 : prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
16810 : prect[i].x = pSeg[i].x2;
16811 : prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
16813 : if (pSeg[i].y1 < pSeg[i].y2) {
16814 : prect[i].y = pSeg[i].y1;
16815 : prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
16817 : prect[i].y = pSeg[i].y2;
16818 1 0.0011 : prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
16821 : pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect);
16822 : DEALLOCATE_LOCAL(prect);
16825 :static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
16826 : Pixel pixel, CARD32 planemask, CARD32 alu);
16829 :exaPolyFillRect(DrawablePtr pDrawable,
16832 : xRectangle *prect)
16833 1 0.0011 :{ /* exaPolyFillRect total: 19 0.0207 */
16834 1 0.0011 : ExaScreenPriv (pDrawable->pScreen);
16835 : RegionPtr pClip = fbGetCompositeClip(pGC);
16836 : PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
16837 : register BoxPtr pbox;
16839 : int extentX1, extentX2, extentY1, extentY2;
16840 : int fullX1, fullX2, fullY1, fullY2;
16841 : int partX1, partX2, partY1, partY2;
16845 : ExaMigrationRec pixmaps[2];
16846 : RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
16848 : /* Compute intersection of rects and clip region */
16849 1 0.0011 : REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
16850 : REGION_INTERSECT(pScreen, pReg, pClip, pReg);
16852 : if (!REGION_NUM_RECTS(pReg)) {
16856 : pixmaps[0].as_dst = TRUE;
16857 : pixmaps[0].as_src = FALSE;
16858 : pixmaps[0].pPix = pPixmap;
16860 4 0.0044 : exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
16862 4 0.0044 : if (pExaScr->swappedOut ||
16863 : pPixmap->drawable.width > pExaScr->info->maxX ||
16864 : pPixmap->drawable.height > pExaScr->info->maxY)
16869 : /* For ROPs where overlaps don't matter, convert rectangles to region and
16870 : * call exaFillRegion{Solid,Tiled}.
16872 2 0.0022 : if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
16873 : (pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop ||
16874 : pGC->alu == GXcopyInverted || pGC->alu == GXset)) {
16875 6 0.0065 : if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
16876 : exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
16877 : pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
16879 : (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
16880 : exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
16881 : pGC->planemask, pGC->alu))) {
16886 : if (pGC->fillStyle != FillSolid &&
16887 : !(pGC->tileIsPixel && pGC->fillStyle == FillTiled))
16892 : exaDoMigration (pixmaps, 1, TRUE);
16894 : if (!exaPixmapIsOffscreen (pPixmap) ||
16895 : !(*pExaScr->info->PrepareSolid) (pPixmap,
16901 : if (pGC->fillStyle == FillTiled && !pGC->tileIsPixel) {
16902 : pixmaps[1].as_dst = FALSE;
16903 : pixmaps[1].as_src = TRUE;
16904 : pixmaps[1].pPix = pGC->tile.pixmap;
16905 : exaDoMigration (pixmaps, 2, FALSE);
16907 : exaDoMigration (pixmaps, 1, FALSE);
16910 : ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
16914 : xorg = pDrawable->x;
16915 : yorg = pDrawable->y;
16917 : pextent = REGION_EXTENTS(pGC->pScreen, pClip);
16918 : extentX1 = pextent->x1;
16919 : extentY1 = pextent->y1;
16920 : extentX2 = pextent->x2;
16921 : extentY2 = pextent->y2;
16924 : fullX1 = prect->x + xorg;
16925 : fullY1 = prect->y + yorg;
16926 : fullX2 = fullX1 + (int) prect->width;
16927 : fullY2 = fullY1 + (int) prect->height;
16930 : if (fullX1 < extentX1)
16931 : fullX1 = extentX1;
16933 : if (fullY1 < extentY1)
16934 : fullY1 = extentY1;
16936 : if (fullX2 > extentX2)
16937 : fullX2 = extentX2;
16939 : if (fullY2 > extentY2)
16940 : fullY2 = extentY2;
16942 : if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
16944 : n = REGION_NUM_RECTS (pClip);
16947 : (*pExaScr->info->Solid) (pPixmap,
16948 : fullX1 + xoff, fullY1 + yoff,
16949 : fullX2 + xoff, fullY2 + yoff);
16953 : pbox = REGION_RECTS(pClip);
16955 : * clip the rectangle to each box in the clip region
16956 : * this is logically equivalent to calling Intersect(),
16957 : * but rectangles may overlap each other here.
16961 : partX1 = pbox->x1;
16962 : if (partX1 < fullX1)
16964 : partY1 = pbox->y1;
16965 : if (partY1 < fullY1)
16967 : partX2 = pbox->x2;
16968 : if (partX2 > fullX2)
16970 : partY2 = pbox->y2;
16971 : if (partY2 > fullY2)
16976 : if (partX1 < partX2 && partY1 < partY2) {
16977 : (*pExaScr->info->Solid) (pPixmap,
16978 : partX1 + xoff, partY1 + yoff,
16979 : partX2 + xoff, partY2 + yoff);
16984 : (*pExaScr->info->DoneSolid) (pPixmap);
16985 : exaMarkSync(pDrawable->pScreen);
16988 : REGION_DESTROY(pScreen, pReg);
16992 :exaSolidBoxClipped (DrawablePtr pDrawable,
17001 : ExaScreenPriv (pDrawable->pScreen);
17002 : PixmapPtr pPixmap;
17006 : int partX1, partX2, partY1, partY2;
17007 : ExaMigrationRec pixmaps[1];
17008 : Bool fallback = FALSE;
17010 : pixmaps[0].as_dst = TRUE;
17011 : pixmaps[0].as_src = FALSE;
17012 : pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
17014 : if (pExaScr->swappedOut ||
17015 : pPixmap->drawable.width > pExaScr->info->maxX ||
17016 : pPixmap->drawable.height > pExaScr->info->maxY)
17020 : exaDoMigration (pixmaps, 1, TRUE);
17023 : exaGetDrawableDeltas (pDrawable, pPixmap, &xoff, &yoff);
17025 : if (fallback || !exaPixmapIsOffscreen(pPixmap) ||
17026 : !(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg))
17028 : EXA_FALLBACK(("to %p (%c)\n", pDrawable,
17029 : exaDrawableLocation(pDrawable)));
17030 : exaDoMigration (pixmaps, 1, FALSE);
17032 : exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
17033 : fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
17034 : fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
17035 : fbAnd (GXcopy, fg, pm),
17036 : fbXor (GXcopy, fg, pm));
17037 : exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
17039 : for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
17043 : partX1 = pbox->x1;
17047 : partX2 = pbox->x2;
17051 : if (partX2 <= partX1)
17054 : partY1 = pbox->y1;
17058 : partY2 = pbox->y2;
17062 : if (partY2 <= partY1)
17066 : (*pExaScr->info->Solid) (pPixmap,
17067 : partX1 + xoff, partY1 + yoff,
17068 : partX2 + xoff, partY2 + yoff);
17071 : exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff,
17078 : (*pExaScr->info->DoneSolid) (pPixmap);
17079 : exaMarkSync(pDrawable->pScreen);
17083 :exaImageGlyphBlt (DrawablePtr pDrawable,
17087 : unsigned int nglyph,
17088 : CharInfoPtr *ppciInit,
17089 : pointer pglyphBase)
17091 : FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
17092 : CharInfoPtr *ppci;
17094 : unsigned char *pglyph; /* pointer bits in glyph */
17095 : int gWidth, gHeight; /* width and height of glyph */
17096 : FbStride gStride; /* stride of glyph */
17100 : void (*glyph) (FbBits *,
17108 : FbStride dstStride;
17110 : int dstXoff, dstYoff;
17111 : FbBits depthMask;
17112 : PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
17113 : ExaMigrationRec pixmaps[1];
17114 : int xBack, widthBack, yBack, heightBack;
17116 : for (ppci = ppciInit, n = nglyph, widthBack = 0; n; n--)
17117 : widthBack += (*ppci++)->metrics.characterWidth;
17120 : if (widthBack < 0)
17122 : xBack += widthBack;
17123 : widthBack = -widthBack;
17125 : yBack = y - FONTASCENT(pGC->font);
17126 : heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
17128 : if (xBack >= pDrawable->width || yBack >= pDrawable->height ||
17129 : (xBack + widthBack) <= 0 || (yBack + heightBack) <= 0)
17132 : pixmaps[0].as_dst = TRUE;
17133 : pixmaps[0].as_src = TRUE;
17134 : pixmaps[0].pPix = pPixmap;
17136 : depthMask = FbFullMask(pDrawable->depth);
17137 : if ((pGC->planemask & depthMask) != depthMask)
17139 : exaDoMigration(pixmaps, 1, FALSE);
17140 : ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
17144 : switch (pDrawable->bitsPerPixel) {
17145 : case 8: glyph = fbGlyph8; break;
17146 : case 16: glyph = fbGlyph16; break;
17147 : case 24: glyph = fbGlyph24; break;
17148 : case 32: glyph = fbGlyph32; break;
17151 : x += pDrawable->x;
17152 : y += pDrawable->y;
17153 : xBack += pDrawable->x;
17154 : yBack += pDrawable->y;
17156 : if (TERMINALFONT (pGC->font) && !glyph)
17162 : exaSolidBoxClipped (pDrawable,
17163 : fbGetCompositeClip(pGC),
17168 : xBack + widthBack,
17169 : yBack + heightBack);
17173 : EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
17174 : exaDoMigration(pixmaps, 1, FALSE);
17175 : exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
17176 : exaPrepareAccessGC (pGC);
17178 : fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
17180 : for (ppci = ppciInit; nglyph; nglyph--, x += pci->metrics.characterWidth)
17183 : gWidth = GLYPHWIDTHPIXELS(pci);
17184 : gHeight = GLYPHHEIGHTPIXELS(pci);
17185 : gx = x + pci->metrics.leftSideBearing;
17186 : gy = y - pci->metrics.ascent;
17188 : if (!gWidth || !gHeight || (gx + gWidth) <= xBack ||
17189 : (gy + gHeight) <= yBack || gx >= (xBack + widthBack) ||
17190 : gy >= (yBack + heightBack))
17193 : pglyph = FONTGLYPHBITS(pglyphBase, pci);
17195 : if (glyph && gWidth <= sizeof (FbStip) * 8 &&
17196 : fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
17198 : (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
17199 : (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight);
17203 : RegionPtr pClip = fbGetCompositeClip(pGC);
17205 : gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
17206 : fbPutXYImage (pDrawable, pClip, pPriv->fg, pPriv->bg, pPriv->pm,
17207 : GXcopy, opaque, gx, gy, gWidth, gHeight,
17208 : (FbStip *) pglyph, gStride, 0);
17211 : exaFinishAccessGC (pGC);
17212 : exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
17215 : exaGetDrawableDeltas(pDrawable, pPixmap, &dstXoff, &dstYoff);
17216 : exaPixmapDirty(pPixmap, xBack + dstXoff, yBack + dstYoff,
17217 : xBack + dstXoff + widthBack, yBack + dstYoff + heightBack);
17220 :const GCOps exaOps = {
17222 : ExaCheckSetSpans,
17225 : ExaCheckCopyPlane,
17238 : exaImageGlyphBlt,
17239 : ExaCheckPolyGlyphBlt,
17240 : ExaCheckPushPixels,
17244 :exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
17246 : RegionRec rgnDst;
17248 : PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
17250 : dx = ptOldOrg.x - pWin->drawable.x;
17251 : dy = ptOldOrg.y - pWin->drawable.y;
17252 : REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
17254 : REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
17256 : REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
17258 : if (pPixmap->screen_x || pPixmap->screen_y)
17259 : REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
17260 : -pPixmap->screen_x, -pPixmap->screen_y);
17263 : fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
17265 : &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
17267 : REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
17271 :exaFillRegionSolid (DrawablePtr pDrawable,
17272 : RegionPtr pRegion,
17274 : CARD32 planemask,
17276 2 0.0022 :{ /* exaFillRegionSolid total: 7 0.0076 */
17277 : ExaScreenPriv(pDrawable->pScreen);
17278 : PixmapPtr pPixmap;
17280 : ExaMigrationRec pixmaps[1];
17281 : int nbox = REGION_NUM_RECTS (pRegion);
17282 : BoxPtr pBox = REGION_RECTS (pRegion);
17284 : pixmaps[0].as_dst = TRUE;
17285 : pixmaps[0].as_src = FALSE;
17286 1 0.0011 : pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
17288 1 0.0011 : if (pPixmap->drawable.width > pExaScr->info->maxX ||
17289 : pPixmap->drawable.height > pExaScr->info->maxY)
17293 : exaDoMigration (pixmaps, 1, TRUE);
17296 2 0.0022 : if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
17297 : (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
17301 : (*pExaScr->info->Solid) (pPixmap,
17302 : pBox->x1 + xoff, pBox->y1 + yoff,
17303 : pBox->x2 + xoff, pBox->y2 + yoff);
17306 : (*pExaScr->info->DoneSolid) (pPixmap);
17307 1 0.0011 : exaMarkSync(pDrawable->pScreen);
17312 : if (alu != GXcopy || planemask != FB_ALLONES)
17315 : EXA_FALLBACK(("to %p (%c)\n", pDrawable,
17316 : exaDrawableLocation(pDrawable)));
17317 : exaDoMigration (pixmaps, 1, FALSE);
17318 : exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
17319 : fbFillRegionSolid (pDrawable, pRegion, 0,
17320 : fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
17321 : exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
17327 :/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
17328 : * Based on fbFillRegionTiled(), fbTile().
17331 :exaFillRegionTiled (DrawablePtr pDrawable,
17332 : RegionPtr pRegion,
17334 : DDXPointPtr pPatOrg,
17335 : CARD32 planemask,
17338 : ExaScreenPriv(pDrawable->pScreen);
17339 : PixmapPtr pPixmap;
17340 : int xoff, yoff, tileXoff, tileYoff;
17341 : int tileWidth, tileHeight;
17342 : ExaMigrationRec pixmaps[2];
17343 : int nbox = REGION_NUM_RECTS (pRegion);
17344 : BoxPtr pBox = REGION_RECTS (pRegion);
17346 : tileWidth = pTile->drawable.width;
17347 : tileHeight = pTile->drawable.height;
17349 : /* If we're filling with a solid color, grab it out and go to
17350 : * FillRegionSolid, saving numerous copies.
17352 : if (tileWidth == 1 && tileHeight == 1)
17353 : return exaFillRegionSolid(pDrawable, pRegion,
17354 : exaGetPixmapFirstPixel (pTile), planemask,
17357 : pixmaps[0].as_dst = TRUE;
17358 : pixmaps[0].as_src = FALSE;
17359 : pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
17360 : pixmaps[1].as_dst = FALSE;
17361 : pixmaps[1].as_src = TRUE;
17362 : pixmaps[1].pPix = pTile;
17364 : if (pPixmap->drawable.width > pExaScr->info->maxX ||
17365 : pPixmap->drawable.height > pExaScr->info->maxY ||
17366 : tileWidth > pExaScr->info->maxX ||
17367 : tileHeight > pExaScr->info->maxY)
17371 : exaDoMigration (pixmaps, 2, TRUE);
17374 : pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
17379 : if (!exaPixmapIsOffscreen(pTile))
17382 : if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile,
17383 : &tileXoff, &tileYoff),
17384 : pPixmap, 0, 0, alu, planemask))
17388 : int height = pBox->y2 - pBox->y1;
17389 : int dstY = pBox->y1;
17392 : tileY = (dstY - pDrawable->y - pPatOrg->y) % tileHeight;
17393 : while (height > 0) {
17394 : int width = pBox->x2 - pBox->x1;
17395 : int dstX = pBox->x1;
17397 : int h = tileHeight - tileY;
17403 : tileX = (dstX - pDrawable->x - pPatOrg->x) % tileWidth;
17404 : while (width > 0) {
17405 : int w = tileWidth - tileX;
17410 : (*pExaScr->info->Copy) (pPixmap,
17411 : tileX + tileXoff, tileY + tileYoff,
17412 : dstX + xoff, dstY + yoff,
17422 : (*pExaScr->info->DoneCopy) (pPixmap);
17423 : exaMarkSync(pDrawable->pScreen);
17428 : if (alu != GXcopy || planemask != FB_ALLONES)
17430 : EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
17431 : exaDrawableLocation(&pTile->drawable),
17432 : exaDrawableLocation(pDrawable)));
17433 : exaDoMigration (pixmaps, 2, FALSE);
17434 : exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
17435 : exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
17436 : fbFillRegionTiled (pDrawable, pRegion, pTile);
17437 : exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
17438 : exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
17444 :exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
17446 : ExaScreenPriv (pWin->drawable.pScreen);
17447 : PixmapPtr pPixmap = exaGetDrawablePixmap((DrawablePtr)pWin);
17450 : int nbox = REGION_NUM_RECTS(pRegion);
17455 : if (!pExaScr->swappedOut) {
17456 : DDXPointRec zeros = { 0, 0 };
17459 : case PW_BACKGROUND:
17460 : switch (pWin->backgroundState) {
17463 : case ParentRelative:
17465 : pWin = pWin->parent;
17466 : } while (pWin->backgroundState == ParentRelative);
17467 : (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
17470 : case BackgroundPixel:
17471 : exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel,
17472 : FB_ALLONES, GXcopy);
17474 : case BackgroundPixmap:
17475 : exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap,
17476 : &zeros, FB_ALLONES, GXcopy);
17481 : if (pWin->borderIsPixel) {
17482 : exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel,
17483 : FB_ALLONES, GXcopy);
17486 : exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap,
17487 : &zeros, FB_ALLONES, GXcopy);
17493 : ExaCheckPaintWindow (pWin, pRegion, what);
17496 : exaGetDrawableDeltas((DrawablePtr)pWin, pPixmap, &xoff, &yoff);
17498 : pBox = REGION_RECTS(pRegion);
17502 : exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
17503 : pBox->x2 + xoff, pBox->y2 + yoff);
17509 : * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
17511 : * This is probably the only case we actually care about. The rest fall through
17512 : * to migration and ExaCheckGetImage, which hopefully will result in migration
17513 : * pushing the pixmap out of framebuffer.
17516 :exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
17517 : unsigned int format, unsigned long planeMask, char *d)
17519 : ExaScreenPriv (pDrawable->pScreen);
17520 : ExaMigrationRec pixmaps[1];
17525 : if (pExaScr->swappedOut || (w == 1 && h == 1))
17528 : if (pExaScr->info->DownloadFromScreen == NULL)
17529 : goto migrate_and_fallback;
17531 : /* Only cover the ZPixmap, solid copy case. */
17532 : if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
17533 : goto migrate_and_fallback;
17535 : /* Only try to handle the 8bpp and up cases, since we don't want to think
17538 : if (pDrawable->bitsPerPixel < 8)
17539 : goto migrate_and_fallback;
17541 : pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
17542 : if (pPix == NULL)
17545 : xoff += pDrawable->x;
17546 : yoff += pDrawable->y;
17548 : ok = pExaScr->info->DownloadFromScreen(pPix, x + xoff, y + yoff, w, h, d,
17549 : PixmapBytePad(w, pDrawable->depth));
17551 : exaWaitSync(pDrawable->pScreen);
17555 :migrate_and_fallback:
17556 : pixmaps[0].as_dst = FALSE;
17557 : pixmaps[0].as_src = TRUE;
17558 : pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
17559 : exaDoMigration (pixmaps, 1, FALSE);
17561 : ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d);
17565 : * GetSpans isn't accelerated yet, but performs migration so that we'll
17566 : * hopefully avoid the read-from-framebuffer cost.
17569 :exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
17570 : int nspans, char *pdstStart)
17572 : ExaMigrationRec pixmaps[1];
17574 : pixmaps[0].as_dst = FALSE;
17575 : pixmaps[0].as_src = TRUE;
17576 : pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
17577 : exaDoMigration (pixmaps, 1, FALSE);
17579 : ExaCheckGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
17582 * Total samples for file : "/home/cworth/src/xorg/xserver/render/glyph.c"
17590 : * Copyright © 2000 SuSE, Inc.
17592 : * Permission to use, copy, modify, distribute, and sell this software and its
17593 : * documentation for any purpose is hereby granted without fee, provided that
17594 : * the above copyright notice appear in all copies and that both that
17595 : * copyright notice and this permission notice appear in supporting
17596 : * documentation, and that the name of SuSE not be used in advertising or
17597 : * publicity pertaining to distribution of the software without specific,
17598 : * written prior permission. SuSE makes no representations about the
17599 : * suitability of this software for any purpose. It is provided "as is"
17600 : * without express or implied warranty.
17602 : * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17603 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
17604 : * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17605 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
17606 : * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17607 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17609 : * Author: Keith Packard, SuSE, Inc.
17612 :#ifdef HAVE_DIX_CONFIG_H
17613 :#include <dix-config.h>
17617 :#include "scrnintstr.h"
17619 :#include "regionstr.h"
17620 :#include "validate.h"
17621 :#include "windowstr.h"
17622 :#include "input.h"
17623 :#include "resource.h"
17624 :#include "colormapst.h"
17625 :#include "cursorstr.h"
17626 :#include "dixstruct.h"
17627 :#include "gcstruct.h"
17628 :#include "servermd.h"
17629 :#include "picturestr.h"
17630 :#include "glyphstr.h"
17633 : * From Knuth -- a good choice for hash/rehash values is p, p-2 where
17634 : * p and p-2 are both prime. These tables are sized to have an extra 10%
17635 : * free to avoid exponential performance degradation as the hash table fills
17637 :static GlyphHashSetRec glyphHashSets[] = {
17640 : { 128, 151, 149 },
17641 : { 256, 283, 281 },
17642 : { 512, 571, 569 },
17643 : { 1024, 1153, 1151 },
17644 : { 2048, 2269, 2267 },
17645 : { 4096, 4519, 4517 },
17646 : { 8192, 9013, 9011 },
17647 : { 16384, 18043, 18041 },
17648 : { 32768, 36109, 36107 },
17649 : { 65536, 72091, 72089 },
17650 : { 131072, 144409, 144407 },
17651 : { 262144, 288361, 288359 },
17652 : { 524288, 576883, 576881 },
17653 : { 1048576, 1153459, 1153457 },
17654 : { 2097152, 2307163, 2307161 },
17655 : { 4194304, 4613893, 4613891 },
17656 : { 8388608, 9227641, 9227639 },
17657 : { 16777216, 18455029, 18455027 },
17658 : { 33554432, 36911011, 36911009 },
17659 : { 67108864, 73819861, 73819859 },
17660 : { 134217728, 147639589, 147639587 },
17661 : { 268435456, 295279081, 295279079 },
17662 : { 536870912, 590559793, 590559791 }
17665 :#define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
17667 :static const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
17669 :static GlyphHashRec globalGlyphs[GlyphFormatNum];
17671 :static int globalTotalGlyphPrivateSize = 0;
17673 :static int glyphPrivateCount = 0;
17676 :ResetGlyphPrivates (void)
17678 : glyphPrivateCount = 0;
17682 :AllocateGlyphPrivateIndex (void)
17684 : return glyphPrivateCount++;
17688 :AllocateGlyphPrivate (ScreenPtr pScreen,
17692 : PictureScreenPtr ps;
17693 : unsigned oldamount;
17695 : ps = GetPictureScreenIfSet (pScreen);
17699 : /* Round up sizes for proper alignment */
17700 : amount = ((amount + (sizeof (DevUnion) - 1)) / sizeof (DevUnion)) *
17701 : sizeof (DevUnion);
17703 : if (index2 >= ps->glyphPrivateLen)
17705 : unsigned *nsizes;
17706 : nsizes = (unsigned *) xrealloc (ps->glyphPrivateSizes,
17707 : (index2 + 1) * sizeof (unsigned));
17711 : while (ps->glyphPrivateLen <= index2)
17713 : nsizes[ps->glyphPrivateLen++] = 0;
17714 : ps->totalGlyphPrivateSize += sizeof (DevUnion);
17716 : ps->glyphPrivateSizes = nsizes;
17718 : oldamount = ps->glyphPrivateSizes[index2];
17719 : if (amount > oldamount)
17721 : ps->glyphPrivateSizes[index2] = amount;
17722 : ps->totalGlyphPrivateSize += (amount - oldamount);
17724 : ps->totalGlyphPrivateSize = BitmapBytePad (ps->totalGlyphPrivateSize * 8);
17730 :SetGlyphScreenPrivateOffsets (void)
17732 : PictureScreenPtr ps;
17736 : for (i = 0; i < screenInfo.numScreens; i++)
17738 : ps = GetPictureScreenIfSet (screenInfo.screens[i]);
17739 : if (ps && ps->totalGlyphPrivateSize)
17741 : ps->glyphPrivateOffset = offset;
17742 : offset += ps->totalGlyphPrivateSize / sizeof (DevUnion);
17748 :SetGlyphPrivatePointers (GlyphPtr glyph)
17750 : PictureScreenPtr ps;
17758 : for (i = 0; i < screenInfo.numScreens; i++)
17760 : ps = GetPictureScreenIfSet (screenInfo.screens[i]);
17761 : if (ps && ps->totalGlyphPrivateSize)
17763 : ppriv = glyph->devPrivates + ps->glyphPrivateOffset;
17764 : sizes = ps->glyphPrivateSizes;
17765 : ptr = (char *) (ppriv + ps->glyphPrivateLen);
17766 : for (len = ps->glyphPrivateLen; --len >= 0; ppriv++, sizes++)
17768 : if ((size = *sizes) != 0)
17770 : ppriv->ptr = (pointer) ptr;
17774 : ppriv->ptr = (pointer) 0;
17781 :ReallocGlobalGlyphPrivate (GlyphPtr glyph)
17783 : PictureScreenPtr ps;
17784 : DevUnion *devPrivates;
17788 : devPrivates = xalloc (globalTotalGlyphPrivateSize);
17789 : if (!devPrivates)
17792 : ptr = (char *) devPrivates;
17793 : for (i = 0; i < screenInfo.numScreens; i++)
17795 : ps = GetPictureScreenIfSet (screenInfo.screens[i]);
17796 : if (ps && ps->totalGlyphPrivateSize)
17798 : if (ps->glyphPrivateOffset != -1)
17800 : memcpy (ptr, glyph->devPrivates + ps->glyphPrivateOffset,
17801 : ps->totalGlyphPrivateSize);
17803 : else if (ps->totalGlyphPrivateSize)
17805 : memset (ptr, 0, ps->totalGlyphPrivateSize);
17808 : ptr += ps->totalGlyphPrivateSize;
17812 : if (glyph->devPrivates)
17813 : xfree (glyph->devPrivates);
17815 : glyph->devPrivates = devPrivates;
17821 :GlyphInit (ScreenPtr pScreen)
17823 : PictureScreenPtr ps = GetPictureScreen (pScreen);
17825 : ps->totalGlyphPrivateSize = 0;
17826 : ps->glyphPrivateSizes = 0;
17827 : ps->glyphPrivateLen = 0;
17828 : ps->glyphPrivateOffset = -1;
17834 :GlyphFinishInit (ScreenPtr pScreen)
17836 : PictureScreenPtr ps = GetPictureScreen (pScreen);
17838 : if (ps->totalGlyphPrivateSize)
17843 : globalTotalGlyphPrivateSize += ps->totalGlyphPrivateSize;
17845 : for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++)
17847 : if (!globalGlyphs[fdepth].hashSet)
17850 : for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++)
17852 : glyph = globalGlyphs[fdepth].table[i].glyph;
17853 : if (glyph && glyph != DeletedGlyph)
17855 : if (!ReallocGlobalGlyphPrivate (glyph))
17861 : SetGlyphScreenPrivateOffsets ();
17863 : for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++)
17865 : if (!globalGlyphs[fdepth].hashSet)
17868 : for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++)
17870 : glyph = globalGlyphs[fdepth].table[i].glyph;
17871 : if (glyph && glyph != DeletedGlyph)
17873 : SetGlyphPrivatePointers (glyph);
17875 : if (!(*ps->RealizeGlyph) (pScreen, glyph))
17882 : ps->glyphPrivateOffset = 0;
17888 :GlyphUninit (ScreenPtr pScreen)
17890 : PictureScreenPtr ps = GetPictureScreen (pScreen);
17894 : globalTotalGlyphPrivateSize -= ps->totalGlyphPrivateSize;
17896 : for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++)
17898 : if (!globalGlyphs[fdepth].hashSet)
17901 : for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++)
17903 : glyph = globalGlyphs[fdepth].table[i].glyph;
17904 : if (glyph && glyph != DeletedGlyph)
17906 : (*ps->UnrealizeGlyph) (pScreen, glyph);
17908 : if (globalTotalGlyphPrivateSize)
17910 : if (!ReallocGlobalGlyphPrivate (glyph))
17915 : if (glyph->devPrivates)
17916 : xfree (glyph->devPrivates);
17917 : glyph->devPrivates = NULL;
17923 : if (globalTotalGlyphPrivateSize)
17924 : SetGlyphScreenPrivateOffsets ();
17926 : for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++)
17928 : if (!globalGlyphs[fdepth].hashSet)
17931 : for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++)
17933 : glyph = globalGlyphs[fdepth].table[i].glyph;
17934 : if (glyph && glyph != DeletedGlyph)
17936 : if (globalTotalGlyphPrivateSize)
17937 : SetGlyphPrivatePointers (glyph);
17942 : if (ps->glyphPrivateSizes)
17943 : xfree (ps->glyphPrivateSizes);
17947 :FindGlyphHashSet (CARD32 filled)
17951 : for (i = 0; i < NGLYPHHASHSETS; i++)
17952 : if (glyphHashSets[i].entries >= filled)
17953 : return &glyphHashSets[i];
17957 :static int _GlyphSetPrivateAllocateIndex = 0;
17960 :AllocateGlyphSetPrivateIndex (void)
17962 : return _GlyphSetPrivateAllocateIndex++;
17966 :ResetGlyphSetPrivateIndex (void)
17968 : _GlyphSetPrivateAllocateIndex = 0;
17972 :_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
17976 : if (n > glyphSet->maxPrivate) {
17977 : if (glyphSet->devPrivates &&
17978 : glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
17979 : new = (pointer *) xrealloc (glyphSet->devPrivates,
17980 : (n + 1) * sizeof (pointer));
17984 : new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
17987 : if (glyphSet->devPrivates)
17989 : glyphSet->devPrivates,
17990 : (glyphSet->maxPrivate + 1) * sizeof (pointer));
17992 : glyphSet->devPrivates = new;
17993 : /* Zero out new, uninitialize privates */
17994 : while (++glyphSet->maxPrivate < n)
17995 : glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
17997 : glyphSet->devPrivates[n] = ptr;
18002 :FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
18003 9 0.0098 :{ /* FindGlyphRef total: 88 0.0959 */
18004 : CARD32 elt, step, s;
18006 : GlyphRefPtr table, gr, del;
18007 2 0.0022 : CARD32 tableSize = hash->hashSet->size;
18009 1 0.0011 : table = hash->table;
18010 37 0.0403 : elt = signature % tableSize;
18015 6 0.0065 : gr = &table[elt];
18016 13 0.0142 : s = gr->signature;
18017 2 0.0022 : glyph = gr->glyph;
18018 5 0.0054 : if (!glyph)
18024 : if (glyph == DeletedGlyph)
18028 : else if (gr == del)
18031 2 0.0022 : else if (s == signature &&
18033 : memcmp (&compare->info, &glyph->info, compare->size) == 0))
18037 3 0.0033 : if (!step)
18039 1 0.0011 : step = signature % hash->hashSet->rehash;
18040 4 0.0044 : if (!step)
18044 : if (elt >= tableSize)
18045 : elt -= tableSize;
18051 :HashGlyph (GlyphPtr glyph)
18053 : CARD32 *bits = (CARD32 *) &(glyph->info);
18055 : int n = glyph->size / sizeof (CARD32);
18063 :#ifdef CHECK_DUPLICATES
18065 :DuplicateRef (GlyphPtr glyph, char *where)
18067 : ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
18071 :CheckDuplicates (GlyphHashPtr hash, char *where)
18076 : for (i = 0; i < hash->hashSet->size; i++)
18078 : g = hash->table[i].glyph;
18079 : if (!g || g == DeletedGlyph)
18081 : for (j = i + 1; j < hash->hashSet->size; j++)
18082 : if (hash->table[j].glyph == g)
18083 : DuplicateRef (g, where);
18087 :#define CheckDuplicates(a,b)
18088 :#define DuplicateRef(a,b)
18092 :FreeGlyph (GlyphPtr glyph, int format)
18094 : CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
18095 : if (--glyph->refcnt == 0)
18097 : PictureScreenPtr ps;
18103 : for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
18104 : if (globalGlyphs[format].table[i].glyph == glyph)
18107 : DuplicateRef (glyph, "FreeGlyph check");
18111 : gr = FindGlyphRef (&globalGlyphs[format],
18112 : HashGlyph (glyph), TRUE, glyph);
18113 : if (gr - globalGlyphs[format].table != first)
18114 : DuplicateRef (glyph, "Found wrong one");
18115 : if (gr->glyph && gr->glyph != DeletedGlyph)
18117 : gr->glyph = DeletedGlyph;
18118 : gr->signature = 0;
18119 : globalGlyphs[format].tableEntries--;
18122 : for (i = 0; i < screenInfo.numScreens; i++)
18124 : ps = GetPictureScreenIfSet (screenInfo.screens[i]);
18126 : (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
18129 : if (glyph->devPrivates)
18130 : xfree (glyph->devPrivates);
18136 :AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
18141 : CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
18142 : /* Locate existing matching glyph */
18143 : hash = HashGlyph (glyph);
18144 : gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
18145 : if (gr->glyph && gr->glyph != DeletedGlyph)
18147 : PictureScreenPtr ps;
18150 : for (i = 0; i < screenInfo.numScreens; i++)
18152 : ps = GetPictureScreenIfSet (screenInfo.screens[i]);
18154 : (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
18156 : if (glyph->devPrivates)
18157 : xfree (glyph->devPrivates);
18159 : glyph = gr->glyph;
18163 : gr->glyph = glyph;
18164 : gr->signature = hash;
18165 : globalGlyphs[glyphSet->fdepth].tableEntries++;
18168 : /* Insert/replace glyphset value */
18169 : gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
18171 : if (gr->glyph && gr->glyph != DeletedGlyph)
18172 : FreeGlyph (gr->glyph, glyphSet->fdepth);
18174 : glyphSet->hash.tableEntries++;
18175 : gr->glyph = glyph;
18176 : gr->signature = id;
18177 : CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
18181 :DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
18186 : gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
18187 : glyph = gr->glyph;
18188 : if (glyph && glyph != DeletedGlyph)
18190 : gr->glyph = DeletedGlyph;
18191 : glyphSet->hash.tableEntries--;
18192 : FreeGlyph (glyph, glyphSet->fdepth);
18199 :FindGlyph (GlyphSetPtr glyphSet, Glyph id)
18200 6 0.0065 :{ /* FindGlyph total: 15 0.0163 */
18203 3 0.0033 : glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
18204 2 0.0022 : if (glyph == DeletedGlyph)
18210 :AllocateGlyph (xGlyphInfo *gi, int fdepth)
18212 : PictureScreenPtr ps;
18217 : size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
18218 : glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
18221 : glyph->refcnt = 0;
18222 : glyph->size = size + sizeof (xGlyphInfo);
18223 : glyph->info = *gi;
18225 : if (globalTotalGlyphPrivateSize)
18227 : glyph->devPrivates = xalloc (globalTotalGlyphPrivateSize);
18228 : if (!glyph->devPrivates)
18231 : SetGlyphPrivatePointers (glyph);
18233 : glyph->devPrivates = NULL;
18235 : for (i = 0; i < screenInfo.numScreens; i++)
18237 : ps = GetPictureScreenIfSet (screenInfo.screens[i]);
18240 : if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph))
18244 : ps = GetPictureScreenIfSet (screenInfo.screens[i]);
18246 : (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
18249 : if (glyph->devPrivates)
18250 : xfree (glyph->devPrivates);
18261 :AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
18263 : hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
18264 : if (!hash->table)
18266 : memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
18267 : hash->hashSet = hashSet;
18268 : hash->tableEntries = 0;
18273 :ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
18275 : CARD32 tableEntries;
18276 : GlyphHashSetPtr hashSet;
18277 : GlyphHashRec newHash;
18284 : tableEntries = hash->tableEntries + change;
18285 : hashSet = FindGlyphHashSet (tableEntries);
18286 : if (hashSet == hash->hashSet)
18289 : CheckDuplicates (hash, "ResizeGlyphHash top");
18290 : if (!AllocateGlyphHash (&newHash, hashSet))
18294 : oldSize = hash->hashSet->size;
18295 : for (i = 0; i < oldSize; i++)
18297 : glyph = hash->table[i].glyph;
18298 : if (glyph && glyph != DeletedGlyph)
18300 : s = hash->table[i].signature;
18301 : gr = FindGlyphRef (&newHash, s, global, glyph);
18302 : gr->signature = s;
18303 : gr->glyph = glyph;
18304 : ++newHash.tableEntries;
18307 : xfree (hash->table);
18311 : CheckDuplicates (hash, "ResizeGlyphHash bottom");
18316 :ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
18318 : return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
18319 : ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
18323 :AllocateGlyphSet (int fdepth, PictFormatPtr format)
18325 : GlyphSetPtr glyphSet;
18328 : if (!globalGlyphs[fdepth].hashSet)
18330 : if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
18334 : size = (sizeof (GlyphSetRec) +
18335 : (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
18336 : glyphSet = xalloc (size);
18339 : bzero((char *)glyphSet, size);
18340 : glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
18341 : if (_GlyphSetPrivateAllocateIndex)
18342 : glyphSet->devPrivates = (pointer)(&glyphSet[1]);
18344 : if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
18346 : xfree (glyphSet);
18349 : glyphSet->refcnt = 1;
18350 : glyphSet->fdepth = fdepth;
18351 : glyphSet->format = format;
18356 :FreeGlyphSet (pointer value,
18359 : GlyphSetPtr glyphSet = (GlyphSetPtr) value;
18361 : if (--glyphSet->refcnt == 0)
18363 : CARD32 i, tableSize = glyphSet->hash.hashSet->size;
18364 : GlyphRefPtr table = glyphSet->hash.table;
18367 : for (i = 0; i < tableSize; i++)
18369 : glyph = table[i].glyph;
18370 : if (glyph && glyph != DeletedGlyph)
18371 : FreeGlyph (glyph, glyphSet->fdepth);
18373 : if (!globalGlyphs[glyphSet->fdepth].tableEntries)
18375 : xfree (globalGlyphs[glyphSet->fdepth].table);
18376 : globalGlyphs[glyphSet->fdepth].table = 0;
18377 : globalGlyphs[glyphSet->fdepth].hashSet = 0;
18380 : ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
18383 : if (glyphSet->devPrivates &&
18384 : glyphSet->devPrivates != (pointer)(&glyphSet[1]))
18385 : xfree(glyphSet->devPrivates);
18387 : xfree (glyphSet);
18392 * Total samples for file : "/home/cworth/src/xorg/xserver/Xext/xace.c"
18398 :/************************************************************
18400 :Author: Eamon Walsh <ewalsh@epoch.ncsc.mil>
18402 :Permission to use, copy, modify, distribute, and sell this software and its
18403 :documentation for any purpose is hereby granted without fee, provided that
18404 :this permission notice appear in supporting documentation. This permission
18405 :notice shall be included in all copies or substantial portions of the
18408 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18409 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18410 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18411 :AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18412 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18413 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18415 :********************************************************/
18417 :#ifdef HAVE_DIX_CONFIG_H
18418 :#include <dix-config.h>
18421 :#include <stdarg.h>
18422 :#include "windowstr.h"
18423 :#include "scrnintstr.h"
18424 :#include "gcstruct.h"
18425 :#include "xacestr.h"
18426 :#include "modinit.h"
18428 :CallbackListPtr XaceHooks[XACE_NUM_HOOKS] = {0};
18430 :/* Proc vectors for untrusted clients, swapped and unswapped versions.
18431 : * These are the same as the normal proc vectors except that extensions
18432 : * that haven't declared themselves secure will have ProcBadRequest plugged
18433 : * in for their major opcode dispatcher. This prevents untrusted clients
18434 : * from guessing extension major opcodes and using the extension even though
18435 : * the extension can't be listed or queried.
18437 :static int (*UntrustedProcVector[256])(
18438 : ClientPtr /*client*/
18440 :static int (*SwappedUntrustedProcVector[256])(
18441 : ClientPtr /*client*/
18444 :/* Entry point for hook functions. Called by Xserver.
18446 :int XaceHook(int hook, ...)
18447 22 0.0240 :{ /* XaceHook total: 74 0.0806 */
18448 : pointer calldata; /* data passed to callback */
18449 : int *prv = NULL; /* points to return value from callback */
18450 : va_list ap; /* argument list */
18451 8 0.0087 : va_start(ap, hook);
18453 : /* Marshal arguments for passing to callback.
18454 : * Each callback has its own case, which sets up a structure to hold
18455 : * the arguments and integer return parameter, or in some cases just
18456 : * sets calldata directly to a single argument (with no return result)
18458 7 0.0076 : switch (hook)
18460 : case XACE_CORE_DISPATCH: {
18461 : XaceCoreDispatchRec rec = {
18462 : va_arg(ap, ClientPtr),
18463 : TRUE /* default allow */
18469 : case XACE_RESOURCE_ACCESS: {
18470 : XaceResourceAccessRec rec = {
18471 : va_arg(ap, ClientPtr),
18473 : va_arg(ap, RESTYPE),
18474 : va_arg(ap, Mask),
18475 : va_arg(ap, pointer),
18476 : TRUE /* default allow */
18482 : case XACE_DEVICE_ACCESS: {
18483 : XaceDeviceAccessRec rec = {
18484 : va_arg(ap, ClientPtr),
18485 : va_arg(ap, DeviceIntPtr),
18486 : va_arg(ap, Bool),
18487 : TRUE /* default allow */
18493 : case XACE_PROPERTY_ACCESS: {
18494 : XacePropertyAccessRec rec = {
18495 : va_arg(ap, ClientPtr),
18496 : va_arg(ap, WindowPtr),
18497 : va_arg(ap, Atom),
18498 : va_arg(ap, Mask),
18499 : XaceAllowOperation /* default allow */
18505 : case XACE_DRAWABLE_ACCESS: {
18506 : XaceDrawableAccessRec rec = {
18507 : va_arg(ap, ClientPtr),
18508 : va_arg(ap, DrawablePtr),
18509 : TRUE /* default allow */
18515 : case XACE_MAP_ACCESS:
18516 : case XACE_BACKGRND_ACCESS: {
18517 : XaceMapAccessRec rec = {
18518 : va_arg(ap, ClientPtr),
18519 : va_arg(ap, WindowPtr),
18520 : TRUE /* default allow */
18526 : case XACE_EXT_DISPATCH:
18527 : case XACE_EXT_ACCESS: {
18528 : XaceExtAccessRec rec = {
18529 : va_arg(ap, ClientPtr),
18530 : va_arg(ap, ExtensionEntry*),
18531 : TRUE /* default allow */
18537 : case XACE_HOSTLIST_ACCESS: {
18538 : XaceHostlistAccessRec rec = {
18539 : va_arg(ap, ClientPtr),
18540 : va_arg(ap, Mask),
18541 : TRUE /* default allow */
18547 : case XACE_SITE_POLICY: {
18548 : XaceSitePolicyRec rec = {
18549 : va_arg(ap, char*),
18551 : FALSE /* default unrecognized */
18557 : case XACE_DECLARE_EXT_SECURE: {
18558 : XaceDeclareExtSecureRec rec = {
18559 : va_arg(ap, ExtensionEntry*),
18565 : case XACE_AUTH_AVAIL: {
18566 : XaceAuthAvailRec rec = {
18567 : va_arg(ap, ClientPtr),
18573 : case XACE_KEY_AVAIL: {
18574 : XaceKeyAvailRec rec = {
18575 : va_arg(ap, xEventPtr),
18576 : va_arg(ap, DeviceIntPtr),
18582 : case XACE_WINDOW_INIT: {
18583 : XaceWindowRec rec = {
18584 : va_arg(ap, ClientPtr),
18585 : va_arg(ap, WindowPtr)
18590 : case XACE_AUDIT_BEGIN: {
18591 : XaceAuditRec rec = {
18592 : va_arg(ap, ClientPtr),
18598 : case XACE_AUDIT_END: {
18599 : XaceAuditRec rec = {
18600 : va_arg(ap, ClientPtr),
18608 : return 0; /* unimplemented hook number */
18613 : /* call callbacks and return result, if any. */
18614 10 0.0109 : CallCallbacks(&XaceHooks[hook], calldata);
18615 4 0.0044 : return prv ? *prv : 0;
18619 :ProcXaceDispatch(ClientPtr client)
18623 : switch (stuff->data)
18626 : return BadRequest;
18628 :} /* ProcXaceDispatch */
18631 :SProcXaceDispatch(ClientPtr client)
18635 : switch (stuff->data)
18638 : return BadRequest;
18640 :} /* SProcXaceDispatch */
18646 : * extEntry is the extension information for the XACE extension.
18648 : * Returns: nothing.
18651 : * Performs any cleanup needed by XACE at server shutdown time.
18654 :XaceResetProc(ExtensionEntry *extEntry)
18658 : for (i=0; i<XACE_NUM_HOOKS; i++)
18660 : DeleteCallbackList(&XaceHooks[i]);
18661 : XaceHooks[i] = NULL;
18663 :} /* XaceResetProc */
18667 :XaceCatchDispatchProc(ClientPtr client)
18668 :{ /* XaceCatchDispatchProc total: 5 0.0054 */
18670 : int major = stuff->reqType;
18672 5 0.0054 : if (!ProcVector[major])
18673 : return (BadRequest);
18675 : if (!XaceHook(XACE_CORE_DISPATCH, client))
18676 : return (BadAccess);
18678 : return client->swapped ?
18679 : (* SwappedProcVector[major])(client) :
18680 : (* ProcVector[major])(client);
18684 :XaceCatchExtProc(ClientPtr client)
18685 4 0.0044 :{ /* XaceCatchExtProc total: 22 0.0240 */
18687 : int major = stuff->reqType;
18688 2 0.0022 : ExtensionEntry *ext = GetExtensionEntry(major);
18690 2 0.0022 : if (!ext || !ProcVector[major])
18691 : return (BadRequest);
18693 1 0.0011 : if (!XaceHook(XACE_EXT_DISPATCH, client, ext))
18694 : return (BadRequest); /* pretend extension doesn't exist */
18696 1 0.0011 : return client->swapped ?
18697 : (* SwappedProcVector[major])(client) :
18698 : (* ProcVector[major])(client);
18702 :/* SecurityClientStateCallback
18705 : * pcbl is &ClientStateCallback.
18706 : * nullata is NULL.
18707 : * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
18708 : * which contains information about client state changes.
18710 : * Returns: nothing.
18714 : * If a new client is connecting, its authorization ID is copied to
18715 : * client->authID. If this is a generated authorization, its reference
18716 : * count is bumped, its timer is cancelled if it was running, and its
18717 : * trustlevel is copied to TRUSTLEVEL(client).
18719 : * If a client is disconnecting and the client was using a generated
18720 : * authorization, the authorization's reference count is decremented, and
18721 : * if it is now zero, the timer for this authorization is started.
18725 :XaceClientStateCallback(
18726 : CallbackListPtr *pcbl,
18727 : pointer nulldata,
18728 : pointer calldata)
18730 : NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
18731 : ClientPtr client = pci->client;
18733 : switch (client->clientState)
18735 : case ClientStateRunning:
18737 : client->requestVector = client->swapped ?
18738 : SwappedUntrustedProcVector : UntrustedProcVector;
18743 :} /* XaceClientStateCallback */
18745 :/* XaceExtensionInit
18747 : * Initialize the XACE Extension
18749 :void XaceExtensionInit(INITARGS)
18751 : ExtensionEntry *extEntry;
18754 : if (!AddCallback(&ClientStateCallback, XaceClientStateCallback, NULL))
18757 : extEntry = AddExtension(XACE_EXTENSION_NAME,
18758 : XaceNumberEvents, XaceNumberErrors,
18759 : ProcXaceDispatch, SProcXaceDispatch,
18760 : XaceResetProc, StandardMinorOpcode);
18762 : /* initialize dispatching intercept functions */
18763 : for (i = 0; i < 128; i++)
18765 : UntrustedProcVector[i] = XaceCatchDispatchProc;
18766 : SwappedUntrustedProcVector[i] = XaceCatchDispatchProc;
18768 : for (i = 128; i < 256; i++)
18770 : UntrustedProcVector[i] = XaceCatchExtProc;
18771 : SwappedUntrustedProcVector[i] = XaceCatchExtProc;
18775 :/* XaceCensorImage
18777 : * Called after pScreen->GetImage to prevent pieces or trusted windows from
18778 : * being returned in image data from an untrusted window.
18781 : * client is the client doing the GetImage.
18782 : * pVisibleRegion is the visible region of the window.
18783 : * widthBytesLine is the width in bytes of one horizontal line in pBuf.
18784 : * pDraw is the source window.
18785 : * x, y, w, h is the rectangle of image data from pDraw in pBuf.
18786 : * format is the format of the image data in pBuf: ZPixmap or XYPixmap.
18787 : * pBuf is the image data.
18789 : * Returns: nothing.
18792 : * Any part of the rectangle (x, y, w, h) that is outside the visible
18793 : * region of the window will be destroyed (overwritten) in pBuf.
18796 :XaceCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y, w, h,
18798 : ClientPtr client;
18799 : RegionPtr pVisibleRegion;
18800 : long widthBytesLine;
18801 : DrawablePtr pDraw;
18803 : unsigned int format;
18806 : ScreenPtr pScreen;
18807 : RegionRec imageRegion; /* region representing x,y,w,h */
18808 : RegionRec censorRegion; /* region to obliterate */
18812 : pScreen = pDraw->pScreen;
18816 : imageBox.x2 = x + w;
18817 : imageBox.y2 = y + h;
18818 : REGION_INIT(pScreen, &imageRegion, &imageBox, 1);
18819 : REGION_NULL(pScreen, &censorRegion);
18821 : /* censorRegion = imageRegion - visibleRegion */
18822 : REGION_SUBTRACT(pScreen, &censorRegion, &imageRegion, pVisibleRegion);
18823 : nRects = REGION_NUM_RECTS(&censorRegion);
18825 : { /* we have something to censor */
18826 : GCPtr pScratchGC = NULL;
18827 : PixmapPtr pPix = NULL;
18828 : xRectangle *pRects = NULL;
18829 : Bool failed = FALSE;
18831 : int bitsPerPixel = 1;
18835 : /* convert region to list-of-rectangles for PolyFillRect */
18837 : pRects = (xRectangle *)ALLOCATE_LOCAL(nRects * sizeof(xRectangle *));
18843 : for (pBox = REGION_RECTS(&censorRegion), i = 0;
18847 : pRects[i].x = pBox->x1;
18848 : pRects[i].y = pBox->y1 - imageBox.y1;
18849 : pRects[i].width = pBox->x2 - pBox->x1;
18850 : pRects[i].height = pBox->y2 - pBox->y1;
18853 : /* use pBuf as a fake pixmap */
18855 : if (format == ZPixmap)
18857 : depth = pDraw->depth;
18858 : bitsPerPixel = pDraw->bitsPerPixel;
18861 : pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
18862 : depth, bitsPerPixel,
18863 : widthBytesLine, (pointer)pBuf);
18870 : pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
18877 : ValidateGC(&pPix->drawable, pScratchGC);
18878 : (* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
18879 : pScratchGC, nRects, pRects);
18884 : /* Censoring was not completed above. To be safe, wipe out
18885 : * all the image data so that nothing trusted gets out.
18887 : bzero(pBuf, (int)(widthBytesLine * h));
18889 : if (pRects) DEALLOCATE_LOCAL(pRects);
18890 : if (pScratchGC) FreeScratchGC(pScratchGC);
18891 : if (pPix) FreeScratchPixmapHeader(pPix);
18893 : REGION_UNINIT(pScreen, &imageRegion);
18894 : REGION_UNINIT(pScreen, &censorRegion);
18895 :} /* XaceCensorImage */
18897 * Total samples for file : "/home/cworth/src/xorg/xserver/dix/dixutils.c"
18903 :/***********************************************************
18905 :Copyright 1987, 1998 The Open Group
18907 :Permission to use, copy, modify, distribute, and sell this software and its
18908 :documentation for any purpose is hereby granted without fee, provided that
18909 :the above copyright notice appear in all copies and that both that
18910 :copyright notice and this permission notice appear in supporting
18913 :The above copyright notice and this permission notice shall be included in
18914 :all copies or substantial portions of the Software.
18916 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18917 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18918 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18919 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18920 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18921 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18923 :Except as contained in this notice, the name of The Open Group shall not be
18924 :used in advertising or otherwise to promote the sale, use or other dealings
18925 :in this Software without prior written authorization from The Open Group.
18928 :Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
18930 : All Rights Reserved
18932 :Permission to use, copy, modify, and distribute this software and its
18933 :documentation for any purpose and without fee is hereby granted,
18934 :provided that the above copyright notice appear in all copies and that
18935 :both that copyright notice and this permission notice appear in
18936 :supporting documentation, and that the name of Digital not be
18937 :used in advertising or publicity pertaining to distribution of the
18938 :software without specific, written prior permission.
18940 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18941 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
18942 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18943 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18944 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
18945 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
18948 :******************************************************************/
18952 :(c)Copyright 1988,1991 Adobe Systems Incorporated. All rights reserved.
18954 :Permission to use, copy, modify, distribute, and sublicense this software and its
18955 :documentation for any purpose and without fee is hereby granted, provided that
18956 :the above copyright notices appear in all copies and that both those copyright
18957 :notices and this permission notice appear in supporting documentation and that
18958 :the name of Adobe Systems Incorporated not be used in advertising or publicity
18959 :pertaining to distribution of the software without specific, written prior
18960 :permission. No trademark license to use the Adobe trademarks is hereby
18961 :granted. If the Adobe trademark "Display PostScript"(tm) is used to describe
18962 :this software, its functionality or for any other purpose, such use shall be
18963 :limited to a statement that this software works in conjunction with the Display
18964 :PostScript system. Proper trademark attribution to reflect Adobe's ownership
18965 :of the trademark shall be given whenever any such reference to the Display
18966 :PostScript system is made.
18968 :ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY
18969 :PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ADOBE
18970 :DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
18971 :WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
18972 :INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE TO YOU
18973 :OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
18974 :DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,NEGLIGENCE, STRICT
18975 :LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18976 :PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER
18977 :SUPPORT FOR THE SOFTWARE.
18979 :Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
18980 :Incorporated which may be registered in certain jurisdictions.
18982 :Author: Adobe Systems Incorporated
18987 :#ifdef HAVE_DIX_CONFIG_H
18988 :#include <dix-config.h>
18991 :#include <X11/X.h>
18992 :#include <X11/Xmd.h>
18994 :#include "windowstr.h"
18995 :#include "dixstruct.h"
18996 :#include "pixmapstr.h"
18997 :#include "scrnintstr.h"
18999 :#include <X11/keysymdef.h>
19003 : * CompareTimeStamps returns -1, 0, or +1 depending on if the first
19004 : * argument is less than, equal to or greater than the second argument.
19008 :CompareTimeStamps(TimeStamp a, TimeStamp b)
19010 : if (a.months < b.months)
19012 : if (a.months > b.months)
19014 : if (a.milliseconds < b.milliseconds)
19016 : if (a.milliseconds > b.milliseconds)
19022 : * convert client times to server TimeStamps
19025 :#define HALFMONTH ((unsigned long) 1<<31)
19026 :_X_EXPORT TimeStamp
19027 :ClientTimeToServerTime(CARD32 c)
19030 : if (c == CurrentTime)
19031 : return currentTime;
19032 : ts.months = currentTime.months;
19033 : ts.milliseconds = c;
19034 : if (c > currentTime.milliseconds)
19036 : if (((unsigned long) c - currentTime.milliseconds) > HALFMONTH)
19039 : else if (c < currentTime.milliseconds)
19041 : if (((unsigned long)currentTime.milliseconds - c) > HALFMONTH)
19048 : * ISO Latin-1 case conversion routine
19050 : * this routine always null-terminates the result, so
19051 : * beware of too-small buffers
19054 :static unsigned char
19055 :ISOLatin1ToLower (unsigned char source)
19057 : unsigned char dest;
19058 : if ((source >= XK_A) && (source <= XK_Z))
19059 : dest = source + (XK_a - XK_A);
19060 : else if ((source >= XK_Agrave) && (source <= XK_Odiaeresis))
19061 : dest = source + (XK_agrave - XK_Agrave);
19062 : else if ((source >= XK_Ooblique) && (source <= XK_Thorn))
19063 : dest = source + (XK_oslash - XK_Ooblique);
19071 :CopyISOLatin1Lowered(unsigned char *dest, unsigned char *source, int length)
19075 : for (i = 0; i < length; i++, source++, dest++)
19076 : *dest = ISOLatin1ToLower (*source);
19081 :CompareISOLatin1Lowered(unsigned char *s1, int s1len,
19082 : unsigned char *s2, int s2len)
19083 1 0.0011 :{ /* CompareISOLatin1Lowered total: 22 0.0240 */
19084 : unsigned char c1, c2;
19088 : /* note -- compare against zero so that -1 ignores len */
19089 8 0.0087 : c1 = s1len-- ? *s1++ : '\0';
19090 10 0.0109 : c2 = s2len-- ? *s2++ : '\0';
19091 3 0.0033 : if (!c1 ||
19093 : (c1 = ISOLatin1ToLower (c1)) != (c2 = ISOLatin1ToLower (c2))))
19096 : return (int) c1 - (int) c2;
19100 : * dixLookupWindow and dixLookupDrawable:
19101 : * Look up the window/drawable taking into account the client doing the
19102 : * lookup, the type of drawable desired, and the type of access desired.
19103 : * Return Success with *pDraw set if the window/drawable exists and the client
19104 : * is allowed access, else return an error code with *pDraw set to NULL. The
19105 : * access mask values are defined in resource.h. The type mask values are
19106 : * defined in pixmap.h, with zero equivalent to M_DRAWABLE.
19109 :dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client,
19110 : Mask type, Mask access)
19111 1 0.0011 :{ /* dixLookupDrawable total: 6 0.0065 */
19112 : DrawablePtr pTmp;
19115 : client->errorValue = id;
19117 : if (id == INVALID)
19118 : return BadDrawable;
19120 : if (id == client->lastDrawableID) {
19121 : pTmp = client->lastDrawable;
19123 : /* an access check is required for cached drawables */
19124 : rtype = (type & M_WINDOW) ? RT_WINDOW : RT_PIXMAP;
19125 : if (!XaceHook(XACE_RESOURCE_ACCESS, client, id, rtype, access, pTmp))
19126 : return BadDrawable;
19128 : pTmp = (DrawablePtr)SecurityLookupIDByClass(client, id, RC_DRAWABLE,
19131 : return BadDrawable;
19132 3 0.0033 : if (!((1 << pTmp->type) & (type ? type : M_DRAWABLE)))
19135 : if (type & M_DRAWABLE) {
19136 : client->lastDrawable = pTmp;
19137 : client->lastDrawableID = id;
19138 : client->lastGCID = INVALID;
19139 : client->lastGC = (GCPtr)NULL;
19146 :dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access)
19149 : rc = dixLookupDrawable((DrawablePtr*)pWin, id, client, M_WINDOW, access);
19150 : return (rc == BadDrawable) ? BadWindow : rc;
19154 :dixLookupGC(GCPtr *pGC, XID id, ClientPtr client, Mask access)
19155 1 0.0011 :{ /* dixLookupGC total: 2 0.0022 */
19156 1 0.0011 : GCPtr pTmp = (GCPtr)SecurityLookupIDByType(client, id, RT_GC, access);
19161 : client->errorValue = id;
19167 :dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access)
19169 : pointer pRes = (pointer)SecurityLookupIDByClass(client, rid, RC_ANY,
19171 : int clientIndex = CLIENT_ID(rid);
19172 : client->errorValue = rid;
19174 : if (clientIndex && pRes && clients[clientIndex] && !(rid & SERVER_BIT)) {
19175 : *pClient = clients[clientIndex];
19183 : * These are deprecated compatibility functions and will be removed soon!
19184 : * Please use the new dixLookup*() functions above.
19186 :_X_EXPORT _X_DEPRECATED WindowPtr
19187 :SecurityLookupWindow(XID id, ClientPtr client, Mask access_mode)
19190 : int i = dixLookupWindow(&pWin, id, client, access_mode);
19191 : static int warn = 1;
19193 : ErrorF("Warning: LookupWindow()/SecurityLookupWindow() "
19194 : "are deprecated. Please convert your driver/module "
19195 : "to use dixLookupWindow().\n");
19196 : return (i == Success) ? pWin : NULL;
19199 :_X_EXPORT _X_DEPRECATED WindowPtr
19200 :LookupWindow(XID id, ClientPtr client)
19202 : return SecurityLookupWindow(id, client, DixUnknownAccess);
19205 :_X_EXPORT _X_DEPRECATED pointer
19206 :SecurityLookupDrawable(XID id, ClientPtr client, Mask access_mode)
19208 : DrawablePtr pDraw;
19209 : int i = dixLookupDrawable(&pDraw, id, client, M_DRAWABLE, access_mode);
19210 : static int warn = 1;
19212 : ErrorF("Warning: LookupDrawable()/SecurityLookupDrawable() "
19213 : "are deprecated. Please convert your driver/module "
19214 : "to use dixLookupDrawable().\n");
19215 : return (i == Success) ? pDraw : NULL;
19218 :_X_EXPORT _X_DEPRECATED pointer
19219 :LookupDrawable(XID id, ClientPtr client)
19221 : return SecurityLookupDrawable(id, client, DixUnknownAccess);
19224 :_X_EXPORT _X_DEPRECATED ClientPtr
19225 :LookupClient(XID id, ClientPtr client)
19227 : ClientPtr pClient;
19228 : int i = dixLookupClient(&pClient, id, client, DixUnknownAccess);
19229 : static int warn = 1;
19231 : ErrorF("Warning: LookupClient() is deprecated. Please convert your "
19232 : "driver/module to use dixLookupClient().\n");
19233 : return (i == Success) ? pClient : NULL;
19236 :/* end deprecated functions */
19239 :AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode,
19240 : Bool toRoot, Bool remap)
19243 : SaveSetElt *pTmp = NULL;
19246 : numnow = client->numSaved;
19250 : pTmp = client->saveSet;
19251 : while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (pointer)pWin))
19254 : if (mode == SetModeInsert)
19256 : if (j < numnow) /* duplicate */
19259 : pTmp = (SaveSetElt *)xrealloc(client->saveSet, sizeof(*pTmp) * numnow);
19261 : return(BadAlloc);
19262 : client->saveSet = pTmp;
19263 : client->numSaved = numnow;
19264 : SaveSetAssignWindow(client->saveSet[numnow - 1], pWin);
19265 : SaveSetAssignToRoot(client->saveSet[numnow - 1], toRoot);
19266 : SaveSetAssignRemap(client->saveSet[numnow - 1], remap);
19269 : else if ((mode == SetModeDelete) && (j < numnow))
19271 : while (j < numnow-1)
19273 : pTmp[j] = pTmp[j+1];
19279 : pTmp = (SaveSetElt *)xrealloc(client->saveSet, sizeof(*pTmp) * numnow);
19281 : client->saveSet = pTmp;
19285 : xfree(client->saveSet);
19286 : client->saveSet = (SaveSetElt *)NULL;
19288 : client->numSaved = numnow;
19295 :DeleteWindowFromAnySaveSet(WindowPtr pWin)
19298 : ClientPtr client;
19300 : for (i = 0; i< currentMaxClients; i++)
19302 : client = clients[i];
19303 : if (client && client->numSaved)
19304 : (void)AlterSaveSetForClient(client, pWin, SetModeDelete, FALSE, TRUE);
19308 :/* No-op Don't Do Anything : sometimes we need to be able to call a procedure
19309 : * that doesn't do anything. For example, on screen with only static
19310 : * colormaps, if someone calls install colormap, it's easier to have a dummy
19311 : * procedure to call than to check if there's a procedure
19318 :typedef struct _BlockHandler {
19319 : BlockHandlerProcPtr BlockHandler;
19320 : WakeupHandlerProcPtr WakeupHandler;
19321 : pointer blockData;
19323 :} BlockHandlerRec, *BlockHandlerPtr;
19325 :static BlockHandlerPtr handlers;
19326 :static int numHandlers;
19327 :static int sizeHandlers;
19328 :static Bool inHandler;
19329 :static Bool handlerDeleted;
19333 : * \param pTimeout DIX doesn't want to know how OS represents time
19334 : * \param pReadMask nor how it represents the det of descriptors
19337 :BlockHandler(pointer pTimeout, pointer pReadmask)
19342 : for (i = 0; i < screenInfo.numScreens; i++)
19343 : (* screenInfo.screens[i]->BlockHandler)(i,
19344 : screenInfo.screens[i]->blockData,
19345 : pTimeout, pReadmask);
19346 : for (i = 0; i < numHandlers; i++)
19347 : (*handlers[i].BlockHandler) (handlers[i].blockData,
19348 : pTimeout, pReadmask);
19349 : if (handlerDeleted)
19351 : for (i = 0; i < numHandlers;)
19352 : if (handlers[i].deleted)
19354 : for (j = i; j < numHandlers - 1; j++)
19355 : handlers[j] = handlers[j+1];
19360 : handlerDeleted = FALSE;
19367 : * \param result 32 bits of undefined result from the wait
19368 : * \param pReadmask the resulting descriptor mask
19371 :WakeupHandler(int result, pointer pReadmask)
19376 : for (i = numHandlers - 1; i >= 0; i--)
19377 : (*handlers[i].WakeupHandler) (handlers[i].blockData,
19378 : result, pReadmask);
19379 : for (i = 0; i < screenInfo.numScreens; i++)
19380 : (* screenInfo.screens[i]->WakeupHandler)(i,
19381 : screenInfo.screens[i]->wakeupData,
19382 : result, pReadmask);
19383 : if (handlerDeleted)
19385 : for (i = 0; i < numHandlers;)
19386 : if (handlers[i].deleted)
19388 : for (j = i; j < numHandlers - 1; j++)
19389 : handlers[j] = handlers[j+1];
19394 : handlerDeleted = FALSE;
19400 : * Reentrant with BlockHandler and WakeupHandler, except wakeup won't
19401 : * get called until next time
19404 :RegisterBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
19405 : WakeupHandlerProcPtr wakeupHandler,
19406 : pointer blockData)
19408 : BlockHandlerPtr new;
19410 : if (numHandlers >= sizeHandlers)
19412 : new = (BlockHandlerPtr) xrealloc (handlers, (numHandlers + 1) *
19413 : sizeof (BlockHandlerRec));
19417 : sizeHandlers = numHandlers + 1;
19419 : handlers[numHandlers].BlockHandler = blockHandler;
19420 : handlers[numHandlers].WakeupHandler = wakeupHandler;
19421 : handlers[numHandlers].blockData = blockData;
19422 : handlers[numHandlers].deleted = FALSE;
19423 : numHandlers = numHandlers + 1;
19428 :RemoveBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
19429 : WakeupHandlerProcPtr wakeupHandler,
19430 : pointer blockData)
19434 : for (i = 0; i < numHandlers; i++)
19435 : if (handlers[i].BlockHandler == blockHandler &&
19436 : handlers[i].WakeupHandler == wakeupHandler &&
19437 : handlers[i].blockData == blockData)
19441 : handlerDeleted = TRUE;
19442 : handlers[i].deleted = TRUE;
19446 : for (; i < numHandlers - 1; i++)
19447 : handlers[i] = handlers[i+1];
19455 :InitBlockAndWakeupHandlers (void)
19457 : xfree (handlers);
19458 : handlers = (BlockHandlerPtr) 0;
19460 : sizeHandlers = 0;
19464 : * A general work queue. Perform some task before the server
19465 : * sleeps for input.
19468 :WorkQueuePtr workQueue;
19469 :static WorkQueuePtr *workQueueLast = &workQueue;
19472 :ProcessWorkQueue(void)
19474 : WorkQueuePtr q, *p;
19478 : * Scan the work queue once, calling each function. Those
19479 : * which return TRUE are removed from the queue, otherwise
19480 : * they will be called again. This must be reentrant with
19485 : if ((*q->function) (q->client, q->closure))
19487 : /* remove q from the list */
19488 : *p = q->next; /* don't fetch until after func called */
19493 : p = &q->next; /* don't fetch until after func called */
19496 : workQueueLast = p;
19500 :ProcessWorkQueueZombies(void)
19502 : WorkQueuePtr q, *p;
19507 : if (q->client && q->client->clientGone)
19509 : (void) (*q->function) (q->client, q->closure);
19510 : /* remove q from the list */
19511 : *p = q->next; /* don't fetch until after func called */
19516 : p = &q->next; /* don't fetch until after func called */
19519 : workQueueLast = p;
19524 : Bool (*function)(ClientPtr /* pClient */, pointer /* closure */),
19525 : ClientPtr client, pointer closure)
19529 : q = (WorkQueuePtr) xalloc (sizeof *q);
19532 : q->function = function;
19533 : q->client = client;
19534 : q->closure = closure;
19536 : *workQueueLast = q;
19537 : workQueueLast = &q->next;
19542 : * Manage a queue of sleeping clients, awakening them
19543 : * when requested, by using the OS functions IgnoreClient
19544 : * and AttendClient. Note that this *ignores* the troubles
19545 : * with request data interleaving itself with events, but
19546 : * we'll leave that until a later time.
19549 :typedef struct _SleepQueue {
19550 : struct _SleepQueue *next;
19551 : ClientPtr client;
19552 : ClientSleepProcPtr function;
19554 :} SleepQueueRec, *SleepQueuePtr;
19556 :static SleepQueuePtr sleepQueue = NULL;
19559 :ClientSleep (ClientPtr client, ClientSleepProcPtr function, pointer closure)
19563 : q = (SleepQueuePtr) xalloc (sizeof *q);
19567 : IgnoreClient (client);
19568 : q->next = sleepQueue;
19569 : q->client = client;
19570 : q->function = function;
19571 : q->closure = closure;
19577 :ClientSignal (ClientPtr client)
19581 : for (q = sleepQueue; q; q = q->next)
19582 : if (q->client == client)
19584 : return QueueWorkProc (q->function, q->client, q->closure);
19590 :ClientWakeup (ClientPtr client)
19592 : SleepQueuePtr q, *prev;
19594 : prev = &sleepQueue;
19595 : while ( (q = *prev) )
19597 : if (q->client == client)
19601 : if (client->clientGone)
19602 : /* Oops -- new zombie cleanup code ensures this only
19603 : * happens from inside CloseDownClient; don't want to
19604 : * recurse here...
19606 : /* CloseDownClient(client) */;
19608 : AttendClient (client);
19616 :ClientIsAsleep (ClientPtr client)
19620 : for (q = sleepQueue; q; q = q->next)
19621 : if (q->client == client)
19627 : * Generic Callback Manager
19630 :/* ===== Private Procedures ===== */
19632 :static int numCallbackListsToCleanup = 0;
19633 :static CallbackListPtr **listsToCleanup = NULL;
19637 : CallbackListPtr *pcbl,
19638 : CallbackProcPtr callback,
19643 : cbr = (CallbackPtr) xalloc(sizeof(CallbackRec));
19646 : cbr->proc = callback;
19647 : cbr->data = data;
19648 : cbr->next = (*pcbl)->list;
19649 : cbr->deleted = FALSE;
19650 : (*pcbl)->list = cbr;
19656 : CallbackListPtr *pcbl,
19657 : CallbackProcPtr callback,
19660 : CallbackListPtr cbl = *pcbl;
19661 : CallbackPtr cbr, pcbr;
19663 : for (pcbr = NULL, cbr = cbl->list;
19665 : pcbr = cbr, cbr = cbr->next)
19667 : if ((cbr->proc == callback) && (cbr->data == data))
19672 : if (cbl->inCallback)
19674 : ++(cbl->numDeleted);
19675 : cbr->deleted = TRUE;
19679 : if (pcbr == NULL)
19680 : cbl->list = cbr->next;
19682 : pcbr->next = cbr->next;
19692 : CallbackListPtr *pcbl,
19693 : pointer call_data)
19694 17 0.0185 :{ /* _CallCallbacks total: 30 0.0327 */
19695 : CallbackListPtr cbl = *pcbl;
19696 : CallbackPtr cbr, pcbr;
19698 3 0.0033 : ++(cbl->inCallback);
19699 3 0.0033 : for (cbr = cbl->list; cbr != NULL; cbr = cbr->next)
19701 6 0.0065 : (*(cbr->proc)) (pcbl, cbr->data, call_data);
19703 : --(cbl->inCallback);
19705 : if (cbl->inCallback) return;
19707 : /* Was the entire list marked for deletion? */
19709 1 0.0011 : if (cbl->deleted)
19711 : DeleteCallbackList(pcbl);
19715 : /* Were some individual callbacks on the list marked for deletion?
19716 : * If so, do the deletions.
19719 : if (cbl->numDeleted)
19721 : for (pcbr = NULL, cbr = cbl->list; (cbr != NULL) && cbl->numDeleted; )
19723 : if (cbr->deleted)
19728 : xfree(pcbr->next);
19729 : pcbr->next = cbr;
19733 : xfree(cbl->list);
19736 : cbl->numDeleted--;
19738 : else /* this one wasn't deleted */
19748 :_DeleteCallbackList(
19749 : CallbackListPtr *pcbl)
19751 : CallbackListPtr cbl = *pcbl;
19752 : CallbackPtr cbr, nextcbr;
19755 : if (cbl->inCallback)
19757 : cbl->deleted = TRUE;
19761 : for (i = 0; i < numCallbackListsToCleanup; i++)
19763 : if ((listsToCleanup[i] = pcbl) != 0)
19765 : listsToCleanup[i] = NULL;
19770 : for (cbr = cbl->list; cbr != NULL; cbr = nextcbr)
19772 : nextcbr = cbr->next;
19779 :static CallbackFuncsRec default_cbfuncs =
19784 : _DeleteCallbackList
19788 :CreateCallbackList(CallbackListPtr *pcbl, CallbackFuncsPtr cbfuncs)
19790 : CallbackListPtr cbl;
19793 : if (!pcbl) return FALSE;
19794 : cbl = (CallbackListPtr) xalloc(sizeof(CallbackListRec));
19795 : if (!cbl) return FALSE;
19796 : cbl->funcs = cbfuncs ? *cbfuncs : default_cbfuncs;
19797 : cbl->inCallback = 0;
19798 : cbl->deleted = FALSE;
19799 : cbl->numDeleted = 0;
19800 : cbl->list = NULL;
19803 : for (i = 0; i < numCallbackListsToCleanup; i++)
19805 : if (!listsToCleanup[i])
19807 : listsToCleanup[i] = pcbl;
19812 : listsToCleanup = (CallbackListPtr **)xnfrealloc(listsToCleanup,
19813 : sizeof(CallbackListPtr *) * (numCallbackListsToCleanup+1));
19814 : listsToCleanup[numCallbackListsToCleanup] = pcbl;
19815 : numCallbackListsToCleanup++;
19819 :/* ===== Public Procedures ===== */
19822 :AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
19824 : if (!pcbl) return FALSE;
19826 : { /* list hasn't been created yet; go create it */
19827 : if (!CreateCallbackList(pcbl, (CallbackFuncsPtr)NULL))
19830 : return ((*(*pcbl)->funcs.AddCallback) (pcbl, callback, data));
19834 :DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, pointer data)
19836 : if (!pcbl || !*pcbl) return FALSE;
19837 : return ((*(*pcbl)->funcs.DeleteCallback) (pcbl, callback, data));
19841 :CallCallbacks(CallbackListPtr *pcbl, pointer call_data)
19842 6 0.0065 :{ /* CallCallbacks total: 27 0.0294 */
19843 10 0.0109 : if (!pcbl || !*pcbl) return;
19844 5 0.0054 : (*(*pcbl)->funcs.CallCallbacks) (pcbl, call_data);
19848 :DeleteCallbackList(CallbackListPtr *pcbl)
19850 : if (!pcbl || !*pcbl) return;
19851 : (*(*pcbl)->funcs.DeleteCallbackList) (pcbl);
19855 :InitCallbackManager(void)
19859 : for (i = 0; i < numCallbackListsToCleanup; i++)
19861 : DeleteCallbackList(listsToCleanup[i]);
19863 : if (listsToCleanup) xfree(listsToCleanup);
19865 : numCallbackListsToCleanup = 0;
19866 : listsToCleanup = NULL;
19869 * Total samples for file : "/home/cworth/src/xorg/xserver/render/render.c"
19877 : * Copyright © 2000 SuSE, Inc.
19879 : * Permission to use, copy, modify, distribute, and sell this software and its
19880 : * documentation for any purpose is hereby granted without fee, provided that
19881 : * the above copyright notice appear in all copies and that both that
19882 : * copyright notice and this permission notice appear in supporting
19883 : * documentation, and that the name of SuSE not be used in advertising or
19884 : * publicity pertaining to distribution of the software without specific,
19885 : * written prior permission. SuSE makes no representations about the
19886 : * suitability of this software for any purpose. It is provided "as is"
19887 : * without express or implied warranty.
19889 : * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19890 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
19891 : * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19892 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19893 : * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19894 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19896 : * Author: Keith Packard, SuSE, Inc.
19899 :#define NEED_REPLIES
19900 :#define NEED_EVENTS
19901 :#ifdef HAVE_DIX_CONFIG_H
19902 :#include <dix-config.h>
19905 :#include <X11/X.h>
19906 :#include <X11/Xproto.h>
19909 :#include "dixstruct.h"
19910 :#include "resource.h"
19911 :#include "scrnintstr.h"
19912 :#include "windowstr.h"
19913 :#include "pixmapstr.h"
19914 :#include "colormapst.h"
19915 :#include "extnsionst.h"
19916 :#include "servermd.h"
19917 :#include <X11/extensions/render.h>
19918 :#include <X11/extensions/renderproto.h>
19919 :#include "picturestr.h"
19920 :#include "glyphstr.h"
19921 :#include <X11/Xfuncproto.h>
19922 :#include "cursorstr.h"
19925 :#include <stdint.h>
19926 :#elif !defined(UINT32_MAX)
19927 :#define UINT32_MAX 0xffffffffU
19930 :static int ProcRenderQueryVersion (ClientPtr pClient);
19931 :static int ProcRenderQueryPictFormats (ClientPtr pClient);
19932 :static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
19933 :static int ProcRenderQueryDithers (ClientPtr pClient);
19934 :static int ProcRenderCreatePicture (ClientPtr pClient);
19935 :static int ProcRenderChangePicture (ClientPtr pClient);
19936 :static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
19937 :static int ProcRenderFreePicture (ClientPtr pClient);
19938 :static int ProcRenderComposite (ClientPtr pClient);
19939 :static int ProcRenderScale (ClientPtr pClient);
19940 :static int ProcRenderTrapezoids (ClientPtr pClient);
19941 :static int ProcRenderTriangles (ClientPtr pClient);
19942 :static int ProcRenderTriStrip (ClientPtr pClient);
19943 :static int ProcRenderTriFan (ClientPtr pClient);
19944 :static int ProcRenderColorTrapezoids (ClientPtr pClient);
19945 :static int ProcRenderColorTriangles (ClientPtr pClient);
19946 :static int ProcRenderTransform (ClientPtr pClient);
19947 :static int ProcRenderCreateGlyphSet (ClientPtr pClient);
19948 :static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
19949 :static int ProcRenderFreeGlyphSet (ClientPtr pClient);
19950 :static int ProcRenderAddGlyphs (ClientPtr pClient);
19951 :static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
19952 :static int ProcRenderFreeGlyphs (ClientPtr pClient);
19953 :static int ProcRenderCompositeGlyphs (ClientPtr pClient);
19954 :static int ProcRenderFillRectangles (ClientPtr pClient);
19955 :static int ProcRenderCreateCursor (ClientPtr pClient);
19956 :static int ProcRenderSetPictureTransform (ClientPtr pClient);
19957 :static int ProcRenderQueryFilters (ClientPtr pClient);
19958 :static int ProcRenderSetPictureFilter (ClientPtr pClient);
19959 :static int ProcRenderCreateAnimCursor (ClientPtr pClient);
19960 :static int ProcRenderAddTraps (ClientPtr pClient);
19961 :static int ProcRenderCreateSolidFill (ClientPtr pClient);
19962 :static int ProcRenderCreateLinearGradient (ClientPtr pClient);
19963 :static int ProcRenderCreateRadialGradient (ClientPtr pClient);
19964 :static int ProcRenderCreateConicalGradient (ClientPtr pClient);
19966 :static int ProcRenderDispatch (ClientPtr pClient);
19968 :static int SProcRenderQueryVersion (ClientPtr pClient);
19969 :static int SProcRenderQueryPictFormats (ClientPtr pClient);
19970 :static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
19971 :static int SProcRenderQueryDithers (ClientPtr pClient);
19972 :static int SProcRenderCreatePicture (ClientPtr pClient);
19973 :static int SProcRenderChangePicture (ClientPtr pClient);
19974 :static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
19975 :static int SProcRenderFreePicture (ClientPtr pClient);
19976 :static int SProcRenderComposite (ClientPtr pClient);
19977 :static int SProcRenderScale (ClientPtr pClient);
19978 :static int SProcRenderTrapezoids (ClientPtr pClient);
19979 :static int SProcRenderTriangles (ClientPtr pClient);
19980 :static int SProcRenderTriStrip (ClientPtr pClient);
19981 :static int SProcRenderTriFan (ClientPtr pClient);
19982 :static int SProcRenderColorTrapezoids (ClientPtr pClient);
19983 :static int SProcRenderColorTriangles (ClientPtr pClient);
19984 :static int SProcRenderTransform (ClientPtr pClient);
19985 :static int SProcRenderCreateGlyphSet (ClientPtr pClient);
19986 :static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
19987 :static int SProcRenderFreeGlyphSet (ClientPtr pClient);
19988 :static int SProcRenderAddGlyphs (ClientPtr pClient);
19989 :static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
19990 :static int SProcRenderFreeGlyphs (ClientPtr pClient);
19991 :static int SProcRenderCompositeGlyphs (ClientPtr pClient);
19992 :static int SProcRenderFillRectangles (ClientPtr pClient);
19993 :static int SProcRenderCreateCursor (ClientPtr pClient);
19994 :static int SProcRenderSetPictureTransform (ClientPtr pClient);
19995 :static int SProcRenderQueryFilters (ClientPtr pClient);
19996 :static int SProcRenderSetPictureFilter (ClientPtr pClient);
19997 :static int SProcRenderCreateAnimCursor (ClientPtr pClient);
19998 :static int SProcRenderAddTraps (ClientPtr pClient);
19999 :static int SProcRenderCreateSolidFill (ClientPtr pClient);
20000 :static int SProcRenderCreateLinearGradient (ClientPtr pClient);
20001 :static int SProcRenderCreateRadialGradient (ClientPtr pClient);
20002 :static int SProcRenderCreateConicalGradient (ClientPtr pClient);
20004 :static int SProcRenderDispatch (ClientPtr pClient);
20006 :int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
20007 : ProcRenderQueryVersion,
20008 : ProcRenderQueryPictFormats,
20009 : ProcRenderQueryPictIndexValues,
20010 : ProcRenderQueryDithers,
20011 : ProcRenderCreatePicture,
20012 : ProcRenderChangePicture,
20013 : ProcRenderSetPictureClipRectangles,
20014 : ProcRenderFreePicture,
20015 : ProcRenderComposite,
20017 : ProcRenderTrapezoids,
20018 : ProcRenderTriangles,
20019 : ProcRenderTriStrip,
20020 : ProcRenderTriFan,
20021 : ProcRenderColorTrapezoids,
20022 : ProcRenderColorTriangles,
20023 : ProcRenderTransform,
20024 : ProcRenderCreateGlyphSet,
20025 : ProcRenderReferenceGlyphSet,
20026 : ProcRenderFreeGlyphSet,
20027 : ProcRenderAddGlyphs,
20028 : ProcRenderAddGlyphsFromPicture,
20029 : ProcRenderFreeGlyphs,
20030 : ProcRenderCompositeGlyphs,
20031 : ProcRenderCompositeGlyphs,
20032 : ProcRenderCompositeGlyphs,
20033 : ProcRenderFillRectangles,
20034 : ProcRenderCreateCursor,
20035 : ProcRenderSetPictureTransform,
20036 : ProcRenderQueryFilters,
20037 : ProcRenderSetPictureFilter,
20038 : ProcRenderCreateAnimCursor,
20039 : ProcRenderAddTraps,
20040 : ProcRenderCreateSolidFill,
20041 : ProcRenderCreateLinearGradient,
20042 : ProcRenderCreateRadialGradient,
20043 : ProcRenderCreateConicalGradient
20046 :int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
20047 : SProcRenderQueryVersion,
20048 : SProcRenderQueryPictFormats,
20049 : SProcRenderQueryPictIndexValues,
20050 : SProcRenderQueryDithers,
20051 : SProcRenderCreatePicture,
20052 : SProcRenderChangePicture,
20053 : SProcRenderSetPictureClipRectangles,
20054 : SProcRenderFreePicture,
20055 : SProcRenderComposite,
20056 : SProcRenderScale,
20057 : SProcRenderTrapezoids,
20058 : SProcRenderTriangles,
20059 : SProcRenderTriStrip,
20060 : SProcRenderTriFan,
20061 : SProcRenderColorTrapezoids,
20062 : SProcRenderColorTriangles,
20063 : SProcRenderTransform,
20064 : SProcRenderCreateGlyphSet,
20065 : SProcRenderReferenceGlyphSet,
20066 : SProcRenderFreeGlyphSet,
20067 : SProcRenderAddGlyphs,
20068 : SProcRenderAddGlyphsFromPicture,
20069 : SProcRenderFreeGlyphs,
20070 : SProcRenderCompositeGlyphs,
20071 : SProcRenderCompositeGlyphs,
20072 : SProcRenderCompositeGlyphs,
20073 : SProcRenderFillRectangles,
20074 : SProcRenderCreateCursor,
20075 : SProcRenderSetPictureTransform,
20076 : SProcRenderQueryFilters,
20077 : SProcRenderSetPictureFilter,
20078 : SProcRenderCreateAnimCursor,
20079 : SProcRenderAddTraps,
20080 : SProcRenderCreateSolidFill,
20081 : SProcRenderCreateLinearGradient,
20082 : SProcRenderCreateRadialGradient,
20083 : SProcRenderCreateConicalGradient
20087 :RenderResetProc (ExtensionEntry *extEntry);
20090 :static CARD8 RenderReqCode;
20092 :int RenderErrBase;
20093 :int RenderClientPrivateIndex;
20095 :typedef struct _RenderClient {
20096 : int major_version;
20097 : int minor_version;
20098 :} RenderClientRec, *RenderClientPtr;
20100 :#define GetRenderClient(pClient) ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
20103 :RenderClientCallback (CallbackListPtr *list,
20107 : NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
20108 : ClientPtr pClient = clientinfo->client;
20109 : RenderClientPtr pRenderClient = GetRenderClient (pClient);
20111 : pRenderClient->major_version = 0;
20112 : pRenderClient->minor_version = 0;
20116 :RenderExtensionInit (void)
20118 : ExtensionEntry *extEntry;
20120 : if (!PictureType)
20122 : if (!PictureFinishInit ())
20124 : RenderClientPrivateIndex = AllocateClientPrivateIndex ();
20125 : if (!AllocateClientPrivate (RenderClientPrivateIndex,
20126 : sizeof (RenderClientRec)))
20128 : if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
20131 : extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
20132 : ProcRenderDispatch, SProcRenderDispatch,
20133 : RenderResetProc, StandardMinorOpcode);
20137 : RenderReqCode = (CARD8) extEntry->base;
20139 : RenderErrBase = extEntry->errorBase;
20143 :RenderResetProc (ExtensionEntry *extEntry)
20145 : ResetPicturePrivateIndex();
20146 : ResetGlyphSetPrivateIndex();
20150 :ProcRenderQueryVersion (ClientPtr client)
20152 : RenderClientPtr pRenderClient = GetRenderClient (client);
20153 : xRenderQueryVersionReply rep;
20155 : REQUEST(xRenderQueryVersionReq);
20157 : pRenderClient->major_version = stuff->majorVersion;
20158 : pRenderClient->minor_version = stuff->minorVersion;
20160 : REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
20161 : rep.type = X_Reply;
20163 : rep.sequenceNumber = client->sequence;
20164 : rep.majorVersion = RENDER_MAJOR;
20165 : rep.minorVersion = RENDER_MINOR;
20166 : if (client->swapped) {
20167 : swaps(&rep.sequenceNumber, n);
20168 : swapl(&rep.length, n);
20169 : swapl(&rep.majorVersion, n);
20170 : swapl(&rep.minorVersion, n);
20172 : WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
20173 : return (client->noClientException);
20178 :VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
20183 : for (d = 0; d < pScreen->numDepths; d++)
20185 : pDepth = pScreen->allowedDepths + d;
20186 : for (v = 0; v < pDepth->numVids; v++)
20188 : if (pDepth->vids[v] == pVisual->vid)
20189 : return pDepth->depth;
20197 :findVisual (ScreenPtr pScreen, VisualID vid)
20199 : VisualPtr pVisual;
20202 : for (v = 0; v < pScreen->numVisuals; v++)
20204 : pVisual = pScreen->visuals + v;
20205 : if (pVisual->vid == vid)
20211 :extern char *ConnectionInfo;
20214 :ProcRenderQueryPictFormats (ClientPtr client)
20216 : RenderClientPtr pRenderClient = GetRenderClient (client);
20217 : xRenderQueryPictFormatsReply *reply;
20218 : xPictScreen *pictScreen;
20219 : xPictDepth *pictDepth;
20220 : xPictVisual *pictVisual;
20221 : xPictFormInfo *pictForm;
20222 : CARD32 *pictSubpixel;
20223 : ScreenPtr pScreen;
20224 : VisualPtr pVisual;
20227 : PictureScreenPtr ps;
20228 : PictFormatPtr pFormat;
20237 :/* REQUEST(xRenderQueryPictFormatsReq); */
20239 : REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
20242 : if (noPanoramiXExtension)
20243 : numScreens = screenInfo.numScreens;
20245 : numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
20247 : numScreens = screenInfo.numScreens;
20249 : ndepth = nformat = nvisual = 0;
20250 : for (s = 0; s < numScreens; s++)
20252 : pScreen = screenInfo.screens[s];
20253 : for (d = 0; d < pScreen->numDepths; d++)
20255 : pDepth = pScreen->allowedDepths + d;
20258 : for (v = 0; v < pDepth->numVids; v++)
20260 : pVisual = findVisual (pScreen, pDepth->vids[v]);
20261 : if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
20265 : ps = GetPictureScreenIfSet(pScreen);
20267 : nformat += ps->nformats;
20269 : if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
20272 : numSubpixel = numScreens;
20274 : rlength = (sizeof (xRenderQueryPictFormatsReply) +
20275 : nformat * sizeof (xPictFormInfo) +
20276 : numScreens * sizeof (xPictScreen) +
20277 : ndepth * sizeof (xPictDepth) +
20278 : nvisual * sizeof (xPictVisual) +
20279 : numSubpixel * sizeof (CARD32));
20280 : reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
20283 : reply->type = X_Reply;
20284 : reply->sequenceNumber = client->sequence;
20285 : reply->length = (rlength - sizeof(xGenericReply)) >> 2;
20286 : reply->numFormats = nformat;
20287 : reply->numScreens = numScreens;
20288 : reply->numDepths = ndepth;
20289 : reply->numVisuals = nvisual;
20290 : reply->numSubpixel = numSubpixel;
20292 : pictForm = (xPictFormInfo *) (reply + 1);
20294 : for (s = 0; s < numScreens; s++)
20296 : pScreen = screenInfo.screens[s];
20297 : ps = GetPictureScreenIfSet(pScreen);
20300 : for (nformat = 0, pFormat = ps->formats;
20301 : nformat < ps->nformats;
20302 : nformat++, pFormat++)
20304 : pictForm->id = pFormat->id;
20305 : pictForm->type = pFormat->type;
20306 : pictForm->depth = pFormat->depth;
20307 : pictForm->direct.red = pFormat->direct.red;
20308 : pictForm->direct.redMask = pFormat->direct.redMask;
20309 : pictForm->direct.green = pFormat->direct.green;
20310 : pictForm->direct.greenMask = pFormat->direct.greenMask;
20311 : pictForm->direct.blue = pFormat->direct.blue;
20312 : pictForm->direct.blueMask = pFormat->direct.blueMask;
20313 : pictForm->direct.alpha = pFormat->direct.alpha;
20314 : pictForm->direct.alphaMask = pFormat->direct.alphaMask;
20315 : if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
20316 : pictForm->colormap = pFormat->index.pColormap->mid;
20318 : pictForm->colormap = None;
20319 : if (client->swapped)
20321 : swapl (&pictForm->id, n);
20322 : swaps (&pictForm->direct.red, n);
20323 : swaps (&pictForm->direct.redMask, n);
20324 : swaps (&pictForm->direct.green, n);
20325 : swaps (&pictForm->direct.greenMask, n);
20326 : swaps (&pictForm->direct.blue, n);
20327 : swaps (&pictForm->direct.blueMask, n);
20328 : swaps (&pictForm->direct.alpha, n);
20329 : swaps (&pictForm->direct.alphaMask, n);
20330 : swapl (&pictForm->colormap, n);
20337 : pictScreen = (xPictScreen *) pictForm;
20338 : for (s = 0; s < numScreens; s++)
20340 : pScreen = screenInfo.screens[s];
20341 : pictDepth = (xPictDepth *) (pictScreen + 1);
20343 : for (d = 0; d < pScreen->numDepths; d++)
20345 : pictVisual = (xPictVisual *) (pictDepth + 1);
20346 : pDepth = pScreen->allowedDepths + d;
20349 : for (v = 0; v < pDepth->numVids; v++)
20351 : pVisual = findVisual (pScreen, pDepth->vids[v]);
20352 : if (pVisual && (pFormat = PictureMatchVisual (pScreen,
20356 : pictVisual->visual = pVisual->vid;
20357 : pictVisual->format = pFormat->id;
20358 : if (client->swapped)
20360 : swapl (&pictVisual->visual, n);
20361 : swapl (&pictVisual->format, n);
20367 : pictDepth->depth = pDepth->depth;
20368 : pictDepth->nPictVisuals = nvisual;
20369 : if (client->swapped)
20371 : swaps (&pictDepth->nPictVisuals, n);
20374 : pictDepth = (xPictDepth *) pictVisual;
20376 : pictScreen->nDepth = ndepth;
20377 : ps = GetPictureScreenIfSet(pScreen);
20379 : pictScreen->fallback = ps->fallback->id;
20381 : pictScreen->fallback = 0;
20382 : if (client->swapped)
20384 : swapl (&pictScreen->nDepth, n);
20385 : swapl (&pictScreen->fallback, n);
20387 : pictScreen = (xPictScreen *) pictDepth;
20389 : pictSubpixel = (CARD32 *) pictScreen;
20391 : for (s = 0; s < numSubpixel; s++)
20393 : pScreen = screenInfo.screens[s];
20394 : ps = GetPictureScreenIfSet(pScreen);
20396 : *pictSubpixel = ps->subpixel;
20398 : *pictSubpixel = SubPixelUnknown;
20399 : if (client->swapped)
20401 : swapl (pictSubpixel, n);
20406 : if (client->swapped)
20408 : swaps (&reply->sequenceNumber, n);
20409 : swapl (&reply->length, n);
20410 : swapl (&reply->numFormats, n);
20411 : swapl (&reply->numScreens, n);
20412 : swapl (&reply->numDepths, n);
20413 : swapl (&reply->numVisuals, n);
20414 : swapl (&reply->numSubpixel, n);
20416 : WriteToClient(client, rlength, (char *) reply);
20418 : return client->noClientException;
20422 :ProcRenderQueryPictIndexValues (ClientPtr client)
20424 : PictFormatPtr pFormat;
20428 : REQUEST(xRenderQueryPictIndexValuesReq);
20429 : xRenderQueryPictIndexValuesReply *reply;
20430 : xIndexValue *values;
20432 : REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
20434 : pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
20441 : client->errorValue = stuff->format;
20442 : return RenderErrBase + BadPictFormat;
20444 : if (pFormat->type != PictTypeIndexed)
20446 : client->errorValue = stuff->format;
20449 : num = pFormat->index.nvalues;
20450 : rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
20451 : num * sizeof(xIndexValue));
20452 : reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
20456 : reply->type = X_Reply;
20457 : reply->sequenceNumber = client->sequence;
20458 : reply->length = (rlength - sizeof(xGenericReply)) >> 2;
20459 : reply->numIndexValues = num;
20461 : values = (xIndexValue *) (reply + 1);
20463 : memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
20465 : if (client->swapped)
20467 : for (i = 0; i < num; i++)
20469 : swapl (&values[i].pixel, n);
20470 : swaps (&values[i].red, n);
20471 : swaps (&values[i].green, n);
20472 : swaps (&values[i].blue, n);
20473 : swaps (&values[i].alpha, n);
20475 : swaps (&reply->sequenceNumber, n);
20476 : swapl (&reply->length, n);
20477 : swapl (&reply->numIndexValues, n);
20480 : WriteToClient(client, rlength, (char *) reply);
20482 : return (client->noClientException);
20486 :ProcRenderQueryDithers (ClientPtr client)
20488 : return BadImplementation;
20492 :ProcRenderCreatePicture (ClientPtr client)
20493 6 0.0065 :{ /* ProcRenderCreatePicture total: 14 0.0153 */
20494 : PicturePtr pPicture;
20495 : DrawablePtr pDrawable;
20496 : PictFormatPtr pFormat;
20497 : int len, error, rc;
20498 : REQUEST(xRenderCreatePictureReq);
20500 : REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
20502 1 0.0011 : LEGAL_NEW_RESOURCE(stuff->pid, client);
20503 2 0.0022 : rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
20505 : if (rc != Success)
20508 1 0.0011 : pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
20514 : client->errorValue = stuff->format;
20515 : return RenderErrBase + BadPictFormat;
20517 : if (pFormat->depth != pDrawable->depth)
20519 : len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
20520 : if (Ones(stuff->mask) != len)
20521 : return BadLength;
20523 : pPicture = CreatePicture (stuff->pid,
20527 : (XID *) (stuff + 1),
20532 4 0.0044 : if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
20538 :ProcRenderChangePicture (ClientPtr client)
20539 6 0.0065 :{ /* ProcRenderChangePicture total: 7 0.0076 */
20540 : PicturePtr pPicture;
20541 : REQUEST(xRenderChangePictureReq);
20544 : REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
20545 1 0.0011 : VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
20546 : RenderErrBase + BadPicture);
20548 : len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
20549 : if (Ones(stuff->mask) != len)
20550 : return BadLength;
20552 : return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
20553 : (DevUnion *) 0, client);
20557 :ProcRenderSetPictureClipRectangles (ClientPtr client)
20558 1 0.0011 :{ /* ProcRenderSetPictureClipRectangles total: 1 0.0011 */
20559 : REQUEST(xRenderSetPictureClipRectanglesReq);
20560 : PicturePtr pPicture;
20564 : REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
20565 : VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
20566 : RenderErrBase + BadPicture);
20567 : if (!pPicture->pDrawable)
20568 : return BadDrawable;
20570 : nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
20572 : return BadLength;
20574 : result = SetPictureClipRects (pPicture,
20575 : stuff->xOrigin, stuff->yOrigin,
20576 : nr, (xRectangle *) &stuff[1]);
20577 : if (client->noClientException != Success)
20578 : return(client->noClientException);
20584 :ProcRenderFreePicture (ClientPtr client)
20585 1 0.0011 :{ /* ProcRenderFreePicture total: 2 0.0022 */
20586 : PicturePtr pPicture;
20587 : REQUEST(xRenderFreePictureReq);
20589 1 0.0011 : REQUEST_SIZE_MATCH(xRenderFreePictureReq);
20591 : VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess,
20592 : RenderErrBase + BadPicture);
20593 : FreeResource (stuff->picture, RT_NONE);
20594 : return(client->noClientException);
20598 :PictOpValid (CARD8 op)
20600 : if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
20602 : if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
20604 : if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
20610 :ProcRenderComposite (ClientPtr client)
20611 1 0.0011 :{ /* ProcRenderComposite total: 1 0.0011 */
20612 : PicturePtr pSrc, pMask, pDst;
20613 : REQUEST(xRenderCompositeReq);
20615 : REQUEST_SIZE_MATCH(xRenderCompositeReq);
20616 : if (!PictOpValid (stuff->op))
20618 : client->errorValue = stuff->op;
20621 : VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
20622 : RenderErrBase + BadPicture);
20623 : if (!pDst->pDrawable)
20624 : return BadDrawable;
20625 : VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
20626 : RenderErrBase + BadPicture);
20627 : VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess,
20628 : RenderErrBase + BadPicture);
20629 : if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
20630 : (pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
20632 : CompositePicture (stuff->op,
20648 :ProcRenderScale (ClientPtr client)
20650 : return BadImplementation;
20654 :ProcRenderTrapezoids (ClientPtr client)
20657 : PicturePtr pSrc, pDst;
20658 : PictFormatPtr pFormat;
20659 : REQUEST(xRenderTrapezoidsReq);
20661 : REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
20662 : if (!PictOpValid (stuff->op))
20664 : client->errorValue = stuff->op;
20667 : VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
20668 : RenderErrBase + BadPicture);
20669 : VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
20670 : RenderErrBase + BadPicture);
20671 : if (!pDst->pDrawable)
20672 : return BadDrawable;
20673 : if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
20675 : if (stuff->maskFormat)
20677 : pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
20678 : stuff->maskFormat,
20683 : client->errorValue = stuff->maskFormat;
20684 : return RenderErrBase + BadPictFormat;
20689 : ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
20690 : if (ntraps % sizeof (xTrapezoid))
20691 : return BadLength;
20692 : ntraps /= sizeof (xTrapezoid);
20694 : CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
20695 : stuff->xSrc, stuff->ySrc,
20696 : ntraps, (xTrapezoid *) &stuff[1]);
20697 : return client->noClientException;
20701 :ProcRenderTriangles (ClientPtr client)
20704 : PicturePtr pSrc, pDst;
20705 : PictFormatPtr pFormat;
20706 : REQUEST(xRenderTrianglesReq);
20708 : REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
20709 : if (!PictOpValid (stuff->op))
20711 : client->errorValue = stuff->op;
20714 : VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
20715 : RenderErrBase + BadPicture);
20716 : VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
20717 : RenderErrBase + BadPicture);
20718 : if (!pDst->pDrawable)
20719 : return BadDrawable;
20720 : if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
20722 : if (stuff->maskFormat)
20724 : pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
20725 : stuff->maskFormat,
20730 : client->errorValue = stuff->maskFormat;
20731 : return RenderErrBase + BadPictFormat;
20736 : ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
20737 : if (ntris % sizeof (xTriangle))
20738 : return BadLength;
20739 : ntris /= sizeof (xTriangle);
20741 : CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
20742 : stuff->xSrc, stuff->ySrc,
20743 : ntris, (xTriangle *) &stuff[1]);
20744 : return client->noClientException;
20748 :ProcRenderTriStrip (ClientPtr client)
20751 : PicturePtr pSrc, pDst;
20752 : PictFormatPtr pFormat;
20753 : REQUEST(xRenderTrianglesReq);
20755 : REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
20756 : if (!PictOpValid (stuff->op))
20758 : client->errorValue = stuff->op;
20761 : VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
20762 : RenderErrBase + BadPicture);
20763 : VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
20764 : RenderErrBase + BadPicture);
20765 : if (!pDst->pDrawable)
20766 : return BadDrawable;
20767 : if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
20769 : if (stuff->maskFormat)
20771 : pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
20772 : stuff->maskFormat,
20777 : client->errorValue = stuff->maskFormat;
20778 : return RenderErrBase + BadPictFormat;
20783 : npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
20785 : return(BadLength);
20787 : if (npoints >= 3)
20788 : CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
20789 : stuff->xSrc, stuff->ySrc,
20790 : npoints, (xPointFixed *) &stuff[1]);
20791 : return client->noClientException;
20795 :ProcRenderTriFan (ClientPtr client)
20798 : PicturePtr pSrc, pDst;
20799 : PictFormatPtr pFormat;
20800 : REQUEST(xRenderTrianglesReq);
20802 : REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
20803 : if (!PictOpValid (stuff->op))
20805 : client->errorValue = stuff->op;
20808 : VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
20809 : RenderErrBase + BadPicture);
20810 : VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
20811 : RenderErrBase + BadPicture);
20812 : if (!pDst->pDrawable)
20813 : return BadDrawable;
20814 : if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
20816 : if (stuff->maskFormat)
20818 : pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
20819 : stuff->maskFormat,
20824 : client->errorValue = stuff->maskFormat;
20825 : return RenderErrBase + BadPictFormat;
20830 : npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
20832 : return(BadLength);
20834 : if (npoints >= 3)
20835 : CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
20836 : stuff->xSrc, stuff->ySrc,
20837 : npoints, (xPointFixed *) &stuff[1]);
20838 : return client->noClientException;
20842 :ProcRenderColorTrapezoids (ClientPtr client)
20844 : return BadImplementation;
20848 :ProcRenderColorTriangles (ClientPtr client)
20850 : return BadImplementation;
20854 :ProcRenderTransform (ClientPtr client)
20856 : return BadImplementation;
20860 :ProcRenderCreateGlyphSet (ClientPtr client)
20862 : GlyphSetPtr glyphSet;
20863 : PictFormatPtr format;
20865 : REQUEST(xRenderCreateGlyphSetReq);
20867 : REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
20869 : LEGAL_NEW_RESOURCE(stuff->gsid, client);
20870 : format = (PictFormatPtr) SecurityLookupIDByType (client,
20876 : client->errorValue = stuff->format;
20877 : return RenderErrBase + BadPictFormat;
20879 : switch (format->depth) {
20881 : f = GlyphFormat1;
20884 : f = GlyphFormat4;
20887 : f = GlyphFormat8;
20890 : f = GlyphFormat16;
20893 : f = GlyphFormat32;
20898 : if (format->type != PictTypeDirect)
20900 : glyphSet = AllocateGlyphSet (f, format);
20903 : if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
20909 :ProcRenderReferenceGlyphSet (ClientPtr client)
20911 : GlyphSetPtr glyphSet;
20912 : REQUEST(xRenderReferenceGlyphSetReq);
20914 : REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
20916 : LEGAL_NEW_RESOURCE(stuff->gsid, client);
20918 : glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
20924 : client->errorValue = stuff->existing;
20925 : return RenderErrBase + BadGlyphSet;
20927 : glyphSet->refcnt++;
20928 : if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
20930 : return client->noClientException;
20933 :#define NLOCALDELTA 64
20934 :#define NLOCALGLYPH 256
20937 :ProcRenderFreeGlyphSet (ClientPtr client)
20939 : GlyphSetPtr glyphSet;
20940 : REQUEST(xRenderFreeGlyphSetReq);
20942 : REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
20943 : glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
20946 : DixDestroyAccess);
20949 : client->errorValue = stuff->glyphset;
20950 : return RenderErrBase + BadGlyphSet;
20952 : FreeResource (stuff->glyphset, RT_NONE);
20953 : return client->noClientException;
20956 :typedef struct _GlyphNew {
20959 :} GlyphNewRec, *GlyphNewPtr;
20962 :ProcRenderAddGlyphs (ClientPtr client)
20964 : GlyphSetPtr glyphSet;
20965 : REQUEST(xRenderAddGlyphsReq);
20966 : GlyphNewRec glyphsLocal[NLOCALGLYPH];
20967 : GlyphNewPtr glyphsBase, glyphs;
20969 : int remain, nglyphs;
20974 : int err = BadAlloc;
20976 : REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
20977 : glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
20983 : client->errorValue = stuff->glyphset;
20984 : return RenderErrBase + BadGlyphSet;
20987 : nglyphs = stuff->nglyphs;
20988 : if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
20991 : if (nglyphs <= NLOCALGLYPH)
20992 : glyphsBase = glyphsLocal;
20995 : glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
21000 : remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
21002 : glyphs = glyphsBase;
21004 : gids = (CARD32 *) (stuff + 1);
21005 : gi = (xGlyphInfo *) (gids + nglyphs);
21006 : bits = (CARD8 *) (gi + nglyphs);
21007 : remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
21008 : while (remain >= 0 && nglyphs)
21010 : glyph = AllocateGlyph (gi, glyphSet->fdepth);
21017 : glyphs->glyph = glyph;
21018 : glyphs->id = *gids;
21020 : size = glyph->size - sizeof (xGlyphInfo);
21021 : if (remain < size)
21023 : memcpy ((CARD8 *) (glyph + 1), bits, size);
21026 : size += 4 - (size & 3);
21034 : if (nglyphs || remain)
21039 : nglyphs = stuff->nglyphs;
21040 : if (!ResizeGlyphSet (glyphSet, nglyphs))
21045 : glyphs = glyphsBase;
21046 : while (nglyphs--) {
21047 : AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
21051 : if (glyphsBase != glyphsLocal)
21052 : Xfree (glyphsBase);
21053 : return client->noClientException;
21055 : while (glyphs != glyphsBase)
21058 : xfree (glyphs->glyph);
21060 : if (glyphsBase != glyphsLocal)
21061 : Xfree (glyphsBase);
21066 :ProcRenderAddGlyphsFromPicture (ClientPtr client)
21068 : return BadImplementation;
21072 :ProcRenderFreeGlyphs (ClientPtr client)
21074 : REQUEST(xRenderFreeGlyphsReq);
21075 : GlyphSetPtr glyphSet;
21080 : REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
21081 : glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
21087 : client->errorValue = stuff->glyphset;
21088 : return RenderErrBase + BadGlyphSet;
21090 : nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
21091 : gids = (CARD32 *) (stuff + 1);
21092 : while (nglyph-- > 0)
21095 : if (!DeleteGlyph (glyphSet, glyph))
21097 : client->errorValue = glyph;
21098 : return RenderErrBase + BadGlyph;
21101 : return client->noClientException;
21105 :ProcRenderCompositeGlyphs (ClientPtr client)
21106 4 0.0044 :{ /* ProcRenderCompositeGlyphs total: 30 0.0327 */
21107 : GlyphSetPtr glyphSet;
21109 : PicturePtr pSrc, pDst;
21110 : PictFormatPtr pFormat;
21111 : GlyphListRec listsLocal[NLOCALDELTA];
21112 : GlyphListPtr lists, listsBase;
21113 : GlyphPtr glyphsLocal[NLOCALGLYPH];
21115 : GlyphPtr *glyphs, *glyphsBase;
21117 : CARD8 *buffer, *end;
21124 : REQUEST(xRenderCompositeGlyphsReq);
21126 : REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
21128 : switch (stuff->renderReqType) {
21129 : default: size = 1; break;
21130 : case X_RenderCompositeGlyphs16: size = 2; break;
21131 : case X_RenderCompositeGlyphs32: size = 4; break;
21134 : if (!PictOpValid (stuff->op))
21136 : client->errorValue = stuff->op;
21139 : VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
21140 : RenderErrBase + BadPicture);
21141 : VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
21142 : RenderErrBase + BadPicture);
21143 : if (!pDst->pDrawable)
21144 : return BadDrawable;
21145 : if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
21147 : if (stuff->maskFormat)
21149 1 0.0011 : pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
21150 : stuff->maskFormat,
21155 : client->errorValue = stuff->maskFormat;
21156 : return RenderErrBase + BadPictFormat;
21162 1 0.0011 : glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
21168 : client->errorValue = stuff->glyphset;
21169 : return RenderErrBase + BadGlyphSet;
21172 : buffer = (CARD8 *) (stuff + 1);
21173 2 0.0022 : end = (CARD8 *) stuff + (client->req_len << 2);
21176 : while (buffer + sizeof (xGlyphElt) < end)
21178 : elt = (xGlyphElt *) buffer;
21179 : buffer += sizeof (xGlyphElt);
21181 : if (elt->len == 0xff)
21187 1 0.0011 : nlist++;
21188 : nglyph += elt->len;
21189 : space = size * elt->len;
21191 : space += 4 - (space & 3);
21195 : if (nglyph <= NLOCALGLYPH)
21196 : glyphsBase = glyphsLocal;
21199 : glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
21203 : if (nlist <= NLOCALDELTA)
21204 : listsBase = listsLocal;
21207 : listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
21211 : buffer = (CARD8 *) (stuff + 1);
21212 : glyphs = glyphsBase;
21213 : lists = listsBase;
21214 1 0.0011 : while (buffer + sizeof (xGlyphElt) < end)
21216 : elt = (xGlyphElt *) buffer;
21217 : buffer += sizeof (xGlyphElt);
21219 : if (elt->len == 0xff)
21221 : if (buffer + sizeof (GlyphSet) < end)
21223 : memcpy(&gs, buffer, sizeof(GlyphSet));
21224 : glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
21230 : client->errorValue = gs;
21231 : if (glyphsBase != glyphsLocal)
21232 : DEALLOCATE_LOCAL (glyphsBase);
21233 : if (listsBase != listsLocal)
21234 : DEALLOCATE_LOCAL (listsBase);
21235 : return RenderErrBase + BadGlyphSet;
21242 : lists->xOff = elt->deltax;
21243 : lists->yOff = elt->deltay;
21244 1 0.0011 : lists->format = glyphSet->format;
21247 3 0.0033 : while (n--)
21249 : if (buffer + size <= end)
21253 7 0.0076 : glyph = *((CARD8 *)buffer); break;
21255 : glyph = *((CARD16 *)buffer); break;
21258 : glyph = *((CARD32 *)buffer); break;
21260 5 0.0054 : if ((*glyphs = FindGlyph (glyphSet, glyph)))
21262 2 0.0022 : lists->len++;
21268 : space = size * elt->len;
21270 1 0.0011 : buffer += 4 - (space & 3);
21274 : if (buffer > end)
21275 : return BadLength;
21277 1 0.0011 : CompositeGlyphs (stuff->op,
21287 : if (glyphsBase != glyphsLocal)
21288 : DEALLOCATE_LOCAL (glyphsBase);
21289 : if (listsBase != listsLocal)
21290 : DEALLOCATE_LOCAL (listsBase);
21292 : return client->noClientException;
21296 :ProcRenderFillRectangles (ClientPtr client)
21297 4 0.0044 :{ /* ProcRenderFillRectangles total: 10 0.0109 */
21300 : REQUEST(xRenderFillRectanglesReq);
21302 : REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
21303 1 0.0011 : if (!PictOpValid (stuff->op))
21305 : client->errorValue = stuff->op;
21308 : VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
21309 : RenderErrBase + BadPicture);
21310 : if (!pDst->pDrawable)
21311 : return BadDrawable;
21313 : things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
21315 : return(BadLength);
21318 2 0.0022 : CompositeRects (stuff->op,
21322 : (xRectangle *) &stuff[1]);
21324 1 0.0011 : return client->noClientException;
21328 :SetBit (unsigned char *line, int x, int bit)
21330 : unsigned char mask;
21332 : if (screenInfo.bitmapBitOrder == LSBFirst)
21333 : mask = (1 << (x & 7));
21335 : mask = (0x80 >> (x & 7));
21336 : /* XXX assumes byte order is host byte order */
21337 : line += (x >> 3);
21344 :#define DITHER_DIM 2
21346 :static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
21351 :#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
21354 :ProcRenderCreateCursor (ClientPtr client)
21356 : REQUEST(xRenderCreateCursorReq);
21358 : ScreenPtr pScreen;
21359 : unsigned short width, height;
21360 : CARD32 *argbbits, *argb;
21361 : unsigned char *srcbits, *srcline;
21362 : unsigned char *mskbits, *mskline;
21366 : CursorMetricRec cm;
21367 : CursorPtr pCursor;
21368 : CARD32 twocolor[3];
21371 : REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
21372 : LEGAL_NEW_RESOURCE(stuff->cid, client);
21374 : VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
21375 : RenderErrBase + BadPicture);
21376 : if (!pSrc->pDrawable)
21377 : return BadDrawable;
21378 : pScreen = pSrc->pDrawable->pScreen;
21379 : width = pSrc->pDrawable->width;
21380 : height = pSrc->pDrawable->height;
21381 : if ( stuff->x > width
21382 : || stuff->y > height )
21383 : return (BadMatch);
21384 : argbbits = xalloc (width * height * sizeof (CARD32));
21386 : return (BadAlloc);
21388 : stride = BitmapBytePad(width);
21389 : nbytes_mono = stride*height;
21390 : srcbits = (unsigned char *)xalloc(nbytes_mono);
21393 : xfree (argbbits);
21394 : return (BadAlloc);
21396 : mskbits = (unsigned char *)xalloc(nbytes_mono);
21401 : return (BadAlloc);
21403 : bzero ((char *) mskbits, nbytes_mono);
21404 : bzero ((char *) srcbits, nbytes_mono);
21406 : if (pSrc->format == PICT_a8r8g8b8)
21408 : (*pScreen->GetImage) (pSrc->pDrawable,
21409 : 0, 0, width, height, ZPixmap,
21410 : 0xffffffff, (pointer) argbbits);
21414 : PixmapPtr pPixmap;
21415 : PicturePtr pPicture;
21416 : PictFormatPtr pFormat;
21419 : pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
21422 : xfree (argbbits);
21425 : return (BadImplementation);
21427 : pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
21430 : xfree (argbbits);
21433 : return (BadAlloc);
21435 : pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
21439 : xfree (argbbits);
21444 : (*pScreen->DestroyPixmap) (pPixmap);
21445 : CompositePicture (PictOpSrc,
21446 : pSrc, 0, pPicture,
21447 : 0, 0, 0, 0, 0, 0, width, height);
21448 : (*pScreen->GetImage) (pPicture->pDrawable,
21449 : 0, 0, width, height, ZPixmap,
21450 : 0xffffffff, (pointer) argbbits);
21451 : FreePicture (pPicture, 0);
21454 : * Check whether the cursor can be directly supported by
21455 : * the core cursor code
21459 : for (y = 0; ncolor <= 2 && y < height; y++)
21461 : for (x = 0; ncolor <= 2 && x < width; x++)
21463 : CARD32 p = *argb++;
21464 : CARD32 a = (p >> 24);
21466 : if (a == 0) /* transparent */
21468 : if (a == 0xff) /* opaque */
21471 : for (n = 0; n < ncolor; n++)
21472 : if (p == twocolor[n])
21475 : twocolor[ncolor++] = p;
21483 : * Convert argb image to two plane cursor
21485 : srcline = srcbits;
21486 : mskline = mskbits;
21488 : for (y = 0; y < height; y++)
21490 : for (x = 0; x < width; x++)
21492 : CARD32 p = *argb++;
21496 : CARD32 a = ((p >> 24));
21498 : SetBit (mskline, x, a != 0);
21499 : SetBit (srcline, x, a != 0 && p == twocolor[0]);
21503 : CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
21504 : CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
21505 : CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
21506 : /* Set mask from dithered alpha value */
21507 : SetBit(mskline, x, a > d);
21508 : /* Set src from dithered intensity value */
21509 : SetBit(srcline, x, a > d && i <= d);
21512 : srcline += stride;
21513 : mskline += stride;
21516 : * Dither to white and black if the cursor has more than two colors
21520 : twocolor[0] = 0xff000000;
21521 : twocolor[1] = 0xffffffff;
21525 : xfree (argbbits);
21529 :#define GetByte(p,s) (((p) >> (s)) & 0xff)
21530 :#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
21532 : cm.width = width;
21533 : cm.height = height;
21534 : cm.xhot = stuff->x;
21535 : cm.yhot = stuff->y;
21536 : pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
21537 : GetColor(twocolor[0], 16),
21538 : GetColor(twocolor[0], 8),
21539 : GetColor(twocolor[0], 0),
21540 : GetColor(twocolor[1], 16),
21541 : GetColor(twocolor[1], 8),
21542 : GetColor(twocolor[1], 0));
21543 : if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
21544 : return (client->noClientException);
21549 :ProcRenderSetPictureTransform (ClientPtr client)
21550 :{ /* ProcRenderSetPictureTransform total: 2 0.0022 */
21551 : REQUEST(xRenderSetPictureTransformReq);
21552 : PicturePtr pPicture;
21555 1 0.0011 : REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
21556 : VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
21557 : RenderErrBase + BadPicture);
21558 : result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
21559 : if (client->noClientException != Success)
21560 : return(client->noClientException);
21566 :ProcRenderQueryFilters (ClientPtr client)
21568 : REQUEST (xRenderQueryFiltersReq);
21569 : DrawablePtr pDrawable;
21570 : xRenderQueryFiltersReply *reply;
21573 : ScreenPtr pScreen;
21574 : PictureScreenPtr ps;
21575 : int i, j, len, total_bytes, rc;
21579 : REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
21580 : rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
21582 : if (rc != Success)
21585 : pScreen = pDrawable->pScreen;
21588 : ps = GetPictureScreenIfSet(pScreen);
21591 : for (i = 0; i < ps->nfilters; i++)
21592 : nbytesName += 1 + strlen (ps->filters[i].name);
21593 : for (i = 0; i < ps->nfilterAliases; i++)
21594 : nbytesName += 1 + strlen (ps->filterAliases[i].alias);
21595 : nnames = ps->nfilters + ps->nfilterAliases;
21597 : len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
21598 : total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
21599 : reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
21602 : aliases = (INT16 *) (reply + 1);
21603 : names = (char *) (aliases + ((nnames + 1) & ~1));
21605 : reply->type = X_Reply;
21606 : reply->sequenceNumber = client->sequence;
21607 : reply->length = len;
21608 : reply->numAliases = nnames;
21609 : reply->numFilters = nnames;
21613 : /* fill in alias values */
21614 : for (i = 0; i < ps->nfilters; i++)
21615 : aliases[i] = FilterAliasNone;
21616 : for (i = 0; i < ps->nfilterAliases; i++)
21618 : for (j = 0; j < ps->nfilters; j++)
21619 : if (ps->filterAliases[i].filter_id == ps->filters[j].id)
21621 : if (j == ps->nfilters)
21623 : for (j = 0; j < ps->nfilterAliases; j++)
21624 : if (ps->filterAliases[i].filter_id ==
21625 : ps->filterAliases[j].alias_id)
21629 : if (j == ps->nfilterAliases)
21630 : j = FilterAliasNone;
21632 : j = j + ps->nfilters;
21634 : aliases[i + ps->nfilters] = j;
21637 : /* fill in filter names */
21638 : for (i = 0; i < ps->nfilters; i++)
21640 : j = strlen (ps->filters[i].name);
21642 : strncpy (names, ps->filters[i].name, j);
21646 : /* fill in filter alias names */
21647 : for (i = 0; i < ps->nfilterAliases; i++)
21649 : j = strlen (ps->filterAliases[i].alias);
21651 : strncpy (names, ps->filterAliases[i].alias, j);
21656 : if (client->swapped)
21660 : for (i = 0; i < reply->numAliases; i++)
21662 : swaps (&aliases[i], n);
21664 : swaps(&reply->sequenceNumber, n);
21665 : swapl(&reply->length, n);
21666 : swapl(&reply->numAliases, n);
21667 : swapl(&reply->numFilters, n);
21669 : WriteToClient(client, total_bytes, (char *) reply);
21672 : return(client->noClientException);
21676 :ProcRenderSetPictureFilter (ClientPtr client)
21677 :{ /* ProcRenderSetPictureFilter total: 4 0.0044 */
21678 : REQUEST (xRenderSetPictureFilterReq);
21679 : PicturePtr pPicture;
21685 1 0.0011 : REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
21686 2 0.0022 : VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
21687 : RenderErrBase + BadPicture);
21688 : name = (char *) (stuff + 1);
21689 : params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
21690 : nparams = ((xFixed *) stuff + client->req_len) - params;
21691 1 0.0011 : result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
21696 :ProcRenderCreateAnimCursor (ClientPtr client)
21698 : REQUEST(xRenderCreateAnimCursorReq);
21699 : CursorPtr *cursors;
21701 : CursorPtr pCursor;
21703 : xAnimCursorElt *elt;
21707 : REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
21708 : LEGAL_NEW_RESOURCE(stuff->cid, client);
21709 : if (client->req_len & 1)
21710 : return BadLength;
21711 : ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
21712 : cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
21715 : deltas = (CARD32 *) (cursors + ncursor);
21716 : elt = (xAnimCursorElt *) (stuff + 1);
21717 : for (i = 0; i < ncursor; i++)
21719 : cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
21720 : RT_CURSOR, DixReadAccess);
21724 : client->errorValue = elt->cursor;
21725 : return BadCursor;
21727 : deltas[i] = elt->delay;
21730 : ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
21732 : if (ret != Success)
21735 : if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
21736 : return client->noClientException;
21741 :ProcRenderAddTraps (ClientPtr client)
21744 : PicturePtr pPicture;
21745 : REQUEST(xRenderAddTrapsReq);
21747 : REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
21748 : VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
21749 : RenderErrBase + BadPicture);
21750 : if (!pPicture->pDrawable)
21751 : return BadDrawable;
21752 : ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
21753 : if (ntraps % sizeof (xTrap))
21754 : return BadLength;
21755 : ntraps /= sizeof (xTrap);
21757 : AddTraps (pPicture,
21758 : stuff->xOff, stuff->yOff,
21759 : ntraps, (xTrap *) &stuff[1]);
21760 : return client->noClientException;
21763 :static int ProcRenderCreateSolidFill(ClientPtr client)
21765 : PicturePtr pPicture;
21767 : REQUEST(xRenderCreateSolidFillReq);
21769 : REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
21771 : LEGAL_NEW_RESOURCE(stuff->pid, client);
21773 : pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
21776 : if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
21781 :static int ProcRenderCreateLinearGradient (ClientPtr client)
21783 : PicturePtr pPicture;
21787 : xRenderColor *colors;
21788 : REQUEST(xRenderCreateLinearGradientReq);
21790 : REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
21792 : LEGAL_NEW_RESOURCE(stuff->pid, client);
21794 : len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
21795 : if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
21796 : return BadLength;
21798 : stops = (xFixed *)(stuff + 1);
21799 : colors = (xRenderColor *)(stops + stuff->nStops);
21801 : pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
21802 : stuff->nStops, stops, colors, &error);
21805 : if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
21810 :static int ProcRenderCreateRadialGradient (ClientPtr client)
21812 : PicturePtr pPicture;
21816 : xRenderColor *colors;
21817 : REQUEST(xRenderCreateRadialGradientReq);
21819 : REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
21821 : LEGAL_NEW_RESOURCE(stuff->pid, client);
21823 : len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
21824 : if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
21825 : return BadLength;
21827 : stops = (xFixed *)(stuff + 1);
21828 : colors = (xRenderColor *)(stops + stuff->nStops);
21830 : pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
21831 : stuff->inner_radius, stuff->outer_radius,
21832 : stuff->nStops, stops, colors, &error);
21835 : if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
21840 :static int ProcRenderCreateConicalGradient (ClientPtr client)
21842 : PicturePtr pPicture;
21846 : xRenderColor *colors;
21847 : REQUEST(xRenderCreateConicalGradientReq);
21849 : REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
21851 : LEGAL_NEW_RESOURCE(stuff->pid, client);
21853 : len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
21854 : if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
21855 : return BadLength;
21857 : stops = (xFixed *)(stuff + 1);
21858 : colors = (xRenderColor *)(stops + stuff->nStops);
21860 : pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
21861 : stuff->nStops, stops, colors, &error);
21864 : if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
21871 :ProcRenderDispatch (ClientPtr client)
21872 8 0.0087 :{ /* ProcRenderDispatch total: 10 0.0109 */
21875 1 0.0011 : if (stuff->data < RenderNumberRequests)
21876 : return (*ProcRenderVector[stuff->data]) (client);
21878 : return BadRequest;
21882 :SProcRenderQueryVersion (ClientPtr client)
21885 : REQUEST(xRenderQueryVersionReq);
21887 : swaps(&stuff->length, n);
21888 : swapl(&stuff->majorVersion, n);
21889 : swapl(&stuff->minorVersion, n);
21890 : return (*ProcRenderVector[stuff->renderReqType])(client);
21894 :SProcRenderQueryPictFormats (ClientPtr client)
21897 : REQUEST(xRenderQueryPictFormatsReq);
21898 : swaps(&stuff->length, n);
21899 : return (*ProcRenderVector[stuff->renderReqType]) (client);
21903 :SProcRenderQueryPictIndexValues (ClientPtr client)
21906 : REQUEST(xRenderQueryPictIndexValuesReq);
21907 : swaps(&stuff->length, n);
21908 : swapl(&stuff->format, n);
21909 : return (*ProcRenderVector[stuff->renderReqType]) (client);
21913 :SProcRenderQueryDithers (ClientPtr client)
21915 : return BadImplementation;
21919 :SProcRenderCreatePicture (ClientPtr client)
21922 : REQUEST(xRenderCreatePictureReq);
21923 : swaps(&stuff->length, n);
21924 : swapl(&stuff->pid, n);
21925 : swapl(&stuff->drawable, n);
21926 : swapl(&stuff->format, n);
21927 : swapl(&stuff->mask, n);
21928 : SwapRestL(stuff);
21929 : return (*ProcRenderVector[stuff->renderReqType]) (client);
21933 :SProcRenderChangePicture (ClientPtr client)
21936 : REQUEST(xRenderChangePictureReq);
21937 : swaps(&stuff->length, n);
21938 : swapl(&stuff->picture, n);
21939 : swapl(&stuff->mask, n);
21940 : SwapRestL(stuff);
21941 : return (*ProcRenderVector[stuff->renderReqType]) (client);
21945 :SProcRenderSetPictureClipRectangles (ClientPtr client)
21948 : REQUEST(xRenderSetPictureClipRectanglesReq);
21949 : swaps(&stuff->length, n);
21950 : swapl(&stuff->picture, n);
21951 : swaps(&stuff->xOrigin, n);
21952 : swaps(&stuff->yOrigin, n);
21953 : SwapRestS(stuff);
21954 : return (*ProcRenderVector[stuff->renderReqType]) (client);
21958 :SProcRenderFreePicture (ClientPtr client)
21961 : REQUEST(xRenderFreePictureReq);
21962 : swaps(&stuff->length, n);
21963 : swapl(&stuff->picture, n);
21964 : return (*ProcRenderVector[stuff->renderReqType]) (client);
21968 :SProcRenderComposite (ClientPtr client)
21971 : REQUEST(xRenderCompositeReq);
21972 : swaps(&stuff->length, n);
21973 : swapl(&stuff->src, n);
21974 : swapl(&stuff->mask, n);
21975 : swapl(&stuff->dst, n);
21976 : swaps(&stuff->xSrc, n);
21977 : swaps(&stuff->ySrc, n);
21978 : swaps(&stuff->xMask, n);
21979 : swaps(&stuff->yMask, n);
21980 : swaps(&stuff->xDst, n);
21981 : swaps(&stuff->yDst, n);
21982 : swaps(&stuff->width, n);
21983 : swaps(&stuff->height, n);
21984 : return (*ProcRenderVector[stuff->renderReqType]) (client);
21988 :SProcRenderScale (ClientPtr client)
21991 : REQUEST(xRenderScaleReq);
21992 : swaps(&stuff->length, n);
21993 : swapl(&stuff->src, n);
21994 : swapl(&stuff->dst, n);
21995 : swapl(&stuff->colorScale, n);
21996 : swapl(&stuff->alphaScale, n);
21997 : swaps(&stuff->xSrc, n);
21998 : swaps(&stuff->ySrc, n);
21999 : swaps(&stuff->xDst, n);
22000 : swaps(&stuff->yDst, n);
22001 : swaps(&stuff->width, n);
22002 : swaps(&stuff->height, n);
22003 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22007 :SProcRenderTrapezoids (ClientPtr client)
22010 : REQUEST(xRenderTrapezoidsReq);
22012 : REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
22013 : swaps (&stuff->length, n);
22014 : swapl (&stuff->src, n);
22015 : swapl (&stuff->dst, n);
22016 : swapl (&stuff->maskFormat, n);
22017 : swaps (&stuff->xSrc, n);
22018 : swaps (&stuff->ySrc, n);
22019 : SwapRestL(stuff);
22020 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22024 :SProcRenderTriangles (ClientPtr client)
22027 : REQUEST(xRenderTrianglesReq);
22029 : REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
22030 : swaps (&stuff->length, n);
22031 : swapl (&stuff->src, n);
22032 : swapl (&stuff->dst, n);
22033 : swapl (&stuff->maskFormat, n);
22034 : swaps (&stuff->xSrc, n);
22035 : swaps (&stuff->ySrc, n);
22036 : SwapRestL(stuff);
22037 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22041 :SProcRenderTriStrip (ClientPtr client)
22044 : REQUEST(xRenderTriStripReq);
22046 : REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
22047 : swaps (&stuff->length, n);
22048 : swapl (&stuff->src, n);
22049 : swapl (&stuff->dst, n);
22050 : swapl (&stuff->maskFormat, n);
22051 : swaps (&stuff->xSrc, n);
22052 : swaps (&stuff->ySrc, n);
22053 : SwapRestL(stuff);
22054 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22058 :SProcRenderTriFan (ClientPtr client)
22061 : REQUEST(xRenderTriFanReq);
22063 : REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
22064 : swaps (&stuff->length, n);
22065 : swapl (&stuff->src, n);
22066 : swapl (&stuff->dst, n);
22067 : swapl (&stuff->maskFormat, n);
22068 : swaps (&stuff->xSrc, n);
22069 : swaps (&stuff->ySrc, n);
22070 : SwapRestL(stuff);
22071 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22075 :SProcRenderColorTrapezoids (ClientPtr client)
22077 : return BadImplementation;
22081 :SProcRenderColorTriangles (ClientPtr client)
22083 : return BadImplementation;
22087 :SProcRenderTransform (ClientPtr client)
22089 : return BadImplementation;
22093 :SProcRenderCreateGlyphSet (ClientPtr client)
22096 : REQUEST(xRenderCreateGlyphSetReq);
22097 : swaps(&stuff->length, n);
22098 : swapl(&stuff->gsid, n);
22099 : swapl(&stuff->format, n);
22100 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22104 :SProcRenderReferenceGlyphSet (ClientPtr client)
22107 : REQUEST(xRenderReferenceGlyphSetReq);
22108 : swaps(&stuff->length, n);
22109 : swapl(&stuff->gsid, n);
22110 : swapl(&stuff->existing, n);
22111 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22115 :SProcRenderFreeGlyphSet (ClientPtr client)
22118 : REQUEST(xRenderFreeGlyphSetReq);
22119 : swaps(&stuff->length, n);
22120 : swapl(&stuff->glyphset, n);
22121 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22125 :SProcRenderAddGlyphs (ClientPtr client)
22132 : REQUEST(xRenderAddGlyphsReq);
22133 : swaps(&stuff->length, n);
22134 : swapl(&stuff->glyphset, n);
22135 : swapl(&stuff->nglyphs, n);
22136 : if (stuff->nglyphs & 0xe0000000)
22137 : return BadLength;
22138 : end = (CARD8 *) stuff + (client->req_len << 2);
22139 : gids = (CARD32 *) (stuff + 1);
22140 : gi = (xGlyphInfo *) (gids + stuff->nglyphs);
22141 : if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
22142 : return BadLength;
22143 : if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
22144 : return BadLength;
22145 : for (i = 0; i < stuff->nglyphs; i++)
22147 : swapl (&gids[i], n);
22148 : swaps (&gi[i].width, n);
22149 : swaps (&gi[i].height, n);
22150 : swaps (&gi[i].x, n);
22151 : swaps (&gi[i].y, n);
22152 : swaps (&gi[i].xOff, n);
22153 : swaps (&gi[i].yOff, n);
22155 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22159 :SProcRenderAddGlyphsFromPicture (ClientPtr client)
22161 : return BadImplementation;
22165 :SProcRenderFreeGlyphs (ClientPtr client)
22168 : REQUEST(xRenderFreeGlyphsReq);
22169 : swaps(&stuff->length, n);
22170 : swapl(&stuff->glyphset, n);
22171 : SwapRestL(stuff);
22172 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22176 :SProcRenderCompositeGlyphs (ClientPtr client)
22186 : REQUEST(xRenderCompositeGlyphsReq);
22188 : switch (stuff->renderReqType) {
22189 : default: size = 1; break;
22190 : case X_RenderCompositeGlyphs16: size = 2; break;
22191 : case X_RenderCompositeGlyphs32: size = 4; break;
22194 : swaps(&stuff->length, n);
22195 : swapl(&stuff->src, n);
22196 : swapl(&stuff->dst, n);
22197 : swapl(&stuff->maskFormat, n);
22198 : swapl(&stuff->glyphset, n);
22199 : swaps(&stuff->xSrc, n);
22200 : swaps(&stuff->ySrc, n);
22201 : buffer = (CARD8 *) (stuff + 1);
22202 : end = (CARD8 *) stuff + (client->req_len << 2);
22203 : while (buffer + sizeof (xGlyphElt) < end)
22205 : elt = (xGlyphElt *) buffer;
22206 : buffer += sizeof (xGlyphElt);
22208 : swaps (&elt->deltax, n);
22209 : swaps (&elt->deltay, n);
22214 : swapl (buffer, n);
22219 : space = size * i;
22227 : swaps (buffer, n);
22234 : swapl (buffer, n);
22240 : buffer += 4 - (space & 3);
22243 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22247 :SProcRenderFillRectangles (ClientPtr client)
22250 : REQUEST(xRenderFillRectanglesReq);
22252 : REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
22253 : swaps(&stuff->length, n);
22254 : swapl(&stuff->dst, n);
22255 : swaps(&stuff->color.red, n);
22256 : swaps(&stuff->color.green, n);
22257 : swaps(&stuff->color.blue, n);
22258 : swaps(&stuff->color.alpha, n);
22259 : SwapRestS(stuff);
22260 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22264 :SProcRenderCreateCursor (ClientPtr client)
22267 : REQUEST(xRenderCreateCursorReq);
22268 : REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
22270 : swaps(&stuff->length, n);
22271 : swapl(&stuff->cid, n);
22272 : swapl(&stuff->src, n);
22273 : swaps(&stuff->x, n);
22274 : swaps(&stuff->y, n);
22275 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22279 :SProcRenderSetPictureTransform (ClientPtr client)
22282 : REQUEST(xRenderSetPictureTransformReq);
22283 : REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
22285 : swaps(&stuff->length, n);
22286 : swapl(&stuff->picture, n);
22287 : swapl(&stuff->transform.matrix11, n);
22288 : swapl(&stuff->transform.matrix12, n);
22289 : swapl(&stuff->transform.matrix13, n);
22290 : swapl(&stuff->transform.matrix21, n);
22291 : swapl(&stuff->transform.matrix22, n);
22292 : swapl(&stuff->transform.matrix23, n);
22293 : swapl(&stuff->transform.matrix31, n);
22294 : swapl(&stuff->transform.matrix32, n);
22295 : swapl(&stuff->transform.matrix33, n);
22296 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22300 :SProcRenderQueryFilters (ClientPtr client)
22303 : REQUEST (xRenderQueryFiltersReq);
22304 : REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
22306 : swaps(&stuff->length, n);
22307 : swapl(&stuff->drawable, n);
22308 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22312 :SProcRenderSetPictureFilter (ClientPtr client)
22315 : REQUEST (xRenderSetPictureFilterReq);
22316 : REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
22318 : swaps(&stuff->length, n);
22319 : swapl(&stuff->picture, n);
22320 : swaps(&stuff->nbytes, n);
22321 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22325 :SProcRenderCreateAnimCursor (ClientPtr client)
22328 : REQUEST (xRenderCreateAnimCursorReq);
22329 : REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
22331 : swaps(&stuff->length, n);
22332 : swapl(&stuff->cid, n);
22333 : SwapRestL(stuff);
22334 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22338 :SProcRenderAddTraps (ClientPtr client)
22341 : REQUEST (xRenderAddTrapsReq);
22342 : REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
22344 : swaps(&stuff->length, n);
22345 : swapl(&stuff->picture, n);
22346 : swaps(&stuff->xOff, n);
22347 : swaps(&stuff->yOff, n);
22348 : SwapRestL(stuff);
22349 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22353 :SProcRenderCreateSolidFill(ClientPtr client)
22356 : REQUEST (xRenderCreateSolidFillReq);
22357 : REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
22359 : swaps(&stuff->length, n);
22360 : swapl(&stuff->pid, n);
22361 : swaps(&stuff->color.alpha, n);
22362 : swaps(&stuff->color.red, n);
22363 : swaps(&stuff->color.green, n);
22364 : swaps(&stuff->color.blue, n);
22365 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22368 :static void swapStops(void *stuff, int n)
22373 : stops = (CARD32 *)(stuff);
22374 : for (i = 0; i < n; ++i) {
22378 : colors = (CARD16 *)(stops);
22379 : for (i = 0; i < 4*n; ++i) {
22386 :SProcRenderCreateLinearGradient (ClientPtr client)
22390 : REQUEST (xRenderCreateLinearGradientReq);
22391 : REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
22393 : swaps(&stuff->length, n);
22394 : swapl(&stuff->pid, n);
22395 : swapl(&stuff->p1.x, n);
22396 : swapl(&stuff->p1.y, n);
22397 : swapl(&stuff->p2.x, n);
22398 : swapl(&stuff->p2.y, n);
22399 : swapl(&stuff->nStops, n);
22401 : len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
22402 : if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
22403 : return BadLength;
22405 : swapStops(stuff+1, stuff->nStops);
22407 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22411 :SProcRenderCreateRadialGradient (ClientPtr client)
22415 : REQUEST (xRenderCreateRadialGradientReq);
22416 : REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
22418 : swaps(&stuff->length, n);
22419 : swapl(&stuff->pid, n);
22420 : swapl(&stuff->inner.x, n);
22421 : swapl(&stuff->inner.y, n);
22422 : swapl(&stuff->outer.x, n);
22423 : swapl(&stuff->outer.y, n);
22424 : swapl(&stuff->inner_radius, n);
22425 : swapl(&stuff->outer_radius, n);
22426 : swapl(&stuff->nStops, n);
22428 : len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
22429 : if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
22430 : return BadLength;
22432 : swapStops(stuff+1, stuff->nStops);
22434 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22438 :SProcRenderCreateConicalGradient (ClientPtr client)
22442 : REQUEST (xRenderCreateConicalGradientReq);
22443 : REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
22445 : swaps(&stuff->length, n);
22446 : swapl(&stuff->pid, n);
22447 : swapl(&stuff->center.x, n);
22448 : swapl(&stuff->center.y, n);
22449 : swapl(&stuff->angle, n);
22450 : swapl(&stuff->nStops, n);
22452 : len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
22453 : if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
22454 : return BadLength;
22456 : swapStops(stuff+1, stuff->nStops);
22458 : return (*ProcRenderVector[stuff->renderReqType]) (client);
22462 :SProcRenderDispatch (ClientPtr client)
22466 : if (stuff->data < RenderNumberRequests)
22467 : return (*SProcRenderVector[stuff->data]) (client);
22469 : return BadRequest;
22473 :#include "panoramiX.h"
22474 :#include "panoramiXsrv.h"
22476 :#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
22477 : pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
22478 : if (!pPicture) { \
22479 : client->errorValue = pid; \
22484 :#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
22485 : if (pid == None) \
22488 : VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
22492 :int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
22494 :unsigned long XRT_PICTURE;
22497 :PanoramiXRenderCreatePicture (ClientPtr client)
22499 : REQUEST(xRenderCreatePictureReq);
22500 : PanoramiXRes *refDraw, *newPict;
22501 : int result = Success, j;
22503 : REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
22504 : if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
22505 : client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
22506 : return BadDrawable;
22507 : if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
22509 : newPict->type = XRT_PICTURE;
22510 : newPict->info[0].id = stuff->pid;
22512 : if (refDraw->type == XRT_WINDOW &&
22513 : stuff->drawable == WindowTable[0]->drawable.id)
22515 : newPict->u.pict.root = TRUE;
22518 : newPict->u.pict.root = FALSE;
22520 : for(j = 1; j < PanoramiXNumScreens; j++)
22521 : newPict->info[j].id = FakeClientID(client->index);
22523 : FOR_NSCREENS_BACKWARD(j) {
22524 : stuff->pid = newPict->info[j].id;
22525 : stuff->drawable = refDraw->info[j].id;
22526 : result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
22527 : if(result != Success) break;
22530 : if (result == Success)
22531 : AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
22539 :PanoramiXRenderChangePicture (ClientPtr client)
22541 : PanoramiXRes *pict;
22542 : int result = Success, j;
22543 : REQUEST(xRenderChangePictureReq);
22545 : REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
22547 : VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
22548 : RenderErrBase + BadPicture);
22550 : FOR_NSCREENS_BACKWARD(j) {
22551 : stuff->picture = pict->info[j].id;
22552 : result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
22553 : if(result != Success) break;
22560 :PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
22562 : REQUEST(xRenderSetPictureClipRectanglesReq);
22563 : int result = Success, j;
22564 : PanoramiXRes *pict;
22566 : REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
22568 : VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
22569 : RenderErrBase + BadPicture);
22571 : FOR_NSCREENS_BACKWARD(j) {
22572 : stuff->picture = pict->info[j].id;
22573 : result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
22574 : if(result != Success) break;
22581 :PanoramiXRenderSetPictureTransform (ClientPtr client)
22583 : REQUEST(xRenderSetPictureTransformReq);
22584 : int result = Success, j;
22585 : PanoramiXRes *pict;
22587 : REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
22589 : VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
22590 : RenderErrBase + BadPicture);
22592 : FOR_NSCREENS_BACKWARD(j) {
22593 : stuff->picture = pict->info[j].id;
22594 : result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
22595 : if(result != Success) break;
22602 :PanoramiXRenderSetPictureFilter (ClientPtr client)
22604 : REQUEST(xRenderSetPictureFilterReq);
22605 : int result = Success, j;
22606 : PanoramiXRes *pict;
22608 : REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
22610 : VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
22611 : RenderErrBase + BadPicture);
22613 : FOR_NSCREENS_BACKWARD(j) {
22614 : stuff->picture = pict->info[j].id;
22615 : result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
22616 : if(result != Success) break;
22623 :PanoramiXRenderFreePicture (ClientPtr client)
22625 : PanoramiXRes *pict;
22626 : int result = Success, j;
22627 : REQUEST(xRenderFreePictureReq);
22629 : REQUEST_SIZE_MATCH(xRenderFreePictureReq);
22631 : client->errorValue = stuff->picture;
22633 : VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess,
22634 : RenderErrBase + BadPicture);
22637 : FOR_NSCREENS_BACKWARD(j) {
22638 : stuff->picture = pict->info[j].id;
22639 : result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
22640 : if(result != Success) break;
22643 : /* Since ProcRenderFreePicture is using FreeResource, it will free
22644 : our resource for us on the last pass through the loop above */
22650 :PanoramiXRenderComposite (ClientPtr client)
22652 : PanoramiXRes *src, *msk, *dst;
22653 : int result = Success, j;
22654 : xRenderCompositeReq orig;
22655 : REQUEST(xRenderCompositeReq);
22657 : REQUEST_SIZE_MATCH(xRenderCompositeReq);
22659 : VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
22660 : RenderErrBase + BadPicture);
22661 : VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess,
22662 : RenderErrBase + BadPicture);
22663 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
22664 : RenderErrBase + BadPicture);
22668 : FOR_NSCREENS_FORWARD(j) {
22669 : stuff->src = src->info[j].id;
22670 : if (src->u.pict.root)
22672 : stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
22673 : stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
22675 : stuff->dst = dst->info[j].id;
22676 : if (dst->u.pict.root)
22678 : stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
22679 : stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
22683 : stuff->mask = msk->info[j].id;
22684 : if (msk->u.pict.root)
22686 : stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
22687 : stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
22690 : result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
22691 : if(result != Success) break;
22698 :PanoramiXRenderCompositeGlyphs (ClientPtr client)
22700 : PanoramiXRes *src, *dst;
22701 : int result = Success, j;
22702 : REQUEST(xRenderCompositeGlyphsReq);
22703 : xGlyphElt origElt, *elt;
22704 : INT16 xSrc, ySrc;
22706 : REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
22707 : VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
22708 : RenderErrBase + BadPicture);
22709 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
22710 : RenderErrBase + BadPicture);
22712 : if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
22713 : sizeof (xGlyphElt)))
22715 : elt = (xGlyphElt *) (stuff + 1);
22717 : xSrc = stuff->xSrc;
22718 : ySrc = stuff->ySrc;
22719 : FOR_NSCREENS_FORWARD(j) {
22720 : stuff->src = src->info[j].id;
22721 : if (src->u.pict.root)
22723 : stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
22724 : stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
22726 : stuff->dst = dst->info[j].id;
22727 : if (dst->u.pict.root)
22729 : elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
22730 : elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
22732 : result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
22733 : if(result != Success) break;
22741 :PanoramiXRenderFillRectangles (ClientPtr client)
22743 : PanoramiXRes *dst;
22744 : int result = Success, j;
22745 : REQUEST(xRenderFillRectanglesReq);
22749 : REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
22750 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
22751 : RenderErrBase + BadPicture);
22752 : extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
22754 : (extra = (char *) ALLOCATE_LOCAL (extra_len)))
22756 : memcpy (extra, stuff + 1, extra_len);
22757 : FOR_NSCREENS_FORWARD(j) {
22758 : if (j) memcpy (stuff + 1, extra, extra_len);
22759 : if (dst->u.pict.root)
22761 : int x_off = panoramiXdataPtr[j].x;
22762 : int y_off = panoramiXdataPtr[j].y;
22764 : if(x_off || y_off) {
22765 : xRectangle *rects = (xRectangle *) (stuff + 1);
22766 : int i = extra_len / sizeof (xRectangle);
22770 : rects->x -= x_off;
22771 : rects->y -= y_off;
22776 : stuff->dst = dst->info[j].id;
22777 : result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
22778 : if(result != Success) break;
22780 : DEALLOCATE_LOCAL(extra);
22787 :PanoramiXRenderTrapezoids(ClientPtr client)
22789 : PanoramiXRes *src, *dst;
22790 : int result = Success, j;
22791 : REQUEST(xRenderTrapezoidsReq);
22795 : REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
22797 : VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
22798 : RenderErrBase + BadPicture);
22799 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
22800 : RenderErrBase + BadPicture);
22802 : extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
22805 : (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
22806 : memcpy (extra, stuff + 1, extra_len);
22808 : FOR_NSCREENS_FORWARD(j) {
22809 : if (j) memcpy (stuff + 1, extra, extra_len);
22810 : if (dst->u.pict.root) {
22811 : int x_off = panoramiXdataPtr[j].x;
22812 : int y_off = panoramiXdataPtr[j].y;
22814 : if(x_off || y_off) {
22815 : xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
22816 : int i = extra_len / sizeof (xTrapezoid);
22819 : trap->top -= y_off;
22820 : trap->bottom -= y_off;
22821 : trap->left.p1.x -= x_off;
22822 : trap->left.p1.y -= y_off;
22823 : trap->left.p2.x -= x_off;
22824 : trap->left.p2.y -= y_off;
22825 : trap->right.p1.x -= x_off;
22826 : trap->right.p1.y -= y_off;
22827 : trap->right.p2.x -= x_off;
22828 : trap->right.p2.y -= y_off;
22834 : stuff->src = src->info[j].id;
22835 : stuff->dst = dst->info[j].id;
22837 : (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
22839 : if(result != Success) break;
22842 : DEALLOCATE_LOCAL(extra);
22849 :PanoramiXRenderTriangles(ClientPtr client)
22851 : PanoramiXRes *src, *dst;
22852 : int result = Success, j;
22853 : REQUEST(xRenderTrianglesReq);
22857 : REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
22859 : VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
22860 : RenderErrBase + BadPicture);
22861 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
22862 : RenderErrBase + BadPicture);
22864 : extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
22867 : (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
22868 : memcpy (extra, stuff + 1, extra_len);
22870 : FOR_NSCREENS_FORWARD(j) {
22871 : if (j) memcpy (stuff + 1, extra, extra_len);
22872 : if (dst->u.pict.root) {
22873 : int x_off = panoramiXdataPtr[j].x;
22874 : int y_off = panoramiXdataPtr[j].y;
22876 : if(x_off || y_off) {
22877 : xTriangle *tri = (xTriangle *) (stuff + 1);
22878 : int i = extra_len / sizeof (xTriangle);
22881 : tri->p1.x -= x_off;
22882 : tri->p1.y -= y_off;
22883 : tri->p2.x -= x_off;
22884 : tri->p2.y -= y_off;
22885 : tri->p3.x -= x_off;
22886 : tri->p3.y -= y_off;
22892 : stuff->src = src->info[j].id;
22893 : stuff->dst = dst->info[j].id;
22895 : (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
22897 : if(result != Success) break;
22900 : DEALLOCATE_LOCAL(extra);
22907 :PanoramiXRenderTriStrip(ClientPtr client)
22909 : PanoramiXRes *src, *dst;
22910 : int result = Success, j;
22911 : REQUEST(xRenderTriStripReq);
22915 : REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
22917 : VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
22918 : RenderErrBase + BadPicture);
22919 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
22920 : RenderErrBase + BadPicture);
22922 : extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
22925 : (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
22926 : memcpy (extra, stuff + 1, extra_len);
22928 : FOR_NSCREENS_FORWARD(j) {
22929 : if (j) memcpy (stuff + 1, extra, extra_len);
22930 : if (dst->u.pict.root) {
22931 : int x_off = panoramiXdataPtr[j].x;
22932 : int y_off = panoramiXdataPtr[j].y;
22934 : if(x_off || y_off) {
22935 : xPointFixed *fixed = (xPointFixed *) (stuff + 1);
22936 : int i = extra_len / sizeof (xPointFixed);
22939 : fixed->x -= x_off;
22940 : fixed->y -= y_off;
22946 : stuff->src = src->info[j].id;
22947 : stuff->dst = dst->info[j].id;
22949 : (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
22951 : if(result != Success) break;
22954 : DEALLOCATE_LOCAL(extra);
22961 :PanoramiXRenderTriFan(ClientPtr client)
22963 : PanoramiXRes *src, *dst;
22964 : int result = Success, j;
22965 : REQUEST(xRenderTriFanReq);
22969 : REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
22971 : VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
22972 : RenderErrBase + BadPicture);
22973 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
22974 : RenderErrBase + BadPicture);
22976 : extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
22979 : (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
22980 : memcpy (extra, stuff + 1, extra_len);
22982 : FOR_NSCREENS_FORWARD(j) {
22983 : if (j) memcpy (stuff + 1, extra, extra_len);
22984 : if (dst->u.pict.root) {
22985 : int x_off = panoramiXdataPtr[j].x;
22986 : int y_off = panoramiXdataPtr[j].y;
22988 : if(x_off || y_off) {
22989 : xPointFixed *fixed = (xPointFixed *) (stuff + 1);
22990 : int i = extra_len / sizeof (xPointFixed);
22993 : fixed->x -= x_off;
22994 : fixed->y -= y_off;
23000 : stuff->src = src->info[j].id;
23001 : stuff->dst = dst->info[j].id;
23003 : (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
23005 : if(result != Success) break;
23008 : DEALLOCATE_LOCAL(extra);
23014 :#if 0 /* Not implemented yet */
23017 :PanoramiXRenderColorTrapezoids(ClientPtr client)
23019 : PanoramiXRes *src, *dst;
23020 : int result = Success, j;
23021 : REQUEST(xRenderColorTrapezoidsReq);
23025 : REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
23027 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
23028 : RenderErrBase + BadPicture);
23030 : extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
23033 : (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
23034 : memcpy (extra, stuff + 1, extra_len);
23036 : FOR_NSCREENS_FORWARD(j) {
23037 : if (j) memcpy (stuff + 1, extra, extra_len);
23038 : if (dst->u.pict.root) {
23039 : int x_off = panoramiXdataPtr[j].x;
23040 : int y_off = panoramiXdataPtr[j].y;
23042 : if(x_off || y_off) {
23047 : stuff->dst = dst->info[j].id;
23049 : (*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
23051 : if(result != Success) break;
23054 : DEALLOCATE_LOCAL(extra);
23061 :PanoramiXRenderColorTriangles(ClientPtr client)
23063 : PanoramiXRes *src, *dst;
23064 : int result = Success, j;
23065 : REQUEST(xRenderColorTrianglesReq);
23069 : REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
23071 : VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
23072 : RenderErrBase + BadPicture);
23074 : extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
23077 : (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
23078 : memcpy (extra, stuff + 1, extra_len);
23080 : FOR_NSCREENS_FORWARD(j) {
23081 : if (j) memcpy (stuff + 1, extra, extra_len);
23082 : if (dst->u.pict.root) {
23083 : int x_off = panoramiXdataPtr[j].x;
23084 : int y_off = panoramiXdataPtr[j].y;
23086 : if(x_off || y_off) {
23091 : stuff->dst = dst->info[j].id;
23093 : (*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
23095 : if(result != Success) break;
23098 : DEALLOCATE_LOCAL(extra);
23107 :PanoramiXRenderAddTraps (ClientPtr client)
23109 : PanoramiXRes *picture;
23110 : int result = Success, j;
23111 : REQUEST(xRenderAddTrapsReq);
23114 : INT16 x_off, y_off;
23116 : REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
23117 : VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess,
23118 : RenderErrBase + BadPicture);
23119 : extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
23121 : (extra = (char *) ALLOCATE_LOCAL (extra_len)))
23123 : memcpy (extra, stuff + 1, extra_len);
23124 : x_off = stuff->xOff;
23125 : y_off = stuff->yOff;
23126 : FOR_NSCREENS_FORWARD(j) {
23127 : if (j) memcpy (stuff + 1, extra, extra_len);
23128 : stuff->picture = picture->info[j].id;
23130 : if (picture->u.pict.root)
23132 : stuff->xOff = x_off + panoramiXdataPtr[j].x;
23133 : stuff->yOff = y_off + panoramiXdataPtr[j].y;
23135 : result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
23136 : if(result != Success) break;
23138 : DEALLOCATE_LOCAL(extra);
23145 :PanoramiXRenderInit (void)
23149 : XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
23150 : for (i = 0; i < RenderNumberRequests; i++)
23151 : PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
23153 : * Stuff in Xinerama aware request processing hooks
23155 : ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
23156 : ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
23157 : ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
23158 : ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
23159 : ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
23160 : ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
23161 : ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
23162 : ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
23163 : ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
23164 : ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
23165 : ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
23167 : ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
23168 : ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
23169 : ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
23170 : ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
23171 : ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
23175 :PanoramiXRenderReset (void)
23178 : for (i = 0; i < RenderNumberRequests; i++)
23179 : ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
23182 :#endif /* PANORAMIX */
23184 * Total samples for file : "/home/cworth/src/xorg/xserver/render/picture.c"
23192 : * Copyright © 2000 SuSE, Inc.
23194 : * Permission to use, copy, modify, distribute, and sell this software and its
23195 : * documentation for any purpose is hereby granted without fee, provided that
23196 : * the above copyright notice appear in all copies and that both that
23197 : * copyright notice and this permission notice appear in supporting
23198 : * documentation, and that the name of SuSE not be used in advertising or
23199 : * publicity pertaining to distribution of the software without specific,
23200 : * written prior permission. SuSE makes no representations about the
23201 : * suitability of this software for any purpose. It is provided "as is"
23202 : * without express or implied warranty.
23204 : * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
23205 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
23206 : * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23207 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
23208 : * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23209 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23211 : * Author: Keith Packard, SuSE, Inc.
23214 :#ifdef HAVE_DIX_CONFIG_H
23215 :#include <dix-config.h>
23219 :#include "scrnintstr.h"
23221 :#include "regionstr.h"
23222 :#include "validate.h"
23223 :#include "windowstr.h"
23224 :#include "input.h"
23225 :#include "resource.h"
23226 :#include "colormapst.h"
23227 :#include "cursorstr.h"
23228 :#include "dixstruct.h"
23229 :#include "gcstruct.h"
23230 :#include "servermd.h"
23231 :#include "picturestr.h"
23233 :_X_EXPORT int PictureScreenPrivateIndex = -1;
23234 :int PictureWindowPrivateIndex;
23235 :static int PictureGeneration;
23236 :RESTYPE PictureType;
23237 :RESTYPE PictFormatType;
23238 :RESTYPE GlyphSetType;
23239 :int PictureCmapPolicy = PictureCmapPolicyDefault;
23241 :/* Picture Private machinery */
23243 :static int picturePrivateCount;
23246 :ResetPicturePrivateIndex (void)
23248 : picturePrivateCount = 0;
23252 :AllocatePicturePrivateIndex (void)
23254 : return picturePrivateCount++;
23258 :AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
23260 : PictureScreenPtr ps = GetPictureScreen(pScreen);
23261 : unsigned int oldamount;
23263 : /* Round up sizes for proper alignment */
23264 : amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
23266 : if (index2 >= ps->PicturePrivateLen)
23268 : unsigned int *nsizes;
23270 : nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
23271 : (index2 + 1) * sizeof(unsigned int));
23274 : while (ps->PicturePrivateLen <= index2)
23276 : nsizes[ps->PicturePrivateLen++] = 0;
23277 : ps->totalPictureSize += sizeof(DevUnion);
23279 : ps->PicturePrivateSizes = nsizes;
23281 : oldamount = ps->PicturePrivateSizes[index2];
23282 : if (amount > oldamount)
23284 : ps->PicturePrivateSizes[index2] = amount;
23285 : ps->totalPictureSize += (amount - oldamount);
23293 :PictureDestroyWindow (WindowPtr pWindow)
23295 : ScreenPtr pScreen = pWindow->drawable.pScreen;
23296 : PicturePtr pPicture;
23297 : PictureScreenPtr ps = GetPictureScreen(pScreen);
23300 : while ((pPicture = GetPictureWindow(pWindow)))
23302 : SetPictureWindow(pWindow, pPicture->pNext);
23303 : if (pPicture->id)
23304 : FreeResource (pPicture->id, PictureType);
23305 : FreePicture ((pointer) pPicture, pPicture->id);
23307 : pScreen->DestroyWindow = ps->DestroyWindow;
23308 : ret = (*pScreen->DestroyWindow) (pWindow);
23309 : ps->DestroyWindow = pScreen->DestroyWindow;
23310 : pScreen->DestroyWindow = PictureDestroyWindow;
23315 :PictureCloseScreen (int index, ScreenPtr pScreen)
23317 : PictureScreenPtr ps = GetPictureScreen(pScreen);
23321 : pScreen->CloseScreen = ps->CloseScreen;
23322 : ret = (*pScreen->CloseScreen) (index, pScreen);
23323 : PictureResetFilters (pScreen);
23324 : for (n = 0; n < ps->nformats; n++)
23325 : if (ps->formats[n].type == PictTypeIndexed)
23326 : (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
23327 : GlyphUninit (pScreen);
23328 : SetPictureScreen(pScreen, 0);
23329 : if (ps->PicturePrivateSizes)
23330 : xfree (ps->PicturePrivateSizes);
23331 : xfree (ps->formats);
23337 :PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
23339 : ScreenPtr pScreen = pColormap->pScreen;
23340 : PictureScreenPtr ps = GetPictureScreen(pScreen);
23342 : pScreen->StoreColors = ps->StoreColors;
23343 : (*pScreen->StoreColors) (pColormap, ndef, pdef);
23344 : ps->StoreColors = pScreen->StoreColors;
23345 : pScreen->StoreColors = PictureStoreColors;
23347 : if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
23349 : PictFormatPtr format = ps->formats;
23350 : int nformats = ps->nformats;
23352 : while (nformats--)
23354 : if (format->type == PictTypeIndexed &&
23355 : format->index.pColormap == pColormap)
23357 : (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
23366 :visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
23371 : for (d = 0; d < pScreen->numDepths; d++)
23373 : pDepth = &pScreen->allowedDepths[d];
23374 : for (v = 0; v < pDepth->numVids; v++)
23375 : if (pDepth->vids[v] == pVisual->vid)
23376 : return pDepth->depth;
23381 :typedef struct _formatInit {
23384 :} FormatInitRec, *FormatInitPtr;
23387 :addFormat (FormatInitRec formats[256],
23394 : for (n = 0; n < nformat; n++)
23395 : if (formats[n].format == format && formats[n].depth == depth)
23397 : formats[nformat].format = format;
23398 : formats[nformat].depth = depth;
23399 : return ++nformat;
23402 :#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
23405 :PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
23408 : PictFormatPtr pFormats;
23409 : FormatInitRec formats[1024];
23412 : VisualPtr pVisual;
23421 : /* formats required by protocol */
23422 : formats[nformats].format = PICT_a1;
23423 : formats[nformats].depth = 1;
23425 : formats[nformats].format = PICT_FORMAT(BitsPerPixel(8),
23428 : formats[nformats].depth = 8;
23430 : formats[nformats].format = PICT_FORMAT(BitsPerPixel(4),
23433 : formats[nformats].depth = 4;
23435 : formats[nformats].format = PICT_a8r8g8b8;
23436 : formats[nformats].depth = 32;
23438 : formats[nformats].format = PICT_x8r8g8b8;
23439 : formats[nformats].depth = 32;
23442 : /* now look through the depths and visuals adding other formats */
23443 : for (v = 0; v < pScreen->numVisuals; v++)
23445 : pVisual = &pScreen->visuals[v];
23446 : depth = visualDepth (pScreen, pVisual);
23449 : bpp = BitsPerPixel (depth);
23450 : switch (pVisual->class) {
23451 : case DirectColor:
23453 : r = Ones (pVisual->redMask);
23454 : g = Ones (pVisual->greenMask);
23455 : b = Ones (pVisual->blueMask);
23456 : type = PICT_TYPE_OTHER;
23458 : * Current rendering code supports only two direct formats,
23459 : * fields must be packed together at the bottom of the pixel
23460 : * and must be either RGB or BGR
23462 : if (pVisual->offsetBlue == 0 &&
23463 : pVisual->offsetGreen == b &&
23464 : pVisual->offsetRed == b + g)
23466 : type = PICT_TYPE_ARGB;
23468 : else if (pVisual->offsetRed == 0 &&
23469 : pVisual->offsetGreen == r &&
23470 : pVisual->offsetBlue == r + g)
23472 : type = PICT_TYPE_ABGR;
23474 : if (type != PICT_TYPE_OTHER)
23476 : format = PICT_FORMAT(bpp, type, 0, r, g, b);
23477 : nformats = addFormat (formats, nformats, format, depth);
23480 : case StaticColor:
23481 : case PseudoColor:
23482 : format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
23483 : nformats = addFormat (formats, nformats, format, depth);
23487 : format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
23488 : nformats = addFormat (formats, nformats, format, depth);
23493 : * Walk supported depths and add useful Direct formats
23495 : for (d = 0; d < pScreen->numDepths; d++)
23497 : pDepth = &pScreen->allowedDepths[d];
23498 : bpp = BitsPerPixel (pDepth->depth);
23502 : /* depth 12 formats */
23503 : if (pDepth->depth >= 12)
23505 : nformats = addFormat (formats, nformats,
23506 : PICT_x4r4g4b4, pDepth->depth);
23507 : nformats = addFormat (formats, nformats,
23508 : PICT_x4b4g4r4, pDepth->depth);
23510 : /* depth 15 formats */
23511 : if (pDepth->depth >= 15)
23513 : nformats = addFormat (formats, nformats,
23514 : PICT_x1r5g5b5, pDepth->depth);
23515 : nformats = addFormat (formats, nformats,
23516 : PICT_x1b5g5r5, pDepth->depth);
23518 : /* depth 16 formats */
23519 : if (pDepth->depth >= 16)
23521 : nformats = addFormat (formats, nformats,
23522 : PICT_a1r5g5b5, pDepth->depth);
23523 : nformats = addFormat (formats, nformats,
23524 : PICT_a1b5g5r5, pDepth->depth);
23525 : nformats = addFormat (formats, nformats,
23526 : PICT_r5g6b5, pDepth->depth);
23527 : nformats = addFormat (formats, nformats,
23528 : PICT_b5g6r5, pDepth->depth);
23529 : nformats = addFormat (formats, nformats,
23530 : PICT_a4r4g4b4, pDepth->depth);
23531 : nformats = addFormat (formats, nformats,
23532 : PICT_a4b4g4r4, pDepth->depth);
23536 : if (pDepth->depth >= 24)
23538 : nformats = addFormat (formats, nformats,
23539 : PICT_r8g8b8, pDepth->depth);
23540 : nformats = addFormat (formats, nformats,
23541 : PICT_b8g8r8, pDepth->depth);
23545 : if (pDepth->depth >= 24)
23547 : nformats = addFormat (formats, nformats,
23548 : PICT_x8r8g8b8, pDepth->depth);
23549 : nformats = addFormat (formats, nformats,
23550 : PICT_x8b8g8r8, pDepth->depth);
23557 : pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
23560 : memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
23561 : for (f = 0; f < nformats; f++)
23563 : pFormats[f].id = FakeClientID (0);
23564 : pFormats[f].depth = formats[f].depth;
23565 : format = formats[f].format;
23566 : pFormats[f].format = format;
23567 : switch (PICT_FORMAT_TYPE(format)) {
23568 : case PICT_TYPE_ARGB:
23569 : pFormats[f].type = PictTypeDirect;
23571 : pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
23572 : if (pFormats[f].direct.alphaMask)
23573 : pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
23574 : PICT_FORMAT_G(format) +
23575 : PICT_FORMAT_B(format));
23577 : pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
23578 : pFormats[f].direct.red = (PICT_FORMAT_G(format) +
23579 : PICT_FORMAT_B(format));
23581 : pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
23582 : pFormats[f].direct.green = PICT_FORMAT_B(format);
23584 : pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
23585 : pFormats[f].direct.blue = 0;
23588 : case PICT_TYPE_ABGR:
23589 : pFormats[f].type = PictTypeDirect;
23591 : pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
23592 : if (pFormats[f].direct.alphaMask)
23593 : pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
23594 : PICT_FORMAT_G(format) +
23595 : PICT_FORMAT_R(format));
23597 : pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
23598 : pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
23599 : PICT_FORMAT_R(format));
23601 : pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
23602 : pFormats[f].direct.green = PICT_FORMAT_R(format);
23604 : pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
23605 : pFormats[f].direct.red = 0;
23608 : case PICT_TYPE_A:
23609 : pFormats[f].type = PictTypeDirect;
23611 : pFormats[f].direct.alpha = 0;
23612 : pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
23614 : /* remaining fields already set to zero */
23617 : case PICT_TYPE_COLOR:
23618 : case PICT_TYPE_GRAY:
23619 : pFormats[f].type = PictTypeIndexed;
23620 : pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
23624 : *nformatp = nformats;
23629 :PictureFindVisual (ScreenPtr pScreen, VisualID visual)
23632 : VisualPtr pVisual;
23633 : for (i = 0, pVisual = pScreen->visuals;
23634 : i < pScreen->numVisuals;
23637 : if (pVisual->vid == visual)
23644 :PictureInitIndexedFormats (ScreenPtr pScreen)
23646 : PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
23647 : PictFormatPtr format;
23652 : format = ps->formats;
23653 : nformat = ps->nformats;
23654 : while (nformat--)
23656 : if (format->type == PictTypeIndexed && !format->index.pColormap)
23658 : if (format->index.vid == pScreen->rootVisual)
23659 : format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
23663 : VisualPtr pVisual;
23665 : pVisual = PictureFindVisual (pScreen, format->index.vid);
23666 : if (CreateColormap (FakeClientID (0), pScreen,
23668 : &format->index.pColormap, AllocNone,
23674 : if (!(*ps->InitIndexed) (pScreen, format))
23683 :PictureFinishInit (void)
23687 : for (s = 0; s < screenInfo.numScreens; s++)
23689 : if (!GlyphFinishInit (screenInfo.screens[s]))
23691 : if (!PictureInitIndexedFormats (screenInfo.screens[s]))
23693 : (void) AnimCurInit (screenInfo.screens[s]);
23700 :PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
23702 : PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
23706 : ps->subpixel = subpixel;
23712 :PictureGetSubpixelOrder (ScreenPtr pScreen)
23714 : PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
23717 : return SubPixelUnknown;
23718 : return ps->subpixel;
23722 :PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
23724 : PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
23725 : PictFormatPtr format;
23731 : format = ps->formats;
23732 : nformat = ps->nformats;
23733 : switch (pVisual->class) {
23736 : case StaticColor:
23737 : case PseudoColor:
23738 : type = PictTypeIndexed;
23741 : case DirectColor:
23742 : type = PictTypeDirect;
23747 : while (nformat--)
23749 : if (format->depth == depth && format->type == type)
23751 : if (type == PictTypeIndexed)
23753 : if (format->index.vid == pVisual->vid)
23758 : if (format->direct.redMask << format->direct.red ==
23759 : pVisual->redMask &&
23760 : format->direct.greenMask << format->direct.green ==
23761 : pVisual->greenMask &&
23762 : format->direct.blueMask << format->direct.blue ==
23763 : pVisual->blueMask)
23775 :PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
23777 : PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
23778 : PictFormatPtr format;
23783 : format = ps->formats;
23784 : nformat = ps->nformats;
23785 : while (nformat--)
23787 : if (format->depth == depth && format->format == (f & 0xffffff))
23795 :PictureParseCmapPolicy (const char *name)
23797 : if ( strcmp (name, "default" ) == 0)
23798 : return PictureCmapPolicyDefault;
23799 : else if ( strcmp (name, "mono" ) == 0)
23800 : return PictureCmapPolicyMono;
23801 : else if ( strcmp (name, "gray" ) == 0)
23802 : return PictureCmapPolicyGray;
23803 : else if ( strcmp (name, "color" ) == 0)
23804 : return PictureCmapPolicyColor;
23805 : else if ( strcmp (name, "all" ) == 0)
23806 : return PictureCmapPolicyAll;
23808 : return PictureCmapPolicyInvalid;
23812 :PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
23814 : PictureScreenPtr ps;
23816 : CARD32 type, a, r, g, b;
23818 : if (PictureGeneration != serverGeneration)
23820 : PictureType = CreateNewResourceType (FreePicture);
23821 : if (!PictureType)
23823 : PictFormatType = CreateNewResourceType (FreePictFormat);
23824 : if (!PictFormatType)
23826 : GlyphSetType = CreateNewResourceType (FreeGlyphSet);
23827 : if (!GlyphSetType)
23829 : PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
23830 : if (PictureScreenPrivateIndex < 0)
23832 : PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
23833 : PictureGeneration = serverGeneration;
23834 :#ifdef XResExtension
23835 : RegisterResourceName (PictureType, "PICTURE");
23836 : RegisterResourceName (PictFormatType, "PICTFORMAT");
23837 : RegisterResourceName (GlyphSetType, "GLYPHSET");
23840 : if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
23845 : formats = PictureCreateDefaultFormats (pScreen, &nformats);
23849 : for (n = 0; n < nformats; n++)
23851 : if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
23856 : if (formats[n].type == PictTypeIndexed)
23858 : VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
23859 : if ((pVisual->class | DynamicClass) == PseudoColor)
23860 : type = PICT_TYPE_COLOR;
23862 : type = PICT_TYPE_GRAY;
23863 : a = r = g = b = 0;
23867 : if ((formats[n].direct.redMask|
23868 : formats[n].direct.blueMask|
23869 : formats[n].direct.greenMask) == 0)
23870 : type = PICT_TYPE_A;
23871 : else if (formats[n].direct.red > formats[n].direct.blue)
23872 : type = PICT_TYPE_ARGB;
23874 : type = PICT_TYPE_ABGR;
23875 : a = Ones (formats[n].direct.alphaMask);
23876 : r = Ones (formats[n].direct.redMask);
23877 : g = Ones (formats[n].direct.greenMask);
23878 : b = Ones (formats[n].direct.blueMask);
23880 : formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
23882 : ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
23888 : SetPictureScreen(pScreen, ps);
23889 : if (!GlyphInit (pScreen))
23891 : SetPictureScreen(pScreen, 0);
23897 : ps->totalPictureSize = sizeof (PictureRec);
23898 : ps->PicturePrivateSizes = 0;
23899 : ps->PicturePrivateLen = 0;
23901 : ps->formats = formats;
23902 : ps->fallback = formats;
23903 : ps->nformats = nformats;
23906 : ps->nfilters = 0;
23907 : ps->filterAliases = 0;
23908 : ps->nfilterAliases = 0;
23910 : ps->subpixel = SubPixelUnknown;
23912 : ps->CloseScreen = pScreen->CloseScreen;
23913 : ps->DestroyWindow = pScreen->DestroyWindow;
23914 : ps->StoreColors = pScreen->StoreColors;
23915 : pScreen->DestroyWindow = PictureDestroyWindow;
23916 : pScreen->CloseScreen = PictureCloseScreen;
23917 : pScreen->StoreColors = PictureStoreColors;
23919 : if (!PictureSetDefaultFilters (pScreen))
23921 : PictureResetFilters (pScreen);
23922 : SetPictureScreen(pScreen, 0);
23932 :SetPictureToDefaults (PicturePtr pPicture)
23933 :{ /* SetPictureToDefaults total: 8 0.0087 */
23934 : pPicture->refcnt = 1;
23935 : pPicture->repeat = 0;
23936 : pPicture->graphicsExposures = FALSE;
23937 : pPicture->subWindowMode = ClipByChildren;
23938 : pPicture->polyEdge = PolyEdgeSharp;
23939 : pPicture->polyMode = PolyModePrecise;
23940 : pPicture->freeCompClip = FALSE;
23941 : pPicture->clientClipType = CT_NONE;
23942 : pPicture->componentAlpha = FALSE;
23943 : pPicture->repeatType = RepeatNone;
23945 : pPicture->alphaMap = 0;
23946 : pPicture->alphaOrigin.x = 0;
23947 : pPicture->alphaOrigin.y = 0;
23949 : pPicture->clipOrigin.x = 0;
23950 1 0.0011 : pPicture->clipOrigin.y = 0;
23951 : pPicture->clientClip = 0;
23953 : pPicture->transform = 0;
23955 : pPicture->dither = None;
23956 4 0.0044 : pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
23957 : pPicture->filter_params = 0;
23958 : pPicture->filter_nparams = 0;
23960 : pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
23961 1 0.0011 : pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
23962 1 0.0011 : pPicture->pSourcePict = 0;
23966 :AllocatePicture (ScreenPtr pScreen)
23967 :{ /* AllocatePicture total: 4 0.0044 */
23968 : PictureScreenPtr ps = GetPictureScreen(pScreen);
23969 : PicturePtr pPicture;
23972 : unsigned int *sizes;
23973 : unsigned int size;
23976 3 0.0033 : pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
23979 : ppriv = (DevUnion *)(pPicture + 1);
23980 : pPicture->devPrivates = ppriv;
23981 : sizes = ps->PicturePrivateSizes;
23982 : ptr = (char *)(ppriv + ps->PicturePrivateLen);
23983 : for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
23985 : if ( (size = *sizes) )
23987 : ppriv->ptr = (pointer)ptr;
23991 : ppriv->ptr = (pointer)NULL;
23997 :CreatePicture (Picture pid,
23998 : DrawablePtr pDrawable,
23999 : PictFormatPtr pFormat,
24002 : ClientPtr client,
24004 2 0.0022 :{ /* CreatePicture total: 12 0.0131 */
24005 : PicturePtr pPicture;
24006 2 0.0022 : PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
24008 : pPicture = AllocatePicture (pDrawable->pScreen);
24011 : *error = BadAlloc;
24015 : pPicture->id = pid;
24016 : pPicture->pDrawable = pDrawable;
24017 : pPicture->pFormat = pFormat;
24018 1 0.0011 : pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
24019 1 0.0011 : if (pDrawable->type == DRAWABLE_PIXMAP)
24021 : ++((PixmapPtr)pDrawable)->refcnt;
24022 : pPicture->pNext = 0;
24026 : pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
24027 : SetPictureWindow(((WindowPtr) pDrawable), pPicture);
24030 : SetPictureToDefaults (pPicture);
24033 : *error = ChangePicture (pPicture, vmask, vlist, 0, client);
24035 : *error = Success;
24036 : if (*error == Success)
24037 4 0.0044 : *error = (*ps->CreatePicture) (pPicture);
24038 1 0.0011 : if (*error != Success)
24040 : FreePicture (pPicture, (XID) 0);
24046 :static CARD32 xRenderColorToCard32(xRenderColor c)
24049 : (c.alpha >> 8 << 24) |
24050 : (c.red >> 8 << 16) |
24051 : (c.green & 0xff00) |
24055 :static unsigned int premultiply(unsigned int x)
24057 : unsigned int a = x >> 24;
24058 : unsigned int t = (x & 0xff00ff) * a + 0x800080;
24059 : t = (t + ((t >> 8) & 0xff00ff)) >> 8;
24062 : x = ((x >> 8) & 0xff) * a + 0x80;
24063 : x = (x + ((x >> 8) & 0xff));
24065 : x |= t | (a << 24);
24069 :static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
24070 : unsigned int y, unsigned int b)
24072 : CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
24076 : x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
24083 :PictureGradientColor (PictGradientStopPtr stop1,
24084 : PictGradientStopPtr stop2,
24087 : CARD32 current_color, next_color;
24090 : current_color = xRenderColorToCard32 (stop1->color);
24091 : next_color = xRenderColorToCard32 (stop2->color);
24093 : dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x));
24094 : idist = 256 - dist;
24096 : return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist,
24097 : next_color, dist));
24100 :static void initGradient(SourcePictPtr pGradient, int stopCount,
24101 : xFixed *stopPoints, xRenderColor *stopColors, int *error)
24106 : if (stopCount <= 0) {
24107 : *error = BadValue;
24112 : for (i = 0; i < stopCount; ++i) {
24113 : if (stopPoints[i] < dpos || stopPoints[i] > (1<<16)) {
24114 : *error = BadValue;
24117 : dpos = stopPoints[i];
24120 : pGradient->gradient.stops = xalloc(stopCount*sizeof(PictGradientStop));
24121 : if (!pGradient->gradient.stops) {
24122 : *error = BadAlloc;
24126 : pGradient->gradient.nstops = stopCount;
24128 : for (i = 0; i < stopCount; ++i) {
24129 : pGradient->gradient.stops[i].x = stopPoints[i];
24130 : pGradient->gradient.stops[i].color = stopColors[i];
24133 : pGradient->gradient.class = SourcePictClassUnknown;
24134 : pGradient->gradient.stopRange = 0xffff;
24135 : pGradient->gradient.colorTable = NULL;
24136 : pGradient->gradient.colorTableSize = 0;
24139 :static PicturePtr createSourcePicture(void)
24141 : PicturePtr pPicture;
24142 : pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
24143 : pPicture->pDrawable = 0;
24144 : pPicture->pFormat = 0;
24145 : pPicture->pNext = 0;
24146 : pPicture->format = PICT_a8r8g8b8;
24147 : pPicture->devPrivates = 0;
24149 : SetPictureToDefaults(pPicture);
24154 :CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
24156 : PicturePtr pPicture;
24157 : pPicture = createSourcePicture();
24159 : *error = BadAlloc;
24163 : pPicture->id = pid;
24164 : pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
24165 : if (!pPicture->pSourcePict) {
24166 : *error = BadAlloc;
24170 : pPicture->pSourcePict->type = SourcePictTypeSolidFill;
24171 : pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
24176 :CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
24177 : int nStops, xFixed *stops, xRenderColor *colors, int *error)
24179 : PicturePtr pPicture;
24181 : if (nStops < 2) {
24182 : *error = BadValue;
24186 : pPicture = createSourcePicture();
24188 : *error = BadAlloc;
24192 : pPicture->id = pid;
24193 : pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
24194 : if (!pPicture->pSourcePict) {
24195 : *error = BadAlloc;
24200 : pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
24201 : pPicture->pSourcePict->linear.p1 = *p1;
24202 : pPicture->pSourcePict->linear.p2 = *p2;
24204 : initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
24212 :#define FixedToDouble(x) ((x)/65536.)
24215 :CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
24216 : xFixed innerRadius, xFixed outerRadius,
24217 : int nStops, xFixed *stops, xRenderColor *colors, int *error)
24219 : PicturePtr pPicture;
24220 : PictRadialGradient *radial;
24222 : if (nStops < 2) {
24223 : *error = BadValue;
24227 : pPicture = createSourcePicture();
24229 : *error = BadAlloc;
24233 : pPicture->id = pid;
24234 : pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
24235 : if (!pPicture->pSourcePict) {
24236 : *error = BadAlloc;
24240 : radial = &pPicture->pSourcePict->radial;
24242 : radial->type = SourcePictTypeRadial;
24243 : radial->c1.x = inner->x;
24244 : radial->c1.y = inner->y;
24245 : radial->c1.radius = innerRadius;
24246 : radial->c2.x = outer->x;
24247 : radial->c2.y = outer->y;
24248 : radial->c2.radius = outerRadius;
24249 : radial->cdx = (radial->c2.x - radial->c1.x) / 65536.;
24250 : radial->cdy = (radial->c2.y - radial->c1.y) / 65536.;
24251 : radial->dr = (radial->c2.radius - radial->c1.radius) / 65536.;
24252 : radial->A = ( radial->cdx * radial->cdx
24253 : + radial->cdy * radial->cdy
24254 : - radial->dr * radial->dr);
24256 : initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
24265 :CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
24266 : int nStops, xFixed *stops, xRenderColor *colors, int *error)
24268 : PicturePtr pPicture;
24270 : if (nStops < 2) {
24271 : *error = BadValue;
24275 : pPicture = createSourcePicture();
24277 : *error = BadAlloc;
24281 : pPicture->id = pid;
24282 : pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
24283 : if (!pPicture->pSourcePict) {
24284 : *error = BadAlloc;
24289 : pPicture->pSourcePict->conical.type = SourcePictTypeConical;
24290 : pPicture->pSourcePict->conical.center = *center;
24291 : pPicture->pSourcePict->conical.angle = angle;
24293 : initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
24301 :#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
24303 :#define NEXT_PTR(_type) ((_type) ulist++->ptr)
24306 :ChangePicture (PicturePtr pPicture,
24310 : ClientPtr client)
24311 4 0.0044 :{ /* ChangePicture total: 16 0.0174 */
24312 : ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
24313 4 0.0044 : PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
24318 : pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
24320 1 0.0011 : while (vmask && !error)
24322 : index2 = (BITS32) lowbit (vmask);
24323 1 0.0011 : vmask &= ~index2;
24324 : pPicture->stateChanges |= index2;
24325 1 0.0011 : switch (index2)
24329 : unsigned int newr;
24330 1 0.0011 : newr = NEXT_VAL(unsigned int);
24331 : if (newr <= RepeatReflect)
24333 1 0.0011 : pPicture->repeat = (newr != RepeatNone);
24334 1 0.0011 : pPicture->repeatType = newr;
24338 : client->errorValue = newr;
24339 : error = BadValue;
24345 : PicturePtr pAlpha;
24349 : Picture pid = NEXT_VAL(Picture);
24355 : pAlpha = (PicturePtr) SecurityLookupIDByType(client,
24358 : DixWriteAccess|DixReadAccess);
24361 : client->errorValue = pid;
24362 : error = BadPixmap;
24365 : if (pAlpha->pDrawable == NULL ||
24366 : pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
24368 : client->errorValue = pid;
24369 : error = BadMatch;
24375 : pAlpha = NEXT_PTR(PicturePtr);
24378 : if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
24379 : pAlpha->refcnt++;
24380 : if (pPicture->alphaMap)
24381 : FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
24382 : pPicture->alphaMap = pAlpha;
24386 : case CPAlphaXOrigin:
24387 : pPicture->alphaOrigin.x = NEXT_VAL(INT16);
24389 : case CPAlphaYOrigin:
24390 : pPicture->alphaOrigin.y = NEXT_VAL(INT16);
24392 : case CPClipXOrigin:
24393 : pPicture->clipOrigin.x = NEXT_VAL(INT16);
24395 : case CPClipYOrigin:
24396 : pPicture->clipOrigin.y = NEXT_VAL(INT16);
24401 : PixmapPtr pPixmap;
24404 : return BadDrawable;
24408 : pid = NEXT_VAL(Pixmap);
24411 : clipType = CT_NONE;
24412 : pPixmap = NullPixmap;
24416 : clipType = CT_PIXMAP;
24417 : pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
24423 : client->errorValue = pid;
24424 : error = BadPixmap;
24431 : pPixmap = NEXT_PTR(PixmapPtr);
24433 : clipType = CT_PIXMAP;
24435 : clipType = CT_NONE;
24440 : if ((pPixmap->drawable.depth != 1) ||
24441 : (pPixmap->drawable.pScreen != pScreen))
24443 : error = BadMatch;
24448 : clipType = CT_PIXMAP;
24449 : pPixmap->refcnt++;
24452 : error = (*ps->ChangePictureClip)(pPicture, clipType,
24453 : (pointer)pPixmap, 0);
24456 : case CPGraphicsExposure:
24458 : unsigned int newe;
24459 : newe = NEXT_VAL(unsigned int);
24460 : if (newe <= xTrue)
24461 : pPicture->graphicsExposures = newe;
24464 : client->errorValue = newe;
24465 : error = BadValue;
24469 : case CPSubwindowMode:
24471 : unsigned int news;
24472 : news = NEXT_VAL(unsigned int);
24473 : if (news == ClipByChildren || news == IncludeInferiors)
24474 : pPicture->subWindowMode = news;
24477 : client->errorValue = news;
24478 : error = BadValue;
24484 : unsigned int newe;
24485 : newe = NEXT_VAL(unsigned int);
24486 : if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
24487 : pPicture->polyEdge = newe;
24490 : client->errorValue = newe;
24491 : error = BadValue;
24497 : unsigned int newm;
24498 : newm = NEXT_VAL(unsigned int);
24499 : if (newm == PolyModePrecise || newm == PolyModeImprecise)
24500 : pPicture->polyMode = newm;
24503 : client->errorValue = newm;
24504 : error = BadValue;
24509 : pPicture->dither = NEXT_VAL(Atom);
24511 : case CPComponentAlpha:
24513 : unsigned int newca;
24515 1 0.0011 : newca = NEXT_VAL (unsigned int);
24516 : if (newca <= xTrue)
24517 : pPicture->componentAlpha = newca;
24520 : client->errorValue = newca;
24521 : error = BadValue;
24526 : client->errorValue = maskQ;
24527 : error = BadValue;
24532 : (*ps->ChangePicture) (pPicture, maskQ);
24537 :SetPictureClipRects (PicturePtr pPicture,
24541 : xRectangle *rects)
24543 : ScreenPtr pScreen = pPicture->pDrawable->pScreen;
24544 : PictureScreenPtr ps = GetPictureScreen(pScreen);
24545 : RegionPtr clientClip;
24548 : clientClip = RECTS_TO_REGION(pScreen,
24549 : nRect, rects, CT_UNSORTED);
24552 : result =(*ps->ChangePictureClip) (pPicture, CT_REGION,
24553 : (pointer) clientClip, 0);
24554 : if (result == Success)
24556 : pPicture->clipOrigin.x = xOrigin;
24557 : pPicture->clipOrigin.y = yOrigin;
24558 : pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
24559 : pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
24565 :SetPictureClipRegion (PicturePtr pPicture,
24568 : RegionPtr pRegion)
24570 : ScreenPtr pScreen = pPicture->pDrawable->pScreen;
24571 : PictureScreenPtr ps = GetPictureScreen(pScreen);
24572 : RegionPtr clientClip;
24578 : type = CT_REGION;
24579 : clientClip = REGION_CREATE (pScreen,
24580 : REGION_EXTENTS(pScreen, pRegion),
24581 : REGION_NUM_RECTS(pRegion));
24584 : if (!REGION_COPY (pSCreen, clientClip, pRegion))
24586 : REGION_DESTROY (pScreen, clientClip);
24596 : result =(*ps->ChangePictureClip) (pPicture, type,
24597 : (pointer) clientClip, 0);
24598 : if (result == Success)
24600 : pPicture->clipOrigin.x = xOrigin;
24601 : pPicture->clipOrigin.y = yOrigin;
24602 : pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
24603 : pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
24609 :transformIsIdentity(PictTransform *t)
24611 : return ((t->matrix[0][0] == t->matrix[1][1]) &&
24612 : (t->matrix[0][0] == t->matrix[2][2]) &&
24613 : (t->matrix[0][0] != 0) &&
24614 : (t->matrix[0][1] == 0) &&
24615 : (t->matrix[0][2] == 0) &&
24616 : (t->matrix[1][0] == 0) &&
24617 : (t->matrix[1][2] == 0) &&
24618 : (t->matrix[2][0] == 0) &&
24619 : (t->matrix[2][1] == 0));
24623 :SetPictureTransform (PicturePtr pPicture,
24624 : PictTransform *transform)
24625 2 0.0022 :{ /* SetPictureTransform total: 10 0.0109 */
24626 : if (transform && transformIsIdentity (transform))
24631 : if (!pPicture->transform)
24633 : pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
24634 : if (!pPicture->transform)
24637 : *pPicture->transform = *transform;
24641 : if (pPicture->transform)
24643 : xfree (pPicture->transform);
24644 : pPicture->transform = 0;
24647 : pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
24649 5 0.0054 : if (pPicture->pDrawable != NULL) {
24651 : PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
24653 1 0.0011 : result = (*ps->ChangePictureTransform) (pPicture, transform);
24662 :CopyPicture (PicturePtr pSrc,
24666 : PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
24667 : Mask origMask = mask;
24669 : pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
24670 : pDst->stateChanges |= mask;
24673 : Mask bit = lowbit(mask);
24678 : pDst->repeat = pSrc->repeat;
24679 : pDst->repeatType = pSrc->repeatType;
24682 : if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
24683 : pSrc->alphaMap->refcnt++;
24684 : if (pDst->alphaMap)
24685 : FreePicture ((pointer) pDst->alphaMap, (XID) 0);
24686 : pDst->alphaMap = pSrc->alphaMap;
24688 : case CPAlphaXOrigin:
24689 : pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
24691 : case CPAlphaYOrigin:
24692 : pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
24694 : case CPClipXOrigin:
24695 : pDst->clipOrigin.x = pSrc->clipOrigin.x;
24697 : case CPClipYOrigin:
24698 : pDst->clipOrigin.y = pSrc->clipOrigin.y;
24701 : switch (pSrc->clientClipType) {
24703 : (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
24706 : if (!pSrc->clientClip) {
24707 : (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
24709 : RegionPtr clientClip;
24710 : RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
24712 : clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
24713 : REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
24714 : REGION_NUM_RECTS(srcClientClip));
24715 : (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
24719 : /* XXX: CT_PIXMAP unimplemented */
24723 : case CPGraphicsExposure:
24724 : pDst->graphicsExposures = pSrc->graphicsExposures;
24727 : pDst->polyEdge = pSrc->polyEdge;
24730 : pDst->polyMode = pSrc->polyMode;
24733 : pDst->dither = pSrc->dither;
24735 : case CPComponentAlpha:
24736 : pDst->componentAlpha = pSrc->componentAlpha;
24742 : (*ps->ChangePicture)(pDst, origMask);
24746 :ValidateOnePicture (PicturePtr pPicture)
24747 5 0.0054 :{ /* ValidateOnePicture total: 10 0.0109 */
24748 1 0.0011 : if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
24750 : PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
24752 4 0.0044 : (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
24753 : pPicture->stateChanges = 0;
24754 : pPicture->serialNumber = pPicture->pDrawable->serialNumber;
24759 :ValidatePicture(PicturePtr pPicture)
24760 1 0.0011 :{ /* ValidatePicture total: 3 0.0033 */
24761 : ValidateOnePicture (pPicture);
24762 1 0.0011 : if (pPicture->alphaMap)
24763 : ValidateOnePicture (pPicture->alphaMap);
24767 :FreePicture (pointer value,
24769 3 0.0033 :{ /* FreePicture total: 8 0.0087 */
24770 : PicturePtr pPicture = (PicturePtr) value;
24772 2 0.0022 : if (--pPicture->refcnt == 0)
24774 : if (pPicture->transform)
24775 : xfree (pPicture->transform);
24777 : if (pPicture->pSourcePict)
24779 : if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
24780 : xfree(pPicture->pSourcePict->linear.stops);
24782 : xfree(pPicture->pSourcePict);
24785 : if (pPicture->pDrawable)
24787 : ScreenPtr pScreen = pPicture->pDrawable->pScreen;
24788 2 0.0022 : PictureScreenPtr ps = GetPictureScreen(pScreen);
24790 : if (pPicture->alphaMap)
24791 : FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
24792 : (*ps->DestroyPicture) (pPicture);
24793 : (*ps->DestroyPictureClip) (pPicture);
24794 : if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
24796 : WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
24797 : PicturePtr *pPrev;
24799 : for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
24801 : pPrev = &(*pPrev)->pNext)
24803 : if (*pPrev == pPicture)
24805 : *pPrev = pPicture->pNext;
24810 1 0.0011 : else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
24812 : (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
24815 : xfree (pPicture);
24821 :FreePictFormat (pointer pPictFormat,
24828 : * ReduceCompositeOp is used to choose simpler ops for cases where alpha
24829 : * channels are always one and so math on the alpha channel per pixel becomes
24830 : * unnecessary. It may also avoid destination reads sometimes if apps aren't
24831 : * being careful to avoid these cases.
24834 :ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
24836 : Bool no_src_alpha, no_dst_alpha;
24838 : no_src_alpha = PICT_FORMAT_COLOR(pSrc->format) &&
24839 : PICT_FORMAT_A(pSrc->format) == 0 &&
24840 : pSrc->alphaMap == NULL &&
24842 : no_dst_alpha = PICT_FORMAT_COLOR(pDst->format) &&
24843 : PICT_FORMAT_A(pDst->format) == 0 &&
24844 : pDst->alphaMap == NULL;
24846 : /* TODO, maybe: Conjoint and Disjoint op reductions? */
24848 : /* Deal with simplifications where the source alpha is always 1. */
24849 : if (no_src_alpha)
24855 : case PictOpInReverse:
24858 : case PictOpOutReverse:
24859 : op = PictOpClear;
24864 : case PictOpAtopReverse:
24865 : op = PictOpOverReverse;
24875 : /* Deal with simplifications when the destination alpha is always 1 */
24876 : if (no_dst_alpha)
24879 : case PictOpOverReverse:
24886 : op = PictOpClear;
24892 : op = PictOpOutReverse;
24899 : /* Reduce some con/disjoint ops to the basic names. */
24901 : case PictOpDisjointClear:
24902 : case PictOpConjointClear:
24903 : op = PictOpClear;
24905 : case PictOpDisjointSrc:
24906 : case PictOpConjointSrc:
24909 : case PictOpDisjointDst:
24910 : case PictOpConjointDst:
24921 :CompositePicture (CARD8 op,
24923 : PicturePtr pMask,
24933 1 0.0011 :{ /* CompositePicture total: 4 0.0044 */
24934 : PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
24936 : ValidatePicture (pSrc);
24938 : ValidatePicture (pMask);
24939 2 0.0022 : ValidatePicture (pDst);
24941 : op = ReduceCompositeOp (op, pSrc, pMask, pDst);
24942 : if (op == PictOpDst)
24945 : (*ps->Composite) (op,
24960 :CompositeGlyphs (CARD8 op,
24963 : PictFormatPtr maskFormat,
24967 : GlyphListPtr lists,
24968 : GlyphPtr *glyphs)
24969 1 0.0011 :{ /* CompositeGlyphs total: 1 0.0011 */
24970 : PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
24972 : ValidatePicture (pSrc);
24973 : ValidatePicture (pDst);
24974 : (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
24978 :CompositeRects (CARD8 op,
24980 : xRenderColor *color,
24982 : xRectangle *rects)
24983 :{ /* CompositeRects total: 1 0.0011 */
24984 1 0.0011 : PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
24986 : ValidatePicture (pDst);
24987 : (*ps->CompositeRects) (op, pDst, color, nRect, rects);
24991 :CompositeTrapezoids (CARD8 op,
24994 : PictFormatPtr maskFormat,
24998 : xTrapezoid *traps)
25000 : PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
25002 : ValidatePicture (pSrc);
25003 : ValidatePicture (pDst);
25004 : (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
25008 :CompositeTriangles (CARD8 op,
25011 : PictFormatPtr maskFormat,
25015 : xTriangle *triangles)
25017 : PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
25019 : ValidatePicture (pSrc);
25020 : ValidatePicture (pDst);
25021 : (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
25025 :CompositeTriStrip (CARD8 op,
25028 : PictFormatPtr maskFormat,
25032 : xPointFixed *points)
25034 : PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
25036 : ValidatePicture (pSrc);
25037 : ValidatePicture (pDst);
25038 : (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
25042 :CompositeTriFan (CARD8 op,
25045 : PictFormatPtr maskFormat,
25049 : xPointFixed *points)
25051 : PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
25053 : ValidatePicture (pSrc);
25054 : ValidatePicture (pDst);
25055 : (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
25059 :AddTraps (PicturePtr pPicture,
25065 : PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
25067 : ValidatePicture (pPicture);
25068 : (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
25072 :PictureTransformPoint3d (PictTransformPtr transform,
25073 : PictVectorPtr vector)
25075 : PictVector result;
25077 : xFixed_32_32 partial;
25080 : for (j = 0; j < 3; j++)
25083 : for (i = 0; i < 3; i++)
25085 : partial = ((xFixed_48_16) transform->matrix[j][i] *
25086 : (xFixed_48_16) vector->vector[i]);
25087 : v += partial >> 16;
25089 : if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
25091 : result.vector[j] = (xFixed) v;
25093 : if (!result.vector[2])
25095 : *vector = result;
25101 :PictureTransformPoint (PictTransformPtr transform,
25102 : PictVectorPtr vector)
25104 : PictVector result;
25106 : xFixed_32_32 partial;
25109 : for (j = 0; j < 3; j++)
25112 : for (i = 0; i < 3; i++)
25114 : partial = ((xFixed_48_16) transform->matrix[j][i] *
25115 : (xFixed_48_16) vector->vector[i]);
25116 : v += partial >> 16;
25118 : if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
25120 : result.vector[j] = (xFixed) v;
25122 : if (!result.vector[2])
25124 : for (j = 0; j < 2; j++)
25126 : partial = (xFixed_48_16) result.vector[j] << 16;
25127 : v = partial / result.vector[2];
25128 : if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
25130 : vector->vector[j] = (xFixed) v;
25132 : vector->vector[2] = xFixed1;
25136 * Total samples for file : "/home/cworth/src/xorg/xserver/mi/miscrinit.c"
25144 :Copyright 1990, 1998 The Open Group
25146 :Permission to use, copy, modify, distribute, and sell this software and its
25147 :documentation for any purpose is hereby granted without fee, provided that
25148 :the above copyright notice appear in all copies and that both that
25149 :copyright notice and this permission notice appear in supporting
25152 :The above copyright notice and this permission notice shall be included
25153 :in all copies or substantial portions of the Software.
25155 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25156 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25157 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25158 :IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
25159 :OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25160 :ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25161 :OTHER DEALINGS IN THE SOFTWARE.
25163 :Except as contained in this notice, the name of The Open Group shall
25164 :not be used in advertising or otherwise to promote the sale, use or
25165 :other dealings in this Software without prior written authorization
25166 :from The Open Group.
25170 :#ifdef HAVE_DIX_CONFIG_H
25171 :#include <dix-config.h>
25174 :#include <X11/X.h>
25175 :#include "servermd.h"
25178 :#include "scrnintstr.h"
25179 :#include "pixmapstr.h"
25181 :#include "miline.h"
25183 :#define _XSHM_SERVER_
25184 :#include <X11/extensions/XShm.h>
25187 :/* We use this structure to propogate some information from miScreenInit to
25188 : * miCreateScreenResources. miScreenInit allocates the structure, fills it
25189 : * in, and puts it into pScreen->devPrivate. miCreateScreenResources
25190 : * extracts the info and frees the structure. We could've accomplished the
25191 : * same thing by adding fields to the screen structure, but they would have
25192 : * ended up being redundant, and would have exposed this mi implementation
25193 : * detail to the whole server.
25198 : pointer pbits; /* pointer to framebuffer */
25199 : int width; /* delta to add to a framebuffer addr to move one row down */
25200 :} miScreenInitParmsRec, *miScreenInitParmsPtr;
25203 :/* this plugs into pScreen->ModifyPixmapHeader */
25205 :miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind,
25207 : PixmapPtr pPixmap;
25211 : int bitsPerPixel;
25213 : pointer pPixData;
25214 12 0.0131 :{ /* miModifyPixmapHeader total: 66 0.0719 */
25215 2 0.0022 : if (!pPixmap)
25219 : * If all arguments are specified, reinitialize everything (including
25220 : * validated state).
25222 7 0.0076 : if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
25223 : (devKind > 0) && pPixData) {
25224 : pPixmap->drawable.depth = depth;
25225 : pPixmap->drawable.bitsPerPixel = bitsPerPixel;
25226 : pPixmap->drawable.id = 0;
25227 : pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
25228 : pPixmap->drawable.x = 0;
25229 : pPixmap->drawable.y = 0;
25230 : pPixmap->drawable.width = width;
25231 : pPixmap->drawable.height = height;
25232 : pPixmap->devKind = devKind;
25233 : pPixmap->refcnt = 1;
25234 : pPixmap->devPrivate.ptr = pPixData;
25237 : * Only modify specified fields, keeping all others intact.
25240 3 0.0033 : if (width > 0)
25241 : pPixmap->drawable.width = width;
25243 5 0.0054 : if (height > 0)
25244 1 0.0011 : pPixmap->drawable.height = height;
25246 1 0.0011 : if (depth > 0)
25247 : pPixmap->drawable.depth = depth;
25249 8 0.0087 : if (bitsPerPixel > 0)
25250 : pPixmap->drawable.bitsPerPixel = bitsPerPixel;
25251 1 0.0011 : else if ((bitsPerPixel < 0) && (depth > 0))
25252 : pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
25255 : * CAVEAT: Non-SI DDXen may use devKind and devPrivate fields for
25256 : * other purposes.
25258 1 0.0011 : if (devKind > 0)
25259 : pPixmap->devKind = devKind;
25260 : else if ((devKind < 0) && ((width > 0) || (depth > 0)))
25261 14 0.0153 : pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
25262 : pPixmap->drawable.depth);
25264 4 0.0044 : if (pPixData)
25265 2 0.0022 : pPixmap->devPrivate.ptr = pPixData;
25271 :miCloseScreen (int iScreen, ScreenPtr pScreen)
25273 : return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
25276 :/* With the introduction of pixmap privates, the "screen pixmap" can no
25277 : * longer be created in miScreenInit, since all the modules that could
25278 : * possibly ask for pixmap private space have not been initialized at
25279 : * that time. pScreen->CreateScreenResources is called after all
25280 : * possible private-requesting modules have been inited; we create the
25281 : * screen pixmap here.
25284 :miCreateScreenResources(pScreen)
25285 : ScreenPtr pScreen;
25287 : miScreenInitParmsPtr pScrInitParms;
25290 : pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
25292 : /* if width is non-zero, pScreen->devPrivate will be a pixmap
25293 : * else it will just take the value pbits
25295 : if (pScrInitParms->width)
25297 : PixmapPtr pPixmap;
25299 : /* create a pixmap with no data, then redirect it to point to
25302 : pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
25306 : if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
25307 : pScreen->height, pScreen->rootDepth,
25308 : BitsPerPixel(pScreen->rootDepth),
25309 : PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
25310 : pScrInitParms->pbits))
25312 : value = (pointer)pPixmap;
25316 : value = pScrInitParms->pbits;
25318 : xfree(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
25319 : pScreen->devPrivate = value; /* pPixmap or pbits */
25324 :miScreenDevPrivateInit(pScreen, width, pbits)
25325 : ScreenPtr pScreen;
25329 : miScreenInitParmsPtr pScrInitParms;
25331 : /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
25332 : * to the screen, until CreateScreenResources can put them in the
25335 : pScrInitParms = (miScreenInitParmsPtr)xalloc(sizeof(miScreenInitParmsRec));
25336 : if (!pScrInitParms)
25338 : pScrInitParms->pbits = pbits;
25339 : pScrInitParms->width = width;
25340 : pScreen->devPrivate = (pointer)pScrInitParms;
25345 :miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
25346 : rootDepth, numDepths, depths, rootVisual, numVisuals, visuals)
25347 : ScreenPtr pScreen;
25348 : pointer pbits; /* pointer to screen bits */
25349 : int xsize, ysize; /* in pixels */
25350 : int dpix, dpiy; /* dots per inch */
25351 : int width; /* pixel width of frame buffer */
25352 : int rootDepth; /* depth of root window */
25353 : int numDepths; /* number of depths supported */
25354 : DepthRec *depths; /* supported depths */
25355 : VisualID rootVisual; /* root visual */
25356 : int numVisuals; /* number of visuals supported */
25357 : VisualRec *visuals; /* supported visuals */
25359 : pScreen->width = xsize;
25360 : pScreen->height = ysize;
25361 : pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
25362 : pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
25363 : pScreen->numDepths = numDepths;
25364 : pScreen->rootDepth = rootDepth;
25365 : pScreen->allowedDepths = depths;
25366 : pScreen->rootVisual = rootVisual;
25367 : /* defColormap */
25368 : pScreen->minInstalledCmaps = 1;
25369 : pScreen->maxInstalledCmaps = 1;
25370 : pScreen->backingStoreSupport = NotUseful;
25371 : pScreen->saveUnderSupport = NotUseful;
25372 : /* whitePixel, blackPixel */
25373 : pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
25374 : pScreen->CreateScreenResources = miCreateScreenResources;
25375 : pScreen->GetScreenPixmap = miGetScreenPixmap;
25376 : pScreen->SetScreenPixmap = miSetScreenPixmap;
25377 : pScreen->numVisuals = numVisuals;
25378 : pScreen->visuals = visuals;
25382 : ShmRegisterFbFuncs(pScreen);
25384 : pScreen->CloseScreen = miCloseScreen;
25386 : /* else CloseScreen */
25387 : /* QueryBestSize, SaveScreen, GetImage, GetSpans */
25388 : pScreen->PointerNonInterestBox = (PointerNonInterestBoxProcPtr) 0;
25389 : pScreen->SourceValidate = (SourceValidateProcPtr) 0;
25390 : /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
25391 : /* RealizeWindow, UnrealizeWindow */
25392 : pScreen->ValidateTree = miValidateTree;
25393 : pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
25394 : pScreen->WindowExposures = miWindowExposures;
25395 : /* PaintWindowBackground, PaintWindowBorder, CopyWindow */
25396 : pScreen->ClearToBackground = miClearToBackground;
25397 : pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
25398 : pScreen->RestackWindow = (RestackWindowProcPtr) 0;
25399 : /* CreatePixmap, DestroyPixmap */
25400 : /* RealizeFont, UnrealizeFont */
25402 : /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
25403 : /* ListInstalledColormaps, StoreColors, ResolveColor */
25404 : /* BitmapToRegion */
25405 : pScreen->SendGraphicsExpose = miSendGraphicsExpose;
25406 : pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
25407 : pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
25408 : pScreen->blockData = (pointer)0;
25409 : pScreen->wakeupData = (pointer)0;
25410 : pScreen->MarkWindow = miMarkWindow;
25411 : pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
25412 : pScreen->ChangeSaveUnder = miChangeSaveUnder;
25413 : pScreen->PostChangeSaveUnder = miPostChangeSaveUnder;
25414 : pScreen->MoveWindow = miMoveWindow;
25415 : pScreen->ResizeWindow = miSlideAndSizeWindow;
25416 : pScreen->GetLayerWindow = miGetLayerWindow;
25417 : pScreen->HandleExposures = miHandleValidateExposures;
25418 : pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
25419 : pScreen->ChangeBorderWidth = miChangeBorderWidth;
25421 : pScreen->SetShape = miSetShape;
25423 : pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
25425 : pScreen->SaveDoomedAreas = 0;
25426 : pScreen->RestoreAreas = 0;
25427 : pScreen->ExposeCopy = 0;
25428 : pScreen->TranslateBackingStore = 0;
25429 : pScreen->ClearBackingStore = 0;
25430 : pScreen->DrawGuarantee = 0;
25432 : miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
25434 : return miScreenDevPrivateInit(pScreen, width, pbits);
25438 :miAllocateGCPrivateIndex()
25440 : static int privateIndex = -1;
25441 : static unsigned long miGeneration = 0;
25443 : if (miGeneration != serverGeneration)
25445 : privateIndex = AllocateGCPrivateIndex();
25446 : miGeneration = serverGeneration;
25448 : return privateIndex;
25451 :_X_EXPORT int miZeroLineScreenIndex;
25452 :static unsigned int miZeroLineGeneration = 0;
25455 :miSetZeroLineBias(pScreen, bias)
25456 : ScreenPtr pScreen;
25457 : unsigned int bias;
25459 : if (miZeroLineGeneration != serverGeneration)
25461 : miZeroLineScreenIndex = AllocateScreenPrivateIndex();
25462 : miZeroLineGeneration = serverGeneration;
25464 : if (miZeroLineScreenIndex >= 0)
25465 : pScreen->devPrivates[miZeroLineScreenIndex].uval = bias;
25468 :_X_EXPORT PixmapPtr
25469 :miGetScreenPixmap(pScreen)
25470 : ScreenPtr pScreen;
25472 : return (PixmapPtr)(pScreen->devPrivate);
25476 :miSetScreenPixmap(pPix)
25480 : pPix->drawable.pScreen->devPrivate = (pointer)pPix;
25483 * Total samples for file : "/home/cworth/src/xorg/xserver/mi/miregion.c"
25489 :/***********************************************************
25491 :Copyright 1987, 1988, 1989, 1998 The Open Group
25493 :Permission to use, copy, modify, distribute, and sell this software and its
25494 :documentation for any purpose is hereby granted without fee, provided that
25495 :the above copyright notice appear in all copies and that both that
25496 :copyright notice and this permission notice appear in supporting
25499 :The above copyright notice and this permission notice shall be included in
25500 :all copies or substantial portions of the Software.
25502 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25503 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25504 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25505 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
25506 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25507 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25509 :Except as contained in this notice, the name of The Open Group shall not be
25510 :used in advertising or otherwise to promote the sale, use or other dealings
25511 :in this Software without prior written authorization from The Open Group.
25514 :Copyright 1987, 1988, 1989 by
25515 :Digital Equipment Corporation, Maynard, Massachusetts.
25517 : All Rights Reserved
25519 :Permission to use, copy, modify, and distribute this software and its
25520 :documentation for any purpose and without fee is hereby granted,
25521 :provided that the above copyright notice appear in all copies and that
25522 :both that copyright notice and this permission notice appear in
25523 :supporting documentation, and that the name of Digital not be
25524 :used in advertising or publicity pertaining to distribution of the
25525 :software without specific, written prior permission.
25527 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25528 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
25529 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
25530 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
25531 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25532 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25535 :******************************************************************/
25537 :/* The panoramix components contained the following notice */
25538 :/*****************************************************************
25540 :Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
25542 :Permission is hereby granted, free of charge, to any person obtaining a copy
25543 :of this software and associated documentation files (the "Software"), to deal
25544 :in the Software without restriction, including without limitation the rights
25545 :to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25546 :copies of the Software.
25548 :The above copyright notice and this permission notice shall be included in
25549 :all copies or substantial portions of the Software.
25551 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25552 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25553 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25554 :DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
25555 :BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
25556 :WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
25557 :IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25559 :Except as contained in this notice, the name of Digital Equipment Corporation
25560 :shall not be used in advertising or otherwise to promote the sale, use or other
25561 :dealings in this Software without prior written authorization from Digital
25562 :Equipment Corporation.
25564 :******************************************************************/
25566 :#ifdef HAVE_DIX_CONFIG_H
25567 :#include <dix-config.h>
25570 :#include "regionstr.h"
25571 :#include <X11/Xprotostr.h>
25572 :#include <X11/Xfuncproto.h>
25575 :#include "mispans.h"
25576 :#include <pixman/pixman.h>
25580 :#define assert(expr) {if (!(expr)) \
25581 : FatalError("Assertion failed file %s, line %d: expr\n", \
25582 : __FILE__, __LINE__); }
25584 :#define assert(expr)
25587 :#define good(reg) assert(miValidRegion(reg))
25590 : * The functions in this file implement the Region abstraction used extensively
25591 : * throughout the X11 sample server. A Region is simply a set of disjoint
25592 : * (non-overlapping) rectangles, plus an "extent" rectangle which is the
25593 : * smallest single rectangle that contains all the non-overlapping rectangles.
25595 : * A Region is implemented as a "y-x-banded" array of rectangles. This array
25596 : * imposes two degrees of order. First, all rectangles are sorted by top side
25597 : * y coordinate first (y1), and then by left side x coordinate (x1).
25599 : * Furthermore, the rectangles are grouped into "bands". Each rectangle in a
25600 : * band has the same top y coordinate (y1), and each has the same bottom y
25601 : * coordinate (y2). Thus all rectangles in a band differ only in their left
25602 : * and right side (x1 and x2). Bands are implicit in the array of rectangles:
25603 : * there is no separate list of band start pointers.
25605 : * The y-x band representation does not minimize rectangles. In particular,
25606 : * if a rectangle vertically crosses a band (the rectangle has scanlines in
25607 : * the y1 to y2 area spanned by the band), then the rectangle may be broken
25608 : * down into two or more smaller rectangles stacked one atop the other.
25610 : * ----------- -----------
25612 : * | | -------- ----------- --------
25613 : * | | | | in y-x banded | | | | band 1
25614 : * | | | | form is | | | |
25615 : * ----------- | | ----------- --------
25617 : * -------- --------
25619 : * An added constraint on the rectangles is that they must cover as much
25620 : * horizontal area as possible: no two rectangles within a band are allowed
25623 : * Whenever possible, bands will be merged together to cover a greater vertical
25624 : * distance (and thus reduce the number of rectangles). Two bands can be merged
25625 : * only if the bottom of one touches the top of the other and they have
25626 : * rectangles in the same places (of the same width, of course).
25628 : * Adam de Boor wrote most of the original region code. Joel McCormack
25629 : * substantially modified or rewrote most of the core arithmetic routines,
25630 : * and added miRegionValidate in order to support several speed improvements
25631 : * to miValidateTree. Bob Scheifler changed the representation to be more
25632 : * compact when empty or a single rectangle, and did a bunch of gratuitous
25636 :/* true iff two Boxes overlap */
25637 :#define EXTENTCHECK(r1,r2) \
25638 : (!( ((r1)->x2 <= (r2)->x1) || \
25639 : ((r1)->x1 >= (r2)->x2) || \
25640 : ((r1)->y2 <= (r2)->y1) || \
25641 : ((r1)->y1 >= (r2)->y2) ) )
25643 :/* true iff (x,y) is in Box */
25644 :#define INBOX(r,x,y) \
25645 : ( ((r)->x2 > x) && \
25646 : ((r)->x1 <= x) && \
25647 : ((r)->y2 > y) && \
25650 :/* true iff Box r1 contains Box r2 */
25651 :#define SUBSUMES(r1,r2) \
25652 : ( ((r1)->x1 <= (r2)->x1) && \
25653 : ((r1)->x2 >= (r2)->x2) && \
25654 : ((r1)->y1 <= (r2)->y1) && \
25655 : ((r1)->y2 >= (r2)->y2) )
25657 :#define xallocData(n) (RegDataPtr)xalloc(REGION_SZOF(n))
25658 :#define xfreeData(reg) if ((reg)->data && (reg)->data->size) xfree((reg)->data)
25660 :#define RECTALLOC_BAIL(pReg,n,bail) \
25661 :if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
25662 : if (!miRectAlloc(pReg, n)) { goto bail; }
25664 :#define RECTALLOC(pReg,n) \
25665 :if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
25666 : if (!miRectAlloc(pReg, n)) { return FALSE; }
25668 :#define ADDRECT(pNextRect,nx1,ny1,nx2,ny2) \
25670 : pNextRect->x1 = nx1; \
25671 : pNextRect->y1 = ny1; \
25672 : pNextRect->x2 = nx2; \
25673 : pNextRect->y2 = ny2; \
25677 :#define NEWRECT(pReg,pNextRect,nx1,ny1,nx2,ny2) \
25679 : if (!(pReg)->data || ((pReg)->data->numRects == (pReg)->data->size))\
25681 : if (!miRectAlloc(pReg, 1)) \
25683 : pNextRect = REGION_TOP(pReg); \
25685 : ADDRECT(pNextRect,nx1,ny1,nx2,ny2); \
25686 : pReg->data->numRects++; \
25687 : assert(pReg->data->numRects<=pReg->data->size); \
25691 :#define DOWNSIZE(reg,numRects) \
25692 :if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
25694 : RegDataPtr NewData; \
25695 : NewData = (RegDataPtr)xrealloc((reg)->data, REGION_SZOF(numRects)); \
25698 : NewData->size = (numRects); \
25699 : (reg)->data = NewData; \
25704 :_X_EXPORT BoxRec miEmptyBox = {0, 0, 0, 0};
25705 :_X_EXPORT RegDataRec miEmptyData = {0, 0};
25707 :RegDataRec miBrokenData = {0, 0};
25708 :static RegionRec miBrokenRegion = { { 0, 0, 0, 0 }, &miBrokenData };
25711 :InitRegions (void)
25713 : pixman_region_set_static_pointers (&miEmptyBox, &miEmptyData, &miBrokenData);
25716 :/*****************************************************************
25717 : * RegionCreate(rect, size)
25718 : * This routine does a simple malloc to make a structure of
25719 : * REGION of "size" number of rectangles.
25720 : *****************************************************************/
25722 :_X_EXPORT RegionPtr
25723 :miRegionCreate(rect, size)
25726 3 0.0033 :{ /* miRegionCreate total: 5 0.0054 */
25729 : pReg = (RegionPtr)xalloc(sizeof(RegionRec));
25730 1 0.0011 : if (!pReg)
25731 : return &miBrokenRegion;
25733 1 0.0011 : miRegionInit (pReg, rect, size);
25739 :miRegionDestroy(pReg)
25741 3 0.0033 :{ /* miRegionDestroy total: 5 0.0054 */
25742 : pixman_region_fini (pReg);
25743 : if (pReg != &miBrokenRegion)
25744 1 0.0011 : xfree(pReg);
25748 :miPrintRegion(rgn)
25755 : num = REGION_NUM_RECTS(rgn);
25756 : size = REGION_SIZE(rgn);
25757 : rects = REGION_RECTS(rgn);
25758 : ErrorF("num: %d size: %d\n", num, size);
25759 : ErrorF("extents: %d %d %d %d\n",
25760 : rgn->extents.x1, rgn->extents.y1, rgn->extents.x2, rgn->extents.y2);
25761 : for (i = 0; i < num; i++)
25762 : ErrorF("%d %d %d %d \n",
25763 : rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
25768 :miRegionEqual(reg1, reg2)
25772 : return pixman_region_equal (reg1, reg2);
25777 :miValidRegion(reg)
25782 : if ((reg->extents.x1 > reg->extents.x2) ||
25783 : (reg->extents.y1 > reg->extents.y2))
25785 : numRects = REGION_NUM_RECTS(reg);
25787 : return ((reg->extents.x1 == reg->extents.x2) &&
25788 : (reg->extents.y1 == reg->extents.y2) &&
25789 : (reg->data->size || (reg->data == &miEmptyData)));
25790 : else if (numRects == 1)
25791 : return (!reg->data);
25794 : BoxPtr pboxP, pboxN;
25797 : pboxP = REGION_RECTS(reg);
25799 : box.y2 = pboxP[numRects-1].y2;
25800 : pboxN = pboxP + 1;
25801 : for (i = numRects; --i > 0; pboxP++, pboxN++)
25803 : if ((pboxN->x1 >= pboxN->x2) ||
25804 : (pboxN->y1 >= pboxN->y2))
25806 : if (pboxN->x1 < box.x1)
25807 : box.x1 = pboxN->x1;
25808 : if (pboxN->x2 > box.x2)
25809 : box.x2 = pboxN->x2;
25810 : if ((pboxN->y1 < pboxP->y1) ||
25811 : ((pboxN->y1 == pboxP->y1) &&
25812 : ((pboxN->x1 < pboxP->x2) || (pboxN->y2 != pboxP->y2))))
25815 : return ((box.x1 == reg->extents.x1) &&
25816 : (box.x2 == reg->extents.x2) &&
25817 : (box.y1 == reg->extents.y1) &&
25818 : (box.y2 == reg->extents.y2));
25821 :#endif /* DEBUG */
25823 :/*****************************************************************
25824 : * RegionInit(pReg, rect, size)
25825 : * Outer region rect is statically allocated.
25826 : *****************************************************************/
25829 :miRegionInit(pReg, rect, size)
25833 3 0.0033 :{ /* miRegionInit total: 5 0.0054 */
25835 : pixman_region_init_with_extents (pReg, rect);
25837 : pixman_region_init (pReg);
25841 :miRegionUninit(pReg)
25844 : pixman_region_fini (pReg);
25848 :miRegionBreak (pReg)
25851 : xfreeData (pReg);
25852 : pReg->extents = miEmptyBox;
25853 : pReg->data = &miBrokenData;
25867 : pRgn->data = xallocData(n);
25869 : return miRegionBreak (pRgn);
25870 : pRgn->data->numRects = 1;
25871 : *REGION_BOXPTR(pRgn) = pRgn->extents;
25873 : else if (!pRgn->data->size)
25875 : pRgn->data = xallocData(n);
25877 : return miRegionBreak (pRgn);
25878 : pRgn->data->numRects = 0;
25884 : n = pRgn->data->numRects;
25885 : if (n > 500) /* XXX pick numbers out of a hat */
25888 : n += pRgn->data->numRects;
25889 : data = (RegDataPtr)xrealloc(pRgn->data, REGION_SZOF(n));
25891 : return miRegionBreak (pRgn);
25892 : pRgn->data = data;
25894 : pRgn->data->size = n;
25899 :miRegionCopy(dst, src)
25902 1 0.0011 :{ /* miRegionCopy total: 1 0.0011 */
25903 : return pixman_region_copy (dst, src);
25906 :/*======================================================================
25907 : * Generic Region Operator
25908 : *====================================================================*/
25911 : *-----------------------------------------------------------------------
25913 : * Attempt to merge the boxes in the current band with those in the
25914 : * previous one. We are guaranteed that the current band extends to
25915 : * the end of the rects array. Used only by miRegionOp.
25918 : * The new index for the previous band.
25921 : * If coalescing takes place:
25922 : * - rectangles in the previous band will have their y2 fields
25924 : * - pReg->data->numRects will be decreased.
25926 : *-----------------------------------------------------------------------
25928 :_X_INLINE static int
25930 : RegionPtr pReg, /* Region to coalesce */
25931 : int prevStart, /* Index of start of previous band */
25932 : int curStart) /* Index of start of current band */
25934 : BoxPtr pPrevBox; /* Current box in previous band */
25935 : BoxPtr pCurBox; /* Current box in current band */
25936 : int numRects; /* Number rectangles in both bands */
25937 : int y2; /* Bottom of current band */
25939 : * Figure out how many rectangles are in the band.
25941 : numRects = curStart - prevStart;
25942 : assert(numRects == pReg->data->numRects - curStart);
25944 : if (!numRects) return curStart;
25947 : * The bands may only be coalesced if the bottom of the previous
25948 : * matches the top scanline of the current.
25950 : pPrevBox = REGION_BOX(pReg, prevStart);
25951 : pCurBox = REGION_BOX(pReg, curStart);
25952 : if (pPrevBox->y2 != pCurBox->y1) return curStart;
25955 : * Make sure the bands have boxes in the same places. This
25956 : * assumes that boxes have been added in such a way that they
25957 : * cover the most area possible. I.e. two boxes in a band must
25958 : * have some horizontal space between them.
25960 : y2 = pCurBox->y2;
25963 : if ((pPrevBox->x1 != pCurBox->x1) || (pPrevBox->x2 != pCurBox->x2)) {
25964 : return (curStart);
25969 : } while (numRects);
25972 : * The bands may be merged, so set the bottom y of each box
25973 : * in the previous band to the bottom y of the current band.
25975 : numRects = curStart - prevStart;
25976 : pReg->data->numRects -= numRects;
25979 : pPrevBox->y2 = y2;
25981 : } while (numRects);
25982 : return prevStart;
25986 :/* Quicky macro to avoid trivial reject procedure calls to miCoalesce */
25988 :#define Coalesce(newReg, prevBand, curBand) \
25989 : if (curBand - prevBand == newReg->data->numRects - curBand) { \
25990 : prevBand = miCoalesce(newReg, prevBand, curBand); \
25992 : prevBand = curBand; \
25996 : *-----------------------------------------------------------------------
25997 : * miAppendNonO --
25998 : * Handle a non-overlapping band for the union and subtract operations.
25999 : * Just adds the (top/bottom-clipped) rectangles into the region.
26000 : * Doesn't have to check for subsumption or anything.
26006 : * pReg->data->numRects is incremented and the rectangles overwritten
26007 : * with the rectangles we're passed.
26009 : *-----------------------------------------------------------------------
26012 :_X_INLINE static Bool
26020 : BoxPtr pNextRect;
26023 : newRects = rEnd - r;
26026 : assert(newRects != 0);
26028 : /* Make sure we have enough space for all rectangles to be added */
26029 : RECTALLOC(pReg, newRects);
26030 : pNextRect = REGION_TOP(pReg);
26031 : pReg->data->numRects += newRects;
26033 : assert(r->x1 < r->x2);
26034 : ADDRECT(pNextRect, r->x1, y1, r->x2, y2);
26036 : } while (r != rEnd);
26041 :#define FindBand(r, rBandEnd, rEnd, ry1) \
26044 : rBandEnd = r+1; \
26045 : while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) { \
26050 :#define AppendRegions(newReg, r, rEnd) \
26053 : if ((newRects = rEnd - r)) { \
26054 : RECTALLOC(newReg, newRects); \
26055 : memmove((char *)REGION_TOP(newReg),(char *)r, \
26056 : newRects * sizeof(BoxRec)); \
26057 : newReg->data->numRects += newRects; \
26062 : *-----------------------------------------------------------------------
26064 : * Apply an operation to two regions. Called by miUnion, miInverse,
26065 : * miSubtract, miIntersect.... Both regions MUST have at least one
26066 : * rectangle, and cannot be the same object.
26069 : * TRUE if successful.
26072 : * The new region is overwritten.
26073 : * pOverlap set to TRUE if overlapFunc ever returns TRUE.
26076 : * The idea behind this function is to view the two regions as sets.
26077 : * Together they cover a rectangle of area that this function divides
26078 : * into horizontal bands where points are covered only by one region
26079 : * or by both. For the first case, the nonOverlapFunc is called with
26080 : * each the band and the band's upper and lower extents. For the
26081 : * second, the overlapFunc is called to process the entire band. It
26082 : * is responsible for clipping the rectangles in the band, though
26083 : * this function provides the boundaries.
26084 : * At the end of each band, the new region is coalesced, if possible,
26085 : * to reduce the number of rectangles in the region.
26087 : *-----------------------------------------------------------------------
26090 :typedef Bool (*OverlapProcPtr)(
26102 : RegionPtr newReg, /* Place to store result */
26103 : RegionPtr reg1, /* First region in operation */
26104 : RegionPtr reg2, /* 2d region in operation */
26105 : OverlapProcPtr overlapFunc, /* Function to call for over-
26106 : * lapping bands */
26107 : Bool appendNon1, /* Append non-overlapping bands */
26108 : /* in region 1 ? */
26109 : Bool appendNon2, /* Append non-overlapping bands */
26110 : /* in region 2 ? */
26113 : BoxPtr r1; /* Pointer into first region */
26114 : BoxPtr r2; /* Pointer into 2d region */
26115 : BoxPtr r1End; /* End of 1st region */
26116 : BoxPtr r2End; /* End of 2d region */
26117 : short ybot; /* Bottom of intersection */
26118 : short ytop; /* Top of intersection */
26119 : RegDataPtr oldData; /* Old data for newReg */
26120 : int prevBand; /* Index of start of
26121 : * previous band in newReg */
26122 : int curBand; /* Index of start of current
26123 : * band in newReg */
26124 : BoxPtr r1BandEnd; /* End of current band in r1 */
26125 : BoxPtr r2BandEnd; /* End of current band in r2 */
26126 : short top; /* Top of non-overlapping band */
26127 : short bot; /* Bottom of non-overlapping band*/
26128 : int r1y1; /* Temps for r1->y1 and r2->y1 */
26134 : * Break any region computed from a broken region
26136 : if (REGION_NAR (reg1) || REGION_NAR(reg2))
26137 : return miRegionBreak (newReg);
26140 : * Initialization:
26141 : * set r1, r2, r1End and r2End appropriately, save the rectangles
26142 : * of the destination region until the end in case it's one of
26143 : * the two source regions, then mark the "new" region empty, allocating
26144 : * another array of rectangles for it to use.
26147 : r1 = REGION_RECTS(reg1);
26148 : newSize = REGION_NUM_RECTS(reg1);
26149 : r1End = r1 + newSize;
26150 : numRects = REGION_NUM_RECTS(reg2);
26151 : r2 = REGION_RECTS(reg2);
26152 : r2End = r2 + numRects;
26153 : assert(r1 != r1End);
26154 : assert(r2 != r2End);
26156 : oldData = (RegDataPtr)NULL;
26157 : if (((newReg == reg1) && (newSize > 1)) ||
26158 : ((newReg == reg2) && (numRects > 1)))
26160 : oldData = newReg->data;
26161 : newReg->data = &miEmptyData;
26163 : /* guess at new size */
26164 : if (numRects > newSize)
26165 : newSize = numRects;
26167 : if (!newReg->data)
26168 : newReg->data = &miEmptyData;
26169 : else if (newReg->data->size)
26170 : newReg->data->numRects = 0;
26171 : if (newSize > newReg->data->size)
26172 : if (!miRectAlloc(newReg, newSize))
26176 : * Initialize ybot.
26177 : * In the upcoming loop, ybot and ytop serve different functions depending
26178 : * on whether the band being handled is an overlapping or non-overlapping
26180 : * In the case of a non-overlapping band (only one of the regions
26181 : * has points in the band), ybot is the bottom of the most recent
26182 : * intersection and thus clips the top of the rectangles in that band.
26183 : * ytop is the top of the next intersection between the two regions and
26184 : * serves to clip the bottom of the rectangles in the current band.
26185 : * For an overlapping band (where the two regions intersect), ytop clips
26186 : * the top of the rectangles of both regions and ybot clips the bottoms.
26189 : ybot = min(r1->y1, r2->y1);
26192 : * prevBand serves to mark the start of the previous band so rectangles
26193 : * can be coalesced into larger rectangles. qv. miCoalesce, above.
26194 : * In the beginning, there is no previous band, so prevBand == curBand
26195 : * (curBand is set later on, of course, but the first band will always
26196 : * start at index 0). prevBand and curBand must be indices because of
26197 : * the possible expansion, and resultant moving, of the new region's
26198 : * array of rectangles.
26204 : * This algorithm proceeds one source-band (as opposed to a
26205 : * destination band, which is determined by where the two regions
26206 : * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
26207 : * rectangle after the last one in the current band for their
26208 : * respective regions.
26210 : assert(r1 != r1End);
26211 : assert(r2 != r2End);
26213 : FindBand(r1, r1BandEnd, r1End, r1y1);
26214 : FindBand(r2, r2BandEnd, r2End, r2y1);
26217 : * First handle the band that doesn't intersect, if any.
26219 : * Note that attention is restricted to one band in the
26220 : * non-intersecting region at once, so if a region has n
26221 : * bands between the current position and the next place it overlaps
26222 : * the other, this entire loop will be passed through n times.
26224 : if (r1y1 < r2y1) {
26225 : if (appendNon1) {
26226 : top = max(r1y1, ybot);
26227 : bot = min(r1->y2, r2y1);
26228 : if (top != bot) {
26229 : curBand = newReg->data->numRects;
26230 : miAppendNonO(newReg, r1, r1BandEnd, top, bot);
26231 : Coalesce(newReg, prevBand, curBand);
26235 : } else if (r2y1 < r1y1) {
26236 : if (appendNon2) {
26237 : top = max(r2y1, ybot);
26238 : bot = min(r2->y2, r1y1);
26239 : if (top != bot) {
26240 : curBand = newReg->data->numRects;
26241 : miAppendNonO(newReg, r2, r2BandEnd, top, bot);
26242 : Coalesce(newReg, prevBand, curBand);
26251 : * Now see if we've hit an intersecting band. The two bands only
26252 : * intersect if ybot > ytop
26254 : ybot = min(r1->y2, r2->y2);
26255 : if (ybot > ytop) {
26256 : curBand = newReg->data->numRects;
26257 : (* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot,
26259 : Coalesce(newReg, prevBand, curBand);
26263 : * If we've finished with a band (y2 == ybot) we skip forward
26264 : * in the region to the next band.
26266 : if (r1->y2 == ybot) r1 = r1BandEnd;
26267 : if (r2->y2 == ybot) r2 = r2BandEnd;
26269 : } while (r1 != r1End && r2 != r2End);
26272 : * Deal with whichever region (if any) still has rectangles left.
26274 : * We only need to worry about banding and coalescing for the very first
26275 : * band left. After that, we can just group all remaining boxes,
26276 : * regardless of how many bands, into one final append to the list.
26279 : if ((r1 != r1End) && appendNon1) {
26280 : /* Do first nonOverlap1Func call, which may be able to coalesce */
26281 : FindBand(r1, r1BandEnd, r1End, r1y1);
26282 : curBand = newReg->data->numRects;
26283 : miAppendNonO(newReg, r1, r1BandEnd, max(r1y1, ybot), r1->y2);
26284 : Coalesce(newReg, prevBand, curBand);
26285 : /* Just append the rest of the boxes */
26286 : AppendRegions(newReg, r1BandEnd, r1End);
26288 : } else if ((r2 != r2End) && appendNon2) {
26289 : /* Do first nonOverlap2Func call, which may be able to coalesce */
26290 : FindBand(r2, r2BandEnd, r2End, r2y1);
26291 : curBand = newReg->data->numRects;
26292 : miAppendNonO(newReg, r2, r2BandEnd, max(r2y1, ybot), r2->y2);
26293 : Coalesce(newReg, prevBand, curBand);
26294 : /* Append rest of boxes */
26295 : AppendRegions(newReg, r2BandEnd, r2End);
26301 : if (!(numRects = newReg->data->numRects))
26303 : xfreeData(newReg);
26304 : newReg->data = &miEmptyData;
26306 : else if (numRects == 1)
26308 : newReg->extents = *REGION_BOXPTR(newReg);
26309 : xfreeData(newReg);
26310 : newReg->data = (RegDataPtr)NULL;
26314 : DOWNSIZE(newReg, numRects);
26321 : *-----------------------------------------------------------------------
26322 : * miSetExtents --
26323 : * Reset the extents of a region to what they should be. Called by
26324 : * miSubtract and miIntersect as they can't figure it out along the
26325 : * way or do so easily, as miUnion can.
26331 : * The region's 'extents' structure is overwritten.
26333 : *-----------------------------------------------------------------------
26336 :miSetExtents (RegionPtr pReg)
26338 : BoxPtr pBox, pBoxEnd;
26342 : if (!pReg->data->size)
26344 : pReg->extents.x2 = pReg->extents.x1;
26345 : pReg->extents.y2 = pReg->extents.y1;
26349 : pBox = REGION_BOXPTR(pReg);
26350 : pBoxEnd = REGION_END(pReg);
26353 : * Since pBox is the first rectangle in the region, it must have the
26354 : * smallest y1 and since pBoxEnd is the last rectangle in the region,
26355 : * it must have the largest y2, because of banding. Initialize x1 and
26356 : * x2 from pBox and pBoxEnd, resp., as good things to initialize them
26359 : pReg->extents.x1 = pBox->x1;
26360 : pReg->extents.y1 = pBox->y1;
26361 : pReg->extents.x2 = pBoxEnd->x2;
26362 : pReg->extents.y2 = pBoxEnd->y2;
26364 : assert(pReg->extents.y1 < pReg->extents.y2);
26365 : while (pBox <= pBoxEnd) {
26366 : if (pBox->x1 < pReg->extents.x1)
26367 : pReg->extents.x1 = pBox->x1;
26368 : if (pBox->x2 > pReg->extents.x2)
26369 : pReg->extents.x2 = pBox->x2;
26373 : assert(pReg->extents.x1 < pReg->extents.x2);
26376 :/*======================================================================
26377 : * Region Intersection
26378 : *====================================================================*/
26380 : *-----------------------------------------------------------------------
26381 : * miIntersectO --
26382 : * Handle an overlapping band for miIntersect.
26385 : * TRUE if successful.
26388 : * Rectangles may be added to the region.
26390 : *-----------------------------------------------------------------------
26394 :miIntersect(newReg, reg1, reg2)
26395 : RegionPtr newReg; /* destination Region */
26397 : RegionPtr reg2; /* source regions */
26398 1 0.0011 :{ /* miIntersect total: 6 0.0065 */
26399 2 0.0022 : return pixman_region_intersect (newReg, reg1, reg2);
26402 :#define MERGERECT(r) \
26404 : if (r->x1 <= x2) { \
26405 : /* Merge with current rectangle */ \
26406 : if (r->x1 < x2) *pOverlap = TRUE; \
26407 : if (x2 < r->x2) x2 = r->x2; \
26409 : /* Add current rectangle, start new one */ \
26410 : NEWRECT(pReg, pNextRect, x1, y1, x2, y2); \
26417 :/*======================================================================
26419 : *====================================================================*/
26422 : *-----------------------------------------------------------------------
26424 : * Handle an overlapping band for the union operation. Picks the
26425 : * left-most rectangle each time and merges it into the region.
26428 : * TRUE if successful.
26431 : * pReg is overwritten.
26432 : * pOverlap is set to TRUE if any boxes overlap.
26434 : *-----------------------------------------------------------------------
26447 : BoxPtr pNextRect;
26448 : int x1; /* left and right side of current union */
26451 : assert (y1 < y2);
26452 : assert(r1 != r1End && r2 != r2End);
26454 : pNextRect = REGION_TOP(pReg);
26456 : /* Start off current rectangle */
26457 : if (r1->x1 < r2->x1)
26469 : while (r1 != r1End && r2 != r2End)
26471 : if (r1->x1 < r2->x1) MERGERECT(r1) else MERGERECT(r2);
26474 : /* Finish off whoever (if any) is left */
26480 : } while (r1 != r1End);
26482 : else if (r2 != r2End)
26487 : } while (r2 != r2End);
26490 : /* Add current rectangle */
26491 : NEWRECT(pReg, pNextRect, x1, y1, x2, y2);
26497 :miUnion(newReg, reg1, reg2)
26498 : RegionPtr newReg; /* destination Region */
26500 : RegionPtr reg2; /* source regions */
26501 14 0.0153 :{ /* miUnion total: 27 0.0294 */
26502 2 0.0022 : return pixman_region_union (newReg, reg1, reg2);
26505 :/*======================================================================
26506 : * Batch Rectangle Union
26507 : *====================================================================*/
26510 : *-----------------------------------------------------------------------
26511 : * miRegionAppend --
26513 : * "Append" the rgn rectangles onto the end of dstrgn, maintaining
26514 : * knowledge of YX-banding when it's easy. Otherwise, dstrgn just
26515 : * becomes a non-y-x-banded random collection of rectangles, and not
26516 : * yet a true region. After a sequence of appends, the caller must
26517 : * call miRegionValidate to ensure that a valid region is constructed.
26520 : * TRUE if successful.
26523 : * dstrgn is modified if rgn has rectangles.
26527 :miRegionAppend(dstrgn, rgn)
26528 : RegionPtr dstrgn;
26531 : int numRects, dnumRects, size;
26535 : if (REGION_NAR(rgn))
26536 : return miRegionBreak (dstrgn);
26538 : if (!rgn->data && (dstrgn->data == &miEmptyData))
26540 : dstrgn->extents = rgn->extents;
26541 : dstrgn->data = (RegDataPtr)NULL;
26545 : numRects = REGION_NUM_RECTS(rgn);
26550 : dnumRects = REGION_NUM_RECTS(dstrgn);
26551 : if (!dnumRects && (size < 200))
26552 : size = 200; /* XXX pick numbers out of a hat */
26553 : RECTALLOC(dstrgn, size);
26554 : old = REGION_RECTS(rgn);
26556 : dstrgn->extents = rgn->extents;
26557 : else if (dstrgn->extents.x2 > dstrgn->extents.x1)
26559 : BoxPtr first, last;
26562 : last = REGION_BOXPTR(dstrgn) + (dnumRects - 1);
26563 : if ((first->y1 > last->y2) ||
26564 : ((first->y1 == last->y1) && (first->y2 == last->y2) &&
26565 : (first->x1 > last->x2)))
26567 : if (rgn->extents.x1 < dstrgn->extents.x1)
26568 : dstrgn->extents.x1 = rgn->extents.x1;
26569 : if (rgn->extents.x2 > dstrgn->extents.x2)
26570 : dstrgn->extents.x2 = rgn->extents.x2;
26571 : dstrgn->extents.y2 = rgn->extents.y2;
26575 : first = REGION_BOXPTR(dstrgn);
26576 : last = old + (numRects - 1);
26577 : if ((first->y1 > last->y2) ||
26578 : ((first->y1 == last->y1) && (first->y2 == last->y2) &&
26579 : (first->x1 > last->x2)))
26582 : if (rgn->extents.x1 < dstrgn->extents.x1)
26583 : dstrgn->extents.x1 = rgn->extents.x1;
26584 : if (rgn->extents.x2 > dstrgn->extents.x2)
26585 : dstrgn->extents.x2 = rgn->extents.x2;
26586 : dstrgn->extents.y1 = rgn->extents.y1;
26589 : dstrgn->extents.x2 = dstrgn->extents.x1;
26594 : new = REGION_BOX(dstrgn, numRects);
26595 : if (dnumRects == 1)
26596 : *new = *REGION_BOXPTR(dstrgn);
26598 : memmove((char *)new,(char *)REGION_BOXPTR(dstrgn),
26599 : dnumRects * sizeof(BoxRec));
26600 : new = REGION_BOXPTR(dstrgn);
26603 : new = REGION_BOXPTR(dstrgn) + dnumRects;
26604 : if (numRects == 1)
26607 : memmove((char *)new, (char *)old, numRects * sizeof(BoxRec));
26608 : dstrgn->data->numRects += numRects;
26613 :#define ExchangeRects(a, b) \
26617 : rects[a] = rects[b]; \
26625 :{ /* QuickSortRects total: 1 0.0011 */
26631 : /* Always called with numRects > 1 */
26635 : if (numRects == 2)
26637 1 0.0011 : if (rects[0].y1 > rects[1].y1 ||
26638 : (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1))
26639 : ExchangeRects(0, 1);
26643 : /* Choose partition element, stick in location 0 */
26644 : ExchangeRects(0, numRects >> 1);
26645 : y1 = rects[0].y1;
26646 : x1 = rects[0].x1;
26648 : /* Partition array */
26658 : } while (i != numRects &&
26659 : (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1)));
26665 : } while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1));
26667 : ExchangeRects(i, j);
26670 : /* Move partition element back to middle */
26671 : ExchangeRects(0, j);
26674 : if (numRects-j-1 > 1)
26675 : QuickSortRects(&rects[j+1], numRects-j-1);
26677 : } while (numRects > 1);
26681 : *-----------------------------------------------------------------------
26682 : * miRegionValidate --
26684 : * Take a ``region'' which is a non-y-x-banded random collection of
26685 : * rectangles, and compute a nice region which is the union of all the
26689 : * TRUE if successful.
26692 : * The passed-in ``region'' may be modified.
26693 : * pOverlap set to TRUE if any retangles overlapped, else FALSE;
26696 : * Step 1. Sort the rectangles into ascending order with primary key y1
26697 : * and secondary key x1.
26699 : * Step 2. Split the rectangles into the minimum number of proper y-x
26700 : * banded regions. This may require horizontally merging
26701 : * rectangles, and vertically coalescing bands. With any luck,
26702 : * this step in an identity tranformation (ala the Box widget),
26703 : * or a coalescing into 1 box (ala Menus).
26705 : * Step 3. Merge the separate regions down to a single region by calling
26706 : * miUnion. Maximize the work each miUnion call does by using
26707 : * a binary merge.
26709 : *-----------------------------------------------------------------------
26713 :miRegionValidate(badreg, pOverlap)
26714 : RegionPtr badreg;
26716 1 0.0011 :{ /* miRegionValidate total: 7 0.0076 */
26717 : /* Descriptor for regions under construction in Step 2. */
26724 : int numRects; /* Original numRects for badreg */
26725 : RegionInfo *ri; /* Array of current regions */
26726 : int numRI; /* Number of entries used in ri */
26727 : int sizeRI; /* Number of entries available in ri */
26728 : int i; /* Index into rects */
26729 : int j; /* Index into ri */
26730 : RegionInfo *rit; /* &ri[j] */
26731 : RegionPtr reg; /* ri[j].reg */
26732 : BoxPtr box; /* Current box in rects */
26733 : BoxPtr riBox; /* Last box in ri[j].reg */
26734 : RegionPtr hreg; /* ri[j_half].reg */
26737 : *pOverlap = FALSE;
26738 : if (!badreg->data)
26743 : numRects = badreg->data->numRects;
26746 : if (REGION_NAR(badreg))
26751 1 0.0011 : if (badreg->extents.x1 < badreg->extents.x2)
26753 : if ((numRects) == 1)
26755 : xfreeData(badreg);
26756 : badreg->data = (RegDataPtr) NULL;
26760 : DOWNSIZE(badreg, numRects);
26766 : /* Step 1: Sort the rects array into ascending (y1, x1) order */
26767 : QuickSortRects(REGION_BOXPTR(badreg), numRects);
26769 : /* Step 2: Scatter the sorted array into the minimum number of regions */
26771 : /* Set up the first region to be the first rectangle in badreg */
26772 : /* Note that step 2 code will never overflow the ri[0].reg rects array */
26773 : ri = (RegionInfo *) xalloc(4 * sizeof(RegionInfo));
26775 : return miRegionBreak (badreg);
26778 : ri[0].prevBand = 0;
26779 : ri[0].curBand = 0;
26780 : ri[0].reg = *badreg;
26781 : box = REGION_BOXPTR(&ri[0].reg);
26782 : ri[0].reg.extents = *box;
26783 : ri[0].reg.data->numRects = 1;
26785 : /* Now scatter rectangles into the minimum set of valid regions. If the
26786 : next rectangle to be added to a region would force an existing rectangle
26787 : in the region to be split up in order to maintain y-x banding, just
26788 : forget it. Try the next region. If it doesn't fit cleanly into any
26789 : region, make a new one. */
26791 : for (i = numRects; --i > 0;)
26794 : /* Look for a region to append box to */
26795 : for (j = numRI, rit = ri; --j >= 0; rit++)
26798 : riBox = REGION_END(reg);
26800 : if (box->y1 == riBox->y1 && box->y2 == riBox->y2)
26802 : /* box is in same band as riBox. Merge or append it */
26803 : if (box->x1 <= riBox->x2)
26805 : /* Merge it with riBox */
26806 : if (box->x1 < riBox->x2) *pOverlap = TRUE;
26807 : if (box->x2 > riBox->x2) riBox->x2 = box->x2;
26811 : RECTALLOC_BAIL(reg, 1, bail);
26812 : *REGION_TOP(reg) = *box;
26813 : reg->data->numRects++;
26815 : goto NextRect; /* So sue me */
26817 1 0.0011 : else if (box->y1 >= riBox->y2)
26819 : /* Put box into new band */
26820 : if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
26821 : if (reg->extents.x1 > box->x1) reg->extents.x1 = box->x1;
26822 : Coalesce(reg, rit->prevBand, rit->curBand);
26823 : rit->curBand = reg->data->numRects;
26824 : RECTALLOC_BAIL(reg, 1, bail);
26825 : *REGION_TOP(reg) = *box;
26826 : reg->data->numRects++;
26829 : /* Well, this region was inappropriate. Try the next one. */
26832 : /* Uh-oh. No regions were appropriate. Create a new one. */
26833 1 0.0011 : if (sizeRI == numRI)
26835 : /* Oops, allocate space for new region information */
26837 : rit = (RegionInfo *) xrealloc(ri, sizeRI * sizeof(RegionInfo));
26841 : rit = &ri[numRI];
26844 : rit->prevBand = 0;
26845 : rit->curBand = 0;
26846 : rit->reg.extents = *box;
26847 : rit->reg.data = (RegDataPtr)NULL;
26848 : if (!miRectAlloc(&rit->reg, (i+numRI) / numRI)) /* MUST force allocation */
26853 : /* Make a final pass over each region in order to Coalesce and set
26854 : extents.x2 and extents.y2 */
26856 : for (j = numRI, rit = ri; --j >= 0; rit++)
26859 : riBox = REGION_END(reg);
26860 : reg->extents.y2 = riBox->y2;
26861 : if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
26862 : Coalesce(reg, rit->prevBand, rit->curBand);
26863 : if (reg->data->numRects == 1) /* keep unions happy below */
26866 : reg->data = (RegDataPtr)NULL;
26870 : /* Step 3: Union all regions into a single region */
26871 1 0.0011 : while (numRI > 1)
26873 : int half = numRI/2;
26874 : for (j = numRI & 1; j < (half + (numRI & 1)); j++)
26876 : reg = &ri[j].reg;
26877 : hreg = &ri[j+half].reg;
26878 : if (!miRegionOp(reg, reg, hreg, miUnionO, TRUE, TRUE, pOverlap))
26880 : if (hreg->extents.x1 < reg->extents.x1)
26881 : reg->extents.x1 = hreg->extents.x1;
26882 : if (hreg->extents.y1 < reg->extents.y1)
26883 : reg->extents.y1 = hreg->extents.y1;
26884 : if (hreg->extents.x2 > reg->extents.x2)
26885 : reg->extents.x2 = hreg->extents.x2;
26886 1 0.0011 : if (hreg->extents.y2 > reg->extents.y2)
26887 : reg->extents.y2 = hreg->extents.y2;
26892 : *badreg = ri[0].reg;
26897 : for (i = 0; i < numRI; i++)
26898 : xfreeData(&ri[i].reg);
26900 : return miRegionBreak (badreg);
26903 :_X_EXPORT RegionPtr
26904 :miRectsToRegion(nrects, prect, ctype)
26906 : xRectangle *prect;
26908 1 0.0011 :{ /* miRectsToRegion total: 8 0.0087 */
26911 : RegDataPtr pData;
26914 : int x1, y1, x2, y2;
26916 : pRgn = miRegionCreate(NullBox, 0);
26917 : if (REGION_NAR (pRgn))
26919 4 0.0044 : if (!nrects)
26925 1 0.0011 : if ((x2 = x1 + (int) prect->width) > MAXSHORT)
26927 : if ((y2 = y1 + (int) prect->height) > MAXSHORT)
26929 : if (x1 != x2 && y1 != y2)
26931 : pRgn->extents.x1 = x1;
26932 : pRgn->extents.y1 = y1;
26933 : pRgn->extents.x2 = x2;
26934 : pRgn->extents.y2 = y2;
26935 : pRgn->data = (RegDataPtr)NULL;
26939 : pData = xallocData(nrects);
26942 : miRegionBreak (pRgn);
26945 : pBox = (BoxPtr) (pData + 1);
26946 : for (i = nrects; --i >= 0; prect++)
26950 : if ((x2 = x1 + (int) prect->width) > MAXSHORT)
26952 : if ((y2 = y1 + (int) prect->height) > MAXSHORT)
26954 : if (x1 != x2 && y1 != y2)
26963 1 0.0011 : if (pBox != (BoxPtr) (pData + 1))
26965 : pData->size = nrects;
26966 : pData->numRects = pBox - (BoxPtr) (pData + 1);
26967 : pRgn->data = pData;
26968 : if (ctype != CT_YXBANDED)
26970 : Bool overlap; /* result ignored */
26971 : pRgn->extents.x1 = pRgn->extents.x2 = 0;
26972 : miRegionValidate(pRgn, &overlap);
26975 : miSetExtents(pRgn);
26985 :/*======================================================================
26986 : * Region Subtraction
26987 : *====================================================================*/
26991 : *-----------------------------------------------------------------------
26993 : * Overlapping band subtraction. x1 is the left-most point not yet
26997 : * TRUE if successful.
27000 : * pReg may have rectangles added to it.
27002 : *-----------------------------------------------------------------------
27007 : *-----------------------------------------------------------------------
27009 : * Subtract regS from regM and leave the result in regD.
27010 : * S stands for subtrahend, M for minuend and D for difference.
27013 : * TRUE if successful.
27016 : * regD is overwritten.
27018 : *-----------------------------------------------------------------------
27021 :miSubtract(regD, regM, regS)
27026 : return pixman_region_subtract (regD, regM, regS);
27029 :/*======================================================================
27030 : * Region Inversion
27031 : *====================================================================*/
27034 : *-----------------------------------------------------------------------
27036 : * Take a region and a box and return a region that is everything
27037 : * in the box but not in the region. The careful reader will note
27038 : * that this is the same as subtracting the region from the box...
27044 : * newReg is overwritten.
27046 : *-----------------------------------------------------------------------
27049 :miInverse(newReg, reg1, invRect)
27050 : RegionPtr newReg; /* Destination region */
27051 : RegionPtr reg1; /* Region to invert */
27052 : BoxPtr invRect; /* Bounding box for inversion */
27054 : return pixman_region_inverse (newReg, reg1, invRect);
27057 :miRectIn(region, prect)
27058 : RegionPtr region;
27061 : return pixman_region_contains_rectangle (region, prect);
27064 :/* TranslateRegion(pReg, x, y)
27065 : translates in place
27069 :miTranslateRegion(pReg, x, y)
27073 2 0.0022 :{ /* miTranslateRegion total: 2 0.0022 */
27074 : pixman_region_translate (pReg, x, y);
27078 :miRegionReset(pReg, pBox)
27082 : pixman_region_reset (pReg, pBox);
27086 :miPointInRegion(pReg, x, y, box)
27089 : BoxPtr box; /* "return" value */
27091 : return pixman_region_contains_point (pReg, x, y, box);
27095 :miRegionNotEmpty(pReg)
27098 : return pixman_region_not_empty (pReg);
27102 :miRegionBroken(RegionPtr pReg)
27105 : return (REGION_NAR(pReg));
27109 :miRegionEmpty(pReg)
27114 : pReg->extents.x2 = pReg->extents.x1;
27115 : pReg->extents.y2 = pReg->extents.y1;
27116 : pReg->data = &miEmptyData;
27120 :miRegionExtents(pReg)
27124 : return(&pReg->extents);
27127 :#define ExchangeSpans(a, b) \
27129 : DDXPointRec tpt; \
27132 : tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
27133 : tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
27136 :/* ||| I should apply the merge sort code to rectangle sorting above, and see
27137 : if mapping time can be improved. But right now I've been at work 12 hours,
27141 :static void QuickSortSpans(
27142 : DDXPointRec spans[],
27150 : /* Always called with numSpans > 1 */
27151 : /* Sorts only by y, doesn't bother to sort by x */
27155 : if (numSpans < 9)
27157 : /* Do insertion sort */
27160 : yprev = spans[0].y;
27163 : { /* while i != numSpans */
27167 : /* spans[i] is out of order. Move into proper location. */
27171 : for (j = 0; y >= spans[j].y; j++) {}
27174 : for (k = i; k != j; k--)
27176 : spans[k] = spans[k-1];
27177 : widths[k] = widths[k-1];
27182 : } /* if out of order */
27185 : } while (i != numSpans);
27189 : /* Choose partition element, stick in location 0 */
27190 : m = numSpans / 2;
27191 : if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
27192 : if (spans[m].y > spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
27193 : if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
27196 : /* Partition array */
27206 : } while (i != numSpans && r->y < y);
27212 : } while (y < r->y);
27214 : ExchangeSpans(i, j);
27217 : /* Move partition element back to middle */
27218 : ExchangeSpans(0, j);
27221 : if (numSpans-j-1 > 1)
27222 : QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
27224 : } while (numSpans > 1);
27227 :#define NextBand() \
27229 : clipy1 = pboxBandStart->y1; \
27230 : clipy2 = pboxBandStart->y2; \
27231 : pboxBandEnd = pboxBandStart + 1; \
27232 : while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) { \
27235 : for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
27239 : Clip a list of scanlines to a region. The caller has allocated the
27240 : space. FSorted is non-zero if the scanline origins are in ascending
27242 : returns the number of new, clipped scanlines.
27247 : RegionPtr prgnDst,
27251 : DDXPointPtr pptNew,
27255 : DDXPointPtr pptLast;
27256 : int *pwidthNewStart; /* the vengeance of Xerox! */
27261 : pptLast = ppt + nspans;
27262 : pwidthNewStart = pwidthNew;
27264 : if (!prgnDst->data)
27266 : /* Do special fast code with clip boundaries in registers(?) */
27267 : /* It doesn't pay much to make use of fSorted in this case,
27268 : so we lump everything together. */
27270 : int clipx1, clipx2, clipy1, clipy2;
27272 : clipx1 = prgnDst->extents.x1;
27273 : clipy1 = prgnDst->extents.y1;
27274 : clipx2 = prgnDst->extents.x2;
27275 : clipy2 = prgnDst->extents.y2;
27277 : for (; ppt != pptLast; ppt++, pwidth++)
27281 : if (clipy1 <= y && y < clipy2)
27283 : x2 = x1 + *pwidth;
27284 : if (x1 < clipx1) x1 = clipx1;
27285 : if (x2 > clipx2) x2 = clipx2;
27288 : /* part of span in clip rectangle */
27291 : *pwidthNew = x2 - x1;
27299 : else if ((numRects = prgnDst->data->numRects))
27301 : /* Have to clip against many boxes */
27302 : BoxPtr pboxBandStart, pboxBandEnd;
27305 : int clipy1, clipy2;
27307 : /* In this case, taking advantage of sorted spans gains more than
27308 : the sorting costs. */
27309 : if ((! fSorted) && (nspans > 1))
27310 : QuickSortSpans(ppt, pwidth, nspans);
27312 : pboxBandStart = REGION_BOXPTR(prgnDst);
27313 : pboxLast = pboxBandStart + numRects;
27317 : for (; ppt != pptLast; )
27322 : /* span is in the current band */
27323 : pbox = pboxBandStart;
27325 : x2 = x1 + *pwidth;
27327 : { /* For each box in band */
27328 : int newx1, newx2;
27332 : if (newx1 < pbox->x1) newx1 = pbox->x1;
27333 : if (newx2 > pbox->x2) newx2 = pbox->x2;
27334 : if (newx1 < newx2)
27336 : /* Part of span in clip rectangle */
27337 : pptNew->x = newx1;
27339 : *pwidthNew = newx2 - newx1;
27344 : } while (pbox != pboxBandEnd);
27350 : /* Move to next band, adjust ppt as needed */
27351 : pboxBandStart = pboxBandEnd;
27352 : if (pboxBandStart == pboxLast)
27353 : break; /* We're completely done */
27358 : return (pwidthNew - pwidthNewStart);
27361 :/* find the band in a region with the most rectangles */
27363 :miFindMaxBand(prgn)
27369 : int nMaxBand = 0;
27373 : nbox = REGION_NUM_RECTS(prgn);
27374 : pbox = REGION_RECTS(prgn);
27378 : yThisBand = pbox->y1;
27380 : while((nbox > 0) && (pbox->y1 == yThisBand))
27386 : if (nThisBand > nMaxBand)
27387 : nMaxBand = nThisBand;
27389 : return (nMaxBand);
27392 * Total samples for file : "malloc.c"
27397 <credited to line zero> 65 0.0708 :
27398 /* malloc_consolidate total: 65 0.0708 */
27400 * Total samples for file : "/home/cworth/src/xorg/xserver/os/io.c"
27406 :/***********************************************************
27408 :Copyright 1987, 1989, 1998 The Open Group
27410 :Permission to use, copy, modify, distribute, and sell this software and its
27411 :documentation for any purpose is hereby granted without fee, provided that
27412 :the above copyright notice appear in all copies and that both that
27413 :copyright notice and this permission notice appear in supporting
27416 :The above copyright notice and this permission notice shall be included in
27417 :all copies or substantial portions of the Software.
27419 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27420 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27421 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27422 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
27423 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27424 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27426 :Except as contained in this notice, the name of The Open Group shall not be
27427 :used in advertising or otherwise to promote the sale, use or other dealings
27428 :in this Software without prior written authorization from The Open Group.
27431 :Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
27433 : All Rights Reserved
27435 :Permission to use, copy, modify, and distribute this software and its
27436 :documentation for any purpose and without fee is hereby granted,
27437 :provided that the above copyright notice appear in all copies and that
27438 :both that copyright notice and this permission notice appear in
27439 :supporting documentation, and that the name of Digital not be
27440 :used in advertising or publicity pertaining to distribution of the
27441 :software without specific, written prior permission.
27443 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27444 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
27445 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
27446 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
27447 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
27448 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27452 :******************************************************************/
27453 :/*****************************************************************
27456 : * WriteToClient, ReadRequestFromClient
27457 : * InsertFakeRequest, ResetCurrentRequest
27459 : *****************************************************************/
27461 :#ifdef HAVE_DIX_CONFIG_H
27462 :#include <dix-config.h>
27466 :#define DEBUG_COMMUNICATION
27469 :#include <X11/Xwinsock.h>
27471 :#include <stdio.h>
27473 :#define TRANS_SERVER
27474 :#define TRANS_REOPEN
27475 :#include <X11/Xtrans/Xtrans.h>
27476 :#include <X11/Xmd.h>
27477 :#include <errno.h>
27478 :#if !defined(WIN32)
27480 :#include <sys/uio.h>
27485 :#include <X11/X.h>
27486 :#define NEED_REPLIES
27487 :#include <X11/Xproto.h>
27489 :#include "osdep.h"
27490 :#include <X11/Xpoll.h>
27491 :#include "opaque.h"
27492 :#include "dixstruct.h"
27495 :_X_EXPORT CallbackListPtr ReplyCallback;
27496 :_X_EXPORT CallbackListPtr FlushCallback;
27498 :static ConnectionInputPtr AllocateInputBuffer(void);
27499 :static ConnectionOutputPtr AllocateOutputBuffer(void);
27500 :static xReqPtr PeekNextRequest(xReqPtr req, ClientPtr client, Bool readmore);
27501 :static void SkipRequests(xReqPtr req, ClientPtr client, int numskipped);
27503 :/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
27504 : * systems are broken and return EWOULDBLOCK when they should return EAGAIN
27507 :#if defined(EAGAIN) && defined(EWOULDBLOCK)
27508 :#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
27511 :#define ETEST(err) (err == EAGAIN)
27513 :#define ETEST(err) (err == EWOULDBLOCK)
27516 :#else /* WIN32 The socket errorcodes differ from the normal errors*/
27517 :#define ETEST(err) (err == EAGAIN || err == WSAEWOULDBLOCK)
27520 :static Bool CriticalOutputPending;
27521 :static int timesThisConnection = 0;
27522 :static ConnectionInputPtr FreeInputs = (ConnectionInputPtr)NULL;
27523 :static ConnectionOutputPtr FreeOutputs = (ConnectionOutputPtr)NULL;
27524 :static OsCommPtr AvailableInput = (OsCommPtr)NULL;
27526 :#define get_req_len(req,cli) ((cli)->swapped ? \
27527 : lswaps((req)->length) : (req)->length)
27530 :#include <X11/extensions/bigreqstr.h>
27532 :#define get_big_req_len(req,cli) ((cli)->swapped ? \
27533 : lswapl(((xBigReq *)(req))->length) : \
27534 : ((xBigReq *)(req))->length)
27537 :#define MAX_TIMES_PER 10
27540 : * A lot of the code in this file manipulates a ConnectionInputPtr:
27542 : * -----------------------------------------------
27543 : * |------- bufcnt ------->| | |
27544 : * | |- gotnow ->| | |
27545 : * | |-------- needed ------>| |
27546 : * |-----------+--------- size --------+---------->|
27547 : * -----------------------------------------------
27552 : * buffer is a pointer to the start of the buffer.
27553 : * bufptr points to the start of the current request.
27554 : * bufcnt counts how many bytes are in the buffer.
27555 : * size is the size of the buffer in bytes.
27557 : * In several of the functions, gotnow and needed are local variables
27558 : * that do the following:
27560 : * gotnow is the number of bytes of the request that we're
27561 : * trying to read that are currently in the buffer.
27562 : * Typically, gotnow = (buffer + bufcnt) - bufptr
27564 : * needed = the length of the request that we're trying to
27565 : * read. Watch out: needed sometimes counts bytes and sometimes
27566 : * counts CARD32's.
27570 :/*****************************************************************
27571 : * ReadRequestFromClient
27572 : * Returns one request in client->requestBuffer. The request
27573 : * length will be in client->req_len. Return status is:
27575 : * > 0 if successful, specifies length in bytes of the request
27576 : * = 0 if entire request is not yet available
27577 : * < 0 if client should be terminated
27579 : * The request returned must be contiguous so that it can be
27580 : * cast in the dispatcher to the correct request type. Because requests
27581 : * are variable length, ReadRequestFromClient() must look at the first 4
27582 : * or 8 bytes of a request to determine the length (the request length is
27583 : * in the 3rd and 4th bytes of the request unless it is a Big Request
27584 : * (see the Big Request Extension), in which case the 3rd and 4th bytes
27585 : * are zero and the following 4 bytes are the request length.
27587 : * Note: in order to make the server scheduler (WaitForSomething())
27588 : * "fair", the ClientsWithInput mask is used. This mask tells which
27589 : * clients have FULL requests left in their buffers. Clients with
27590 : * partial requests require a read. Basically, client buffers
27591 : * are drained before select() is called again. But, we can't keep
27592 : * reading from a client that is sending buckets of data (or has
27593 : * a partial request) because others clients need to be scheduled.
27594 : *****************************************************************/
27596 :#define YieldControl() \
27597 : { isItTimeToYield = TRUE; \
27598 : timesThisConnection = 0; }
27599 :#define YieldControlNoInput() \
27600 : { YieldControl(); \
27601 : FD_CLR(fd, &ClientsWithInput); }
27602 :#define YieldControlDeath() \
27603 : { timesThisConnection = 0; }
27606 :ReadRequestFromClient(ClientPtr client)
27607 2 0.0022 :{ /* ReadRequestFromClient total: 60 0.0654 */
27608 3 0.0033 : OsCommPtr oc = (OsCommPtr)client->osPrivate;
27609 : ConnectionInputPtr oci = oc->input;
27611 : unsigned int gotnow, needed;
27613 : register xReq *request;
27614 : Bool need_header;
27616 : Bool move_header;
27619 : /* If an input buffer was empty, either free it if it is too big
27620 : * or link it into our list of free input buffers. This means that
27621 : * different clients can share the same input buffer (at different
27622 : * times). This was done to save memory.
27625 : if (AvailableInput)
27627 : if (AvailableInput != oc)
27629 : register ConnectionInputPtr aci = AvailableInput->input;
27630 : if (aci->size > BUFWATERMARK)
27632 : xfree(aci->buffer);
27637 : aci->next = FreeInputs;
27638 : FreeInputs = aci;
27640 : AvailableInput->input = (ConnectionInputPtr)NULL;
27642 : AvailableInput = (OsCommPtr)NULL;
27645 : /* make sure we have an input buffer */
27649 : if ((oci = FreeInputs))
27651 : FreeInputs = oci->next;
27653 : else if (!(oci = AllocateInputBuffer()))
27655 : YieldControlDeath();
27661 : /* advance to start of next request */
27663 3 0.0033 : oci->bufptr += oci->lenLastReq;
27665 : need_header = FALSE;
27667 : move_header = FALSE;
27669 6 0.0065 : gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
27670 2 0.0022 : if (gotnow < sizeof(xReq))
27672 : /* We don't have an entire xReq yet. Can't tell how big
27673 : * the request will be until we get the whole xReq.
27675 : needed = sizeof(xReq);
27676 : need_header = TRUE;
27680 : /* We have a whole xReq. We can tell how big the whole
27681 : * request will be unless it is a Big Request.
27683 : request = (xReq *)oci->bufptr;
27684 2 0.0022 : needed = get_req_len(request, client);
27686 1 0.0011 : if (!needed && client->big_requests)
27688 : /* It's a Big Request. */
27689 : move_header = TRUE;
27690 : if (gotnow < sizeof(xBigReq))
27692 : /* Still need more data to tell just how big. */
27693 : needed = sizeof(xBigReq) >> 2; /* needed is in CARD32s now */
27694 : need_header = TRUE;
27697 : needed = get_big_req_len(request, client);
27700 1 0.0011 : client->req_len = needed;
27701 : needed <<= 2; /* needed is in bytes now */
27703 : if (gotnow < needed)
27705 : /* Need to read more data, either so that we can get a
27706 : * complete xReq (if need_header is TRUE), a complete
27707 : * xBigReq (if move_header is TRUE), or the rest of the
27708 : * request (if need_header and move_header are both FALSE).
27711 : oci->lenLastReq = 0;
27712 2 0.0022 : if (needed > MAXBUFSIZE)
27714 : /* request is too big for us to handle */
27715 : YieldControlDeath();
27718 : if ((gotnow == 0) ||
27719 : ((oci->bufptr - oci->buffer + needed) > oci->size))
27721 : /* no data, or the request is too big to fit in the buffer */
27723 : if ((gotnow > 0) && (oci->bufptr != oci->buffer))
27724 : /* save the data we've already read */
27725 : memmove(oci->buffer, oci->bufptr, gotnow);
27726 : if (needed > oci->size)
27728 : /* make buffer bigger to accomodate request */
27731 : ibuf = (char *)xrealloc(oci->buffer, needed);
27734 : YieldControlDeath();
27737 : oci->size = needed;
27738 : oci->buffer = ibuf;
27740 : oci->bufptr = oci->buffer;
27741 : oci->bufcnt = gotnow;
27743 : /* XXX this is a workaround. This function is sometimes called
27744 : * after the trans_conn has been freed. In this case trans_conn
27745 : * will be null. Really ought to restructure things so that we
27746 : * never get here in those circumstances.
27748 : if (!oc->trans_conn)
27750 : /* treat as if an error occured on the read, which is what
27753 : YieldControlDeath();
27756 : result = _XSERVTransRead(oc->trans_conn, oci->buffer + oci->bufcnt,
27757 : oci->size - oci->bufcnt);
27760 : if ((result < 0) && ETEST(errno))
27762 :#if defined(SVR4) && defined(i386) && !defined(sun)
27766 : YieldControlNoInput();
27770 : YieldControlDeath();
27773 : oci->bufcnt += result;
27774 : gotnow += result;
27775 : /* free up some space after huge requests */
27776 : if ((oci->size > BUFWATERMARK) &&
27777 : (oci->bufcnt < BUFSIZE) && (needed < BUFSIZE))
27781 : ibuf = (char *)xrealloc(oci->buffer, BUFSIZE);
27784 : oci->size = BUFSIZE;
27785 : oci->buffer = ibuf;
27786 : oci->bufptr = ibuf + oci->bufcnt - gotnow;
27789 : if (need_header && gotnow >= needed)
27791 : /* We wanted an xReq, now we've gotten it. */
27792 : request = (xReq *)oci->bufptr;
27793 : needed = get_req_len(request, client);
27795 : if (!needed && client->big_requests)
27797 : move_header = TRUE;
27798 : if (gotnow < sizeof(xBigReq))
27799 : needed = sizeof(xBigReq) >> 2;
27801 : needed = get_big_req_len(request, client);
27804 : client->req_len = needed;
27807 : if (gotnow < needed)
27809 : /* Still don't have enough; punt. */
27810 : YieldControlNoInput();
27814 1 0.0011 : if (needed == 0)
27817 : if (client->big_requests)
27818 : needed = sizeof(xBigReq);
27821 : needed = sizeof(xReq);
27823 3 0.0033 : oci->lenLastReq = needed;
27826 : * Check to see if client has at least one whole request in the
27827 : * buffer beyond the request we're returning to the caller.
27828 : * If there is only a partial request, treat like buffer
27829 : * is empty so that select() will be called again and other clients
27830 : * can get into the queue.
27833 1 0.0011 : gotnow -= needed;
27834 : if (gotnow >= sizeof(xReq))
27836 1 0.0011 : request = (xReq *)(oci->bufptr + needed);
27837 9 0.0098 : if (gotnow >= (result = (get_req_len(request, client) << 2))
27840 : (client->big_requests &&
27841 : (gotnow >= sizeof(xBigReq) &&
27842 : gotnow >= (get_big_req_len(request, client) << 2))))
27845 11 0.0120 : FD_SET(fd, &ClientsWithInput);
27848 :#ifdef SMART_SCHEDULE
27849 1 0.0011 : if (!SmartScheduleDisable)
27850 : FD_CLR(fd, &ClientsWithInput);
27853 : YieldControlNoInput();
27859 : AvailableInput = oc;
27860 :#ifdef SMART_SCHEDULE
27861 : if (!SmartScheduleDisable)
27862 : FD_CLR(fd, &ClientsWithInput);
27865 : YieldControlNoInput();
27867 :#ifdef SMART_SCHEDULE
27868 3 0.0033 : if (SmartScheduleDisable)
27870 : if (++timesThisConnection >= MAX_TIMES_PER)
27875 : request = (xReq *)oci->bufptr;
27876 : oci->bufptr += (sizeof(xBigReq) - sizeof(xReq));
27877 : *(xReq *)oci->bufptr = *request;
27878 : oci->lenLastReq -= (sizeof(xBigReq) - sizeof(xReq));
27879 : client->req_len -= (sizeof(xBigReq) - sizeof(xReq)) >> 2;
27882 3 0.0033 : client->requestBuffer = (pointer)oci->bufptr;
27883 :#ifdef DEBUG_COMMUNICATION
27885 : xReq *req = client->requestBuffer;
27886 : ErrorF("REQUEST: ClientIDX: %i, type: 0x%x data: 0x%x len: %i\n",
27887 : client->index,req->reqType,req->data,req->length);
27893 :/*****************************************************************
27894 : * InsertFakeRequest
27895 : * Splice a consed up (possibly partial) request in as the next request.
27897 : **********************/
27900 :InsertFakeRequest(ClientPtr client, char *data, int count)
27902 : OsCommPtr oc = (OsCommPtr)client->osPrivate;
27903 : ConnectionInputPtr oci = oc->input;
27905 : int gotnow, moveup;
27907 : if (AvailableInput)
27909 : if (AvailableInput != oc)
27911 : ConnectionInputPtr aci = AvailableInput->input;
27912 : if (aci->size > BUFWATERMARK)
27914 : xfree(aci->buffer);
27919 : aci->next = FreeInputs;
27920 : FreeInputs = aci;
27922 : AvailableInput->input = (ConnectionInputPtr)NULL;
27924 : AvailableInput = (OsCommPtr)NULL;
27928 : if ((oci = FreeInputs))
27929 : FreeInputs = oci->next;
27930 : else if (!(oci = AllocateInputBuffer()))
27934 : oci->bufptr += oci->lenLastReq;
27935 : oci->lenLastReq = 0;
27936 : gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
27937 : if ((gotnow + count) > oci->size)
27941 : ibuf = (char *)xrealloc(oci->buffer, gotnow + count);
27944 : oci->size = gotnow + count;
27945 : oci->buffer = ibuf;
27946 : oci->bufptr = ibuf + oci->bufcnt - gotnow;
27948 : moveup = count - (oci->bufptr - oci->buffer);
27952 : memmove(oci->bufptr + moveup, oci->bufptr, gotnow);
27953 : oci->bufptr += moveup;
27954 : oci->bufcnt += moveup;
27956 : memmove(oci->bufptr - count, data, count);
27957 : oci->bufptr -= count;
27959 : if ((gotnow >= sizeof(xReq)) &&
27960 : (gotnow >= (int)(get_req_len((xReq *)oci->bufptr, client) << 2)))
27961 : FD_SET(fd, &ClientsWithInput);
27963 : YieldControlNoInput();
27967 :/*****************************************************************
27968 : * ResetRequestFromClient
27969 : * Reset to reexecute the current request, and yield.
27971 : **********************/
27974 :ResetCurrentRequest(ClientPtr client)
27976 : OsCommPtr oc = (OsCommPtr)client->osPrivate;
27977 : register ConnectionInputPtr oci = oc->input;
27979 : register xReq *request;
27980 : int gotnow, needed;
27981 : if (AvailableInput == oc)
27982 : AvailableInput = (OsCommPtr)NULL;
27983 : oci->lenLastReq = 0;
27984 : gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
27985 : if (gotnow < sizeof(xReq))
27987 : YieldControlNoInput();
27991 : request = (xReq *)oci->bufptr;
27992 : needed = get_req_len(request, client);
27994 : if (!needed && client->big_requests)
27996 : oci->bufptr -= sizeof(xBigReq) - sizeof(xReq);
27997 : *(xReq *)oci->bufptr = *request;
27998 : ((xBigReq *)oci->bufptr)->length = client->req_len;
27999 : if (client->swapped)
28002 : swapl(&((xBigReq *)oci->bufptr)->length, n);
28006 : if (gotnow >= (needed << 2))
28008 : if (FD_ISSET(fd, &AllClients))
28010 : FD_SET(fd, &ClientsWithInput);
28014 : FD_SET(fd, &IgnoredClientsWithInput);
28019 : YieldControlNoInput();
28025 :/*****************************************************************
28026 : * PeekNextRequest and SkipRequests were implemented to support DBE
28027 : * idioms, but can certainly be used outside of DBE. There are two
28028 : * related macros in os.h, ReqLen and CastxReq. See the porting
28029 : * layer document for more details.
28031 : **********************/
28034 :/*****************************************************************
28035 : * PeekNextRequest
28036 : * lets you look ahead at the unexecuted requests in a
28037 : * client's request buffer.
28039 : * Note: this implementation of PeekNextRequest ignores the
28040 : * readmore parameter.
28042 : **********************/
28046 : xReqPtr req, /* request we're starting from */
28047 : ClientPtr client, /* client whose requests we're skipping */
28048 : Bool readmore) /* attempt to read more if next request isn't there? */
28050 : register ConnectionInputPtr oci = ((OsCommPtr)client->osPrivate)->input;
28051 : xReqPtr pnextreq;
28052 : int needed, gotnow, reqlen;
28054 : if (!oci) return NULL;
28058 : /* caller wants the request after the one currently being executed */
28059 : pnextreq = (xReqPtr)
28060 : (((CARD32 *)client->requestBuffer) + client->req_len);
28064 : /* caller wants the request after the one specified by req */
28065 : reqlen = get_req_len(req, client);
28067 : if (!reqlen) reqlen = get_big_req_len(req, client);
28069 : pnextreq = (xReqPtr)(((char *)req) + (reqlen << 2));
28072 : /* see how much of the next request we have available */
28074 : gotnow = oci->bufcnt - (((char *)pnextreq) - oci->buffer);
28076 : if (gotnow < sizeof(xReq))
28079 : needed = get_req_len(pnextreq, client) << 2;
28083 : /* it's a big request */
28084 : if (gotnow < sizeof(xBigReq))
28086 : needed = get_big_req_len(pnextreq, client) << 2;
28090 : /* if we have less than we need, return NULL */
28092 : return (gotnow < needed) ? NULL : pnextreq;
28095 :/*****************************************************************
28097 : * lets you skip over some of the requests in a client's
28098 : * request buffer. Presumably the caller has used PeekNextRequest
28099 : * to examine the requests being skipped and has performed whatever
28100 : * actions they dictate.
28102 : **********************/
28104 :_X_EXPORT CallbackListPtr SkippedRequestsCallback = NULL;
28108 : xReqPtr req, /* last request being skipped */
28109 : ClientPtr client, /* client whose requests we're skipping */
28110 : int numskipped) /* how many requests we're skipping */
28112 : OsCommPtr oc = (OsCommPtr)client->osPrivate;
28113 : register ConnectionInputPtr oci = oc->input;
28116 : /* see if anyone wants to snoop the skipped requests */
28118 : if (SkippedRequestsCallback)
28120 : SkippedRequestInfoRec skipinfo;
28121 : skipinfo.req = req;
28122 : skipinfo.client = client;
28123 : skipinfo.numskipped = numskipped;
28124 : CallCallbacks(&SkippedRequestsCallback, &skipinfo);
28127 : /* adjust the sequence number */
28128 : client->sequence += numskipped;
28130 : /* twiddle the oci to skip over the requests */
28132 : reqlen = get_req_len(req, client);
28134 : if (!reqlen) reqlen = get_big_req_len(req, client);
28137 : oci->bufptr = (char *)req;
28138 : oci->lenLastReq = reqlen;
28140 : /* see if any requests left in the buffer */
28142 : if ( ((char *)req + reqlen) == (oci->buffer + oci->bufcnt) )
28144 : /* no requests; mark input buffer as available and client
28145 : * as having no input
28148 : AvailableInput = oc;
28149 : YieldControlNoInput();
28154 : /* lookup table for adding padding bytes to data that is read from
28155 : or written to the X socket. */
28156 :static int padlength[4] = {0, 3, 2, 1};
28158 : /********************
28159 : * FlushAllOutput()
28160 : * Flush all clients with output. However, if some client still
28161 : * has input in the queue (more requests), then don't flush. This
28162 : * will prevent the output queue from being flushed every time around
28163 : * the round robin queue. Now, some say that it SHOULD be flushed
28164 : * every time around, but...
28166 : **********************/
28169 :FlushAllOutput(void)
28171 : register int index, base;
28172 : register fd_mask mask; /* raphael */
28174 : register ClientPtr client;
28175 : Bool newoutput = NewOutputPending;
28176 :#if defined(WIN32)
28177 : fd_set newOutputPending;
28180 : if (FlushCallback)
28181 : CallCallbacks(&FlushCallback, NULL);
28187 : * It may be that some client still has critical output pending,
28188 : * but he is not yet ready to receive it anyway, so we will
28189 : * simply wait for the select to tell us when he's ready to receive.
28191 : CriticalOutputPending = FALSE;
28192 : NewOutputPending = FALSE;
28195 : for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++)
28197 : mask = OutputPending.fds_bits[ base ];
28198 : OutputPending.fds_bits[ base ] = 0;
28201 : index = ffs(mask) - 1;
28202 : mask &= ~lowbit(mask);
28203 : if ((index = ConnectionTranslation[(base * (sizeof(fd_mask)*8)) + index]) == 0)
28205 : client = clients[index];
28206 : if (client->clientGone)
28208 : oc = (OsCommPtr)client->osPrivate;
28209 : if (FD_ISSET(oc->fd, &ClientsWithInput))
28211 : FD_SET(oc->fd, &OutputPending); /* set the bit again */
28212 : NewOutputPending = TRUE;
28215 : (void)FlushClient(client, oc, (char *)NULL, 0);
28219 : FD_ZERO(&newOutputPending);
28220 : for (base = 0; base < XFD_SETCOUNT(&OutputPending); base++)
28222 : index = XFD_FD(&OutputPending, base);
28223 : if ((index = GetConnectionTranslation(index)) == 0)
28225 : client = clients[index];
28226 : if (client->clientGone)
28228 : oc = (OsCommPtr)client->osPrivate;
28229 : if (FD_ISSET(oc->fd, &ClientsWithInput))
28231 : FD_SET(oc->fd, &newOutputPending); /* set the bit again */
28232 : NewOutputPending = TRUE;
28235 : (void)FlushClient(client, oc, (char *)NULL, 0);
28237 : XFD_COPYSET(&newOutputPending, &OutputPending);
28238 :#endif /* WIN32 */
28242 :FlushIfCriticalOutputPending(void)
28244 : if (CriticalOutputPending)
28245 : FlushAllOutput();
28249 :SetCriticalOutputPending(void)
28251 : CriticalOutputPending = TRUE;
28254 :/*****************
28256 : * Copies buf into ClientPtr.buf if it fits (with padding), else
28257 : * flushes ClientPtr.buf and buf to client. As of this writing,
28258 : * every use of WriteToClient is cast to void, and the result
28259 : * is ignored. Potentially, this could be used by requests
28260 : * that are sending several chunks of data and want to break
28261 : * out of a loop on error. Thus, we will leave the type of
28262 : * this routine as int.
28263 : *****************/
28266 :WriteToClient (ClientPtr who, int count, char *buf)
28268 : OsCommPtr oc = (OsCommPtr)who->osPrivate;
28269 : ConnectionOutputPtr oco = oc->output;
28271 :#ifdef DEBUG_COMMUNICATION
28272 : Bool multicount = FALSE;
28276 :#ifdef DEBUG_COMMUNICATION
28280 : xGenericReply *rep;
28283 : if (!who->replyBytesRemaining) {
28286 : rep = (xGenericReply*)buf;
28287 : if (rep->sequenceNumber == who->sequence) {
28288 : snprintf(info,127,"Xreply: type: 0x%x data: 0x%x "
28289 : "len: %i seq#: 0x%x", rep->type, rep->data1,
28290 : rep->length, rep->sequenceNumber);
28291 : multicount = TRUE;
28295 : err = (xError*)buf;
28296 : snprintf(info,127,"Xerror: Code: 0x%x resID: 0x%x maj: 0x%x "
28297 : "min: %x", err->errorCode,err->resourceID,
28298 : err->minorCode,err->majorCode);
28301 : if ((buf[0] & 0x7f) == KeymapNotify)
28302 : snprintf(info,127,"KeymapNotifyEvent: %i",buf[0]);
28304 : ev = (xEvent*)buf;
28305 : snprintf(info,127,"XEvent: type: 0x%x detail: 0x%x "
28306 : "seq#: 0x%x", ev->u.u.type, ev->u.u.detail,
28307 : ev->u.u.sequenceNumber);
28310 : ErrorF("REPLY: ClientIDX: %i %s\n",who->index, info);
28312 : multicount = TRUE;
28318 : if ((oco = FreeOutputs))
28320 : FreeOutputs = oco->next;
28322 : else if (!(oco = AllocateOutputBuffer()))
28324 : if (oc->trans_conn) {
28325 : _XSERVTransDisconnect(oc->trans_conn);
28326 : _XSERVTransClose(oc->trans_conn);
28327 : oc->trans_conn = NULL;
28329 : MarkClientException(who);
28332 : oc->output = oco;
28335 : padBytes = padlength[count & 3];
28337 : if(ReplyCallback)
28339 : ReplyInfoRec replyinfo;
28341 : replyinfo.client = who;
28342 : replyinfo.replyData = buf;
28343 : replyinfo.dataLenBytes = count + padBytes;
28344 : if (who->replyBytesRemaining)
28345 : { /* still sending data of an earlier reply */
28346 : who->replyBytesRemaining -= count + padBytes;
28347 : replyinfo.startOfReply = FALSE;
28348 : replyinfo.bytesRemaining = who->replyBytesRemaining;
28349 : CallCallbacks((&ReplyCallback), (pointer)&replyinfo);
28351 : else if (who->clientState == ClientStateRunning
28352 : && buf[0] == X_Reply)
28353 : { /* start of new reply */
28355 : unsigned long bytesleft;
28358 : replylen = ((xGenericReply *)buf)->length;
28359 : if (who->swapped)
28360 : swapl(&replylen, n);
28361 : bytesleft = (replylen * 4) + SIZEOF(xReply) - count - padBytes;
28362 : replyinfo.startOfReply = TRUE;
28363 : replyinfo.bytesRemaining = who->replyBytesRemaining = bytesleft;
28364 : CallCallbacks((&ReplyCallback), (pointer)&replyinfo);
28367 :#ifdef DEBUG_COMMUNICATION
28368 : else if (multicount) {
28369 : if (who->replyBytesRemaining) {
28370 : who->replyBytesRemaining -= (count + padBytes);
28373 : replylen = ((xGenericReply *)buf)->length;
28374 : who->replyBytesRemaining =
28375 : (replylen * 4) + SIZEOF(xReply) - count - padBytes;
28379 : if (oco->count + count + padBytes > oco->size)
28381 : FD_CLR(oc->fd, &OutputPending);
28382 : if(!XFD_ANYSET(&OutputPending)) {
28383 : CriticalOutputPending = FALSE;
28384 : NewOutputPending = FALSE;
28386 : return FlushClient(who, oc, buf, count);
28389 : NewOutputPending = TRUE;
28390 : FD_SET(oc->fd, &OutputPending);
28391 : memmove((char *)oco->buf + oco->count, buf, count);
28392 : oco->count += count + padBytes;
28396 : /********************
28398 : * If the client isn't keeping up with us, then we try to continue
28399 : * buffering the data and set the apropriate bit in ClientsWritable
28400 : * (which is used by WaitFor in the select). If the connection yields
28401 : * a permanent error, or we can't allocate any more space, we then
28402 : * close the connection.
28404 : **********************/
28407 :FlushClient(ClientPtr who, OsCommPtr oc, char *extraBuf, int extraCount)
28409 : ConnectionOutputPtr oco = oc->output;
28410 : int connection = oc->fd;
28411 : XtransConnInfo trans_conn = oc->trans_conn;
28412 : struct iovec iov[3];
28413 : static char padBuffer[3];
28422 : padsize = padlength[extraCount & 3];
28423 : notWritten = oco->count + extraCount + padsize;
28424 : todo = notWritten;
28425 : while (notWritten) {
28426 : long before = written; /* amount of whole thing written */
28427 : long remain = todo; /* amount to try this time, <= notWritten */
28431 : /* You could be very general here and have "in" and "out" iovecs
28432 : * and write a loop without using a macro, but what the heck. This
28435 : * how much of this piece is new?
28436 : * if more new then we are trying this time, clamp
28438 : * then bump down amount already written, for next piece
28439 : * else put new stuff in iovec, will need all of next piece
28441 : * Note that todo had better be at least 1 or else we'll end up
28442 : * writing 0 iovecs.
28444 :#define InsertIOV(pointer, length) \
28445 : len = (length) - before; \
28446 : if (len > remain) \
28448 : if (len <= 0) { \
28449 : before = (-len); \
28451 : iov[i].iov_len = len; \
28452 : iov[i].iov_base = (pointer) + before; \
28458 : InsertIOV ((char *)oco->buf, oco->count)
28459 : InsertIOV (extraBuf, extraCount)
28460 : InsertIOV (padBuffer, padsize)
28463 : if (trans_conn && (len = _XSERVTransWritev(trans_conn, iov, i)) >= 0)
28466 : notWritten -= len;
28467 : todo = notWritten;
28469 : else if (ETEST(errno)
28470 :#ifdef SUNSYSV /* check for another brain-damaged OS bug */
28473 :#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
28474 : || ((errno == EMSGSIZE) && (todo == 1))
28478 : /* If we've arrived here, then the client is stuffed to the gills
28479 : and not ready to accept more. Make a note of it and buffer
28481 : FD_SET(connection, &ClientsWriteBlocked);
28482 : AnyClientsWriteBlocked = TRUE;
28484 : if (written < oco->count)
28488 : oco->count -= written;
28489 : memmove((char *)oco->buf,
28490 : (char *)oco->buf + written,
28497 : written -= oco->count;
28501 : if (notWritten > oco->size)
28503 : unsigned char *obuf;
28505 : obuf = (unsigned char *)xrealloc(oco->buf,
28506 : notWritten + BUFSIZE);
28509 : _XSERVTransDisconnect(oc->trans_conn);
28510 : _XSERVTransClose(oc->trans_conn);
28511 : oc->trans_conn = NULL;
28512 : MarkClientException(who);
28516 : oco->size = notWritten + BUFSIZE;
28520 : /* If the amount written extended into the padBuffer, then the
28521 : difference "extraCount - written" may be less than 0 */
28522 : if ((len = extraCount - written) > 0)
28523 : memmove ((char *)oco->buf + oco->count,
28524 : extraBuf + written,
28527 : oco->count = notWritten; /* this will include the pad */
28528 : /* return only the amount explicitly requested */
28529 : return extraCount;
28531 :#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
28532 : else if (errno == EMSGSIZE)
28539 : if (oc->trans_conn)
28541 : _XSERVTransDisconnect(oc->trans_conn);
28542 : _XSERVTransClose(oc->trans_conn);
28543 : oc->trans_conn = NULL;
28545 : MarkClientException(who);
28551 : /* everything was flushed out */
28553 : /* check to see if this client was write blocked */
28554 : if (AnyClientsWriteBlocked)
28556 : FD_CLR(oc->fd, &ClientsWriteBlocked);
28557 : if (! XFD_ANYSET(&ClientsWriteBlocked))
28558 : AnyClientsWriteBlocked = FALSE;
28560 : if (oco->size > BUFWATERMARK)
28567 : oco->next = FreeOutputs;
28568 : FreeOutputs = oco;
28570 : oc->output = (ConnectionOutputPtr)NULL;
28571 : return extraCount; /* return only the amount explicitly requested */
28574 :static ConnectionInputPtr
28575 :AllocateInputBuffer(void)
28577 : ConnectionInputPtr oci;
28579 : oci = (ConnectionInputPtr)xalloc(sizeof(ConnectionInput));
28581 : return (ConnectionInputPtr)NULL;
28582 : oci->buffer = (char *)xalloc(BUFSIZE);
28583 : if (!oci->buffer)
28586 : return (ConnectionInputPtr)NULL;
28588 : oci->size = BUFSIZE;
28589 : oci->bufptr = oci->buffer;
28591 : oci->lenLastReq = 0;
28595 :static ConnectionOutputPtr
28596 :AllocateOutputBuffer(void)
28598 : ConnectionOutputPtr oco;
28600 : oco = (ConnectionOutputPtr)xalloc(sizeof(ConnectionOutput));
28602 : return (ConnectionOutputPtr)NULL;
28603 : oco->buf = (unsigned char *) xalloc(BUFSIZE);
28607 : return (ConnectionOutputPtr)NULL;
28609 : oco->size = BUFSIZE;
28615 :FreeOsBuffers(OsCommPtr oc)
28617 : ConnectionInputPtr oci;
28618 : ConnectionOutputPtr oco;
28620 : if (AvailableInput == oc)
28621 : AvailableInput = (OsCommPtr)NULL;
28622 : if ((oci = oc->input))
28626 : xfree(oci->buffer);
28631 : FreeInputs = oci;
28632 : oci->next = (ConnectionInputPtr)NULL;
28633 : oci->bufptr = oci->buffer;
28635 : oci->lenLastReq = 0;
28638 : if ((oco = oc->output))
28647 : FreeOutputs = oco;
28648 : oco->next = (ConnectionOutputPtr)NULL;
28655 :ResetOsBuffers(void)
28657 : ConnectionInputPtr oci;
28658 : ConnectionOutputPtr oco;
28660 : while ((oci = FreeInputs))
28662 : FreeInputs = oci->next;
28663 : xfree(oci->buffer);
28666 : while ((oco = FreeOutputs))
28668 : FreeOutputs = oco->next;
28674 * Total samples for file : "/home/cworth/src/xorg/xserver/dix/dispatch.c"
28680 :/************************************************************
28682 :Copyright 1987, 1989, 1998 The Open Group
28684 :Permission to use, copy, modify, distribute, and sell this software and its
28685 :documentation for any purpose is hereby granted without fee, provided that
28686 :the above copyright notice appear in all copies and that both that
28687 :copyright notice and this permission notice appear in supporting
28690 :The above copyright notice and this permission notice shall be included in
28691 :all copies or substantial portions of the Software.
28693 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28694 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28695 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28696 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
28697 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28698 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28700 :Except as contained in this notice, the name of The Open Group shall not be
28701 :used in advertising or otherwise to promote the sale, use or other dealings
28702 :in this Software without prior written authorization from The Open Group.
28705 :Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
28707 : All Rights Reserved
28709 :Permission to use, copy, modify, and distribute this software and its
28710 :documentation for any purpose and without fee is hereby granted,
28711 :provided that the above copyright notice appear in all copies and that
28712 :both that copyright notice and this permission notice appear in
28713 :supporting documentation, and that the name of Digital not be
28714 :used in advertising or publicity pertaining to distribution of the
28715 :software without specific, written prior permission.
28717 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
28718 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
28719 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
28720 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
28721 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
28722 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
28725 :********************************************************/
28727 :/* The panoramix components contained the following notice */
28728 :/*****************************************************************
28730 :Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
28732 :Permission is hereby granted, free of charge, to any person obtaining a copy
28733 :of this software and associated documentation files (the "Software"), to deal
28734 :in the Software without restriction, including without limitation the rights
28735 :to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28736 :copies of the Software.
28738 :The above copyright notice and this permission notice shall be included in
28739 :all copies or substantial portions of the Software.
28741 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28742 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28743 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28744 :DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
28745 :BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
28746 :WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
28747 :IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28749 :Except as contained in this notice, the name of Digital Equipment Corporation
28750 :shall not be used in advertising or otherwise to promote the sale, use or other
28751 :dealings in this Software without prior written authorization from Digital
28752 :Equipment Corporation.
28754 :******************************************************************/
28756 :/* XSERVER_DTRACE additions:
28757 : * Copyright 2005-2006 Sun Microsystems, Inc. All rights reserved.
28759 : * Permission is hereby granted, free of charge, to any person obtaining a
28760 : * copy of this software and associated documentation files (the
28761 : * "Software"), to deal in the Software without restriction, including
28762 : * without limitation the rights to use, copy, modify, merge, publish,
28763 : * distribute, and/or sell copies of the Software, and to permit persons
28764 : * to whom the Software is furnished to do so, provided that the above
28765 : * copyright notice(s) and this permission notice appear in all copies of
28766 : * the Software and that both the above copyright notice(s) and this
28767 : * permission notice appear in supporting documentation.
28769 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28770 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28771 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
28772 : * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
28773 : * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
28774 : * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
28775 : * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
28776 : * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
28777 : * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28779 : * Except as contained in this notice, the name of a copyright holder
28780 : * shall not be used in advertising or otherwise to promote the sale, use
28781 : * or other dealings in this Software without prior written authorization
28782 : * of the copyright holder.
28787 :#ifdef HAVE_DIX_CONFIG_H
28788 :#include <dix-config.h>
28791 :#ifdef PANORAMIX_DEBUG
28792 :#include <stdio.h>
28793 :int ProcInitialConnection();
28796 :#include "windowstr.h"
28797 :#include <X11/fonts/fontstruct.h>
28798 :#include "dixfontstr.h"
28799 :#include "gcstruct.h"
28800 :#include "selection.h"
28801 :#include "colormapst.h"
28802 :#include "cursorstr.h"
28803 :#include "scrnintstr.h"
28804 :#include "opaque.h"
28805 :#include "input.h"
28806 :#include "servermd.h"
28807 :#include "extnsionst.h"
28808 :#include "dixfont.h"
28809 :#include "dispatch.h"
28810 :#include "swaprep.h"
28811 :#include "swapreq.h"
28813 :#include "panoramiX.h"
28814 :#include "panoramiXsrv.h"
28818 :#include "appgroup.h"
28821 :#ifndef XKB_IN_SERVER
28822 :#define XKB_IN_SERVER
28824 :#include "inputstr.h"
28825 :#include <xkbsrv.h>
28828 :#ifdef XSERVER_DTRACE
28829 :#include <sys/types.h>
28830 :typedef const char *string;
28831 :#include "Xserver-dtrace.h"
28833 :char *RequestNames[256];
28834 :static void LoadRequestNames(void);
28835 :static void FreeRequestNames(void);
28836 :#define GetRequestName(i) (RequestNames[i])
28839 :#define mskcnt ((MAXCLIENTS + 31) / 32)
28840 :#define BITMASK(i) (1U << ((i) & 31))
28841 :#define MASKIDX(i) ((i) >> 5)
28842 :#define MASKWORD(buf, i) buf[MASKIDX(i)]
28843 :#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
28844 :#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
28845 :#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
28847 :extern xConnSetupPrefix connSetupPrefix;
28848 :extern char *ConnectionInfo;
28850 :_X_EXPORT Selection *CurrentSelections;
28851 :_X_EXPORT int NumCurrentSelections;
28852 :CallbackListPtr SelectionCallback = NULL;
28854 :static ClientPtr grabClient;
28855 :#define GrabNone 0
28856 :#define GrabActive 1
28857 :#define GrabKickout 2
28858 :static int grabState = GrabNone;
28859 :static long grabWaiters[mskcnt];
28860 :_X_EXPORT CallbackListPtr ServerGrabCallback = NULL;
28861 :HWEventQueuePtr checkForInput[2];
28862 :extern int connBlockScreenStart;
28864 :static void KillAllClients(void);
28866 :static void DeleteClientFromAnySelections(ClientPtr client);
28868 :static int nextFreeClientID; /* always MIN free client ID */
28870 :static int nClients; /* number of authorized clients */
28872 :_X_EXPORT CallbackListPtr ClientStateCallback;
28874 :/* dispatchException & isItTimeToYield must be declared volatile since they
28875 : * are modified by signal handlers - otherwise optimizer may assume it doesn't
28876 : * need to actually check value in memory when used and may miss changes from
28877 : * signal handlers.
28879 :_X_EXPORT volatile char dispatchException = 0;
28880 :_X_EXPORT volatile char isItTimeToYield;
28882 :/* Various of the DIX function interfaces were not designed to allow
28883 : * the client->errorValue to be set on BadValue and other errors.
28884 : * Rather than changing interfaces and breaking untold code we introduce
28885 : * a new global that dispatch can use.
28887 :XID clientErrorValue; /* XXX this is a kludge */
28889 :#define SAME_SCREENS(a, b) (\
28890 : (a.pScreen == b.pScreen))
28893 :SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
28895 : checkForInput[0] = c0;
28896 : checkForInput[1] = c1;
28900 :UpdateCurrentTime(void)
28902 : TimeStamp systime;
28904 : /* To avoid time running backwards, we must call GetTimeInMillis before
28905 : * calling ProcessInputEvents.
28907 : systime.months = currentTime.months;
28908 : systime.milliseconds = GetTimeInMillis();
28909 : if (systime.milliseconds < currentTime.milliseconds)
28910 : systime.months++;
28911 : if (*checkForInput[0] != *checkForInput[1])
28912 : ProcessInputEvents();
28913 : if (CompareTimeStamps(systime, currentTime) == LATER)
28914 : currentTime = systime;
28917 :/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
28919 :UpdateCurrentTimeIf(void)
28921 : TimeStamp systime;
28923 : systime.months = currentTime.months;
28924 : systime.milliseconds = GetTimeInMillis();
28925 : if (systime.milliseconds < currentTime.milliseconds)
28926 : systime.months++;
28927 : if (*checkForInput[0] == *checkForInput[1])
28928 : currentTime = systime;
28932 :InitSelections(void)
28934 : if (CurrentSelections)
28935 : xfree(CurrentSelections);
28936 : CurrentSelections = (Selection *)NULL;
28937 : NumCurrentSelections = 0;
28941 :FlushClientCaches(XID id)
28942 :{ /* FlushClientCaches total: 4 0.0044 */
28944 : ClientPtr client;
28946 : client = clients[CLIENT_ID(id)];
28947 1 0.0011 : if (client == NullClient)
28949 1 0.0011 : for (i=0; i<currentMaxClients; i++)
28951 : client = clients[i];
28952 : if (client != NullClient)
28954 : if (client->lastDrawableID == id)
28956 : client->lastDrawableID = WindowTable[0]->drawable.id;
28957 : client->lastDrawable = (DrawablePtr)WindowTable[0];
28959 : else if (client->lastGCID == id)
28961 : client->lastGCID = INVALID;
28962 : client->lastGC = (GCPtr)NULL;
28967 :#ifdef SMART_SCHEDULE
28969 :#undef SMART_DEBUG
28971 :#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
28972 :#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
28974 :Bool SmartScheduleDisable = FALSE;
28975 :long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
28976 :long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
28977 :long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
28978 :long SmartScheduleTime;
28979 :static ClientPtr SmartLastClient;
28980 :static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
28982 :#ifdef SMART_DEBUG
28983 :long SmartLastPrint;
28986 :void Dispatch(void);
28987 :void InitProcVectors(void);
28990 :SmartScheduleClient (int *clientReady, int nready)
28992 : ClientPtr pClient;
28995 : int bestPrio, best = 0;
28996 : int bestRobin, robin;
28997 : long now = SmartScheduleTime;
29000 : bestPrio = -0x7fffffff;
29002 : idle = 2 * SmartScheduleSlice;
29003 : for (i = 0; i < nready; i++)
29005 : client = clientReady[i];
29006 : pClient = clients[client];
29007 : /* Praise clients which are idle */
29008 : if ((now - pClient->smart_check_tick) >= idle)
29010 : if (pClient->smart_priority < 0)
29011 : pClient->smart_priority++;
29013 : pClient->smart_check_tick = now;
29015 : /* check priority to select best client */
29016 : robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
29017 : if (pClient->smart_priority > bestPrio ||
29018 : (pClient->smart_priority == bestPrio && robin > bestRobin))
29020 : bestPrio = pClient->smart_priority;
29021 : bestRobin = robin;
29024 :#ifdef SMART_DEBUG
29025 : if ((now - SmartLastPrint) >= 5000)
29026 : fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
29029 :#ifdef SMART_DEBUG
29030 : if ((now - SmartLastPrint) >= 5000)
29032 : fprintf (stderr, " use %2d\n", best);
29033 : SmartLastPrint = now;
29036 : pClient = clients[best];
29037 : SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
29039 : * Set current client pointer
29041 : if (SmartLastClient != pClient)
29043 : pClient->smart_start_tick = now;
29044 : SmartLastClient = pClient;
29052 : * If it's been a long time since another client
29053 : * has run, bump the slice up to get maximal
29054 : * performance from a single client
29056 : if ((now - pClient->smart_start_tick) > 1000 &&
29057 : SmartScheduleSlice < SmartScheduleMaxSlice)
29059 : SmartScheduleSlice += SmartScheduleInterval;
29064 : SmartScheduleSlice = SmartScheduleInterval;
29070 :#define MAJOROP ((xReq *)client->requestBuffer)->reqType
29074 :{ /* Dispatch total: 37 0.0403 */
29075 : int *clientReady; /* array of request ready clients */
29077 : ClientPtr client;
29079 : HWEventQueuePtr* icheck = checkForInput;
29080 :#ifdef SMART_SCHEDULE
29084 : nextFreeClientID = 1;
29085 : InitSelections();
29088 : clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
29089 : if (!clientReady)
29092 :#ifdef XSERVER_DTRACE
29093 : LoadRequestNames();
29096 : while (!dispatchException)
29098 : if (*icheck[0] != *icheck[1])
29100 : ProcessInputEvents();
29101 : FlushIfCriticalOutputPending();
29104 : nready = WaitForSomething(clientReady);
29106 :#ifdef SMART_SCHEDULE
29107 : if (nready && !SmartScheduleDisable)
29109 : clientReady[0] = SmartScheduleClient (clientReady, nready);
29113 : /*****************
29114 : * Handle events in round robin fashion, doing input between
29116 : *****************/
29118 : while (!dispatchException && (--nready >= 0))
29120 : client = clients[clientReady[nready]];
29123 : /* KillClient can cause this to happen */
29126 : /* GrabServer activation can cause this to be true */
29127 : if (grabState == GrabKickout)
29129 : grabState = GrabActive;
29132 : isItTimeToYield = FALSE;
29134 : requestingClient = client;
29135 :#ifdef SMART_SCHEDULE
29136 : start_tick = SmartScheduleTime;
29138 1 0.0011 : while (!isItTimeToYield)
29140 8 0.0087 : if (*icheck[0] != *icheck[1])
29142 : ProcessInputEvents();
29143 : FlushIfCriticalOutputPending();
29145 :#ifdef SMART_SCHEDULE
29146 6 0.0065 : if (!SmartScheduleDisable &&
29147 : (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
29149 : /* Penalize clients which consume ticks */
29150 : if (client->smart_priority > SMART_MIN_PRIORITY)
29151 : client->smart_priority--;
29155 : /* now, finally, deal with client requests */
29157 2 0.0022 : result = ReadRequestFromClient(client);
29158 2 0.0022 : if (result <= 0)
29161 : CloseDownClient(client);
29165 2 0.0022 : client->sequence++;
29167 : if (client->requestLogIndex == MAX_REQUEST_LOG)
29168 : client->requestLogIndex = 0;
29169 : client->requestLog[client->requestLogIndex] = MAJOROP;
29170 : client->requestLogIndex++;
29172 :#ifdef XSERVER_DTRACE
29173 : XSERVER_REQUEST_START(GetRequestName(MAJOROP), MAJOROP,
29174 : ((xReq *)client->requestBuffer)->length,
29175 : client->index, client->requestBuffer);
29177 4 0.0044 : if (result > (maxBigRequestSize << 2))
29178 : result = BadLength;
29180 : XaceHook(XACE_AUDIT_BEGIN, client);
29181 3 0.0033 : result = (* client->requestVector[MAJOROP])(client);
29182 8 0.0087 : XaceHook(XACE_AUDIT_END, client, result);
29184 :#ifdef XSERVER_DTRACE
29185 : XSERVER_REQUEST_DONE(GetRequestName(MAJOROP), MAJOROP,
29186 : client->sequence, client->index, result);
29189 1 0.0011 : if (result != Success)
29191 : if (client->noClientException != Success)
29192 : CloseDownClient(client);
29194 : SendErrorToClient(client, MAJOROP,
29195 : MinorOpcodeOfRequest(client),
29196 : client->errorValue, result);
29200 : FlushIfCriticalOutputPending ();
29203 : FlushAllOutput();
29204 :#ifdef SMART_SCHEDULE
29205 : client = clients[clientReady[nready]];
29207 : client->smart_stop_tick = SmartScheduleTime;
29209 : requestingClient = NULL;
29211 : dispatchException &= ~DE_PRIORITYCHANGE;
29213 :#if defined(DDXBEFORERESET)
29214 : ddxBeforeReset ();
29216 : KillAllClients();
29217 : DEALLOCATE_LOCAL(clientReady);
29218 : dispatchException &= ~DE_RESET;
29219 :#ifdef XSERVER_DTRACE
29220 : FreeRequestNames();
29227 :ProcBadRequest(ClientPtr client)
29229 : return (BadRequest);
29233 :ProcCreateWindow(ClientPtr client)
29235 : WindowPtr pParent, pWin;
29236 : REQUEST(xCreateWindowReq);
29237 : int result, len, rc;
29239 : REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
29241 : LEGAL_NEW_RESOURCE(stuff->wid, client);
29242 : rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess);
29243 : if (rc != Success)
29245 : len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
29246 : if (Ones(stuff->mask) != len)
29247 : return BadLength;
29248 : if (!stuff->width || !stuff->height)
29250 : client->errorValue = 0;
29253 : pWin = CreateWindow(stuff->wid, pParent, stuff->x,
29254 : stuff->y, stuff->width, stuff->height,
29255 : stuff->borderWidth, stuff->class,
29256 : stuff->mask, (XID *) &stuff[1],
29257 : (int)stuff->depth,
29258 : client, stuff->visual, &result);
29261 : Mask mask = pWin->eventMask;
29263 : pWin->eventMask = 0; /* subterfuge in case AddResource fails */
29264 : if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
29266 : pWin->eventMask = mask;
29268 : if (client->noClientException != Success)
29269 : return(client->noClientException);
29275 :ProcChangeWindowAttributes(ClientPtr client)
29278 : REQUEST(xChangeWindowAttributesReq);
29282 : REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
29283 : rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
29284 : if (rc != Success)
29286 : len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
29287 : if (len != Ones(stuff->valueMask))
29288 : return BadLength;
29289 : result = ChangeWindowAttributes(pWin,
29290 : stuff->valueMask,
29291 : (XID *) &stuff[1],
29293 : if (client->noClientException != Success)
29294 : return(client->noClientException);
29300 :ProcGetWindowAttributes(ClientPtr client)
29303 : REQUEST(xResourceReq);
29304 : xGetWindowAttributesReply wa;
29307 : REQUEST_SIZE_MATCH(xResourceReq);
29308 : rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
29309 : if (rc != Success)
29311 : GetWindowAttributes(pWin, client, &wa);
29312 : WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
29313 : return(client->noClientException);
29317 :ProcDestroyWindow(ClientPtr client)
29320 : REQUEST(xResourceReq);
29323 : REQUEST_SIZE_MATCH(xResourceReq);
29324 : rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
29325 : if (rc != Success)
29327 : if (pWin->parent)
29328 : FreeResource(stuff->id, RT_NONE);
29329 : return(client->noClientException);
29333 :ProcDestroySubwindows(ClientPtr client)
29336 : REQUEST(xResourceReq);
29339 : REQUEST_SIZE_MATCH(xResourceReq);
29340 : rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
29341 : if (rc != Success)
29343 : DestroySubwindows(pWin, client);
29344 : return(client->noClientException);
29348 :ProcChangeSaveSet(ClientPtr client)
29351 : REQUEST(xChangeSaveSetReq);
29354 : REQUEST_SIZE_MATCH(xChangeSaveSetReq);
29355 : rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
29356 : if (rc != Success)
29358 : if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
29360 : if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
29362 : result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
29363 : if (client->noClientException != Success)
29364 : return(client->noClientException);
29370 : client->errorValue = stuff->mode;
29371 : return( BadValue );
29376 :ProcReparentWindow(ClientPtr client)
29378 : WindowPtr pWin, pParent;
29379 : REQUEST(xReparentWindowReq);
29382 : REQUEST_SIZE_MATCH(xReparentWindowReq);
29383 : rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
29384 : if (rc != Success)
29386 : rc = dixLookupWindow(&pParent, stuff->parent, client, DixWriteAccess);
29387 : if (rc != Success)
29389 : if (SAME_SCREENS(pWin->drawable, pParent->drawable))
29391 : if ((pWin->backgroundState == ParentRelative) &&
29392 : (pParent->drawable.depth != pWin->drawable.depth))
29394 : if ((pWin->drawable.class != InputOnly) &&
29395 : (pParent->drawable.class == InputOnly))
29397 : result = ReparentWindow(pWin, pParent,
29398 : (short)stuff->x, (short)stuff->y, client);
29399 : if (client->noClientException != Success)
29400 : return(client->noClientException);
29405 : return (BadMatch);
29409 :ProcMapWindow(ClientPtr client)
29412 : REQUEST(xResourceReq);
29415 : REQUEST_SIZE_MATCH(xResourceReq);
29416 : rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
29417 : if (rc != Success)
29419 : MapWindow(pWin, client);
29420 : /* update cache to say it is mapped */
29421 : return(client->noClientException);
29425 :ProcMapSubwindows(ClientPtr client)
29428 : REQUEST(xResourceReq);
29431 : REQUEST_SIZE_MATCH(xResourceReq);
29432 : rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
29433 : if (rc != Success)
29435 : MapSubwindows(pWin, client);
29436 : /* update cache to say it is mapped */
29437 : return(client->noClientException);
29441 :ProcUnmapWindow(ClientPtr client)
29444 : REQUEST(xResourceReq);
29447 : REQUEST_SIZE_MATCH(xResourceReq);
29448 : rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
29449 : if (rc != Success)
29451 : UnmapWindow(pWin, FALSE);
29452 : /* update cache to say it is mapped */
29453 : return(client->noClientException);
29457 :ProcUnmapSubwindows(ClientPtr client)
29460 : REQUEST(xResourceReq);
29463 : REQUEST_SIZE_MATCH(xResourceReq);
29464 : rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
29465 : if (rc != Success)
29467 : UnmapSubwindows(pWin);
29468 : return(client->noClientException);
29472 :ProcConfigureWindow(ClientPtr client)
29475 : REQUEST(xConfigureWindowReq);
29479 : REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
29480 : rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
29481 : if (rc != Success)
29483 : len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
29484 : if (Ones((Mask)stuff->mask) != len)
29485 : return BadLength;
29486 : result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
29488 : if (client->noClientException != Success)
29489 : return(client->noClientException);
29495 :ProcCirculateWindow(ClientPtr client)
29498 : REQUEST(xCirculateWindowReq);
29501 : REQUEST_SIZE_MATCH(xCirculateWindowReq);
29502 : if ((stuff->direction != RaiseLowest) &&
29503 : (stuff->direction != LowerHighest))
29505 : client->errorValue = stuff->direction;
29508 : rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
29509 : if (rc != Success)
29511 : CirculateWindow(pWin, (int)stuff->direction, client);
29512 : return(client->noClientException);
29516 :GetGeometry(ClientPtr client, xGetGeometryReply *rep)
29518 : DrawablePtr pDraw;
29520 : REQUEST(xResourceReq);
29521 : REQUEST_SIZE_MATCH(xResourceReq);
29523 : rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixReadAccess);
29524 : if (rc != Success)
29527 : rep->type = X_Reply;
29529 : rep->sequenceNumber = client->sequence;
29530 : rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
29531 : rep->depth = pDraw->depth;
29532 : rep->width = pDraw->width;
29533 : rep->height = pDraw->height;
29535 : /* XXX - Because the pixmap-implementation of the multibuffer extension
29536 : * may have the buffer-id's drawable resource value be a pointer
29537 : * to the buffer's window instead of the buffer itself
29538 : * (this happens if the buffer is the displayed buffer),
29539 : * we also have to check that the id matches before we can
29540 : * truly say that it is a DRAWABLE_WINDOW.
29543 : if ((pDraw->type == UNDRAWABLE_WINDOW) ||
29544 : ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
29546 : WindowPtr pWin = (WindowPtr)pDraw;
29547 : rep->x = pWin->origin.x - wBorderWidth (pWin);
29548 : rep->y = pWin->origin.y - wBorderWidth (pWin);
29549 : rep->borderWidth = pWin->borderWidth;
29551 : else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
29553 : rep->x = rep->y = rep->borderWidth = 0;
29561 :ProcGetGeometry(ClientPtr client)
29563 : xGetGeometryReply rep;
29566 : if ((status = GetGeometry(client, &rep)) != Success)
29569 : WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
29570 : return(client->noClientException);
29575 :ProcQueryTree(ClientPtr client)
29577 : xQueryTreeReply reply;
29578 : int rc, numChildren = 0;
29579 : WindowPtr pChild, pWin, pHead;
29580 : Window *childIDs = (Window *)NULL;
29581 : REQUEST(xResourceReq);
29583 : REQUEST_SIZE_MATCH(xResourceReq);
29584 : rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
29585 : if (rc != Success)
29587 : reply.type = X_Reply;
29588 : reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
29589 : reply.sequenceNumber = client->sequence;
29590 : if (pWin->parent)
29591 : reply.parent = pWin->parent->drawable.id;
29593 : reply.parent = (Window)None;
29594 : pHead = RealChildHead(pWin);
29595 : for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
29599 : int curChild = 0;
29601 : childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
29604 : for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
29605 : childIDs[curChild++] = pChild->drawable.id;
29608 : reply.nChildren = numChildren;
29609 : reply.length = (numChildren * sizeof(Window)) >> 2;
29611 : WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
29614 : client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
29615 : WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
29616 : DEALLOCATE_LOCAL(childIDs);
29619 : return(client->noClientException);
29623 :ProcInternAtom(ClientPtr client)
29627 : REQUEST(xInternAtomReq);
29629 : REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
29630 : if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
29632 : client->errorValue = stuff->onlyIfExists;
29633 : return(BadValue);
29635 : tchar = (char *) &stuff[1];
29636 : atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
29637 : if (atom != BAD_RESOURCE)
29639 : xInternAtomReply reply;
29640 : reply.type = X_Reply;
29641 : reply.length = 0;
29642 : reply.sequenceNumber = client->sequence;
29643 : reply.atom = atom;
29644 : WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
29645 : return(client->noClientException);
29648 : return (BadAlloc);
29652 :ProcGetAtomName(ClientPtr client)
29655 : xGetAtomNameReply reply;
29657 : REQUEST(xResourceReq);
29659 : REQUEST_SIZE_MATCH(xResourceReq);
29660 : if ( (str = NameForAtom(stuff->id)) )
29662 : len = strlen(str);
29663 : reply.type = X_Reply;
29664 : reply.length = (len + 3) >> 2;
29665 : reply.sequenceNumber = client->sequence;
29666 : reply.nameLength = len;
29667 : WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
29668 : (void)WriteToClient(client, len, str);
29669 : return(client->noClientException);
29673 : client->errorValue = stuff->id;
29674 : return (BadAtom);
29679 :ProcSetSelectionOwner(ClientPtr client)
29683 : REQUEST(xSetSelectionOwnerReq);
29685 : REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
29686 : UpdateCurrentTime();
29687 : time = ClientTimeToServerTime(stuff->time);
29689 : /* If the client's time stamp is in the future relative to the server's
29690 : time stamp, do not set the selection, just return success. */
29691 : if (CompareTimeStamps(time, currentTime) == LATER)
29693 : if (stuff->window != None)
29695 : int rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
29696 : if (rc != Success)
29700 : pWin = (WindowPtr)None;
29701 : if (ValidAtom(stuff->selection))
29706 : * First, see if the selection is already set...
29708 : while ((i < NumCurrentSelections) &&
29709 : CurrentSelections[i].selection != stuff->selection)
29711 : if (i < NumCurrentSelections)
29715 : /* If the timestamp in client's request is in the past relative
29716 : to the time stamp indicating the last time the owner of the
29717 : selection was set, do not set the selection, just return
29719 : if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
29722 : if (CurrentSelections[i].client &&
29723 : (!pWin || (CurrentSelections[i].client != client)))
29725 : event.u.u.type = SelectionClear;
29726 : event.u.selectionClear.time = time.milliseconds;
29727 : event.u.selectionClear.window = CurrentSelections[i].window;
29728 : event.u.selectionClear.atom = CurrentSelections[i].selection;
29729 : (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
29730 : NoEventMask, NoEventMask /* CantBeFiltered */,
29737 : * It doesn't exist, so add it...
29739 : Selection *newsels;
29742 : newsels = (Selection *)xalloc(sizeof(Selection));
29744 : newsels = (Selection *)xrealloc(CurrentSelections,
29745 : (NumCurrentSelections + 1) * sizeof(Selection));
29748 : NumCurrentSelections++;
29749 : CurrentSelections = newsels;
29750 : CurrentSelections[i].selection = stuff->selection;
29752 : CurrentSelections[i].lastTimeChanged = time;
29753 : CurrentSelections[i].window = stuff->window;
29754 : CurrentSelections[i].pWin = pWin;
29755 : CurrentSelections[i].client = (pWin ? client : NullClient);
29756 : if (SelectionCallback)
29758 : SelectionInfoRec info;
29760 : info.selection = &CurrentSelections[i];
29761 : info.kind= SelectionSetOwner;
29762 : CallCallbacks(&SelectionCallback, &info);
29764 : return (client->noClientException);
29768 : client->errorValue = stuff->selection;
29769 : return (BadAtom);
29774 :ProcGetSelectionOwner(ClientPtr client)
29776 : REQUEST(xResourceReq);
29778 : REQUEST_SIZE_MATCH(xResourceReq);
29779 : if (ValidAtom(stuff->id))
29782 : xGetSelectionOwnerReply reply;
29785 : while ((i < NumCurrentSelections) &&
29786 : CurrentSelections[i].selection != stuff->id) i++;
29787 : reply.type = X_Reply;
29788 : reply.length = 0;
29789 : reply.sequenceNumber = client->sequence;
29790 : if (i < NumCurrentSelections)
29791 : reply.owner = CurrentSelections[i].window;
29793 : reply.owner = None;
29794 : WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
29795 : return(client->noClientException);
29799 : client->errorValue = stuff->id;
29800 : return (BadAtom);
29805 :ProcConvertSelection(ClientPtr client)
29810 : REQUEST(xConvertSelectionReq);
29813 : REQUEST_SIZE_MATCH(xConvertSelectionReq);
29814 : rc = dixLookupWindow(&pWin, stuff->requestor, client, DixReadAccess);
29815 : if (rc != Success)
29818 : paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
29819 : if (stuff->property != None)
29820 : paramsOkay &= ValidAtom(stuff->property);
29826 : while ((i < NumCurrentSelections) &&
29827 : CurrentSelections[i].selection != stuff->selection) i++;
29828 : if ((i < NumCurrentSelections) &&
29829 : (CurrentSelections[i].window != None) &&
29830 : XaceHook(XACE_RESOURCE_ACCESS, client,
29831 : CurrentSelections[i].window, RT_WINDOW,
29832 : DixReadAccess, CurrentSelections[i].pWin))
29834 : event.u.u.type = SelectionRequest;
29835 : event.u.selectionRequest.time = stuff->time;
29836 : event.u.selectionRequest.owner =
29837 : CurrentSelections[i].window;
29838 : event.u.selectionRequest.requestor = stuff->requestor;
29839 : event.u.selectionRequest.selection = stuff->selection;
29840 : event.u.selectionRequest.target = stuff->target;
29841 : event.u.selectionRequest.property = stuff->property;
29842 : if (TryClientEvents(
29843 : CurrentSelections[i].client, &event, 1, NoEventMask,
29844 : NoEventMask /* CantBeFiltered */, NullGrab))
29845 : return (client->noClientException);
29847 : event.u.u.type = SelectionNotify;
29848 : event.u.selectionNotify.time = stuff->time;
29849 : event.u.selectionNotify.requestor = stuff->requestor;
29850 : event.u.selectionNotify.selection = stuff->selection;
29851 : event.u.selectionNotify.target = stuff->target;
29852 : event.u.selectionNotify.property = None;
29853 : (void) TryClientEvents(client, &event, 1, NoEventMask,
29854 : NoEventMask /* CantBeFiltered */, NullGrab);
29855 : return (client->noClientException);
29859 : client->errorValue = stuff->property;
29860 : return (BadAtom);
29865 :ProcGrabServer(ClientPtr client)
29867 : REQUEST_SIZE_MATCH(xReq);
29868 : if (grabState != GrabNone && client != grabClient)
29870 : ResetCurrentRequest(client);
29871 : client->sequence--;
29872 : BITSET(grabWaiters, client->index);
29873 : IgnoreClient(client);
29874 : return(client->noClientException);
29876 : OnlyListenToOneClient(client);
29877 : grabState = GrabKickout;
29878 : grabClient = client;
29880 : if (ServerGrabCallback)
29882 : ServerGrabInfoRec grabinfo;
29883 : grabinfo.client = client;
29884 : grabinfo.grabstate = SERVER_GRABBED;
29885 : CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
29888 : return(client->noClientException);
29892 :UngrabServer(ClientPtr client)
29896 : grabState = GrabNone;
29897 : ListenToAllClients();
29898 : for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
29903 : while (!GETBIT(grabWaiters, i))
29905 : BITCLEAR(grabWaiters, i);
29906 : AttendClient(clients[i]);
29909 : if (ServerGrabCallback)
29911 : ServerGrabInfoRec grabinfo;
29912 : grabinfo.client = client;
29913 : grabinfo.grabstate = SERVER_UNGRABBED;
29914 : CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
29919 :ProcUngrabServer(ClientPtr client)
29921 : REQUEST_SIZE_MATCH(xReq);
29922 : UngrabServer(client);
29923 : return(client->noClientException);
29927 :ProcTranslateCoords(ClientPtr client)
29929 : REQUEST(xTranslateCoordsReq);
29931 : WindowPtr pWin, pDst;
29932 : xTranslateCoordsReply rep;
29935 : REQUEST_SIZE_MATCH(xTranslateCoordsReq);
29936 : rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixReadAccess);
29937 : if (rc != Success)
29939 : rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixReadAccess);
29940 : if (rc != Success)
29942 : rep.type = X_Reply;
29944 : rep.sequenceNumber = client->sequence;
29945 : if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
29947 : rep.sameScreen = xFalse;
29948 : rep.child = None;
29949 : rep.dstX = rep.dstY = 0;
29954 : rep.sameScreen = xTrue;
29955 : rep.child = None;
29956 : /* computing absolute coordinates -- adjust to destination later */
29957 : x = pWin->drawable.x + stuff->srcX;
29958 : y = pWin->drawable.y + stuff->srcY;
29959 : pWin = pDst->firstChild;
29965 : if ((pWin->mapped) &&
29966 : (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
29967 : (x < pWin->drawable.x + (int)pWin->drawable.width +
29968 : wBorderWidth (pWin)) &&
29969 : (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
29970 : (y < pWin->drawable.y + (int)pWin->drawable.height +
29971 : wBorderWidth (pWin))
29973 : /* When a window is shaped, a further check
29974 : * is made to see if the point is inside
29977 : && (!wBoundingShape(pWin) ||
29978 : POINT_IN_REGION(pWin->drawable.pScreen,
29979 : &pWin->borderSize, x, y, &box))
29981 : && (!wInputShape(pWin) ||
29982 : POINT_IN_REGION(pWin->drawable.pScreen,
29983 : wInputShape(pWin),
29984 : x - pWin->drawable.x,
29985 : y - pWin->drawable.y, &box))
29989 : rep.child = pWin->drawable.id;
29990 : pWin = (WindowPtr) NULL;
29993 : pWin = pWin->nextSib;
29995 : /* adjust to destination coordinates */
29996 : rep.dstX = x - pDst->drawable.x;
29997 : rep.dstY = y - pDst->drawable.y;
29999 : WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
30000 : return(client->noClientException);
30004 :ProcOpenFont(ClientPtr client)
30007 : REQUEST(xOpenFontReq);
30009 : REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
30010 : client->errorValue = stuff->fid;
30011 : LEGAL_NEW_RESOURCE(stuff->fid, client);
30012 : err = OpenFont(client, stuff->fid, (Mask) 0,
30013 : stuff->nbytes, (char *)&stuff[1]);
30014 : if (err == Success)
30016 : return(client->noClientException);
30023 :ProcCloseFont(ClientPtr client)
30026 : REQUEST(xResourceReq);
30028 : REQUEST_SIZE_MATCH(xResourceReq);
30029 : pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
30030 : DixDestroyAccess);
30031 : if ( pFont != (FontPtr)NULL) /* id was valid */
30033 : FreeResource(stuff->id, RT_NONE);
30034 : return(client->noClientException);
30038 : client->errorValue = stuff->id;
30039 : return (BadFont);
30044 :ProcQueryFont(ClientPtr client)
30046 : xQueryFontReply *reply;
30049 : REQUEST(xResourceReq);
30051 : REQUEST_SIZE_MATCH(xResourceReq);
30052 : client->errorValue = stuff->id; /* EITHER font or gc */
30053 : pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
30057 : pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
30061 : client->errorValue = stuff->id;
30062 : return(BadFont); /* procotol spec says only error is BadFont */
30064 : pFont = pGC->font;
30068 : xCharInfo *pmax = FONTINKMAX(pFont);
30069 : xCharInfo *pmin = FONTINKMIN(pFont);
30070 : int nprotoxcistructs;
30073 : nprotoxcistructs = (
30074 : pmax->rightSideBearing == pmin->rightSideBearing &&
30075 : pmax->leftSideBearing == pmin->leftSideBearing &&
30076 : pmax->descent == pmin->descent &&
30077 : pmax->ascent == pmin->ascent &&
30078 : pmax->characterWidth == pmin->characterWidth) ?
30079 : 0 : N2dChars(pFont);
30081 : rlength = sizeof(xQueryFontReply) +
30082 : FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
30083 : nprotoxcistructs * sizeof(xCharInfo);
30084 : reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
30087 : return(BadAlloc);
30090 : reply->type = X_Reply;
30091 : reply->length = (rlength - sizeof(xGenericReply)) >> 2;
30092 : reply->sequenceNumber = client->sequence;
30093 : QueryFont( pFont, reply, nprotoxcistructs);
30095 : WriteReplyToClient(client, rlength, reply);
30096 : DEALLOCATE_LOCAL(reply);
30097 : return(client->noClientException);
30102 :ProcQueryTextExtents(ClientPtr client)
30104 : REQUEST(xQueryTextExtentsReq);
30105 : xQueryTextExtentsReply reply;
30108 : ExtentInfoRec info;
30109 : unsigned long length;
30111 : REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
30113 : pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
30117 : pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
30121 : client->errorValue = stuff->fid;
30124 : pFont = pGC->font;
30126 : length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
30127 : length = length << 1;
30128 : if (stuff->oddLength)
30131 : return(BadLength);
30134 : if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
30135 : return(BadAlloc);
30136 : reply.type = X_Reply;
30137 : reply.length = 0;
30138 : reply.sequenceNumber = client->sequence;
30139 : reply.drawDirection = info.drawDirection;
30140 : reply.fontAscent = info.fontAscent;
30141 : reply.fontDescent = info.fontDescent;
30142 : reply.overallAscent = info.overallAscent;
30143 : reply.overallDescent = info.overallDescent;
30144 : reply.overallWidth = info.overallWidth;
30145 : reply.overallLeft = info.overallLeft;
30146 : reply.overallRight = info.overallRight;
30147 : WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
30148 : return(client->noClientException);
30152 :ProcListFonts(ClientPtr client)
30154 : REQUEST(xListFontsReq);
30156 : REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
30158 : return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
30159 : stuff->maxNames);
30163 :ProcListFontsWithInfo(ClientPtr client)
30165 : REQUEST(xListFontsWithInfoReq);
30167 : REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
30169 : return StartListFontsWithInfo(client, stuff->nbytes,
30170 : (unsigned char *) &stuff[1], stuff->maxNames);
30175 : * \param value must conform to DeleteType
30178 :dixDestroyPixmap(pointer value, XID pid)
30180 : PixmapPtr pPixmap = (PixmapPtr)value;
30181 : return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
30185 :ProcCreatePixmap(ClientPtr client)
30186 1 0.0011 :{ /* ProcCreatePixmap total: 9 0.0098 */
30188 : DrawablePtr pDraw;
30189 : REQUEST(xCreatePixmapReq);
30193 : REQUEST_SIZE_MATCH(xCreatePixmapReq);
30194 : client->errorValue = stuff->pid;
30195 1 0.0011 : LEGAL_NEW_RESOURCE(stuff->pid, client);
30197 1 0.0011 : rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
30199 : if (rc != Success)
30202 : if (!stuff->width || !stuff->height)
30204 : client->errorValue = 0;
30207 1 0.0011 : if (stuff->width > 32767 || stuff->height > 32767)
30209 : /* It is allowed to try and allocate a pixmap which is larger than
30210 : * 32767 in either dimension. However, all of the framebuffer code
30211 : * is buggy and does not reliably draw to such big pixmaps, basically
30212 : * because the Region data structure operates with signed shorts
30213 : * for the rectangles in it.
30215 : * Furthermore, several places in the X server computes the
30216 : * size in bytes of the pixmap and tries to store it in an
30217 : * integer. This integer can overflow and cause the allocated size
30218 : * to be much smaller.
30220 : * So, such big pixmaps are rejected here with a BadAlloc
30224 : if (stuff->depth != 1)
30226 1 0.0011 : pDepth = pDraw->pScreen->allowedDepths;
30227 1 0.0011 : for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
30228 2 0.0022 : if (pDepth->depth == stuff->depth)
30230 : client->errorValue = stuff->depth;
30234 1 0.0011 : pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
30235 : (pDraw->pScreen, stuff->width,
30236 : stuff->height, stuff->depth);
30239 : pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
30240 : pMap->drawable.id = stuff->pid;
30241 : if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
30242 : return(client->noClientException);
30244 : return (BadAlloc);
30248 :ProcFreePixmap(ClientPtr client)
30249 1 0.0011 :{ /* ProcFreePixmap total: 6 0.0065 */
30252 : REQUEST(xResourceReq);
30254 4 0.0044 : REQUEST_SIZE_MATCH(xResourceReq);
30255 : pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
30256 : DixDestroyAccess);
30259 1 0.0011 : FreeResource(stuff->id, RT_NONE);
30260 : return(client->noClientException);
30264 : client->errorValue = stuff->id;
30265 : return (BadPixmap);
30270 :ProcCreateGC(ClientPtr client)
30274 : DrawablePtr pDraw;
30276 : REQUEST(xCreateGCReq);
30278 : REQUEST_AT_LEAST_SIZE(xCreateGCReq);
30279 : client->errorValue = stuff->gc;
30280 : LEGAL_NEW_RESOURCE(stuff->gc, client);
30281 : rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess);
30282 : if (rc != Success)
30285 : len = client->req_len - (sizeof(xCreateGCReq) >> 2);
30286 : if (len != Ones(stuff->mask))
30287 : return BadLength;
30288 : pGC = (GC *)CreateGC(pDraw, stuff->mask,
30289 : (XID *) &stuff[1], &error);
30290 : if (error != Success)
30292 : if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
30293 : return (BadAlloc);
30294 : return(client->noClientException);
30298 :ProcChangeGC(ClientPtr client)
30299 1 0.0011 :{ /* ProcChangeGC total: 1 0.0011 */
30303 : REQUEST(xChangeGCReq);
30304 : REQUEST_AT_LEAST_SIZE(xChangeGCReq);
30306 : result = dixLookupGC(&pGC, stuff->gc, client, DixWriteAccess);
30307 : if (result != Success)
30310 : len = client->req_len - (sizeof(xChangeGCReq) >> 2);
30311 : if (len != Ones(stuff->mask))
30312 : return BadLength;
30314 : result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
30315 : if (client->noClientException != Success)
30316 : return(client->noClientException);
30319 : client->errorValue = clientErrorValue;
30325 :ProcCopyGC(ClientPtr client)
30330 : REQUEST(xCopyGCReq);
30331 : REQUEST_SIZE_MATCH(xCopyGCReq);
30333 : result = dixLookupGC(&pGC, stuff->srcGC, client, DixReadAccess);
30334 : if (result != Success)
30336 : result = dixLookupGC(&dstGC, stuff->dstGC, client, DixWriteAccess);
30337 : if (result != Success)
30339 : if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
30340 : return (BadMatch);
30341 : result = CopyGC(pGC, dstGC, stuff->mask);
30342 : if (client->noClientException != Success)
30343 : return(client->noClientException);
30346 : client->errorValue = clientErrorValue;
30352 :ProcSetDashes(ClientPtr client)
30356 : REQUEST(xSetDashesReq);
30358 : REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
30359 : if (stuff->nDashes == 0)
30361 : client->errorValue = 0;
30365 : result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess);
30366 : if (result != Success)
30369 : result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
30370 : (unsigned char *)&stuff[1]);
30371 : if (client->noClientException != Success)
30372 : return(client->noClientException);
30375 : client->errorValue = clientErrorValue;
30381 :ProcSetClipRectangles(ClientPtr client)
30382 :{ /* ProcSetClipRectangles total: 1 0.0011 */
30385 : REQUEST(xSetClipRectanglesReq);
30387 : REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
30388 : if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
30389 : (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
30391 : client->errorValue = stuff->ordering;
30394 1 0.0011 : result = dixLookupGC(&pGC,stuff->gc, client, DixWriteAccess);
30395 : if (result != Success)
30398 : nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
30400 : return(BadLength);
30402 : result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
30403 : nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
30404 : if (client->noClientException != Success)
30405 : return(client->noClientException);
30411 :ProcFreeGC(ClientPtr client)
30415 : REQUEST(xResourceReq);
30416 : REQUEST_SIZE_MATCH(xResourceReq);
30418 : rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
30419 : if (rc != Success)
30422 : FreeResource(stuff->id, RT_NONE);
30423 : return(client->noClientException);
30427 :ProcClearToBackground(ClientPtr client)
30429 : REQUEST(xClearAreaReq);
30433 : REQUEST_SIZE_MATCH(xClearAreaReq);
30434 : rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
30435 : if (rc != Success)
30437 : if (pWin->drawable.class == InputOnly)
30439 : client->errorValue = stuff->window;
30440 : return (BadMatch);
30442 : if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
30444 : client->errorValue = stuff->exposures;
30445 : return(BadValue);
30447 : (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
30448 : stuff->width, stuff->height,
30449 : (Bool)stuff->exposures);
30450 : return(client->noClientException);
30454 :ProcCopyArea(ClientPtr client)
30455 1 0.0011 :{ /* ProcCopyArea total: 1 0.0011 */
30456 : DrawablePtr pDst;
30457 : DrawablePtr pSrc;
30459 : REQUEST(xCopyAreaReq);
30463 : REQUEST_SIZE_MATCH(xCopyAreaReq);
30465 : VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
30466 : if (stuff->dstDrawable != stuff->srcDrawable)
30468 : rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
30470 : if (rc != Success)
30472 : if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
30474 : client->errorValue = stuff->dstDrawable;
30475 : return (BadMatch);
30481 : pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
30482 : stuff->width, stuff->height,
30483 : stuff->dstX, stuff->dstY);
30484 : if (pGC->graphicsExposures)
30486 : (*pDst->pScreen->SendGraphicsExpose)
30487 : (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
30489 : REGION_DESTROY(pDst->pScreen, pRgn);
30492 : return(client->noClientException);
30496 :ProcCopyPlane(ClientPtr client)
30498 : DrawablePtr psrcDraw, pdstDraw;
30500 : REQUEST(xCopyPlaneReq);
30504 : REQUEST_SIZE_MATCH(xCopyPlaneReq);
30506 : VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
30507 : if (stuff->dstDrawable != stuff->srcDrawable)
30509 : rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
30511 : if (rc != Success)
30514 : if (pdstDraw->pScreen != psrcDraw->pScreen)
30516 : client->errorValue = stuff->dstDrawable;
30517 : return (BadMatch);
30521 : psrcDraw = pdstDraw;
30523 : /* Check to see if stuff->bitPlane has exactly ONE good bit set */
30524 : if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
30525 : (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
30527 : client->errorValue = stuff->bitPlane;
30528 : return(BadValue);
30531 : pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
30532 : stuff->width, stuff->height,
30533 : stuff->dstX, stuff->dstY, stuff->bitPlane);
30534 : if (pGC->graphicsExposures)
30536 : (*pdstDraw->pScreen->SendGraphicsExpose)
30537 : (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
30539 : REGION_DESTROY(pdstDraw->pScreen, pRgn);
30541 : return(client->noClientException);
30545 :ProcPolyPoint(ClientPtr client)
30549 : DrawablePtr pDraw;
30550 : REQUEST(xPolyPointReq);
30552 : REQUEST_AT_LEAST_SIZE(xPolyPointReq);
30553 : if ((stuff->coordMode != CoordModeOrigin) &&
30554 : (stuff->coordMode != CoordModePrevious))
30556 : client->errorValue = stuff->coordMode;
30559 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30560 : npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
30562 : (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
30563 : (xPoint *) &stuff[1]);
30564 : return (client->noClientException);
30568 :ProcPolyLine(ClientPtr client)
30572 : DrawablePtr pDraw;
30573 : REQUEST(xPolyLineReq);
30575 : REQUEST_AT_LEAST_SIZE(xPolyLineReq);
30576 : if ((stuff->coordMode != CoordModeOrigin) &&
30577 : (stuff->coordMode != CoordModePrevious))
30579 : client->errorValue = stuff->coordMode;
30582 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30583 : npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
30585 : (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
30586 : (DDXPointPtr) &stuff[1]);
30587 : return(client->noClientException);
30591 :ProcPolySegment(ClientPtr client)
30595 : DrawablePtr pDraw;
30596 : REQUEST(xPolySegmentReq);
30598 : REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
30599 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30600 : nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
30602 : return(BadLength);
30605 : (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
30606 : return (client->noClientException);
30610 :ProcPolyRectangle (ClientPtr client)
30614 : DrawablePtr pDraw;
30615 : REQUEST(xPolyRectangleReq);
30617 : REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
30618 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30619 : nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
30621 : return(BadLength);
30624 : (*pGC->ops->PolyRectangle)(pDraw, pGC,
30625 : nrects, (xRectangle *) &stuff[1]);
30626 : return(client->noClientException);
30630 :ProcPolyArc(ClientPtr client)
30634 : DrawablePtr pDraw;
30635 : REQUEST(xPolyArcReq);
30637 : REQUEST_AT_LEAST_SIZE(xPolyArcReq);
30638 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30639 : narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
30640 : if (narcs % sizeof(xArc))
30641 : return(BadLength);
30642 : narcs /= sizeof(xArc);
30644 : (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
30645 : return (client->noClientException);
30649 :ProcFillPoly(ClientPtr client)
30653 : DrawablePtr pDraw;
30654 : REQUEST(xFillPolyReq);
30656 : REQUEST_AT_LEAST_SIZE(xFillPolyReq);
30657 : if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
30658 : (stuff->shape != Convex))
30660 : client->errorValue = stuff->shape;
30663 : if ((stuff->coordMode != CoordModeOrigin) &&
30664 : (stuff->coordMode != CoordModePrevious))
30666 : client->errorValue = stuff->coordMode;
30670 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30671 : things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
30673 : (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
30674 : stuff->coordMode, things,
30675 : (DDXPointPtr) &stuff[1]);
30676 : return(client->noClientException);
30680 :ProcPolyFillRectangle(ClientPtr client)
30681 :{ /* ProcPolyFillRectangle total: 1 0.0011 */
30684 : DrawablePtr pDraw;
30685 : REQUEST(xPolyFillRectangleReq);
30687 : REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
30688 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30689 : things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
30691 : return(BadLength);
30692 1 0.0011 : things >>= 3;
30695 : (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
30696 : (xRectangle *) &stuff[1]);
30697 : return (client->noClientException);
30701 :ProcPolyFillArc(ClientPtr client)
30705 : DrawablePtr pDraw;
30706 : REQUEST(xPolyFillArcReq);
30708 : REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
30709 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30710 : narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
30711 : if (narcs % sizeof(xArc))
30712 : return(BadLength);
30713 : narcs /= sizeof(xArc);
30715 : (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
30716 : return (client->noClientException);
30719 :#ifdef MATCH_CLIENT_ENDIAN
30722 :ServerOrder (void)
30724 : int whichbyte = 1;
30726 : if (*((char *) &whichbyte))
30731 :#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
30734 :ReformatImage (char *base, int nbytes, int bpp, int order)
30737 : case 1: /* yuck */
30738 : if (BITMAP_BIT_ORDER != order)
30739 : BitOrderInvert ((unsigned char *) base, nbytes);
30740 :#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
30741 : ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
30745 : break; /* yuck */
30749 : if (IMAGE_BYTE_ORDER != order)
30750 : TwoByteSwap ((unsigned char *) base, nbytes);
30753 : if (IMAGE_BYTE_ORDER != order)
30754 : FourByteSwap ((unsigned char *) base, nbytes);
30759 :#define ReformatImage(b,n,bpp,o)
30762 :/* 64-bit server notes: the protocol restricts padding of images to
30763 : * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
30764 : * to use internally. Removes need for internal alignment checking.
30765 : * All of the PutImage functions could be changed individually, but
30766 : * as currently written, they call other routines which require things
30767 : * to be 64-bit padded on scanlines, so we changed things here.
30768 : * If an image would be padded differently for 64- versus 32-, then
30769 : * copy each scanline to a 64-bit padded scanline.
30770 : * Also, we need to make sure that the image is aligned on a 64-bit
30771 : * boundary, even if the scanlines are padded to our satisfaction.
30774 :ProcPutImage(ClientPtr client)
30777 : DrawablePtr pDraw;
30778 : long length; /* length of scanline server padded */
30779 : long lengthProto; /* length of scanline protocol padded */
30781 : REQUEST(xPutImageReq);
30783 : REQUEST_AT_LEAST_SIZE(xPutImageReq);
30784 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
30785 : if (stuff->format == XYBitmap)
30787 : if ((stuff->depth != 1) ||
30788 : (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
30790 : length = BitmapBytePad(stuff->width + stuff->leftPad);
30792 : else if (stuff->format == XYPixmap)
30794 : if ((pDraw->depth != stuff->depth) ||
30795 : (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
30797 : length = BitmapBytePad(stuff->width + stuff->leftPad);
30798 : length *= stuff->depth;
30800 : else if (stuff->format == ZPixmap)
30802 : if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
30804 : length = PixmapBytePad(stuff->width, stuff->depth);
30808 : client->errorValue = stuff->format;
30812 : tmpImage = (char *)&stuff[1];
30813 : lengthProto = length;
30815 : if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
30816 : (sizeof(xPutImageReq) >> 2)) != client->req_len)
30817 : return BadLength;
30819 : ReformatImage (tmpImage, lengthProto * stuff->height,
30820 : stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
30821 : ClientOrder(client));
30823 : (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
30824 : stuff->width, stuff->height,
30825 : stuff->leftPad, stuff->format, tmpImage);
30827 : return (client->noClientException);
30831 :DoGetImage(ClientPtr client, int format, Drawable drawable,
30832 : int x, int y, int width, int height,
30833 : Mask planemask, xGetImageReply **im_return)
30835 : DrawablePtr pDraw;
30836 : int nlines, linesPerBuf, rc;
30838 : long widthBytesLine, length;
30841 : xGetImageReply xgi;
30842 : RegionPtr pVisibleRegion = NULL;
30844 : if ((format != XYPixmap) && (format != ZPixmap))
30846 : client->errorValue = format;
30847 : return(BadValue);
30849 : rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
30850 : if (rc != Success)
30853 : if(pDraw->type == DRAWABLE_WINDOW)
30855 : if( /* check for being viewable */
30856 : !((WindowPtr) pDraw)->realized ||
30857 : /* check for being on screen */
30858 : pDraw->x + x < 0 ||
30859 : pDraw->x + x + width > pDraw->pScreen->width ||
30860 : pDraw->y + y < 0 ||
30861 : pDraw->y + y + height > pDraw->pScreen->height ||
30862 : /* check for being inside of border */
30863 : x < - wBorderWidth((WindowPtr)pDraw) ||
30864 : x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
30865 : y < -wBorderWidth((WindowPtr)pDraw) ||
30866 : y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
30868 : return(BadMatch);
30869 : xgi.visual = wVisual (((WindowPtr) pDraw));
30874 : x+width > (int)pDraw->width ||
30876 : y+height > (int)pDraw->height
30878 : return(BadMatch);
30879 : xgi.visual = None;
30882 : xgi.type = X_Reply;
30883 : xgi.sequenceNumber = client->sequence;
30884 : xgi.depth = pDraw->depth;
30885 : if(format == ZPixmap)
30887 : widthBytesLine = PixmapBytePad(width, pDraw->depth);
30888 : length = widthBytesLine * height;
30893 : widthBytesLine = BitmapBytePad(width);
30894 : plane = ((Mask)1) << (pDraw->depth - 1);
30895 : /* only planes asked for */
30896 : length = widthBytesLine * height *
30897 : Ones(planemask & (plane | (plane - 1)));
30901 : xgi.length = length;
30904 : pBuf = (char *)xalloc(sz_xGetImageReply + length);
30906 : return (BadAlloc);
30907 : if (widthBytesLine == 0)
30910 : linesPerBuf = height;
30911 : *im_return = (xGetImageReply *)pBuf;
30912 : *(xGetImageReply *)pBuf = xgi;
30913 : pBuf += sz_xGetImageReply;
30915 : xgi.length = (xgi.length + 3) >> 2;
30916 : if (widthBytesLine == 0 || height == 0)
30918 : else if (widthBytesLine >= IMAGE_BUFSIZE)
30922 : linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
30923 : if (linesPerBuf > height)
30924 : linesPerBuf = height;
30926 : length = linesPerBuf * widthBytesLine;
30927 : if (linesPerBuf < height)
30929 : /* we have to make sure intermediate buffers don't need padding */
30930 : while ((linesPerBuf > 1) &&
30931 : (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
30934 : length -= widthBytesLine;
30936 : while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
30939 : length += widthBytesLine;
30942 : if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
30943 : return (BadAlloc);
30944 : WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
30947 : if (pDraw->type == DRAWABLE_WINDOW &&
30948 : !XaceHook(XACE_DRAWABLE_ACCESS, client, pDraw))
30950 : pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
30951 : if (pVisibleRegion)
30953 : REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion,
30954 : -pDraw->x, -pDraw->y);
30958 : if (linesPerBuf == 0)
30960 : /* nothing to do */
30962 : else if (format == ZPixmap)
30965 : while (height - linesDone > 0)
30967 : nlines = min(linesPerBuf, height - linesDone);
30968 : (*pDraw->pScreen->GetImage) (pDraw,
30976 : if (pVisibleRegion)
30977 : XaceCensorImage(client, pVisibleRegion, widthBytesLine,
30978 : pDraw, x, y + linesDone, width,
30979 : nlines, format, pBuf);
30981 : /* Note that this is NOT a call to WriteSwappedDataToClient,
30982 : as we do NOT byte swap */
30985 : ReformatImage (pBuf, (int)(nlines * widthBytesLine),
30986 : BitsPerPixel (pDraw->depth),
30987 : ClientOrder(client));
30989 :/* Don't split me, gcc pukes when you do */
30990 : (void)WriteToClient(client,
30991 : (int)(nlines * widthBytesLine),
30994 : linesDone += nlines;
30997 : else /* XYPixmap */
30999 : for (; plane; plane >>= 1)
31001 : if (planemask & plane)
31004 : while (height - linesDone > 0)
31006 : nlines = min(linesPerBuf, height - linesDone);
31007 : (*pDraw->pScreen->GetImage) (pDraw,
31015 : if (pVisibleRegion)
31016 : XaceCensorImage(client, pVisibleRegion,
31018 : pDraw, x, y + linesDone, width,
31019 : nlines, format, pBuf);
31021 : /* Note: NOT a call to WriteSwappedDataToClient,
31022 : as we do NOT byte swap */
31024 : pBuf += nlines * widthBytesLine;
31026 : ReformatImage (pBuf,
31027 : (int)(nlines * widthBytesLine),
31029 : ClientOrder (client));
31031 :/* Don't split me, gcc pukes when you do */
31032 : (void)WriteToClient(client,
31033 : (int)(nlines * widthBytesLine),
31036 : linesDone += nlines;
31041 : if (pVisibleRegion)
31042 : REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
31044 : DEALLOCATE_LOCAL(pBuf);
31045 : return (client->noClientException);
31049 :ProcGetImage(ClientPtr client)
31051 : REQUEST(xGetImageReq);
31053 : REQUEST_SIZE_MATCH(xGetImageReq);
31055 : return DoGetImage(client, stuff->format, stuff->drawable,
31056 : stuff->x, stuff->y,
31057 : (int)stuff->width, (int)stuff->height,
31058 : stuff->planeMask, (xGetImageReply **)NULL);
31062 :ProcPolyText(ClientPtr client)
31065 : REQUEST(xPolyTextReq);
31066 : DrawablePtr pDraw;
31069 : REQUEST_AT_LEAST_SIZE(xPolyTextReq);
31070 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
31072 : err = PolyText(client,
31075 : (unsigned char *)&stuff[1],
31076 : ((unsigned char *) stuff) + (client->req_len << 2),
31080 : stuff->drawable);
31082 : if (err == Success)
31084 : return(client->noClientException);
31091 :ProcImageText8(ClientPtr client)
31094 : DrawablePtr pDraw;
31097 : REQUEST(xImageTextReq);
31099 : REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
31100 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
31102 : err = ImageText(client,
31106 : (unsigned char *)&stuff[1],
31110 : stuff->drawable);
31112 : if (err == Success)
31114 : return(client->noClientException);
31121 :ProcImageText16(ClientPtr client)
31124 : DrawablePtr pDraw;
31127 : REQUEST(xImageTextReq);
31129 : REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
31130 : VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
31132 : err = ImageText(client,
31136 : (unsigned char *)&stuff[1],
31140 : stuff->drawable);
31142 : if (err == Success)
31144 : return(client->noClientException);
31152 :ProcCreateColormap(ClientPtr client)
31154 : VisualPtr pVisual;
31155 : ColormapPtr pmap;
31158 : ScreenPtr pScreen;
31159 : REQUEST(xCreateColormapReq);
31162 : REQUEST_SIZE_MATCH(xCreateColormapReq);
31164 : if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
31166 : client->errorValue = stuff->alloc;
31167 : return(BadValue);
31169 : mid = stuff->mid;
31170 : LEGAL_NEW_RESOURCE(mid, client);
31171 : result = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
31172 : if (result != Success)
31175 : pScreen = pWin->drawable.pScreen;
31176 : for (i = 0, pVisual = pScreen->visuals;
31177 : i < pScreen->numVisuals;
31180 : if (pVisual->vid != stuff->visual)
31182 : result = CreateColormap(mid, pScreen, pVisual, &pmap,
31183 : (int)stuff->alloc, client->index);
31184 : if (client->noClientException != Success)
31185 : return(client->noClientException);
31189 : client->errorValue = stuff->visual;
31190 : return(BadMatch);
31194 :ProcFreeColormap(ClientPtr client)
31196 : ColormapPtr pmap;
31197 : REQUEST(xResourceReq);
31199 : REQUEST_SIZE_MATCH(xResourceReq);
31200 : pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
31201 : DixDestroyAccess);
31204 : /* Freeing a default colormap is a no-op */
31205 : if (!(pmap->flags & IsDefault))
31206 : FreeResource(stuff->id, RT_NONE);
31207 : return (client->noClientException);
31211 : client->errorValue = stuff->id;
31212 : return (BadColor);
31218 :ProcCopyColormapAndFree(ClientPtr client)
31221 : ColormapPtr pSrcMap;
31222 : REQUEST(xCopyColormapAndFreeReq);
31225 : REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
31226 : mid = stuff->mid;
31227 : LEGAL_NEW_RESOURCE(mid, client);
31228 : if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap,
31229 : RT_COLORMAP, DixReadAccess|DixWriteAccess)) )
31231 : result = CopyColormapAndFree(mid, pSrcMap, client->index);
31232 : if (client->noClientException != Success)
31233 : return(client->noClientException);
31239 : client->errorValue = stuff->srcCmap;
31240 : return(BadColor);
31245 :ProcInstallColormap(ClientPtr client)
31247 : ColormapPtr pcmp;
31248 : REQUEST(xResourceReq);
31250 : REQUEST_SIZE_MATCH(xResourceReq);
31251 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
31252 : RT_COLORMAP, DixReadAccess);
31255 : (*(pcmp->pScreen->InstallColormap)) (pcmp);
31256 : return (client->noClientException);
31260 : client->errorValue = stuff->id;
31261 : return (BadColor);
31266 :ProcUninstallColormap(ClientPtr client)
31268 : ColormapPtr pcmp;
31269 : REQUEST(xResourceReq);
31271 : REQUEST_SIZE_MATCH(xResourceReq);
31272 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
31273 : RT_COLORMAP, DixReadAccess);
31276 : if(pcmp->mid != pcmp->pScreen->defColormap)
31277 : (*(pcmp->pScreen->UninstallColormap)) (pcmp);
31278 : return (client->noClientException);
31282 : client->errorValue = stuff->id;
31283 : return (BadColor);
31288 :ProcListInstalledColormaps(ClientPtr client)
31290 : xListInstalledColormapsReply *preply;
31293 : REQUEST(xResourceReq);
31295 : REQUEST_SIZE_MATCH(xResourceReq);
31296 : rc = dixLookupWindow(&pWin, stuff->id, client, DixReadAccess);
31297 : if (rc != Success)
31300 : preply = (xListInstalledColormapsReply *)
31301 : ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
31302 : pWin->drawable.pScreen->maxInstalledCmaps *
31303 : sizeof(Colormap));
31305 : return(BadAlloc);
31307 : preply->type = X_Reply;
31308 : preply->sequenceNumber = client->sequence;
31309 : nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
31310 : (pWin->drawable.pScreen, (Colormap *)&preply[1]);
31311 : preply->nColormaps = nummaps;
31312 : preply->length = nummaps;
31313 : WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
31314 : client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
31315 : WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
31316 : DEALLOCATE_LOCAL(preply);
31317 : return(client->noClientException);
31321 :ProcAllocColor (ClientPtr client)
31323 : ColormapPtr pmap;
31325 : xAllocColorReply acr;
31326 : REQUEST(xAllocColorReq);
31328 : REQUEST_SIZE_MATCH(xAllocColorReq);
31329 : pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31330 : RT_COLORMAP, DixWriteAccess);
31333 : acr.type = X_Reply;
31335 : acr.sequenceNumber = client->sequence;
31336 : acr.red = stuff->red;
31337 : acr.green = stuff->green;
31338 : acr.blue = stuff->blue;
31340 : if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
31341 : &acr.pixel, client->index)) )
31343 : if (client->noClientException != Success)
31344 : return(client->noClientException);
31349 : if (noPanoramiXExtension || !pmap->pScreen->myNum)
31351 : WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
31352 : return (client->noClientException);
31357 : client->errorValue = stuff->cmap;
31358 : return (BadColor);
31363 :ProcAllocNamedColor (ClientPtr client)
31365 : ColormapPtr pcmp;
31366 : REQUEST(xAllocNamedColorReq);
31368 : REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
31369 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31370 : RT_COLORMAP, DixWriteAccess);
31375 : xAllocNamedColorReply ancr;
31377 : ancr.type = X_Reply;
31379 : ancr.sequenceNumber = client->sequence;
31381 : if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
31382 : &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
31384 : ancr.screenRed = ancr.exactRed;
31385 : ancr.screenGreen = ancr.exactGreen;
31386 : ancr.screenBlue = ancr.exactBlue;
31388 : if( (retval = AllocColor(pcmp,
31389 : &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
31390 : &ancr.pixel, client->index)) )
31392 : if (client->noClientException != Success)
31393 : return(client->noClientException);
31398 : if (noPanoramiXExtension || !pcmp->pScreen->myNum)
31400 : WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
31401 : return (client->noClientException);
31409 : client->errorValue = stuff->cmap;
31410 : return (BadColor);
31415 :ProcAllocColorCells (ClientPtr client)
31417 : ColormapPtr pcmp;
31418 : REQUEST(xAllocColorCellsReq);
31420 : REQUEST_SIZE_MATCH(xAllocColorCellsReq);
31421 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31422 : RT_COLORMAP, DixWriteAccess);
31425 : xAllocColorCellsReply accr;
31426 : int npixels, nmasks, retval;
31428 : Pixel *ppixels, *pmasks;
31430 : npixels = stuff->colors;
31433 : client->errorValue = npixels;
31434 : return (BadValue);
31436 : if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
31438 : client->errorValue = stuff->contiguous;
31439 : return (BadValue);
31441 : nmasks = stuff->planes;
31442 : length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
31443 : ppixels = (Pixel *)ALLOCATE_LOCAL(length);
31445 : return(BadAlloc);
31446 : pmasks = ppixels + npixels;
31448 : if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks,
31449 : (Bool)stuff->contiguous, ppixels, pmasks)) )
31451 : DEALLOCATE_LOCAL(ppixels);
31452 : if (client->noClientException != Success)
31453 : return(client->noClientException);
31458 : if (noPanoramiXExtension || !pcmp->pScreen->myNum)
31461 : accr.type = X_Reply;
31462 : accr.length = length >> 2;
31463 : accr.sequenceNumber = client->sequence;
31464 : accr.nPixels = npixels;
31465 : accr.nMasks = nmasks;
31466 : WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
31467 : client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
31468 : WriteSwappedDataToClient(client, length, ppixels);
31470 : DEALLOCATE_LOCAL(ppixels);
31471 : return (client->noClientException);
31475 : client->errorValue = stuff->cmap;
31476 : return (BadColor);
31481 :ProcAllocColorPlanes(ClientPtr client)
31483 : ColormapPtr pcmp;
31484 : REQUEST(xAllocColorPlanesReq);
31486 : REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
31487 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31488 : RT_COLORMAP, DixWriteAccess);
31491 : xAllocColorPlanesReply acpr;
31492 : int npixels, retval;
31496 : npixels = stuff->colors;
31499 : client->errorValue = npixels;
31500 : return (BadValue);
31502 : if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
31504 : client->errorValue = stuff->contiguous;
31505 : return (BadValue);
31507 : acpr.type = X_Reply;
31508 : acpr.sequenceNumber = client->sequence;
31509 : acpr.nPixels = npixels;
31510 : length = (long)npixels * sizeof(Pixel);
31511 : ppixels = (Pixel *)ALLOCATE_LOCAL(length);
31513 : return(BadAlloc);
31514 : if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
31515 : (int)stuff->red, (int)stuff->green, (int)stuff->blue,
31516 : (Bool)stuff->contiguous, ppixels,
31517 : &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
31519 : DEALLOCATE_LOCAL(ppixels);
31520 : if (client->noClientException != Success)
31521 : return(client->noClientException);
31525 : acpr.length = length >> 2;
31527 : if (noPanoramiXExtension || !pcmp->pScreen->myNum)
31530 : WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
31531 : client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
31532 : WriteSwappedDataToClient(client, length, ppixels);
31534 : DEALLOCATE_LOCAL(ppixels);
31535 : return (client->noClientException);
31539 : client->errorValue = stuff->cmap;
31540 : return (BadColor);
31545 :ProcFreeColors(ClientPtr client)
31547 : ColormapPtr pcmp;
31548 : REQUEST(xFreeColorsReq);
31550 : REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
31551 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31552 : RT_COLORMAP, DixWriteAccess);
31558 : if(pcmp->flags & AllAllocated)
31559 : return(BadAccess);
31560 : count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
31561 : retval = FreeColors(pcmp, client->index, count,
31562 : (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
31563 : if (client->noClientException != Success)
31564 : return(client->noClientException);
31567 : client->errorValue = clientErrorValue;
31574 : client->errorValue = stuff->cmap;
31575 : return (BadColor);
31580 :ProcStoreColors (ClientPtr client)
31582 : ColormapPtr pcmp;
31583 : REQUEST(xStoreColorsReq);
31585 : REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
31586 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31587 : RT_COLORMAP, DixWriteAccess);
31593 : count = (client->req_len << 2) - sizeof(xStoreColorsReq);
31594 : if (count % sizeof(xColorItem))
31595 : return(BadLength);
31596 : count /= sizeof(xColorItem);
31597 : retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
31598 : if (client->noClientException != Success)
31599 : return(client->noClientException);
31602 : client->errorValue = clientErrorValue;
31608 : client->errorValue = stuff->cmap;
31609 : return (BadColor);
31614 :ProcStoreNamedColor (ClientPtr client)
31616 : ColormapPtr pcmp;
31617 : REQUEST(xStoreNamedColorReq);
31619 : REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
31620 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31621 : RT_COLORMAP, DixWriteAccess);
31627 : if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
31628 : stuff->nbytes, &def.red, &def.green, &def.blue))
31630 : def.flags = stuff->flags;
31631 : def.pixel = stuff->pixel;
31632 : retval = StoreColors(pcmp, 1, &def);
31633 : if (client->noClientException != Success)
31634 : return(client->noClientException);
31638 : return (BadName);
31642 : client->errorValue = stuff->cmap;
31643 : return (BadColor);
31648 :ProcQueryColors(ClientPtr client)
31650 : ColormapPtr pcmp;
31651 : REQUEST(xQueryColorsReq);
31653 : REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
31654 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31655 : RT_COLORMAP, DixReadAccess);
31658 : int count, retval;
31660 : xQueryColorsReply qcr;
31662 : count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
31663 : prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
31664 : if(!prgbs && count)
31665 : return(BadAlloc);
31666 : if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
31668 : if (prgbs) DEALLOCATE_LOCAL(prgbs);
31669 : if (client->noClientException != Success)
31670 : return(client->noClientException);
31673 : client->errorValue = clientErrorValue;
31677 : qcr.type = X_Reply;
31678 : qcr.length = (count * sizeof(xrgb)) >> 2;
31679 : qcr.sequenceNumber = client->sequence;
31680 : qcr.nColors = count;
31681 : WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
31684 : client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
31685 : WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
31687 : if (prgbs) DEALLOCATE_LOCAL(prgbs);
31688 : return(client->noClientException);
31693 : client->errorValue = stuff->cmap;
31694 : return (BadColor);
31699 :ProcLookupColor(ClientPtr client)
31701 : ColormapPtr pcmp;
31702 : REQUEST(xLookupColorReq);
31704 : REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
31705 : pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
31706 : RT_COLORMAP, DixReadAccess);
31709 : xLookupColorReply lcr;
31711 : if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
31712 : &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
31714 : lcr.type = X_Reply;
31716 : lcr.sequenceNumber = client->sequence;
31717 : lcr.screenRed = lcr.exactRed;
31718 : lcr.screenGreen = lcr.exactGreen;
31719 : lcr.screenBlue = lcr.exactBlue;
31720 : (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
31721 : &lcr.screenGreen,
31724 : WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
31725 : return(client->noClientException);
31727 : return (BadName);
31731 : client->errorValue = stuff->cmap;
31732 : return (BadColor);
31737 :ProcCreateCursor (ClientPtr client)
31739 : CursorPtr pCursor;
31742 : unsigned char * srcbits;
31743 : unsigned char * mskbits;
31744 : unsigned short width, height;
31746 : CursorMetricRec cm;
31749 : REQUEST(xCreateCursorReq);
31751 : REQUEST_SIZE_MATCH(xCreateCursorReq);
31752 : LEGAL_NEW_RESOURCE(stuff->cid, client);
31754 : src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
31755 : RT_PIXMAP, DixReadAccess);
31756 : msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
31757 : RT_PIXMAP, DixReadAccess);
31758 : if ( src == (PixmapPtr)NULL)
31760 : client->errorValue = stuff->source;
31761 : return (BadPixmap);
31763 : if ( msk == (PixmapPtr)NULL)
31765 : if (stuff->mask != None)
31767 : client->errorValue = stuff->mask;
31768 : return (BadPixmap);
31771 : else if ( src->drawable.width != msk->drawable.width
31772 : || src->drawable.height != msk->drawable.height
31773 : || src->drawable.depth != 1
31774 : || msk->drawable.depth != 1)
31775 : return (BadMatch);
31777 : width = src->drawable.width;
31778 : height = src->drawable.height;
31780 : if ( stuff->x > width
31781 : || stuff->y > height )
31782 : return (BadMatch);
31784 : n = BitmapBytePad(width)*height;
31785 : srcbits = (unsigned char *)xalloc(n);
31787 : return (BadAlloc);
31788 : mskbits = (unsigned char *)xalloc(n);
31792 : return (BadAlloc);
31795 : /* zeroing the (pad) bits helps some ddx cursor handling */
31796 : bzero((char *)srcbits, n);
31797 : (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
31798 : XYPixmap, 1, (pointer)srcbits);
31799 : if ( msk == (PixmapPtr)NULL)
31801 : unsigned char *bits = mskbits;
31807 : /* zeroing the (pad) bits helps some ddx cursor handling */
31808 : bzero((char *)mskbits, n);
31809 : (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
31810 : height, XYPixmap, 1, (pointer)mskbits);
31812 : cm.width = width;
31813 : cm.height = height;
31814 : cm.xhot = stuff->x;
31815 : cm.yhot = stuff->y;
31816 : pCursor = AllocCursor( srcbits, mskbits, &cm,
31817 : stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
31818 : stuff->backRed, stuff->backGreen, stuff->backBlue);
31820 : if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
31821 : return (client->noClientException);
31826 :ProcCreateGlyphCursor (ClientPtr client)
31828 : CursorPtr pCursor;
31831 : REQUEST(xCreateGlyphCursorReq);
31833 : REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
31834 : LEGAL_NEW_RESOURCE(stuff->cid, client);
31836 : res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
31837 : stuff->mask, stuff->maskChar,
31838 : stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
31839 : stuff->backRed, stuff->backGreen, stuff->backBlue,
31840 : &pCursor, client);
31841 : if (res != Success)
31843 : if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
31844 : return client->noClientException;
31850 :ProcFreeCursor (ClientPtr client)
31852 : CursorPtr pCursor;
31853 : REQUEST(xResourceReq);
31855 : REQUEST_SIZE_MATCH(xResourceReq);
31856 : pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
31857 : RT_CURSOR, DixDestroyAccess);
31860 : FreeResource(stuff->id, RT_NONE);
31861 : return (client->noClientException);
31865 : client->errorValue = stuff->id;
31866 : return (BadCursor);
31871 :ProcQueryBestSize (ClientPtr client)
31873 : xQueryBestSizeReply reply;
31874 : DrawablePtr pDraw;
31875 : ScreenPtr pScreen;
31877 : REQUEST(xQueryBestSizeReq);
31878 : REQUEST_SIZE_MATCH(xQueryBestSizeReq);
31880 : if ((stuff->class != CursorShape) &&
31881 : (stuff->class != TileShape) &&
31882 : (stuff->class != StippleShape))
31884 : client->errorValue = stuff->class;
31885 : return(BadValue);
31888 : rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
31890 : if (rc != Success)
31892 : if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
31893 : return (BadMatch);
31894 : pScreen = pDraw->pScreen;
31895 : (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
31896 : &stuff->height, pScreen);
31897 : reply.type = X_Reply;
31898 : reply.length = 0;
31899 : reply.sequenceNumber = client->sequence;
31900 : reply.width = stuff->width;
31901 : reply.height = stuff->height;
31902 : WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
31903 : return (client->noClientException);
31908 :ProcSetScreenSaver (ClientPtr client)
31910 : int blankingOption, exposureOption;
31911 : REQUEST(xSetScreenSaverReq);
31913 : REQUEST_SIZE_MATCH(xSetScreenSaverReq);
31914 : blankingOption = stuff->preferBlank;
31915 : if ((blankingOption != DontPreferBlanking) &&
31916 : (blankingOption != PreferBlanking) &&
31917 : (blankingOption != DefaultBlanking))
31919 : client->errorValue = blankingOption;
31922 : exposureOption = stuff->allowExpose;
31923 : if ((exposureOption != DontAllowExposures) &&
31924 : (exposureOption != AllowExposures) &&
31925 : (exposureOption != DefaultExposures))
31927 : client->errorValue = exposureOption;
31930 : if (stuff->timeout < -1)
31932 : client->errorValue = stuff->timeout;
31935 : if (stuff->interval < -1)
31937 : client->errorValue = stuff->interval;
31941 : if (blankingOption == DefaultBlanking)
31942 : ScreenSaverBlanking = defaultScreenSaverBlanking;
31944 : ScreenSaverBlanking = blankingOption;
31945 : if (exposureOption == DefaultExposures)
31946 : ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
31948 : ScreenSaverAllowExposures = exposureOption;
31950 : if (stuff->timeout >= 0)
31951 : ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
31953 : ScreenSaverTime = defaultScreenSaverTime;
31954 : if (stuff->interval >= 0)
31955 : ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
31957 : ScreenSaverInterval = defaultScreenSaverInterval;
31959 : SetScreenSaverTimer();
31960 : return (client->noClientException);
31964 :ProcGetScreenSaver(ClientPtr client)
31966 : xGetScreenSaverReply rep;
31968 : REQUEST_SIZE_MATCH(xReq);
31969 : rep.type = X_Reply;
31971 : rep.sequenceNumber = client->sequence;
31972 : rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
31973 : rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
31974 : rep.preferBlanking = ScreenSaverBlanking;
31975 : rep.allowExposures = ScreenSaverAllowExposures;
31976 : WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
31977 : return (client->noClientException);
31981 :ProcChangeHosts(ClientPtr client)
31983 : REQUEST(xChangeHostsReq);
31986 : REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
31988 : if(stuff->mode == HostInsert)
31989 : result = AddHost(client, (int)stuff->hostFamily,
31990 : stuff->hostLength, (pointer)&stuff[1]);
31991 : else if (stuff->mode == HostDelete)
31992 : result = RemoveHost(client, (int)stuff->hostFamily,
31993 : stuff->hostLength, (pointer)&stuff[1]);
31996 : client->errorValue = stuff->mode;
32000 : result = client->noClientException;
32005 :ProcListHosts(ClientPtr client)
32007 : xListHostsReply reply;
32008 : int len, nHosts, result;
32010 : /* REQUEST(xListHostsReq); */
32012 : REQUEST_SIZE_MATCH(xListHostsReq);
32014 : /* untrusted clients can't list hosts */
32015 : if (!XaceHook(XACE_HOSTLIST_ACCESS, client, DixReadAccess))
32016 : return BadAccess;
32018 : result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
32019 : if (result != Success)
32021 : reply.type = X_Reply;
32022 : reply.sequenceNumber = client->sequence;
32023 : reply.nHosts = nHosts;
32024 : reply.length = len >> 2;
32025 : WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
32028 : client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
32029 : WriteSwappedDataToClient(client, len, pdata);
32032 : return (client->noClientException);
32036 :ProcChangeAccessControl(ClientPtr client)
32039 : REQUEST(xSetAccessControlReq);
32041 : REQUEST_SIZE_MATCH(xSetAccessControlReq);
32042 : if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
32044 : client->errorValue = stuff->mode;
32047 : result = ChangeAccessControl(client, stuff->mode == EnableAccess);
32049 : result = client->noClientException;
32053 :/*********************
32054 : * CloseDownRetainedResources
32056 : * Find all clients that are gone and have terminated in RetainTemporary
32057 : * and destroy their resources.
32058 : *********************/
32061 :CloseDownRetainedResources(void)
32064 : ClientPtr client;
32066 : for (i=1; i<currentMaxClients; i++)
32068 : client = clients[i];
32069 : if (client && (client->closeDownMode == RetainTemporary)
32070 : && (client->clientGone))
32071 : CloseDownClient(client);
32076 :ProcKillClient(ClientPtr client)
32078 : REQUEST(xResourceReq);
32079 : ClientPtr killclient;
32082 : REQUEST_SIZE_MATCH(xResourceReq);
32083 : if (stuff->id == AllTemporary)
32085 : CloseDownRetainedResources();
32086 : return (client->noClientException);
32089 : rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
32090 : if (rc == Success) {
32091 : CloseDownClient(killclient);
32092 : /* if an LBX proxy gets killed, isItTimeToYield will be set */
32093 : if (isItTimeToYield || (client == killclient))
32095 : /* force yield and return Success, so that Dispatch()
32096 : * doesn't try to touch client
32098 : isItTimeToYield = TRUE;
32099 : return (Success);
32101 : return (client->noClientException);
32108 :ProcSetFontPath(ClientPtr client)
32110 : unsigned char *ptr;
32111 : unsigned long nbytes, total;
32115 : REQUEST(xSetFontPathReq);
32117 : REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
32119 : nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
32121 : ptr = (unsigned char *)&stuff[1];
32122 : nfonts = stuff->nFonts;
32123 : while (--nfonts >= 0)
32125 : if ((total == 0) || (total < (n = (*ptr + 1))))
32126 : return(BadLength);
32131 : return(BadLength);
32132 : result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
32136 : result = client->noClientException;
32137 : client->errorValue = error;
32143 :ProcGetFontPath(ClientPtr client)
32145 : xGetFontPathReply reply;
32146 : int stringLens, numpaths;
32147 : unsigned char *bufferStart;
32148 : /* REQUEST (xReq); */
32150 : REQUEST_SIZE_MATCH(xReq);
32151 : bufferStart = GetFontPath(&numpaths, &stringLens);
32153 : reply.type = X_Reply;
32154 : reply.sequenceNumber = client->sequence;
32155 : reply.length = (stringLens + numpaths + 3) >> 2;
32156 : reply.nPaths = numpaths;
32158 : WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
32159 : if (stringLens || numpaths)
32160 : (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
32161 : return(client->noClientException);
32165 :ProcChangeCloseDownMode(ClientPtr client)
32167 : REQUEST(xSetCloseDownModeReq);
32169 : REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
32170 : if ((stuff->mode == AllTemporary) ||
32171 : (stuff->mode == RetainPermanent) ||
32172 : (stuff->mode == RetainTemporary))
32174 : client->closeDownMode = stuff->mode;
32175 : return (client->noClientException);
32179 : client->errorValue = stuff->mode;
32180 : return (BadValue);
32184 :int ProcForceScreenSaver(ClientPtr client)
32186 : REQUEST(xForceScreenSaverReq);
32188 : REQUEST_SIZE_MATCH(xForceScreenSaverReq);
32190 : if ((stuff->mode != ScreenSaverReset) &&
32191 : (stuff->mode != ScreenSaverActive))
32193 : client->errorValue = stuff->mode;
32196 : SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
32197 : return client->noClientException;
32200 :int ProcNoOperation(ClientPtr client)
32202 : REQUEST_AT_LEAST_SIZE(xReq);
32204 : /* noop -- don't do anything */
32205 : return(client->noClientException);
32209 :InitProcVectors(void)
32212 : for (i = 0; i<256; i++)
32214 : if(!ProcVector[i])
32216 : ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
32217 : ReplySwapVector[i] = ReplyNotSwappd;
32220 : for(i = LASTEvent; i < 128; i++)
32222 : EventSwapVector[i] = NotImplemented;
32227 :/**********************
32228 : * CloseDownClient
32230 : * Client can either mark his resources destroy or retain. If retained and
32231 : * then killed again, the client is really destroyed.
32232 : *********************/
32234 :char dispatchExceptionAtReset = DE_RESET;
32237 :CloseDownClient(ClientPtr client)
32239 : Bool really_close_down = client->clientGone ||
32240 : client->closeDownMode == DestroyAll;
32242 : if (!client->clientGone)
32244 : /* ungrab server if grabbing client dies */
32245 : if (grabState != GrabNone && grabClient == client)
32247 : UngrabServer(client);
32249 : BITCLEAR(grabWaiters, client->index);
32250 : DeleteClientFromAnySelections(client);
32251 : ReleaseActiveGrabs(client);
32252 : DeleteClientFontStuff(client);
32253 : if (!really_close_down)
32255 : /* This frees resources that should never be retained
32256 : * no matter what the close down mode is. Actually we
32257 : * could do this unconditionally, but it's probably
32258 : * better not to traverse all the client's resources
32259 : * twice (once here, once a few lines down in
32260 : * FreeClientResources) in the common case of
32261 : * really_close_down == TRUE.
32263 : FreeClientNeverRetainResources(client);
32264 : client->clientState = ClientStateRetained;
32265 : if (ClientStateCallback)
32267 : NewClientInfoRec clientinfo;
32269 : clientinfo.client = client;
32270 : clientinfo.prefix = (xConnSetupPrefix *)NULL;
32271 : clientinfo.setup = (xConnSetup *) NULL;
32272 : CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
32275 : client->clientGone = TRUE; /* so events aren't sent to client */
32276 : if (ClientIsAsleep(client))
32277 : ClientSignal (client);
32278 : ProcessWorkQueueZombies();
32279 : CloseDownConnection(client);
32281 : /* If the client made it to the Running stage, nClients has
32282 : * been incremented on its behalf, so we need to decrement it
32283 : * now. If it hasn't gotten to Running, nClients has *not*
32284 : * been incremented, so *don't* decrement it.
32286 : if (client->clientState != ClientStateInitial &&
32287 : client->clientState != ClientStateAuthenticating )
32293 : if (really_close_down)
32295 : if (client->clientState == ClientStateRunning && nClients == 0)
32296 : dispatchException |= dispatchExceptionAtReset;
32298 : client->clientState = ClientStateGone;
32299 : if (ClientStateCallback)
32301 : NewClientInfoRec clientinfo;
32303 : clientinfo.client = client;
32304 : clientinfo.prefix = (xConnSetupPrefix *)NULL;
32305 : clientinfo.setup = (xConnSetup *) NULL;
32306 : CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
32308 : FreeClientResources(client);
32309 :#ifdef XSERVER_DTRACE
32310 : XSERVER_CLIENT_DISCONNECT(client->index);
32312 : if (client->index < nextFreeClientID)
32313 : nextFreeClientID = client->index;
32314 : clients[client->index] = NullClient;
32315 :#ifdef SMART_SCHEDULE
32316 : SmartLastClient = NullClient;
32320 : while (!clients[currentMaxClients-1])
32321 : currentMaxClients--;
32326 :KillAllClients(void)
32329 : for (i=1; i<currentMaxClients; i++)
32330 : if (clients[i]) {
32331 : /* Make sure Retained clients are released. */
32332 : clients[i]->closeDownMode = DestroyAll;
32333 : CloseDownClient(clients[i]);
32337 :extern int clientPrivateLen;
32338 :extern unsigned *clientPrivateSizes;
32339 :extern unsigned totalClientSize;
32341 :void InitClient(ClientPtr client, int i, pointer ospriv)
32343 : client->index = i;
32344 : client->sequence = 0;
32345 : client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
32346 : client->clientGone = FALSE;
32349 : client->closeDownMode = DestroyAll;
32350 : client->lastDrawable = (DrawablePtr)WindowTable[0];
32351 : client->lastDrawableID = WindowTable[0]->drawable.id;
32355 : client->closeDownMode = RetainPermanent;
32356 : client->lastDrawable = (DrawablePtr)NULL;
32357 : client->lastDrawableID = INVALID;
32359 : client->lastGC = (GCPtr) NULL;
32360 : client->lastGCID = INVALID;
32361 : client->numSaved = 0;
32362 : client->saveSet = (SaveSetElt *)NULL;
32363 : client->noClientException = Success;
32365 : client->requestLogIndex = 0;
32367 : client->requestVector = InitialVector;
32368 : client->osPrivate = ospriv;
32369 : client->swapped = FALSE;
32370 : client->big_requests = FALSE;
32371 : client->priority = 0;
32372 : client->clientState = ClientStateInitial;
32374 : if (!noXkbExtension) {
32375 : client->xkbClientFlags = 0;
32376 : client->mapNotifyMask = 0;
32377 : QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
32380 : client->replyBytesRemaining = 0;
32382 : client->appgroup = NULL;
32384 : client->fontResFunc = NULL;
32385 :#ifdef SMART_SCHEDULE
32386 : client->smart_priority = 0;
32387 : client->smart_start_tick = SmartScheduleTime;
32388 : client->smart_stop_tick = SmartScheduleTime;
32389 : client->smart_check_tick = SmartScheduleTime;
32394 :InitClientPrivates(ClientPtr client)
32402 : if (totalClientSize == sizeof(ClientRec))
32403 : ppriv = (DevUnion *)NULL;
32404 : else if (client->index)
32405 : ppriv = (DevUnion *)(client + 1);
32408 : ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
32412 : client->devPrivates = ppriv;
32413 : sizes = clientPrivateSizes;
32414 : ptr = (char *)(ppriv + clientPrivateLen);
32416 : bzero(ppriv, totalClientSize - sizeof(ClientRec));
32417 : for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
32419 : if ( (size = *sizes) )
32421 : ppriv->ptr = (pointer)ptr;
32425 : ppriv->ptr = (pointer)NULL;
32428 : /* Allow registrants to initialize the serverClient devPrivates */
32429 : if (!client->index && ClientStateCallback)
32431 : NewClientInfoRec clientinfo;
32433 : clientinfo.client = client;
32434 : clientinfo.prefix = (xConnSetupPrefix *)NULL;
32435 : clientinfo.setup = (xConnSetup *) NULL;
32436 : CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
32441 :/************************
32442 : * int NextAvailableClient(ospriv)
32444 : * OS dependent portion can't assign client id's because of CloseDownModes.
32445 : * Returns NULL if there are no free clients.
32446 : *************************/
32448 :ClientPtr NextAvailableClient(pointer ospriv)
32451 : ClientPtr client;
32454 : i = nextFreeClientID;
32455 : if (i == MAXCLIENTS)
32456 : return (ClientPtr)NULL;
32457 : clients[i] = client = (ClientPtr)xalloc(totalClientSize);
32459 : return (ClientPtr)NULL;
32460 : InitClient(client, i, ospriv);
32461 : InitClientPrivates(client);
32462 : if (!InitClientResources(client))
32465 : return (ClientPtr)NULL;
32467 : data.reqType = 1;
32468 : data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
32469 : if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
32471 : FreeClientResources(client);
32473 : return (ClientPtr)NULL;
32475 : if (i == currentMaxClients)
32476 : currentMaxClients++;
32477 : while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
32478 : nextFreeClientID++;
32479 : if (ClientStateCallback)
32481 : NewClientInfoRec clientinfo;
32483 : clientinfo.client = client;
32484 : clientinfo.prefix = (xConnSetupPrefix *)NULL;
32485 : clientinfo.setup = (xConnSetup *) NULL;
32486 : CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
32492 :ProcInitialConnection(ClientPtr client)
32495 : xConnClientPrefix *prefix;
32496 : int whichbyte = 1;
32498 : prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
32499 : if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
32500 : return (client->noClientException = -1);
32501 : if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
32502 : (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
32504 : client->swapped = TRUE;
32505 : SwapConnClientPrefix(prefix);
32507 : stuff->reqType = 2;
32508 : stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
32509 : ((prefix->nbytesAuthString + (unsigned)3) >> 2);
32510 : if (client->swapped)
32512 : swaps(&stuff->length, whichbyte);
32514 : ResetCurrentRequest(client);
32515 : return (client->noClientException);
32519 :SendConnSetup(ClientPtr client, char *reason)
32521 : xWindowRoot *root;
32524 : char* lConnectionInfo;
32525 : xConnSetupPrefix* lconnSetupPrefix;
32529 : xConnSetupPrefix csp;
32531 : csp.success = xFalse;
32532 : csp.lengthReason = strlen(reason);
32533 : csp.length = (csp.lengthReason + (unsigned)3) >> 2;
32534 : csp.majorVersion = X_PROTOCOL;
32535 : csp.minorVersion = X_PROTOCOL_REVISION;
32536 : if (client->swapped)
32537 : WriteSConnSetupPrefix(client, &csp);
32539 : (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
32540 : (void)WriteToClient(client, (int)csp.lengthReason, reason);
32541 : return (client->noClientException = -1);
32544 : numScreens = screenInfo.numScreens;
32545 : lConnectionInfo = ConnectionInfo;
32546 : lconnSetupPrefix = &connSetupPrefix;
32548 : /* We're about to start speaking X protocol back to the client by
32549 : * sending the connection setup info. This means the authorization
32550 : * step is complete, and we can count the client as an
32551 : * authorized one.
32555 : client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
32556 : client->sequence = 0;
32558 : XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
32560 : ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
32561 : ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
32562 :#ifdef MATCH_CLIENT_ENDIAN
32563 : ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
32564 : ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
32566 : /* fill in the "currentInputMask" */
32567 : root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
32569 : if (noPanoramiXExtension)
32570 : numScreens = screenInfo.numScreens;
32572 : numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
32575 : for (i=0; i<numScreens; i++)
32580 : root->currentInputMask = WindowTable[i]->eventMask |
32581 : wOtherEventMasks (WindowTable[i]);
32582 : pDepth = (xDepth *)(root + 1);
32583 : for (j = 0; j < root->nDepths; j++)
32585 : pDepth = (xDepth *)(((char *)(pDepth + 1)) +
32586 : pDepth->nVisuals * sizeof(xVisualType));
32588 : root = (xWindowRoot *)pDepth;
32591 : if (client->swapped)
32593 : WriteSConnSetupPrefix(client, lconnSetupPrefix);
32594 : WriteSConnectionInfo(client,
32595 : (unsigned long)(lconnSetupPrefix->length << 2),
32596 : lConnectionInfo);
32600 : (void)WriteToClient(client, sizeof(xConnSetupPrefix),
32601 : (char *) lconnSetupPrefix);
32602 : (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
32603 : lConnectionInfo);
32605 : client->clientState = ClientStateRunning;
32606 : if (ClientStateCallback)
32608 : NewClientInfoRec clientinfo;
32610 : clientinfo.client = client;
32611 : clientinfo.prefix = lconnSetupPrefix;
32612 : clientinfo.setup = (xConnSetup *)lConnectionInfo;
32613 : CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
32615 : return (client->noClientException);
32619 :ProcEstablishConnection(ClientPtr client)
32621 : char *reason, *auth_proto, *auth_string;
32622 : xConnClientPrefix *prefix;
32625 : prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
32626 : auth_proto = (char *)prefix + sz_xConnClientPrefix;
32627 : auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
32628 : if ((prefix->majorVersion != X_PROTOCOL) ||
32629 : (prefix->minorVersion != X_PROTOCOL_REVISION))
32630 : reason = "Protocol version mismatch";
32632 : reason = ClientAuthorized(client,
32633 : (unsigned short)prefix->nbytesAuthProto,
32635 : (unsigned short)prefix->nbytesAuthString,
32638 : * If Kerberos is being used for this client, the clientState
32639 : * will be set to ClientStateAuthenticating at this point.
32640 : * More messages need to be exchanged among the X server, Kerberos
32641 : * server, and client to figure out if everyone is authorized.
32642 : * So we don't want to send the connection setup info yet, since
32643 : * the auth step isn't really done.
32645 : if (client->clientState == ClientStateCheckingSecurity)
32646 : client->clientState = ClientStateCheckedSecurity;
32647 : else if (client->clientState != ClientStateAuthenticating)
32648 : return(SendConnSetup(client, reason));
32649 : return(client->noClientException);
32653 :SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
32654 : XID resId, int errorCode)
32658 : rep.type = X_Error;
32659 : rep.sequenceNumber = client->sequence;
32660 : rep.errorCode = errorCode;
32661 : rep.majorCode = majorCode;
32662 : rep.minorCode = minorCode;
32663 : rep.resourceID = resId;
32665 : WriteEventsToClient (client, 1, (xEvent *)&rep);
32669 :DeleteWindowFromAnySelections(WindowPtr pWin)
32673 : for (i = 0; i< NumCurrentSelections; i++)
32674 : if (CurrentSelections[i].pWin == pWin)
32676 : if (SelectionCallback)
32678 : SelectionInfoRec info;
32680 : info.selection = &CurrentSelections[i];
32681 : info.kind = SelectionWindowDestroy;
32682 : CallCallbacks(&SelectionCallback, &info);
32684 : CurrentSelections[i].pWin = (WindowPtr)NULL;
32685 : CurrentSelections[i].window = None;
32686 : CurrentSelections[i].client = NullClient;
32691 :DeleteClientFromAnySelections(ClientPtr client)
32695 : for (i = 0; i< NumCurrentSelections; i++)
32696 : if (CurrentSelections[i].client == client)
32698 : if (SelectionCallback)
32700 : SelectionInfoRec info;
32702 : info.selection = &CurrentSelections[i];
32703 : info.kind = SelectionWindowDestroy;
32704 : CallCallbacks(&SelectionCallback, &info);
32706 : CurrentSelections[i].pWin = (WindowPtr)NULL;
32707 : CurrentSelections[i].window = None;
32708 : CurrentSelections[i].client = NullClient;
32713 :MarkClientException(ClientPtr client)
32715 : client->noClientException = -1;
32718 :#ifdef XSERVER_DTRACE
32719 :#include <ctype.h>
32721 :/* Load table of request names for dtrace probes */
32722 :static void LoadRequestNames(void)
32726 : extern void LoadExtensionNames(char **RequestNames);
32728 : bzero(RequestNames, 256 * sizeof(char *));
32730 : xedb = fopen(XERRORDB_PATH, "r");
32731 : if (xedb != NULL) {
32733 : while (fgets(buf, sizeof(buf), xedb)) {
32734 : if ((strncmp("XRequest.", buf, 9) == 0) && (isdigit(buf[9]))) {
32736 : i = strtol(buf + 9, &name, 10);
32737 : if (RequestNames[i] == 0) {
32738 : char *end = strchr(name, '\n');
32739 : if (end) { *end = '\0'; }
32740 : RequestNames[i] = strdup(name + 1);
32747 : LoadExtensionNames(RequestNames);
32749 : for (i = 0; i < 256; i++) {
32750 : if (RequestNames[i] == 0) {
32751 :#define RN_SIZE 12 /* "Request#' + up to 3 digits + \0 */
32752 : RequestNames[i] = xalloc(RN_SIZE);
32753 : if (RequestNames[i]) {
32754 : snprintf(RequestNames[i], RN_SIZE, "Request#%d", i);
32757 : /* fprintf(stderr, "%d: %s\n", i, RequestNames[i]); */
32761 :static void FreeRequestNames(void)
32765 : for (i = 0; i < 256; i++) {
32766 : if (RequestNames[i] != 0) {
32767 : free(RequestNames[i]);
32768 : RequestNames[i] = 0;
32775 * Total samples for file : "/home/cworth/src/xorg/xserver/dix/gc.c"
32781 :/***********************************************************
32783 :Copyright 1987, 1998 The Open Group
32785 :Permission to use, copy, modify, distribute, and sell this software and its
32786 :documentation for any purpose is hereby granted without fee, provided that
32787 :the above copyright notice appear in all copies and that both that
32788 :copyright notice and this permission notice appear in supporting
32791 :The above copyright notice and this permission notice shall be included in
32792 :all copies or substantial portions of the Software.
32794 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32795 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32796 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32797 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
32798 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32799 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32801 :Except as contained in this notice, the name of The Open Group shall not be
32802 :used in advertising or otherwise to promote the sale, use or other dealings
32803 :in this Software without prior written authorization from The Open Group.
32806 :Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
32808 : All Rights Reserved
32810 :Permission to use, copy, modify, and distribute this software and its
32811 :documentation for any purpose and without fee is hereby granted,
32812 :provided that the above copyright notice appear in all copies and that
32813 :both that copyright notice and this permission notice appear in
32814 :supporting documentation, and that the name of Digital not be
32815 :used in advertising or publicity pertaining to distribution of the
32816 :software without specific, written prior permission.
32818 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
32819 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
32820 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
32821 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
32822 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
32823 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
32826 :******************************************************************/
32829 :#ifdef HAVE_DIX_CONFIG_H
32830 :#include <dix-config.h>
32833 :#include <X11/X.h>
32834 :#include <X11/Xmd.h>
32835 :#include <X11/Xproto.h>
32837 :#include "resource.h"
32838 :#include "gcstruct.h"
32839 :#include "pixmapstr.h"
32840 :#include "dixfontstr.h"
32841 :#include "scrnintstr.h"
32842 :#include "region.h"
32845 :#include <assert.h>
32847 :extern XID clientErrorValue;
32848 :extern FontPtr defaultFont;
32850 :static Bool CreateDefaultTile(GCPtr pGC);
32852 :static unsigned char DefaultDash[2] = {4, 4};
32855 :ValidateGC(DrawablePtr pDraw, GC *pGC)
32856 3 0.0033 :{ /* ValidateGC total: 3 0.0033 */
32857 : (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
32858 : pGC->stateChanges = 0;
32859 : pGC->serialNumber = pDraw->serialNumber;
32863 :/* dixChangeGC(client, pGC, mask, pC32, pUnion)
32865 : * This function was created as part of the Security extension
32866 : * implementation. The client performing the gc change must be passed so
32867 : * that access checks can be performed on any tiles, stipples, or fonts
32868 : * that are specified. ddxen can call this too; they should normally
32869 : * pass NullClient for the client since any access checking should have
32870 : * already been done at a higher level.
32872 : * Since we had to create a new function anyway, we decided to change the
32873 : * way the list of gc values is passed to eliminate the compiler warnings
32874 : * caused by the DoChangeGC interface. You can pass the values via pC32
32875 : * or pUnion, but not both; one of them must be NULL. If you don't need
32876 : * to pass any pointers, you can use either one:
32878 : * example calling dixChangeGC using pC32 parameter
32881 : * v[0] = foreground;
32882 : * v[1] = background;
32883 : * dixChangeGC(client, pGC, GCForeground|GCBackground, v, NULL);
32885 : * example calling dixChangeGC using pUnion parameter;
32886 : * same effect as above
32888 : * ChangeGCVal v[2];
32889 : * v[0].val = foreground;
32890 : * v[1].val = background;
32891 : * dixChangeGC(client, pGC, GCForeground|GCBackground, NULL, v);
32893 : * However, if you need to pass a pointer to a pixmap or font, you MUST
32894 : * use the pUnion parameter.
32896 : * example calling dixChangeGC passing pointers in the value list
32897 : * v[1].ptr is a pointer to a pixmap
32899 : * ChangeGCVal v[2];
32900 : * v[0].val = FillTiled;
32901 : * v[1].ptr = pPixmap;
32902 : * dixChangeGC(client, pGC, GCFillStyle|GCTile, NULL, v);
32904 : * Note: we could have gotten by with just the pUnion parameter, but on
32905 : * 64 bit machines that would have forced us to copy the value list that
32906 : * comes in the ChangeGC request.
32908 : * Ideally, we'd change all the DoChangeGC calls to dixChangeGC, but this
32909 : * is far too many changes to consider at this time, so we've only
32910 : * changed the ones that caused compiler warnings. New code should use
32916 :#define NEXTVAL(_type, _var) { \
32917 : if (pC32) _var = (_type)*pC32++; \
32919 : _var = (_type)(pUnion->val); pUnion++; \
32923 :#define NEXT_PTR(_type, _var) { \
32924 : assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; }
32927 :dixChangeGC(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion)
32928 :{ /* dixChangeGC total: 24 0.0261 */
32931 : PixmapPtr pPixmap;
32934 : assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
32935 : pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
32937 : maskQ = mask; /* save these for when we walk the GCque */
32938 5 0.0054 : while (mask && !error)
32940 1 0.0011 : index2 = (BITS32) lowbit (mask);
32941 7 0.0076 : mask &= ~index2;
32942 : pGC->stateChanges |= index2;
32943 1 0.0011 : switch (index2)
32948 3 0.0033 : NEXTVAL(CARD8, newalu);
32949 : if (newalu <= GXset)
32950 1 0.0011 : pGC->alu = newalu;
32953 : clientErrorValue = newalu;
32954 : error = BadValue;
32958 : case GCPlaneMask:
32959 : NEXTVAL(unsigned long, pGC->planemask);
32961 : case GCForeground:
32962 1 0.0011 : NEXTVAL(unsigned long, pGC->fgPixel);
32964 : * this is for CreateGC
32966 : if (!pGC->tileIsPixel && !pGC->tile.pixmap)
32968 : pGC->tileIsPixel = TRUE;
32969 : pGC->tile.pixel = pGC->fgPixel;
32972 : case GCBackground:
32973 : NEXTVAL(unsigned long, pGC->bgPixel);
32975 : case GCLineWidth: /* ??? line width is a CARD16 */
32976 : NEXTVAL(CARD16, pGC->lineWidth);
32978 : case GCLineStyle:
32980 : unsigned int newlinestyle;
32981 : NEXTVAL(unsigned int, newlinestyle);
32982 : if (newlinestyle <= LineDoubleDash)
32983 : pGC->lineStyle = newlinestyle;
32986 : clientErrorValue = newlinestyle;
32987 : error = BadValue;
32993 : unsigned int newcapstyle;
32994 : NEXTVAL(unsigned int, newcapstyle);
32995 : if (newcapstyle <= CapProjecting)
32996 : pGC->capStyle = newcapstyle;
32999 : clientErrorValue = newcapstyle;
33000 : error = BadValue;
33004 : case GCJoinStyle:
33006 : unsigned int newjoinstyle;
33007 : NEXTVAL(unsigned int, newjoinstyle);
33008 : if (newjoinstyle <= JoinBevel)
33009 : pGC->joinStyle = newjoinstyle;
33012 : clientErrorValue = newjoinstyle;
33013 : error = BadValue;
33017 : case GCFillStyle:
33019 : unsigned int newfillstyle;
33020 : NEXTVAL(unsigned int, newfillstyle);
33021 : if (newfillstyle <= FillOpaqueStippled)
33022 : pGC->fillStyle = newfillstyle;
33025 : clientErrorValue = newfillstyle;
33026 : error = BadValue;
33032 : unsigned int newfillrule;
33033 : NEXTVAL(unsigned int, newfillrule);
33034 : if (newfillrule <= WindingRule)
33035 : pGC->fillRule = newfillrule;
33038 : clientErrorValue = newfillrule;
33039 : error = BadValue;
33048 : NEXT_PTR(PixmapPtr, pPixmap);
33052 : NEXTVAL(XID, newpix);
33053 : pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
33054 : newpix, RT_PIXMAP, DixReadAccess);
33058 : if ((pPixmap->drawable.depth != pGC->depth) ||
33059 : (pPixmap->drawable.pScreen != pGC->pScreen))
33061 : error = BadMatch;
33065 : pPixmap->refcnt++;
33066 : if (!pGC->tileIsPixel)
33067 : (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
33068 : pGC->tileIsPixel = FALSE;
33069 : pGC->tile.pixmap = pPixmap;
33074 : clientErrorValue = newpix;
33075 : error = BadPixmap;
33081 : XID newstipple = 0;
33084 : NEXT_PTR(PixmapPtr, pPixmap);
33088 : NEXTVAL(XID, newstipple)
33089 : pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
33090 : newstipple, RT_PIXMAP, DixReadAccess);
33094 : if ((pPixmap->drawable.depth != 1) ||
33095 : (pPixmap->drawable.pScreen != pGC->pScreen))
33097 : error = BadMatch;
33101 : pPixmap->refcnt++;
33102 : if (pGC->stipple)
33103 : (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
33104 : pGC->stipple = pPixmap;
33109 : clientErrorValue = newstipple;
33110 : error = BadPixmap;
33114 : case GCTileStipXOrigin:
33115 : NEXTVAL(INT16, pGC->patOrg.x);
33117 : case GCTileStipYOrigin:
33118 : NEXTVAL(INT16, pGC->patOrg.y);
33126 : NEXT_PTR(FontPtr, pFont);
33130 : NEXTVAL(XID, newfont)
33131 : pFont = (FontPtr)SecurityLookupIDByType(client, newfont,
33132 : RT_FONT, DixReadAccess);
33138 : CloseFont(pGC->font, (Font)0);
33139 : pGC->font = pFont;
33143 : clientErrorValue = newfont;
33148 : case GCSubwindowMode:
33150 : unsigned int newclipmode;
33151 1 0.0011 : NEXTVAL(unsigned int, newclipmode);
33152 : if (newclipmode <= IncludeInferiors)
33153 1 0.0011 : pGC->subWindowMode = newclipmode;
33156 : clientErrorValue = newclipmode;
33157 : error = BadValue;
33161 : case GCGraphicsExposures:
33163 : unsigned int newge;
33164 : NEXTVAL(unsigned int, newge);
33165 : if (newge <= xTrue)
33166 : pGC->graphicsExposures = newge;
33169 : clientErrorValue = newge;
33170 : error = BadValue;
33174 : case GCClipXOrigin:
33175 2 0.0022 : NEXTVAL(INT16, pGC->clipOrg.x);
33177 : case GCClipYOrigin:
33178 : NEXTVAL(INT16, pGC->clipOrg.y);
33183 : int clipType = 0;
33187 : NEXT_PTR(PixmapPtr, pPixmap);
33191 : NEXTVAL(Pixmap, pid)
33194 : clipType = CT_NONE;
33195 : pPixmap = NullPixmap;
33198 : pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
33199 : pid, RT_PIXMAP, DixReadAccess);
33204 : if ((pPixmap->drawable.depth != 1) ||
33205 : (pPixmap->drawable.pScreen != pGC->pScreen))
33207 : error = BadMatch;
33211 : clipType = CT_PIXMAP;
33212 : pPixmap->refcnt++;
33215 : else if (!pUnion && (pid != None))
33217 : clientErrorValue = pid;
33218 : error = BadPixmap;
33220 : if(error == Success)
33222 : (*pGC->funcs->ChangeClip)(pGC, clipType,
33223 : (pointer)pPixmap, 0);
33227 : case GCDashOffset:
33228 : NEXTVAL(INT16, pGC->dashOffset);
33233 : NEXTVAL(CARD8, newdash);
33234 : if (newdash == 4)
33236 : if (pGC->dash != DefaultDash)
33238 : xfree(pGC->dash);
33239 : pGC->numInDashList = 2;
33240 : pGC->dash = DefaultDash;
33243 : else if (newdash != 0)
33245 : unsigned char *dash;
33247 : dash = (unsigned char *)xalloc(2 * sizeof(unsigned char));
33250 : if (pGC->dash != DefaultDash)
33251 : xfree(pGC->dash);
33252 : pGC->numInDashList = 2;
33253 : pGC->dash = dash;
33254 : dash[0] = newdash;
33255 : dash[1] = newdash;
33258 : error = BadAlloc;
33262 : clientErrorValue = newdash;
33263 : error = BadValue;
33269 : unsigned int newarcmode;
33270 : NEXTVAL(unsigned int, newarcmode);
33271 : if (newarcmode <= ArcPieSlice)
33272 : pGC->arcMode = newarcmode;
33275 : clientErrorValue = newarcmode;
33276 : error = BadValue;
33281 : clientErrorValue = maskQ;
33282 : error = BadValue;
33285 : } /* end while mask && !error */
33287 1 0.0011 : if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
33289 : if (!CreateDefaultTile (pGC))
33291 : pGC->fillStyle = FillSolid;
33292 : error = BadAlloc;
33295 : (*pGC->funcs->ChangeGC)(pGC, maskQ);
33302 :/* Publically defined entry to ChangeGC. Just calls dixChangeGC and tells
33303 : * it that all of the entries are constants or IDs */
33305 :ChangeGC(GC *pGC, BITS32 mask, XID *pval)
33306 2 0.0022 :{ /* ChangeGC total: 5 0.0054 */
33307 3 0.0033 : return (dixChangeGC(NullClient, pGC, mask, pval, NULL));
33310 :/* DoChangeGC(pGC, mask, pval, fPointer)
33311 : mask is a set of bits indicating which values to change.
33312 : pval contains an appropriate value for each mask.
33313 : fPointer is true if the values for tiles, stipples, fonts or clipmasks
33314 : are pointers instead of IDs. Note: if you are passing pointers you
33315 : MUST declare the array of values as type pointer! Other data types
33316 : may not be large enough to hold pointers on some machines. Yes,
33317 : this means you have to cast to (XID *) when you pass the array to
33318 : DoChangeGC. Similarly, if you are not passing pointers (fPointer = 0) you
33319 : MUST declare the array as type XID (not unsigned long!), or again the wrong
33320 : size data type may be used. To avoid this cruftiness, use dixChangeGC
33323 : if there is an error, the value is marked as changed
33324 : anyway, which is probably wrong, but infrequent.
33327 : all values sent over the protocol for ChangeGC requests are
33331 :DoChangeGC(GC *pGC, BITS32 mask, XID *pval, int fPointer)
33334 : /* XXX might be a problem on 64 bit big-endian servers */
33335 : return dixChangeGC(NullClient, pGC, mask, NULL, (ChangeGCValPtr)pval);
33337 : return dixChangeGC(NullClient, pGC, mask, pval, NULL);
33341 :/* CreateGC(pDrawable, mask, pval, pStatus)
33342 : creates a default GC for the given drawable, using mask to fill
33343 : in any non-default values.
33344 : Returns a pointer to the new GC on success, NULL otherwise.
33345 : returns status of non-default fields in pStatus
33347 : should check for failure to create default tile
33352 :AllocateGC(ScreenPtr pScreen)
33353 :{ /* AllocateGC total: 2 0.0022 */
33361 : pGC = (GCPtr)xalloc(pScreen->totalGCSize);
33364 : ppriv = (DevUnion *)(pGC + 1);
33365 : pGC->devPrivates = ppriv;
33366 : sizes = pScreen->GCPrivateSizes;
33367 : ptr = (char *)(ppriv + pScreen->GCPrivateLen);
33368 : for (i = pScreen->GCPrivateLen; --i >= 0; ppriv++, sizes++)
33370 : if ( (size = *sizes) )
33372 : ppriv->ptr = (pointer)ptr;
33376 1 0.0011 : ppriv->ptr = (pointer)NULL;
33383 :CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus)
33384 :{ /* CreateGC total: 1 0.0011 */
33387 : pGC = AllocateGC(pDrawable->pScreen);
33390 : *pStatus = BadAlloc;
33391 : return (GCPtr)NULL;
33394 : pGC->pScreen = pDrawable->pScreen;
33395 : pGC->depth = pDrawable->depth;
33396 : pGC->alu = GXcopy; /* dst <- src */
33397 : pGC->planemask = ~0;
33398 : pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
33401 : pGC->fgPixel = 0;
33402 : pGC->bgPixel = 1;
33403 : pGC->lineWidth = 0;
33404 : pGC->lineStyle = LineSolid;
33405 : pGC->capStyle = CapButt;
33406 : pGC->joinStyle = JoinMiter;
33407 : pGC->fillStyle = FillSolid;
33408 : pGC->fillRule = EvenOddRule;
33409 : pGC->arcMode = ArcPieSlice;
33410 : if (mask & GCForeground)
33413 : * magic special case -- ChangeGC checks for this condition
33414 : * and snags the Foreground value to create a pseudo default-tile
33416 : pGC->tileIsPixel = FALSE;
33417 : pGC->tile.pixmap = NullPixmap;
33421 : pGC->tileIsPixel = TRUE;
33422 : pGC->tile.pixel = 0;
33425 1 0.0011 : pGC->patOrg.x = 0;
33426 : pGC->patOrg.y = 0;
33427 : pGC->subWindowMode = ClipByChildren;
33428 : pGC->graphicsExposures = TRUE;
33429 : pGC->clipOrg.x = 0;
33430 : pGC->clipOrg.y = 0;
33431 : pGC->clientClipType = CT_NONE;
33432 : pGC->clientClip = (pointer)NULL;
33433 : pGC->numInDashList = 2;
33434 : pGC->dash = DefaultDash;
33435 : pGC->dashOffset = 0;
33436 : pGC->lastWinOrg.x = 0;
33437 : pGC->lastWinOrg.y = 0;
33439 : /* use the default font and stipple */
33440 : pGC->font = defaultFont;
33441 : defaultFont->refcnt++;
33442 : pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
33443 : pGC->stipple->refcnt++;
33445 : pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
33446 : if (!(*pGC->pScreen->CreateGC)(pGC))
33447 : *pStatus = BadAlloc;
33449 : *pStatus = ChangeGC(pGC, mask, pval);
33451 : *pStatus = Success;
33452 : if (*pStatus != Success)
33454 : if (!pGC->tileIsPixel && !pGC->tile.pixmap)
33455 : pGC->tileIsPixel = TRUE; /* undo special case */
33456 : FreeGC(pGC, (XID)0);
33457 : pGC = (GCPtr)NULL;
33464 :CreateDefaultTile (GCPtr pGC)
33468 : GCPtr pgcScratch;
33474 : (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
33475 : pTile = (PixmapPtr)
33476 : (*pGC->pScreen->CreatePixmap)(pGC->pScreen,
33477 : w, h, pGC->depth);
33478 : pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
33479 : if (!pTile || !pgcScratch)
33482 : (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
33484 : FreeScratchGC(pgcScratch);
33487 : tmpval[0] = GXcopy;
33488 : tmpval[1] = pGC->tile.pixel;
33489 : tmpval[2] = FillSolid;
33490 : (void)ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle,
33492 : ValidateGC((DrawablePtr)pTile, pgcScratch);
33497 : (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
33498 : /* Always remember to free the scratch graphics context after use. */
33499 : FreeScratchGC(pgcScratch);
33501 : pGC->tileIsPixel = FALSE;
33502 : pGC->tile.pixmap = pTile;
33507 :CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask)
33513 : if (pgcSrc == pgcDst)
33515 : pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
33516 : pgcDst->stateChanges |= mask;
33520 : index2 = (BITS32) lowbit (mask);
33525 : pgcDst->alu = pgcSrc->alu;
33527 : case GCPlaneMask:
33528 : pgcDst->planemask = pgcSrc->planemask;
33530 : case GCForeground:
33531 : pgcDst->fgPixel = pgcSrc->fgPixel;
33533 : case GCBackground:
33534 : pgcDst->bgPixel = pgcSrc->bgPixel;
33536 : case GCLineWidth:
33537 : pgcDst->lineWidth = pgcSrc->lineWidth;
33539 : case GCLineStyle:
33540 : pgcDst->lineStyle = pgcSrc->lineStyle;
33543 : pgcDst->capStyle = pgcSrc->capStyle;
33545 : case GCJoinStyle:
33546 : pgcDst->joinStyle = pgcSrc->joinStyle;
33548 : case GCFillStyle:
33549 : pgcDst->fillStyle = pgcSrc->fillStyle;
33552 : pgcDst->fillRule = pgcSrc->fillRule;
33556 : if (EqualPixUnion(pgcDst->tileIsPixel,
33558 : pgcSrc->tileIsPixel,
33563 : if (!pgcDst->tileIsPixel)
33564 : (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
33565 : pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
33566 : pgcDst->tile = pgcSrc->tile;
33567 : if (!pgcDst->tileIsPixel)
33568 : pgcDst->tile.pixmap->refcnt++;
33573 : if (pgcDst->stipple == pgcSrc->stipple)
33575 : if (pgcDst->stipple)
33576 : (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
33577 : pgcDst->stipple = pgcSrc->stipple;
33578 : if (pgcDst->stipple)
33579 : pgcDst->stipple->refcnt ++;
33582 : case GCTileStipXOrigin:
33583 : pgcDst->patOrg.x = pgcSrc->patOrg.x;
33585 : case GCTileStipYOrigin:
33586 : pgcDst->patOrg.y = pgcSrc->patOrg.y;
33589 : if (pgcDst->font == pgcSrc->font)
33591 : if (pgcDst->font)
33592 : CloseFont(pgcDst->font, (Font)0);
33593 : if ((pgcDst->font = pgcSrc->font) != NullFont)
33594 : (pgcDst->font)->refcnt++;
33596 : case GCSubwindowMode:
33597 : pgcDst->subWindowMode = pgcSrc->subWindowMode;
33599 : case GCGraphicsExposures:
33600 : pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
33602 : case GCClipXOrigin:
33603 : pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
33605 : case GCClipYOrigin:
33606 : pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
33609 : (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
33611 : case GCDashOffset:
33612 : pgcDst->dashOffset = pgcSrc->dashOffset;
33615 : if (pgcSrc->dash == DefaultDash)
33617 : if (pgcDst->dash != DefaultDash)
33619 : xfree(pgcDst->dash);
33620 : pgcDst->numInDashList = pgcSrc->numInDashList;
33621 : pgcDst->dash = pgcSrc->dash;
33626 : unsigned char *dash;
33629 : dash = (unsigned char *)xalloc(pgcSrc->numInDashList *
33630 : sizeof(unsigned char));
33633 : if (pgcDst->dash != DefaultDash)
33634 : xfree(pgcDst->dash);
33635 : pgcDst->numInDashList = pgcSrc->numInDashList;
33636 : pgcDst->dash = dash;
33637 : for (i=0; i<pgcSrc->numInDashList; i++)
33638 : dash[i] = pgcSrc->dash[i];
33641 : error = BadAlloc;
33645 : pgcDst->arcMode = pgcSrc->arcMode;
33648 : clientErrorValue = maskQ;
33649 : error = BadValue;
33653 : if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
33655 : if (!CreateDefaultTile (pgcDst))
33657 : pgcDst->fillStyle = FillSolid;
33658 : error = BadAlloc;
33661 : (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
33666 : * does the diX part of freeing the characteristics in the GC.
33668 : * \param value must conform to DeleteType
33671 :FreeGC(pointer value, XID gid)
33672 :{ /* FreeGC total: 1 0.0011 */
33673 : GCPtr pGC = (GCPtr)value;
33675 : CloseFont(pGC->font, (Font)0);
33676 : (* pGC->funcs->DestroyClip)(pGC);
33678 : if (!pGC->tileIsPixel)
33679 : (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
33680 : if (pGC->stipple)
33681 : (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
33683 : (*pGC->funcs->DestroyGC) (pGC);
33684 1 0.0011 : if (pGC->dash != DefaultDash)
33685 : xfree(pGC->dash);
33690 :/* CreateScratchGC(pScreen, depth)
33691 : like CreateGC, but doesn't do the default tile or stipple,
33692 :since we can't create them without already having a GC. any code
33693 :using the tile or stipple has to set them explicitly anyway,
33694 :since the state of the scratch gc is unknown. This is OK
33695 :because ChangeGC() has to be able to deal with NULL tiles and
33696 :stipples anyway (in case the CreateGC() call has provided a
33697 :value for them -- we can't set the default tile until the
33698 :client-supplied attributes are installed, since the fgPixel
33699 :is what fills the default tile. (maybe this comment should
33700 :go with CreateGC() or ChangeGC().)
33704 :CreateScratchGC(ScreenPtr pScreen, unsigned depth)
33708 : pGC = AllocateGC(pScreen);
33710 : return (GCPtr)NULL;
33712 : pGC->pScreen = pScreen;
33713 : pGC->depth = depth;
33714 : pGC->alu = GXcopy; /* dst <- src */
33715 : pGC->planemask = ~0;
33716 : pGC->serialNumber = 0;
33718 : pGC->fgPixel = 0;
33719 : pGC->bgPixel = 1;
33720 : pGC->lineWidth = 0;
33721 : pGC->lineStyle = LineSolid;
33722 : pGC->capStyle = CapButt;
33723 : pGC->joinStyle = JoinMiter;
33724 : pGC->fillStyle = FillSolid;
33725 : pGC->fillRule = EvenOddRule;
33726 : pGC->arcMode = ArcPieSlice;
33727 : pGC->font = defaultFont;
33728 : if ( pGC->font) /* necessary, because open of default font could fail */
33729 : pGC->font->refcnt++;
33730 : pGC->tileIsPixel = TRUE;
33731 : pGC->tile.pixel = 0;
33732 : pGC->stipple = NullPixmap;
33733 : pGC->patOrg.x = 0;
33734 : pGC->patOrg.y = 0;
33735 : pGC->subWindowMode = ClipByChildren;
33736 : pGC->graphicsExposures = TRUE;
33737 : pGC->clipOrg.x = 0;
33738 : pGC->clipOrg.y = 0;
33739 : pGC->clientClipType = CT_NONE;
33740 : pGC->dashOffset = 0;
33741 : pGC->numInDashList = 2;
33742 : pGC->dash = DefaultDash;
33743 : pGC->lastWinOrg.x = 0;
33744 : pGC->lastWinOrg.y = 0;
33746 : pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
33747 : if (!(*pScreen->CreateGC)(pGC))
33749 : FreeGC(pGC, (XID)0);
33750 : pGC = (GCPtr)NULL;
33756 :FreeGCperDepth(int screenNum)
33759 : ScreenPtr pScreen;
33762 : pScreen = screenInfo.screens[screenNum];
33763 : ppGC = pScreen->GCperDepth;
33765 : for (i = 0; i <= pScreen->numDepths; i++)
33766 : (void)FreeGC(ppGC[i], (XID)0);
33767 : pScreen->rgf = ~0L;
33772 :CreateGCperDepth(int screenNum)
33775 : ScreenPtr pScreen;
33779 : pScreen = screenInfo.screens[screenNum];
33780 : pScreen->rgf = 0;
33781 : ppGC = pScreen->GCperDepth;
33782 : /* do depth 1 separately because it's not included in list */
33783 : if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
33785 : ppGC[0]->graphicsExposures = FALSE;
33786 : /* Make sure we don't overflow GCperDepth[] */
33787 : if( pScreen->numDepths > MAXFORMATS )
33790 : pDepth = pScreen->allowedDepths;
33791 : for (i=0; i<pScreen->numDepths; i++, pDepth++)
33793 : if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
33795 : for (; i >= 0; i--)
33796 : (void)FreeGC(ppGC[i], (XID)0);
33799 : ppGC[i+1]->graphicsExposures = FALSE;
33805 :CreateDefaultStipple(int screenNum)
33807 : ScreenPtr pScreen;
33811 : GCPtr pgcScratch;
33813 : pScreen = screenInfo.screens[screenNum];
33817 : (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
33818 : if (!(pScreen->PixmapPerDepth[0] =
33819 : (*pScreen->CreatePixmap)(pScreen, w, h, 1)))
33821 : /* fill stipple with 1 */
33822 : tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
33823 : pgcScratch = GetScratchGC(1, pScreen);
33826 : (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
33829 : (void)ChangeGC(pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
33830 : ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
33835 : (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
33836 : pgcScratch, 1, &rect);
33837 : FreeScratchGC(pgcScratch);
33842 :FreeDefaultStipple(int screenNum)
33844 : ScreenPtr pScreen = screenInfo.screens[screenNum];
33845 : (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
33849 :SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
33852 : unsigned char *p, *indash;
33853 : BITS32 maskQ = 0;
33861 : /* dash segment must be > 0 */
33862 : clientErrorValue = 0;
33868 : p = (unsigned char *)xalloc(2 * ndash * sizeof(unsigned char));
33870 : p = (unsigned char *)xalloc(ndash * sizeof(unsigned char));
33874 : pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
33875 : if (offset != pGC->dashOffset)
33877 : pGC->dashOffset = offset;
33878 : pGC->stateChanges |= GCDashOffset;
33879 : maskQ |= GCDashOffset;
33882 : if (pGC->dash != DefaultDash)
33883 : xfree(pGC->dash);
33884 : pGC->numInDashList = ndash;
33888 : pGC->numInDashList += ndash;
33892 : *p++ = *indash++;
33896 : pGC->stateChanges |= GCDashList;
33897 : maskQ |= GCDashList;
33899 : if (pGC->funcs->ChangeGC)
33900 : (*pGC->funcs->ChangeGC) (pGC, maskQ);
33905 :VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
33906 :{ /* VerifyRectOrder total: 1 0.0011 */
33907 : xRectangle *prectP, *prectN;
33913 : return CT_UNSORTED;
33917 : for(i = 1, prectP = prects, prectN = prects + 1;
33919 : i++, prectP++, prectN++)
33920 : if(prectN->y < prectP->y)
33923 : return CT_YSORTED;
33927 : for(i = 1, prectP = prects, prectN = prects + 1;
33929 : i++, prectP++, prectN++)
33930 : if((prectN->y < prectP->y) ||
33931 : ( (prectN->y == prectP->y) &&
33932 : (prectN->x < prectP->x) ) )
33935 : return CT_YXSORTED;
33937 1 0.0011 : if(nrects > 1)
33939 : for(i = 1, prectP = prects, prectN = prects + 1;
33941 : i++, prectP++, prectN++)
33942 : if((prectN->y != prectP->y &&
33943 : prectN->y < prectP->y + (int) prectP->height) ||
33944 : ((prectN->y == prectP->y) &&
33945 : (prectN->height != prectP->height ||
33946 : prectN->x < prectP->x + (int) prectP->width)))
33949 : return CT_YXBANDED;
33955 :SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
33956 : xRectangle *prects, int ordering)
33957 :{ /* SetClipRects total: 2 0.0022 */
33959 : xRectangle *prectsNew;
33961 : newct = VerifyRectOrder(nrects, prects, ordering);
33963 : return(BadMatch);
33964 : size = nrects * sizeof(xRectangle);
33965 : prectsNew = (xRectangle *) xalloc(size);
33966 : if (!prectsNew && size)
33969 : pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
33970 1 0.0011 : pGC->clipOrg.x = xOrigin;
33971 : pGC->stateChanges |= GCClipXOrigin;
33973 : pGC->clipOrg.y = yOrigin;
33974 : pGC->stateChanges |= GCClipYOrigin;
33977 : memmove((char *)prectsNew, (char *)prects, size);
33978 : (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects);
33979 1 0.0011 : if (pGC->funcs->ChangeGC)
33980 : (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
33986 : sets reasonable defaults
33987 : if we can get a pre-allocated one, use it and mark it as used.
33988 : if we can't, create one out of whole cloth (The Velveteen GC -- if
33989 : you use it often enough it will become real.)
33992 :GetScratchGC(unsigned depth, ScreenPtr pScreen)
33993 2 0.0022 :{ /* GetScratchGC total: 8 0.0087 */
33997 : for (i=0; i<=pScreen->numDepths; i++)
33998 2 0.0022 : if ( pScreen->GCperDepth[i]->depth == depth &&
33999 : !(pScreen->rgf & (1L << (i+1)))
34002 : pScreen->rgf |= (1L << (i+1));
34003 : pGC = (pScreen->GCperDepth[i]);
34005 : pGC->alu = GXcopy;
34006 : pGC->planemask = ~0;
34007 : pGC->serialNumber = 0;
34008 : pGC->fgPixel = 0;
34009 : pGC->bgPixel = 1;
34010 : pGC->lineWidth = 0;
34011 : pGC->lineStyle = LineSolid;
34012 : pGC->capStyle = CapButt;
34013 : pGC->joinStyle = JoinMiter;
34014 : pGC->fillStyle = FillSolid;
34015 : pGC->fillRule = EvenOddRule;
34016 : pGC->arcMode = ArcChord;
34017 3 0.0033 : pGC->patOrg.x = 0;
34018 : pGC->patOrg.y = 0;
34019 : pGC->subWindowMode = ClipByChildren;
34020 : pGC->graphicsExposures = FALSE;
34021 : pGC->clipOrg.x = 0;
34022 : pGC->clipOrg.y = 0;
34023 : if (pGC->clientClipType != CT_NONE)
34024 : (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
34025 : pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
34028 : /* if we make it this far, need to roll our own */
34029 : pGC = CreateScratchGC(pScreen, depth);
34031 : pGC->graphicsExposures = FALSE;
34036 : if the gc to free is in the table of pre-existing ones,
34037 :mark it as available.
34038 : if not, free it for real
34041 :FreeScratchGC(GCPtr pGC)
34042 4 0.0044 :{ /* FreeScratchGC total: 10 0.0109 */
34043 : ScreenPtr pScreen = pGC->pScreen;
34046 1 0.0011 : for (i=0; i<=pScreen->numDepths; i++)
34048 3 0.0033 : if ( pScreen->GCperDepth[i] == pGC)
34050 : pScreen->rgf &= ~(1L << (i+1));
34054 : (void)FreeGC(pGC, (GContext)0);
34057 * Total samples for file : "/home/cworth/src/xorg/xserver/Xext/security.c"
34065 :Copyright 1996, 1998 The Open Group
34067 :Permission to use, copy, modify, distribute, and sell this software and its
34068 :documentation for any purpose is hereby granted without fee, provided that
34069 :the above copyright notice appear in all copies and that both that
34070 :copyright notice and this permission notice appear in supporting
34073 :The above copyright notice and this permission notice shall be included in
34074 :all copies or substantial portions of the Software.
34076 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34077 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34078 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34079 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
34080 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34081 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34083 :Except as contained in this notice, the name of The Open Group shall not be
34084 :used in advertising or otherwise to promote the sale, use or other dealings
34085 :in this Software without prior written authorization from The Open Group.
34089 :#ifdef HAVE_DIX_CONFIG_H
34090 :#include <dix-config.h>
34093 :#include "dixstruct.h"
34094 :#include "extnsionst.h"
34095 :#include "windowstr.h"
34096 :#include "inputstr.h"
34097 :#include "scrnintstr.h"
34098 :#include "gcstruct.h"
34099 :#include "colormapst.h"
34100 :#include "propertyst.h"
34101 :#include "xacestr.h"
34102 :#include "securitysrv.h"
34103 :#include <X11/extensions/securstr.h>
34104 :#include <assert.h>
34105 :#include <stdarg.h>
34107 :#include "appgroup.h"
34109 :#include <stdio.h> /* for file reading operations */
34110 :#include <X11/Xatom.h> /* for XA_STRING */
34112 :#ifndef DEFAULTPOLICYFILE
34113 :# define DEFAULTPOLICYFILE NULL
34115 :#if defined(WIN32) || defined(__CYGWIN__)
34116 :#include <X11/Xos.h>
34120 :#include "modinit.h"
34122 :static int SecurityErrorBase; /* first Security error number */
34123 :static int SecurityEventBase; /* first Security event number */
34124 :static int securityClientPrivateIndex;
34125 :static int securityExtnsnPrivateIndex;
34127 :/* this is what we store as client security state */
34129 : unsigned int trustLevel;
34131 :} SecurityClientStateRec;
34133 :#define STATEVAL(extnsn) \
34134 : ((extnsn)->devPrivates[securityExtnsnPrivateIndex].val)
34135 :#define STATEPTR(client) \
34136 : ((client)->devPrivates[securityClientPrivateIndex].ptr)
34137 :#define TRUSTLEVEL(client) \
34138 : (((SecurityClientStateRec*)STATEPTR(client))->trustLevel)
34139 :#define AUTHID(client) \
34140 : (((SecurityClientStateRec*)STATEPTR(client))->authId)
34142 :static CallbackListPtr SecurityValidateGroupCallback = NULL;
34144 :RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */
34146 :static RESTYPE RTEventClient;
34148 :#define CALLBACK(name) static void \
34149 :name(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
34154 : * format is the formatting string to be used to interpret the
34155 : * remaining arguments.
34157 : * Returns: nothing.
34160 : * Writes the message to the log file if security logging is on.
34164 :SecurityAudit(char *format, ...)
34168 : if (auditTrailLevel < SECURITY_AUDIT_LEVEL)
34170 : va_start(args, format);
34171 : VAuditF(format, args);
34173 :} /* SecurityAudit */
34175 :#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
34177 :/* SecurityDeleteAuthorization
34180 : * value is the authorization to delete.
34181 : * id is its resource ID.
34183 : * Returns: Success.
34186 : * Frees everything associated with the authorization.
34190 :SecurityDeleteAuthorization(
34194 : SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
34195 : unsigned short name_len, data_len;
34196 : char *name, *data;
34199 : OtherClientsPtr pEventClient;
34201 : /* Remove the auth using the os layer auth manager */
34203 : status = AuthorizationFromID(pAuth->id, &name_len, &name,
34204 : &data_len, &data);
34206 : status = RemoveAuthorization(name_len, name, data_len, data);
34210 : /* free the auth timer if there is one */
34212 : if (pAuth->timer) TimerFree(pAuth->timer);
34214 : /* send revoke events */
34216 : while ((pEventClient = pAuth->eventClients))
34218 : /* send revocation event event */
34219 : ClientPtr client = rClient(pEventClient);
34221 : if (!client->clientGone)
34223 : xSecurityAuthorizationRevokedEvent are;
34224 : are.type = SecurityEventBase + XSecurityAuthorizationRevoked;
34225 : are.sequenceNumber = client->sequence;
34226 : are.authId = pAuth->id;
34227 : WriteEventsToClient(client, 1, (xEvent *)&are);
34229 : FreeResource(pEventClient->resource, RT_NONE);
34232 : /* kill all clients using this auth */
34234 : for (i = 1; i<currentMaxClients; i++)
34236 : if (clients[i] && (AUTHID(clients[i]) == pAuth->id))
34237 : CloseDownClient(clients[i]);
34240 : SecurityAudit("revoked authorization ID %d\n", pAuth->id);
34244 :} /* SecurityDeleteAuthorization */
34247 :/* resource delete function for RTEventClient */
34249 :SecurityDeleteAuthorizationEventClient(
34253 : OtherClientsPtr pEventClient, prev = NULL;
34254 : SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
34256 : for (pEventClient = pAuth->eventClients;
34258 : pEventClient = pEventClient->next)
34260 : if (pEventClient->resource == id)
34263 : prev->next = pEventClient->next;
34265 : pAuth->eventClients = pEventClient->next;
34266 : xfree(pEventClient);
34269 : prev = pEventClient;
34272 : return -1; /* make compiler happy */
34273 :} /* SecurityDeleteAuthorizationEventClient */
34276 :/* SecurityComputeAuthorizationTimeout
34279 : * pAuth is the authorization for which we are computing the timeout
34280 : * seconds is the number of seconds we want to wait
34283 : * the number of milliseconds that the auth timer should be set to
34286 : * Sets pAuth->secondsRemaining to any "overflow" amount of time
34287 : * that didn't fit in 32 bits worth of milliseconds
34291 :SecurityComputeAuthorizationTimeout(
34292 : SecurityAuthorizationPtr pAuth,
34293 : unsigned int seconds)
34295 : /* maxSecs is the number of full seconds that can be expressed in
34296 : * 32 bits worth of milliseconds
34298 : CARD32 maxSecs = (CARD32)(~0) / (CARD32)MILLI_PER_SECOND;
34300 : if (seconds > maxSecs)
34301 : { /* only come here if we want to wait more than 49 days */
34302 : pAuth->secondsRemaining = seconds - maxSecs;
34303 : return maxSecs * MILLI_PER_SECOND;
34306 : { /* by far the common case */
34307 : pAuth->secondsRemaining = 0;
34308 : return seconds * MILLI_PER_SECOND;
34310 :} /* SecurityStartAuthorizationTimer */
34312 :/* SecurityAuthorizationExpired
34314 : * This function is passed as an argument to TimerSet and gets called from
34315 : * the timer manager in the os layer when its time is up.
34318 : * timer is the timer for this authorization.
34319 : * time is the current time.
34320 : * pval is the authorization whose time is up.
34323 : * A new time delay in milliseconds if the timer should wait some
34324 : * more, else zero.
34327 : * Frees the authorization resource if the timeout period is really
34328 : * over, otherwise recomputes pAuth->secondsRemaining.
34332 :SecurityAuthorizationExpired(
34333 : OsTimerPtr timer,
34337 : SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)pval;
34339 : assert(pAuth->timer == timer);
34341 : if (pAuth->secondsRemaining)
34343 : return SecurityComputeAuthorizationTimeout(pAuth,
34344 : pAuth->secondsRemaining);
34348 : FreeResource(pAuth->id, RT_NONE);
34351 :} /* SecurityAuthorizationExpired */
34353 :/* SecurityStartAuthorizationTimer
34356 : * pAuth is the authorization whose timer should be started.
34358 : * Returns: nothing.
34361 : * A timer is started, set to expire after the timeout period for
34362 : * this authorization. When it expires, the function
34363 : * SecurityAuthorizationExpired will be called.
34367 :SecurityStartAuthorizationTimer(
34368 : SecurityAuthorizationPtr pAuth)
34370 : pAuth->timer = TimerSet(pAuth->timer, 0,
34371 : SecurityComputeAuthorizationTimeout(pAuth, pAuth->timeout),
34372 : SecurityAuthorizationExpired, pAuth);
34373 :} /* SecurityStartAuthorizationTimer */
34376 :/* Proc functions all take a client argument, execute the request in
34377 : * client->requestBuffer, and return a protocol error status.
34381 :ProcSecurityQueryVersion(
34382 : ClientPtr client)
34384 : /* REQUEST(xSecurityQueryVersionReq); */
34385 : xSecurityQueryVersionReply rep;
34387 : /* paranoia: this "can't happen" because this extension is hidden
34388 : * from untrusted clients, but just in case...
34390 : if (TRUSTLEVEL(client) != XSecurityClientTrusted)
34391 : return BadRequest;
34393 : REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
34394 : rep.type = X_Reply;
34395 : rep.sequenceNumber = client->sequence;
34397 : rep.majorVersion = SECURITY_MAJOR_VERSION;
34398 : rep.minorVersion = SECURITY_MINOR_VERSION;
34399 : if(client->swapped)
34402 : swaps(&rep.sequenceNumber, n);
34403 : swaps(&rep.majorVersion, n);
34404 : swaps(&rep.minorVersion, n);
34406 : (void)WriteToClient(client, SIZEOF(xSecurityQueryVersionReply),
34408 : return (client->noClientException);
34409 :} /* ProcSecurityQueryVersion */
34413 :SecurityEventSelectForAuthorization(
34414 : SecurityAuthorizationPtr pAuth,
34415 : ClientPtr client,
34418 : OtherClients *pEventClient;
34420 : for (pEventClient = pAuth->eventClients;
34422 : pEventClient = pEventClient->next)
34424 : if (SameClient(pEventClient, client))
34427 : FreeResource(pEventClient->resource, RT_NONE);
34429 : pEventClient->mask = mask;
34434 : pEventClient = (OtherClients *) xalloc(sizeof(OtherClients));
34435 : if (!pEventClient)
34437 : pEventClient->mask = mask;
34438 : pEventClient->resource = FakeClientID(client->index);
34439 : pEventClient->next = pAuth->eventClients;
34440 : if (!AddResource(pEventClient->resource, RTEventClient,
34443 : xfree(pEventClient);
34446 : pAuth->eventClients = pEventClient;
34449 :} /* SecurityEventSelectForAuthorization */
34453 :ProcSecurityGenerateAuthorization(
34454 : ClientPtr client)
34456 : REQUEST(xSecurityGenerateAuthorizationReq);
34457 : int len; /* request length in CARD32s*/
34458 : Bool removeAuth = FALSE; /* if bailout, call RemoveAuthorization? */
34459 : SecurityAuthorizationPtr pAuth = NULL; /* auth we are creating */
34460 : int err; /* error to return from this function */
34461 : XID authId; /* authorization ID assigned by os layer */
34462 : xSecurityGenerateAuthorizationReply rep; /* reply struct */
34463 : unsigned int trustLevel; /* trust level of new auth */
34464 : XID group; /* group of new auth */
34465 : CARD32 timeout; /* timeout of new auth */
34466 : CARD32 *values; /* list of supplied attributes */
34467 : char *protoname; /* auth proto name sent in request */
34468 : char *protodata; /* auth proto data sent in request */
34469 : unsigned int authdata_len; /* # bytes of generated auth data */
34470 : char *pAuthdata; /* generated auth data */
34471 : Mask eventMask; /* what events on this auth does client want */
34473 : /* paranoia: this "can't happen" because this extension is hidden
34474 : * from untrusted clients, but just in case...
34476 : if (TRUSTLEVEL(client) != XSecurityClientTrusted)
34477 : return BadRequest;
34479 : /* check request length */
34481 : REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
34482 : len = SIZEOF(xSecurityGenerateAuthorizationReq) >> 2;
34483 : len += (stuff->nbytesAuthProto + (unsigned)3) >> 2;
34484 : len += (stuff->nbytesAuthData + (unsigned)3) >> 2;
34485 : values = ((CARD32 *)stuff) + len;
34486 : len += Ones(stuff->valueMask);
34487 : if (client->req_len != len)
34488 : return BadLength;
34490 : /* check valuemask */
34491 : if (stuff->valueMask & ~XSecurityAllAuthorizationAttributes)
34493 : client->errorValue = stuff->valueMask;
34497 : /* check timeout */
34499 : if (stuff->valueMask & XSecurityTimeout)
34501 : timeout = *values++;
34504 : /* check trustLevel */
34505 : trustLevel = XSecurityClientUntrusted;
34506 : if (stuff->valueMask & XSecurityTrustLevel)
34508 : trustLevel = *values++;
34509 : if (trustLevel != XSecurityClientTrusted &&
34510 : trustLevel != XSecurityClientUntrusted)
34512 : client->errorValue = trustLevel;
34517 : /* check group */
34519 : if (stuff->valueMask & XSecurityGroup)
34521 : group = *values++;
34522 : if (SecurityValidateGroupCallback)
34524 : SecurityValidateGroupInfoRec vgi;
34525 : vgi.group = group;
34526 : vgi.valid = FALSE;
34527 : CallCallbacks(&SecurityValidateGroupCallback, (pointer)&vgi);
34529 : /* if nobody said they recognized it, it's an error */
34533 : client->errorValue = group;
34539 : /* check event mask */
34541 : if (stuff->valueMask & XSecurityEventMask)
34543 : eventMask = *values++;
34544 : if (eventMask & ~XSecurityAllEventMasks)
34546 : client->errorValue = eventMask;
34551 : protoname = (char *)&stuff[1];
34552 : protodata = protoname + ((stuff->nbytesAuthProto + (unsigned)3) >> 2);
34554 : /* call os layer to generate the authorization */
34556 : authId = GenerateAuthorization(stuff->nbytesAuthProto, protoname,
34557 : stuff->nbytesAuthData, protodata,
34558 : &authdata_len, &pAuthdata);
34559 : if ((XID) ~0L == authId)
34561 : err = SecurityErrorBase + XSecurityBadAuthorizationProtocol;
34565 : /* now that we've added the auth, remember to remove it if we have to
34566 : * abort the request for some reason (like allocation failure)
34568 : removeAuth = TRUE;
34570 : /* associate additional information with this auth ID */
34572 : pAuth = (SecurityAuthorizationPtr)xalloc(sizeof(SecurityAuthorizationRec));
34579 : /* fill in the auth fields */
34581 : pAuth->id = authId;
34582 : pAuth->timeout = timeout;
34583 : pAuth->group = group;
34584 : pAuth->trustLevel = trustLevel;
34585 : pAuth->refcnt = 0; /* the auth was just created; nobody's using it yet */
34586 : pAuth->secondsRemaining = 0;
34587 : pAuth->timer = NULL;
34588 : pAuth->eventClients = NULL;
34590 : /* handle event selection */
34593 : err = SecurityEventSelectForAuthorization(pAuth, client, eventMask);
34594 : if (err != Success)
34598 : if (!AddResource(authId, SecurityAuthorizationResType, pAuth))
34604 : /* start the timer ticking */
34606 : if (pAuth->timeout != 0)
34607 : SecurityStartAuthorizationTimer(pAuth);
34609 : /* tell client the auth id and data */
34611 : rep.type = X_Reply;
34612 : rep.length = (authdata_len + 3) >> 2;
34613 : rep.sequenceNumber = client->sequence;
34614 : rep.authId = authId;
34615 : rep.dataLength = authdata_len;
34617 : if (client->swapped)
34620 : swapl(&rep.length, n);
34621 : swaps(&rep.sequenceNumber, n);
34622 : swapl(&rep.authId, n);
34623 : swaps(&rep.dataLength, n);
34626 : WriteToClient(client, SIZEOF(xSecurityGenerateAuthorizationReply),
34628 : WriteToClient(client, authdata_len, pAuthdata);
34630 : SecurityAudit("client %d generated authorization %d trust %d timeout %d group %d events %d\n",
34631 : client->index, pAuth->id, pAuth->trustLevel, pAuth->timeout,
34632 : pAuth->group, eventMask);
34634 : /* the request succeeded; don't call RemoveAuthorization or free pAuth */
34636 : removeAuth = FALSE;
34638 : err = client->noClientException;
34642 : RemoveAuthorization(stuff->nbytesAuthProto, protoname,
34643 : authdata_len, pAuthdata);
34644 : if (pAuth) xfree(pAuth);
34647 :} /* ProcSecurityGenerateAuthorization */
34650 :ProcSecurityRevokeAuthorization(
34651 : ClientPtr client)
34653 : REQUEST(xSecurityRevokeAuthorizationReq);
34654 : SecurityAuthorizationPtr pAuth;
34656 : /* paranoia: this "can't happen" because this extension is hidden
34657 : * from untrusted clients, but just in case...
34659 : if (TRUSTLEVEL(client) != XSecurityClientTrusted)
34660 : return BadRequest;
34662 : REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
34664 : pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(client,
34665 : stuff->authId, SecurityAuthorizationResType, DixDestroyAccess);
34667 : return SecurityErrorBase + XSecurityBadAuthorization;
34669 : FreeResource(stuff->authId, RT_NONE);
34671 :} /* ProcSecurityRevokeAuthorization */
34675 :ProcSecurityDispatch(
34676 : ClientPtr client)
34680 : switch (stuff->data)
34682 : case X_SecurityQueryVersion:
34683 : return ProcSecurityQueryVersion(client);
34684 : case X_SecurityGenerateAuthorization:
34685 : return ProcSecurityGenerateAuthorization(client);
34686 : case X_SecurityRevokeAuthorization:
34687 : return ProcSecurityRevokeAuthorization(client);
34689 : return BadRequest;
34691 :} /* ProcSecurityDispatch */
34694 :SProcSecurityQueryVersion(
34695 : ClientPtr client)
34697 : REQUEST(xSecurityQueryVersionReq);
34700 : swaps(&stuff->length, n);
34701 : REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
34702 : swaps(&stuff->majorVersion, n);
34703 : swaps(&stuff->minorVersion,n);
34704 : return ProcSecurityQueryVersion(client);
34705 :} /* SProcSecurityQueryVersion */
34709 :SProcSecurityGenerateAuthorization(
34710 : ClientPtr client)
34712 : REQUEST(xSecurityGenerateAuthorizationReq);
34715 : unsigned long nvalues;
34717 : swaps(&stuff->length, n);
34718 : REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
34719 : swaps(&stuff->nbytesAuthProto, n);
34720 : swaps(&stuff->nbytesAuthData, n);
34721 : swapl(&stuff->valueMask, n);
34722 : values = (CARD32 *)(&stuff[1]) +
34723 : ((stuff->nbytesAuthProto + (unsigned)3) >> 2) +
34724 : ((stuff->nbytesAuthData + (unsigned)3) >> 2);
34725 : nvalues = (((CARD32 *)stuff) + stuff->length) - values;
34726 : SwapLongs(values, nvalues);
34727 : return ProcSecurityGenerateAuthorization(client);
34728 :} /* SProcSecurityGenerateAuthorization */
34732 :SProcSecurityRevokeAuthorization(
34733 : ClientPtr client)
34735 : REQUEST(xSecurityRevokeAuthorizationReq);
34738 : swaps(&stuff->length, n);
34739 : REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
34740 : swapl(&stuff->authId, n);
34741 : return ProcSecurityRevokeAuthorization(client);
34742 :} /* SProcSecurityRevokeAuthorization */
34746 :SProcSecurityDispatch(
34747 : ClientPtr client)
34751 : switch (stuff->data)
34753 : case X_SecurityQueryVersion:
34754 : return SProcSecurityQueryVersion(client);
34755 : case X_SecurityGenerateAuthorization:
34756 : return SProcSecurityGenerateAuthorization(client);
34757 : case X_SecurityRevokeAuthorization:
34758 : return SProcSecurityRevokeAuthorization(client);
34760 : return BadRequest;
34762 :} /* SProcSecurityDispatch */
34765 :SwapSecurityAuthorizationRevokedEvent(
34766 : xSecurityAuthorizationRevokedEvent *from,
34767 : xSecurityAuthorizationRevokedEvent *to)
34769 : to->type = from->type;
34770 : to->detail = from->detail;
34771 : cpswaps(from->sequenceNumber, to->sequenceNumber);
34772 : cpswapl(from->authId, to->authId);
34775 :/* SecurityDetermineEventPropogationLimits
34777 : * This is a helper function for SecurityCheckDeviceAccess.
34780 : * dev is the device for which the starting and stopping windows for
34781 : * event propogation should be determined.
34782 : * The values pointed to by ppWin and ppStopWin are not used.
34785 : * ppWin is filled in with a pointer to the window at which event
34786 : * propogation for the given device should start given the current
34787 : * state of the server (pointer position, window layout, etc.)
34788 : * ppStopWin is filled in with the window at which event propogation
34789 : * should stop; events should not go to ppStopWin.
34791 : * Side Effects: none.
34795 :SecurityDetermineEventPropogationLimits(
34796 : DeviceIntPtr dev,
34797 : WindowPtr *ppWin,
34798 : WindowPtr *ppStopWin)
34800 : WindowPtr pFocusWin = dev->focus ? dev->focus->win : NoneWin;
34802 : if (pFocusWin == NoneWin)
34803 : { /* no focus -- events don't go anywhere */
34804 : *ppWin = *ppStopWin = NULL;
34808 : if (pFocusWin == PointerRootWin)
34809 : { /* focus follows the pointer */
34810 : *ppWin = GetSpriteWindow();
34811 : *ppStopWin = NULL; /* propogate all the way to the root */
34814 : { /* a real window is set for the focus */
34815 : WindowPtr pSpriteWin = GetSpriteWindow();
34816 : *ppStopWin = pFocusWin->parent; /* don't go past the focus window */
34818 : /* if the pointer is in a subwindow of the focus window, start
34819 : * at that subwindow, else start at the focus window itself
34821 : if (IsParent(pFocusWin, pSpriteWin))
34822 : *ppWin = pSpriteWin;
34823 : else *ppWin = pFocusWin;
34825 :} /* SecurityDetermineEventPropogationLimits */
34828 :/* SecurityCheckDeviceAccess
34831 : * client is the client attempting to access a device.
34832 : * dev is the device being accessed.
34833 : * fromRequest is TRUE if the device access is a direct result of
34834 : * the client executing some request and FALSE if it is a
34835 : * result of the server trying to send an event (e.g. KeymapNotify)
34838 : * TRUE if the device access should be allowed, else FALSE.
34841 : * An audit message is generated if access is denied.
34844 :CALLBACK(SecurityCheckDeviceAccess)
34846 : XaceDeviceAccessRec *rec = (XaceDeviceAccessRec*)calldata;
34847 : ClientPtr client = rec->client;
34848 : DeviceIntPtr dev = rec->dev;
34849 : Bool fromRequest = rec->fromRequest;
34850 : WindowPtr pWin, pStopWin;
34851 : Bool untrusted_got_event;
34852 : Bool found_event_window;
34856 : /* trusted clients always allowed to do anything */
34857 : if (TRUSTLEVEL(client) == XSecurityClientTrusted)
34860 : /* device security other than keyboard is not implemented yet */
34861 : if (dev != inputInfo.keyboard)
34864 : /* some untrusted client wants access */
34868 : reqtype = ((xReq *)client->requestBuffer)->reqType;
34871 : /* never allow these */
34872 : case X_ChangeKeyboardMapping:
34873 : case X_ChangeKeyboardControl:
34874 : case X_SetModifierMapping:
34875 : SecurityAudit("client %d attempted request %d\n",
34876 : client->index, reqtype);
34877 : rec->rval = FALSE;
34884 : untrusted_got_event = FALSE;
34885 : found_event_window = FALSE;
34889 : untrusted_got_event =
34890 : (TRUSTLEVEL(rClient(dev->grab)) != XSecurityClientTrusted);
34894 : SecurityDetermineEventPropogationLimits(dev, &pWin, &pStopWin);
34896 : eventmask = KeyPressMask | KeyReleaseMask;
34897 : while ( (pWin != pStopWin) && !found_event_window)
34899 : OtherClients *other;
34901 : if (pWin->eventMask & eventmask)
34903 : found_event_window = TRUE;
34904 : client = wClient(pWin);
34905 : if (TRUSTLEVEL(client) != XSecurityClientTrusted)
34907 : untrusted_got_event = TRUE;
34910 : if (wOtherEventMasks(pWin) & eventmask)
34912 : found_event_window = TRUE;
34913 : for (other = wOtherClients(pWin); other; other = other->next)
34915 : if (other->mask & eventmask)
34917 : client = rClient(other);
34918 : if (TRUSTLEVEL(client) != XSecurityClientTrusted)
34920 : untrusted_got_event = TRUE;
34926 : if (wDontPropagateMask(pWin) & eventmask)
34928 : pWin = pWin->parent;
34929 : } /* while propogating the event */
34932 : /* allow access by untrusted clients only if an event would have gone
34933 : * to an untrusted client
34936 : if (!untrusted_got_event)
34938 : char *devname = dev->name;
34939 : if (!devname) devname = "unnamed";
34941 : SecurityAudit("client %d attempted request %d device %d (%s)\n",
34942 : client->index, reqtype, dev->id, devname);
34944 : SecurityAudit("client %d attempted to access device %d (%s)\n",
34945 : client->index, dev->id, devname);
34946 : rec->rval = FALSE;
34949 :} /* SecurityCheckDeviceAccess */
34953 :/* SecurityAuditResourceIDAccess
34956 : * client is the client doing the resource access.
34957 : * id is the resource id.
34962 : * An audit message is generated with details of the denied
34963 : * resource access.
34967 :SecurityAuditResourceIDAccess(
34968 : ClientPtr client,
34971 : int cid = CLIENT_ID(id);
34972 : int reqtype = ((xReq *)client->requestBuffer)->reqType;
34975 : case X_ChangeProperty:
34976 : case X_DeleteProperty:
34977 : case X_GetProperty:
34979 : xChangePropertyReq *req =
34980 : (xChangePropertyReq *)client->requestBuffer;
34981 : int propertyatom = req->property;
34982 : char *propertyname = NameForAtom(propertyatom);
34984 : SecurityAudit("client %d attempted request %d with window 0x%x property %s of client %d\n",
34985 : client->index, reqtype, id, propertyname, cid);
34990 : SecurityAudit("client %d attempted request %d with resource 0x%x of client %d\n",
34991 : client->index, reqtype, id, cid);
34996 :} /* SecurityAuditResourceIDAccess */
34999 :/* SecurityCheckResourceIDAccess
35001 : * This function gets plugged into client->CheckAccess and is called from
35002 : * SecurityLookupIDByType/Class to determine if the client can access the
35006 : * client is the client doing the resource access.
35007 : * id is the resource id.
35008 : * rtype is its type or class.
35009 : * access_mode represents the intended use of the resource; see
35011 : * res is a pointer to the resource structure for this resource.
35014 : * If access is granted, the value of rval that was passed in, else FALSE.
35017 : * Disallowed resource accesses are audited.
35020 :CALLBACK(SecurityCheckResourceIDAccess)
35021 8 0.0087 :{ /* SecurityCheckResourceIDAccess total: 36 0.0392 */
35022 : XaceResourceAccessRec *rec = (XaceResourceAccessRec*)calldata;
35023 : ClientPtr client = rec->client;
35024 1 0.0011 : XID id = rec->id;
35025 3 0.0033 : RESTYPE rtype = rec->rtype;
35026 : Mask access_mode = rec->access_mode;
35027 : pointer rval = rec->res;
35028 : int cid, reqtype;
35030 22 0.0240 : if (TRUSTLEVEL(client) == XSecurityClientTrusted ||
35031 : DixUnknownAccess == access_mode)
35032 : return; /* for compatibility, we have to allow access */
35034 : cid = CLIENT_ID(id);
35035 : reqtype = ((xReq *)client->requestBuffer)->reqType;
35037 : { /* these are always allowed */
35038 : case X_QueryTree:
35039 : case X_TranslateCoords:
35040 : case X_GetGeometry:
35041 : /* property access is controlled in SecurityCheckPropertyAccess */
35042 : case X_GetProperty:
35043 : case X_ChangeProperty:
35044 : case X_DeleteProperty:
35045 : case X_RotateProperties:
35046 : case X_ListProperties:
35053 : { /* not a server-owned resource */
35055 : * The following 'if' restricts clients to only access resources at
35056 : * the same trustLevel. Since there are currently only two trust levels,
35057 : * and trusted clients never call this function, this degenerates into
35058 : * saying that untrusted clients can only access resources of other
35059 : * untrusted clients. One way to add the notion of groups would be to
35060 : * allow values other than Trusted (0) and Untrusted (1) for this field.
35061 : * Clients at the same trust level would be able to use each other's
35062 : * resources, but not those of clients at other trust levels. I haven't
35063 : * tried it, but this probably mostly works already. The obvious
35064 : * competing alternative for grouping clients for security purposes is to
35065 : * use app groups. dpw
35067 : if (TRUSTLEVEL(client) == TRUSTLEVEL(clients[cid])
35069 : || (RT_COLORMAP == rtype &&
35070 : XagDefaultColormap (client) == (Colormap) id)
35077 : else /* server-owned resource - probably a default colormap or root window */
35079 : if (RT_WINDOW == rtype || RC_DRAWABLE == rtype)
35082 : { /* the following operations are allowed on root windows */
35083 : case X_CreatePixmap:
35085 : case X_CreateWindow:
35086 : case X_CreateColormap:
35087 : case X_ListProperties:
35088 : case X_GrabPointer:
35089 : case X_UngrabButton:
35090 : case X_QueryBestSize:
35091 : case X_GetWindowAttributes:
35093 : case X_SendEvent:
35094 : { /* see if it is an event specified by the ICCCM */
35095 : xSendEventReq *req = (xSendEventReq *)
35096 : (client->requestBuffer);
35097 : if (req->propagate == xTrue
35099 : (req->eventMask != ColormapChangeMask &&
35100 : req->eventMask != StructureNotifyMask &&
35101 : req->eventMask !=
35102 : (SubstructureRedirectMask|SubstructureNotifyMask)
35105 : (req->event.u.u.type != UnmapNotify &&
35106 : req->event.u.u.type != ConfigureRequest &&
35107 : req->event.u.u.type != ClientMessage
35110 : { /* not an ICCCM event */
35114 : } /* case X_SendEvent on root */
35116 : case X_ChangeWindowAttributes:
35117 : { /* Allow selection of PropertyNotify and StructureNotify
35118 : * events on the root.
35120 : xChangeWindowAttributesReq *req =
35121 : (xChangeWindowAttributesReq *)(client->requestBuffer);
35122 : if (req->valueMask == CWEventMask)
35124 : CARD32 value = *((CARD32 *)(req + 1));
35126 : ~(PropertyChangeMask|StructureNotifyMask)) == 0)
35130 : } /* case X_ChangeWindowAttributes on root */
35134 : /* others not allowed */
35138 : } /* end server-owned window or drawable */
35139 : else if (SecurityAuthorizationResType == rtype)
35141 : SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)rval;
35142 : if (pAuth->trustLevel != TRUSTLEVEL(client))
35145 : else if (RT_COLORMAP != rtype)
35146 : { /* don't allow anything else besides colormaps */
35152 : SecurityAuditResourceIDAccess(client, id);
35153 : rec->rval = FALSE; /* deny access */
35154 2 0.0022 :} /* SecurityCheckResourceIDAccess */
35157 :/* SecurityClientStateCallback
35160 : * pcbl is &ClientStateCallback.
35161 : * nullata is NULL.
35162 : * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
35163 : * which contains information about client state changes.
35165 : * Returns: nothing.
35169 : * If a new client is connecting, its authorization ID is copied to
35170 : * client->authID. If this is a generated authorization, its reference
35171 : * count is bumped, its timer is cancelled if it was running, and its
35172 : * trustlevel is copied to TRUSTLEVEL(client).
35174 : * If a client is disconnecting and the client was using a generated
35175 : * authorization, the authorization's reference count is decremented, and
35176 : * if it is now zero, the timer for this authorization is started.
35179 :CALLBACK(SecurityClientStateCallback)
35181 : NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
35182 : ClientPtr client = pci->client;
35184 : switch (client->clientState)
35186 : case ClientStateInitial:
35187 : TRUSTLEVEL(client) = XSecurityClientTrusted;
35188 : AUTHID(client) = None;
35191 : case ClientStateRunning:
35193 : XID authId = AuthorizationIDOfClient(client);
35194 : SecurityAuthorizationPtr pAuth;
35196 : TRUSTLEVEL(client) = XSecurityClientTrusted;
35197 : AUTHID(client) = authId;
35198 : pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
35199 : SecurityAuthorizationResType);
35201 : { /* it is a generated authorization */
35203 : if (pAuth->refcnt == 1)
35205 : if (pAuth->timer) TimerCancel(pAuth->timer);
35207 : TRUSTLEVEL(client) = pAuth->trustLevel;
35211 : case ClientStateGone:
35212 : case ClientStateRetained: /* client disconnected */
35214 : SecurityAuthorizationPtr pAuth;
35216 : /* client may not have any state (bad authorization) */
35217 : if (!STATEPTR(client))
35220 : pAuth = (SecurityAuthorizationPtr)LookupIDByType(AUTHID(client),
35221 : SecurityAuthorizationResType);
35223 : { /* it is a generated authorization */
35225 : if (pAuth->refcnt == 0)
35227 : SecurityStartAuthorizationTimer(pAuth);
35234 :} /* SecurityClientStateCallback */
35236 :CALLBACK(SecurityCheckDrawableAccess)
35238 : XaceDrawableAccessRec *rec = (XaceDrawableAccessRec*)calldata;
35240 : if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
35241 : rec->rval = FALSE;
35244 :CALLBACK(SecurityCheckMapAccess)
35246 : XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
35247 : WindowPtr pWin = rec->pWin;
35249 : if (STATEPTR(rec->client) &&
35250 : (TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
35251 : (pWin->drawable.class == InputOnly) &&
35252 : pWin->parent && pWin->parent->parent &&
35253 : (TRUSTLEVEL(wClient(pWin->parent)) == XSecurityClientTrusted))
35255 : rec->rval = FALSE;
35258 :CALLBACK(SecurityCheckBackgrndAccess)
35260 : XaceMapAccessRec *rec = (XaceMapAccessRec*)calldata;
35262 : if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
35263 : rec->rval = FALSE;
35266 :CALLBACK(SecurityCheckExtAccess)
35267 3 0.0033 :{ /* SecurityCheckExtAccess total: 14 0.0153 */
35268 : XaceExtAccessRec *rec = (XaceExtAccessRec*)calldata;
35270 10 0.0109 : if ((TRUSTLEVEL(rec->client) != XSecurityClientTrusted) &&
35271 : !STATEVAL(rec->ext))
35273 : rec->rval = FALSE;
35276 :CALLBACK(SecurityCheckHostlistAccess)
35278 : XaceHostlistAccessRec *rec = (XaceHostlistAccessRec*)calldata;
35280 : if (TRUSTLEVEL(rec->client) != XSecurityClientTrusted)
35282 : rec->rval = FALSE;
35283 : if (rec->access_mode == DixWriteAccess)
35284 : SecurityAudit("client %d attempted to change host access\n",
35285 : rec->client->index);
35287 : SecurityAudit("client %d attempted to list hosts\n",
35288 : rec->client->index);
35292 :CALLBACK(SecurityDeclareExtSecure)
35294 : XaceDeclareExtSecureRec *rec = (XaceDeclareExtSecureRec*)calldata;
35296 : /* security state for extensions is simply a boolean trust value */
35297 : STATEVAL(rec->ext) = rec->secure;
35300 :/**********************************************************************/
35302 :typedef struct _PropertyAccessRec {
35304 : ATOM mustHaveProperty;
35305 : char *mustHaveValue;
35306 : char windowRestriction;
35307 :#define SecurityAnyWindow 0
35308 :#define SecurityRootWindow 1
35309 :#define SecurityWindowWithProperty 2
35311 : char writeAction;
35312 : char destroyAction;
35313 : struct _PropertyAccessRec *next;
35314 :} PropertyAccessRec, *PropertyAccessPtr;
35316 :static PropertyAccessPtr PropertyAccessList = NULL;
35317 :static char SecurityDefaultAction = XaceErrorOperation;
35318 :static char *SecurityPolicyFile = DEFAULTPOLICYFILE;
35319 :static ATOM SecurityMaxPropertyName = 0;
35321 :static char *SecurityKeywords[] = {
35322 :#define SecurityKeywordComment 0
35324 :#define SecurityKeywordProperty 1
35326 :#define SecurityKeywordSitePolicy 2
35328 :#define SecurityKeywordRoot 3
35330 :#define SecurityKeywordAny 4
35334 :#define NUMKEYWORDS (sizeof(SecurityKeywords) / sizeof(char *))
35337 :/*#define PROPDEBUG 1*/
35340 :SecurityFreePropertyAccessList(void)
35342 : while (PropertyAccessList)
35344 : PropertyAccessPtr freeit = PropertyAccessList;
35345 : PropertyAccessList = PropertyAccessList->next;
35348 :} /* SecurityFreePropertyAccessList */
35350 :#define SecurityIsWhitespace(c) ( (c == ' ') || (c == '\t') || (c == '\n') )
35353 :SecuritySkipWhitespace(
35356 : while (SecurityIsWhitespace(*p))
35359 :} /* SecuritySkipWhitespace */
35363 :SecurityParseString(
35366 : char *startOfString;
35368 : char endChar = 0;
35370 : s = SecuritySkipWhitespace(s);
35372 : if (*s == '"' || *s == '\'')
35375 : startOfString = s;
35376 : while (*s && (*s != endChar))
35381 : startOfString = s;
35382 : while (*s && !SecurityIsWhitespace(*s))
35389 : return startOfString;
35394 : return (endChar) ? NULL : startOfString;
35396 :} /* SecurityParseString */
35400 :SecurityParseKeyword(
35405 : s = SecuritySkipWhitespace(s);
35406 : for (i = 0; i < NUMKEYWORDS; i++)
35408 : int len = strlen(SecurityKeywords[i]);
35409 : if (strncmp(s, SecurityKeywords[i], len) == 0)
35417 :} /* SecurityParseKeyword */
35421 :SecurityParsePropertyAccessRule(
35426 : char action = SecurityDefaultAction;
35427 : char readAction, writeAction, destroyAction;
35428 : PropertyAccessPtr pacl, prev, cur;
35429 : char *mustHaveProperty = NULL;
35430 : char *mustHaveValue = NULL;
35432 : char windowRestriction;
35436 : /* get property name */
35437 : propname = SecurityParseString(&p);
35438 : if (!propname || (strlen(propname) == 0))
35441 : /* get window on which property must reside for rule to apply */
35443 : keyword = SecurityParseKeyword(&p);
35444 : if (keyword == SecurityKeywordRoot)
35445 : windowRestriction = SecurityRootWindow;
35446 : else if (keyword == SecurityKeywordAny)
35447 : windowRestriction = SecurityAnyWindow;
35448 : else /* not root or any, must be a property name */
35450 : mustHaveProperty = SecurityParseString(&p);
35451 : if (!mustHaveProperty || (strlen(mustHaveProperty) == 0))
35453 : windowRestriction = SecurityWindowWithProperty;
35454 : p = SecuritySkipWhitespace(p);
35456 : { /* property value is specified too */
35457 : p++; /* skip over '=' */
35458 : mustHaveValue = SecurityParseString(&p);
35459 : if (!mustHaveValue)
35464 : /* get operations and actions */
35467 : readAction = writeAction = destroyAction = SecurityDefaultAction;
35468 : while ( (c = *p++) && !invalid)
35472 : case 'i': action = XaceIgnoreOperation; break;
35473 : case 'a': action = XaceAllowOperation; break;
35474 : case 'e': action = XaceErrorOperation; break;
35476 : case 'r': readAction = action; break;
35477 : case 'w': writeAction = action; break;
35478 : case 'd': destroyAction = action; break;
35481 : if (!SecurityIsWhitespace(c))
35489 : /* We've successfully collected all the information needed for this
35490 : * property access rule. Now record it in a PropertyAccessRec.
35492 : size = sizeof(PropertyAccessRec);
35494 : /* If there is a property value string, allocate space for it
35495 : * right after the PropertyAccessRec.
35497 : if (mustHaveValue)
35498 : size += strlen(mustHaveValue) + 1;
35499 : pacl = (PropertyAccessPtr)Xalloc(size);
35503 : pacl->name = MakeAtom(propname, strlen(propname), TRUE);
35504 : if (pacl->name == BAD_RESOURCE)
35509 : if (mustHaveProperty)
35511 : pacl->mustHaveProperty = MakeAtom(mustHaveProperty,
35512 : strlen(mustHaveProperty), TRUE);
35513 : if (pacl->mustHaveProperty == BAD_RESOURCE)
35520 : pacl->mustHaveProperty = 0;
35522 : if (mustHaveValue)
35524 : pacl->mustHaveValue = (char *)(pacl + 1);
35525 : strcpy(pacl->mustHaveValue, mustHaveValue);
35528 : pacl->mustHaveValue = NULL;
35530 : SecurityMaxPropertyName = max(SecurityMaxPropertyName, pacl->name);
35532 : pacl->windowRestriction = windowRestriction;
35533 : pacl->readAction = readAction;
35534 : pacl->writeAction = writeAction;
35535 : pacl->destroyAction = destroyAction;
35537 : /* link the new rule into the list of rules in order of increasing
35538 : * property name (atom) value to make searching easier
35541 : for (prev = NULL, cur = PropertyAccessList;
35542 : cur && cur->name <= pacl->name;
35543 : prev = cur, cur = cur->next)
35547 : pacl->next = cur;
35548 : PropertyAccessList = pacl;
35552 : prev->next = pacl;
35553 : pacl->next = cur;
35556 :} /* SecurityParsePropertyAccessRule */
35558 :static char **SecurityPolicyStrings = NULL;
35559 :static int nSecurityPolicyStrings = 0;
35562 :SecurityParseSitePolicy(
35565 : char *policyStr = SecurityParseString(&p);
35566 : char *copyPolicyStr;
35567 : char **newStrings;
35572 : copyPolicyStr = (char *)Xalloc(strlen(policyStr) + 1);
35573 : if (!copyPolicyStr)
35575 : strcpy(copyPolicyStr, policyStr);
35576 : newStrings = (char **)Xrealloc(SecurityPolicyStrings,
35577 : sizeof (char *) * (nSecurityPolicyStrings + 1));
35580 : Xfree(copyPolicyStr);
35584 : SecurityPolicyStrings = newStrings;
35585 : SecurityPolicyStrings[nSecurityPolicyStrings++] = copyPolicyStr;
35589 :} /* SecurityParseSitePolicy */
35593 :SecurityGetSitePolicyStrings(n)
35596 : *n = nSecurityPolicyStrings;
35597 : return SecurityPolicyStrings;
35598 :} /* SecurityGetSitePolicyStrings */
35601 :SecurityFreeSitePolicyStrings(void)
35603 : if (SecurityPolicyStrings)
35605 : assert(nSecurityPolicyStrings);
35606 : while (nSecurityPolicyStrings--)
35608 : Xfree(SecurityPolicyStrings[nSecurityPolicyStrings]);
35610 : Xfree(SecurityPolicyStrings);
35611 : SecurityPolicyStrings = NULL;
35612 : nSecurityPolicyStrings = 0;
35614 :} /* SecurityFreeSitePolicyStrings */
35618 :SecurityLoadPropertyAccessList(void)
35621 : int lineNumber = 0;
35623 : SecurityMaxPropertyName = 0;
35625 : if (!SecurityPolicyFile)
35628 : f = fopen(SecurityPolicyFile, "r");
35631 : ErrorF("error opening security policy file %s\n",
35632 : SecurityPolicyFile);
35642 : if (!(p = fgets(buf, sizeof(buf), f)))
35646 : /* if first line, check version number */
35647 : if (lineNumber == 1)
35649 : char *v = SecurityParseString(&p);
35650 : if (strcmp(v, SECURITY_POLICY_FILE_VERSION) != 0)
35652 : ErrorF("%s: invalid security policy file version, ignoring file\n",
35653 : SecurityPolicyFile);
35656 : validLine = TRUE;
35660 : switch (SecurityParseKeyword(&p))
35662 : case SecurityKeywordComment:
35663 : validLine = TRUE;
35666 : case SecurityKeywordProperty:
35667 : validLine = SecurityParsePropertyAccessRule(p);
35670 : case SecurityKeywordSitePolicy:
35671 : validLine = SecurityParseSitePolicy(p);
35675 : validLine = (*p == '\0'); /* blank lines OK, others not */
35681 : ErrorF("Line %d of %s invalid, ignoring\n",
35682 : lineNumber, SecurityPolicyFile);
35683 : } /* end while more input */
35687 : PropertyAccessPtr pacl;
35688 : char *op = "aie";
35689 : for (pacl = PropertyAccessList; pacl; pacl = pacl->next)
35691 : ErrorF("property %s ", NameForAtom(pacl->name));
35692 : switch (pacl->windowRestriction)
35694 : case SecurityAnyWindow: ErrorF("any "); break;
35695 : case SecurityRootWindow: ErrorF("root "); break;
35696 : case SecurityWindowWithProperty:
35698 : ErrorF("%s ", NameForAtom(pacl->mustHaveProperty));
35699 : if (pacl->mustHaveValue)
35700 : ErrorF(" = \"%s\" ", pacl->mustHaveValue);
35705 : ErrorF("%cr %cw %cd\n", op[pacl->readAction],
35706 : op[pacl->writeAction], op[pacl->destroyAction]);
35709 :#endif /* PROPDEBUG */
35712 :} /* SecurityLoadPropertyAccessList */
35716 :SecurityMatchString(
35720 : while (*ws && *cs)
35724 : Bool match = FALSE;
35726 : while (!(match = SecurityMatchString(ws, cs)) && *cs)
35732 : else if (*ws == *cs)
35739 : return ( ( (*ws == '\0') || ((*ws == '*') && *(ws+1) == '\0') )
35740 : && (*cs == '\0') );
35741 :} /* SecurityMatchString */
35744 :#include <sys/types.h>
35745 :#include <sys/stat.h>
35749 :CALLBACK(SecurityCheckPropertyAccess)
35751 : XacePropertyAccessRec *rec = (XacePropertyAccessRec*)calldata;
35752 : ClientPtr client = rec->client;
35753 : WindowPtr pWin = rec->pWin;
35754 : ATOM propertyName = rec->propertyName;
35755 : Mask access_mode = rec->access_mode;
35756 : PropertyAccessPtr pacl;
35757 : char action = SecurityDefaultAction;
35759 : /* if client trusted or window untrusted, allow operation */
35761 : if ( (TRUSTLEVEL(client) == XSecurityClientTrusted) ||
35762 : (TRUSTLEVEL(wClient(pWin)) != XSecurityClientTrusted) )
35766 : /* For testing, it's more convenient if the property rules file gets
35767 : * reloaded whenever it changes, so we can rapidly try things without
35768 : * having to reset the server.
35772 : static time_t lastmod = 0;
35773 : int ret = stat(SecurityPolicyFile , &buf);
35774 : if ( (ret == 0) && (buf.st_mtime > lastmod) )
35776 : ErrorF("reloading property rules\n");
35777 : SecurityFreePropertyAccessList();
35778 : SecurityLoadPropertyAccessList();
35779 : lastmod = buf.st_mtime;
35784 : /* If the property atom is bigger than any atoms on the list,
35785 : * we know we won't find it, so don't even bother looking.
35787 : if (propertyName <= SecurityMaxPropertyName)
35789 : /* untrusted client operating on trusted window; see if it's allowed */
35791 : for (pacl = PropertyAccessList; pacl; pacl = pacl->next)
35793 : if (pacl->name < propertyName)
35795 : if (pacl->name > propertyName)
35798 : /* pacl->name == propertyName, so see if it applies to this window */
35800 : switch (pacl->windowRestriction)
35802 : case SecurityAnyWindow: /* always applies */
35805 : case SecurityRootWindow:
35807 : /* if not a root window, this rule doesn't apply */
35808 : if (pWin->parent)
35813 : case SecurityWindowWithProperty:
35815 : PropertyPtr pProp = wUserProps (pWin);
35816 : Bool match = FALSE;
35822 : if (pProp->propertyName == pacl->mustHaveProperty)
35824 : pProp = pProp->next;
35828 : if (!pacl->mustHaveValue)
35830 : if (pProp->type != XA_STRING || pProp->format != 8)
35834 : pEndData = ((char *)pProp->data) + pProp->size;
35835 : while (!match && p < pEndData)
35837 : if (SecurityMatchString(pacl->mustHaveValue, p))
35840 : { /* skip to the next string */
35841 : while (*p++ && p < pEndData)
35848 : break; /* end case SecurityWindowWithProperty */
35849 : } /* end switch on windowRestriction */
35851 : /* If we get here, the property access rule pacl applies.
35852 : * If pacl doesn't apply, something above should have
35853 : * executed a continue, which will skip the follwing code.
35855 : action = XaceAllowOperation;
35856 : if (access_mode & DixReadAccess)
35857 : action = max(action, pacl->readAction);
35858 : if (access_mode & DixWriteAccess)
35859 : action = max(action, pacl->writeAction);
35860 : if (access_mode & DixDestroyAccess)
35861 : action = max(action, pacl->destroyAction);
35863 : } /* end for each pacl */
35864 : } /* end if propertyName <= SecurityMaxPropertyName */
35866 : if (XaceAllowOperation != action)
35867 : { /* audit the access violation */
35868 : int cid = CLIENT_ID(pWin->drawable.id);
35869 : int reqtype = ((xReq *)client->requestBuffer)->reqType;
35870 : char *actionstr = (XaceIgnoreOperation == action) ?
35871 : "ignored" : "error";
35872 : SecurityAudit("client %d attempted request %d with window 0x%x property %s (atom 0x%x) of client %d, %s\n",
35873 : client->index, reqtype, pWin->drawable.id,
35874 : NameForAtom(propertyName), propertyName, cid, actionstr);
35876 : /* return codes increase with strictness */
35877 : if (action > rec->rval)
35878 : rec->rval = action;
35879 :} /* SecurityCheckPropertyAccess */
35882 :/* SecurityResetProc
35885 : * extEntry is the extension information for the security extension.
35887 : * Returns: nothing.
35890 : * Performs any cleanup needed by Security at server shutdown time.
35894 :SecurityResetProc(
35895 : ExtensionEntry *extEntry)
35897 : SecurityFreePropertyAccessList();
35898 : SecurityFreeSitePolicyStrings();
35899 :} /* SecurityResetProc */
35903 :XSecurityOptions(argc, argv, i)
35908 : if (strcmp(argv[i], "-sp") == 0)
35911 : SecurityPolicyFile = argv[++i];
35915 :} /* XSecurityOptions */
35918 :/* SecurityExtensionSetup
35920 : * Arguments: none.
35922 : * Returns: nothing.
35925 : * Sets up the Security extension if possible.
35926 : * This function contains things that need to be done
35927 : * before any other extension init functions get called.
35931 :SecurityExtensionSetup(INITARGS)
35933 : /* Allocate the client private index */
35934 : securityClientPrivateIndex = AllocateClientPrivateIndex();
35935 : if (!AllocateClientPrivate(securityClientPrivateIndex,
35936 : sizeof (SecurityClientStateRec)))
35937 : FatalError("SecurityExtensionSetup: Can't allocate client private.\n");
35939 : /* Allocate the extension private index */
35940 : securityExtnsnPrivateIndex = AllocateExtensionPrivateIndex();
35941 : if (!AllocateExtensionPrivate(securityExtnsnPrivateIndex, 0))
35942 : FatalError("SecurityExtensionSetup: Can't allocate extnsn private.\n");
35944 : /* register callbacks */
35945 :#define XaceRC XaceRegisterCallback
35946 : XaceRC(XACE_RESOURCE_ACCESS, SecurityCheckResourceIDAccess, NULL);
35947 : XaceRC(XACE_DEVICE_ACCESS, SecurityCheckDeviceAccess, NULL);
35948 : XaceRC(XACE_PROPERTY_ACCESS, SecurityCheckPropertyAccess, NULL);
35949 : XaceRC(XACE_DRAWABLE_ACCESS, SecurityCheckDrawableAccess, NULL);
35950 : XaceRC(XACE_MAP_ACCESS, SecurityCheckMapAccess, NULL);
35951 : XaceRC(XACE_BACKGRND_ACCESS, SecurityCheckBackgrndAccess, NULL);
35952 : XaceRC(XACE_EXT_DISPATCH, SecurityCheckExtAccess, NULL);
35953 : XaceRC(XACE_EXT_ACCESS, SecurityCheckExtAccess, NULL);
35954 : XaceRC(XACE_HOSTLIST_ACCESS, SecurityCheckHostlistAccess, NULL);
35955 : XaceRC(XACE_DECLARE_EXT_SECURE, SecurityDeclareExtSecure, NULL);
35956 :} /* SecurityExtensionSetup */
35959 :/* SecurityExtensionInit
35961 : * Arguments: none.
35963 : * Returns: nothing.
35966 : * Enables the Security extension if possible.
35970 :SecurityExtensionInit(INITARGS)
35972 : ExtensionEntry *extEntry;
35974 : SecurityAuthorizationResType =
35975 : CreateNewResourceType(SecurityDeleteAuthorization);
35977 : RTEventClient = CreateNewResourceType(
35978 : SecurityDeleteAuthorizationEventClient);
35980 : if (!SecurityAuthorizationResType || !RTEventClient)
35983 : RTEventClient |= RC_NEVERRETAIN;
35985 : if (!AddCallback(&ClientStateCallback, SecurityClientStateCallback, NULL))
35988 : extEntry = AddExtension(SECURITY_EXTENSION_NAME,
35989 : XSecurityNumberEvents, XSecurityNumberErrors,
35990 : ProcSecurityDispatch, SProcSecurityDispatch,
35991 : SecurityResetProc, StandardMinorOpcode);
35993 : SecurityErrorBase = extEntry->errorBase;
35994 : SecurityEventBase = extEntry->eventBase;
35996 : EventSwapVector[SecurityEventBase + XSecurityAuthorizationRevoked] =
35997 : (EventSwapPtr)SwapSecurityAuthorizationRevokedEvent;
35999 : SecurityLoadPropertyAccessList();
36001 :} /* SecurityExtensionInit */
36003 * Total samples for file : "/home/cworth/src/xorg/xserver/hw/xfree86/dri/dri.c"
36009 :/**************************************************************************
36011 :Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
36012 :Copyright 2000 VA Linux Systems, Inc.
36013 :All Rights Reserved.
36015 :Permission is hereby granted, free of charge, to any person obtaining a
36016 :copy of this software and associated documentation files (the
36017 :"Software"), to deal in the Software without restriction, including
36018 :without limitation the rights to use, copy, modify, merge, publish,
36019 :distribute, sub license, and/or sell copies of the Software, and to
36020 :permit persons to whom the Software is furnished to do so, subject to
36021 :the following conditions:
36023 :The above copyright notice and this permission notice (including the
36024 :next paragraph) shall be included in all copies or substantial portions
36027 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36028 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36029 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
36030 :IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
36031 :ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
36032 :TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
36033 :SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36035 :**************************************************************************/
36039 : * Jens Owen <jens@tungstengraphics.com>
36040 : * Rickard E. (Rik) Faith <faith@valinux.com>
36044 :#ifdef HAVE_XORG_CONFIG_H
36045 :#include <xorg-config.h>
36049 :#include <sys/time.h>
36050 :#include <unistd.h>
36051 :#include <string.h>
36052 :#include <stdio.h>
36053 :#include <sys/ioctl.h>
36054 :#include <errno.h>
36056 :#define NEED_REPLIES
36057 :#define NEED_EVENTS
36058 :#include <X11/X.h>
36059 :#include <X11/Xproto.h>
36060 :#include "xf86drm.h"
36062 :#include "dixstruct.h"
36063 :#include "extnsionst.h"
36064 :#include "colormapst.h"
36065 :#include "cursorstr.h"
36066 :#include "scrnintstr.h"
36067 :#include "windowstr.h"
36068 :#include "servermd.h"
36069 :#define _XF86DRI_SERVER_
36070 :#include "xf86dristr.h"
36071 :#include "swaprep.h"
36072 :#include "xf86str.h"
36074 :#include "sarea.h"
36075 :#include "dristruct.h"
36077 :#include "xf86drm.h"
36078 :#include "glxserver.h"
36080 :#include "mipointer.h"
36081 :#include "xf86_OSproc.h"
36083 :#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
36085 :#if !defined(PANORAMIX)
36086 :extern Bool noPanoramiXExtension;
36089 :static int DRIEntPrivIndex = -1;
36090 :static int DRIScreenPrivIndex = -1;
36091 :static int DRIWindowPrivIndex = -1;
36092 :static unsigned long DRIGeneration = 0;
36093 :static unsigned int DRIDrawableValidationStamp = 0;
36095 :static RESTYPE DRIDrawablePrivResType;
36096 :static RESTYPE DRIContextPrivResType;
36097 :static void DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv);
36099 :drmServerInfo DRIDRMServerInfo;
36101 : /* Wrapper just like xf86DrvMsg, but
36102 : without the verbosity level checking.
36103 : This will make it easy to turn off some
36104 : messages later, based on verbosity
36108 : * Since we're already referencing things from the XFree86 common layer in
36109 : * this file, we'd might as well just call xf86VDrvMsgVerb, and have
36110 : * consistent message formatting. The verbosity of these messages can be
36111 : * easily changed here.
36113 :#define DRI_MSG_VERBOSITY 1
36115 :DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
36119 : va_start(ap, format);
36120 : xf86VDrvMsgVerb(scrnIndex, type, DRI_MSG_VERBOSITY, format, ap);
36126 :DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
36128 : if (pDRIEntPriv->pLSAREA != NULL) {
36129 : drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
36130 : pDRIEntPriv->pLSAREA = NULL;
36132 : if (pDRIEntPriv->hLSAREA != 0) {
36133 : drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
36135 : if (pDRIEntPriv->drmFD >= 0) {
36136 : drmClose(pDRIEntPriv->drmFD);
36137 : pDRIEntPriv->drmFD = 0;
36142 :DRIMasterFD(ScrnInfoPtr pScrn)
36144 : return DRI_ENT_PRIV(pScrn)->drmFD;
36148 :DRIMasterSareaPointer(ScrnInfoPtr pScrn)
36150 : return DRI_ENT_PRIV(pScrn)->pLSAREA;
36154 :DRIMasterSareaHandle(ScrnInfoPtr pScrn)
36156 : return DRI_ENT_PRIV(pScrn)->hLSAREA;
36161 :DRIOpenDRMMaster(ScrnInfoPtr pScrn,
36162 : unsigned long sAreaSize,
36163 : const char *busID,
36164 : const char *drmDriverName)
36166 : drmSetVersion saveSv, sv;
36167 : Bool drmWasAvailable;
36168 : DRIEntPrivPtr pDRIEntPriv;
36169 : DRIEntPrivRec tmp;
36170 : drmVersionPtr drmlibv;
36171 : int drmlibmajor, drmlibminor;
36172 : const char *openBusID;
36176 : if (DRIEntPrivIndex == -1)
36177 : DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
36179 : pDRIEntPriv = DRI_ENT_PRIV(pScrn);
36181 : if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
36184 : drmWasAvailable = drmAvailable();
36186 : memset(&tmp, 0, sizeof(tmp));
36188 : /* Check the DRM lib version.
36189 : * drmGetLibVersion was not supported in version 1.0, so check for
36190 : * symbol first to avoid possible crash or hang.
36195 : if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
36196 : drmlibv = drmGetLibVersion(-1);
36197 : if (drmlibv != NULL) {
36198 : drmlibmajor = drmlibv->version_major;
36199 : drmlibminor = drmlibv->version_minor;
36200 : drmFreeVersion(drmlibv);
36204 : /* Check if the libdrm can handle falling back to loading based on name
36205 : * if a busid string is passed.
36207 : openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
36210 : sv.drm_di_major = 1;
36211 : sv.drm_di_minor = 1;
36212 : sv.drm_dd_major = -1;
36216 : while (count--) {
36217 : tmp.drmFD = drmOpen(drmDriverName, openBusID);
36219 : if (tmp.drmFD < 0) {
36220 : DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
36224 : err = drmSetInterfaceVersion(tmp.drmFD, &sv);
36226 : if (err != -EPERM)
36230 : drmClose(tmp.drmFD);
36235 : if (tmp.drmFD <= 0) {
36236 : DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
36240 : if (!drmWasAvailable) {
36241 : DRIDrvMsg(-1, X_INFO,
36242 : "[drm] loaded kernel module for \"%s\" driver.\n",
36247 : sv.drm_di_major = 1;
36248 : sv.drm_di_minor = 0;
36251 : DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
36252 : sv.drm_di_major, sv.drm_di_minor);
36254 : if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
36257 : err = drmSetBusid(tmp.drmFD, busID);
36260 : DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
36265 : * Create a lock-containing sarea.
36268 : if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
36269 : DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
36270 : DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
36275 : if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
36276 : (drmAddressPtr)(&tmp.pLSAREA)) < 0) {
36277 : DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
36278 : tmp.pLSAREA = NULL;
36282 : memset(tmp.pLSAREA, 0, sAreaSize);
36285 : * Reserved contexts are handled by the first opened screen.
36288 : tmp.resOwner = NULL;
36290 : if (!pDRIEntPriv)
36291 : pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
36293 : if (!pDRIEntPriv) {
36294 : DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
36295 : "DRM device.\n");
36298 : *pDRIEntPriv = tmp;
36299 : xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
36302 : DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
36307 : DRIOpenDRMCleanup(&tmp);
36313 :DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
36315 : DRIScreenPrivPtr pDRIPriv;
36316 : drm_context_t * reserved;
36317 : int reserved_count;
36319 : Bool xineramaInCore = FALSE;
36320 : DRIEntPrivPtr pDRIEntPriv;
36321 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
36323 : /* If the DRI extension is disabled, do not initialize the DRI */
36324 : if (noXFree86DRIExtension) {
36325 : DRIDrvMsg(pScreen->myNum, X_WARNING,
36326 : "Direct rendering has been disabled.\n");
36331 : * If Xinerama is on, don't allow DRI to initialise. It won't be usable
36334 : if (xf86LoaderCheckSymbol("noPanoramiXExtension"))
36335 : xineramaInCore = TRUE;
36337 : if (xineramaInCore) {
36338 : if (!noPanoramiXExtension) {
36339 : DRIDrvMsg(pScreen->myNum, X_WARNING,
36340 : "Direct rendering is not supported when Xinerama is enabled\n");
36345 : if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
36346 : pDRIInfo->busIdString,
36347 : pDRIInfo->drmDriverName))
36350 : pDRIEntPriv = DRI_ENT_PRIV(pScrn);
36352 : if (DRIGeneration != serverGeneration) {
36353 : if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
36355 : DRIGeneration = serverGeneration;
36358 : pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
36360 : pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
36361 : DRIScreenPrivIndex = -1;
36365 : pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv;
36366 : pDRIPriv->drmFD = pDRIEntPriv->drmFD;
36367 : pDRIPriv->directRenderingSupport = TRUE;
36368 : pDRIPriv->pDriverInfo = pDRIInfo;
36369 : pDRIPriv->nrWindows = 0;
36370 : pDRIPriv->nrWindowsVisible = 0;
36371 : pDRIPriv->fullscreen = NULL;
36373 : pDRIPriv->createDummyCtx = pDRIInfo->createDummyCtx;
36374 : pDRIPriv->createDummyCtxPriv = pDRIInfo->createDummyCtxPriv;
36376 : pDRIPriv->grabbedDRILock = FALSE;
36377 : pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
36378 : *pDRMFD = pDRIPriv->drmFD;
36380 : if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
36382 : if (drmAddMap( pDRIPriv->drmFD,
36384 : pDRIPriv->pDriverInfo->SAREASize,
36387 : &pDRIPriv->hSAREA) < 0)
36389 : pDRIPriv->directRenderingSupport = FALSE;
36390 : pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
36391 : drmClose(pDRIPriv->drmFD);
36392 : DRIDrvMsg(pScreen->myNum, X_INFO,
36393 : "[drm] drmAddMap failed\n");
36396 : DRIDrvMsg(pScreen->myNum, X_INFO,
36397 : "[drm] added %d byte SAREA at %p\n",
36398 : pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
36400 : /* Backwards compat. */
36401 : if (drmMap( pDRIPriv->drmFD,
36402 : pDRIPriv->hSAREA,
36403 : pDRIPriv->pDriverInfo->SAREASize,
36404 : (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
36406 : pDRIPriv->directRenderingSupport = FALSE;
36407 : pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
36408 : drmClose(pDRIPriv->drmFD);
36409 : DRIDrvMsg(pScreen->myNum, X_INFO,
36410 : "[drm] drmMap failed\n");
36413 : DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
36414 : pDRIPriv->hSAREA, pDRIPriv->pSAREA);
36415 : memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
36417 : DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
36418 : "SAREA also for drawables.\n");
36419 : pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
36420 : pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
36421 : pDRIEntPriv->sAreaGrabbed = TRUE;
36424 : pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
36425 : pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
36427 : if (drmAddMap( pDRIPriv->drmFD,
36428 : (drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
36429 : pDRIPriv->pDriverInfo->frameBufferSize,
36430 : DRM_FRAME_BUFFER,
36432 : &pDRIPriv->hFrameBuffer) < 0)
36434 : pDRIPriv->directRenderingSupport = FALSE;
36435 : pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
36436 : drmUnmap(pDRIPriv->pSAREA, pDRIPriv->pDriverInfo->SAREASize);
36437 : drmClose(pDRIPriv->drmFD);
36438 : DRIDrvMsg(pScreen->myNum, X_INFO,
36439 : "[drm] drmAddMap failed\n");
36442 : DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
36443 : pDRIPriv->hFrameBuffer);
36445 : if (pDRIEntPriv->resOwner == NULL) {
36446 : pDRIEntPriv->resOwner = pScreen;
36448 : /* Add tags for reserved contexts */
36449 : if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
36450 : &reserved_count))) {
36454 : for (i = 0; i < reserved_count; i++) {
36455 : tag = DRICreateContextPrivFromHandle(pScreen,
36457 : DRI_CONTEXT_RESERVED);
36458 : drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
36460 : drmFreeReservedContextList(reserved);
36461 : DRIDrvMsg(pScreen->myNum, X_INFO,
36462 : "[drm] added %d reserved context%s for kernel\n",
36463 : reserved_count, reserved_count > 1 ? "s" : "");
36467 : /* validate max drawable table entry set by driver */
36468 : if ((pDRIPriv->pDriverInfo->maxDrawableTableEntry <= 0) ||
36469 : (pDRIPriv->pDriverInfo->maxDrawableTableEntry > SAREA_MAX_DRAWABLES)) {
36470 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36471 : "Invalid max drawable table size set by driver: %d\n",
36472 : pDRIPriv->pDriverInfo->maxDrawableTableEntry);
36475 : /* Initialize drawable tables (screen private and SAREA) */
36476 : for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
36477 : pDRIPriv->DRIDrawables[i] = NULL;
36478 : pDRIPriv->pSAREA->drawableTable[i].stamp = 0;
36479 : pDRIPriv->pSAREA->drawableTable[i].flags = 0;
36482 : pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
36483 : pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
36485 : if (!pDRIEntPriv->keepFDOpen)
36486 : pDRIEntPriv->keepFDOpen = pDRIInfo->keepFDOpen;
36488 : pDRIEntPriv->refCount++;
36494 :DRIFinishScreenInit(ScreenPtr pScreen)
36496 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36497 : DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
36498 : DRIContextFlags flags = 0;
36499 : DRIContextPrivPtr pDRIContextPriv;
36501 : /* Set up flags for DRICreateContextPriv */
36502 : switch (pDRIInfo->driverSwapMethod) {
36503 : case DRI_KERNEL_SWAP: flags = DRI_CONTEXT_2DONLY; break;
36504 : case DRI_HIDE_X_CONTEXT: flags = DRI_CONTEXT_PRESERVED; break;
36507 : if (!(pDRIContextPriv = DRICreateContextPriv(pScreen,
36508 : &pDRIPriv->myContext,
36510 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36511 : "failed to create server context\n");
36514 : pDRIPriv->myContextPriv = pDRIContextPriv;
36516 : DRIDrvMsg(pScreen->myNum, X_INFO,
36517 : "X context handle = %p\n", pDRIPriv->myContext);
36519 : /* Now that we have created the X server's context, we can grab the
36520 : * hardware lock for the X server.
36522 : DRILock(pScreen, 0);
36523 : pDRIPriv->grabbedDRILock = TRUE;
36525 : /* pointers so that we can prevent memory leaks later */
36526 : pDRIPriv->hiddenContextStore = NULL;
36527 : pDRIPriv->partial3DContextStore = NULL;
36529 : switch(pDRIInfo->driverSwapMethod) {
36530 : case DRI_HIDE_X_CONTEXT:
36531 : /* Server will handle 3D swaps, and hide 2D swaps from kernel.
36532 : * Register server context as a preserved context.
36535 : /* allocate memory for hidden context store */
36536 : pDRIPriv->hiddenContextStore
36537 : = (void *)xcalloc(1, pDRIInfo->contextSize);
36538 : if (!pDRIPriv->hiddenContextStore) {
36539 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36540 : "failed to allocate hidden context\n");
36541 : DRIDestroyContextPriv(pDRIContextPriv);
36545 : /* allocate memory for partial 3D context store */
36546 : pDRIPriv->partial3DContextStore
36547 : = (void *)xcalloc(1, pDRIInfo->contextSize);
36548 : if (!pDRIPriv->partial3DContextStore) {
36549 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36550 : "[DRI] failed to allocate partial 3D context\n");
36551 : xfree(pDRIPriv->hiddenContextStore);
36552 : DRIDestroyContextPriv(pDRIContextPriv);
36556 : /* save initial context store */
36557 : if (pDRIInfo->SwapContext) {
36558 : (*pDRIInfo->SwapContext)(
36562 : pDRIPriv->hiddenContextStore,
36566 : /* fall through */
36568 : case DRI_SERVER_SWAP:
36569 : /* For swap methods of DRI_SERVER_SWAP and DRI_HIDE_X_CONTEXT
36570 : * setup signal handler for receiving swap requests from kernel
36572 : if (!(pDRIPriv->drmSIGIOHandlerInstalled =
36573 : drmInstallSIGIOHandler(pDRIPriv->drmFD, DRISwapContext))) {
36574 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36575 : "[drm] failed to setup DRM signal handler\n");
36576 : if (pDRIPriv->hiddenContextStore)
36577 : xfree(pDRIPriv->hiddenContextStore);
36578 : if (pDRIPriv->partial3DContextStore)
36579 : xfree(pDRIPriv->partial3DContextStore);
36580 : DRIDestroyContextPriv(pDRIContextPriv);
36583 : DRIDrvMsg(pScreen->myNum, X_INFO,
36584 : "[drm] installed DRM signal handler\n");
36591 : /* Wrap DRI support */
36592 : if (pDRIInfo->wrap.ValidateTree) {
36593 : pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
36594 : pScreen->ValidateTree = pDRIInfo->wrap.ValidateTree;
36596 : if (pDRIInfo->wrap.PostValidateTree) {
36597 : pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
36598 : pScreen->PostValidateTree = pDRIInfo->wrap.PostValidateTree;
36600 : if (pDRIInfo->wrap.WindowExposures) {
36601 : pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
36602 : pScreen->WindowExposures = pDRIInfo->wrap.WindowExposures;
36604 : if (pDRIInfo->wrap.CopyWindow) {
36605 : pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
36606 : pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow;
36608 : if (pDRIInfo->wrap.ClipNotify) {
36609 : pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
36610 : pScreen->ClipNotify = pDRIInfo->wrap.ClipNotify;
36612 : if (pDRIInfo->wrap.AdjustFrame) {
36613 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
36614 : pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
36615 : pScrn->AdjustFrame = pDRIInfo->wrap.AdjustFrame;
36617 : pDRIPriv->wrapped = TRUE;
36619 : DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n");
36625 :DRICloseScreen(ScreenPtr pScreen)
36627 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36628 : DRIInfoPtr pDRIInfo;
36629 : drm_context_t * reserved;
36630 : int reserved_count;
36631 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
36632 : DRIEntPrivPtr pDRIEntPriv = DRI_ENT_PRIV(pScrn);
36633 : Bool closeMaster;
36637 : pDRIInfo = pDRIPriv->pDriverInfo;
36639 : if (pDRIPriv->wrapped) {
36640 : /* Unwrap DRI Functions */
36641 : if (pDRIInfo->wrap.ValidateTree) {
36642 : pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
36643 : pDRIPriv->wrap.ValidateTree = NULL;
36645 : if (pDRIInfo->wrap.PostValidateTree) {
36646 : pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
36647 : pDRIPriv->wrap.PostValidateTree = NULL;
36649 : if (pDRIInfo->wrap.WindowExposures) {
36650 : pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
36651 : pDRIPriv->wrap.WindowExposures = NULL;
36653 : if (pDRIInfo->wrap.CopyWindow) {
36654 : pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
36655 : pDRIPriv->wrap.CopyWindow = NULL;
36657 : if (pDRIInfo->wrap.ClipNotify) {
36658 : pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
36659 : pDRIPriv->wrap.ClipNotify = NULL;
36661 : if (pDRIInfo->wrap.AdjustFrame) {
36662 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
36663 : pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
36664 : pDRIPriv->wrap.AdjustFrame = NULL;
36666 : pDRIPriv->wrapped = FALSE;
36669 : if (pDRIPriv->drmSIGIOHandlerInstalled) {
36670 : if (!drmRemoveSIGIOHandler(pDRIPriv->drmFD)) {
36671 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36672 : "[drm] failed to remove DRM signal handler\n");
36676 : if (pDRIPriv->dummyCtxPriv && pDRIPriv->createDummyCtx) {
36677 : DRIDestroyDummyContext(pScreen, pDRIPriv->createDummyCtxPriv);
36680 : if (!DRIDestroyContextPriv(pDRIPriv->myContextPriv)) {
36681 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36682 : "failed to destroy server context\n");
36685 : /* Remove tags for reserved contexts */
36686 : if (pDRIEntPriv->resOwner == pScreen) {
36687 : pDRIEntPriv->resOwner = NULL;
36689 : if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
36690 : &reserved_count))) {
36693 : for (i = 0; i < reserved_count; i++) {
36694 : DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
36697 : drmFreeReservedContextList(reserved);
36698 : DRIDrvMsg(pScreen->myNum, X_INFO,
36699 : "[drm] removed %d reserved context%s for kernel\n",
36700 : reserved_count, reserved_count > 1 ? "s" : "");
36704 : /* Make sure signals get unblocked etc. */
36705 : drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
36706 : pDRIPriv->pLockRefCount = NULL;
36707 : closeMaster = (--pDRIEntPriv->refCount == 0) &&
36708 : !pDRIEntPriv->keepFDOpen;
36709 : if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
36710 : DRIDrvMsg(pScreen->myNum, X_INFO,
36711 : "[drm] unmapping %d bytes of SAREA %p at %p\n",
36712 : pDRIInfo->SAREASize,
36713 : pDRIPriv->hSAREA,
36714 : pDRIPriv->pSAREA);
36715 : if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
36716 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36717 : "[drm] unable to unmap %d bytes"
36718 : " of SAREA %p at %p\n",
36719 : pDRIInfo->SAREASize,
36720 : pDRIPriv->hSAREA,
36721 : pDRIPriv->pSAREA);
36724 : pDRIEntPriv->sAreaGrabbed = FALSE;
36727 : if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
36728 : drmClose(pDRIPriv->drmFD);
36729 : if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
36730 : DRIDrvMsg(pScreen->myNum, X_INFO,
36731 : "[drm] Closed DRM master.\n");
36732 : pDRIEntPriv->drmFD = -1;
36737 : pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
36738 : DRIScreenPrivIndex = -1;
36742 :#define DRM_MSG_VERBOSITY 3
36744 :static int dri_drm_debug_print(const char *format, va_list ap)
36746 : xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap);
36750 :static void dri_drm_get_perms(gid_t *group, mode_t *mode)
36752 : *group = xf86ConfigDRI.group;
36753 : *mode = xf86ConfigDRI.mode;
36756 :drmServerInfo DRIDRMServerInfo = {
36757 : dri_drm_debug_print,
36758 : xf86LoadKernelModule,
36759 : dri_drm_get_perms,
36763 :DRIExtensionInit(void)
36766 : ScreenPtr pScreen;
36768 : if (DRIScreenPrivIndex < 0 || DRIGeneration != serverGeneration) {
36772 : /* Allocate a window private index with a zero sized private area for
36773 : * each window, then should a window become a DRI window, we'll hang
36774 : * a DRIWindowPrivateRec off of this private index.
36776 : if ((DRIWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
36779 : DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete);
36780 : DRIContextPrivResType = CreateNewResourceType(DRIContextPrivDelete);
36782 : for (i = 0; i < screenInfo.numScreens; i++)
36784 : pScreen = screenInfo.screens[i];
36785 : if (!AllocateWindowPrivate(pScreen, DRIWindowPrivIndex, 0))
36789 : RegisterBlockAndWakeupHandlers(DRIBlockHandler, DRIWakeupHandler, NULL);
36798 : * This stub routine is called when the X Server recycles, resources
36799 : * allocated by DRIExtensionInit need to be managed here.
36801 : * Currently this routine is a stub because all the interesting resources
36802 : * are managed via the screen init process.
36807 :DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
36809 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36812 : *isCapable = pDRIPriv->directRenderingSupport;
36814 : *isCapable = FALSE;
36820 :DRIOpenConnection(ScreenPtr pScreen, drm_handle_t * hSAREA, char **busIdString)
36822 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36824 : *hSAREA = pDRIPriv->hSAREA;
36825 : *busIdString = pDRIPriv->pDriverInfo->busIdString;
36831 :DRIAuthConnection(ScreenPtr pScreen, drm_magic_t magic)
36833 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36835 : if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
36840 :DRICloseConnection(ScreenPtr pScreen)
36846 :DRIGetClientDriverName(ScreenPtr pScreen,
36847 : int *ddxDriverMajorVersion,
36848 : int *ddxDriverMinorVersion,
36849 : int *ddxDriverPatchVersion,
36850 : char **clientDriverName)
36852 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36854 : *ddxDriverMajorVersion = pDRIPriv->pDriverInfo->ddxDriverMajorVersion;
36855 : *ddxDriverMinorVersion = pDRIPriv->pDriverInfo->ddxDriverMinorVersion;
36856 : *ddxDriverPatchVersion = pDRIPriv->pDriverInfo->ddxDriverPatchVersion;
36857 : *clientDriverName = pDRIPriv->pDriverInfo->clientDriverName;
36862 :/* DRICreateContextPriv and DRICreateContextPrivFromHandle are helper
36863 : functions that layer on drmCreateContext and drmAddContextTag.
36865 : DRICreateContextPriv always creates a kernel drm_context_t and then calls
36866 : DRICreateContextPrivFromHandle to create a DRIContextPriv structure for
36867 : DRI tracking. For the SIGIO handler, the drm_context_t is associated with
36868 : DRIContextPrivPtr. Any special flags are stored in the DRIContextPriv
36869 : area and are passed to the kernel (if necessary).
36871 : DRICreateContextPriv returns a pointer to newly allocated
36872 : DRIContextPriv, and returns the kernel drm_context_t in pHWContext. */
36875 :DRICreateContextPriv(ScreenPtr pScreen,
36876 : drm_context_t * pHWContext,
36877 : DRIContextFlags flags)
36879 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36881 : if (drmCreateContext(pDRIPriv->drmFD, pHWContext)) {
36885 : return DRICreateContextPrivFromHandle(pScreen, *pHWContext, flags);
36889 :DRICreateContextPrivFromHandle(ScreenPtr pScreen,
36890 : drm_context_t hHWContext,
36891 : DRIContextFlags flags)
36893 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36894 : DRIContextPrivPtr pDRIContextPriv;
36895 : int contextPrivSize;
36897 : contextPrivSize = sizeof(DRIContextPrivRec) +
36898 : pDRIPriv->pDriverInfo->contextSize;
36899 : if (!(pDRIContextPriv = xcalloc(1, contextPrivSize))) {
36902 : pDRIContextPriv->pContextStore = (void *)(pDRIContextPriv + 1);
36904 : drmAddContextTag(pDRIPriv->drmFD, hHWContext, pDRIContextPriv);
36906 : pDRIContextPriv->hwContext = hHWContext;
36907 : pDRIContextPriv->pScreen = pScreen;
36908 : pDRIContextPriv->flags = flags;
36909 : pDRIContextPriv->valid3D = FALSE;
36911 : if (flags & DRI_CONTEXT_2DONLY) {
36912 : if (drmSetContextFlags(pDRIPriv->drmFD,
36914 : DRM_CONTEXT_2DONLY)) {
36915 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36916 : "[drm] failed to set 2D context flag\n");
36917 : DRIDestroyContextPriv(pDRIContextPriv);
36921 : if (flags & DRI_CONTEXT_PRESERVED) {
36922 : if (drmSetContextFlags(pDRIPriv->drmFD,
36924 : DRM_CONTEXT_PRESERVED)) {
36925 : DRIDrvMsg(pScreen->myNum, X_ERROR,
36926 : "[drm] failed to set preserved flag\n");
36927 : DRIDestroyContextPriv(pDRIContextPriv);
36931 : return pDRIContextPriv;
36935 :DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv)
36937 : DRIScreenPrivPtr pDRIPriv;
36939 : if (!pDRIContextPriv) return TRUE;
36941 : pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
36943 : if (!(pDRIContextPriv->flags & DRI_CONTEXT_RESERVED)) {
36944 : /* Don't delete reserved contexts from
36945 : kernel area -- the kernel manages its
36946 : reserved contexts itself. */
36947 : if (drmDestroyContext(pDRIPriv->drmFD, pDRIContextPriv->hwContext))
36951 : /* Remove the tag last to prevent a race
36952 : condition where the context has pending
36953 : buffers. The context can't be re-used
36954 : while in this thread, but buffers can be
36955 : dispatched asynchronously. */
36956 : drmDelContextTag(pDRIPriv->drmFD, pDRIContextPriv->hwContext);
36957 : xfree(pDRIContextPriv);
36962 :DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
36964 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
36965 : __GLXscreen *pGLXScreen = __glXgetActiveScreen(pScreen->myNum);
36966 : __GLcontextModes *modes = pGLXScreen->modes;
36967 : void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
36968 : DRIContextPrivPtr pDRIContextPriv;
36969 : void *contextStore;
36970 : VisualPtr visual;
36973 : visual = pScreen->visuals;
36975 : /* Find the X visual that corresponds the the first GLX visual */
36977 : visNum < pScreen->numVisuals;
36978 : visNum++, visual++) {
36979 : if (modes->visualID == visual->vid)
36982 : if (visNum == pScreen->numVisuals) return FALSE;
36984 : if (!(pDRIContextPriv =
36985 : DRICreateContextPriv(pScreen,
36986 : &pDRIPriv->pSAREA->dummy_context, 0))) {
36990 : contextStore = DRIGetContextStore(pDRIContextPriv);
36991 : if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) {
36992 : if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, visual,
36993 : pDRIPriv->pSAREA->dummy_context,
36994 : *pVisualConfigPriv,
36995 : (DRIContextType)(long)contextStore)) {
36996 : DRIDestroyContextPriv(pDRIContextPriv);
37001 : pDRIPriv->dummyCtxPriv = pDRIContextPriv;
37006 :DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv)
37008 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37009 : DRIContextPrivPtr pDRIContextPriv = pDRIPriv->dummyCtxPriv;
37010 : void *contextStore;
37012 : if (!pDRIContextPriv) return;
37013 : if (pDRIPriv->pDriverInfo->DestroyContext && hasCtxPriv) {
37014 : contextStore = DRIGetContextStore(pDRIContextPriv);
37015 : pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
37016 : pDRIContextPriv->hwContext,
37017 : (DRIContextType)(long)contextStore);
37020 : DRIDestroyContextPriv(pDRIPriv->dummyCtxPriv);
37021 : pDRIPriv->dummyCtxPriv = NULL;
37025 :DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
37026 : XID context, drm_context_t * pHWContext)
37028 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37029 : __GLXscreen *pGLXScreen = __glXgetActiveScreen(pScreen->myNum);
37030 : __GLcontextModes *modes = pGLXScreen->modes;
37031 : void **pVisualConfigPriv = pGLXScreen->pVisualPriv;
37032 : DRIContextPrivPtr pDRIContextPriv;
37033 : void *contextStore;
37035 : if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) {
37036 : if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) {
37037 : DRIDrvMsg(pScreen->myNum, X_INFO,
37038 : "[drm] Could not create dummy context\n");
37043 : /* Find the GLX visual associated with the one requested */
37044 : for (modes = pGLXScreen->modes; modes != NULL; modes = modes->next) {
37045 : if (modes->visualID == visual->vid)
37047 : pVisualConfigPriv++;
37050 : if (modes == NULL) {
37051 : /* No matching GLX visual found */
37055 : if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) {
37059 : contextStore = DRIGetContextStore(pDRIContextPriv);
37060 : if (pDRIPriv->pDriverInfo->CreateContext) {
37061 : if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, visual,
37062 : *pHWContext, *pVisualConfigPriv,
37063 : (DRIContextType)(long)contextStore))) {
37064 : DRIDestroyContextPriv(pDRIContextPriv);
37069 : /* track this in case the client dies before cleanup */
37070 : AddResource(context, DRIContextPrivResType, (pointer)pDRIContextPriv);
37076 :DRIDestroyContext(ScreenPtr pScreen, XID context)
37078 : FreeResourceByType(context, DRIContextPrivResType, FALSE);
37083 :/* DRIContextPrivDelete is called by the resource manager. */
37085 :DRIContextPrivDelete(pointer pResource, XID id)
37087 : DRIContextPrivPtr pDRIContextPriv = (DRIContextPrivPtr)pResource;
37088 : DRIScreenPrivPtr pDRIPriv;
37089 : void *contextStore;
37091 : pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
37092 : if (pDRIPriv->pDriverInfo->DestroyContext) {
37093 : contextStore = DRIGetContextStore(pDRIContextPriv);
37094 : pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
37095 : pDRIContextPriv->hwContext,
37096 : (DRIContextType)(long)contextStore);
37098 : return DRIDestroyContextPriv(pDRIContextPriv);
37102 :/* This walks the drawable timestamp array and invalidates all of them
37103 : * in the case of transition from private to shared backbuffers. It's
37104 : * not necessary for correctness, because DRIClipNotify gets called in
37105 : * time to prevent any conflict, but the transition from
37106 : * shared->private is sometimes missed if we don't do this.
37109 :DRIClipNotifyAllDrawables(ScreenPtr pScreen)
37112 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37114 : for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
37115 : pDRIPriv->pSAREA->drawableTable[i].stamp = DRIDrawableValidationStamp++;
37121 :DRITransitionToSharedBuffers(ScreenPtr pScreen)
37123 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37124 : DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
37126 : DRIClipNotifyAllDrawables( pScreen );
37128 : if (pDRIInfo->TransitionSingleToMulti3D)
37129 : pDRIInfo->TransitionSingleToMulti3D( pScreen );
37134 :DRITransitionToPrivateBuffers(ScreenPtr pScreen)
37136 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37137 : DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
37139 : DRIClipNotifyAllDrawables( pScreen );
37141 : if (pDRIInfo->TransitionMultiToSingle3D)
37142 : pDRIInfo->TransitionMultiToSingle3D( pScreen );
37147 :DRITransitionTo3d(ScreenPtr pScreen)
37149 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37150 : DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
37152 : DRIClipNotifyAllDrawables( pScreen );
37154 : if (pDRIInfo->TransitionTo3d)
37155 : pDRIInfo->TransitionTo3d( pScreen );
37159 :DRITransitionTo2d(ScreenPtr pScreen)
37161 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37162 : DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
37164 : DRIClipNotifyAllDrawables( pScreen );
37166 : if (pDRIInfo->TransitionTo2d)
37167 : pDRIInfo->TransitionTo2d( pScreen );
37172 :DRIDCNTreeTraversal(WindowPtr pWin, pointer data)
37174 : DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
37176 : if (pDRIDrawablePriv) {
37177 : ScreenPtr pScreen = pWin->drawable.pScreen;
37178 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37180 : if (REGION_NUM_RECTS(&pWin->clipList) > 0) {
37181 : WindowPtr *pDRIWindows = (WindowPtr*)data;
37184 : while (pDRIWindows[i])
37187 : pDRIWindows[i] = pWin;
37189 : pDRIPriv->nrWalked++;
37192 : if (pDRIPriv->nrWindows == pDRIPriv->nrWalked)
37193 : return WT_STOPWALKING;
37196 : return WT_WALKCHILDREN;
37200 :DRIDriverClipNotify(ScreenPtr pScreen)
37202 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37204 : if (pDRIPriv->pDriverInfo->ClipNotify) {
37205 : WindowPtr *pDRIWindows = xcalloc(sizeof(WindowPtr), pDRIPriv->nrWindows);
37206 : DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
37208 : if (pDRIPriv->nrWindows > 0) {
37209 : pDRIPriv->nrWalked = 0;
37210 : TraverseTree(WindowTable[pScreen->myNum], DRIDCNTreeTraversal,
37211 : (pointer)pDRIWindows);
37214 : pDRIInfo->ClipNotify(pScreen, pDRIWindows, pDRIPriv->nrWindows);
37216 : xfree(pDRIWindows);
37221 :DRIIncreaseNumberVisible(ScreenPtr pScreen)
37223 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37225 : switch (++pDRIPriv->nrWindowsVisible) {
37227 : DRITransitionTo3d( pScreen );
37230 : DRITransitionToSharedBuffers( pScreen );
37236 : DRIDriverClipNotify(pScreen);
37240 :DRIDecreaseNumberVisible(ScreenPtr pScreen)
37242 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37244 : switch (--pDRIPriv->nrWindowsVisible) {
37246 : DRITransitionTo2d( pScreen );
37249 : DRITransitionToPrivateBuffers( pScreen );
37255 : DRIDriverClipNotify(pScreen);
37259 :DRICreateDrawable(ScreenPtr pScreen, Drawable id,
37260 : DrawablePtr pDrawable, drm_drawable_t * hHWDrawable)
37262 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37263 : DRIDrawablePrivPtr pDRIDrawablePriv;
37266 : if (pDrawable->type == DRAWABLE_WINDOW) {
37267 : pWin = (WindowPtr)pDrawable;
37268 : if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
37269 : pDRIDrawablePriv->refCount++;
37271 : if (!pDRIDrawablePriv->hwDrawable) {
37272 : drmCreateDrawable(pDRIPriv->drmFD, &pDRIDrawablePriv->hwDrawable);
37276 : /* allocate a DRI Window Private record */
37277 : if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) {
37281 : /* Only create a drm_drawable_t once */
37282 : if (drmCreateDrawable(pDRIPriv->drmFD,
37283 : &pDRIDrawablePriv->hwDrawable)) {
37284 : xfree(pDRIDrawablePriv);
37288 : /* add it to the list of DRI drawables for this screen */
37289 : pDRIDrawablePriv->pScreen = pScreen;
37290 : pDRIDrawablePriv->refCount = 1;
37291 : pDRIDrawablePriv->drawableIndex = -1;
37292 : pDRIDrawablePriv->nrects = REGION_NUM_RECTS(&pWin->clipList);
37294 : /* save private off of preallocated index */
37295 : pWin->devPrivates[DRIWindowPrivIndex].ptr =
37296 : (pointer)pDRIDrawablePriv;
37298 : pDRIPriv->nrWindows++;
37300 : if (pDRIDrawablePriv->nrects)
37301 : DRIIncreaseNumberVisible(pScreen);
37303 : /* track this in case this window is destroyed */
37304 : AddResource(id, DRIDrawablePrivResType, (pointer)pWin);
37307 : if (pDRIDrawablePriv->hwDrawable) {
37308 : drmUpdateDrawableInfo(pDRIPriv->drmFD,
37309 : pDRIDrawablePriv->hwDrawable,
37310 : DRM_DRAWABLE_CLIPRECTS,
37311 : REGION_NUM_RECTS(&pWin->clipList),
37312 : REGION_RECTS(&pWin->clipList));
37313 : *hHWDrawable = pDRIDrawablePriv->hwDrawable;
37316 : else { /* pixmap (or for GLX 1.3, a PBuffer) */
37325 :DRIDestroyDrawable(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable)
37327 : DRIDrawablePrivPtr pDRIDrawablePriv;
37331 : if (pDrawable->type == DRAWABLE_WINDOW) {
37332 : pWin = (WindowPtr)pDrawable;
37333 : pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
37334 : pDRIDrawablePriv->refCount--;
37335 : if (pDRIDrawablePriv->refCount <= 0) {
37336 : /* This calls back DRIDrawablePrivDelete which frees private area */
37337 : FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
37340 : else { /* pixmap (or for GLX 1.3, a PBuffer) */
37349 :DRIDrawablePrivDelete(pointer pResource, XID id)
37351 : DrawablePtr pDrawable = (DrawablePtr)pResource;
37352 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
37353 : DRIDrawablePrivPtr pDRIDrawablePriv;
37356 : if (pDrawable->type == DRAWABLE_WINDOW) {
37357 : pWin = (WindowPtr)pDrawable;
37358 : pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
37360 : if (pDRIDrawablePriv->drawableIndex != -1) {
37361 : /* bump stamp to force outstanding 3D requests to resync */
37362 : pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
37363 : = DRIDrawableValidationStamp++;
37365 : /* release drawable table entry */
37366 : pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
37369 : if (drmDestroyDrawable(pDRIPriv->drmFD,
37370 : pDRIDrawablePriv->hwDrawable)) {
37374 : xfree(pDRIDrawablePriv);
37375 : pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
37377 : pDRIPriv->nrWindows--;
37379 : if (REGION_NUM_RECTS(&pWin->clipList))
37380 : DRIDecreaseNumberVisible(pDrawable->pScreen);
37382 : else { /* pixmap (or for GLX 1.3, a PBuffer) */
37391 :DRIGetDrawableInfo(ScreenPtr pScreen,
37392 : DrawablePtr pDrawable,
37393 : unsigned int* index,
37394 : unsigned int* stamp,
37399 : int* numClipRects,
37400 : drm_clip_rect_t ** pClipRects,
37403 : int* numBackClipRects,
37404 : drm_clip_rect_t ** pBackClipRects)
37406 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37407 : DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv;
37408 : WindowPtr pWin, pOldWin;
37412 : printf("maxDrawableTableEntry = %d\n", pDRIPriv->pDriverInfo->maxDrawableTableEntry);
37415 : if (pDrawable->type == DRAWABLE_WINDOW) {
37416 : pWin = (WindowPtr)pDrawable;
37417 : if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
37419 : /* Manage drawable table */
37420 : if (pDRIDrawablePriv->drawableIndex == -1) { /* load SAREA table */
37422 : /* Search table for empty entry */
37424 : while (i < pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
37425 : if (!(pDRIPriv->DRIDrawables[i])) {
37426 : pDRIPriv->DRIDrawables[i] = pDrawable;
37427 : pDRIDrawablePriv->drawableIndex = i;
37428 : pDRIPriv->pSAREA->drawableTable[i].stamp =
37429 : DRIDrawableValidationStamp++;
37435 : /* Search table for oldest entry */
37436 : if (i == pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
37437 : unsigned int oldestStamp = ~0;
37438 : int oldestIndex = 0;
37439 : i = pDRIPriv->pDriverInfo->maxDrawableTableEntry;
37441 : if (pDRIPriv->pSAREA->drawableTable[i].stamp <
37445 : pDRIPriv->pSAREA->drawableTable[i].stamp;
37448 : pDRIDrawablePriv->drawableIndex = oldestIndex;
37450 : /* release oldest drawable table entry */
37451 : pOldWin = (WindowPtr)pDRIPriv->DRIDrawables[oldestIndex];
37452 : pOldDrawPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pOldWin);
37453 : pOldDrawPriv->drawableIndex = -1;
37455 : /* claim drawable table entry */
37456 : pDRIPriv->DRIDrawables[oldestIndex] = pDrawable;
37458 : /* validate SAREA entry */
37459 : pDRIPriv->pSAREA->drawableTable[oldestIndex].stamp =
37460 : DRIDrawableValidationStamp++;
37462 : /* check for stamp wrap around */
37463 : if (oldestStamp > DRIDrawableValidationStamp) {
37465 : /* walk SAREA table and invalidate all drawables */
37467 : i < pDRIPriv->pDriverInfo->maxDrawableTableEntry;
37469 : pDRIPriv->pSAREA->drawableTable[i].stamp =
37470 : DRIDrawableValidationStamp++;
37475 : /* If the driver wants to be notified when the index is
37476 : * set for a drawable, let it know now.
37478 : if (pDRIPriv->pDriverInfo->SetDrawableIndex)
37479 : pDRIPriv->pDriverInfo->SetDrawableIndex(pWin,
37480 : pDRIDrawablePriv->drawableIndex);
37482 : /* reinit drawable ID if window is visible */
37483 : if ((pWin->viewable) &&
37484 : (pDRIPriv->pDriverInfo->bufferRequests != DRI_NO_WINDOWS))
37486 : (*pDRIPriv->pDriverInfo->InitBuffers)(pWin,
37487 : &pWin->clipList, pDRIDrawablePriv->drawableIndex);
37491 : *index = pDRIDrawablePriv->drawableIndex;
37492 : *stamp = pDRIPriv->pSAREA->drawableTable[*index].stamp;
37493 : *X = (int)(pWin->drawable.x);
37494 : *Y = (int)(pWin->drawable.y);
37496 : *W = (int)(pWin->winSize.extents.x2 - pWin->winSize.extents.x1);
37497 : *H = (int)(pWin->winSize.extents.y2 - pWin->winSize.extents.y1);
37499 : *W = (int)(pWin->drawable.width);
37500 : *H = (int)(pWin->drawable.height);
37501 : *numClipRects = REGION_NUM_RECTS(&pWin->clipList);
37502 : *pClipRects = (drm_clip_rect_t *)REGION_RECTS(&pWin->clipList);
37504 : if (!*numClipRects && pDRIPriv->fullscreen) {
37505 : /* use fake full-screen clip rect */
37506 : pDRIPriv->fullscreen_rect.x1 = *X;
37507 : pDRIPriv->fullscreen_rect.y1 = *Y;
37508 : pDRIPriv->fullscreen_rect.x2 = *X + *W;
37509 : pDRIPriv->fullscreen_rect.y2 = *Y + *H;
37511 : *numClipRects = 1;
37512 : *pClipRects = &pDRIPriv->fullscreen_rect;
37518 : if (pDRIPriv->nrWindowsVisible == 1 && *numClipRects) {
37519 : /* Use a single cliprect. */
37523 : int x1 = x0 + *W;
37524 : int y1 = y0 + *H;
37526 : if (x0 < 0) x0 = 0;
37527 : if (y0 < 0) y0 = 0;
37528 : if (x1 > pScreen->width) x1 = pScreen->width;
37529 : if (y1 > pScreen->height) y1 = pScreen->height;
37531 : if (y0 >= y1 || x0 >= x1) {
37532 : *numBackClipRects = 0;
37533 : *pBackClipRects = NULL;
37535 : pDRIPriv->private_buffer_rect.x1 = x0;
37536 : pDRIPriv->private_buffer_rect.y1 = y0;
37537 : pDRIPriv->private_buffer_rect.x2 = x1;
37538 : pDRIPriv->private_buffer_rect.y2 = y1;
37540 : *numBackClipRects = 1;
37541 : *pBackClipRects = &(pDRIPriv->private_buffer_rect);
37544 : /* Use the frontbuffer cliprects for back buffers. */
37545 : *numBackClipRects = 0;
37546 : *pBackClipRects = 0;
37550 : /* Not a DRIDrawable */
37554 : else { /* pixmap (or for GLX 1.3, a PBuffer) */
37563 :DRIGetDeviceInfo(ScreenPtr pScreen,
37564 : drm_handle_t * hFrameBuffer,
37568 : int* devPrivateSize,
37569 : void** pDevPrivate)
37571 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37573 : *hFrameBuffer = pDRIPriv->hFrameBuffer;
37575 : *fbSize = pDRIPriv->pDriverInfo->frameBufferSize;
37576 : *fbStride = pDRIPriv->pDriverInfo->frameBufferStride;
37577 : *devPrivateSize = pDRIPriv->pDriverInfo->devPrivateSize;
37578 : *pDevPrivate = pDRIPriv->pDriverInfo->devPrivate;
37584 :DRICreateInfoRec(void)
37586 : DRIInfoPtr inforec = (DRIInfoPtr)xcalloc(1, sizeof(DRIInfoRec));
37587 : if (!inforec) return NULL;
37589 : /* Initialize defaults */
37590 : inforec->busIdString = NULL;
37592 : /* Wrapped function defaults */
37593 : inforec->wrap.WakeupHandler = DRIDoWakeupHandler;
37594 : inforec->wrap.BlockHandler = DRIDoBlockHandler;
37595 : inforec->wrap.WindowExposures = DRIWindowExposures;
37596 : inforec->wrap.CopyWindow = DRICopyWindow;
37597 : inforec->wrap.ValidateTree = DRIValidateTree;
37598 : inforec->wrap.PostValidateTree = DRIPostValidateTree;
37599 : inforec->wrap.ClipNotify = DRIClipNotify;
37600 : inforec->wrap.AdjustFrame = DRIAdjustFrame;
37602 : inforec->TransitionTo2d = 0;
37603 : inforec->TransitionTo3d = 0;
37604 : inforec->SetDrawableIndex = 0;
37610 :DRIDestroyInfoRec(DRIInfoPtr DRIInfo)
37612 : if (DRIInfo->busIdString) xfree(DRIInfo->busIdString);
37613 : xfree((char*)DRIInfo);
37618 :DRIWakeupHandler(pointer wakeupData, int result, pointer pReadmask)
37622 : for (i = 0; i < screenInfo.numScreens; i++) {
37623 : ScreenPtr pScreen = screenInfo.screens[i];
37624 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37627 : pDRIPriv->pDriverInfo->wrap.WakeupHandler)
37628 : (*pDRIPriv->pDriverInfo->wrap.WakeupHandler)(i, wakeupData,
37629 : result, pReadmask);
37634 :DRIBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
37638 : for (i = 0; i < screenInfo.numScreens; i++) {
37639 : ScreenPtr pScreen = screenInfo.screens[i];
37640 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37643 : pDRIPriv->pDriverInfo->wrap.BlockHandler)
37644 : (*pDRIPriv->pDriverInfo->wrap.BlockHandler)(i, blockData,
37645 : pTimeout, pReadmask);
37650 :DRIDoWakeupHandler(int screenNum, pointer wakeupData,
37651 : unsigned long result, pointer pReadmask)
37653 : ScreenPtr pScreen = screenInfo.screens[screenNum];
37654 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37656 : DRILock(pScreen, 0);
37657 : if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
37658 : /* hide X context by swapping 2D component here */
37659 : (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
37662 : pDRIPriv->partial3DContextStore,
37664 : pDRIPriv->hiddenContextStore);
37669 :DRIDoBlockHandler(int screenNum, pointer blockData,
37670 : pointer pTimeout, pointer pReadmask)
37672 : ScreenPtr pScreen = screenInfo.screens[screenNum];
37673 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37675 : if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
37676 : /* hide X context by swapping 2D component here */
37677 : (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
37682 : pDRIPriv->partial3DContextStore);
37685 : if (pDRIPriv->windowsTouched)
37686 : DRM_SPINUNLOCK(&pDRIPriv->pSAREA->drawable_lock, 1);
37687 : pDRIPriv->windowsTouched = FALSE;
37689 : DRIUnlock(pScreen);
37693 :DRISwapContext(int drmFD, void *oldctx, void *newctx)
37695 : DRIContextPrivPtr oldContext = (DRIContextPrivPtr)oldctx;
37696 : DRIContextPrivPtr newContext = (DRIContextPrivPtr)newctx;
37697 : ScreenPtr pScreen = newContext->pScreen;
37698 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37699 : void* oldContextStore = NULL;
37700 : DRIContextType oldContextType;
37701 : void* newContextStore = NULL;
37702 : DRIContextType newContextType;
37703 : DRISyncType syncType;
37705 : static int count = 0;
37707 : if (!newContext) {
37708 : DRIDrvMsg(pScreen->myNum, X_ERROR,
37709 : "[DRI] Context Switch Error: oldContext=%x, newContext=%x\n",
37710 : oldContext, newContext);
37714 : /* usefull for debugging, just print out after n context switches */
37715 : if (!count || !(count % 1)) {
37716 : DRIDrvMsg(pScreen->myNum, X_INFO,
37717 : "[DRI] Context switch %5d from %p/0x%08x (%d)\n",
37720 : oldContext ? oldContext->flags : 0,
37721 : oldContext ? oldContext->hwContext : -1);
37722 : DRIDrvMsg(pScreen->myNum, X_INFO,
37723 : "[DRI] Context switch %5d to %p/0x%08x (%d)\n",
37726 : newContext ? newContext->flags : 0,
37727 : newContext ? newContext->hwContext : -1);
37732 : if (!pDRIPriv->pDriverInfo->SwapContext) {
37733 : DRIDrvMsg(pScreen->myNum, X_ERROR,
37734 : "[DRI] DDX driver missing context swap call back\n");
37738 : if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
37740 : /* only 3D contexts are swapped in this case */
37741 : if (oldContext) {
37742 : oldContextStore = DRIGetContextStore(oldContext);
37743 : oldContext->valid3D = TRUE;
37744 : oldContextType = DRI_3D_CONTEXT;
37746 : oldContextType = DRI_NO_CONTEXT;
37748 : newContextStore = DRIGetContextStore(newContext);
37749 : if ((newContext->valid3D) &&
37750 : (newContext->hwContext != pDRIPriv->myContext)) {
37751 : newContextType = DRI_3D_CONTEXT;
37754 : newContextType = DRI_2D_CONTEXT;
37756 : syncType = DRI_3D_SYNC;
37758 : else /* default: driverSwapMethod == DRI_SERVER_SWAP */ {
37760 : /* optimize 2D context swaps */
37762 : if (newContext->flags & DRI_CONTEXT_2DONLY) {
37763 : /* go from 3D context to 2D context and only save 2D
37764 : * subset of 3D state
37766 : oldContextStore = DRIGetContextStore(oldContext);
37767 : oldContextType = DRI_2D_CONTEXT;
37768 : newContextStore = DRIGetContextStore(newContext);
37769 : newContextType = DRI_2D_CONTEXT;
37770 : syncType = DRI_3D_SYNC;
37771 : pDRIPriv->lastPartial3DContext = oldContext;
37773 : else if (oldContext->flags & DRI_CONTEXT_2DONLY) {
37774 : if (pDRIPriv->lastPartial3DContext == newContext) {
37775 : /* go from 2D context back to previous 3D context and
37776 : * only restore 2D subset of previous 3D state
37778 : oldContextStore = DRIGetContextStore(oldContext);
37779 : oldContextType = DRI_2D_CONTEXT;
37780 : newContextStore = DRIGetContextStore(newContext);
37781 : newContextType = DRI_2D_CONTEXT;
37782 : syncType = DRI_2D_SYNC;
37785 : /* go from 2D context to a different 3D context */
37787 : /* call DDX driver to do partial restore */
37788 : oldContextStore = DRIGetContextStore(oldContext);
37789 : newContextStore =
37790 : DRIGetContextStore(pDRIPriv->lastPartial3DContext);
37791 : (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
37796 : newContextStore);
37798 : /* now setup for a complete 3D swap */
37799 : oldContextStore = newContextStore;
37800 : oldContext->valid3D = TRUE;
37801 : oldContextType = DRI_3D_CONTEXT;
37802 : newContextStore = DRIGetContextStore(newContext);
37803 : if ((newContext->valid3D) &&
37804 : (newContext->hwContext != pDRIPriv->myContext)) {
37805 : newContextType = DRI_3D_CONTEXT;
37808 : newContextType = DRI_2D_CONTEXT;
37810 : syncType = DRI_NO_SYNC;
37814 : /* now setup for a complete 3D swap */
37815 : oldContextStore = newContextStore;
37816 : oldContext->valid3D = TRUE;
37817 : oldContextType = DRI_3D_CONTEXT;
37818 : newContextStore = DRIGetContextStore(newContext);
37819 : if ((newContext->valid3D) &&
37820 : (newContext->hwContext != pDRIPriv->myContext)) {
37821 : newContextType = DRI_3D_CONTEXT;
37824 : newContextType = DRI_2D_CONTEXT;
37826 : syncType = DRI_3D_SYNC;
37830 : /* call DDX driver to perform the swap */
37831 : (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
37836 : newContextStore);
37840 :DRIGetContextStore(DRIContextPrivPtr context)
37842 : return((void *)context->pContextStore);
37846 :DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
37848 : ScreenPtr pScreen = pWin->drawable.pScreen;
37849 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37850 : DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
37852 : if(pDRIDrawablePriv) {
37853 : (*pDRIPriv->pDriverInfo->InitBuffers)(pWin, prgn,
37854 : pDRIDrawablePriv->drawableIndex);
37857 : /* call lower wrapped functions */
37858 : if (pDRIPriv && pDRIPriv->wrap.WindowExposures) {
37861 : pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
37863 : /* call lower layers */
37864 : (*pScreen->WindowExposures)(pWin, prgn, bsreg);
37867 : pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
37868 : pScreen->WindowExposures = DRIWindowExposures;
37874 :DRITreeTraversal(WindowPtr pWin, pointer data)
37876 : DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
37878 : if(pDRIDrawablePriv) {
37879 : ScreenPtr pScreen = pWin->drawable.pScreen;
37880 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37882 : if(REGION_NUM_RECTS(&(pWin->clipList)) > 0) {
37883 : RegionPtr reg = (RegionPtr)data;
37885 : REGION_UNION(pScreen, reg, reg, &(pWin->clipList));
37886 : pDRIPriv->nrWalked++;
37889 : if(pDRIPriv->nrWindows == pDRIPriv->nrWalked)
37890 : return WT_STOPWALKING;
37892 : return WT_WALKCHILDREN;
37896 :DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
37898 : ScreenPtr pScreen = pWin->drawable.pScreen;
37899 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37901 : if(!pDRIPriv) return;
37903 : if(pDRIPriv->nrWindowsVisible > 0) {
37906 : REGION_NULL(pScreen, ®);
37907 : pDRIPriv->nrWalked = 0;
37908 : TraverseTree(pWin, DRITreeTraversal, (pointer)(®));
37910 : if(REGION_NOTEMPTY(pScreen, ®)) {
37911 : REGION_TRANSLATE(pScreen, ®, ptOldOrg.x - pWin->drawable.x,
37912 : ptOldOrg.y - pWin->drawable.y);
37913 : REGION_INTERSECT(pScreen, ®, ®, prgnSrc);
37915 : /* The MoveBuffers interface is not ideal */
37916 : (*pDRIPriv->pDriverInfo->MoveBuffers)(pWin, ptOldOrg, ®,
37917 : pDRIPriv->pDriverInfo->ddxDrawableTableEntry);
37920 : REGION_UNINIT(pScreen, ®);
37923 : /* call lower wrapped functions */
37924 : if(pDRIPriv->wrap.CopyWindow) {
37926 : pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
37928 : /* call lower layers */
37929 : (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
37932 : pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
37933 : pScreen->CopyWindow = DRICopyWindow;
37938 :DRIGetSecs(long *secs, long *usecs)
37940 : struct timeval tv;
37942 : gettimeofday(&tv, NULL);
37944 : *secs = tv.tv_sec;
37945 : *usecs = tv.tv_usec;
37948 :static unsigned long
37949 :DRIComputeMilliSeconds(unsigned long s_secs, unsigned long s_usecs,
37950 : unsigned long f_secs, unsigned long f_usecs)
37952 : if (f_usecs < s_usecs) {
37954 : f_usecs += 1000000;
37956 : return (f_secs - s_secs) * 1000 + (f_usecs - s_usecs) / 1000;
37960 :DRISpinLockTimeout(drmLock *lock, int val, unsigned long timeout /* in mS */)
37962 : int count = 10000;
37963 :#if !defined(__alpha__) && !defined(__powerpc__)
37968 : long s_secs, s_usecs;
37969 : long f_secs, f_usecs;
37973 : DRIGetSecs(&s_secs, &s_usecs);
37976 : DRM_SPINLOCK_COUNT(lock, val, count, ret);
37977 : if (!ret) return; /* Got lock */
37978 : DRIGetSecs(&f_secs, &f_usecs);
37979 : msecs = DRIComputeMilliSeconds(s_secs, s_usecs, f_secs, f_usecs);
37980 : if (msecs - prev < 250) count *= 2; /* Not more than 0.5S */
37981 : } while (msecs < timeout);
37983 : /* Didn't get lock, so take it. The worst
37984 : that can happen is that there is some
37985 : garbage written to the wrong part of the
37986 : framebuffer that a refresh will repair.
37987 : That's undesirable, but better than
37988 : locking the server. This should be a
37989 : very rare event. */
37990 : DRM_SPINLOCK_TAKE(lock, val);
37994 :DRILockTree(ScreenPtr pScreen)
37996 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
37998 : if(!pDRIPriv) return;
38000 : /* Restore the last known 3D context if the X context is hidden */
38001 : if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
38002 : (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
38007 : pDRIPriv->partial3DContextStore);
38010 : /* Call kernel to release lock */
38011 : DRIUnlock(pScreen);
38013 : /* Grab drawable spin lock: a time out between 10 and 30 seconds is
38014 : appropriate, since this should never time out except in the case of
38015 : client death while the lock is being held. The timeout must be
38016 : greater than any reasonable rendering time. */
38017 : DRISpinLockTimeout(&pDRIPriv->pSAREA->drawable_lock, 1, 10000); /*10 secs*/
38019 : /* Call kernel flush outstanding buffers and relock */
38020 : DRILock(pScreen, DRM_LOCK_QUIESCENT|DRM_LOCK_FLUSH_ALL);
38022 : /* Switch back to our 2D context if the X context is hidden */
38023 : if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
38024 : /* hide X context by swapping 2D component here */
38025 : (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
38028 : pDRIPriv->partial3DContextStore,
38030 : pDRIPriv->hiddenContextStore);
38035 :DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
38037 : ScreenPtr pScreen = pParent->drawable.pScreen;
38038 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38040 : int returnValue = 1; /* always return 1, not checked by dix/window.c */
38042 : if(!pDRIPriv) return returnValue;
38044 : /* call lower wrapped functions */
38045 : if(pDRIPriv->wrap.ValidateTree) {
38047 : pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
38049 : /* call lower layers */
38050 : returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
38053 : pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
38054 : pScreen->ValidateTree = DRIValidateTree;
38057 : return returnValue;
38061 :DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
38063 : ScreenPtr pScreen;
38064 : DRIScreenPrivPtr pDRIPriv;
38067 : pScreen = pParent->drawable.pScreen;
38069 : pScreen = pChild->drawable.pScreen;
38071 : if(!(pDRIPriv = DRI_SCREEN_PRIV(pScreen))) return;
38073 : if (pDRIPriv->wrap.PostValidateTree) {
38075 : pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
38077 : /* call lower layers */
38078 : (*pScreen->PostValidateTree)(pParent, pChild, kind);
38081 : pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
38082 : pScreen->PostValidateTree = DRIPostValidateTree;
38087 :DRIClipNotify(WindowPtr pWin, int dx, int dy)
38089 : ScreenPtr pScreen = pWin->drawable.pScreen;
38090 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38091 : DRIDrawablePrivPtr pDRIDrawablePriv;
38093 : if(!pDRIPriv) return;
38095 : if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
38096 : int nrects = REGION_NUM_RECTS(&pWin->clipList);
38098 : if(!pDRIPriv->windowsTouched) {
38099 : DRILockTree(pScreen);
38100 : pDRIPriv->windowsTouched = TRUE;
38103 : if (nrects && !pDRIDrawablePriv->nrects)
38104 : DRIIncreaseNumberVisible(pScreen);
38105 : else if (!nrects && pDRIDrawablePriv->nrects)
38106 : DRIDecreaseNumberVisible(pScreen);
38108 : DRIDriverClipNotify(pScreen);
38110 : pDRIDrawablePriv->nrects = nrects;
38112 : pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
38113 : = DRIDrawableValidationStamp++;
38115 : drmUpdateDrawableInfo(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable,
38116 : DRM_DRAWABLE_CLIPRECTS,
38117 : nrects, REGION_RECTS(&pWin->clipList));
38120 : /* call lower wrapped functions */
38121 : if(pDRIPriv->wrap.ClipNotify) {
38124 : pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
38126 : /* call lower layers */
38127 : (*pScreen->ClipNotify)(pWin, dx, dy);
38130 : pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
38131 : pScreen->ClipNotify = DRIClipNotify;
38136 :DRIGetDrawableIndex(WindowPtr pWin)
38138 : ScreenPtr pScreen = pWin->drawable.pScreen;
38139 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38140 : DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
38143 : if (pDRIDrawablePriv) {
38144 : index = pDRIDrawablePriv->drawableIndex;
38147 : index = pDRIPriv->pDriverInfo->ddxDrawableTableEntry;
38154 :DRIGetDrawableStamp(ScreenPtr pScreen, CARD32 drawable_index)
38156 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38157 : return pDRIPriv->pSAREA->drawableTable[drawable_index].stamp;
38162 :DRIPrintDrawableLock(ScreenPtr pScreen, char *msg)
38164 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38166 : ErrorF("%s: %d\n", msg, pDRIPriv->pSAREA->drawable_lock.lock);
38170 :DRILock(ScreenPtr pScreen, int flags)
38172 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38174 : if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
38176 : if (!*pDRIPriv->pLockRefCount) {
38177 : DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
38178 : *pDRIPriv->pLockingContext = pDRIPriv->myContext;
38179 : } else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
38180 : DRIDrvMsg(pScreen->myNum, X_ERROR,
38181 : "[DRI] Locking deadlock.\n"
38182 : "\tAlready locked with context %d,\n"
38183 : "\ttrying to lock with context %d.\n",
38184 : pDRIPriv->pLockingContext,
38185 : pDRIPriv->myContext);
38187 : (*pDRIPriv->pLockRefCount)++;
38191 :DRIUnlock(ScreenPtr pScreen)
38193 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38195 : if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
38197 : if (*pDRIPriv->pLockRefCount > 0) {
38198 : if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
38199 : DRIDrvMsg(pScreen->myNum, X_ERROR,
38200 : "[DRI] Unlocking inconsistency:\n"
38201 : "\tContext %d trying to unlock lock held by context %d\n",
38202 : pDRIPriv->pLockingContext,
38203 : pDRIPriv->myContext);
38205 : (*pDRIPriv->pLockRefCount)--;
38207 : DRIDrvMsg(pScreen->myNum, X_ERROR,
38208 : "DRIUnlock called when not locked.\n");
38211 : if (! *pDRIPriv->pLockRefCount)
38212 : DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
38216 :DRIGetSAREAPrivate(ScreenPtr pScreen)
38217 6 0.0065 :{ /* DRIGetSAREAPrivate total: 25 0.0272 */
38218 4 0.0044 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38219 2 0.0022 : if (!pDRIPriv) return 0;
38221 1 0.0011 : return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec));
38225 :DRIGetContext(ScreenPtr pScreen)
38226 8 0.0087 :{ /* DRIGetContext total: 16 0.0174 */
38227 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38228 1 0.0011 : if (!pDRIPriv) return 0;
38230 : return pDRIPriv->myContext;
38234 :DRIGetTexOffsetFuncs(ScreenPtr pScreen,
38235 : DRITexOffsetStartProcPtr *texOffsetStartFunc,
38236 : DRITexOffsetFinishProcPtr *texOffsetFinishFunc)
38238 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38240 : if (!pDRIPriv) return;
38242 : *texOffsetStartFunc = pDRIPriv->pDriverInfo->texOffsetStart;
38243 : *texOffsetFinishFunc = pDRIPriv->pDriverInfo->texOffsetFinish;
38246 :/* This lets get at the unwrapped functions so that they can correctly
38247 : * call the lowerlevel functions, and choose whether they will be
38248 : * called at every level of recursion (eg in validatetree).
38250 :DRIWrappedFuncsRec *
38251 :DRIGetWrappedFuncs(ScreenPtr pScreen)
38253 : return &(DRI_SCREEN_PRIV(pScreen)->wrap);
38256 :/* note that this returns the library version, not the protocol version */
38258 :DRIQueryVersion(int *majorVersion,
38259 : int *minorVersion,
38260 : int *patchVersion)
38262 : *majorVersion = DRIINFO_MAJOR_VERSION;
38263 : *minorVersion = DRIINFO_MINOR_VERSION;
38264 : *patchVersion = DRIINFO_PATCH_VERSION;
38268 :_DRIAdjustFrame(ScrnInfoPtr pScrn, DRIScreenPrivPtr pDRIPriv, int x, int y)
38270 : pDRIPriv->pSAREA->frame.x = x;
38271 : pDRIPriv->pSAREA->frame.y = y;
38272 : pDRIPriv->pSAREA->frame.width = pScrn->frameX1 - x + 1;
38273 : pDRIPriv->pSAREA->frame.height = pScrn->frameY1 - y + 1;
38277 :DRIAdjustFrame(int scrnIndex, int x, int y, int flags)
38279 : ScreenPtr pScreen = screenInfo.screens[scrnIndex];
38280 : DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
38281 : ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
38284 : if (!pDRIPriv || !pDRIPriv->pSAREA) {
38285 : DRIDrvMsg(scrnIndex, X_ERROR, "[DRI] No SAREA (%p %p)\n",
38286 : pDRIPriv, pDRIPriv ? pDRIPriv->pSAREA : NULL);
38290 : if (pDRIPriv->fullscreen) {
38291 : /* Fix up frame */
38292 : pScrn->frameX0 = pDRIPriv->pSAREA->frame.x;
38293 : pScrn->frameY0 = pDRIPriv->pSAREA->frame.y;
38294 : pScrn->frameX1 = pScrn->frameX0 + pDRIPriv->pSAREA->frame.width - 1;
38295 : pScrn->frameY1 = pScrn->frameY0 + pDRIPriv->pSAREA->frame.height - 1;
38297 : /* Fix up cursor */
38298 : miPointerPosition(&px, &py);
38299 : if (px < pScrn->frameX0) px = pScrn->frameX0;
38300 : if (px > pScrn->frameX1) px = pScrn->frameX1;
38301 : if (py < pScrn->frameY0) py = pScrn->frameY0;
38302 : if (py > pScrn->frameY1) py = pScrn->frameY1;
38303 : pScreen->SetCursorPosition(pScreen, px, py, TRUE);
38307 : if (pDRIPriv->wrap.AdjustFrame) {
38309 : pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
38310 : /* call lower layers */
38311 : (*pScrn->AdjustFrame)(scrnIndex, x, y, flags);
38313 : pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
38314 : pScrn->AdjustFrame = DRIAdjustFrame;
38317 : _DRIAdjustFrame(pScrn, pDRIPriv, x, y);
38321 : * DRIMoveBuffersHelper swaps the regions rects in place leaving you
38322 : * a region with the rects in the order that you need to blit them,
38323 : * but it is possibly (likely) an invalid region afterwards. If you
38324 : * need to use the region again for anything you have to call
38325 : * REGION_VALIDATE on it, or better yet, save a copy first.
38329 :DRIMoveBuffersHelper(
38330 : ScreenPtr pScreen,
38338 : BoxPtr extents, pbox, firstBox, lastBox;
38342 : extents = REGION_EXTENTS(pScreen, reg);
38343 : nbox = REGION_NUM_RECTS(reg);
38344 : pbox = REGION_RECTS(reg);
38346 : if((dy > 0) && (dy < (extents->y2 - extents->y1))) {
38350 : lastBox = pbox + nbox - 1;
38351 : while((unsigned long)firstBox < (unsigned long)lastBox) {
38352 : tmpBox = *firstBox;
38353 : *firstBox = *lastBox;
38354 : *lastBox = tmpBox;
38359 : } else *ydir = 1;
38361 : if((dx > 0) && (dx < (extents->x2 - extents->x1))) {
38364 : firstBox = lastBox = pbox;
38368 : if(pbox->y1 == y) lastBox++;
38370 : while((unsigned long)firstBox < (unsigned long)lastBox) {
38371 : tmpBox = *firstBox;
38372 : *firstBox = *lastBox;
38373 : *lastBox = tmpBox;
38378 : firstBox = lastBox = pbox;
38382 : while((unsigned long)firstBox < (unsigned long)lastBox) {
38383 : tmpBox = *firstBox;
38384 : *firstBox = *lastBox;
38385 : *lastBox = tmpBox;
38390 : } else *xdir = 1;
38395 :DRICreatePCIBusID(pciVideoPtr PciInfo)
38401 : busID = xalloc(20);
38402 : if (busID == NULL)
38405 : tag = pciTag(PciInfo->bus, PciInfo->device, PciInfo->func);
38406 : domain = xf86GetPciDomain(tag);
38407 : snprintf(busID, 20, "pci:%04x:%02x:%02x.%d", domain,
38408 : PCI_BUS_NO_DOMAIN(PciInfo->bus), PciInfo->device, PciInfo->func);
38412 :static void drmSIGIOHandler(int interrupt, void *closure)
38414 : unsigned long key;
38418 : typedef void (*_drmCallback)(int, void *, void *);
38420 : drm_context_t old;
38421 : drm_context_t new;
38425 : drmHashEntry *entry;
38426 : void *hash_table;
38428 : hash_table = drmGetHashTable();
38430 : if (!hash_table) return;
38431 : if (drmHashFirst(hash_table, &key, &value)) {
38435 : fprintf(stderr, "Trying %d\n", entry->fd);
38437 : if ((count = read(entry->fd, buf, sizeof(buf))) > 0) {
38438 : buf[count] = '\0';
38440 : fprintf(stderr, "Got %s\n", buf);
38443 : for (pt = buf; *pt != ' '; ++pt); /* Find first space */
38445 : old = strtol(pt, &pt, 0);
38446 : new = strtol(pt, NULL, 0);
38447 : oldctx = drmGetContextTag(entry->fd, old);
38448 : newctx = drmGetContextTag(entry->fd, new);
38450 : fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
38452 : ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
38453 : ctx.handle = new;
38454 : ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
38456 : } while (drmHashNext(hash_table, &key, &value));
38461 :int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
38463 : drmHashEntry *entry;
38465 : entry = drmGetEntry(fd);
38468 : return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
38471 :int drmRemoveSIGIOHandler(int fd)
38473 : drmHashEntry *entry = drmGetEntry(fd);
38477 : return xf86RemoveSIGIOHandler(fd);
38480 * Total samples for file : "/home/cworth/src/xorg/xserver/render/filter.c"
38487 : * Copyright © 2002 Keith Packard
38489 : * Permission to use, copy, modify, distribute, and sell this software and its
38490 : * documentation for any purpose is hereby granted without fee, provided that
38491 : * the above copyright notice appear in all copies and that both that
38492 : * copyright notice and this permission notice appear in supporting
38493 : * documentation, and that the name of Keith Packard not be used in
38494 : * advertising or publicity pertaining to distribution of the software without
38495 : * specific, written prior permission. Keith Packard makes no
38496 : * representations about the suitability of this software for any purpose. It
38497 : * is provided "as is" without express or implied warranty.
38499 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
38500 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
38501 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
38502 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
38503 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38504 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
38505 : * PERFORMANCE OF THIS SOFTWARE.
38508 :#ifdef HAVE_DIX_CONFIG_H
38509 :#include <dix-config.h>
38513 :#include "scrnintstr.h"
38515 :#include "regionstr.h"
38516 :#include "validate.h"
38517 :#include "windowstr.h"
38518 :#include "input.h"
38519 :#include "resource.h"
38520 :#include "colormapst.h"
38521 :#include "cursorstr.h"
38522 :#include "dixstruct.h"
38523 :#include "gcstruct.h"
38524 :#include "servermd.h"
38525 :#include "picturestr.h"
38527 :static char **filterNames;
38528 :static int nfilterNames;
38531 : * standard but not required filters don't have constant indices
38535 :PictureGetFilterId (char *filter, int len, Bool makeit)
38536 3 0.0033 :{ /* PictureGetFilterId total: 16 0.0174 */
38542 7 0.0076 : len = strlen (filter);
38543 : for (i = 0; i < nfilterNames; i++)
38544 6 0.0065 : if (!CompareISOLatin1Lowered ((unsigned char *) filterNames[i], -1, (unsigned char *) filter, len))
38548 : name = xalloc (len + 1);
38551 : memcpy (name, filter, len);
38552 : name[len] = '\0';
38554 : names = xrealloc (filterNames, (nfilterNames + 1) * sizeof (char *));
38556 : names = xalloc (sizeof (char *));
38562 : filterNames = names;
38563 : i = nfilterNames++;
38564 : filterNames[i] = name;
38569 :PictureSetDefaultIds (void)
38571 : /* careful here -- this list must match the #define values */
38573 : if (PictureGetFilterId (FilterNearest, -1, TRUE) != PictFilterNearest)
38575 : if (PictureGetFilterId (FilterBilinear, -1, TRUE) != PictFilterBilinear)
38578 : if (PictureGetFilterId (FilterFast, -1, TRUE) != PictFilterFast)
38580 : if (PictureGetFilterId (FilterGood, -1, TRUE) != PictFilterGood)
38582 : if (PictureGetFilterId (FilterBest, -1, TRUE) != PictFilterBest)
38585 : if (PictureGetFilterId (FilterConvolution, -1, TRUE) != PictFilterConvolution)
38591 :PictureGetFilterName (int id)
38593 : if (0 <= id && id < nfilterNames)
38594 : return filterNames[id];
38600 :PictureFreeFilterIds (void)
38604 : for (i = 0; i < nfilterNames; i++)
38605 : xfree (filterNames[i]);
38606 : xfree (filterNames);
38607 : nfilterNames = 0;
38612 :PictureAddFilter (ScreenPtr pScreen,
38614 : PictFilterValidateParamsProcPtr ValidateParams)
38616 : PictureScreenPtr ps = GetPictureScreen(pScreen);
38617 : int id = PictureGetFilterId (filter, -1, TRUE);
38619 : PictFilterPtr filters;
38624 : * It's an error to attempt to reregister a filter
38626 : for (i = 0; i < ps->nfilters; i++)
38627 : if (ps->filters[i].id == id)
38630 : filters = xrealloc (ps->filters, (ps->nfilters + 1) * sizeof (PictFilterRec));
38632 : filters = xalloc (sizeof (PictFilterRec));
38635 : ps->filters = filters;
38636 : i = ps->nfilters++;
38637 : ps->filters[i].name = PictureGetFilterName (id);
38638 : ps->filters[i].id = id;
38639 : ps->filters[i].ValidateParams = ValidateParams;
38644 :PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias)
38646 : PictureScreenPtr ps = GetPictureScreen(pScreen);
38647 : int filter_id = PictureGetFilterId (filter, -1, FALSE);
38648 : int alias_id = PictureGetFilterId (alias, -1, TRUE);
38651 : if (filter_id < 0 || alias_id < 0)
38653 : for (i = 0; i < ps->nfilterAliases; i++)
38654 : if (ps->filterAliases[i].alias_id == alias_id)
38656 : if (i == ps->nfilterAliases)
38658 : PictFilterAliasPtr aliases;
38660 : if (ps->filterAliases)
38661 : aliases = xrealloc (ps->filterAliases,
38662 : (ps->nfilterAliases + 1) *
38663 : sizeof (PictFilterAliasRec));
38665 : aliases = xalloc (sizeof (PictFilterAliasRec));
38668 : ps->filterAliases = aliases;
38669 : ps->filterAliases[i].alias = PictureGetFilterName (alias_id);
38670 : ps->filterAliases[i].alias_id = alias_id;
38671 : ps->nfilterAliases++;
38673 : ps->filterAliases[i].filter_id = filter_id;
38678 :PictureFindFilter (ScreenPtr pScreen, char *name, int len)
38679 2 0.0022 :{ /* PictureFindFilter total: 8 0.0087 */
38680 1 0.0011 : PictureScreenPtr ps = GetPictureScreen(pScreen);
38681 : int id = PictureGetFilterId (name, len, FALSE);
38686 : /* Check for an alias, allow them to recurse */
38687 : for (i = 0; i < ps->nfilterAliases; i++)
38688 4 0.0044 : if (ps->filterAliases[i].alias_id == id)
38690 : id = ps->filterAliases[i].filter_id;
38693 : /* find the filter */
38694 : for (i = 0; i < ps->nfilters; i++)
38695 : if (ps->filters[i].id == id)
38696 : return &ps->filters[i];
38701 :convolutionFilterValidateParams (PicturePtr pPicture,
38709 : if (xFixedFrac (params[0]) || xFixedFrac (params[1]))
38713 : if ((xFixedToInt (params[0]) * xFixedToInt (params[1])) > nparams)
38721 :PictureSetDefaultFilters (ScreenPtr pScreen)
38723 : if (!filterNames)
38724 : if (!PictureSetDefaultIds ())
38726 : if (PictureAddFilter (pScreen, FilterNearest, 0) < 0)
38728 : if (PictureAddFilter (pScreen, FilterBilinear, 0) < 0)
38731 : if (!PictureSetFilterAlias (pScreen, FilterNearest, FilterFast))
38733 : if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterGood))
38735 : if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterBest))
38738 : if (PictureAddFilter (pScreen, FilterConvolution, convolutionFilterValidateParams) < 0)
38745 :PictureResetFilters (ScreenPtr pScreen)
38747 : PictureScreenPtr ps = GetPictureScreen(pScreen);
38749 : xfree (ps->filters);
38750 : xfree (ps->filterAliases);
38751 : PictureFreeFilterIds ();
38755 :SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams)
38756 :{ /* SetPictureFilter total: 10 0.0109 */
38757 : PictFilterPtr pFilter;
38758 : xFixed *new_params;
38759 : int i, s, result;
38761 3 0.0033 : pFilter = PictureFindFilter (screenInfo.screens[0], name, len);
38763 : if (pPicture->pDrawable == NULL) {
38764 : /* For source pictures, the picture isn't tied to a screen. So, ensure
38765 : * that all screens can handle a filter we set for the picture.
38767 : for (s = 0; s < screenInfo.numScreens; s++) {
38768 : if (PictureFindFilter (screenInfo.screens[s], name, len)->id !=
38778 : if (pFilter->ValidateParams)
38780 : if (!(*pFilter->ValidateParams) (pPicture, pFilter->id, params, nparams))
38783 : else if (nparams)
38786 5 0.0054 : if (nparams != pPicture->filter_nparams)
38788 : new_params = xalloc (nparams * sizeof (xFixed));
38791 : xfree (pPicture->filter_params);
38792 : pPicture->filter_params = new_params;
38793 : pPicture->filter_nparams = nparams;
38795 : for (i = 0; i < nparams; i++)
38796 : pPicture->filter_params[i] = params[i];
38797 : pPicture->filter = pFilter->id;
38799 : if (pPicture->pDrawable) {
38800 : ScreenPtr pScreen = pPicture->pDrawable->pScreen;
38801 : PictureScreenPtr ps = GetPictureScreen(pScreen);
38803 1 0.0011 : result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter,
38804 : params, nparams);
38810 * Total samples for file : "/home/cworth/src/xorg/xserver/fb/fbgc.c"
38817 : * Copyright © 1998 Keith Packard
38819 : * Permission to use, copy, modify, distribute, and sell this software and its
38820 : * documentation for any purpose is hereby granted without fee, provided that
38821 : * the above copyright notice appear in all copies and that both that
38822 : * copyright notice and this permission notice appear in supporting
38823 : * documentation, and that the name of Keith Packard not be used in
38824 : * advertising or publicity pertaining to distribution of the software without
38825 : * specific, written prior permission. Keith Packard makes no
38826 : * representations about the suitability of this software for any purpose. It
38827 : * is provided "as is" without express or implied warranty.
38829 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
38830 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
38831 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
38832 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
38833 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38834 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
38835 : * PERFORMANCE OF THIS SOFTWARE.
38838 :#ifdef HAVE_DIX_CONFIG_H
38839 :#include <dix-config.h>
38842 :#include <stdlib.h>
38846 :const GCFuncs fbGCFuncs = {
38856 :const GCOps fbGCOps = {
38880 :fbCreateGC(GCPtr pGC)
38882 : pGC->clientClip = NULL;
38883 : pGC->clientClipType = CT_NONE;
38885 : pGC->ops = (GCOps *) &fbGCOps;
38886 : pGC->funcs = (GCFuncs *) &fbGCFuncs;
38888 : /* fb wants to translate before scan conversion */
38889 : pGC->miTranslate = 1;
38891 : fbGetRotatedPixmap(pGC) = 0;
38892 : fbGetExpose(pGC) = 1;
38893 : fbGetFreeCompClip(pGC) = 0;
38894 : fbGetCompositeClip(pGC) = 0;
38895 : fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth);
38900 : * Pad pixmap to FB_UNIT bits wide
38903 :fbPadPixmap (PixmapPtr pPixmap)
38915 : fbGetDrawable (&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
38917 : width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
38918 : height = pPixmap->drawable.height;
38919 : mask = FbBitsMask (0, width);
38922 : b = READ(bits) & mask;
38924 : while (w < FB_UNIT)
38926 : b = b | FbScrRight(b, w);
38933 : fbFinishAccess (&pPixmap->drawable);
38937 : * Verify that 'bits' repeats every 'len' bits
38940 :fbBitsRepeat (FbBits bits, int len, int width)
38942 : FbBits mask = FbBitsMask(0, len);
38943 : FbBits orig = bits & mask;
38946 : if (width > FB_UNIT)
38948 : for (i = 0; i < width / len; i++)
38950 : if ((bits & mask) != orig)
38952 : bits = FbScrLeft(bits,len);
38958 : * Check whether an entire bitmap line is a repetition of
38959 : * the first 'len' bits
38962 :fbLineRepeat (FbBits *bits, int len, int width)
38964 : FbBits first = bits[0];
38966 : if (!fbBitsRepeat (first, len, width))
38968 : width = (width + FB_UNIT-1) >> FB_SHIFT;
38971 : if (READ(bits) != first)
38977 : * The even stipple code wants the first FB_UNIT/bpp bits on
38978 : * each scanline to represent the entire stipple
38981 :fbCanEvenStipple (PixmapPtr pStipple, int bpp)
38983 : int len = FB_UNIT / bpp;
38987 : int stipXoff, stipYoff;
38990 : /* can't even stipple 24bpp drawables */
38991 : if ((bpp & (bpp-1)) != 0)
38993 : /* make sure the stipple width is a multiple of the even stipple width */
38994 : if (pStipple->drawable.width % len != 0)
38996 : fbGetDrawable (&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff);
38997 : h = pStipple->drawable.height;
38998 : /* check to see that the stipple repeats horizontally */
39001 : if (!fbLineRepeat (bits, len, pStipple->drawable.width)) {
39002 : fbFinishAccess (&pStipple->drawable);
39007 : fbFinishAccess (&pStipple->drawable);
39012 :fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
39013 2 0.0022 :{ /* fbValidateGC total: 34 0.0370 */
39014 : FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
39017 1 0.0011 : pGC->lastWinOrg.x = pDrawable->x;
39018 : pGC->lastWinOrg.y = pDrawable->y;
39021 : * if the client clip is different or moved OR the subwindowMode has
39022 : * changed OR the window's clip has changed since the last validation
39023 : * we need to recompute the composite clip
39026 : if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
39027 : (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
39030 : miComputeCompositeClip (pGC, pDrawable);
39031 1 0.0011 : pPriv->oneRect = REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1;
39034 :#ifdef FB_24_32BIT
39035 : if (pPriv->bpp != pDrawable->bitsPerPixel)
39037 : changes |= GCStipple|GCForeground|GCBackground|GCPlaneMask;
39038 : pPriv->bpp = pDrawable->bitsPerPixel;
39040 : if ((changes & GCTile) && fbGetRotatedPixmap(pGC))
39042 : (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
39043 : fbGetRotatedPixmap(pGC) = 0;
39046 : if (pGC->fillStyle == FillTiled)
39048 : PixmapPtr pOldTile, pNewTile;
39050 : pOldTile = pGC->tile.pixmap;
39051 : if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
39053 : pNewTile = fbGetRotatedPixmap(pGC);
39054 : if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
39057 : (*pGC->pScreen->DestroyPixmap) (pNewTile);
39058 : pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel);
39062 : fbGetRotatedPixmap(pGC) = pOldTile;
39063 : pGC->tile.pixmap = pNewTile;
39064 : changes |= GCTile;
39069 : if (changes & GCTile)
39071 : if (!pGC->tileIsPixel &&
39072 : FbEvenTile (pGC->tile.pixmap->drawable.width *
39073 : pDrawable->bitsPerPixel))
39074 : fbPadPixmap (pGC->tile.pixmap);
39076 1 0.0011 : if (changes & GCStipple)
39078 : pPriv->evenStipple = FALSE;
39080 3 0.0033 : if (pGC->stipple) {
39082 : /* can we do an even stipple ?? */
39083 : if (FbEvenStip (pGC->stipple->drawable.width,
39084 : pDrawable->bitsPerPixel) &&
39085 : (fbCanEvenStipple (pGC->stipple, pDrawable->bitsPerPixel)))
39086 : pPriv->evenStipple = TRUE;
39088 : if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < FB_UNIT)
39089 : fbPadPixmap (pGC->stipple);
39093 : * Recompute reduced rop values
39095 3 0.0033 : if (changes & (GCForeground|GCBackground|GCPlaneMask|GCFunction))
39098 : FbBits depthMask;
39100 3 0.0033 : mask = FbFullMask(pDrawable->bitsPerPixel);
39101 2 0.0022 : depthMask = FbFullMask(pDrawable->depth);
39103 1 0.0011 : pPriv->fg = pGC->fgPixel & mask;
39104 1 0.0011 : pPriv->bg = pGC->bgPixel & mask;
39106 : if ((pGC->planemask & depthMask) == depthMask)
39107 2 0.0022 : pPriv->pm = mask;
39109 : pPriv->pm = pGC->planemask & mask;
39111 1 0.0011 : s = pDrawable->bitsPerPixel;
39112 : while (s < FB_UNIT)
39114 : pPriv->fg |= pPriv->fg << s;
39115 : pPriv->bg |= pPriv->bg << s;
39116 : pPriv->pm |= pPriv->pm << s;
39119 7 0.0076 : pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
39120 1 0.0011 : pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
39121 : pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
39122 3 0.0033 : pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
39124 : if (changes & GCDashList)
39126 : unsigned short n = pGC->numInDashList;
39127 : unsigned char *dash = pGC->dash;
39128 : unsigned int dashLength = 0;
39131 1 0.0011 : dashLength += (unsigned int ) *dash++;
39132 : pPriv->dashLength = dashLength;
39136 * Total samples for file : "pixman-mmx.c"
39141 <credited to line zero> 33 0.0359 :
39142 /* __i686.get_pc_thunk.bx total: 15 0.0163 */
39143 /* __divdi3 total: 18 0.0196 */
39145 * Total samples for file : "/home/cworth/src/xorg/xserver/mi/migc.c"
39153 :Copyright 1993, 1998 The Open Group
39155 :Permission to use, copy, modify, distribute, and sell this software and its
39156 :documentation for any purpose is hereby granted without fee, provided that
39157 :the above copyright notice appear in all copies and that both that
39158 :copyright notice and this permission notice appear in supporting
39161 :The above copyright notice and this permission notice shall be included
39162 :in all copies or substantial portions of the Software.
39164 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
39165 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39166 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
39167 :IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
39168 :OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
39169 :ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
39170 :OTHER DEALINGS IN THE SOFTWARE.
39172 :Except as contained in this notice, the name of The Open Group shall
39173 :not be used in advertising or otherwise to promote the sale, use or
39174 :other dealings in this Software without prior written authorization
39175 :from The Open Group.
39180 :#ifdef HAVE_DIX_CONFIG_H
39181 :#include <dix-config.h>
39184 :#include "scrnintstr.h"
39185 :#include "gcstruct.h"
39186 :#include "pixmapstr.h"
39187 :#include "windowstr.h"
39192 :miChangeGC(pGC, mask)
39194 : unsigned long mask;
39195 6 0.0065 :{ /* miChangeGC total: 6 0.0065 */
39203 : if (pGC->pRotatedPixmap)
39204 : (*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap);
39205 : if (pGC->freeCompClip)
39206 : REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
39207 : miDestroyGCOps(pGC->ops);
39211 : * create a private op array for a gc
39214 :_X_EXPORT GCOpsPtr
39215 :miCreateGCOps(prototype)
39216 : GCOpsPtr prototype;
39220 : /* XXX */ Must_have_memory = TRUE;
39221 : ret = (GCOpsPtr) xalloc(sizeof(GCOps));
39222 : /* XXX */ Must_have_memory = FALSE;
39225 : *ret = *prototype;
39226 : ret->devPrivate.val = 1;
39231 :miDestroyGCOps(ops)
39234 : if (ops->devPrivate.val)
39240 :miDestroyClip(pGC)
39242 1 0.0011 :{ /* miDestroyClip total: 1 0.0011 */
39243 : if (pGC->clientClipType == CT_NONE)
39245 : else if (pGC->clientClipType == CT_PIXMAP)
39247 : (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip));
39252 : * we know we'll never have a list of rectangles, since ChangeClip
39253 : * immediately turns them into a region
39255 : REGION_DESTROY(pGC->pScreen, pGC->clientClip);
39257 : pGC->clientClip = NULL;
39258 : pGC->clientClipType = CT_NONE;
39262 :miChangeClip(pGC, type, pvalue, nrects)
39267 3 0.0033 :{ /* miChangeClip total: 4 0.0044 */
39268 : (*pGC->funcs->DestroyClip) (pGC);
39269 : if (type == CT_PIXMAP)
39271 : /* convert the pixmap to a region */
39272 : pGC->clientClip = (pointer) BITMAP_TO_REGION(pGC->pScreen,
39273 : (PixmapPtr) pvalue);
39274 : (*pGC->pScreen->DestroyPixmap) (pvalue);
39276 : else if (type == CT_REGION)
39278 : /* stuff the region in the GC */
39279 : pGC->clientClip = pvalue;
39281 1 0.0011 : else if (type != CT_NONE)
39283 : pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nrects,
39284 : (xRectangle *) pvalue,
39288 : pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION : CT_NONE;
39289 : pGC->stateChanges |= GCClipMask;
39293 :miCopyClip(pgcDst, pgcSrc)
39294 : GCPtr pgcDst, pgcSrc;
39296 : RegionPtr prgnNew;
39298 : switch (pgcSrc->clientClipType)
39301 : ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
39302 : /* Fall through !! */
39304 : (*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType,
39305 : pgcSrc->clientClip, 0);
39308 : prgnNew = REGION_CREATE(pgcSrc->pScreen, NULL, 1);
39309 : REGION_COPY(pgcDst->pScreen, prgnNew,
39310 : (RegionPtr) (pgcSrc->clientClip));
39311 : (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (pointer) prgnNew, 0);
39318 :miCopyGC(pGCSrc, changes, pGCDst)
39320 : unsigned long changes;
39327 :miComputeCompositeClip(pGC, pDrawable)
39329 : DrawablePtr pDrawable;
39330 4 0.0044 :{ /* miComputeCompositeClip total: 20 0.0218 */
39331 : ScreenPtr pScreen;
39333 : /* This prevents warnings about pScreen not being used. */
39334 : pGC->pScreen = pScreen = pGC->pScreen;
39336 : if (pDrawable->type == DRAWABLE_WINDOW)
39338 : WindowPtr pWin = (WindowPtr) pDrawable;
39339 : RegionPtr pregWin;
39340 : Bool freeTmpClip, freeCompClip;
39342 : if (pGC->subWindowMode == IncludeInferiors)
39344 : pregWin = NotClippedByChildren(pWin);
39345 : freeTmpClip = TRUE;
39349 : pregWin = &pWin->clipList;
39350 : freeTmpClip = FALSE;
39352 : freeCompClip = pGC->freeCompClip;
39355 : * if there is no client clip, we can get by with just keeping the
39356 : * pointer we got, and remembering whether or not should destroy (or
39357 : * maybe re-use) it later. this way, we avoid unnecessary copying of
39358 : * regions. (this wins especially if many clients clip by children
39359 : * and have no client clip.)
39361 : if (pGC->clientClipType == CT_NONE)
39363 : if (freeCompClip)
39364 : REGION_DESTROY(pScreen, pGC->pCompositeClip);
39365 : pGC->pCompositeClip = pregWin;
39366 : pGC->freeCompClip = freeTmpClip;
39371 : * we need one 'real' region to put into the composite clip. if
39372 : * pregWin the current composite clip are real, we can get rid of
39373 : * one. if pregWin is real and the current composite clip isn't,
39374 : * use pregWin for the composite clip. if the current composite
39375 : * clip is real and pregWin isn't, use the current composite
39376 : * clip. if neither is real, create a new region.
39379 : REGION_TRANSLATE(pScreen, pGC->clientClip,
39380 : pDrawable->x + pGC->clipOrg.x,
39381 : pDrawable->y + pGC->clipOrg.y);
39383 : if (freeCompClip)
39385 : REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
39386 : pregWin, pGC->clientClip);
39388 : REGION_DESTROY(pScreen, pregWin);
39390 : else if (freeTmpClip)
39392 : REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip);
39393 : pGC->pCompositeClip = pregWin;
39397 1 0.0011 : pGC->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
39398 : REGION_INTERSECT(pScreen, pGC->pCompositeClip,
39399 : pregWin, pGC->clientClip);
39401 : pGC->freeCompClip = TRUE;
39402 : REGION_TRANSLATE(pScreen, pGC->clientClip,
39403 : -(pDrawable->x + pGC->clipOrg.x),
39404 : -(pDrawable->y + pGC->clipOrg.y));
39406 : } /* end of composite clip for a window */
39409 : BoxRec pixbounds;
39411 : /* XXX should we translate by drawable.x/y here ? */
39412 : /* If you want pixmaps in offscreen memory, yes */
39413 3 0.0033 : pixbounds.x1 = pDrawable->x;
39414 1 0.0011 : pixbounds.y1 = pDrawable->y;
39415 : pixbounds.x2 = pDrawable->x + pDrawable->width;
39416 : pixbounds.y2 = pDrawable->y + pDrawable->height;
39418 1 0.0011 : if (pGC->freeCompClip)
39420 8 0.0087 : REGION_RESET(pScreen, pGC->pCompositeClip, &pixbounds);
39424 : pGC->freeCompClip = TRUE;
39425 : pGC->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
39428 : if (pGC->clientClipType == CT_REGION)
39430 : if(pDrawable->x || pDrawable->y) {
39431 : REGION_TRANSLATE(pScreen, pGC->clientClip,
39432 : pDrawable->x + pGC->clipOrg.x,
39433 : pDrawable->y + pGC->clipOrg.y);
39434 : REGION_INTERSECT(pScreen, pGC->pCompositeClip,
39435 : pGC->pCompositeClip, pGC->clientClip);
39436 : REGION_TRANSLATE(pScreen, pGC->clientClip,
39437 : -(pDrawable->x + pGC->clipOrg.x),
39438 : -(pDrawable->y + pGC->clipOrg.y));
39440 1 0.0011 : REGION_TRANSLATE(pScreen, pGC->pCompositeClip,
39441 : -pGC->clipOrg.x, -pGC->clipOrg.y);
39442 : REGION_INTERSECT(pScreen, pGC->pCompositeClip,
39443 : pGC->pCompositeClip, pGC->clientClip);
39444 : REGION_TRANSLATE(pScreen, pGC->pCompositeClip,
39445 : pGC->clipOrg.x, pGC->clipOrg.y);
39448 : } /* end of composite clip for pixmap */
39449 1 0.0011 :} /* end miComputeCompositeClip */
39451 * Total samples for file : "/home/cworth/src/xorg/xserver/Xext/xvmain.c"
39457 :/***********************************************************
39458 :Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
39459 :and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
39461 : All Rights Reserved
39463 :Permission to use, copy, modify, and distribute this software and its
39464 :documentation for any purpose and without fee is hereby granted,
39465 :provided that the above copyright notice appear in all copies and that
39466 :both that copyright notice and this permission notice appear in
39467 :supporting documentation, and that the names of Digital or MIT not be
39468 :used in advertising or publicity pertaining to distribution of the
39469 :software without specific, written prior permission.
39471 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39472 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39473 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
39474 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39475 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
39476 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
39479 :******************************************************************/
39484 :** xvmain.c --- Xv server extension main device independent module.
39488 :** David Carver (Digital Workstation Engineering/Project Athena)
39492 :** 04.09.91 Carver
39493 :** - change: stop video always generates an event even when video
39496 :** 29.08.91 Carver
39497 :** - change: unrealizing windows no longer preempts video
39499 :** 11.06.91 Carver
39500 :** - changed SetPortControl to SetPortAttribute
39501 :** - changed GetPortControl to GetPortAttribute
39502 :** - changed QueryBestSize
39504 :** 28.05.91 Carver
39505 :** - fixed Put and Get requests to not preempt operations to same drawable
39507 :** 15.05.91 Carver
39508 :** - version 2.0 upgrade
39510 :** 19.03.91 Carver
39511 :** - fixed Put and Get requests to honor grabbed ports.
39512 :** - fixed Video requests to update di structure with new drawable, and
39513 :** client after calling ddx.
39515 :** 24.01.91 Carver
39516 :** - version 1.4 upgrade
39520 :** Port structures reference client structures in a two different
39521 :** ways: when grabs, or video is active. Each reference is encoded
39522 :** as fake client resources and thus when the client is goes away so
39523 :** does the reference (it is zeroed). No other action is taken, so
39524 :** video doesn't necessarily stop. It probably will as a result of
39525 :** other resources going away, but if a client starts video using
39526 :** none of its own resources, then the video will continue to play
39527 :** after the client disappears.
39532 :#ifdef HAVE_DIX_CONFIG_H
39533 :#include <dix-config.h>
39536 :#include <string.h>
39538 :#include <X11/X.h>
39539 :#include <X11/Xproto.h>
39542 :#include "scrnintstr.h"
39543 :#include "windowstr.h"
39544 :#include "pixmapstr.h"
39546 :#include "extnsionst.h"
39547 :#include "dixstruct.h"
39548 :#include "resource.h"
39549 :#include "opaque.h"
39550 :#include "input.h"
39554 :#include <X11/extensions/Xv.h>
39555 :#include <X11/extensions/Xvproto.h>
39556 :#include "xvdix.h"
39559 :#include "panoramiX.h"
39560 :#include "panoramiXsrv.h"
39561 :#include "xvdisp.h"
39564 :int XvScreenIndex = -1;
39565 :unsigned long XvExtensionGeneration = 0;
39566 :unsigned long XvScreenGeneration = 0;
39567 :unsigned long XvResourceGeneration = 0;
39573 :unsigned long XvRTPort;
39574 :unsigned long XvRTEncoding;
39575 :unsigned long XvRTGrab;
39576 :unsigned long XvRTVideoNotify;
39577 :unsigned long XvRTVideoNotifyList;
39578 :unsigned long XvRTPortNotify;
39584 :extern XID clientErrorValue;
39586 :static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *);
39587 :static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *);
39588 :static Bool CreateResourceTypes(void);
39590 :static Bool XvCloseScreen(int, ScreenPtr);
39591 :static Bool XvDestroyPixmap(PixmapPtr);
39592 :static Bool XvDestroyWindow(WindowPtr);
39593 :static void XvResetProc(ExtensionEntry*);
39594 :static int XvdiDestroyGrab(pointer, XID);
39595 :static int XvdiDestroyEncoding(pointer, XID);
39596 :static int XvdiDestroyVideoNotify(pointer, XID);
39597 :static int XvdiDestroyPortNotify(pointer, XID);
39598 :static int XvdiDestroyVideoNotifyList(pointer, XID);
39599 :static int XvdiDestroyPort(pointer, XID);
39600 :static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int);
39606 :** XvExtensionInit
39612 :XvExtensionInit(void)
39614 : ExtensionEntry *extEntry;
39616 : /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN
39617 : INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */
39618 : if (XvScreenGeneration != serverGeneration)
39620 : if (!CreateResourceTypes())
39622 : ErrorF("XvExtensionInit: Unable to allocate resource types\n");
39625 : XvScreenIndex = AllocateScreenPrivateIndex ();
39626 : if (XvScreenIndex < 0)
39628 : ErrorF("XvExtensionInit: Unable to allocate screen private index\n");
39632 : XineramaRegisterConnectionBlockCallback(XineramifyXv);
39634 : XvScreenGeneration = serverGeneration;
39637 : if (XvExtensionGeneration != serverGeneration)
39639 : XvExtensionGeneration = serverGeneration;
39641 : extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors,
39642 : ProcXvDispatch, SProcXvDispatch,
39643 : XvResetProc, StandardMinorOpcode);
39646 : FatalError("XvExtensionInit: AddExtensions failed\n");
39649 : XvReqCode = extEntry->base;
39650 : XvEventBase = extEntry->eventBase;
39651 : XvErrorBase = extEntry->errorBase;
39653 : EventSwapVector[XvEventBase+XvVideoNotify] =
39654 : (EventSwapPtr)WriteSwappedVideoNotifyEvent;
39655 : EventSwapVector[XvEventBase+XvPortNotify] =
39656 : (EventSwapPtr)WriteSwappedPortNotifyEvent;
39658 : (void)MakeAtom(XvName, strlen(XvName), xTrue);
39664 :CreateResourceTypes(void)
39668 : if (XvResourceGeneration == serverGeneration) return TRUE;
39670 : XvResourceGeneration = serverGeneration;
39672 : if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort)))
39674 : ErrorF("CreateResourceTypes: failed to allocate port resource.\n");
39678 : if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab)))
39680 : ErrorF("CreateResourceTypes: failed to allocate grab resource.\n");
39684 : if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding)))
39686 : ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n");
39690 : if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify)))
39692 : ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n");
39696 : if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList)))
39698 : ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n");
39702 : if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify)))
39704 : ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n");
39713 :XvScreenInit(ScreenPtr pScreen)
39715 : XvScreenPtr pxvs;
39717 : if (XvScreenGeneration != serverGeneration)
39719 : if (!CreateResourceTypes())
39721 : ErrorF("XvScreenInit: Unable to allocate resource types\n");
39724 : XvScreenIndex = AllocateScreenPrivateIndex ();
39725 : if (XvScreenIndex < 0)
39727 : ErrorF("XvScreenInit: Unable to allocate screen private index\n");
39731 : XineramaRegisterConnectionBlockCallback(XineramifyXv);
39733 : XvScreenGeneration = serverGeneration;
39736 : if (pScreen->devPrivates[XvScreenIndex].ptr)
39738 : ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n");
39741 : /* ALLOCATE SCREEN PRIVATE RECORD */
39743 : pxvs = (XvScreenPtr) xalloc (sizeof (XvScreenRec));
39746 : ErrorF("XvScreenInit: Unable to allocate screen private structure\n");
39750 : pScreen->devPrivates[XvScreenIndex].ptr = (pointer)pxvs;
39753 : pxvs->DestroyPixmap = pScreen->DestroyPixmap;
39754 : pxvs->DestroyWindow = pScreen->DestroyWindow;
39755 : pxvs->CloseScreen = pScreen->CloseScreen;
39757 : pScreen->DestroyPixmap = XvDestroyPixmap;
39758 : pScreen->DestroyWindow = XvDestroyWindow;
39759 : pScreen->CloseScreen = XvCloseScreen;
39767 : ScreenPtr pScreen
39770 : XvScreenPtr pxvs;
39772 : pxvs = (XvScreenPtr) pScreen->devPrivates[XvScreenIndex].ptr;
39774 : pScreen->DestroyPixmap = pxvs->DestroyPixmap;
39775 : pScreen->DestroyWindow = pxvs->DestroyWindow;
39776 : pScreen->CloseScreen = pxvs->CloseScreen;
39778 : (* pxvs->ddCloseScreen)(ii, pScreen);
39782 : pScreen->devPrivates[XvScreenIndex].ptr = (pointer)NULL;
39784 : return (*pScreen->CloseScreen)(ii, pScreen);
39789 :XvResetProc(ExtensionEntry* extEntry)
39794 :XvGetScreenIndex(void)
39796 : return XvScreenIndex;
39799 :_X_EXPORT unsigned long
39806 :XvDestroyPixmap(PixmapPtr pPix)
39807 4 0.0044 :{ /* XvDestroyPixmap total: 26 0.0283 */
39809 : ScreenPtr pScreen;
39810 : XvScreenPtr pxvs;
39816 2 0.0022 : pScreen = pPix->drawable.pScreen;
39818 1 0.0011 : SCREEN_PROLOGUE(pScreen, DestroyPixmap);
39820 : pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
39822 : /* CHECK TO SEE IF THIS PORT IS IN USE */
39824 : pa = pxvs->pAdaptors;
39825 1 0.0011 : na = pxvs->nAdaptors;
39826 1 0.0011 : while (na--)
39828 1 0.0011 : np = pa->nPorts;
39829 1 0.0011 : pp = pa->pPorts;
39831 3 0.0033 : while (np--)
39833 2 0.0022 : if (pp->pDraw == (DrawablePtr)pPix)
39835 : XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
39837 : (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp,
39840 : pp->pDraw = (DrawablePtr)NULL;
39841 : pp->client = (ClientPtr)NULL;
39842 4 0.0044 : pp->time = currentTime;
39849 : status = (* pScreen->DestroyPixmap)(pPix);
39851 1 0.0011 : SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap);
39858 :XvDestroyWindow(WindowPtr pWin)
39861 : ScreenPtr pScreen;
39862 : XvScreenPtr pxvs;
39868 : pScreen = pWin->drawable.pScreen;
39870 : SCREEN_PROLOGUE(pScreen, DestroyWindow);
39872 : pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
39874 : /* CHECK TO SEE IF THIS PORT IS IN USE */
39876 : pa = pxvs->pAdaptors;
39877 : na = pxvs->nAdaptors;
39885 : if (pp->pDraw == (DrawablePtr)pWin)
39887 : XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
39889 : (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp,
39892 : pp->pDraw = (DrawablePtr)NULL;
39893 : pp->client = (ClientPtr)NULL;
39894 : pp->time = currentTime;
39902 : status = (* pScreen->DestroyWindow)(pWin);
39904 : SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow);
39910 :/* The XvdiVideoStopped procedure is a hook for the device dependent layer.
39911 : It provides a way for the dd layer to inform the di layer that video has
39912 : stopped in a port for reasons that the di layer had no control over; note
39913 : that it doesn't call back into the dd layer */
39916 :XvdiVideoStopped(XvPortPtr pPort, int reason)
39919 : /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
39921 : if (!pPort->pDraw) return Success;
39923 : XvdiSendVideoNotify(pPort, pPort->pDraw, reason);
39925 : pPort->pDraw = (DrawablePtr)NULL;
39926 : pPort->client = (ClientPtr)NULL;
39927 : pPort->time = currentTime;
39934 :XvdiDestroyPort(pointer pPort, XID id)
39936 : return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort);
39940 :XvdiDestroyGrab(pointer pGrab, XID id)
39942 : ((XvGrabPtr)pGrab)->client = (ClientPtr)NULL;
39947 :XvdiDestroyVideoNotify(pointer pn, XID id)
39949 : /* JUST CLEAR OUT THE client POINTER FIELD */
39951 : ((XvVideoNotifyPtr)pn)->client = (ClientPtr)NULL;
39956 :XvdiDestroyPortNotify(pointer pn, XID id)
39958 : /* JUST CLEAR OUT THE client POINTER FIELD */
39960 : ((XvPortNotifyPtr)pn)->client = (ClientPtr)NULL;
39965 :XvdiDestroyVideoNotifyList(pointer pn, XID id)
39967 : XvVideoNotifyPtr npn,cpn;
39969 : /* ACTUALLY DESTROY THE NOTITY LIST */
39971 : cpn = (XvVideoNotifyPtr)pn;
39976 : if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify);
39984 :XvdiDestroyEncoding(pointer value, XID id)
39990 :XvdiSendVideoNotify(pPort, pDraw, reason)
39993 :DrawablePtr pDraw;
39998 : XvVideoNotifyPtr pn;
40000 : pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList);
40006 : event.u.u.type = XvEventBase + XvVideoNotify;
40007 : event.u.u.sequenceNumber = pn->client->sequence;
40008 : event.u.videoNotify.time = currentTime.milliseconds;
40009 : event.u.videoNotify.drawable = pDraw->id;
40010 : event.u.videoNotify.port = pPort->id;
40011 : event.u.videoNotify.reason = reason;
40012 : (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask,
40013 : NoEventMask, NullGrab);
40024 :XvdiSendPortNotify(
40030 : XvPortNotifyPtr pn;
40032 : pn = pPort->pNotify;
40038 : event.u.u.type = XvEventBase + XvPortNotify;
40039 : event.u.u.sequenceNumber = pn->client->sequence;
40040 : event.u.portNotify.time = currentTime.milliseconds;
40041 : event.u.portNotify.port = pPort->id;
40042 : event.u.portNotify.attribute = attribute;
40043 : event.u.portNotify.value = value;
40044 : (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask,
40045 : NoEventMask, NullGrab);
40055 :#define CHECK_SIZE(dw, dh, sw, sh) { \
40056 : if(!dw || !dh || !sw || !sh) return Success; \
40057 : /* The region code will break these if they are too large */ \
40058 : if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \
40059 : return BadValue; \
40065 : ClientPtr client,
40066 : DrawablePtr pDraw,
40069 : INT16 vid_x, INT16 vid_y,
40070 : CARD16 vid_w, CARD16 vid_h,
40071 : INT16 drw_x, INT16 drw_y,
40072 : CARD16 drw_w, CARD16 drw_h
40074 : DrawablePtr pOldDraw;
40076 : CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
40078 : /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
40080 : UpdateCurrentTime();
40082 : /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
40083 : INFORM CLIENT OF ITS FAILURE */
40085 : if (pPort->grab.client && (pPort->grab.client != client))
40087 : XvdiSendVideoNotify(pPort, pDraw, XvBusy);
40091 : /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
40092 : EVENTS TO ANY CLIENTS WHO WANT THEM */
40094 : pOldDraw = pPort->pDraw;
40095 : if ((pOldDraw) && (pOldDraw != pDraw))
40097 : XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
40100 : (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC,
40101 : vid_x, vid_y, vid_w, vid_h,
40102 : drw_x, drw_y, drw_w, drw_h);
40104 : if ((pPort->pDraw) && (pOldDraw != pDraw))
40106 : pPort->client = client;
40107 : XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
40110 : pPort->time = currentTime;
40112 : return (Success);
40118 : ClientPtr client,
40119 : DrawablePtr pDraw,
40122 : INT16 vid_x, INT16 vid_y,
40123 : CARD16 vid_w, CARD16 vid_h,
40124 : INT16 drw_x, INT16 drw_y,
40125 : CARD16 drw_w, CARD16 drw_h
40129 : CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
40131 : /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
40133 : UpdateCurrentTime();
40135 : /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
40136 : INFORM CLIENT OF ITS FAILURE */
40138 : if (pPort->grab.client && (pPort->grab.client != client))
40140 : XvdiSendVideoNotify(pPort, pDraw, XvBusy);
40144 : pPort->time = currentTime;
40146 : status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC,
40147 : vid_x, vid_y, vid_w, vid_h,
40148 : drw_x, drw_y, drw_w, drw_h);
40156 : ClientPtr client,
40157 : DrawablePtr pDraw,
40160 : INT16 src_x, INT16 src_y,
40161 : CARD16 src_w, CARD16 src_h,
40162 : INT16 drw_x, INT16 drw_y,
40163 : CARD16 drw_w, CARD16 drw_h,
40164 : XvImagePtr image,
40165 : unsigned char* data,
40167 : CARD16 width, CARD16 height
40169 : CHECK_SIZE(drw_w, drw_h, src_w, src_h);
40171 : /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
40173 : UpdateCurrentTime();
40175 : /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
40176 : INFORM CLIENT OF ITS FAILURE */
40178 : if (pPort->grab.client && (pPort->grab.client != client))
40180 : XvdiSendVideoNotify(pPort, pDraw, XvBusy);
40184 : pPort->time = currentTime;
40186 : return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC,
40187 : src_x, src_y, src_w, src_h,
40188 : drw_x, drw_y, drw_w, drw_h,
40189 : image, data, sync, width, height);
40195 : ClientPtr client,
40196 : DrawablePtr pDraw,
40199 : INT16 vid_x, INT16 vid_y,
40200 : CARD16 vid_w, CARD16 vid_h,
40201 : INT16 drw_x, INT16 drw_y,
40202 : CARD16 drw_w, CARD16 drw_h
40204 : DrawablePtr pOldDraw;
40206 : CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
40208 : /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
40210 : UpdateCurrentTime();
40212 : /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
40213 : INFORM CLIENT OF ITS FAILURE */
40215 : if (pPort->grab.client && (pPort->grab.client != client))
40217 : XvdiSendVideoNotify(pPort, pDraw, XvBusy);
40221 : /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
40222 : EVENTS TO ANY CLIENTS WHO WANT THEM */
40224 : pOldDraw = pPort->pDraw;
40225 : if ((pOldDraw) && (pOldDraw != pDraw))
40227 : XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
40230 : (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC,
40231 : vid_x, vid_y, vid_w, vid_h,
40232 : drw_x, drw_y, drw_w, drw_h);
40234 : if ((pPort->pDraw) && (pOldDraw != pDraw))
40236 : pPort->client = client;
40237 : XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
40240 : pPort->time = currentTime;
40242 : return (Success);
40248 : ClientPtr client,
40249 : DrawablePtr pDraw,
40252 : INT16 vid_x, INT16 vid_y,
40253 : CARD16 vid_w, CARD16 vid_h,
40254 : INT16 drw_x, INT16 drw_y,
40255 : CARD16 drw_w, CARD16 drw_h
40259 : CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
40261 : /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
40263 : UpdateCurrentTime();
40265 : /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
40266 : INFORM CLIENT OF ITS FAILURE */
40268 : if (pPort->grab.client && (pPort->grab.client != client))
40270 : XvdiSendVideoNotify(pPort, pDraw, XvBusy);
40274 : status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC,
40275 : vid_x, vid_y, vid_w, vid_h,
40276 : drw_x, drw_y, drw_w, drw_h);
40278 : pPort->time = currentTime;
40286 : ClientPtr client,
40291 : unsigned long id;
40294 : UpdateCurrentTime();
40295 : time = ClientTimeToServerTime(ctime);
40297 : if (pPort->grab.client && (client != pPort->grab.client))
40299 : *p_result = XvAlreadyGrabbed;
40303 : if ((CompareTimeStamps(time, currentTime) == LATER) ||
40304 : (CompareTimeStamps(time, pPort->time) == EARLIER))
40306 : *p_result = XvInvalidTime;
40310 : if (client == pPort->grab.client)
40312 : *p_result = Success;
40316 : id = FakeClientID(client->index);
40318 : if (!AddResource(id, XvRTGrab, &pPort->grab))
40323 : /* IF THERE IS ACTIVE VIDEO THEN STOP IT */
40325 : if ((pPort->pDraw) && (client != pPort->client))
40327 : XVCALL(diStopVideo)((ClientPtr)NULL, pPort, pPort->pDraw);
40330 : pPort->grab.client = client;
40331 : pPort->grab.id = id;
40333 : pPort->time = currentTime;
40335 : *p_result = Success;
40343 : ClientPtr client,
40349 : UpdateCurrentTime();
40350 : time = ClientTimeToServerTime(ctime);
40352 : if ((!pPort->grab.client) || (client != pPort->grab.client))
40357 : if ((CompareTimeStamps(time, currentTime) == LATER) ||
40358 : (CompareTimeStamps(time, pPort->time) == EARLIER))
40363 : /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */
40365 : FreeResource(pPort->grab.id, XvRTGrab);
40366 : pPort->grab.client = (ClientPtr)NULL;
40368 : pPort->time = currentTime;
40376 :XvdiSelectVideoNotify(
40377 : ClientPtr client,
40378 : DrawablePtr pDraw,
40381 : XvVideoNotifyPtr pn,tpn,fpn;
40383 : /* FIND VideoNotify LIST */
40385 : pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList);
40387 : /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */
40389 : if (!onoff && !pn) return Success;
40391 : /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST
40392 : WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */
40396 : if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec))))
40398 : tpn->next = (XvVideoNotifyPtr)NULL;
40399 : if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn))
40407 : /* LOOK TO SEE IF ENTRY ALREADY EXISTS */
40409 : fpn = (XvVideoNotifyPtr)NULL;
40413 : if (tpn->client == client)
40415 : if (!onoff) tpn->client = (ClientPtr)NULL;
40418 : if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */
40422 : /* IF TUNNING OFF, THEN JUST RETURN */
40424 : if (!onoff) return Success;
40426 : /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */
40434 : if (!(tpn = (XvVideoNotifyPtr)xalloc(sizeof(XvVideoNotifyRec))))
40436 : tpn->next = pn->next;
40441 : /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */
40442 : /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */
40444 : tpn->client = (ClientPtr)NULL;
40445 : tpn->id = FakeClientID(client->index);
40446 : AddResource(tpn->id, XvRTVideoNotify, tpn);
40448 : tpn->client = client;
40454 :XvdiSelectPortNotify(
40455 : ClientPtr client,
40459 : XvPortNotifyPtr pn,tpn;
40461 : /* SEE IF CLIENT IS ALREADY IN LIST */
40463 : tpn = (XvPortNotifyPtr)NULL;
40464 : pn = pPort->pNotify;
40467 : if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */
40468 : if (pn->client == client) break;
40472 : /* IS THE CLIENT ALREADY ON THE LIST? */
40480 : pn->client = (ClientPtr)NULL;
40481 : FreeResource(pn->id, XvRTPortNotify);
40487 : /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE
40488 : CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */
40492 : if (!(tpn = (XvPortNotifyPtr)xalloc(sizeof(XvPortNotifyRec))))
40494 : tpn->next = pPort->pNotify;
40495 : pPort->pNotify = tpn;
40498 : tpn->client = client;
40499 : tpn->id = FakeClientID(client->index);
40500 : AddResource(tpn->id, XvRTPortNotify, tpn);
40508 : ClientPtr client,
40510 : DrawablePtr pDraw
40514 : /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
40516 : if (!pPort->pDraw || (pPort->pDraw != pDraw))
40518 : XvdiSendVideoNotify(pPort, pDraw, XvStopped);
40522 : /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
40523 : INFORM CLIENT OF ITS FAILURE */
40525 : if ((client) && (pPort->grab.client) && (pPort->grab.client != client))
40527 : XvdiSendVideoNotify(pPort, pDraw, XvBusy);
40531 : XvdiSendVideoNotify(pPort, pDraw, XvStopped);
40533 : status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw);
40535 : pPort->pDraw = (DrawablePtr)NULL;
40536 : pPort->client = (ClientPtr)client;
40537 : pPort->time = currentTime;
40545 : ClientPtr client,
40547 : DrawablePtr pDraw
40551 : /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
40553 : if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success;
40555 : XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
40557 : status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw);
40559 : pPort->pDraw = (DrawablePtr)NULL;
40560 : pPort->client = (ClientPtr)client;
40561 : pPort->time = currentTime;
40570 : DrawablePtr pDraw
40577 : pa = pPort->pAdaptor;
40579 : if (pa->pScreen != pDraw->pScreen) return BadMatch;
40581 : nf = pa->nFormats;
40582 : pf = pa->pFormats;
40586 : if ((pf->depth == pDraw->depth)
40588 : && ((pDraw->type == DRAWABLE_PIXMAP) ||
40589 : (wVisual(((WindowPtr)pDraw)) == pf->visual))
40601 :XvdiSetPortAttribute(
40602 : ClientPtr client,
40608 : XvdiSendPortNotify(pPort, attribute, value);
40611 : (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value);
40616 :XvdiGetPortAttribute(
40617 : ClientPtr client,
40624 : (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value);
40629 :WriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to)
40633 : to->u.u.type = from->u.u.type;
40634 : to->u.u.detail = from->u.u.detail;
40635 : cpswaps(from->u.videoNotify.sequenceNumber,
40636 : to->u.videoNotify.sequenceNumber);
40637 : cpswapl(from->u.videoNotify.time, to->u.videoNotify.time);
40638 : cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable);
40639 : cpswapl(from->u.videoNotify.port, to->u.videoNotify.port);
40644 :WriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to)
40648 : to->u.u.type = from->u.u.type;
40649 : to->u.u.detail = from->u.u.detail;
40650 : cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber);
40651 : cpswapl(from->u.portNotify.time, to->u.portNotify.time);
40652 : cpswapl(from->u.portNotify.port, to->u.portNotify.port);
40653 : cpswapl(from->u.portNotify.value, to->u.portNotify.value);
40657 * Total samples for file : "/home/cworth/src/xorg/xserver/render/mirect.c"
40665 : * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
40667 : * Permission to use, copy, modify, distribute, and sell this software and its
40668 : * documentation for any purpose is hereby granted without fee, provided that
40669 : * the above copyright notice appear in all copies and that both that
40670 : * copyright notice and this permission notice appear in supporting
40671 : * documentation, and that the name of Keith Packard not be used in
40672 : * advertising or publicity pertaining to distribution of the software without
40673 : * specific, written prior permission. Keith Packard makes no
40674 : * representations about the suitability of this software for any purpose. It
40675 : * is provided "as is" without express or implied warranty.
40677 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
40678 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
40679 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
40680 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
40681 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
40682 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
40683 : * PERFORMANCE OF THIS SOFTWARE.
40686 :#ifdef HAVE_DIX_CONFIG_H
40687 :#include <dix-config.h>
40690 :#include "scrnintstr.h"
40691 :#include "gcstruct.h"
40692 :#include "pixmapstr.h"
40693 :#include "windowstr.h"
40695 :#include "picturestr.h"
40696 :#include "mipict.h"
40699 :miColorRects (PicturePtr pDst,
40700 : PicturePtr pClipPict,
40701 : xRenderColor *color,
40703 : xRectangle *rects,
40706 1 0.0011 :{ /* miColorRects total: 15 0.0163 */
40707 : ScreenPtr pScreen = pDst->pDrawable->pScreen;
40710 : CARD32 tmpval[5];
40712 : unsigned long mask;
40714 1 0.0011 : miRenderColorToPixel (pDst->pFormat, color, &pixel);
40716 : pGC = GetScratchGC (pDst->pDrawable->depth, pScreen);
40719 : tmpval[0] = GXcopy;
40720 : tmpval[1] = pixel;
40721 1 0.0011 : tmpval[2] = pDst->subWindowMode;
40722 : mask = GCFunction | GCForeground | GCSubwindowMode;
40723 4 0.0044 : if (pClipPict->clientClipType == CT_REGION)
40725 1 0.0011 : tmpval[3] = pDst->clipOrigin.x - xoff;
40726 : tmpval[4] = pDst->clipOrigin.y - yoff;
40727 : mask |= GCClipXOrigin|GCClipYOrigin;
40729 : pClip = REGION_CREATE (pScreen, NULL, 1);
40730 : REGION_COPY (pScreen, pClip,
40731 : (RegionPtr) pClipPict->clientClip);
40732 : (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
40735 1 0.0011 : ChangeGC (pGC, mask, tmpval);
40736 2 0.0022 : ValidateGC (pDst->pDrawable, pGC);
40737 1 0.0011 : if (xoff || yoff)
40740 : for (i = 0; i < nRect; i++)
40742 : rects[i].x -= xoff;
40743 : rects[i].y -= yoff;
40746 3 0.0033 : (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
40747 : if (xoff || yoff)
40750 : for (i = 0; i < nRect; i++)
40752 : rects[i].x += xoff;
40753 : rects[i].y += yoff;
40756 : FreeScratchGC (pGC);
40760 :miCompositeRects (CARD8 op,
40762 : xRenderColor *color,
40764 : xRectangle *rects)
40765 3 0.0033 :{ /* miCompositeRects total: 9 0.0098 */
40766 : ScreenPtr pScreen = pDst->pDrawable->pScreen;
40768 : if (color->alpha == 0xffff)
40770 2 0.0022 : if (op == PictOpOver)
40773 1 0.0011 : if (op == PictOpClear)
40774 : color->red = color->green = color->blue = color->alpha = 0;
40776 1 0.0011 : if (op == PictOpSrc || op == PictOpClear)
40778 : miColorRects (pDst, pDst, color, nRect, rects, 0, 0);
40779 1 0.0011 : if (pDst->alphaMap)
40780 : miColorRects (pDst->alphaMap, pDst,
40781 : color, nRect, rects,
40782 : pDst->alphaOrigin.x,
40783 : pDst->alphaOrigin.y);
40787 : PictFormatPtr rgbaFormat;
40788 : PixmapPtr pPixmap;
40794 : CARD32 tmpval[2];
40796 : rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
40800 : pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1,
40801 : rgbaFormat->depth);
40805 : miRenderColorToPixel (rgbaFormat, color, &pixel);
40807 : pGC = GetScratchGC (rgbaFormat->depth, pScreen);
40810 : tmpval[0] = GXcopy;
40811 : tmpval[1] = pixel;
40813 : ChangeGC (pGC, GCFunction | GCForeground, tmpval);
40814 : ValidateGC (&pPixmap->drawable, pGC);
40819 : (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
40821 : tmpval[0] = xTrue;
40822 : pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat,
40823 : CPRepeat, tmpval, 0, &error);
40830 : CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0,
40838 : FreePicture ((pointer) pSrc, 0);
40840 : FreeScratchGC (pGC);
40842 : (*pScreen->DestroyPixmap) (pPixmap);
40849 * Total samples for file : "/home/cworth/src/pixman/pixman/pixman-utils.c"
40856 : * Copyright © 2000 SuSE, Inc.
40858 : * Permission to use, copy, modify, distribute, and sell this software and its
40859 : * documentation for any purpose is hereby granted without fee, provided that
40860 : * the above copyright notice appear in all copies and that both that
40861 : * copyright notice and this permission notice appear in supporting
40862 : * documentation, and that the name of SuSE not be used in advertising or
40863 : * publicity pertaining to distribution of the software without specific,
40864 : * written prior permission. SuSE makes no representations about the
40865 : * suitability of this software for any purpose. It is provided "as is"
40866 : * without express or implied warranty.
40868 : * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
40869 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
40870 : * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40871 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
40872 : * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
40873 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40875 : * Author: Keith Packard, SuSE, Inc.
40878 :#include <config.h>
40879 :#include "pixman.h"
40880 :#include "pixman-private.h"
40881 :#include "pixman-mmx.h"
40884 :pixman_transform_point_3d (pixman_transform_t *transform,
40885 : pixman_vector_t *vector)
40887 : pixman_vector_t result;
40889 : pixman_fixed_32_32_t partial;
40890 : pixman_fixed_48_16_t v;
40892 : for (j = 0; j < 3; j++)
40895 : for (i = 0; i < 3; i++)
40897 : partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
40898 : (pixman_fixed_48_16_t) vector->vector[i]);
40899 : v += partial >> 16;
40902 : if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
40905 : result.vector[j] = (pixman_fixed_48_16_t) v;
40908 : if (!result.vector[2])
40911 : *vector = result;
40916 :pixman_blt (uint32_t *src_bits,
40917 : uint32_t *dst_bits,
40922 : int src_x, int src_y,
40923 : int dst_x, int dst_y,
40924 : int width, int height)
40927 : if (pixman_have_mmx())
40929 : return pixman_blt_mmx (src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
40930 : src_x, src_y, dst_x, dst_y, width, height);
40938 :pixman_fill8 (uint32_t *bits,
40946 : int byte_stride = stride * sizeof (uint32_t);
40947 : uint8_t *dst = (uint8_t *) bits;
40948 : uint8_t v = xor & 0xff;
40951 : dst = dst + y * byte_stride + x;
40955 : for (i = 0; i < width; ++i)
40958 : dst += byte_stride;
40963 :pixman_fill16 (uint32_t *bits,
40971 : int short_stride = (stride * sizeof (uint32_t)) / sizeof (uint16_t);
40972 : uint16_t *dst = (uint16_t *)bits;
40973 : uint16_t v = xor & 0xffff;
40976 : dst = dst + y * short_stride + x;
40980 : for (i = 0; i < width; ++i)
40983 : dst += short_stride;
40988 :pixman_fill32 (uint32_t *bits,
40998 : bits = bits + y * stride + x;
41002 : for (i = 0; i < width; ++i)
41010 :pixman_fill (uint32_t *bits,
41020 : printf ("filling: %d %d %d %d (stride: %d, bpp: %d) pixel: %x\n",
41021 : x, y, width, height, stride, bpp, xor);
41025 : if (!pixman_have_mmx() || !pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
41031 : pixman_fill8 (bits, stride, x, y, width, height, xor);
41035 : pixman_fill16 (bits, stride, x, y, width, height, xor);
41039 : pixman_fill32 (bits, stride, x, y, width, height, xor);
41053 : * Compute the smallest value no less than y which is on a
41058 :pixman_sample_ceil_y (pixman_fixed_t y, int n)
41059 :{ /* pixman_sample_ceil_y total: 1 0.0011 */
41060 : pixman_fixed_t f = pixman_fixed_frac(y);
41061 : pixman_fixed_t i = pixman_fixed_floor(y);
41063 1 0.0011 : f = ((f + Y_FRAC_FIRST(n)) / STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
41064 : if (f > Y_FRAC_LAST(n))
41066 : f = Y_FRAC_FIRST(n);
41067 : i += pixman_fixed_1;
41072 :#define _div(a,b) ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b)))
41075 : * Compute the largest value no greater than y which is on a
41079 :pixman_sample_floor_y (pixman_fixed_t y, int n)
41080 :{ /* pixman_sample_floor_y total: 5 0.0054 */
41081 : pixman_fixed_t f = pixman_fixed_frac(y);
41082 1 0.0011 : pixman_fixed_t i = pixman_fixed_floor (y);
41084 4 0.0044 : f = _div(f - Y_FRAC_FIRST(n), STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
41085 : if (f < Y_FRAC_FIRST(n))
41087 : f = Y_FRAC_LAST(n);
41088 : i -= pixman_fixed_1;
41094 : * Step an edge by any amount (including negative values)
41097 :pixman_edge_step (pixman_edge_t *e, int n)
41098 :{ /* pixman_edge_step total: 3 0.0033 */
41099 : pixman_fixed_48_16_t ne;
41101 : e->x += n * e->stepx;
41103 : ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
41107 1 0.0011 : if (ne > 0)
41109 2 0.0022 : int nx = (ne + e->dy - 1) / e->dy;
41110 : e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
41111 : e->x += nx * e->signdx;
41116 : if (ne <= -e->dy)
41118 : int nx = (-ne) / e->dy;
41119 : e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
41120 : e->x -= nx * e->signdx;
41126 : * A private routine to initialize the multi-step
41127 : * elements of an edge structure
41130 :_pixman_edge_tMultiInit (pixman_edge_t *e, int n, pixman_fixed_t *stepx_p, pixman_fixed_t *dx_p)
41131 2 0.0022 :{ /* _pixman_edge_tMultiInit total: 7 0.0076 */
41132 : pixman_fixed_t stepx;
41133 : pixman_fixed_48_16_t ne;
41135 2 0.0022 : ne = n * (pixman_fixed_48_16_t) e->dx;
41136 : stepx = n * e->stepx;
41139 1 0.0011 : int nx = ne / e->dy;
41140 : ne -= nx * e->dy;
41141 1 0.0011 : stepx += nx * e->signdx;
41143 1 0.0011 : *dx_p = ne;
41144 : *stepx_p = stepx;
41148 : * Initialize one edge structure given the line endpoints and a
41149 : * starting y value
41152 :pixman_edge_init (pixman_edge_t *e,
41154 : pixman_fixed_t y_start,
41155 : pixman_fixed_t x_top,
41156 : pixman_fixed_t y_top,
41157 : pixman_fixed_t x_bot,
41158 : pixman_fixed_t y_bot)
41159 2 0.0022 :{ /* pixman_edge_init total: 7 0.0076 */
41160 : pixman_fixed_t dx, dy;
41164 : dx = x_bot - x_top;
41165 : dy = y_bot - y_top;
41173 : e->stepx = dx / dy;
41179 1 0.0011 : e->signdx = -1;
41180 : e->stepx = -(-dx / dy);
41181 : e->dx = -dx % dy;
41185 3 0.0033 : _pixman_edge_tMultiInit (e, STEP_Y_SMALL(n), &e->stepx_small, &e->dx_small);
41186 : _pixman_edge_tMultiInit (e, STEP_Y_BIG(n), &e->stepx_big, &e->dx_big);
41188 1 0.0011 : pixman_edge_step (e, y_start - y_top);
41192 : * Initialize one edge structure given a line, starting y value
41193 : * and a pixel offset for the line
41196 :pixman_line_fixed_edge_init (pixman_edge_t *e,
41198 : pixman_fixed_t y,
41199 : const pixman_line_fixed_t *line,
41202 1 0.0011 :{ /* pixman_line_fixed_edge_init total: 1 0.0011 */
41203 : pixman_fixed_t x_off_fixed = pixman_int_to_fixed(x_off);
41204 : pixman_fixed_t y_off_fixed = pixman_int_to_fixed(y_off);
41205 : const pixman_point_fixed_t *top, *bot;
41207 : if (line->p1.y <= line->p2.y)
41217 : pixman_edge_init (e, n, y,
41218 : top->x + x_off_fixed,
41219 : top->y + y_off_fixed,
41220 : bot->x + x_off_fixed,
41221 : bot->y + y_off_fixed);
41224 * Total samples for file : "/home/cworth/src/xorg/xserver/os/utils.c"
41232 :Copyright 1987, 1998 The Open Group
41234 :Permission to use, copy, modify, distribute, and sell this software and its
41235 :documentation for any purpose is hereby granted without fee, provided that
41236 :the above copyright notice appear in all copies and that both that
41237 :copyright notice and this permission notice appear in supporting
41240 :The above copyright notice and this permission notice shall be included
41241 :in all copies or substantial portions of the Software.
41243 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
41244 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41245 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
41246 :IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
41247 :OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
41248 :ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41249 :OTHER DEALINGS IN THE SOFTWARE.
41251 :Except as contained in this notice, the name of The Open Group shall
41252 :not be used in advertising or otherwise to promote the sale, use or
41253 :other dealings in this Software without prior written authorization
41254 :from The Open Group.
41257 :Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
41258 :Copyright 1994 Quarterdeck Office Systems.
41260 : All Rights Reserved
41262 :Permission to use, copy, modify, and distribute this software and its
41263 :documentation for any purpose and without fee is hereby granted,
41264 :provided that the above copyright notice appear in all copies and that
41265 :both that copyright notice and this permission notice appear in
41266 :supporting documentation, and that the names of Digital and
41267 :Quarterdeck not be used in advertising or publicity pertaining to
41268 :distribution of the software without specific, written prior
41271 :DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
41272 :SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
41273 :FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
41274 :OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
41275 :OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
41276 :OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
41277 :OR PERFORMANCE OF THIS SOFTWARE.
41281 :#ifdef HAVE_DIX_CONFIG_H
41282 :#include <dix-config.h>
41286 :#include <stdlib.h>
41287 :#include <signal.h>
41290 :#if defined(WIN32) && !defined(__CYGWIN__)
41291 :#include <X11/Xwinsock.h>
41293 :#include <X11/Xos.h>
41294 :#include <stdio.h>
41296 :#if !defined(WIN32) || !defined(__MINGW32__)
41297 :#include <sys/time.h>
41298 :#include <sys/resource.h>
41301 :#include <X11/X.h>
41303 :#define TRANS_SERVER
41304 :#define TRANS_REOPEN
41305 :#include <X11/Xtrans/Xtrans.h>
41306 :#include "input.h"
41307 :#include "dixfont.h"
41308 :#include "osdep.h"
41309 :#include "extension.h"
41310 :#ifdef X_POSIX_C_SOURCE
41311 :#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
41312 :#include <signal.h>
41313 :#undef _POSIX_C_SOURCE
41315 :#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
41316 :#include <signal.h>
41318 :#define _POSIX_SOURCE
41319 :#include <signal.h>
41320 :#undef _POSIX_SOURCE
41324 :#include <sys/wait.h>
41326 :#if !defined(SYSV) && !defined(WIN32) && !defined(Lynx) && !defined(QNX4)
41327 :#include <sys/resource.h>
41329 :#include <sys/stat.h>
41330 :#include <ctype.h> /* for isspace */
41331 :#include <stdarg.h>
41334 :#include <sys/resource.h>
41335 :#include <netdb.h>
41338 :#include <stdlib.h> /* for malloc() */
41340 :#if defined(TCPCONN) || defined(STREAMSCONN)
41342 :# include <netdb.h>
41346 :#include "opaque.h"
41348 :#ifdef SMART_SCHEDULE
41349 :#include "dixstruct.h"
41353 :#include <xkbsrv.h>
41356 :#include "securitysrv.h"
41360 :#include "picture.h"
41364 :#include "DiPrint.h"
41367 :_X_EXPORT Bool noTestExtensions;
41369 :_X_EXPORT Bool noBigReqExtension = FALSE;
41372 :_X_EXPORT Bool noCompositeExtension = FALSE;
41376 :_X_EXPORT Bool noDamageExtension = FALSE;
41379 :_X_EXPORT Bool noDbeExtension = FALSE;
41381 :#ifdef DPMSExtension
41382 :_X_EXPORT Bool noDPMSExtension = FALSE;
41385 :_X_EXPORT Bool noEVIExtension = FALSE;
41388 :_X_EXPORT Bool noFontCacheExtension = FALSE;
41391 :_X_EXPORT Bool noGlxExtension = FALSE;
41393 :#ifdef SCREENSAVER
41394 :_X_EXPORT Bool noScreenSaverExtension = FALSE;
41397 :_X_EXPORT Bool noMITShmExtension = FALSE;
41400 :_X_EXPORT Bool noMITMiscExtension = FALSE;
41402 :#ifdef MULTIBUFFER
41403 :_X_EXPORT Bool noMultibufferExtension = FALSE;
41406 :_X_EXPORT Bool noRRExtension = FALSE;
41409 :_X_EXPORT Bool noRenderExtension = FALSE;
41412 :_X_EXPORT Bool noShapeExtension = FALSE;
41415 :_X_EXPORT Bool noSecurityExtension = FALSE;
41418 :_X_EXPORT Bool noSyncExtension = FALSE;
41421 :_X_EXPORT Bool noXcupExtension = FALSE;
41424 :_X_EXPORT Bool noResExtension = FALSE;
41427 :_X_EXPORT Bool noXagExtension = FALSE;
41430 :_X_EXPORT Bool noXCMiscExtension = FALSE;
41433 :/* Xevie is disabled by default for now until the
41434 : * interface is stable */
41435 :_X_EXPORT Bool noXevieExtension = TRUE;
41437 :#ifdef XF86BIGFONT
41438 :_X_EXPORT Bool noXFree86BigfontExtension = FALSE;
41441 :_X_EXPORT Bool noXFree86DGAExtension = FALSE;
41444 :_X_EXPORT Bool noXFree86DRIExtension = FALSE;
41447 :_X_EXPORT Bool noXFree86MiscExtension = FALSE;
41449 :#ifdef XF86VIDMODE
41450 :_X_EXPORT Bool noXFree86VidModeExtension = FALSE;
41453 :_X_EXPORT Bool noXFixesExtension = FALSE;
41455 :/* |noXkbExtension| is defined in xc/programs/Xserver/xkb/xkbInit.c */
41457 :/* Xinerama is disabled by default unless enabled via +xinerama */
41458 :_X_EXPORT Bool noPanoramiXExtension = TRUE;
41461 :_X_EXPORT Bool noXInputExtension = FALSE;
41464 :_X_EXPORT Bool noXIdleExtension = FALSE;
41467 :_X_EXPORT Bool noXvExtension = FALSE;
41470 :#define X_INCLUDE_NETDB_H
41471 :#include <X11/Xos_r.h>
41473 :#include <errno.h>
41478 :Bool PanoramiXExtensionDisabledHack = FALSE;
41481 :int auditTrailLevel = 1;
41483 :_X_EXPORT Bool Must_have_memory = FALSE;
41487 :extern int SelectWaitTime;
41490 :#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
41491 :#define HAS_SAVED_IDS_AND_SETEUID
41495 :#define MEM_FAIL_SCALE 100000
41496 :long Memory_fail = 0;
41497 :#include <stdlib.h> /* for random() */
41500 :static char *dev_tty_from_init = NULL; /* since we need to parse it anyway */
41503 :OsSignal(sig, handler)
41505 : OsSigHandlerPtr handler;
41507 :#ifdef X_NOT_POSIX
41508 : return signal(sig, handler);
41510 : struct sigaction act, oact;
41512 : sigemptyset(&act.sa_mask);
41513 : if (handler != SIG_IGN)
41514 : sigaddset(&act.sa_mask, sig);
41515 : act.sa_flags = 0;
41516 : act.sa_handler = handler;
41517 : sigaction(sig, &act, &oact);
41518 : return oact.sa_handler;
41522 :#ifdef SERVER_LOCK
41524 : * Explicit support for a server lock file like the ones used for UUCP.
41525 : * For architectures with virtual terminals that can run more than one
41526 : * server at a time. This keeps the servers from stomping on each other
41527 : * if the user forgets to give them different display numbers.
41529 :#define LOCK_DIR "/tmp"
41530 :#define LOCK_TMP_PREFIX "/.tX"
41531 :#define LOCK_PREFIX "/.X"
41532 :#define LOCK_SUFFIX "-lock"
41535 :#include <limits.h>
41536 :#include <sys/param.h>
41541 :#include <sys/param.h>
41543 :#include <param.h>
41547 :#define PATH_MAX MAXPATHLEN
41549 :#define PATH_MAX 1024
41554 :static Bool StillLocking = FALSE;
41555 :static char LockFile[PATH_MAX];
41556 :static Bool nolock = FALSE;
41560 : * Check if the server lock file exists. If so, check if the PID
41561 : * contained inside is valid. If so, then die. Otherwise, create
41562 : * the lock file containing the PID.
41567 : char tmp[PATH_MAX], pid_str[12];
41568 : int lfd, i, haslock, l_pid, t;
41569 : char *tmppath = NULL;
41573 : if (nolock) return;
41577 : tmppath = LOCK_DIR;
41579 : sprintf(port, "%d", atoi(display));
41580 : len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) :
41581 : strlen(LOCK_TMP_PREFIX);
41582 : len += strlen(tmppath) + strlen(port) + strlen(LOCK_SUFFIX) + 1;
41583 : if (len > sizeof(LockFile))
41584 : FatalError("Display name `%s' is too long\n", port);
41585 : (void)sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
41586 : (void)sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
41589 : * Create a temporary file containing our PID. Attempt three times
41590 : * to create the file.
41592 : StillLocking = TRUE;
41596 : lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
41607 : lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
41615 : FatalError("Could not create lock file in %s\n", tmp);
41616 : (void) sprintf(pid_str, "%10ld\n", (long)getpid());
41617 : (void) write(lfd, pid_str, 11);
41619 : (void) fchmod(lfd, 0444);
41621 : (void) chmod(tmp, 0444);
41623 : (void) close(lfd);
41626 : * OK. Now the tmp file exists. Try three times to move it in place
41631 : while ((!haslock) && (i++ < 3)) {
41632 : haslock = (link(tmp,LockFile) == 0);
41641 : * Read the pid from the existing file
41643 : lfd = open(LockFile, O_RDONLY);
41646 : FatalError("Can't read lock file %s\n", LockFile);
41648 : pid_str[0] = '\0';
41649 : if (read(lfd, pid_str, 11) != 11) {
41651 : * Bogus lock file.
41653 : unlink(LockFile);
41657 : pid_str[11] = '\0';
41658 : sscanf(pid_str, "%d", &l_pid);
41662 : * Now try to kill the PID to see if it exists.
41665 : t = kill(l_pid, 0);
41666 : if ((t< 0) && (errno == ESRCH)) {
41668 : * Stale lock file.
41670 : unlink(LockFile);
41673 : else if (((t < 0) && (errno == EPERM)) || (t == 0)) {
41675 : * Process is still active.
41678 : FatalError("Server is already active for display %s\n%s %s\n%s\n",
41679 : port, "\tIf this server is no longer running, remove",
41680 : LockFile, "\tand start again.");
41686 : FatalError("Could not create server lock file: %s\n", LockFile);
41687 : StillLocking = FALSE;
41691 : * UnlockServer --
41692 : * Remove the server lock file.
41695 :UnlockServer(void)
41697 : if (nolock) return;
41699 : if (!StillLocking){
41701 : (void) unlink(LockFile);
41704 :#endif /* SERVER_LOCK */
41706 :/* Force connections to close on SIGHUP from init */
41710 :AutoResetServer (int sig)
41712 : int olderrno = errno;
41714 : dispatchException |= DE_RESET;
41715 : isItTimeToYield = TRUE;
41720 :#if defined(SYSV) && defined(X_NOT_POSIX)
41721 : OsSignal (SIGHUP, AutoResetServer);
41723 : errno = olderrno;
41726 :/* Force connections to close and then exit on SIGTERM, SIGINT */
41732 : int olderrno = errno;
41734 : dispatchException |= DE_TERMINATE;
41735 : isItTimeToYield = TRUE;
41736 :#if defined(SYSV) && defined(X_NOT_POSIX)
41738 : OsSignal(sig, SIG_IGN);
41740 : errno = olderrno;
41743 :#if defined WIN32 && defined __MINGW32__
41745 :GetTimeInMillis (void)
41747 : return GetTickCount ();
41751 :GetTimeInMillis(void)
41752 1 0.0011 :{ /* GetTimeInMillis total: 1 0.0011 */
41753 : struct timeval tv;
41755 :#ifdef MONOTONIC_CLOCK
41756 : struct timespec tp;
41757 : if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
41758 : return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
41761 : X_GETTIMEOFDAY(&tv);
41762 : return(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
41767 :AdjustWaitForDelay (pointer waitTime, unsigned long newdelay)
41769 : static struct timeval delay_val;
41770 : struct timeval **wt = (struct timeval **) waitTime;
41771 : unsigned long olddelay;
41775 : delay_val.tv_sec = newdelay / 1000;
41776 : delay_val.tv_usec = 1000 * (newdelay % 1000);
41777 : *wt = &delay_val;
41781 : olddelay = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000;
41782 : if (newdelay < olddelay)
41784 : (*wt)->tv_sec = newdelay / 1000;
41785 : (*wt)->tv_usec = 1000 * (newdelay % 1000);
41792 :#if !defined(AIXrt) && !defined(AIX386)
41793 : ErrorF("use: X [:<display>] [option]\n");
41794 : ErrorF("-a # mouse acceleration (pixels)\n");
41795 : ErrorF("-ac disable access control restrictions\n");
41797 : ErrorF("-alloc int chance alloc should fail\n");
41799 : ErrorF("-audit int set audit trail level\n");
41800 : ErrorF("-auth file select authorization file\n");
41801 : ErrorF("-br create root window with black background\n");
41802 : ErrorF("+bs enable any backing store support\n");
41803 : ErrorF("-bs disable any backing store support\n");
41804 : ErrorF("-c turns off key-click\n");
41805 : ErrorF("c # key-click volume (0-100)\n");
41806 : ErrorF("-cc int default color visual class\n");
41807 : ErrorF("-co file color database file\n");
41808 :#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
41809 : ErrorF("-config file read options from file\n");
41811 : ErrorF("-core generate core dump on fatal error\n");
41812 : ErrorF("-dpi int screen resolution in dots per inch\n");
41813 :#ifdef DPMSExtension
41814 : ErrorF("dpms enables VESA DPMS monitor control\n");
41815 : ErrorF("-dpms disables VESA DPMS monitor control\n");
41817 : ErrorF("-deferglyphs [none|all|16] defer loading of [no|all|16-bit] glyphs\n");
41818 : ErrorF("-f # bell base (0-100)\n");
41819 : ErrorF("-fc string cursor font\n");
41820 : ErrorF("-fn string default font name\n");
41821 : ErrorF("-fp string default font path\n");
41822 : ErrorF("-help prints message with these options\n");
41823 : ErrorF("-I ignore all remaining arguments\n");
41824 :#ifdef RLIMIT_DATA
41825 : ErrorF("-ld int limit data space to N Kb\n");
41827 :#ifdef RLIMIT_NOFILE
41828 : ErrorF("-lf int limit number of open files to N\n");
41830 :#ifdef RLIMIT_STACK
41831 : ErrorF("-ls int limit stack space to N Kb\n");
41833 :#ifdef SERVER_LOCK
41834 : ErrorF("-nolock disable the locking mechanism\n");
41836 :#ifndef NOLOGOHACK
41837 : ErrorF("-logo enable logo in screen saver\n");
41838 : ErrorF("nologo disable logo in screen saver\n");
41840 : ErrorF("-nolisten string don't listen on protocol\n");
41841 : ErrorF("-noreset don't reset after last client exists\n");
41842 : ErrorF("-reset reset after last client exists\n");
41843 : ErrorF("-p # screen-saver pattern duration (minutes)\n");
41844 : ErrorF("-pn accept failure to listen on all ports\n");
41845 : ErrorF("-nopn reject failure to listen on all ports\n");
41846 : ErrorF("-r turns off auto-repeat\n");
41847 : ErrorF("r turns on auto-repeat \n");
41849 : ErrorF("-render [default|mono|gray|color] set render color alloc policy\n");
41851 : ErrorF("-s # screen-saver timeout (minutes)\n");
41853 : ErrorF("-sp file security policy file\n");
41858 : ErrorF("-su disable any save under support\n");
41859 : ErrorF("-t # mouse threshold (pixels)\n");
41860 : ErrorF("-terminate terminate at server reset\n");
41861 : ErrorF("-to # connection time out\n");
41862 : ErrorF("-tst disable testing extensions\n");
41863 : ErrorF("ttyxx server started from init on /dev/ttyxx\n");
41864 : ErrorF("v video blanking for screen-saver\n");
41865 : ErrorF("-v screen-saver without video blanking\n");
41866 : ErrorF("-wm WhenMapped default backing-store\n");
41867 : ErrorF("-wr create root window with white background\n");
41868 : ErrorF("-x string loads named extension at init time \n");
41869 : ErrorF("-maxbigreqsize set maximal bigrequest size \n");
41871 : ErrorF("+xinerama Enable XINERAMA extension\n");
41872 : ErrorF("-xinerama Disable XINERAMA extension\n");
41874 :#ifdef SMART_SCHEDULE
41875 : ErrorF("-dumbSched Disable smart scheduling, enable old behavior\n");
41876 : ErrorF("-schedInterval int Set scheduler interval in msec\n");
41878 : ErrorF("+extension name Enable extension\n");
41879 : ErrorF("-extension name Disable extension\n");
41883 :#endif /* !AIXrt && ! AIX386 */
41890 :/* This function performs a rudimentary sanity check
41891 : * on the display name passed in on the command-line,
41892 : * since this string is used to generate filenames.
41893 : * It is especially important that the display name
41894 : * not contain a "/" and not start with a "-".
41898 :VerifyDisplayName(const char *d)
41900 : if ( d == (char *)0 ) return( 0 ); /* null */
41901 : if ( *d == '\0' ) return( 0 ); /* empty */
41902 : if ( *d == '-' ) return( 0 ); /* could be confused for an option */
41903 : if ( *d == '.' ) return( 0 ); /* must not equal "." or ".." */
41904 : if ( strchr(d, '/') != (char *)0 ) return( 0 ); /* very important!!! */
41909 : * This function is responsible for doing initalisation of any global
41910 : * variables at an very early point of server startup (even before
41911 : * |ProcessCommandLine()|.
41913 :void InitGlobals(void)
41915 : ddxInitGlobals();
41920 : * This function parses the command line. Handles device-independent fields
41921 : * and allows ddx to handle additional fields. It is not allowed to modify
41922 : * argc or any of the strings pointed to by argv.
41925 :ProcessCommandLine(int argc, char *argv[])
41929 : defaultKeyboardControl.autoRepeat = TRUE;
41931 :#ifdef NO_PART_NET
41932 : PartialNetwork = FALSE;
41934 : PartialNetwork = TRUE;
41937 : for ( i = 1; i < argc; i++ )
41939 : /* call ddx first, so it can peek/override if it wants */
41940 : if((skip = ddxProcessArgument(argc, argv, i)))
41944 : else if(argv[i][0] == ':')
41946 : /* initialize display */
41947 : display = argv[i];
41949 : if( ! VerifyDisplayName( display ) ) {
41950 : ErrorF("Bad display name: %s\n", display);
41952 : FatalError("Bad display name, exiting: %s\n", display);
41955 : else if ( strcmp( argv[i], "-a") == 0)
41958 : defaultPointerControl.num = atoi(argv[i]);
41962 : else if ( strcmp( argv[i], "-ac") == 0)
41964 : defeatAccessControl = TRUE;
41967 : else if ( strcmp( argv[i], "-alloc") == 0)
41970 : Memory_fail = atoi(argv[i]);
41975 : else if ( strcmp( argv[i], "-audit") == 0)
41978 : auditTrailLevel = atoi(argv[i]);
41982 : else if ( strcmp( argv[i], "-auth") == 0)
41985 : InitAuthorization (argv[i]);
41989 : else if ( strcmp( argv[i], "-br") == 0)
41990 : blackRoot = TRUE;
41991 : else if ( strcmp( argv[i], "+bs") == 0)
41992 : enableBackingStore = TRUE;
41993 : else if ( strcmp( argv[i], "-bs") == 0)
41994 : disableBackingStore = TRUE;
41995 : else if ( strcmp( argv[i], "c") == 0)
41998 : defaultKeyboardControl.click = atoi(argv[i]);
42002 : else if ( strcmp( argv[i], "-c") == 0)
42004 : defaultKeyboardControl.click = 0;
42006 : else if ( strcmp( argv[i], "-cc") == 0)
42009 : defaultColorVisualClass = atoi(argv[i]);
42013 : else if ( strcmp( argv[i], "-co") == 0)
42016 : rgbPath = argv[i];
42020 : else if ( strcmp( argv[i], "-core") == 0)
42023 :#if !defined(WIN32) || !defined(__MINGW32__)
42024 : struct rlimit core_limit;
42025 : getrlimit (RLIMIT_CORE, &core_limit);
42026 : core_limit.rlim_cur = core_limit.rlim_max;
42027 : setrlimit (RLIMIT_CORE, &core_limit);
42030 : else if ( strcmp( argv[i], "-dpi") == 0)
42033 : monitorResolution = atoi(argv[i]);
42037 :#ifdef DPMSExtension
42038 : else if ( strcmp( argv[i], "dpms") == 0)
42039 : DPMSEnabledSwitch = TRUE;
42040 : else if ( strcmp( argv[i], "-dpms") == 0)
42041 : DPMSDisabledSwitch = TRUE;
42043 : else if ( strcmp( argv[i], "-deferglyphs") == 0)
42045 : if(++i >= argc || !ParseGlyphCachingMode(argv[i]))
42048 : else if ( strcmp( argv[i], "-f") == 0)
42051 : defaultKeyboardControl.bell = atoi(argv[i]);
42055 : else if ( strcmp( argv[i], "-fc") == 0)
42058 : defaultCursorFont = argv[i];
42062 : else if ( strcmp( argv[i], "-fn") == 0)
42065 : defaultTextFont = argv[i];
42069 : else if ( strcmp( argv[i], "-fp") == 0)
42073 : defaultFontPath = argv[i];
42078 : else if ( strcmp( argv[i], "-help") == 0)
42084 : else if ( (skip=XkbProcessArguments(argc,argv,i))!=0 ) {
42090 :#ifdef RLIMIT_DATA
42091 : else if ( strcmp( argv[i], "-ld") == 0)
42095 : limitDataSpace = atoi(argv[i]);
42096 : if (limitDataSpace > 0)
42097 : limitDataSpace *= 1024;
42103 :#ifdef RLIMIT_NOFILE
42104 : else if ( strcmp( argv[i], "-lf") == 0)
42107 : limitNoFile = atoi(argv[i]);
42112 :#ifdef RLIMIT_STACK
42113 : else if ( strcmp( argv[i], "-ls") == 0)
42117 : limitStackSpace = atoi(argv[i]);
42118 : if (limitStackSpace > 0)
42119 : limitStackSpace *= 1024;
42125 :#ifdef SERVER_LOCK
42126 : else if ( strcmp ( argv[i], "-nolock") == 0)
42128 :#if !defined(WIN32) && !defined(__CYGWIN__)
42129 : if (getuid() != 0)
42130 : ErrorF("Warning: the -nolock option can only be used by root\n");
42136 :#ifndef NOLOGOHACK
42137 : else if ( strcmp( argv[i], "-logo") == 0)
42139 : logoScreenSaver = 1;
42141 : else if ( strcmp( argv[i], "nologo") == 0)
42143 : logoScreenSaver = 0;
42146 : else if ( strcmp( argv[i], "-nolisten") == 0)
42149 : if (_XSERVTransNoListen(argv[i]))
42150 : FatalError ("Failed to disable listen for %s transport",
42155 : else if ( strcmp( argv[i], "-noreset") == 0)
42157 : dispatchExceptionAtReset = 0;
42159 : else if ( strcmp( argv[i], "-reset") == 0)
42161 : dispatchExceptionAtReset = DE_RESET;
42163 : else if ( strcmp( argv[i], "-p") == 0)
42166 : defaultScreenSaverInterval = ((CARD32)atoi(argv[i])) *
42171 : else if ( strcmp( argv[i], "-pn") == 0)
42172 : PartialNetwork = TRUE;
42173 : else if ( strcmp( argv[i], "-nopn") == 0)
42174 : PartialNetwork = FALSE;
42175 : else if ( strcmp( argv[i], "r") == 0)
42176 : defaultKeyboardControl.autoRepeat = TRUE;
42177 : else if ( strcmp( argv[i], "-r") == 0)
42178 : defaultKeyboardControl.autoRepeat = FALSE;
42179 : else if ( strcmp( argv[i], "-s") == 0)
42182 : defaultScreenSaverTime = ((CARD32)atoi(argv[i])) *
42187 : else if ( strcmp( argv[i], "-su") == 0)
42188 : disableSaveUnders = TRUE;
42189 : else if ( strcmp( argv[i], "-t") == 0)
42192 : defaultPointerControl.threshold = atoi(argv[i]);
42196 : else if ( strcmp( argv[i], "-terminate") == 0)
42198 : dispatchExceptionAtReset = DE_TERMINATE;
42200 : else if ( strcmp( argv[i], "-to") == 0)
42203 : TimeOutValue = ((CARD32)atoi(argv[i])) * MILLI_PER_SECOND;
42207 : else if ( strcmp( argv[i], "-tst") == 0)
42209 : noTestExtensions = TRUE;
42211 : else if ( strcmp( argv[i], "v") == 0)
42212 : defaultScreenSaverBlanking = PreferBlanking;
42213 : else if ( strcmp( argv[i], "-v") == 0)
42214 : defaultScreenSaverBlanking = DontPreferBlanking;
42215 : else if ( strcmp( argv[i], "-wm") == 0)
42216 : defaultBackingStore = WhenMapped;
42217 : else if ( strcmp( argv[i], "-wr") == 0)
42218 : whiteRoot = TRUE;
42219 : else if ( strcmp( argv[i], "-maxbigreqsize") == 0) {
42221 : long reqSizeArg = atol(argv[i]);
42223 : /* Request size > 128MB does not make much sense... */
42224 : if( reqSizeArg > 0L && reqSizeArg < 128L ) {
42225 : maxBigRequestSize = (reqSizeArg * 1048576L) - 1L;
42238 : else if ( strcmp( argv[i], "+xinerama") == 0){
42239 : noPanoramiXExtension = FALSE;
42241 : else if ( strcmp( argv[i], "-xinerama") == 0){
42242 : noPanoramiXExtension = TRUE;
42244 : else if ( strcmp( argv[i], "-disablexineramaextension") == 0){
42245 : PanoramiXExtensionDisabledHack = TRUE;
42248 : else if ( strcmp( argv[i], "-x") == 0)
42252 : /* For U**x, which doesn't support dynamic loading, there's nothing
42253 : * to do when we see a -x. Either the extension is linked in or
42256 : else if ( strcmp( argv[i], "-I") == 0)
42258 : /* ignore all remaining arguments */
42261 : else if (strncmp (argv[i], "tty", 3) == 0)
42263 : /* just in case any body is interested */
42264 : dev_tty_from_init = argv[i];
42267 : else if ((skip = XdmcpOptions(argc, argv, i)) != i)
42273 : else if ((skip = PrinterOptions(argc, argv, i)) != i)
42279 : else if ((skip = XSecurityOptions(argc, argv, i)) != i)
42285 : else if ( strcmp( argv[i], "-timeout") == 0)
42288 : SelectWaitTime = atoi(argv[i]);
42292 : else if ( strcmp( argv[i], "-sync") == 0)
42297 :#ifdef SMART_SCHEDULE
42298 : else if ( strcmp( argv[i], "-dumbSched") == 0)
42300 : SmartScheduleDisable = TRUE;
42302 : else if ( strcmp( argv[i], "-schedInterval") == 0)
42306 : SmartScheduleInterval = atoi(argv[i]);
42307 : SmartScheduleSlice = SmartScheduleInterval;
42312 : else if ( strcmp( argv[i], "-schedMax") == 0)
42316 : SmartScheduleMaxSlice = atoi(argv[i]);
42323 : else if ( strcmp( argv[i], "-render" ) == 0)
42327 : int policy = PictureParseCmapPolicy (argv[i]);
42329 : if (policy != PictureCmapPolicyInvalid)
42330 : PictureCmapPolicy = policy;
42338 : else if ( strcmp( argv[i], "+extension") == 0)
42342 : if (!EnableDisableExtension(argv[i], TRUE))
42343 : EnableDisableExtensionError(argv[i], TRUE);
42348 : else if ( strcmp( argv[i], "-extension") == 0)
42352 : if (!EnableDisableExtension(argv[i], FALSE))
42353 : EnableDisableExtensionError(argv[i], FALSE);
42360 : ErrorF("Unrecognized option: %s\n", argv[i]);
42362 : FatalError("Unrecognized option: %s\n", argv[i]);
42367 :#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
42369 :InsertFileIntoCommandLine(
42370 : int *resargc, char ***resargv,
42371 : int prefix_argc, char **prefix_argv,
42373 : int suffix_argc, char **suffix_argv)
42384 : f = fopen(filename, "r");
42386 : FatalError("Can't open option file %s\n", filename);
42388 : fstat(fileno(f), &st);
42390 : buf = (char *) xalloc((unsigned) st.st_size + 1);
42392 : FatalError("Out of Memory\n");
42394 : len = fread(buf, 1, (unsigned) st.st_size, f);
42399 : FatalError("Error reading option file %s\n", filename);
42409 : while (isspace(*p))
42415 : while (*p && *p != '\n')
42419 : while (*p && !isspace(*p))
42421 : /* Since p and q might still be pointing at the same place, we */
42422 : /* need to step p over the whitespace now before we add the null. */
42430 : buf = (char *) xrealloc(buf, q - buf);
42432 : FatalError("Out of memory reallocing option buf\n");
42434 : *resargc = prefix_argc + insert_argc + suffix_argc;
42435 : *resargv = (char **) xalloc((*resargc + 1) * sizeof(char *));
42437 : FatalError("Out of Memory\n");
42439 : memcpy(*resargv, prefix_argv, prefix_argc * sizeof(char *));
42442 : for (i = 0; i < insert_argc; i++)
42444 : (*resargv)[prefix_argc + i] = p;
42445 : p += strlen(p) + 1;
42448 : memcpy(*resargv + prefix_argc + insert_argc,
42449 : suffix_argv, suffix_argc * sizeof(char *));
42451 : (*resargv)[*resargc] = NULL;
42452 :} /* end InsertFileIntoCommandLine */
42456 :ExpandCommandLine(int *pargc, char ***pargv)
42460 :#if !defined(WIN32) && !defined(__CYGWIN__)
42461 : if (getuid() != geteuid())
42465 : for (i = 1; i < *pargc; i++)
42467 : if ( (0 == strcmp((*pargv)[i], "-config")) && (i < (*pargc - 1)) )
42469 : InsertFileIntoCommandLine(pargc, pargv,
42471 : (*pargv)[i+1], /* filename */
42472 : *pargc - i - 2, *pargv + i + 2);
42476 :} /* end ExpandCommandLine */
42479 :/* Implement a simple-minded font authorization scheme. The authorization
42480 : name is "hp-hostname-1", the contents are simply the host name. */
42482 :set_font_authorizations(char **authorizations, int *authlen, pointer client)
42484 :#define AUTHORIZATION_NAME "hp-hostname-1"
42485 :#if defined(TCPCONN) || defined(STREAMSCONN)
42486 : static char *result = NULL;
42487 : static char *p = NULL;
42491 : char hname[1024], *hnameptr;
42492 : unsigned int len;
42493 :#if defined(IPv6) && defined(AF_INET6)
42494 : struct addrinfo hints, *ai = NULL;
42496 : struct hostent *host;
42497 :#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
42498 : _Xgethostbynameparams hparams;
42502 : gethostname(hname, 1024);
42503 :#if defined(IPv6) && defined(AF_INET6)
42504 : bzero(&hints, sizeof(hints));
42505 : hints.ai_flags = AI_CANONNAME;
42506 : if (getaddrinfo(hname, NULL, &hints, &ai) == 0) {
42507 : hnameptr = ai->ai_canonname;
42509 : hnameptr = hname;
42512 : host = _XGethostbyname(hname, hparams);
42513 : if (host == NULL)
42514 : hnameptr = hname;
42516 : hnameptr = host->h_name;
42519 : len = strlen(hnameptr) + 1;
42520 : result = xalloc(len + sizeof(AUTHORIZATION_NAME) + 4);
42523 : *p++ = sizeof(AUTHORIZATION_NAME) >> 8;
42524 : *p++ = sizeof(AUTHORIZATION_NAME) & 0xff;
42525 : *p++ = (len) >> 8;
42526 : *p++ = (len & 0xff);
42528 : memmove(p, AUTHORIZATION_NAME, sizeof(AUTHORIZATION_NAME));
42529 : p += sizeof(AUTHORIZATION_NAME);
42530 : memmove(p, hnameptr, len);
42532 :#if defined(IPv6) && defined(AF_INET6)
42534 : freeaddrinfo(ai);
42538 : *authlen = p - result;
42539 : *authorizations = result;
42541 :#else /* TCPCONN */
42543 :#endif /* TCPCONN */
42546 :/* XALLOC -- X's internal memory allocator. Why does it return unsigned
42547 : * long * instead of the more common char *? Well, if you read K&R you'll
42548 : * see they say that alloc must return a pointer "suitable for conversion"
42549 : * to whatever type you really want. In a full-blown generic allocator
42550 : * there's no way to solve the alignment problems without potentially
42551 : * wasting lots of space. But we have a more limited problem. We know
42552 : * we're only ever returning pointers to structures which will have to
42553 : * be long word aligned. So we are making a stronger guarantee. It might
42554 : * have made sense to make Xalloc return char * to conform with people's
42555 : * expectations of malloc, but this makes lint happier.
42558 :#ifndef INTERNAL_MALLOC
42561 :Xalloc(unsigned long amount)
42562 6 0.0065 :{ /* Xalloc total: 10 0.0109 */
42563 : register pointer ptr;
42565 1 0.0011 : if ((long)amount <= 0) {
42566 : return (unsigned long *)NULL;
42568 : /* aligned extra on long word boundary */
42569 : amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
42571 : if (!Must_have_memory && Memory_fail &&
42572 : ((random() % MEM_FAIL_SCALE) < Memory_fail))
42573 : return (unsigned long *)NULL;
42575 1 0.0011 : if ((ptr = (pointer)malloc(amount))) {
42576 : return (unsigned long *)ptr;
42578 : if (Must_have_memory)
42579 : FatalError("Out of memory");
42580 : return (unsigned long *)NULL;
42583 :/*****************
42585 : * "no failure" realloc, alternate interface to Xalloc w/o Must_have_memory
42586 : *****************/
42589 :XNFalloc(unsigned long amount)
42591 : register pointer ptr;
42593 : if ((long)amount <= 0)
42595 : return (unsigned long *)NULL;
42597 : /* aligned extra on long word boundary */
42598 : amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
42599 : ptr = (pointer)malloc(amount);
42602 : FatalError("Out of memory");
42604 : return ((unsigned long *)ptr);
42607 :/*****************
42609 : *****************/
42612 :Xcalloc(unsigned long amount)
42614 : unsigned long *ret;
42616 : ret = Xalloc (amount);
42618 : bzero ((char *) ret, (int) amount);
42622 :/*****************
42624 : *****************/
42627 :XNFcalloc(unsigned long amount)
42629 : unsigned long *ret;
42631 : ret = Xalloc (amount);
42633 : bzero ((char *) ret, (int) amount);
42634 : else if ((long)amount > 0)
42635 : FatalError("Out of memory");
42639 :/*****************
42641 : *****************/
42644 :Xrealloc(pointer ptr, unsigned long amount)
42647 : if (!Must_have_memory && Memory_fail &&
42648 : ((random() % MEM_FAIL_SCALE) < Memory_fail))
42649 : return (unsigned long *)NULL;
42651 : if ((long)amount <= 0)
42653 : if (ptr && !amount)
42655 : return (unsigned long *)NULL;
42657 : amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
42659 : ptr = (pointer)realloc((char *)ptr, amount);
42661 : ptr = (pointer)malloc(amount);
42663 : return (unsigned long *)ptr;
42664 : if (Must_have_memory)
42665 : FatalError("Out of memory");
42666 : return (unsigned long *)NULL;
42669 :/*****************
42671 : * "no failure" realloc, alternate interface to Xrealloc w/o Must_have_memory
42672 : *****************/
42675 :XNFrealloc(pointer ptr, unsigned long amount)
42677 : if (( ptr = (pointer)Xrealloc( ptr, amount ) ) == NULL)
42679 : if ((long)amount > 0)
42680 : FatalError( "Out of memory" );
42682 : return ((unsigned long *)ptr);
42685 :/*****************
42688 : *****************/
42691 :Xfree(pointer ptr)
42692 7 0.0076 :{ /* Xfree total: 10 0.0109 */
42693 1 0.0011 : if (ptr)
42694 1 0.0011 : free((char *)ptr);
42698 :OsInitAllocator (void)
42701 : static int been_here;
42703 : /* Check the memory system after each generation */
42710 :#endif /* !INTERNAL_MALLOC */
42714 :Xstrdup(const char *s)
42721 : sd = (char *)Xalloc(strlen(s) + 1);
42729 :XNFstrdup(const char *s)
42736 : sd = (char *)XNFalloc(strlen(s) + 1);
42741 :#ifdef SMART_SCHEDULE
42743 :unsigned long SmartScheduleIdleCount;
42744 :Bool SmartScheduleIdle;
42745 :Bool SmartScheduleTimerStopped;
42748 :#define SMART_SCHEDULE_POSSIBLE
42751 :#ifdef SMART_SCHEDULE_POSSIBLE
42752 :#define SMART_SCHEDULE_SIGNAL SIGALRM
42753 :#define SMART_SCHEDULE_TIMER ITIMER_REAL
42757 :SmartScheduleStopTimer (void)
42759 :#ifdef SMART_SCHEDULE_POSSIBLE
42760 : struct itimerval timer;
42762 : timer.it_interval.tv_sec = 0;
42763 : timer.it_interval.tv_usec = 0;
42764 : timer.it_value.tv_sec = 0;
42765 : timer.it_value.tv_usec = 0;
42766 : (void) setitimer (ITIMER_REAL, &timer, 0);
42767 : SmartScheduleTimerStopped = TRUE;
42772 :SmartScheduleStartTimer (void)
42774 :#ifdef SMART_SCHEDULE_POSSIBLE
42775 : struct itimerval timer;
42777 : SmartScheduleTimerStopped = FALSE;
42778 : timer.it_interval.tv_sec = 0;
42779 : timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
42780 : timer.it_value.tv_sec = 0;
42781 : timer.it_value.tv_usec = SmartScheduleInterval * 1000;
42782 : return setitimer (ITIMER_REAL, &timer, 0) >= 0;
42787 :#ifdef SMART_SCHEDULE_POSSIBLE
42789 :SmartScheduleTimer (int sig)
42791 : int olderrno = errno;
42793 : SmartScheduleTime += SmartScheduleInterval;
42794 : if (SmartScheduleIdle)
42796 : SmartScheduleStopTimer ();
42798 : errno = olderrno;
42803 :SmartScheduleInit (void)
42805 :#ifdef SMART_SCHEDULE_POSSIBLE
42806 : struct sigaction act;
42808 : if (SmartScheduleDisable)
42811 : bzero ((char *) &act, sizeof(struct sigaction));
42813 : /* Set up the timer signal function */
42814 : act.sa_handler = SmartScheduleTimer;
42815 : sigemptyset (&act.sa_mask);
42816 : sigaddset (&act.sa_mask, SMART_SCHEDULE_SIGNAL);
42817 : if (sigaction (SMART_SCHEDULE_SIGNAL, &act, 0) < 0)
42819 : perror ("sigaction for smart scheduler");
42822 : /* Set up the virtual timer */
42823 : if (!SmartScheduleStartTimer ())
42825 : perror ("scheduling timer");
42828 : /* stop the timer and wait for WaitForSomething to start it */
42829 : SmartScheduleStopTimer ();
42838 :static sigset_t PreviousSignalMask;
42839 :static int BlockedSignalCount;
42843 :OsBlockSignals (void)
42846 : if (BlockedSignalCount++ == 0)
42850 : sigemptyset (&set);
42852 : sigaddset (&set, SIGALRM);
42855 : sigaddset (&set, SIGVTALRM);
42858 : sigaddset (&set, SIGWINCH);
42861 : sigaddset (&set, SIGIO);
42864 : sigaddset (&set, SIGTSTP);
42867 : sigaddset (&set, SIGTTIN);
42870 : sigaddset (&set, SIGTTOU);
42873 : sigaddset (&set, SIGCHLD);
42875 : sigprocmask (SIG_BLOCK, &set, &PreviousSignalMask);
42881 :OsReleaseSignals (void)
42884 : if (--BlockedSignalCount == 0)
42886 : sigprocmask (SIG_SETMASK, &PreviousSignalMask, 0);
42891 :#if !defined(WIN32)
42893 : * "safer" versions of system(3), popen(3) and pclose(3) which give up
42894 : * all privs before running a command.
42896 : * This is based on the code in FreeBSD 2.2 libc.
42898 : * XXX It'd be good to redirect stderr so that it ends up in the log file
42899 : * as well. As it is now, xkbcomp messages don't end up in the log file.
42903 :System(char *command)
42907 : void (*csig)(int);
42915 : csig = signal(SIGCHLD, SIG_DFL);
42919 : ErrorF("System: `%s'\n", command);
42922 : switch (pid = fork()) {
42923 : case -1: /* error */
42925 : case 0: /* child */
42926 : if (setgid(getgid()) == -1)
42928 : if (setuid(getuid()) == -1)
42930 : execl("/bin/sh", "sh", "-c", command, (char *)NULL);
42932 : default: /* parent */
42934 : p = waitpid(pid, &status, 0);
42935 : } while (p == -1 && errno == EINTR);
42940 : signal(SIGCHLD, csig);
42943 : return p == -1 ? -1 : status;
42946 :static struct pid {
42947 : struct pid *next;
42953 :Popen(char *command, char *type)
42957 : int pdes[2], pid;
42959 : if (command == NULL || type == NULL)
42962 : if ((*type != 'r' && *type != 'w') || type[1])
42965 : if ((cur = (struct pid *)xalloc(sizeof(struct pid))) == NULL)
42968 : if (pipe(pdes) < 0) {
42973 : switch (pid = fork()) {
42974 : case -1: /* error */
42979 : case 0: /* child */
42980 : if (setgid(getgid()) == -1)
42982 : if (setuid(getuid()) == -1)
42984 : if (*type == 'r') {
42985 : if (pdes[1] != 1) {
42987 : dup2(pdes[1], 1);
42992 : if (pdes[0] != 0) {
42994 : dup2(pdes[0], 0);
42999 : execl("/bin/sh", "sh", "-c", command, (char *)NULL);
43003 : /* Avoid EINTR during stdio calls */
43004 : OsBlockSignals ();
43007 : if (*type == 'r') {
43008 : iop = fdopen(pdes[0], type);
43011 : iop = fdopen(pdes[1], type);
43017 : cur->next = pidlist;
43021 : ErrorF("Popen: `%s', fp = %p\n", command, iop);
43027 :/* fopen that drops privileges */
43029 :Fopen(char *file, char *type)
43032 :#ifndef HAS_SAVED_IDS_AND_SETEUID
43034 : int pdes[2], pid;
43036 : if (file == NULL || type == NULL)
43039 : if ((*type != 'r' && *type != 'w') || type[1])
43042 : if ((cur = (struct pid *)xalloc(sizeof(struct pid))) == NULL)
43045 : if (pipe(pdes) < 0) {
43050 : switch (pid = fork()) {
43051 : case -1: /* error */
43056 : case 0: /* child */
43057 : if (setgid(getgid()) == -1)
43059 : if (setuid(getuid()) == -1)
43061 : if (*type == 'r') {
43062 : if (pdes[1] != 1) {
43064 : dup2(pdes[1], 1);
43069 : if (pdes[0] != 0) {
43071 : dup2(pdes[0], 0);
43076 : execl("/bin/cat", "cat", file, (char *)NULL);
43080 : /* Avoid EINTR during stdio calls */
43081 : OsBlockSignals ();
43084 : if (*type == 'r') {
43085 : iop = fdopen(pdes[0], type);
43088 : iop = fdopen(pdes[1], type);
43094 : cur->next = pidlist;
43098 : ErrorF("Fopen(%s), fp = %p\n", file, iop);
43106 : euid = geteuid();
43108 : if (seteuid(ruid) == -1) {
43111 : iop = fopen(file, type);
43113 : if (seteuid(euid) == -1) {
43118 :#endif /* HAS_SAVED_IDS_AND_SETEUID */
43122 :Pclose(pointer iop)
43124 : struct pid *cur, *last;
43129 : ErrorF("Pclose: fp = %p\n", iop);
43134 : for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
43135 : if (cur->fp == iop)
43141 : pid = waitpid(cur->pid, &pstat, 0);
43142 : } while (pid == -1 && errno == EINTR);
43144 : if (last == NULL)
43145 : pidlist = cur->next;
43147 : last->next = cur->next;
43150 : /* allow EINTR again */
43151 : OsReleaseSignals ();
43153 : return pid == -1 ? -1 : pstat;
43157 :Fclose(pointer iop)
43159 :#ifdef HAS_SAVED_IDS_AND_SETEUID
43160 : return fclose(iop);
43162 : return Pclose(iop);
43166 :#endif /* !WIN32 */
43170 : * CheckUserParameters: check for long command line arguments and long
43171 : * environment variables. By default, these checks are only done when
43172 : * the server's euid != ruid. In 3.3.x, these checks were done in an
43173 : * external wrapper utility.
43176 :/* Consider LD* variables insecure? */
43177 :#ifndef REMOVE_ENV_LD
43178 :#define REMOVE_ENV_LD 1
43181 :/* Remove long environment variables? */
43182 :#ifndef REMOVE_LONG_ENV
43183 :#define REMOVE_LONG_ENV 1
43187 : * Disallow stdout or stderr as pipes? It's possible to block the X server
43188 : * when piping stdout+stderr to a pipe.
43190 : * Don't enable this because it looks like it's going to cause problems.
43192 :#ifndef NO_OUTPUT_PIPES
43193 :#define NO_OUTPUT_PIPES 0
43197 :/* Check args and env only if running setuid (euid == 0 && euid != uid) ? */
43198 :#ifndef CHECK_EUID
43200 :#define CHECK_EUID 1
43202 :#define CHECK_EUID 0
43207 : * Maybe the locale can be faked to make isprint(3) report that everything
43208 : * is printable? Avoid it by default.
43210 :#ifndef USE_ISPRINT
43211 :#define USE_ISPRINT 0
43214 :#define MAX_ARG_LENGTH 128
43215 :#define MAX_ENV_LENGTH 256
43216 :#define MAX_ENV_PATH_LENGTH 2048 /* Limit for *PATH and TERMCAP */
43219 :#include <ctype.h>
43220 :#define checkPrintable(c) isprint(c)
43222 :#define checkPrintable(c) (((c) & 0x7f) >= 0x20 && ((c) & 0x7f) != 0x7f)
43235 :#if defined(VENDORSUPPORT)
43236 :#define BUGADDRESS VENDORSUPPORT
43237 :#elif defined(BUILDERADDR)
43238 :#define BUGADDRESS BUILDERADDR
43240 :#define BUGADDRESS "xorg@freedesktop.org"
43244 : "\nIf the arguments used are valid, and have been rejected incorrectly\n" \
43245 : "please send details of the arguments and why they are valid to\n" \
43246 : "%s. In the meantime, you can start the Xserver as\n" \
43247 : "the \"super user\" (root).\n"
43250 : "\nIf the environment is valid, and have been rejected incorrectly\n" \
43251 : "please send details of the environment and why it is valid to\n" \
43252 : "%s. In the meantime, you can start the Xserver as\n" \
43253 : "the \"super user\" (root).\n"
43256 :CheckUserParameters(int argc, char **argv, char **envp)
43258 : enum BadCode bad = NotBad;
43260 : char *a, *e = NULL;
43261 :#if defined(__QNX__) && !defined(__QNXNTO__)
43262 : char cmd_name[64];
43266 : if (geteuid() == 0 && getuid() != geteuid())
43269 : /* Check each argv[] */
43270 : for (i = 1; i < argc; i++) {
43271 : if (strcmp(argv[i], "-fp") == 0)
43273 : i++; /* continue with next argument. skip the length check */
43278 : if (strlen(argv[i]) > MAX_ARG_LENGTH) {
43279 : bad = ArgTooLong;
43285 : if (checkPrintable(*a) == 0) {
43286 : bad = UnprintableArg;
43295 : /* Check each envp[] */
43296 : for (i = 0; envp[i]; i++) {
43298 : /* Check for bad environment variables and values */
43300 : while (envp[i] && (strncmp(envp[i], "LD", 2) == 0)) {
43302 : ErrorF("CheckUserParameters: removing %s from the "
43303 : "environment\n", strtok(envp[i], "="));
43305 : for (j = i; envp[j]; j++) {
43306 : envp[j] = envp[j+1];
43310 : if (envp[i] && (strlen(envp[i]) > MAX_ENV_LENGTH)) {
43311 :#if REMOVE_LONG_ENV
43313 : ErrorF("CheckUserParameters: removing %s from the "
43314 : "environment\n", strtok(envp[i], "="));
43316 : for (j = i; envp[j]; j++) {
43317 : envp[j] = envp[j+1];
43324 : eq = strchr(envp[i], '=');
43327 : len = eq - envp[i];
43328 : e = malloc(len + 1);
43330 : bad = InternalError;
43333 : strncpy(e, envp[i], len);
43336 : (strcmp(e + len - 4, "PATH") == 0 ||
43337 : strcmp(e, "TERMCAP") == 0)) {
43338 : if (strlen(envp[i]) > MAX_ENV_PATH_LENGTH) {
43339 : bad = EnvTooLong;
43345 : bad = EnvTooLong;
43352 :#if NO_OUTPUT_PIPES
43356 : if (fstat(fileno(stdout), &buf) == 0 && S_ISFIFO(buf.st_mode))
43357 : bad = OutputIsPipe;
43358 : if (fstat(fileno(stderr), &buf) == 0 && S_ISFIFO(buf.st_mode))
43359 : bad = OutputIsPipe;
43367 : ErrorF("Command line argument number %d is unsafe\n", i);
43368 : ErrorF(ARGMSG, BUGADDRESS);
43371 : ErrorF("Command line argument number %d is too long\n", i);
43372 : ErrorF(ARGMSG, BUGADDRESS);
43374 : case UnprintableArg:
43375 : ErrorF("Command line argument number %d contains unprintable"
43376 : " characters\n", i);
43377 : ErrorF(ARGMSG, BUGADDRESS);
43380 : ErrorF("Environment variable `%s' is too long\n", e);
43381 : ErrorF(ENVMSG, BUGADDRESS);
43383 : case OutputIsPipe:
43384 : ErrorF("Stdout and/or stderr is a pipe\n");
43386 : case InternalError:
43387 : ErrorF("Internal Error\n");
43390 : ErrorF("Unknown error\n");
43391 : ErrorF(ARGMSG, BUGADDRESS);
43392 : ErrorF(ENVMSG, BUGADDRESS);
43395 : FatalError("X server aborted because of unsafe environment\n");
43399 : * CheckUserAuthorization: check if the user is allowed to start the
43400 : * X server. This usually means some sort of PAM checking, and it is
43401 : * usually only done for setuid servers (uid != euid).
43405 :#include <security/pam_appl.h>
43406 :#include <security/pam_misc.h>
43408 :#endif /* USE_PAM */
43411 :CheckUserAuthorization(void)
43414 : static struct pam_conv conv = {
43419 : pam_handle_t *pamh = NULL;
43420 : struct passwd *pw;
43423 : if (getuid() != geteuid()) {
43424 : pw = getpwuid(getuid());
43426 : FatalError("getpwuid() failed for uid %d\n", getuid());
43428 : retval = pam_start("xserver", pw->pw_name, &conv, &pamh);
43429 : if (retval != PAM_SUCCESS)
43430 : FatalError("pam_start() failed.\n"
43431 : "\tMissing or mangled PAM config file or module?\n");
43433 : retval = pam_authenticate(pamh, 0);
43434 : if (retval != PAM_SUCCESS) {
43435 : pam_end(pamh, retval);
43436 : FatalError("PAM authentication failed, cannot start X server.\n"
43437 : "\tPerhaps you do not have console ownership?\n");
43440 : retval = pam_acct_mgmt(pamh, 0);
43441 : if (retval != PAM_SUCCESS) {
43442 : pam_end(pamh, retval);
43443 : FatalError("PAM authentication failed, cannot start X server.\n"
43444 : "\tPerhaps you do not have console ownership?\n");
43447 : /* this is not a session, so do not do session management */
43448 : pam_end(pamh, PAM_SUCCESS);
43454 :#include <fcntl.h>
43457 :lockit (int fd, short what)
43459 : struct flock lck;
43461 : lck.l_whence = 0;
43464 : lck.l_type = what;
43466 : (void)fcntl (fd, F_SETLKW, &lck);
43469 :/* SCO OpenServer 5 lacks pread/pwrite. Emulate them. */
43471 :pread (int fd, void *buf, size_t nbytes, off_t offset)
43476 : lockit (fd, F_RDLCK);
43477 : saved = lseek (fd, 0, SEEK_CUR);
43478 : lseek (fd, offset, SEEK_SET);
43479 : ret = read (fd, buf, nbytes);
43480 : lseek (fd, saved, SEEK_SET);
43481 : lockit (fd, F_UNLCK);
43487 :pwrite (int fd, const void *buf, size_t nbytes, off_t offset)
43492 : lockit (fd, F_WRLCK);
43493 : saved = lseek (fd, 0, SEEK_CUR);
43494 : lseek (fd, offset, SEEK_SET);
43495 : ret = write (fd, buf, nbytes);
43496 : lseek (fd, saved, SEEK_SET);
43497 : lockit (fd, F_UNLCK);
43501 :#endif /* __SCO__ */
43503 * Total samples for file : "/home/cworth/src/xorg/xserver/fb/fbpixmap.c"
43510 : * Copyright © 1998 Keith Packard
43512 : * Permission to use, copy, modify, distribute, and sell this software and its
43513 : * documentation for any purpose is hereby granted without fee, provided that
43514 : * the above copyright notice appear in all copies and that both that
43515 : * copyright notice and this permission notice appear in supporting
43516 : * documentation, and that the name of Keith Packard not be used in
43517 : * advertising or publicity pertaining to distribution of the software without
43518 : * specific, written prior permission. Keith Packard makes no
43519 : * representations about the suitability of this software for any purpose. It
43520 : * is provided "as is" without express or implied warranty.
43522 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
43523 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
43524 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
43525 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
43526 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
43527 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
43528 : * PERFORMANCE OF THIS SOFTWARE.
43531 :#ifdef HAVE_DIX_CONFIG_H
43532 :#include <dix-config.h>
43535 :#include <stdlib.h>
43540 :fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp)
43541 :{ /* fbCreatePixmapBpp total: 10 0.0109 */
43542 : PixmapPtr pPixmap;
43544 : size_t paddedWidth;
43548 1 0.0011 : paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
43549 : if (paddedWidth / 4 > 32767 || height > 32767)
43550 : return NullPixmap;
43551 : datasize = height * paddedWidth;
43552 1 0.0011 : base = pScreen->totalPixmapSize;
43554 1 0.0011 : if (base & 7)
43555 : adjust = 8 - (base & 7);
43556 : datasize += adjust;
43558 : datasize += 2 * paddedWidth;
43560 1 0.0011 : pPixmap = AllocatePixmap(pScreen, datasize);
43562 : return NullPixmap;
43563 : pPixmap->drawable.type = DRAWABLE_PIXMAP;
43564 : pPixmap->drawable.class = 0;
43565 : pPixmap->drawable.pScreen = pScreen;
43566 : pPixmap->drawable.depth = depth;
43567 : pPixmap->drawable.bitsPerPixel = bpp;
43568 : pPixmap->drawable.id = 0;
43569 2 0.0022 : pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
43570 : pPixmap->drawable.x = 0;
43571 : pPixmap->drawable.y = 0;
43572 : pPixmap->drawable.width = width;
43573 1 0.0011 : pPixmap->drawable.height = height;
43574 : pPixmap->devKind = paddedWidth;
43575 : pPixmap->refcnt = 1;
43576 2 0.0022 : pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);
43578 : pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
43579 : fbInitializeDrawable (&pPixmap->drawable);
43583 : pPixmap->screen_x = 0;
43584 : pPixmap->screen_y = 0;
43591 :fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth)
43592 2 0.0022 :{ /* fbCreatePixmap total: 10 0.0109 */
43594 4 0.0044 : bpp = BitsPerPixel (depth);
43595 :#ifdef FB_SCREEN_PRIVATE
43596 1 0.0011 : if (bpp == 32 && depth <= 24)
43597 : bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
43599 2 0.0022 : return fbCreatePixmapBpp (pScreen, width, height, depth, bpp);
43603 :fbDestroyPixmap (PixmapPtr pPixmap)
43604 1 0.0011 :{ /* fbDestroyPixmap total: 1 0.0011 */
43605 : if(--pPixmap->refcnt)
43611 :#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
43612 :if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
43613 : (!((reg)->data->numRects && \
43614 : ((r-1)->y1 == (ry1)) && \
43615 : ((r-1)->y2 == (ry2)) && \
43616 : ((r-1)->x1 <= (rx1)) && \
43617 : ((r-1)->x2 >= (rx2))))) \
43619 : if ((reg)->data->numRects == (reg)->data->size) \
43621 : miRectAlloc(reg, 1); \
43622 : fr = REGION_BOXPTR(reg); \
43623 : r = fr + (reg)->data->numRects; \
43629 : (reg)->data->numRects++; \
43630 : if(r->x1 < (reg)->extents.x1) \
43631 : (reg)->extents.x1 = r->x1; \
43632 : if(r->x2 > (reg)->extents.x2) \
43633 : (reg)->extents.x2 = r->x2; \
43637 :/* Convert bitmap clip mask into clipping region.
43638 : * First, goes through each line and makes boxes by noting the transitions
43639 : * from 0 to 1 and 1 to 0.
43640 : * Then it coalesces the current line with the previous if they have boxes
43641 : * at the same X coordinates.
43644 :fbPixmapToRegion(PixmapPtr pPix)
43646 : register RegionPtr pReg;
43649 : int width, h, base, rx1 = 0, crects;
43650 : FbBits *pwLineEnd;
43651 : int irectPrevStart, irectLineStart;
43652 : register BoxPtr prectO, prectN;
43653 : BoxPtr FirstRect, rects, prectLineStart;
43654 : Bool fInBox, fSame;
43655 : register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
43659 : pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1);
43661 : return NullRegion;
43662 : FirstRect = REGION_BOXPTR(pReg);
43663 : rects = FirstRect;
43665 : fbPrepareAccess(&pPix->drawable);
43667 : pwLine = (FbBits *) pPix->devPrivate.ptr;
43668 : nWidth = pPix->devKind >> (FB_SHIFT-3);
43670 : width = pPix->drawable.width;
43671 : pReg->extents.x1 = width - 1;
43672 : pReg->extents.x2 = 0;
43673 : irectPrevStart = -1;
43674 : for(h = 0; h < pPix->drawable.height; h++)
43677 : pwLine += nWidth;
43678 : irectLineStart = rects - FirstRect;
43679 : /* If the Screen left most bit of the word is set, we're starting in
43681 : if(READ(pw) & mask0)
43688 : /* Process all words which are fully in the pixmap */
43689 : pwLineEnd = pw + (width >> FB_SHIFT);
43690 : for (base = 0; pw < pwLineEnd; base += FB_UNIT)
43703 : for(ib = 0; ib < FB_UNIT; ib++)
43705 : /* If the Screen left most bit of the word is set, we're
43706 : * starting a box */
43712 : /* start new box */
43721 : ADDRECT(pReg, rects, FirstRect,
43722 : rx1, h, base + ib, h + 1);
43726 : /* Shift the word VISUALLY left one. */
43727 : w = FbScrLeft(w, 1);
43730 : if(width & FB_MASK)
43732 : /* Process final partial word on line */
43734 : for(ib = 0; ib < (width & FB_MASK); ib++)
43736 : /* If the Screen left most bit of the word is set, we're
43737 : * starting a box */
43743 : /* start new box */
43752 : ADDRECT(pReg, rects, FirstRect,
43753 : rx1, h, base + ib, h + 1);
43757 : /* Shift the word VISUALLY left one. */
43758 : w = FbScrLeft(w, 1);
43761 : /* If scanline ended with last bit set, end the box */
43764 : ADDRECT(pReg, rects, FirstRect,
43765 : rx1, h, base + (width & FB_MASK), h + 1);
43767 : /* if all rectangles on this line have the same x-coords as
43768 : * those on the previous line, then add 1 to all the previous y2s and
43769 : * throw away all the rectangles from this line
43772 : if(irectPrevStart != -1)
43774 : crects = irectLineStart - irectPrevStart;
43775 : if(crects == ((rects - FirstRect) - irectLineStart))
43777 : prectO = FirstRect + irectPrevStart;
43778 : prectN = prectLineStart = FirstRect + irectLineStart;
43780 : while(prectO < prectLineStart)
43782 : if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
43792 : prectO = FirstRect + irectPrevStart;
43793 : while(prectO < prectLineStart)
43799 : pReg->data->numRects -= crects;
43804 : irectPrevStart = irectLineStart;
43806 : if (!pReg->data->numRects)
43807 : pReg->extents.x1 = pReg->extents.x2 = 0;
43810 : pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
43811 : pReg->extents.y2 = REGION_END(pReg)->y2;
43812 : if (pReg->data->numRects == 1)
43814 : xfree(pReg->data);
43815 : pReg->data = (RegDataPtr)NULL;
43819 : fbFinishAccess(&pPix->drawable);
43821 : if (!miValidRegion(pReg))
43822 : FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
43830 :#include <stdio.h>
43836 :fbValidateBits (FbStip *bits, int stride, FbStip data)
43840 : if (*bits != data)
43843 : NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)",
43844 : bits, *bits, data));
43846 : fprintf (stderr, "fbValidateBits failed\n");
43855 :fbValidateDrawable (DrawablePtr pDrawable)
43857 : FbStip *bits, *first, *last;
43863 : if (pDrawable->type != DRAWABLE_PIXMAP)
43864 : pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
43865 : fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
43866 : first = bits - stride;
43867 : last = bits + stride * pDrawable->height;
43868 : if (!fbValidateBits (first, stride, FB_HEAD_BITS) ||
43869 : !fbValidateBits (last, stride, FB_TAIL_BITS))
43870 : fbInitializeDrawable(pDrawable);
43871 : fbFinishAccess (pDrawable);
43875 :fbSetBits (FbStip *bits, int stride, FbStip data)
43882 :fbInitializeDrawable (DrawablePtr pDrawable)
43884 : FbStip *bits, *first, *last;
43888 : fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
43889 : first = bits - stride;
43890 : last = bits + stride * pDrawable->height;
43891 : fbSetBits (first, stride, FB_HEAD_BITS);
43892 : fbSetBits (last, stride, FB_TAIL_BITS);
43893 : fbFinishAccess (pDrawable);
43895 :#endif /* FB_DEBUG */
43897 * Total samples for file : "/home/cworth/src/xorg/xserver/render/miglyph.c"
43905 : * Copyright © 2000 SuSE, Inc.
43907 : * Permission to use, copy, modify, distribute, and sell this software and its
43908 : * documentation for any purpose is hereby granted without fee, provided that
43909 : * the above copyright notice appear in all copies and that both that
43910 : * copyright notice and this permission notice appear in supporting
43911 : * documentation, and that the name of SuSE not be used in advertising or
43912 : * publicity pertaining to distribution of the software without specific,
43913 : * written prior permission. SuSE makes no representations about the
43914 : * suitability of this software for any purpose. It is provided "as is"
43915 : * without express or implied warranty.
43917 : * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
43918 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
43919 : * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43920 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
43921 : * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
43922 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43924 : * Author: Keith Packard, SuSE, Inc.
43927 :#ifdef HAVE_DIX_CONFIG_H
43928 :#include <dix-config.h>
43931 :#include "scrnintstr.h"
43932 :#include "gcstruct.h"
43933 :#include "pixmapstr.h"
43934 :#include "windowstr.h"
43936 :#include "picturestr.h"
43937 :#include "mipict.h"
43940 :miRealizeGlyph (ScreenPtr pScreen,
43947 :miUnrealizeGlyph (ScreenPtr pScreen,
43953 :miGlyphExtents (int nlist,
43954 : GlyphListPtr list,
43955 : GlyphPtr *glyphs,
43957 2 0.0022 :{ /* miGlyphExtents total: 16 0.0174 */
43958 : int x1, x2, y1, y2;
43965 : extents->x1 = MAXSHORT;
43966 : extents->x2 = MINSHORT;
43967 : extents->y1 = MAXSHORT;
43968 : extents->y2 = MINSHORT;
43977 : glyph = *glyphs++;
43978 1 0.0011 : x1 = x - glyph->info.x;
43979 : if (x1 < MINSHORT)
43981 5 0.0054 : y1 = y - glyph->info.y;
43982 : if (y1 < MINSHORT)
43984 2 0.0022 : x2 = x1 + glyph->info.width;
43985 : if (x2 > MAXSHORT)
43987 : y2 = y1 + glyph->info.height;
43988 : if (y2 > MAXSHORT)
43990 : if (x1 < extents->x1)
43991 : extents->x1 = x1;
43992 : if (x2 > extents->x2)
43993 : extents->x2 = x2;
43994 4 0.0044 : if (y1 < extents->y1)
43995 : extents->y1 = y1;
43996 1 0.0011 : if (y2 > extents->y2)
43997 : extents->y2 = y2;
43998 : x += glyph->info.xOff;
43999 1 0.0011 : y += glyph->info.yOff;
44004 :#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
44007 :miGlyphs (CARD8 op,
44010 : PictFormatPtr maskFormat,
44014 : GlyphListPtr list,
44015 : GlyphPtr *glyphs)
44017 : PixmapPtr pPixmap = 0;
44018 : PicturePtr pPicture;
44019 : PixmapPtr pMaskPixmap = 0;
44020 : PicturePtr pMask;
44021 : ScreenPtr pScreen = pDst->pDrawable->pScreen;
44022 : int width = 0, height = 0;
44024 : int xDst = list->xOff, yDst = list->yOff;
44029 : CARD32 component_alpha;
44036 : miGlyphExtents (nlist, list, glyphs, &extents);
44038 : if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
44040 : width = extents.x2 - extents.x1;
44041 : height = extents.y2 - extents.y1;
44042 : pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
44043 : if (!pMaskPixmap)
44045 : component_alpha = NeedsComponent(maskFormat->format);
44046 : pMask = CreatePicture (0, &pMaskPixmap->drawable,
44047 : maskFormat, CPComponentAlpha, &component_alpha,
44048 : serverClient, &error);
44051 : (*pScreen->DestroyPixmap) (pMaskPixmap);
44054 : pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
44055 : ValidateGC (&pMaskPixmap->drawable, pGC);
44058 : rect.width = width;
44059 : rect.height = height;
44060 : (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
44061 : FreeScratchGC (pGC);
44079 : glyph = *glyphs++;
44082 : pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height,
44083 : list->format->depth,
44084 : list->format->depth,
44085 : 0, (pointer) (glyph + 1));
44088 : component_alpha = NeedsComponent(list->format->format);
44089 : pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
44090 : CPComponentAlpha, &component_alpha,
44091 : serverClient, &error);
44094 : FreeScratchPixmapHeader (pPixmap);
44098 : (*pScreen->ModifyPixmapHeader) (pPixmap,
44099 : glyph->info.width, glyph->info.height,
44100 : 0, 0, -1, (pointer) (glyph + 1));
44101 : pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
44104 : CompositePicture (PictOpAdd,
44110 : x - glyph->info.x,
44111 : y - glyph->info.y,
44112 : glyph->info.width,
44113 : glyph->info.height);
44117 : CompositePicture (op,
44121 : xSrc + (x - glyph->info.x) - xDst,
44122 : ySrc + (y - glyph->info.y) - yDst,
44124 : x - glyph->info.x,
44125 : y - glyph->info.y,
44126 : glyph->info.width,
44127 : glyph->info.height);
44129 : x += glyph->info.xOff;
44130 : y += glyph->info.yOff;
44135 : FreeScratchPixmapHeader (pPixmap);
44136 : FreePicture ((pointer) pPicture, 0);
44145 : CompositePicture (op,
44154 : FreePicture ((pointer) pMask, (XID) 0);
44155 : (*pScreen->DestroyPixmap) (pMaskPixmap);
44159 * Total samples for file : "/home/cworth/src/xorg/xserver/dix/pixmap.c"
44167 :Copyright 1993, 1998 The Open Group
44169 :Permission to use, copy, modify, distribute, and sell this software and its
44170 :documentation for any purpose is hereby granted without fee, provided that
44171 :the above copyright notice appear in all copies and that both that
44172 :copyright notice and this permission notice appear in supporting
44175 :The above copyright notice and this permission notice shall be included
44176 :in all copies or substantial portions of the Software.
44178 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
44179 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44180 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
44181 :IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
44182 :OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
44183 :ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
44184 :OTHER DEALINGS IN THE SOFTWARE.
44186 :Except as contained in this notice, the name of The Open Group shall
44187 :not be used in advertising or otherwise to promote the sale, use or
44188 :other dealings in this Software without prior written authorization
44189 :from The Open Group.
44193 :#ifdef HAVE_DIX_CONFIG_H
44194 :#include <dix-config.h>
44197 :#include <X11/X.h>
44198 :#include "scrnintstr.h"
44201 :#include "windowstr.h"
44202 :#include "resource.h"
44203 :#include "dixstruct.h"
44204 :#include "gcstruct.h"
44205 :#include "servermd.h"
44210 : * Scratch pixmap management and device independent pixmap allocation
44215 :/* callable by ddx */
44216 :_X_EXPORT PixmapPtr
44217 :GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
44218 : int bitsPerPixel, int devKind, pointer pPixData)
44219 1 0.0011 :{ /* GetScratchPixmapHeader total: 1 0.0011 */
44220 : PixmapPtr pPixmap = pScreen->pScratchPixmap;
44223 : pScreen->pScratchPixmap = NULL;
44225 : /* width and height of 0 means don't allocate any pixmap data */
44226 : pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth);
44229 : if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
44230 : bitsPerPixel, devKind, pPixData))
44232 : (*pScreen->DestroyPixmap)(pPixmap);
44234 : return NullPixmap;
44238 :/* callable by ddx */
44240 :FreeScratchPixmapHeader(PixmapPtr pPixmap)
44241 1 0.0011 :{ /* FreeScratchPixmapHeader total: 2 0.0022 */
44244 : ScreenPtr pScreen = pPixmap->drawable.pScreen;
44246 : pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
44247 : if (pScreen->pScratchPixmap)
44248 : (*pScreen->DestroyPixmap)(pPixmap);
44250 : pScreen->pScratchPixmap = pPixmap;
44256 :CreateScratchPixmapsForScreen(int scrnum)
44258 : /* let it be created on first use */
44259 : screenInfo.screens[scrnum]->pScratchPixmap = NULL;
44265 :FreeScratchPixmapsForScreen(int scrnum)
44267 : FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap);
44271 :/* callable by ddx */
44272 :_X_EXPORT PixmapPtr
44273 :AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
44274 3 0.0033 :{ /* AllocatePixmap total: 13 0.0142 */
44275 : PixmapPtr pPixmap;
44282 : if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize)
44283 : return NullPixmap;
44285 : pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize);
44287 : return NullPixmap;
44288 : ppriv = (DevUnion *)(pPixmap + 1);
44289 : pPixmap->devPrivates = ppriv;
44290 : sizes = pScreen->PixmapPrivateSizes;
44291 1 0.0011 : ptr = (char *)(ppriv + pScreen->PixmapPrivateLen);
44292 1 0.0011 : for (i = pScreen->PixmapPrivateLen; --i >= 0; ppriv++, sizes++)
44294 2 0.0022 : if ((size = *sizes) != 0)
44296 1 0.0011 : ppriv->ptr = (pointer)ptr;
44297 1 0.0011 : ptr += size;
44300 2 0.0022 : ppriv->ptr = (pointer)NULL;
44305 : pPixmap->drawable.pad0 = 0;
44306 : pPixmap->drawable.pad1 = 0;
44313 * Total samples for file : "fbpseudocolor.c"
44318 <credited to line zero> 14 0.0153 :
44319 /* __i686.get_pc_thunk.cx total: 2 0.0022 */
44320 /* __i686.get_pc_thunk.bx total: 12 0.0131 */
44322 * Total samples for file : "/home/cworth/src/xorg/xserver/render/mitrap.c"
44330 : * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
44332 : * Permission to use, copy, modify, distribute, and sell this software and its
44333 : * documentation for any purpose is hereby granted without fee, provided that
44334 : * the above copyright notice appear in all copies and that both that
44335 : * copyright notice and this permission notice appear in supporting
44336 : * documentation, and that the name of Keith Packard not be used in
44337 : * advertising or publicity pertaining to distribution of the software without
44338 : * specific, written prior permission. Keith Packard makes no
44339 : * representations about the suitability of this software for any purpose. It
44340 : * is provided "as is" without express or implied warranty.
44342 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
44343 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
44344 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
44345 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
44346 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
44347 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44348 : * PERFORMANCE OF THIS SOFTWARE.
44351 :#ifdef HAVE_DIX_CONFIG_H
44352 :#include <dix-config.h>
44355 :#include "scrnintstr.h"
44356 :#include "gcstruct.h"
44357 :#include "pixmapstr.h"
44358 :#include "windowstr.h"
44359 :#include "servermd.h"
44361 :#include "picturestr.h"
44362 :#include "mipict.h"
44365 :miCreateAlphaPicture (ScreenPtr pScreen,
44367 : PictFormatPtr pPictFormat,
44371 : PixmapPtr pPixmap;
44372 : PicturePtr pPicture;
44377 : if (width > 32767 || height > 32767)
44380 : if (!pPictFormat)
44382 : if (pDst->polyEdge == PolyEdgeSharp)
44383 : pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
44385 : pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
44386 : if (!pPictFormat)
44390 : pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
44391 : pPictFormat->depth);
44394 : pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
44397 : (*pScreen->DestroyPixmap) (pPixmap);
44400 : ValidateGC (&pPixmap->drawable, pGC);
44403 : rect.width = width;
44404 : rect.height = height;
44405 : (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
44406 : FreeScratchGC (pGC);
44407 : pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
44408 : 0, 0, serverClient, &error);
44409 : (*pScreen->DestroyPixmap) (pPixmap);
44414 :miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
44415 :{ /* miLineFixedX total: 8 0.0087 */
44416 : xFixed dx = l->p2.x - l->p1.x;
44417 1 0.0011 : xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
44418 1 0.0011 : xFixed dy = l->p2.y - l->p1.y;
44420 4 0.0044 : ex += (dy - 1);
44421 : return l->p1.x + (xFixed) (ex / dy);
44425 :miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
44426 :{ /* miTrapezoidBounds total: 3 0.0033 */
44427 : box->y1 = MAXSHORT;
44428 : box->y2 = MINSHORT;
44429 : box->x1 = MAXSHORT;
44430 : box->x2 = MINSHORT;
44431 : for (; ntrap; ntrap--, traps++)
44433 : INT16 x1, y1, x2, y2;
44435 : if (!xTrapezoidValid(traps))
44437 : y1 = xFixedToInt (traps->top);
44438 : if (y1 < box->y1)
44441 : y2 = xFixedToInt (xFixedCeil (traps->bottom));
44442 : if (y2 > box->y2)
44445 : x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
44446 : miLineFixedX (&traps->left, traps->bottom, FALSE)));
44447 : if (x1 < box->x1)
44450 3 0.0033 : x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
44451 : miLineFixedX (&traps->right, traps->bottom, TRUE))));
44452 : if (x2 > box->x2)
44458 :miTrapezoids (CARD8 op,
44461 : PictFormatPtr maskFormat,
44465 : xTrapezoid *traps)
44466 :{ /* miTrapezoids total: 1 0.0011 */
44467 : ScreenPtr pScreen = pDst->pDrawable->pScreen;
44468 : PictureScreenPtr ps = GetPictureScreen(pScreen);
44471 : * Check for solid alpha add
44473 : if (op == PictOpAdd && miIsSolidAlpha (pSrc))
44475 : for (; ntrap; ntrap--, traps++)
44476 : (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
44478 : else if (maskFormat)
44480 : PicturePtr pPicture;
44482 : INT16 xDst, yDst;
44483 : INT16 xRel, yRel;
44485 : xDst = traps[0].left.p1.x >> 16;
44486 : yDst = traps[0].left.p1.y >> 16;
44488 : miTrapezoidBounds (ntrap, traps, &bounds);
44489 : if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
44491 : pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
44492 : bounds.x2 - bounds.x1,
44493 : bounds.y2 - bounds.y1);
44496 1 0.0011 : for (; ntrap; ntrap--, traps++)
44497 : (*ps->RasterizeTrapezoid) (pPicture, traps,
44498 : -bounds.x1, -bounds.y1);
44499 : xRel = bounds.x1 + xSrc - xDst;
44500 : yRel = bounds.y1 + ySrc - yDst;
44501 : CompositePicture (op, pSrc, pPicture, pDst,
44502 : xRel, yRel, 0, 0, bounds.x1, bounds.y1,
44503 : bounds.x2 - bounds.x1,
44504 : bounds.y2 - bounds.y1);
44505 : FreePicture (pPicture, 0);
44509 : if (pDst->polyEdge == PolyEdgeSharp)
44510 : maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
44512 : maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
44513 : for (; ntrap; ntrap--, traps++)
44514 : miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
44518 * Total samples for file : "/home/cworth/src/pixman/pixman/pixman-image.c"
44525 : * Copyright © 2000 SuSE, Inc.
44526 : * Copyright © 2007 Red Hat, Inc.
44528 : * Permission to use, copy, modify, distribute, and sell this software and its
44529 : * documentation for any purpose is hereby granted without fee, provided that
44530 : * the above copyright notice appear in all copies and that both that
44531 : * copyright notice and this permission notice appear in supporting
44532 : * documentation, and that the name of SuSE not be used in advertising or
44533 : * publicity pertaining to distribution of the software without specific,
44534 : * written prior permission. SuSE makes no representations about the
44535 : * suitability of this software for any purpose. It is provided "as is"
44536 : * without express or implied warranty.
44538 : * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
44539 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
44540 : * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
44541 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
44542 : * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
44543 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44546 :#include <config.h>
44548 :#include <stdlib.h>
44549 :#include <stdio.h>
44550 :#include <string.h>
44552 :#include "pixman.h"
44553 :#include "pixman-private.h"
44556 :init_source_image (source_image_t *image)
44558 : image->class = SOURCE_IMAGE_CLASS_UNKNOWN;
44561 :static pixman_bool_t
44562 :init_gradient (gradient_t *gradient,
44563 : const pixman_gradient_stop_t *stops,
44566 : return_val_if_fail (n_stops > 0, FALSE);
44568 : init_source_image (&gradient->common);
44570 : gradient->stops = malloc (n_stops * sizeof (pixman_gradient_stop_t));
44571 : if (!gradient->stops)
44574 : memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
44576 : gradient->n_stops = n_stops;
44578 : gradient->stop_range = 0xffff;
44579 : gradient->color_table = NULL;
44580 : gradient->color_table_size = 0;
44586 :color_to_uint32 (const pixman_color_t *color)
44589 : (color->alpha >> 8 << 24) |
44590 : (color->red >> 8 << 16) |
44591 : (color->green & 0xff00) |
44592 : (color->blue >> 8);
44595 :static pixman_image_t *image_cache;
44597 :static pixman_image_t *
44600 : pixman_image_t *image;
44604 : image = image_cache;
44605 : image_cache = image->next;
44609 : image = malloc (sizeof (pixman_image_t));
44616 :delete_image (pixman_image_t *image)
44618 : image->next = image_cache;
44619 : image_cache = image;
44622 :static pixman_image_t *
44623 :allocate_image (void)
44624 :{ /* allocate_image total: 7 0.0076 */
44625 : pixman_image_t *image = new_image();
44629 : image_common_t *common = &image->common;
44631 : pixman_region_init (&common->full_region);
44632 1 0.0011 : pixman_region_init (&common->clip_region);
44633 : common->src_clip = &common->full_region;
44634 : common->has_client_clip = FALSE;
44635 : common->transform = NULL;
44636 : common->repeat = PIXMAN_REPEAT_NONE;
44637 : common->filter = PIXMAN_FILTER_NEAREST;
44638 : common->filter_params = NULL;
44639 1 0.0011 : common->n_filter_params = 0;
44640 1 0.0011 : common->alpha_map = NULL;
44641 : common->component_alpha = FALSE;
44642 1 0.0011 : common->ref_count = 1;
44643 : common->read_func = NULL;
44644 1 0.0011 : common->write_func = NULL;
44650 :/* Ref Counting */
44652 :pixman_image_ref (pixman_image_t *image)
44654 : image->common.ref_count++;
44660 :pixman_image_unref (pixman_image_t *image)
44661 1 0.0011 :{ /* pixman_image_unref total: 2 0.0022 */
44662 : image_common_t *common = (image_common_t *)image;
44664 : common->ref_count--;
44666 : if (common->ref_count == 0)
44668 : pixman_region_fini (&common->clip_region);
44669 : pixman_region_fini (&common->full_region);
44671 : if (common->transform)
44672 : free (common->transform);
44674 : if (common->filter_params)
44675 : free (common->filter_params);
44677 : if (common->alpha_map)
44678 : pixman_image_unref ((pixman_image_t *)common->alpha_map);
44681 : if (image->type == BITS && image->bits.indexed)
44682 : free (image->bits.indexed);
44686 : memset (image, 0xaa, sizeof (pixman_image_t));
44688 : if (image->type == LINEAR || image->type == RADIAL || image->type == CONICAL)
44690 : if (image->gradient.stops)
44691 : free (image->gradient.stops);
44695 : if (image->type == BITS && image->bits.free_me)
44696 : free (image->bits.free_me);
44698 : delete_image (image);
44702 :/* Constructors */
44704 :pixman_image_create_solid_fill (pixman_color_t *color)
44706 : pixman_image_t *img = allocate_image();
44710 : init_source_image (&img->solid.common);
44712 : img->type = SOLID;
44713 : img->solid.color = color_to_uint32 (color);
44719 :pixman_image_create_linear_gradient (pixman_point_fixed_t *p1,
44720 : pixman_point_fixed_t *p2,
44721 : const pixman_gradient_stop_t *stops,
44724 : pixman_image_t *image;
44725 : linear_gradient_t *linear;
44727 : return_val_if_fail (n_stops >= 2, NULL);
44729 : image = allocate_image();
44734 : linear = &image->linear;
44736 : if (!init_gradient (&linear->common, stops, n_stops))
44742 : linear->p1 = *p1;
44743 : linear->p2 = *p2;
44745 : image->type = LINEAR;
44752 :pixman_image_create_radial_gradient (pixman_point_fixed_t *inner,
44753 : pixman_point_fixed_t *outer,
44754 : pixman_fixed_t inner_radius,
44755 : pixman_fixed_t outer_radius,
44756 : const pixman_gradient_stop_t *stops,
44759 : pixman_image_t *image;
44760 : radial_gradient_t *radial;
44762 : return_val_if_fail (n_stops >= 2, NULL);
44764 : image = allocate_image();
44769 : radial = &image->radial;
44771 : if (!init_gradient (&radial->common, stops, n_stops))
44777 : image->type = RADIAL;
44779 : radial->c1.x = inner->x;
44780 : radial->c1.y = inner->y;
44781 : radial->c1.radius = inner_radius;
44782 : radial->c2.x = outer->x;
44783 : radial->c2.y = outer->y;
44784 : radial->c2.radius = outer_radius;
44785 : radial->cdx = pixman_fixed_to_double (radial->c2.x - radial->c1.x);
44786 : radial->cdy = pixman_fixed_to_double (radial->c2.y - radial->c1.y);
44787 : radial->dr = pixman_fixed_to_double (radial->c2.radius - radial->c1.radius);
44788 : radial->A = (radial->cdx * radial->cdx
44789 : + radial->cdy * radial->cdy
44790 : - radial->dr * radial->dr);
44796 :pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
44797 : pixman_fixed_t angle,
44798 : const pixman_gradient_stop_t *stops,
44801 : pixman_image_t *image = allocate_image();
44802 : conical_gradient_t *conical;
44807 : conical = &image->conical;
44809 : if (!init_gradient (&conical->common, stops, n_stops))
44815 : image->type = CONICAL;
44816 : conical->center = *center;
44817 : conical->angle = angle;
44823 :create_bits (pixman_format_code_t format,
44826 : int *rowstride_bytes)
44832 : bpp = PIXMAN_FORMAT_BPP (format);
44833 : stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (uint32_t);
44834 : buf_size = height * stride;
44836 : if (rowstride_bytes)
44837 : *rowstride_bytes = stride;
44839 : return calloc (buf_size, 1);
44843 :reset_clip_region (pixman_image_t *image)
44845 : pixman_region_fini (&image->common.clip_region);
44847 : if (image->type == BITS)
44849 : pixman_region_init_rect (&image->common.clip_region, 0, 0,
44850 : image->bits.width, image->bits.height);
44854 : pixman_region_init (&image->common.clip_region);
44859 :pixman_image_create_bits (pixman_format_code_t format,
44863 : int rowstride_bytes)
44864 1 0.0011 :{ /* pixman_image_create_bits total: 1 0.0011 */
44865 : pixman_image_t *image;
44866 : uint32_t *free_me = NULL;
44868 : /* must be a whole number of uint32_t's
44870 : return_val_if_fail (bits == NULL ||
44871 : (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
44875 : free_me = bits = create_bits (format, width, height, &rowstride_bytes);
44880 : image = allocate_image();
44885 : image->type = BITS;
44886 : image->bits.format = format;
44887 : image->bits.width = width;
44888 : image->bits.height = height;
44889 : image->bits.bits = bits;
44890 : image->bits.free_me = free_me;
44892 : image->bits.rowstride = rowstride_bytes / sizeof (uint32_t); /* we store it in number
44895 : image->bits.indexed = NULL;
44897 : pixman_region_fini (&image->common.full_region);
44898 : pixman_region_init_rect (&image->common.full_region, 0, 0,
44899 : image->bits.width, image->bits.height);
44901 : reset_clip_region (image);
44906 :pixman_image_set_clip_region (pixman_image_t *image,
44907 : pixman_region16_t *region)
44909 : image_common_t *common = (image_common_t *)image;
44913 : return pixman_region_copy (&common->clip_region, region);
44917 : reset_clip_region (image);
44923 :/* Sets whether the clip region includes a clip region set by the client
44926 :pixman_image_set_has_client_clip (pixman_image_t *image,
44927 : pixman_bool_t client_clip)
44929 : image->common.has_client_clip = client_clip;
44933 :pixman_image_set_transform (pixman_image_t *image,
44934 : const pixman_transform_t *transform)
44936 : static const pixman_transform_t id =
44938 : { { pixman_fixed_1, 0, 0 },
44939 : { 0, pixman_fixed_1, 0 },
44940 : { 0, 0, pixman_fixed_1 }
44944 : image_common_t *common = (image_common_t *)image;
44946 : if (common->transform == transform)
44949 : if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
44951 : transform = NULL;
44955 : if (common->transform)
44956 : free (common->transform);
44960 : common->transform = malloc (sizeof (pixman_transform_t));
44961 : if (!common->transform)
44964 : *common->transform = *transform;
44968 : common->transform = NULL;
44975 :pixman_image_set_repeat (pixman_image_t *image,
44976 : pixman_repeat_t repeat)
44977 1 0.0011 :{ /* pixman_image_set_repeat total: 1 0.0011 */
44978 : image->common.repeat = repeat;
44982 :pixman_image_set_filter (pixman_image_t *image,
44983 : pixman_filter_t filter,
44984 : const pixman_fixed_t *params,
44987 : image_common_t *common = (image_common_t *)image;
44988 : pixman_fixed_t *new_params;
44990 : if (params == common->filter_params && filter == common->filter)
44993 : new_params = NULL;
44996 : new_params = malloc (n_params * sizeof (pixman_fixed_t));
45000 : memcpy (new_params,
45001 : params, n_params * sizeof (pixman_fixed_t));
45004 : common->filter = filter;
45006 : if (common->filter_params)
45007 : free (common->filter_params);
45009 : common->filter_params = new_params;
45010 : common->n_filter_params = n_params;
45014 :/* Unlike all the other property setters, this function does not
45015 : * copy the content of indexed. Doing this copying is simply
45016 : * way, way too expensive.
45019 :pixman_image_set_indexed (pixman_image_t *image,
45020 : const pixman_indexed_t *indexed)
45022 : bits_image_t *bits = (bits_image_t *)image;
45024 : bits->indexed = indexed;
45028 :pixman_image_set_alpha_map (pixman_image_t *image,
45029 : pixman_image_t *alpha_map,
45033 : image_common_t *common = (image_common_t *)image;
45035 : return_if_fail (!alpha_map || alpha_map->type == BITS);
45037 : if (common->alpha_map != (bits_image_t *)alpha_map)
45039 : if (common->alpha_map)
45040 : pixman_image_unref ((pixman_image_t *)common->alpha_map);
45043 : common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
45045 : common->alpha_map = NULL;
45048 : common->alpha_origin.x = x;
45049 : common->alpha_origin.y = y;
45053 :pixman_image_set_component_alpha (pixman_image_t *image,
45054 : pixman_bool_t component_alpha)
45056 : image->common.component_alpha = component_alpha;
45061 :pixman_image_set_accessors (pixman_image_t *image,
45062 : pixman_read_memory_func_t read_func,
45063 : pixman_write_memory_func_t write_func)
45065 : return_if_fail (image != NULL);
45067 : image->common.read_func = read_func;
45068 : image->common.write_func = write_func;
45072 :pixman_image_get_data (pixman_image_t *image)
45074 : if (image->type == BITS)
45075 : return image->bits.bits;
45081 :pixman_image_get_width (pixman_image_t *image)
45083 : if (image->type == BITS)
45084 : return image->bits.width;
45090 :pixman_image_get_height (pixman_image_t *image)
45092 : if (image->type == BITS)
45093 : return image->bits.height;
45099 :pixman_image_get_stride (pixman_image_t *image)
45101 : if (image->type == BITS)
45102 : return image->bits.rowstride * sizeof (uint32_t);
45108 :pixman_image_get_depth (pixman_image_t *image)
45110 : if (image->type == BITS)
45111 : return PIXMAN_FORMAT_DEPTH (image->bits.format);
45117 :color_to_pixel (pixman_color_t *color,
45119 : pixman_format_code_t format)
45121 : uint32_t c = color_to_uint32 (color);
45123 : if (!(format == PIXMAN_a8r8g8b8 ||
45124 : format == PIXMAN_x8r8g8b8 ||
45125 : format == PIXMAN_a8b8g8r8 ||
45126 : format == PIXMAN_x8b8g8r8 ||
45127 : format == PIXMAN_r5g6b5 ||
45128 : format == PIXMAN_b5g6r5 ||
45129 : format == PIXMAN_a8))
45134 : if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
45136 : c = ((c & 0xff000000) >> 0) |
45137 : ((c & 0x00ff0000) >> 16) |
45138 : ((c & 0x0000ff00) >> 0) |
45139 : ((c & 0x000000ff) << 16);
45142 : if (format == PIXMAN_a8)
45144 : else if (format == PIXMAN_r5g6b5 ||
45145 : format == PIXMAN_b5g6r5)
45146 : c = cvt8888to0565 (c);
45149 : printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
45150 : printf ("pixel: %x\n", c);
45158 :pixman_image_fill_rectangles (pixman_op_t op,
45159 : pixman_image_t *dest,
45160 : pixman_color_t *color,
45162 : const pixman_rectangle16_t *rects)
45164 : pixman_image_t *solid;
45165 : pixman_color_t c;
45168 : if (color->alpha == 0xffff)
45170 : if (op == PIXMAN_OP_OVER)
45171 : op = PIXMAN_OP_SRC;
45174 : if (op == PIXMAN_OP_CLEAR)
45183 : op = PIXMAN_OP_SRC;
45186 : if (op == PIXMAN_OP_SRC)
45190 : if (color_to_pixel (color, &pixel, dest->bits.format))
45192 : for (i = 0; i < n_rects; ++i)
45194 : pixman_region16_t fill_region;
45196 : pixman_box16_t *boxes;
45198 : pixman_region_init_rect (&fill_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
45199 : pixman_region_intersect (&fill_region, &fill_region, &dest->common.clip_region);
45201 : boxes = pixman_region_rectangles (&fill_region, &n_boxes);
45202 : for (j = 0; j < n_boxes; ++j)
45204 : const pixman_box16_t *box = &(boxes[j]);
45205 : pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
45206 : box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1,
45210 : pixman_region_fini (&fill_region);
45216 : solid = pixman_image_create_solid_fill (color);
45220 : for (i = 0; i < n_rects; ++i)
45222 : const pixman_rectangle16_t *rect = &(rects[i]);
45224 : pixman_image_composite (op, solid, NULL, dest,
45226 : rect->x, rect->y,
45227 : rect->width, rect->height);
45230 : pixman_image_unref (solid);
45235 * Total samples for file : "/home/cworth/src/xorg/xserver/mi/mibstore.c"
45241 :/***********************************************************
45243 :Copyright 1987, 1998 The Open Group
45245 :Permission to use, copy, modify, distribute, and sell this software and its
45246 :documentation for any purpose is hereby granted without fee, provided that
45247 :the above copyright notice appear in all copies and that both that
45248 :copyright notice and this permission notice appear in supporting
45251 :The above copyright notice and this permission notice shall be included in
45252 :all copies or substantial portions of the Software.
45254 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45255 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45256 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45257 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
45258 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
45259 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45261 :Except as contained in this notice, the name of The Open Group shall not be
45262 :used in advertising or otherwise to promote the sale, use or other dealings
45263 :in this Software without prior written authorization from The Open Group.
45266 :Copyright 1987 by the Regents of the University of California
45268 : All Rights Reserved
45270 :Permission to use, copy, modify, and distribute this software and its
45271 :documentation for any purpose and without fee is hereby granted, provided
45272 :that the above copyright notice appear in all copies and that both that
45273 :copyright notice and this permission notice appear in supporting
45274 :documentation, and that the name The Open Group not be used in advertising or publicity
45275 :pertaining to distribution of the software without specific, written prior
45278 :The University of California makes no representations about the suitability
45279 :of this software for any purpose. It is provided "as is" without express or
45282 :******************************************************************/
45285 :#define NEED_EVENTS
45286 :#ifdef HAVE_DIX_CONFIG_H
45287 :#include <dix-config.h>
45290 :#include <X11/X.h>
45291 :#include <X11/Xmd.h>
45292 :#include <X11/Xproto.h>
45294 :#include "regionstr.h"
45295 :#include "scrnintstr.h"
45296 :#include "gcstruct.h"
45297 :#include "windowstr.h"
45298 :#include "pixmapstr.h"
45299 :#include <X11/fonts/fontstruct.h>
45300 :#include "dixfontstr.h"
45301 :#include "dixstruct.h" /* For requestingClient */
45303 :#include "mibstorest.h"
45306 : * When the server fails to allocate a backing store pixmap, if you want
45307 : * it to dynamically retry to allocate backing store on every subsequent
45308 : * graphics op, you can enable BSEAGER; otherwise, backing store will be
45309 : * disabled on the window until it is unmapped and then remapped.
45311 :/* #define BSEAGER */
45314 : * NOTES ON USAGE:
45316 : * The functions in this file implement a machine-independent backing-store
45317 : * scheme. To use it, the output library must do the following:
45318 : * - Provide a SaveAreas function that takes a destination pixmap, a
45319 : * region of the areas to save (in the pixmap's coordinate system)
45320 : * and the screen origin of the region. It should copy the areas from
45321 : * the screen into the pixmap.
45322 : * - Provide a RestoreAreas function that takes a source pixmap, a region
45323 : * of the areas to restore (in the screen's coordinate system) and the
45324 : * origin of the pixmap on the screen. It should copy the areas from
45325 : * the pixmap into the screen.
45326 : * - Provide a SetClipmaskRgn function that takes a gc and a region
45327 : * and merges the region into any CT_PIXMAP client clip that
45328 : * is specified in the GC. This routine is only needed if
45329 : * miValidateBackingStore will see CT_PIXMAP clip lists; not
45330 : * true for any of the sample servers (which convert the PIXMAP
45331 : * clip lists into CT_REGION clip lists; an expensive but simple
45332 : * to code option).
45333 : * - The function placed in a window's ClearToBackground vector must call
45334 : * pScreen->ClearBackingStore with the window, followed by
45335 : * the window-relative x and y coordinates, followed by the width and
45336 : * height of the area to be cleared, followed by the generateExposures
45337 : * flag. This has been taken care of in miClearToBackground.
45338 : * - Whatever determines GraphicsExpose events for the CopyArea and
45339 : * CopyPlane requests should call pWin->backStorage->ExposeCopy
45340 : * with the source and destination drawables, the GC used, a source-
45341 : * window-relative region of exposed areas, the source and destination
45342 : * coordinates and the bitplane copied, if CopyPlane, or 0, if
45346 : * This is a cross between saving everything and just saving the
45347 : * obscued areas (as in Pike's layers.) This method has the advantage
45348 : * of only doing each output operation once per pixel, visible or
45349 : * invisible, and avoids having to do all the crufty storage
45350 : * management of keeping several separate rectangles. Since the
45351 : * ddx layer ouput primitives are required to draw through clipping
45352 : * rectangles anyway, sending multiple drawing requests for each of
45353 : * several rectangles isn't necessary. (Of course, it could be argued
45354 : * that the ddx routines should just take one rectangle each and
45355 : * get called multiple times, but that would make taking advantage of
45356 : * smart hardware harder, and probably be slower as well.)
45359 :#define SETUP_BACKING_TERSE(pGC) \
45360 : miBSGCPtr pGCPrivate = (miBSGCPtr)(pGC)->devPrivates[miBSGCIndex].ptr; \
45361 : GCFuncs *oldFuncs = pGC->funcs;
45363 :#define SETUP_BACKING(pDrawable,pGC) \
45364 : miBSWindowPtr pBackingStore = \
45365 : (miBSWindowPtr)((WindowPtr)(pDrawable))->backStorage; \
45366 : DrawablePtr pBackingDrawable = (DrawablePtr) \
45367 : pBackingStore->pBackingPixmap; \
45368 : SETUP_BACKING_TERSE(pGC) \
45369 : GCPtr pBackingGC = pGCPrivate->pBackingGC;
45371 :#define PROLOGUE(pGC) { \
45372 : pGC->ops = pGCPrivate->wrapOps;\
45373 : pGC->funcs = pGCPrivate->wrapFuncs; \
45376 :#define EPILOGUE(pGC) { \
45377 : pGCPrivate->wrapOps = (pGC)->ops; \
45378 : (pGC)->ops = &miBSGCOps; \
45379 : (pGC)->funcs = oldFuncs; \
45382 :static void miCreateBSPixmap(WindowPtr pWin, BoxPtr pExtents);
45383 :static void miDestroyBSPixmap(WindowPtr pWin);
45384 :static void miTileVirtualBS(WindowPtr pWin);
45385 :static void miBSAllocate(WindowPtr pWin), miBSFree(WindowPtr pWin);
45386 :static Bool miBSCreateGCPrivate(GCPtr pGC);
45387 :static void miBSClearBackingRegion(WindowPtr pWin, RegionPtr pRgn);
45389 :#define MoreCopy0 ;
45390 :#define MoreCopy2 *dstCopy++ = *srcCopy++; *dstCopy++ = *srcCopy++;
45391 :#define MoreCopy4 MoreCopy2 MoreCopy2
45393 :#define copyData(src,dst,n,morecopy) \
45395 : short *srcCopy = (short *)(src); \
45396 : short *dstCopy = (short *)(dst); \
45398 : int bsx = pBackingStore->x; \
45399 : int bsy = pBackingStore->y; \
45400 : for (i = n; --i >= 0; ) \
45402 : *dstCopy++ = *srcCopy++ - bsx; \
45403 : *dstCopy++ = *srcCopy++ - bsy; \
45408 :#define copyPoints(src,dst,n,mode) \
45409 :if (mode == CoordModeOrigin) \
45411 : copyData(src,dst,n,MoreCopy0); \
45415 : memmove((char *)(dst), (char *)(src), (n) << 2); \
45416 : *((short *)(dst)) -= pBackingStore->x; \
45417 : *((short *)(dst) + 1) -= pBackingStore->y; \
45421 : * wrappers for screen funcs
45424 :static int miBSScreenIndex;
45425 :static unsigned long miBSGeneration = 0;
45427 :static Bool miBSCloseScreen(int i, ScreenPtr pScreen);
45428 :static void miBSGetImage(DrawablePtr pDrawable, int sx, int sy,
45429 : int w, int h, unsigned int format,
45430 : unsigned long planemask, char *pdstLine);
45431 :static void miBSGetSpans(DrawablePtr pDrawable, int wMax,
45432 : DDXPointPtr ppt, int *pwidth, int nspans,
45433 : char *pdstStart);
45434 :static Bool miBSChangeWindowAttributes(WindowPtr pWin,
45435 : unsigned long mask);
45436 :static Bool miBSCreateGC(GCPtr pGC);
45437 :static Bool miBSDestroyWindow(WindowPtr pWin);
45440 : * backing store screen functions
45443 :static void miBSSaveDoomedAreas(WindowPtr pWin, RegionPtr pObscured,
45445 :static RegionPtr miBSRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed);
45446 :static void miBSExposeCopy(WindowPtr pSrc, DrawablePtr pDst,
45447 : GCPtr pGC, RegionPtr prgnExposed,
45448 : int srcx, int srcy, int dstx, int dsty,
45449 : unsigned long plane);
45450 :static RegionPtr miBSTranslateBackingStore(WindowPtr pWin, int windx,
45451 : int windy, RegionPtr oldClip,
45452 : int oldx, int oldy);
45453 :static RegionPtr miBSClearBackingStore(WindowPtr pWin, int x, int y,
45454 : int w, int h, Bool generateExposures);
45455 :static void miBSDrawGuarantee(WindowPtr pWin, GCPtr pGC,
45459 : * wrapper vectors for GC funcs and ops
45462 :static int miBSGCIndex;
45464 :static void miBSValidateGC(GCPtr pGC, unsigned long stateChanges,
45465 : DrawablePtr pDrawable);
45466 :static void miBSCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
45467 :static void miBSDestroyGC(GCPtr pGC);
45468 :static void miBSChangeGC(GCPtr pGC, unsigned long mask);
45469 :static void miBSChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
45470 :static void miBSDestroyClip(GCPtr pGC);
45471 :static void miBSCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
45473 :static GCFuncs miBSGCFuncs = {
45483 :static void miBSFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
45484 : DDXPointPtr pptInit, int *pwidthInit,
45486 :static void miBSSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
45487 : DDXPointPtr ppt, int *pwidth, int nspans,
45489 :static void miBSPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
45490 : int x, int y, int w, int h, int leftPad,
45491 : int format, char *pBits);
45492 :static RegionPtr miBSCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
45493 : GCPtr pGC, int srcx, int srcy, int w, int h,
45494 : int dstx, int dsty);
45495 :static RegionPtr miBSCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
45496 : GCPtr pGC, int srcx, int srcy, int w, int h,
45497 : int dstx, int dsty, unsigned long plane);
45498 :static void miBSPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
45499 : int npt, xPoint *pptInit);
45500 :static void miBSPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
45501 : int npt, DDXPointPtr pptInit);
45502 :static void miBSPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
45503 : xSegment *pSegs);
45504 :static void miBSPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
45505 : int nrects, xRectangle *pRects);
45506 :static void miBSPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
45508 :static void miBSFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
45509 : int shape, int mode, int count,
45510 : DDXPointPtr pPts);
45511 :static void miBSPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
45512 : int nrectFill, xRectangle *prectInit);
45513 :static void miBSPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
45514 : int narcs, xArc *parcs);
45515 :static int miBSPolyText8(DrawablePtr pDrawable, GCPtr pGC,
45516 : int x, int y, int count, char *chars);
45517 :static int miBSPolyText16(DrawablePtr pDrawable, GCPtr pGC,
45518 : int x, int y, int count,
45519 : unsigned short *chars);
45520 :static void miBSImageText8(DrawablePtr pDrawable, GCPtr pGC,
45521 : int x, int y, int count, char *chars);
45522 :static void miBSImageText16(DrawablePtr pDrawable, GCPtr pGC,
45523 : int x, int y, int count,
45524 : unsigned short *chars);
45525 :static void miBSImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
45526 : int x, int y, unsigned int nglyph,
45527 : CharInfoPtr *ppci, pointer pglyphBase);
45528 :static void miBSPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
45529 : int x, int y, unsigned int nglyph,
45530 : CharInfoPtr *ppci, pointer pglyphBase);
45531 :static void miBSPushPixels(GCPtr pGC, PixmapPtr pBitMap,
45532 : DrawablePtr pDst, int w, int h,
45535 :static GCOps miBSGCOps = {
45536 : miBSFillSpans, miBSSetSpans, miBSPutImage,
45537 : miBSCopyArea, miBSCopyPlane, miBSPolyPoint,
45538 : miBSPolylines, miBSPolySegment, miBSPolyRectangle,
45539 : miBSPolyArc, miBSFillPolygon, miBSPolyFillRect,
45540 : miBSPolyFillArc, miBSPolyText8, miBSPolyText16,
45541 : miBSImageText8, miBSImageText16, miBSImageGlyphBlt,
45542 : miBSPolyGlyphBlt, miBSPushPixels
45545 :#define FUNC_PROLOGUE(pGC, pPriv) \
45546 : ((pGC)->funcs = pPriv->wrapFuncs),\
45547 : ((pGC)->ops = pPriv->wrapOps)
45549 :#define FUNC_EPILOGUE(pGC, pPriv) \
45550 : ((pGC)->funcs = &miBSGCFuncs),\
45551 : ((pGC)->ops = &miBSGCOps)
45554 : * every GC in the server is initially wrapped with these
45555 : * "cheap" functions. This allocates no memory and is used
45556 : * to discover GCs used with windows which have backing
45560 :static void miBSCheapValidateGC(GCPtr pGC, unsigned long stateChanges,
45561 : DrawablePtr pDrawable);
45562 :static void miBSCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
45563 :static void miBSCheapDestroyGC(GCPtr pGC);
45564 :static void miBSCheapChangeGC(GCPtr pGC, unsigned long mask);
45565 :static void miBSCheapChangeClip(GCPtr pGC, int type, pointer pvalue,
45567 :static void miBSCheapDestroyClip(GCPtr pGC);
45568 :static void miBSCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
45570 :static GCFuncs miBSCheapGCFuncs = {
45571 : miBSCheapValidateGC,
45572 : miBSCheapChangeGC,
45574 : miBSCheapDestroyGC,
45575 : miBSCheapChangeClip,
45576 : miBSCheapDestroyClip,
45577 : miBSCheapCopyClip,
45580 :#define CHEAP_FUNC_PROLOGUE(pGC) \
45581 : ((pGC)->funcs = (GCFuncs *) (pGC)->devPrivates[miBSGCIndex].ptr)
45583 :#define CHEAP_FUNC_EPILOGUE(pGC) \
45584 : ((pGC)->funcs = &miBSCheapGCFuncs)
45587 : * called from device screen initialization proc. Gets a GCPrivateIndex
45588 : * and wraps appropriate per-screen functions. pScreen->BackingStoreFuncs
45589 : * must be previously initialized.
45593 :miInitializeBackingStore (pScreen)
45594 : ScreenPtr pScreen;
45596 : miBSScreenPtr pScreenPriv;
45598 : if (miBSGeneration != serverGeneration)
45600 : miBSScreenIndex = AllocateScreenPrivateIndex ();
45601 : if (miBSScreenIndex < 0)
45603 : miBSGCIndex = AllocateGCPrivateIndex ();
45604 : miBSGeneration = serverGeneration;
45606 : if (!AllocateGCPrivate(pScreen, miBSGCIndex, 0))
45608 : pScreenPriv = (miBSScreenPtr) xalloc (sizeof (miBSScreenRec));
45609 : if (!pScreenPriv)
45612 : pScreenPriv->CloseScreen = pScreen->CloseScreen;
45613 : pScreenPriv->GetImage = pScreen->GetImage;
45614 : pScreenPriv->GetSpans = pScreen->GetSpans;
45615 : pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
45616 : pScreenPriv->CreateGC = pScreen->CreateGC;
45617 : pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
45619 : pScreen->CloseScreen = miBSCloseScreen;
45620 : pScreen->GetImage = miBSGetImage;
45621 : pScreen->GetSpans = miBSGetSpans;
45622 : pScreen->ChangeWindowAttributes = miBSChangeWindowAttributes;
45623 : pScreen->CreateGC = miBSCreateGC;
45624 : pScreen->DestroyWindow = miBSDestroyWindow;
45626 : pScreen->SaveDoomedAreas = miBSSaveDoomedAreas;
45627 : pScreen->RestoreAreas = miBSRestoreAreas;
45628 : pScreen->ExposeCopy = miBSExposeCopy;
45629 : pScreen->TranslateBackingStore = miBSTranslateBackingStore;
45630 : pScreen->ClearBackingStore = miBSClearBackingStore;
45631 : pScreen->DrawGuarantee = miBSDrawGuarantee;
45633 : pScreen->devPrivates[miBSScreenIndex].ptr = (pointer) pScreenPriv;
45637 : * Screen function wrappers
45640 :#define SCREEN_PROLOGUE(pScreen, field)\
45641 : ((pScreen)->field = \
45642 : ((miBSScreenPtr) \
45643 : (pScreen)->devPrivates[miBSScreenIndex].ptr)->field)
45645 :#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
45646 : ((pScreen)->field = wrapper)
45649 : * CloseScreen wrapper -- unwrap everything, free the private data
45650 : * and call the wrapped function
45654 :miBSCloseScreen (i, pScreen)
45656 : ScreenPtr pScreen;
45658 : miBSScreenPtr pScreenPriv;
45660 : pScreenPriv = (miBSScreenPtr) pScreen->devPrivates[miBSScreenIndex].ptr;
45662 : pScreen->CloseScreen = pScreenPriv->CloseScreen;
45663 : pScreen->GetImage = pScreenPriv->GetImage;
45664 : pScreen->GetSpans = pScreenPriv->GetSpans;
45665 : pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
45666 : pScreen->CreateGC = pScreenPriv->CreateGC;
45668 : xfree ((pointer) pScreenPriv);
45670 : return (*pScreen->CloseScreen) (i, pScreen);
45673 :static void miBSFillVirtualBits(DrawablePtr pDrawable, GCPtr pGC,
45674 : RegionPtr pRgn, int x, int y, int state,
45675 : PixUnion pixunion, unsigned long planemask);
45678 :miBSGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
45679 : DrawablePtr pDrawable;
45680 : int sx, sy, w, h;
45681 : unsigned int format;
45682 : unsigned long planemask;
45685 : ScreenPtr pScreen = pDrawable->pScreen;
45687 : unsigned char depth;
45689 : SCREEN_PROLOGUE (pScreen, GetImage);
45691 : if (pDrawable->type != DRAWABLE_PIXMAP &&
45692 : ((WindowPtr) pDrawable)->visibility != VisibilityUnobscured)
45694 : PixmapPtr pPixmap;
45695 : miBSWindowPtr pWindowPriv;
45696 : GCPtr pGC = NULL;
45697 : WindowPtr pWin, pSrcWin;
45699 : RegionRec Remaining;
45700 : RegionRec Border;
45701 : RegionRec Inside;
45705 : pWin = (WindowPtr) pDrawable;
45707 : depth = pDrawable->depth;
45708 : bounds.x1 = sx + pDrawable->x;
45709 : bounds.y1 = sy + pDrawable->y;
45710 : bounds.x2 = bounds.x1 + w;
45711 : bounds.y2 = bounds.y1 + h;
45712 : REGION_INIT(pScreen, &Remaining, &bounds, 0);
45715 : bounds.x1 = sx + pDrawable->x - pWin->drawable.x;
45716 : bounds.y1 = sy + pDrawable->y - pWin->drawable.y;
45717 : bounds.x2 = bounds.x1 + w;
45718 : bounds.y2 = bounds.y1 + h;
45719 : if (pWin->viewable && pWin->backStorage &&
45720 : pWin->drawable.depth == depth &&
45721 : (RECT_IN_REGION(pScreen, &(pWindowPriv =
45722 : (miBSWindowPtr) pWin->backStorage)->SavedRegion,
45723 : &bounds) != rgnOUT ||
45724 : RECT_IN_REGION(pScreen, &Remaining,
45725 : REGION_EXTENTS(pScreen, &pWin->borderSize)) != rgnOUT))
45729 : XID subWindowMode = IncludeInferiors;
45732 : pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
45735 : pGC = GetScratchGC (depth, pScreen);
45738 : (*pScreen->DestroyPixmap) (pPixmap);
45741 : ChangeGC (pGC, GCSubwindowMode, &subWindowMode);
45742 : ValidateGC ((DrawablePtr)pPixmap, pGC);
45743 : REGION_NULL(pScreen, &Border);
45744 : REGION_NULL(pScreen, &Inside);
45745 : pSrcWin = (WindowPtr) pDrawable;
45748 : if (pSrcWin->parent)
45750 : x += pSrcWin->origin.x;
45751 : y += pSrcWin->origin.y;
45752 : pSrcWin = pSrcWin->parent;
45754 : (*pGC->ops->CopyArea) ((DrawablePtr)pSrcWin,
45755 : (DrawablePtr)pPixmap, pGC,
45758 : REGION_SUBTRACT(pScreen, &Remaining, &Remaining,
45759 : &((WindowPtr) pDrawable)->borderClip);
45762 : REGION_INTERSECT(pScreen, &Inside, &Remaining, &pWin->winSize);
45763 : REGION_TRANSLATE(pScreen, &Inside,
45764 : -pWin->drawable.x,
45765 : -pWin->drawable.y);
45766 : REGION_INTERSECT(pScreen, &Inside, &Inside,
45767 : &pWindowPriv->SavedRegion);
45769 : /* offset of sub-window in GetImage pixmap */
45770 : xoff = pWin->drawable.x - pDrawable->x - sx;
45771 : yoff = pWin->drawable.y - pDrawable->y - sy;
45773 : if (REGION_NUM_RECTS(&Inside) > 0)
45775 : switch (pWindowPriv->status)
45777 : case StatusContents:
45778 : pBox = REGION_RECTS(&Inside);
45779 : for (n = REGION_NUM_RECTS(&Inside); --n >= 0;)
45781 : (*pGC->ops->CopyArea) (
45782 : (DrawablePtr)pWindowPriv->pBackingPixmap,
45783 : (DrawablePtr)pPixmap, pGC,
45784 : pBox->x1 - pWindowPriv->x,
45785 : pBox->y1 - pWindowPriv->y,
45786 : pBox->x2 - pBox->x1,
45787 : pBox->y2 - pBox->y1,
45789 : pBox->y1 + yoff);
45793 : case StatusVirtual:
45794 : case StatusVDirty:
45795 : if (pWindowPriv->backgroundState == BackgroundPixmap ||
45796 : pWindowPriv->backgroundState == BackgroundPixel)
45797 : miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Inside,
45799 : (int) pWindowPriv->backgroundState,
45800 : pWindowPriv->background, ~0L);
45804 : REGION_SUBTRACT(pScreen, &Border, &pWin->borderSize,
45806 : REGION_INTERSECT(pScreen, &Border, &Border, &Remaining);
45807 : if (REGION_NUM_RECTS(&Border) > 0)
45809 : REGION_TRANSLATE(pScreen, &Border, -pWin->drawable.x,
45810 : -pWin->drawable.y);
45811 : miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Border,
45813 : pWin->borderIsPixel ? (int)BackgroundPixel : (int)BackgroundPixmap,
45814 : pWin->border, ~0L);
45818 : if (pWin->viewable && pWin->firstChild)
45819 : pWin = pWin->firstChild;
45822 : while (!pWin->nextSib && pWin != (WindowPtr) pDrawable)
45823 : pWin = pWin->parent;
45824 : if (pWin == (WindowPtr) pDrawable)
45826 : pWin = pWin->nextSib;
45830 : REGION_UNINIT(pScreen, &Remaining);
45834 : REGION_UNINIT(pScreen, &Border);
45835 : REGION_UNINIT(pScreen, &Inside);
45836 : (*pScreen->GetImage) ((DrawablePtr) pPixmap,
45837 : 0, 0, w, h, format, planemask, pdstLine);
45838 : (*pScreen->DestroyPixmap) (pPixmap);
45839 : FreeScratchGC (pGC);
45849 : (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
45850 : format, planemask, pdstLine);
45853 : SCREEN_EPILOGUE (pScreen, GetImage, miBSGetImage);
45857 :miBSGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
45858 : DrawablePtr pDrawable;
45865 : ScreenPtr pScreen = pDrawable->pScreen;
45871 : SCREEN_PROLOGUE (pScreen, GetSpans);
45873 : if (pDrawable->type != DRAWABLE_PIXMAP && ((WindowPtr) pDrawable)->backStorage)
45875 : PixmapPtr pPixmap;
45876 : miBSWindowPtr pWindowPriv;
45879 : pWin = (WindowPtr) pDrawable;
45880 : pWindowPriv = (miBSWindowPtr) pWin->backStorage;
45881 : pPixmap = pWindowPriv->pBackingPixmap;
45883 : bounds.x1 = ppt->x;
45884 : bounds.y1 = ppt->y;
45885 : bounds.x2 = bounds.x1 + *pwidth;
45886 : bounds.y2 = ppt->y;
45887 : for (i = 0; i < nspans; i++)
45889 : if (ppt[i].x < bounds.x1)
45890 : bounds.x1 = ppt[i].x;
45891 : if (ppt[i].x + pwidth[i] > bounds.x2)
45892 : bounds.x2 = ppt[i].x + pwidth[i];
45893 : if (ppt[i].y < bounds.y1)
45894 : bounds.y1 = ppt[i].y;
45895 : else if (ppt[i].y > bounds.y2)
45896 : bounds.y2 = ppt[i].y;
45899 : switch (RECT_IN_REGION(pScreen, &pWindowPriv->SavedRegion, &bounds))
45904 : miCreateBSPixmap (pWin, NullBox);
45905 : if (!(pPixmap = pWindowPriv->pBackingPixmap))
45908 : pWindowPriv->status = StatusNoPixmap;
45909 : pGC = GetScratchGC(pPixmap->drawable.depth,
45910 : pPixmap->drawable.pScreen);
45913 : ValidateGC ((DrawablePtr) pPixmap, pGC);
45914 : (*pGC->ops->CopyArea)
45915 : (pDrawable, (DrawablePtr) pPixmap, pGC,
45916 : bounds.x1, bounds.y1,
45917 : bounds.x2 - bounds.x1, bounds.y2 - bounds.y1,
45918 : bounds.x1 + pPixmap->drawable.x - pWin->drawable.x -
45920 : bounds.y1 + pPixmap->drawable.y - pWin->drawable.y -
45922 : FreeScratchGC(pGC);
45924 : pWindowPriv->status = StatusContents;
45925 : /* fall through */
45929 : miCreateBSPixmap (pWin, NullBox);
45930 : if (!(pPixmap = pWindowPriv->pBackingPixmap))
45933 : dx = pPixmap->drawable.x - pWin->drawable.x - pWindowPriv->x;
45934 : dy = pPixmap->drawable.y - pWin->drawable.y - pWindowPriv->y;
45935 : for (i = 0; i < nspans; i++)
45940 : (*pScreen->GetSpans) ((DrawablePtr) pPixmap, wMax, ppt, pwidth,
45941 : nspans, pdstStart);
45944 : (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans,
45951 : (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
45954 : SCREEN_EPILOGUE (pScreen, GetSpans, miBSGetSpans);
45958 :miBSChangeWindowAttributes (pWin, mask)
45960 : unsigned long mask;
45962 : ScreenPtr pScreen;
45965 : pScreen = pWin->drawable.pScreen;
45967 : SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
45969 : ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
45971 : if (ret && (mask & CWBackingStore))
45973 : if (pWin->backingStore != NotUseful || pWin->DIXsaveUnder)
45974 : miBSAllocate (pWin);
45979 : SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, miBSChangeWindowAttributes);
45985 : * GC Create wrapper. Set up the cheap GC func wrappers to track
45986 : * GC validation on BackingStore windows
45990 :miBSCreateGC (pGC)
45993 : ScreenPtr pScreen = pGC->pScreen;
45996 : SCREEN_PROLOGUE (pScreen, CreateGC);
45998 : if ( (ret = (*pScreen->CreateGC) (pGC)) )
46000 : pGC->devPrivates[miBSGCIndex].ptr = (pointer) pGC->funcs;
46001 : pGC->funcs = &miBSCheapGCFuncs;
46004 : SCREEN_EPILOGUE (pScreen, CreateGC, miBSCreateGC);
46010 :miBSDestroyWindow (pWin)
46013 : ScreenPtr pScreen = pWin->drawable.pScreen;
46016 : SCREEN_PROLOGUE (pScreen, DestroyWindow);
46018 : ret = (*pScreen->DestroyWindow) (pWin);
46022 : SCREEN_EPILOGUE (pScreen, DestroyWindow, miBSDestroyWindow);
46028 : * cheap GC func wrappers. Simply track validation on windows
46029 : * with backing store to enable the real func/op wrappers
46033 :miBSCheapValidateGC (pGC, stateChanges, pDrawable)
46035 : unsigned long stateChanges;
46036 : DrawablePtr pDrawable;
46037 1 0.0011 :{ /* miBSCheapValidateGC total: 5 0.0054 */
46038 : CHEAP_FUNC_PROLOGUE (pGC);
46040 1 0.0011 : if (pDrawable->type != DRAWABLE_PIXMAP &&
46041 : ((WindowPtr) pDrawable)->backStorage != NULL &&
46042 : miBSCreateGCPrivate (pGC))
46044 : (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
46048 : (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
46050 : /* rewrap funcs as Validate may have changed them */
46051 : pGC->devPrivates[miBSGCIndex].ptr = (pointer) pGC->funcs;
46053 1 0.0011 : CHEAP_FUNC_EPILOGUE (pGC);
46058 :miBSCheapChangeGC (pGC, mask)
46060 : unsigned long mask;
46061 1 0.0011 :{ /* miBSCheapChangeGC total: 1 0.0011 */
46062 : CHEAP_FUNC_PROLOGUE (pGC);
46064 : (*pGC->funcs->ChangeGC) (pGC, mask);
46066 : CHEAP_FUNC_EPILOGUE (pGC);
46070 :miBSCheapCopyGC (pGCSrc, mask, pGCDst)
46071 : GCPtr pGCSrc, pGCDst;
46072 : unsigned long mask;
46074 : CHEAP_FUNC_PROLOGUE (pGCDst);
46076 : (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
46078 : CHEAP_FUNC_EPILOGUE (pGCDst);
46082 :miBSCheapDestroyGC (pGC)
46085 : CHEAP_FUNC_PROLOGUE (pGC);
46087 : (*pGC->funcs->DestroyGC) (pGC);
46089 : /* leave it unwrapped */
46093 :miBSCheapChangeClip (pGC, type, pvalue, nrects)
46098 1 0.0011 :{ /* miBSCheapChangeClip total: 3 0.0033 */
46099 : CHEAP_FUNC_PROLOGUE (pGC);
46101 : (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
46103 : CHEAP_FUNC_EPILOGUE (pGC);
46107 :miBSCheapCopyClip(pgcDst, pgcSrc)
46108 : GCPtr pgcDst, pgcSrc;
46110 : CHEAP_FUNC_PROLOGUE (pgcDst);
46112 : (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
46114 : CHEAP_FUNC_EPILOGUE (pgcDst);
46118 :miBSCheapDestroyClip(pGC)
46121 : CHEAP_FUNC_PROLOGUE (pGC);
46123 : (* pGC->funcs->DestroyClip)(pGC);
46125 : CHEAP_FUNC_EPILOGUE (pGC);
46129 : * create the full func/op wrappers for a GC
46133 :miBSCreateGCPrivate (pGC)
46136 : miBSGCRec *pPriv;
46138 : pPriv = (miBSGCRec *) xalloc (sizeof (miBSGCRec));
46141 : pPriv->pBackingGC = NULL;
46142 : pPriv->guarantee = GuaranteeNothing;
46143 : pPriv->serialNumber = 0;
46144 : pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
46145 : pPriv->wrapOps = pGC->ops;
46146 : pPriv->wrapFuncs = pGC->funcs;
46147 : pGC->funcs = &miBSGCFuncs;
46148 : pGC->ops = &miBSGCOps;
46149 : pGC->devPrivates[miBSGCIndex].ptr = (pointer) pPriv;
46154 :miBSDestroyGCPrivate (GCPtr pGC)
46156 : miBSGCRec *pPriv;
46158 : pPriv = (miBSGCRec *) pGC->devPrivates[miBSGCIndex].ptr;
46161 : pGC->devPrivates[miBSGCIndex].ptr = (pointer) pPriv->wrapFuncs;
46162 : pGC->funcs = &miBSCheapGCFuncs;
46163 : pGC->ops = pPriv->wrapOps;
46164 : if (pPriv->pBackingGC)
46165 : FreeGC (pPriv->pBackingGC, (GContext) 0);
46166 : xfree ((pointer) pPriv);
46171 : * GC ops -- wrap each GC operation with our own function
46175 : *-----------------------------------------------------------------------
46176 : * miBSFillSpans --
46177 : * Perform a FillSpans, routing output to backing-store as needed.
46184 : *-----------------------------------------------------------------------
46187 :miBSFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
46188 : DrawablePtr pDrawable;
46190 : int nInit; /* number of spans to fill */
46191 : DDXPointPtr pptInit; /* pointer to list of start points */
46192 : int *pwidthInit; /* pointer to list of n widths */
46195 : DDXPointPtr pptCopy, pptReset;
46197 : SETUP_BACKING (pDrawable, pGC);
46201 : pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(nInit*sizeof(DDXPointRec));
46202 : pwidthCopy=(int *)ALLOCATE_LOCAL(nInit*sizeof(int));
46203 : if (pptCopy && pwidthCopy)
46205 : copyData(pptInit, pptCopy, nInit, MoreCopy0);
46206 : memmove((char *)pwidthCopy,(char *)pwidthInit,nInit*sizeof(int));
46208 : (* pGC->ops->FillSpans)(pDrawable, pGC, nInit, pptInit,
46209 : pwidthInit, fSorted);
46210 : if (pGC->miTranslate)
46215 : pptReset = pptCopy;
46216 : dx = pDrawable->x - pBackingDrawable->x;
46217 : dy = pDrawable->y - pBackingDrawable->y;
46221 : pptReset->x -= dx;
46222 : pptReset->y -= dy;
46226 : (* pBackingGC->ops->FillSpans)(pBackingDrawable,
46227 : pBackingGC, nInit, pptCopy, pwidthCopy,
46230 : if (pwidthCopy) DEALLOCATE_LOCAL(pwidthCopy);
46231 : if (pptCopy) DEALLOCATE_LOCAL(pptCopy);
46237 : *-----------------------------------------------------------------------
46238 : * miBSSetSpans --
46239 : * Perform a SetSpans, routing output to backing-store as needed.
46246 : *-----------------------------------------------------------------------
46249 :miBSSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
46250 : DrawablePtr pDrawable;
46258 : DDXPointPtr pptCopy, pptReset;
46260 : SETUP_BACKING (pDrawable, pGC);
46264 : pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(nspans*sizeof(DDXPointRec));
46265 : pwidthCopy=(int *)ALLOCATE_LOCAL(nspans*sizeof(int));
46266 : if (pptCopy && pwidthCopy)
46268 : copyData(ppt, pptCopy, nspans, MoreCopy0);
46269 : memmove((char *)pwidthCopy,(char *)pwidth,nspans*sizeof(int));
46271 : (* pGC->ops->SetSpans)(pDrawable, pGC, psrc, ppt, pwidth,
46272 : nspans, fSorted);
46273 : if (pGC->miTranslate)
46278 : pptReset = pptCopy;
46279 : dx = pDrawable->x - pBackingDrawable->x;
46280 : dy = pDrawable->y - pBackingDrawable->y;
46284 : pptReset->x -= dx;
46285 : pptReset->y -= dy;
46289 : (* pBackingGC->ops->SetSpans)(pBackingDrawable, pBackingGC,
46290 : psrc, pptCopy, pwidthCopy, nspans, fSorted);
46292 : if (pwidthCopy) DEALLOCATE_LOCAL(pwidthCopy);
46293 : if (pptCopy) DEALLOCATE_LOCAL(pptCopy);
46299 : *-----------------------------------------------------------------------
46300 : * miBSPutImage --
46301 : * Perform a PutImage, routing output to backing-store as needed.
46308 : *-----------------------------------------------------------------------
46311 :miBSPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
46312 : DrawablePtr pDrawable;
46323 : SETUP_BACKING (pDrawable, pGC);
46327 : (*pGC->ops->PutImage)(pDrawable, pGC,
46328 : depth, x, y, w, h, leftPad, format, pBits);
46329 : (*pBackingGC->ops->PutImage)(pBackingDrawable, pBackingGC,
46330 : depth, x - pBackingStore->x, y - pBackingStore->y,
46331 : w, h, leftPad, format, pBits);
46336 :typedef RegionPtr (* CopyAreaProcPtr)(DrawablePtr, DrawablePtr, GCPtr,
46337 : int, int, int, int, int, int);
46338 :typedef RegionPtr (* CopyPlaneProcPtr)(DrawablePtr, DrawablePtr, GCPtr,
46339 : int, int, int, int, int, int,
46340 : unsigned long bitPlane);
46342 : *-----------------------------------------------------------------------
46344 : * Perform a CopyArea or CopyPlane within a window that has backing
46348 : * TRUE if the copy was performed or FALSE if a regular one should
46352 : * Things are copied (no s***!)
46355 : * The idea here is to form two regions that cover the source box.
46356 : * One contains the exposed rectangles while the other contains
46357 : * the obscured ones. An array of <box, drawable> pairs is then
46358 : * formed where the <box> indicates the area to be copied and the
46359 : * <drawable> indicates from where it is to be copied (exposed regions
46360 : * come from the screen while obscured ones come from the backing
46361 : * pixmap). The array 'sequence' is then filled with the indices of
46362 : * the pairs in the order in which they should be copied to prevent
46363 : * things from getting screwed up. A call is also made through the
46364 : * backingGC to take care of any copying into the backing pixmap.
46366 : *-----------------------------------------------------------------------
46370 : WindowPtr pWin, /* Window being scrolled */
46371 : GCPtr pGC, /* GC we're called through */
46372 : int srcx, /* X of source rectangle */
46373 : int srcy, /* Y of source rectangle */
46374 : int w, /* Width of source rectangle */
46375 : int h, /* Height of source rectangle */
46376 : int dstx, /* X of destination rectangle */
46377 : int dsty, /* Y of destination rectangle */
46378 : unsigned long plane, /* Plane to copy (0 for CopyArea) */
46379 : CopyPlaneProcPtr copyProc, /* Procedure to call to perform the copy */
46380 : RegionPtr *ppRgn) /* resultant Graphics Expose region */
46382 : RegionPtr pRgnExp; /* Exposed region */
46383 : RegionPtr pRgnObs; /* Obscured region */
46384 : BoxRec box; /* Source box (screen coord) */
46386 : BoxPtr pBox; /* Source box */
46389 : } source; /* Place from which to copy */
46390 : } *boxes; /* Array of box/drawable pairs covering
46392 : int *sequence; /* Sequence of boxes to move */
46393 : int i, j, k, l, y;
46395 : int dx, dy, nrects;
46396 : Bool graphicsExposures;
46397 : CopyPlaneProcPtr pixCopyProc;
46398 : int numRectsExp, numRectsObs;
46399 : BoxPtr pBoxExp, pBoxObs;
46401 : SETUP_BACKING (pWin, pGC);
46405 : * Create a region of exposed boxes in pRgnExp.
46407 : box.x1 = srcx + pWin->drawable.x;
46408 : box.x2 = box.x1 + w;
46409 : box.y1 = srcy + pWin->drawable.y;
46410 : box.y2 = box.y1 + h;
46412 : pRgnExp = REGION_CREATE(pGC->pScreen, &box, 1);
46413 : REGION_INTERSECT(pGC->pScreen, pRgnExp, pRgnExp, &pWin->clipList);
46414 : pRgnObs = REGION_CREATE(pGC->pScreen, NULL, 1);
46415 : REGION_INVERSE( pGC->pScreen, pRgnObs, pRgnExp, &box);
46418 : * Translate regions into window coordinates for proper calls
46419 : * to the copyProc, then make sure none of the obscured region sticks
46420 : * into invalid areas of the backing pixmap.
46422 : REGION_TRANSLATE(pGC->pScreen, pRgnExp,
46423 : -pWin->drawable.x,
46424 : -pWin->drawable.y);
46425 : REGION_TRANSLATE(pGC->pScreen, pRgnObs,
46426 : -pWin->drawable.x,
46427 : -pWin->drawable.y);
46428 : REGION_INTERSECT(pGC->pScreen, pRgnObs, pRgnObs, &pBackingStore->SavedRegion);
46431 : * If the obscured region is empty, there's no point being fancy.
46433 : if (!REGION_NOTEMPTY(pGC->pScreen, pRgnObs))
46435 : REGION_DESTROY(pGC->pScreen, pRgnExp);
46436 : REGION_DESTROY(pGC->pScreen, pRgnObs);
46441 : numRectsExp = REGION_NUM_RECTS(pRgnExp);
46442 : pBoxExp = REGION_RECTS(pRgnExp);
46443 : pBoxObs = REGION_RECTS(pRgnObs);
46444 : numRectsObs = REGION_NUM_RECTS(pRgnObs);
46445 : nrects = numRectsExp + numRectsObs;
46447 : boxes = (struct BoxDraw *)ALLOCATE_LOCAL(nrects * sizeof(struct BoxDraw));
46448 : sequence = (int *) ALLOCATE_LOCAL(nrects * sizeof(int));
46451 : if (!boxes || !sequence)
46453 : if (sequence) DEALLOCATE_LOCAL(sequence);
46454 : if (boxes) DEALLOCATE_LOCAL(boxes);
46455 : REGION_DESTROY(pGC->pScreen, pRgnExp);
46456 : REGION_DESTROY(pGC->pScreen, pRgnObs);
46462 : * Order the boxes in the two regions so we know from which drawable
46463 : * to copy which box, storing the result in the boxes array
46465 : for (i = 0, j = 0, k = 0;
46466 : (i < numRectsExp) && (j < numRectsObs);
46469 : if (pBoxExp[i].y1 < pBoxObs[j].y1)
46471 : boxes[k].pBox = &pBoxExp[i];
46472 : boxes[k].source = win;
46475 : else if ((pBoxObs[j].y1 < pBoxExp[i].y1) ||
46476 : (pBoxObs[j].x1 < pBoxExp[i].x1))
46478 : boxes[k].pBox = &pBoxObs[j];
46479 : boxes[k].source = pix;
46484 : boxes[k].pBox = &pBoxExp[i];
46485 : boxes[k].source = win;
46491 : * Catch any leftover boxes from either region (note that only
46492 : * one can have leftover boxes...)
46494 : if (i != numRectsExp)
46498 : boxes[k].pBox = &pBoxExp[i];
46499 : boxes[k].source = win;
46502 : } while (i < numRectsExp);
46509 : boxes[k].pBox = &pBoxObs[j];
46510 : boxes[k].source = pix;
46513 : } while (j < numRectsObs);
46516 : if (dsty <= srcy)
46519 : * Scroll up or vertically stationary, so vertical order is ok.
46521 : if (dstx <= srcx)
46524 : * Scroll left or horizontally stationary, so horizontal order
46527 : for (i = 0; i < nrects; i++)
46535 : * Scroll right. Need to reverse the rectangles within each
46538 : for (i = 0, j = 1, k = 0;
46540 : j = i + 1, k = i)
46542 : y = boxes[i].pBox->y1;
46543 : while ((j < nrects) && (boxes[j].pBox->y1 == y))
46547 : for (j--; j >= k; j--, i++)
46557 : * Scroll down. Must reverse vertical banding, at least.
46562 : * Scroll left. Horizontal order is ok.
46564 : for (i = nrects - 1, j = i - 1, k = i, l = 0;
46566 : j = i - 1, k = i)
46569 : * Find extent of current horizontal band, then reverse
46570 : * the order of the whole band.
46572 : y = boxes[i].pBox->y1;
46573 : while ((j >= 0) && (boxes[j].pBox->y1 == y))
46577 : for (j++; j <= k; j++, i--, l++)
46586 : * Scroll right or horizontal stationary.
46587 : * Reverse horizontal order as well (if stationary, horizontal
46588 : * order can be swapped without penalty and this is faster
46591 : for (i = 0, j = nrects - 1; i < nrects; i++, j--)
46599 : * XXX: To avoid getting multiple NoExpose events from this operation,
46600 : * we turn OFF graphicsExposures in the gc and deal with any uncopied
46601 : * areas later, if there's something not in backing-store.
46604 : graphicsExposures = pGC->graphicsExposures;
46605 : pGC->graphicsExposures = FALSE;
46607 : dx = dstx - srcx;
46608 : dy = dsty - srcy;
46611 : * Figure out which copy procedure to use from the backing GC. Note we
46612 : * must do this because some implementations (sun's, e.g.) have
46613 : * pBackingGC a fake GC with the real one below it, thus the devPriv for
46614 : * pBackingGC won't be what the output library expects.
46618 : pixCopyProc = pBackingGC->ops->CopyPlane;
46622 : pixCopyProc = (CopyPlaneProcPtr)pBackingGC->ops->CopyArea;
46625 : for (i = 0; i < nrects; i++)
46627 : pBox = boxes[sequence[i]].pBox;
46630 : * If we're copying from the pixmap, we need to place its contents
46631 : * onto the screen before scrolling the pixmap itself. If we're copying
46632 : * from the window, we need to copy its contents into the pixmap before
46633 : * we scroll the window itself.
46635 : if (boxes[sequence[i]].source == pix)
46637 : (void) (* copyProc) (pBackingDrawable, &(pWin->drawable), pGC,
46638 : pBox->x1 - pBackingStore->x,
46639 : pBox->y1 - pBackingStore->y,
46640 : pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
46641 : pBox->x1 + dx, pBox->y1 + dy, plane);
46642 : (void) (* pixCopyProc) (pBackingDrawable, pBackingDrawable, pBackingGC,
46643 : pBox->x1 - pBackingStore->x,
46644 : pBox->y1 - pBackingStore->y,
46645 : pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
46646 : pBox->x1 + dx - pBackingStore->x,
46647 : pBox->y1 + dy - pBackingStore->y, plane);
46651 : (void) (* pixCopyProc) (&(pWin->drawable), pBackingDrawable, pBackingGC,
46652 : pBox->x1, pBox->y1,
46653 : pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
46654 : pBox->x1 + dx - pBackingStore->x,
46655 : pBox->y1 + dy - pBackingStore->y, plane);
46656 : (void) (* copyProc) (&(pWin->drawable), &(pWin->drawable), pGC,
46657 : pBox->x1, pBox->y1,
46658 : pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
46659 : pBox->x1 + dx, pBox->y1 + dy, plane);
46662 : DEALLOCATE_LOCAL(sequence);
46663 : DEALLOCATE_LOCAL(boxes);
46665 : pGC->graphicsExposures = graphicsExposures;
46667 : * Form union of rgnExp and rgnObs and see if covers entire area
46668 : * to be copied. Store the resultant region for miBSCopyArea
46669 : * to return to dispatch which will send the appropriate expose
46672 : REGION_UNION(pGC->pScreen, pRgnExp, pRgnExp, pRgnObs);
46674 : box.x2 = srcx + w;
46676 : box.y2 = srcy + h;
46677 : if (RECT_IN_REGION(pGC->pScreen, pRgnExp, &box) == rgnIN)
46679 : REGION_EMPTY(pGC->pScreen, pRgnExp);
46683 : REGION_INVERSE( pGC->pScreen, pRgnExp, pRgnExp, &box);
46684 : REGION_TRANSLATE( pGC->pScreen, pRgnExp,
46685 : dx + pWin->drawable.x,
46686 : dy + pWin->drawable.y);
46687 : REGION_INTERSECT( pGC->pScreen, pRgnObs, pRgnExp, &pWin->clipList);
46688 : (*pWin->drawable.pScreen->PaintWindowBackground) (pWin,
46689 : pRgnObs, PW_BACKGROUND);
46690 : REGION_TRANSLATE( pGC->pScreen, pRgnExp,
46691 : -pWin->drawable.x,
46692 : -pWin->drawable.y);
46693 : miBSClearBackingRegion (pWin, pRgnExp);
46695 : if (graphicsExposures)
46696 : *ppRgn = pRgnExp;
46698 : REGION_DESTROY(pGC->pScreen, pRgnExp);
46699 : REGION_DESTROY(pGC->pScreen, pRgnObs);
46705 : *-----------------------------------------------------------------------
46706 : * miBSCopyArea --
46707 : * Perform a CopyArea from the source to the destination, extracting
46708 : * from the source's backing-store and storing into the destination's
46709 : * backing-store without messing anything up. If the source and
46710 : * destination are different, there's not too much to worry about:
46711 : * we can just issue several calls to the regular CopyArea function.
46718 : *-----------------------------------------------------------------------
46721 :miBSCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
46722 : DrawablePtr pSrc;
46723 : DrawablePtr pDst;
46734 : int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
46735 : RegionPtr pixExposed = 0, winExposed = 0;
46737 : SETUP_BACKING(pDst, pGC);
46741 : if ((pSrc != pDst) ||
46742 : (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
46743 : (unsigned long) 0, (CopyPlaneProcPtr)pGC->ops->CopyArea,
46747 : * always copy to the backing store first, miBSDoCopy
46748 : * returns FALSE if the *source* region is disjoint
46749 : * from the backing store saved region. So, copying
46750 : * *to* the backing store is always safe
46752 : if (pGC->clientClipType != CT_PIXMAP)
46755 : * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
46756 : * the backing store. An unnecessary optimisation,
46757 : * but a useful one when GetSpans is slow.
46759 : pExtents = REGION_EXTENTS(pDst->pScreen,
46760 : (RegionPtr)pBackingGC->clientClip);
46767 : dx = pExtents->x1 - bdstx;
46774 : dy = pExtents->y1 - bdsty;
46781 : dx = (bdstx + bw) - pExtents->x2;
46784 : dy = (bdsty + bh) - pExtents->y2;
46787 : if (bw > 0 && bh > 0)
46788 : pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
46789 : pBackingDrawable, pBackingGC,
46790 : bsrcx, bsrcy, bw, bh, bdstx - pBackingStore->x,
46791 : bdsty - pBackingStore->y);
46794 : pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
46795 : pBackingDrawable, pBackingGC,
46796 : srcx, srcy, w, h,
46797 : dstx - pBackingStore->x, dsty - pBackingStore->y);
46799 : winExposed = (* pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
46803 : * compute the composite graphics exposure region
46808 : REGION_UNION(pDst->pScreen, winExposed, winExposed, pixExposed);
46809 : REGION_DESTROY(pDst->pScreen, pixExposed);
46812 : winExposed = pixExposed;
46816 : return winExposed;
46820 : *-----------------------------------------------------------------------
46821 : * miBSCopyPlane --
46828 : *-----------------------------------------------------------------------
46831 :miBSCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
46832 : DrawablePtr pSrc;
46833 : DrawablePtr pDst;
46841 : unsigned long plane;
46845 : int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
46846 : RegionPtr winExposed = 0, pixExposed = 0;
46847 : SETUP_BACKING(pDst, pGC);
46851 : if ((pSrc != pDst) ||
46852 : (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
46853 : plane, pGC->ops->CopyPlane, &winExposed)))
46856 : * always copy to the backing store first, miBSDoCopy
46857 : * returns FALSE if the *source* region is disjoint
46858 : * from the backing store saved region. So, copying
46859 : * *to* the backing store is always safe
46861 : if (pGC->clientClipType != CT_PIXMAP)
46864 : * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
46865 : * the backing store. An unnecessary optimisation,
46866 : * but a useful one when GetSpans is slow.
46868 : pExtents = REGION_EXTENTS(pDst->pScreen,
46869 : (RegionPtr)pBackingGC->clientClip);
46876 : dx = pExtents->x1 - bdstx;
46883 : dy = pExtents->y1 - bdsty;
46890 : dx = (bdstx + bw) - pExtents->x2;
46893 : dy = (bdsty + bh) - pExtents->y2;
46896 : if (bw > 0 && bh > 0)
46897 : pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
46898 : pBackingDrawable,
46899 : pBackingGC, bsrcx, bsrcy, bw, bh,
46900 : bdstx - pBackingStore->x,
46901 : bdsty - pBackingStore->y, plane);
46904 : pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
46905 : pBackingDrawable,
46906 : pBackingGC, srcx, srcy, w, h,
46907 : dstx - pBackingStore->x,
46908 : dsty - pBackingStore->y, plane);
46910 : winExposed = (* pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
46911 : dstx, dsty, plane);
46916 : * compute the composite graphics exposure region
46922 : REGION_UNION(pDst->pScreen, winExposed, winExposed, pixExposed);
46923 : REGION_DESTROY(pDst->pScreen, pixExposed);
46926 : winExposed = pixExposed;
46930 : return winExposed;
46934 : *-----------------------------------------------------------------------
46935 : * miBSPolyPoint --
46936 : * Perform a PolyPoint, routing output to backing-store as needed.
46943 : *-----------------------------------------------------------------------
46946 :miBSPolyPoint (pDrawable, pGC, mode, npt, pptInit)
46947 : DrawablePtr pDrawable;
46949 : int mode; /* Origin or Previous */
46954 : SETUP_BACKING (pDrawable, pGC);
46958 : pptCopy = (xPoint *)ALLOCATE_LOCAL(npt*sizeof(xPoint));
46961 : copyPoints(pptInit, pptCopy, npt, mode);
46963 : (* pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
46965 : (* pBackingGC->ops->PolyPoint) (pBackingDrawable,
46966 : pBackingGC, mode, npt, pptCopy);
46968 : DEALLOCATE_LOCAL(pptCopy);
46975 : *-----------------------------------------------------------------------
46976 : * miBSPolyLines --
46977 : * Perform a Polylines, routing output to backing-store as needed.
46983 : *-----------------------------------------------------------------------
46986 :miBSPolylines (pDrawable, pGC, mode, npt, pptInit)
46987 : DrawablePtr pDrawable;
46991 : DDXPointPtr pptInit;
46993 : DDXPointPtr pptCopy;
46994 : SETUP_BACKING (pDrawable, pGC);
46998 : pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(npt*sizeof(DDXPointRec));
47001 : copyPoints(pptInit, pptCopy, npt, mode);
47003 : (* pGC->ops->Polylines)(pDrawable, pGC, mode, npt, pptInit);
47004 : (* pBackingGC->ops->Polylines)(pBackingDrawable,
47005 : pBackingGC, mode, npt, pptCopy);
47006 : DEALLOCATE_LOCAL(pptCopy);
47013 : *-----------------------------------------------------------------------
47014 : * miBSPolySegment --
47015 : * Perform a PolySegment, routing output to backing-store as needed.
47022 : *-----------------------------------------------------------------------
47025 :miBSPolySegment(pDrawable, pGC, nseg, pSegs)
47026 : DrawablePtr pDrawable;
47031 : xSegment *pSegsCopy;
47033 : SETUP_BACKING (pDrawable, pGC);
47037 : pSegsCopy = (xSegment *)ALLOCATE_LOCAL(nseg*sizeof(xSegment));
47040 : copyData(pSegs, pSegsCopy, nseg << 1, MoreCopy0);
47042 : (* pGC->ops->PolySegment)(pDrawable, pGC, nseg, pSegs);
47043 : (* pBackingGC->ops->PolySegment)(pBackingDrawable,
47044 : pBackingGC, nseg, pSegsCopy);
47046 : DEALLOCATE_LOCAL(pSegsCopy);
47053 : *-----------------------------------------------------------------------
47054 : * miBSPolyRectangle --
47055 : * Perform a PolyRectangle, routing output to backing-store as needed.
47062 : *-----------------------------------------------------------------------
47065 :miBSPolyRectangle(pDrawable, pGC, nrects, pRects)
47066 : DrawablePtr pDrawable;
47069 : xRectangle *pRects;
47071 : xRectangle *pRectsCopy;
47072 : SETUP_BACKING (pDrawable, pGC);
47076 : pRectsCopy =(xRectangle *)ALLOCATE_LOCAL(nrects*sizeof(xRectangle));
47079 : copyData(pRects, pRectsCopy, nrects, MoreCopy2);
47081 : (* pGC->ops->PolyRectangle)(pDrawable, pGC, nrects, pRects);
47082 : (* pBackingGC->ops->PolyRectangle)(pBackingDrawable,
47083 : pBackingGC, nrects, pRectsCopy);
47085 : DEALLOCATE_LOCAL(pRectsCopy);
47092 : *-----------------------------------------------------------------------
47094 : * Perform a PolyArc, routing output to backing-store as needed.
47100 : *-----------------------------------------------------------------------
47103 :miBSPolyArc(pDrawable, pGC, narcs, parcs)
47104 : DrawablePtr pDrawable;
47110 : SETUP_BACKING (pDrawable, pGC);
47114 : pArcsCopy = (xArc *)ALLOCATE_LOCAL(narcs*sizeof(xArc));
47117 : copyData(parcs, pArcsCopy, narcs, MoreCopy4);
47119 : (* pGC->ops->PolyArc)(pDrawable, pGC, narcs, parcs);
47120 : (* pBackingGC->ops->PolyArc)(pBackingDrawable, pBackingGC,
47121 : narcs, pArcsCopy);
47123 : DEALLOCATE_LOCAL(pArcsCopy);
47130 : *-----------------------------------------------------------------------
47131 : * miBSFillPolygon --
47132 : * Perform a FillPolygon, routing output to backing-store as needed.
47139 : *-----------------------------------------------------------------------
47142 :miBSFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
47143 : DrawablePtr pDrawable;
47147 : DDXPointPtr pPts;
47149 : DDXPointPtr pPtsCopy;
47150 : SETUP_BACKING (pDrawable, pGC);
47154 : pPtsCopy = (DDXPointPtr)ALLOCATE_LOCAL(count*sizeof(DDXPointRec));
47157 : copyPoints(pPts, pPtsCopy, count, mode);
47158 : (* pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, count, pPts);
47159 : (* pBackingGC->ops->FillPolygon)(pBackingDrawable,
47160 : pBackingGC, shape, mode,
47161 : count, pPtsCopy);
47163 : DEALLOCATE_LOCAL(pPtsCopy);
47170 : *-----------------------------------------------------------------------
47171 : * miBSPolyFillRect --
47172 : * Perform a PolyFillRect, routing output to backing-store as needed.
47179 : *-----------------------------------------------------------------------
47182 :miBSPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
47183 : DrawablePtr pDrawable;
47185 : int nrectFill; /* number of rectangles to fill */
47186 : xRectangle *prectInit; /* Pointer to first rectangle to fill */
47188 : xRectangle *pRectCopy;
47189 : SETUP_BACKING (pDrawable, pGC);
47194 : (xRectangle *)ALLOCATE_LOCAL(nrectFill*sizeof(xRectangle));
47197 : copyData(prectInit, pRectCopy, nrectFill, MoreCopy2);
47199 : (* pGC->ops->PolyFillRect)(pDrawable, pGC, nrectFill, prectInit);
47200 : (* pBackingGC->ops->PolyFillRect)(pBackingDrawable,
47201 : pBackingGC, nrectFill, pRectCopy);
47203 : DEALLOCATE_LOCAL(pRectCopy);
47210 : *-----------------------------------------------------------------------
47211 : * miBSPolyFillArc --
47212 : * Perform a PolyFillArc, routing output to backing-store as needed.
47219 : *-----------------------------------------------------------------------
47222 :miBSPolyFillArc(pDrawable, pGC, narcs, parcs)
47223 : DrawablePtr pDrawable;
47229 : SETUP_BACKING (pDrawable, pGC);
47233 : pArcsCopy = (xArc *)ALLOCATE_LOCAL(narcs*sizeof(xArc));
47236 : copyData(parcs, pArcsCopy, narcs, MoreCopy4);
47237 : (* pGC->ops->PolyFillArc)(pDrawable, pGC, narcs, parcs);
47238 : (* pBackingGC->ops->PolyFillArc)(pBackingDrawable,
47239 : pBackingGC, narcs, pArcsCopy);
47240 : DEALLOCATE_LOCAL(pArcsCopy);
47248 : *-----------------------------------------------------------------------
47249 : * miBSPolyText8 --
47250 : * Perform a PolyText8, routing output to backing-store as needed.
47256 : *-----------------------------------------------------------------------
47259 :miBSPolyText8(pDrawable, pGC, x, y, count, chars)
47260 : DrawablePtr pDrawable;
47267 : SETUP_BACKING (pDrawable, pGC);
47271 : result = (* pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
47272 : (* pBackingGC->ops->PolyText8)(pBackingDrawable, pBackingGC,
47273 : x - pBackingStore->x, y - pBackingStore->y,
47281 : *-----------------------------------------------------------------------
47282 : * miBSPolyText16 --
47283 : * Perform a PolyText16, routing output to backing-store as needed.
47289 : *-----------------------------------------------------------------------
47292 :miBSPolyText16(pDrawable, pGC, x, y, count, chars)
47293 : DrawablePtr pDrawable;
47297 : unsigned short *chars;
47300 : SETUP_BACKING (pDrawable, pGC);
47304 : result = (* pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
47305 : (* pBackingGC->ops->PolyText16)(pBackingDrawable, pBackingGC,
47306 : x - pBackingStore->x, y - pBackingStore->y,
47315 : *-----------------------------------------------------------------------
47316 : * miBSImageText8 --
47317 : * Perform a ImageText8, routing output to backing-store as needed.
47323 : *-----------------------------------------------------------------------
47326 :miBSImageText8(pDrawable, pGC, x, y, count, chars)
47327 : DrawablePtr pDrawable;
47333 : SETUP_BACKING (pDrawable, pGC);
47336 : (* pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
47337 : (* pBackingGC->ops->ImageText8)(pBackingDrawable, pBackingGC,
47338 : x - pBackingStore->x, y - pBackingStore->y,
47345 : *-----------------------------------------------------------------------
47346 : * miBSImageText16 --
47347 : * Perform a ImageText16, routing output to backing-store as needed.
47353 : *-----------------------------------------------------------------------
47356 :miBSImageText16(pDrawable, pGC, x, y, count, chars)
47357 : DrawablePtr pDrawable;
47361 : unsigned short *chars;
47363 : SETUP_BACKING (pDrawable, pGC);
47366 : (* pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
47367 : (* pBackingGC->ops->ImageText16)(pBackingDrawable, pBackingGC,
47368 : x - pBackingStore->x, y - pBackingStore->y,
47375 : *-----------------------------------------------------------------------
47376 : * miBSImageGlyphBlt --
47377 : * Perform a ImageGlyphBlt, routing output to backing-store as needed.
47383 : *-----------------------------------------------------------------------
47386 :miBSImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
47387 : DrawablePtr pDrawable;
47390 : unsigned int nglyph;
47391 : CharInfoPtr *ppci; /* array of character info */
47392 : pointer pglyphBase; /* start of array of glyphs */
47394 : SETUP_BACKING (pDrawable, pGC);
47397 : (* pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
47399 : (* pBackingGC->ops->ImageGlyphBlt)(pBackingDrawable, pBackingGC,
47400 : x - pBackingStore->x, y - pBackingStore->y,
47401 : nglyph, ppci, pglyphBase);
47407 : *-----------------------------------------------------------------------
47408 : * miBSPolyGlyphBlt --
47409 : * Perform a PolyGlyphBlt, routing output to backing-store as needed.
47415 : *-----------------------------------------------------------------------
47418 :miBSPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
47419 : DrawablePtr pDrawable;
47422 : unsigned int nglyph;
47423 : CharInfoPtr *ppci; /* array of character info */
47424 : pointer pglyphBase; /* start of array of glyphs */
47426 : SETUP_BACKING (pDrawable, pGC);
47429 : (* pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
47430 : ppci, pglyphBase);
47431 : (* pBackingGC->ops->PolyGlyphBlt)(pBackingDrawable, pBackingGC,
47432 : x - pBackingStore->x, y - pBackingStore->y,
47433 : nglyph, ppci, pglyphBase);
47438 : *-----------------------------------------------------------------------
47439 : * miBSPushPixels --
47440 : * Perform a PushPixels, routing output to backing-store as needed.
47446 : *-----------------------------------------------------------------------
47449 :miBSPushPixels(pGC, pBitMap, pDst, w, h, x, y)
47451 : PixmapPtr pBitMap;
47452 : DrawablePtr pDst;
47455 : SETUP_BACKING (pDst, pGC);
47458 : (* pGC->ops->PushPixels)(pGC, pBitMap, pDst, w, h, x, y);
47459 : if (pGC->miTranslate) {
47463 : (* pBackingGC->ops->PushPixels)(pBackingGC, pBitMap,
47464 : pBackingDrawable, w, h,
47465 : x - pBackingStore->x, y - pBackingStore->y);
47471 : *-----------------------------------------------------------------------
47472 : * miBSClearBackingStore --
47473 : * Clear the given area of the backing pixmap with the background of
47474 : * the window, whatever it is. If generateExposures is TRUE, generate
47475 : * exposure events for the area. Note that if the area has any
47476 : * part outside the saved portions of the window, we do not allow the
47477 : * count in the expose events to be 0, since there will be more
47478 : * expose events to come.
47484 : * Areas of pixmap are cleared and Expose events are generated.
47486 : *-----------------------------------------------------------------------
47489 :miBSClearBackingStore(pWin, x, y, w, h, generateExposures)
47495 : Bool generateExposures;
47499 : miBSWindowPtr pBackingStore;
47500 : ScreenPtr pScreen;
47504 : pointer gcvalues[4];
47505 : unsigned long gcmask;
47506 : xRectangle *rects;
47509 : PixUnion background;
47510 : char backgroundState;
47513 : pBackingStore = (miBSWindowPtr)pWin->backStorage;
47514 : pScreen = pWin->drawable.pScreen;
47516 : if ((pBackingStore->status == StatusNoPixmap) ||
47517 : (pBackingStore->status == StatusBadAlloc))
47518 : return NullRegion;
47521 : w = (int) pWin->drawable.width - x;
47523 : h = (int) pWin->drawable.height - y;
47529 : pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
47531 : return NullRegion;
47532 : REGION_INTERSECT( pScreen, pRgn, pRgn, &pBackingStore->SavedRegion);
47534 : if (REGION_NOTEMPTY( pScreen, pRgn))
47537 : * if clearing entire window, simply make new virtual
47538 : * tile. For the root window, we also destroy the pixmap
47539 : * to save a pile of memory
47541 : if (x == 0 && y == 0 &&
47542 : w == pWin->drawable.width &&
47543 : h == pWin->drawable.height)
47545 : if (!pWin->parent)
47546 : miDestroyBSPixmap (pWin);
47547 : if (pBackingStore->status != StatusContents)
47548 : miTileVirtualBS (pWin);
47551 : ts_x_origin = ts_y_origin = 0;
47553 : backgroundState = pWin->backgroundState;
47554 : background = pWin->background;
47555 : if (backgroundState == ParentRelative) {
47556 : WindowPtr pParent;
47559 : while (pParent->backgroundState == ParentRelative) {
47560 : ts_x_origin -= pParent->origin.x;
47561 : ts_y_origin -= pParent->origin.y;
47562 : pParent = pParent->parent;
47564 : backgroundState = pParent->backgroundState;
47565 : background = pParent->background;
47568 : if ((backgroundState != None) &&
47569 : ((pBackingStore->status == StatusContents) ||
47570 : !SameBackground (pBackingStore->backgroundState,
47571 : pBackingStore->background,
47575 : if (!pBackingStore->pBackingPixmap)
47576 : miCreateBSPixmap(pWin, NullBox);
47578 : pGC = GetScratchGC(pWin->drawable.depth, pScreen);
47579 : if (pGC && pBackingStore->pBackingPixmap)
47582 : * First take care of any ParentRelative stuff by altering the
47583 : * tile/stipple origin to match the coordinates of the upper-left
47584 : * corner of the first ancestor without a ParentRelative background.
47585 : * This coordinate is, of course, negative.
47588 : if (backgroundState == BackgroundPixel)
47590 : gcvalues[0] = (pointer) background.pixel;
47591 : gcvalues[1] = (pointer)FillSolid;
47592 : gcmask = GCForeground|GCFillStyle;
47596 : gcvalues[0] = (pointer)FillTiled;
47597 : gcvalues[1] = (pointer) background.pixmap;
47598 : gcmask = GCFillStyle|GCTile;
47600 : gcvalues[2] = (pointer)(long)(ts_x_origin - pBackingStore->x);
47601 : gcvalues[3] = (pointer)(long)(ts_y_origin - pBackingStore->y);
47602 : gcmask |= GCTileStipXOrigin|GCTileStipYOrigin;
47603 : DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE);
47604 : ValidateGC((DrawablePtr)pBackingStore->pBackingPixmap, pGC);
47607 : * Figure out the array of rectangles to fill and fill them with
47608 : * PolyFillRect in the proper mode, as set in the GC above.
47610 : numRects = REGION_NUM_RECTS(pRgn);
47611 : rects = (xRectangle *)ALLOCATE_LOCAL(numRects*sizeof(xRectangle));
47615 : for (i = 0, pBox = REGION_RECTS(pRgn);
47619 : rects[i].x = pBox->x1 - pBackingStore->x;
47620 : rects[i].y = pBox->y1 - pBackingStore->y;
47621 : rects[i].width = pBox->x2 - pBox->x1;
47622 : rects[i].height = pBox->y2 - pBox->y1;
47624 : (* pGC->ops->PolyFillRect) (
47625 : (DrawablePtr)pBackingStore->pBackingPixmap,
47626 : pGC, numRects, rects);
47627 : DEALLOCATE_LOCAL(rects);
47629 : FreeScratchGC(pGC);
47633 : if (!generateExposures)
47635 : REGION_DESTROY(pScreen, pRgn);
47641 : * result must be screen relative, but is currently
47642 : * drawable relative.
47644 : REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x,
47645 : pWin->drawable.y);
47650 : REGION_DESTROY( pScreen, pRgn);
47657 :miBSClearBackingRegion (pWin, pRgn)
47664 : i = REGION_NUM_RECTS(pRgn);
47665 : pBox = REGION_RECTS(pRgn);
47668 : (void) miBSClearBackingStore(pWin, pBox->x1, pBox->y1,
47669 : pBox->x2 - pBox->x1,
47670 : pBox->y2 - pBox->y1,
47677 : * fill a region of the destination with virtual bits
47679 : * pRgn is to be translated by (x,y)
47683 :miBSFillVirtualBits (pDrawable, pGC, pRgn, x, y, state, pixunion, planeMask)
47684 : DrawablePtr pDrawable;
47689 : PixUnion pixunion;
47690 : unsigned long planeMask;
47694 : pointer gcval[5];
47695 : xRectangle *pRect;
47700 : if (state == None)
47702 : numRects = REGION_NUM_RECTS(pRgn);
47703 : pRect = (xRectangle *)ALLOCATE_LOCAL(numRects * sizeof(xRectangle));
47707 : if (pDrawable->type != DRAWABLE_PIXMAP)
47709 : pWin = (WindowPtr) pDrawable;
47710 : if (!pWin->backStorage)
47715 : gcval[i++] = (pointer)planeMask;
47716 : gcmask |= GCPlaneMask;
47717 : if (state == BackgroundPixel)
47719 : if (pGC->fgPixel != pixunion.pixel)
47721 : gcval[i++] = (pointer)pixunion.pixel;
47722 : gcmask |= GCForeground;
47724 : if (pGC->fillStyle != FillSolid)
47726 : gcval[i++] = (pointer)FillSolid;
47727 : gcmask |= GCFillStyle;
47732 : if (pGC->fillStyle != FillTiled)
47734 : gcval[i++] = (pointer)FillTiled;
47735 : gcmask |= GCFillStyle;
47737 : if (pGC->tileIsPixel || pGC->tile.pixmap != pixunion.pixmap)
47739 : gcval[i++] = (pointer)pixunion.pixmap;
47740 : gcmask |= GCTile;
47742 : if (pGC->patOrg.x != x)
47744 : gcval[i++] = (pointer)(long)x;
47745 : gcmask |= GCTileStipXOrigin;
47747 : if (pGC->patOrg.y != y)
47749 : gcval[i++] = (pointer)(long)y;
47750 : gcmask |= GCTileStipYOrigin;
47754 : DoChangeGC (pGC, gcmask, (XID *)gcval, 1);
47757 : (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
47759 : if (pDrawable->serialNumber != pGC->serialNumber)
47760 : ValidateGC (pDrawable, pGC);
47762 : pBox = REGION_RECTS(pRgn);
47763 : for (i = numRects; --i >= 0; pBox++, pRect++)
47765 : pRect->x = pBox->x1 + x;
47766 : pRect->y = pBox->y1 + y;
47767 : pRect->width = pBox->x2 - pBox->x1;
47768 : pRect->height = pBox->y2 - pBox->y1;
47770 : pRect -= numRects;
47771 : (*pGC->ops->PolyFillRect) (pDrawable, pGC, numRects, pRect);
47773 : (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
47774 : DEALLOCATE_LOCAL (pRect);
47778 : *-----------------------------------------------------------------------
47779 : * miBSAllocate --
47780 : * Create and install backing store info for a window
47782 : *-----------------------------------------------------------------------
47786 :miBSAllocate(pWin)
47789 : miBSWindowPtr pBackingStore;
47790 : ScreenPtr pScreen;
47792 : if (pWin->drawable.pScreen->backingStoreSupport == NotUseful)
47794 : pScreen = pWin->drawable.pScreen;
47795 : if (!(pBackingStore = (miBSWindowPtr)pWin->backStorage))
47798 : pBackingStore = (miBSWindowPtr)xalloc(sizeof(miBSWindowRec));
47799 : if (!pBackingStore)
47802 : pBackingStore->pBackingPixmap = NullPixmap;
47803 : pBackingStore->x = 0;
47804 : pBackingStore->y = 0;
47805 : REGION_NULL( pScreen, &pBackingStore->SavedRegion);
47806 : pBackingStore->viewable = (char)pWin->viewable;
47807 : pBackingStore->status = StatusNoPixmap;
47808 : pBackingStore->backgroundState = None;
47809 : pWin->backStorage = (pointer) pBackingStore;
47813 : * Now want to initialize the backing pixmap and SavedRegion if
47814 : * necessary. The initialization consists of finding all the
47815 : * currently-obscured regions, by taking the inverse of the window's
47816 : * clip list, storing the result in SavedRegion, and exposing those
47817 : * areas of the window.
47820 : if (pBackingStore->status == StatusNoPixmap &&
47821 : ((pWin->backingStore == WhenMapped && pWin->viewable) ||
47822 : (pWin->backingStore == Always)))
47825 : RegionPtr pSavedRegion;
47827 : pSavedRegion = &pBackingStore->SavedRegion;
47829 : box.x1 = pWin->drawable.x;
47830 : box.x2 = box.x1 + (int) pWin->drawable.width;
47831 : box.y1 = pWin->drawable.y;
47832 : box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
47834 : REGION_INVERSE( pScreen, pSavedRegion, &pWin->clipList, &box);
47835 : REGION_TRANSLATE( pScreen, pSavedRegion,
47836 : -pWin->drawable.x,
47837 : -pWin->drawable.y);
47839 : if (wBoundingShape (pWin))
47840 : REGION_INTERSECT(pScreen, pSavedRegion, pSavedRegion,
47841 : wBoundingShape (pWin));
47842 : if (wClipShape (pWin))
47843 : REGION_INTERSECT(pScreen, pSavedRegion, pSavedRegion,
47844 : wClipShape (pWin));
47846 : /* if window is already on-screen, assume it has been drawn to */
47847 : if (pWin->viewable)
47848 : pBackingStore->status = StatusVDirty;
47849 : miTileVirtualBS (pWin);
47852 : * deliver all the newly available regions
47853 : * as exposure events to the window
47856 : miSendExposures(pWin, pSavedRegion, 0, 0);
47858 : else if (!pWin->viewable)
47861 : * Turn off backing store when we're not supposed to
47862 : * be saving anything
47864 : if (pBackingStore->status != StatusNoPixmap)
47866 : REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
47867 : miDestroyBSPixmap (pWin);
47873 : *-----------------------------------------------------------------------
47875 : * Destroy and free all the stuff associated with the backing-store
47876 : * for the given window.
47882 : * The backing pixmap and all the regions and GC's are destroyed.
47884 : *-----------------------------------------------------------------------
47890 : miBSWindowPtr pBackingStore;
47891 : ScreenPtr pScreen;
47893 : pScreen = pWin->drawable.pScreen;
47895 : pBackingStore = (miBSWindowPtr)pWin->backStorage;
47896 : if (pBackingStore)
47898 : miDestroyBSPixmap (pWin);
47900 : REGION_UNINIT( pScreen, &pBackingStore->SavedRegion);
47902 : xfree(pBackingStore);
47903 : pWin->backStorage = NULL;
47908 : *-----------------------------------------------------------------------
47909 : * miResizeBackingStore --
47910 : * Alter the size of the backing pixmap as necessary when the
47911 : * SavedRegion changes size. The contents of the old pixmap are
47912 : * copied/shifted into the new/same pixmap.
47915 : * The new Pixmap is created as necessary.
47918 : * The old pixmap is destroyed.
47920 : *-----------------------------------------------------------------------
47923 :miResizeBackingStore(
47925 : int dx, /* bits are moving this far */
47926 : int dy, /* bits are moving this far */
47927 : Bool saveBits) /* bits are useful */
47929 : miBSWindowPtr pBackingStore;
47930 : PixmapPtr pBackingPixmap;
47931 : ScreenPtr pScreen;
47934 : PixmapPtr pNewPixmap;
47938 : pBackingStore = (miBSWindowPtr)(pWin->backStorage);
47939 : pBackingPixmap = pBackingStore->pBackingPixmap;
47940 : if (!pBackingPixmap)
47942 : pScreen = pWin->drawable.pScreen;
47943 : extents = REGION_EXTENTS(pScreen, &pBackingStore->SavedRegion);
47944 : pNewPixmap = pBackingPixmap;
47946 : nw = extents->x2 - extents->x1;
47947 : nh = extents->y2 - extents->y1;
47949 : /* the policy here could be more sophisticated */
47950 : if (nw != pBackingPixmap->drawable.width ||
47951 : nh != pBackingPixmap->drawable.height)
47953 : if (!saveBits || !nw || !nh)
47955 : pNewPixmap = NullPixmap;
47956 : pBackingStore->status = StatusNoPixmap;
47960 : pNewPixmap = (PixmapPtr)(*pScreen->CreatePixmap)
47963 : pWin->drawable.depth);
47967 : pBackingStore->status = StatusNoPixmap;
47969 : pBackingStore->status = StatusBadAlloc;
47976 : pBackingStore->x = 0;
47977 : pBackingStore->y = 0;
47981 : nx = pBackingStore->x - extents->x1 + dx;
47982 : ny = pBackingStore->y - extents->y1 + dy;
47983 : pBackingStore->x = extents->x1;
47984 : pBackingStore->y = extents->y1;
47986 : if (saveBits && (pNewPixmap != pBackingPixmap || nx != 0 || ny != 0))
47988 : pGC = GetScratchGC(pNewPixmap->drawable.depth, pScreen);
47991 : ValidateGC((DrawablePtr)pNewPixmap, pGC);
47992 : /* if we implement a policy where the pixmap can be larger than
47993 : * the region extents, we might want to optimize this copyarea
47994 : * by only copying the old extents, rather than the entire
47997 : (*pGC->ops->CopyArea)((DrawablePtr)pBackingPixmap,
47998 : (DrawablePtr)pNewPixmap, pGC,
48000 : pBackingPixmap->drawable.width,
48001 : pBackingPixmap->drawable.height,
48003 : FreeScratchGC(pGC);
48007 : /* SavedRegion is used in the backingGC clip; force an update */
48008 : pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
48009 : if (pNewPixmap != pBackingPixmap)
48011 : (* pScreen->DestroyPixmap)(pBackingPixmap);
48012 : pBackingStore->pBackingPixmap = pNewPixmap;
48017 : *-----------------------------------------------------------------------
48018 : * miBSSaveDoomedAreas --
48019 : * Saved the areas of the given window that are about to be
48020 : * obscured. If the window has moved, pObscured is expected to
48021 : * be at the new screen location and (dx,dy) is expected to be the offset
48022 : * to the window's previous location.
48028 : * The region is copied from the screen into pBackingPixmap and
48029 : * SavedRegion is updated.
48031 : *-----------------------------------------------------------------------
48034 :miBSSaveDoomedAreas(pWin, pObscured, dx, dy)
48036 : RegionPtr pObscured;
48039 : miBSWindowPtr pBackingStore;
48040 : ScreenPtr pScreen;
48043 : pBackingStore = (miBSWindowPtr)pWin->backStorage;
48044 : pScreen = pWin->drawable.pScreen;
48047 : * If the window isn't realized, it's being unmapped, thus we don't
48048 : * want to save anything if backingStore isn't Always.
48050 : if (!pWin->realized)
48052 : pBackingStore->viewable = (char)pWin->viewable;
48053 : if (pWin->backingStore != Always)
48055 : REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
48056 : miDestroyBSPixmap (pWin);
48059 : if (pBackingStore->status == StatusBadAlloc)
48060 : pBackingStore->status = StatusNoPixmap;
48063 : /* Don't even pretend to save anything for a virtual background None */
48064 : if ((pBackingStore->status == StatusVirtual) &&
48065 : (pBackingStore->backgroundState == None))
48068 : if (REGION_NOTEMPTY(pScreen, pObscured))
48070 : BoxRec oldExtents;
48071 : x = pWin->drawable.x;
48072 : y = pWin->drawable.y;
48073 : REGION_TRANSLATE(pScreen, pObscured, -x, -y);
48074 : oldExtents = *REGION_EXTENTS(pScreen, &pBackingStore->SavedRegion);
48075 : REGION_UNION( pScreen, &pBackingStore->SavedRegion,
48076 : &pBackingStore->SavedRegion,
48079 : * only save the bits if we've actually
48080 : * started using backing store
48082 : if (pBackingStore->status != StatusVirtual)
48084 : if (!pBackingStore->pBackingPixmap)
48085 : miCreateBSPixmap (pWin, &oldExtents);
48087 : miResizeBackingStore(pWin, 0, 0, TRUE);
48089 : if (pBackingStore->pBackingPixmap) {
48090 : if (pBackingStore->x | pBackingStore->y)
48092 : REGION_TRANSLATE( pScreen, pObscured,
48093 : -pBackingStore->x,
48094 : -pBackingStore->y);
48095 : x += pBackingStore->x;
48096 : y += pBackingStore->y;
48098 : (* pScreen->BackingStoreFuncs.SaveAreas)
48099 : (pBackingStore->pBackingPixmap, pObscured,
48100 : x - dx, y - dy, pWin);
48103 : REGION_TRANSLATE(pScreen, pObscured, x, y);
48107 : if (REGION_BROKEN (pScreen, pObscured))
48109 : REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
48110 : miDestroyBSPixmap (pWin);
48117 : *-----------------------------------------------------------------------
48118 : * miBSRestoreAreas --
48119 : * Restore areas from backing-store that are no longer obscured.
48120 : * expects prgnExposed to contain a screen-relative area.
48123 : * The region to generate exposure events on (which may be
48124 : * different from the region to paint).
48127 : * Areas are copied from pBackingPixmap to the screen. prgnExposed
48128 : * is altered to contain the region that could not be restored from
48132 : * This is called before sending any exposure events to the client,
48133 : * and so might be called if the window has grown. Changing the backing
48134 : * pixmap doesn't require revalidating the backingGC because the
48135 : * client's next output request will result in a call to ValidateGC,
48136 : * since the window clip region has changed, which will in turn call
48137 : * miValidateBackingStore.
48138 : *-----------------------------------------------------------------------
48141 :miBSRestoreAreas(pWin, prgnExposed)
48143 : RegionPtr prgnExposed;
48145 : PixmapPtr pBackingPixmap;
48146 : miBSWindowPtr pBackingStore;
48147 : RegionPtr prgnSaved;
48148 : RegionPtr prgnRestored;
48149 : ScreenPtr pScreen;
48150 : RegionPtr exposures = prgnExposed;
48152 : pScreen = pWin->drawable.pScreen;
48153 : pBackingStore = (miBSWindowPtr)pWin->backStorage;
48154 : pBackingPixmap = pBackingStore->pBackingPixmap;
48156 : prgnSaved = &pBackingStore->SavedRegion;
48158 : if (pBackingStore->status == StatusContents)
48160 : REGION_TRANSLATE(pScreen, prgnSaved, pWin->drawable.x,
48161 : pWin->drawable.y);
48163 : prgnRestored = REGION_CREATE( pScreen, (BoxPtr)NULL, 1);
48164 : REGION_INTERSECT( pScreen, prgnRestored, prgnExposed, prgnSaved);
48167 : * Since prgnExposed is no longer obscured, we no longer
48168 : * will have a valid copy of it in backing-store, but there is a valid
48169 : * copy of it on screen, so subtract the area we just restored from
48170 : * from the area to be exposed.
48173 : if (REGION_NOTEMPTY( pScreen, prgnRestored))
48175 : REGION_SUBTRACT( pScreen, prgnSaved, prgnSaved, prgnExposed);
48176 : REGION_SUBTRACT( pScreen, prgnExposed, prgnExposed, prgnRestored);
48179 : * Do the actual restoration
48181 : (* pScreen->BackingStoreFuncs.RestoreAreas) (pBackingPixmap,
48183 : pWin->drawable.x + pBackingStore->x,
48184 : pWin->drawable.y + pBackingStore->y,
48187 : * if the saved region is completely empty, dispose of the
48188 : * backing pixmap, otherwise, retranslate the saved
48189 : * region to window relative
48192 : if (REGION_NOTEMPTY(pScreen, prgnSaved))
48194 : REGION_TRANSLATE(pScreen, prgnSaved,
48195 : -pWin->drawable.x,
48196 : -pWin->drawable.y);
48197 : miResizeBackingStore(pWin, 0, 0, TRUE);
48200 : miDestroyBSPixmap (pWin);
48203 : REGION_TRANSLATE(pScreen, prgnSaved,
48204 : -pWin->drawable.x, -pWin->drawable.y);
48205 : REGION_DESTROY( pScreen, prgnRestored);
48208 : else if ((pBackingStore->status == StatusVirtual) ||
48209 : (pBackingStore->status == StatusVDirty))
48211 : REGION_TRANSLATE(pScreen, prgnSaved,
48212 : pWin->drawable.x, pWin->drawable.y);
48213 : exposures = REGION_CREATE( pScreen, NullBox, 1);
48214 : if (SameBackground (pBackingStore->backgroundState,
48215 : pBackingStore->background,
48216 : pWin->backgroundState,
48217 : pWin->background))
48219 : REGION_SUBTRACT( pScreen, exposures, prgnExposed, prgnSaved);
48223 : miTileVirtualBS(pWin);
48225 : /* we need to expose all we have (virtually) retiled */
48226 : REGION_UNION( pScreen, exposures, prgnExposed, prgnSaved);
48228 : REGION_SUBTRACT( pScreen, prgnSaved, prgnSaved, prgnExposed);
48229 : REGION_TRANSLATE(pScreen, prgnSaved,
48230 : -pWin->drawable.x, -pWin->drawable.y);
48232 : else if (pWin->viewable && !pBackingStore->viewable &&
48233 : pWin->backingStore != Always)
48236 : * The window was just mapped and nothing has been saved in
48237 : * backing-store from the last time it was mapped. We want to capture
48238 : * any output to regions that are already obscured but there are no
48239 : * bits to snag off the screen, so we initialize things just as we did
48240 : * in miBSAllocate, above.
48244 : prgnSaved = &pBackingStore->SavedRegion;
48246 : box.x1 = pWin->drawable.x;
48247 : box.x2 = box.x1 + (int) pWin->drawable.width;
48248 : box.y1 = pWin->drawable.y;
48249 : box.y2 = box.y1 + (int) pWin->drawable.height;
48251 : REGION_INVERSE( pScreen, prgnSaved, &pWin->clipList, &box);
48252 : REGION_TRANSLATE( pScreen, prgnSaved,
48253 : -pWin->drawable.x,
48254 : -pWin->drawable.y);
48256 : if (wBoundingShape (pWin))
48257 : REGION_INTERSECT(pScreen, prgnSaved, prgnSaved,
48258 : wBoundingShape (pWin));
48259 : if (wClipShape (pWin))
48260 : REGION_INTERSECT(pScreen, prgnSaved, prgnSaved,
48261 : wClipShape (pWin));
48263 : miTileVirtualBS(pWin);
48265 : exposures = REGION_CREATE( pScreen, &box, 1);
48267 : pBackingStore->viewable = (char)pWin->viewable;
48268 : return exposures;
48273 : *-----------------------------------------------------------------------
48274 : * miBSTranslateBackingStore --
48275 : * Shift the backing-store in the given direction. Called when bit
48276 : * gravity is shifting things around.
48279 : * An occluded region of the window which should be sent exposure events.
48280 : * This region should be in absolute coordinates (i.e. include
48281 : * new window position).
48284 : * If the window changed size as well as position, the backing pixmap
48285 : * is resized. The contents of the backing pixmap are shifted
48288 : * Bob and I have rewritten this routine quite a few times, each
48289 : * time it gets a few more cases correct, and introducing some
48290 : * interesting bugs. Naturally, I think the code is correct this
48293 : * Let me try to explain what this routine is for:
48295 : * It's called from SlideAndSizeWindow whenever a window
48296 : * with backing store is resized. There are two separate
48299 : * a) The window has ForgetGravity
48301 : * In this case, windx, windy will be 0 and oldClip will
48302 : * be NULL. This indicates that all of the window contents
48303 : * currently saved offscreen should be discarded, and the
48304 : * entire window exposed. TranslateBackingStore, then, should
48305 : * prepare a completely new backing store region based on the
48306 : * new window clipList and return that region for exposure.
48308 : * b) The window has some other gravity
48310 : * In this case, windx, windy will be set to the distance
48311 : * that the bits should move within the window. oldClip
48312 : * will be set to the old visible portion of the window.
48313 : * TranslateBackingStore, then, should adjust the backing
48314 : * store to accommodate the portion of the existing backing
48315 : * store bits which coorespond to backing store bits which
48316 : * will still be occluded in the new configuration. oldx,oldy
48317 : * are set to the old position of the window on the screen.
48319 : * Furthermore, in this case any contents of the screen which
48320 : * are about to become occluded should be fetched from the screen
48321 : * and placed in backing store. This is to avoid the eventual
48322 : * occlusion by the win gravity shifting the child window bits around
48323 : * on top of this window, and potentially losing information
48325 : * It's also called from SetShape, but I think (he says not
48326 : * really knowing for sure) that this code will even work
48328 : *-----------------------------------------------------------------------
48332 :miBSTranslateBackingStore(pWin, windx, windy, oldClip, oldx, oldy)
48334 : int windx; /* bit translation distance in window */
48336 : RegionPtr oldClip; /* Region being copied */
48337 : int oldx; /* old window position */
48340 : miBSWindowPtr pBackingStore;
48341 : RegionPtr pSavedRegion;
48342 : RegionPtr newSaved, doomed;
48343 : ScreenPtr pScreen;
48345 : int scrdx; /* bit translation distance on screen */
48347 : int dx; /* distance window moved on screen */
48350 : pScreen = pWin->drawable.pScreen;
48351 : pBackingStore = (miBSWindowPtr)(pWin->backStorage);
48352 : if ((pBackingStore->status == StatusNoPixmap) ||
48353 : (pBackingStore->status == StatusBadAlloc))
48354 : return NullRegion;
48357 : * Compute the new saved region
48360 : newSaved = REGION_CREATE( pScreen, NullBox, 1);
48361 : extents.x1 = pWin->drawable.x;
48362 : extents.x2 = pWin->drawable.x + (int) pWin->drawable.width;
48363 : extents.y1 = pWin->drawable.y;
48364 : extents.y2 = pWin->drawable.y + (int) pWin->drawable.height;
48365 : REGION_INVERSE( pScreen, newSaved, &pWin->clipList, &extents);
48367 : REGION_TRANSLATE( pScreen, newSaved,
48368 : -pWin->drawable.x, -pWin->drawable.y);
48370 : if (wBoundingShape (pWin) || wClipShape (pWin)) {
48371 : if (wBoundingShape (pWin))
48372 : REGION_INTERSECT( pScreen, newSaved, newSaved,
48373 : wBoundingShape (pWin));
48374 : if (wClipShape (pWin))
48375 : REGION_INTERSECT( pScreen, newSaved, newSaved, wClipShape (pWin));
48379 : pSavedRegion = &pBackingStore->SavedRegion;
48381 : /* now find any visible areas we can save from the screen */
48382 : /* and then translate newSaved to old local coordinates */
48385 : /* bit gravity makes things virtually too hard, punt */
48386 : if (((windx != 0) || (windy != 0)) &&
48387 : (pBackingStore->status != StatusContents))
48388 : miCreateBSPixmap(pWin, NullBox);
48391 : * The window is moving this far on the screen
48393 : dx = pWin->drawable.x - oldx;
48394 : dy = pWin->drawable.y - oldy;
48396 : * The bits will be moving on the screen by the
48397 : * amount the window is moving + the amount the
48398 : * bits are moving within the window
48400 : scrdx = windx + dx;
48401 : scrdy = windy + dy;
48404 : * intersect at old bit position to discover the
48405 : * bits on the screen which can be put into the
48406 : * new backing store
48408 : REGION_TRANSLATE( pScreen, oldClip, windx - oldx, windy - oldy);
48409 : doomed = REGION_CREATE( pScreen, NullBox, 1);
48410 : REGION_INTERSECT( pScreen, doomed, oldClip, newSaved);
48411 : REGION_TRANSLATE( pScreen, oldClip, oldx - windx, oldy - windy);
48414 : * Translate the old saved region to the position in the
48415 : * window where it will appear to be
48417 : REGION_TRANSLATE( pScreen, pSavedRegion, windx, windy);
48420 : * Add the old saved region to the new saved region, so
48421 : * that calls to RestoreAreas will be able to fetch those
48424 : REGION_UNION( pScreen, newSaved, newSaved, pSavedRegion);
48427 : * Swap the new saved region into the window
48432 : tmp = *pSavedRegion;
48433 : *pSavedRegion = *newSaved;
48436 : miResizeBackingStore (pWin, windx, windy, TRUE);
48439 : * Compute the newly enabled region
48440 : * of backing store. This region will be
48441 : * set to background in the backing pixmap and
48442 : * sent as exposure events to the client.
48444 : REGION_SUBTRACT( pScreen, newSaved, pSavedRegion, newSaved);
48447 : * Fetch bits which will be obscured from
48450 : if (REGION_NOTEMPTY( pScreen, doomed))
48453 : * Don't clear regions which have bits on the
48456 : REGION_SUBTRACT( pScreen, newSaved, newSaved, doomed);
48459 : * Make the region to SaveDoomedAreas absolute, instead
48460 : * of window relative.
48462 : REGION_TRANSLATE( pScreen, doomed,
48463 : pWin->drawable.x, pWin->drawable.y);
48464 : (* pScreen->SaveDoomedAreas) (pWin, doomed, scrdx, scrdy);
48467 : REGION_DESTROY(pScreen, doomed);
48470 : * and clear whatever there is that's new
48472 : if (REGION_NOTEMPTY( pScreen, newSaved))
48474 : miBSClearBackingRegion (pWin, newSaved);
48476 : * Make the exposed region absolute
48478 : REGION_TRANSLATE(pScreen, newSaved,
48479 : pWin->drawable.x,
48480 : pWin->drawable.y);
48484 : REGION_DESTROY(pScreen, newSaved);
48485 : newSaved = NullRegion;
48491 : * ForgetGravity: just reset backing store and
48492 : * expose the whole mess
48494 : REGION_COPY( pScreen, pSavedRegion, newSaved);
48495 : REGION_TRANSLATE( pScreen, newSaved,
48496 : pWin->drawable.x, pWin->drawable.y);
48498 : miResizeBackingStore (pWin, 0, 0, FALSE);
48499 : (void) miBSClearBackingStore (pWin, 0, 0, 0, 0, FALSE);
48506 : * Inform the backing store layer that you are about to validate
48507 : * a gc with a window, and that subsequent output to the window
48508 : * is (or is not) guaranteed to be already clipped to the visible
48509 : * regions of the window.
48513 :miBSDrawGuarantee (pWin, pGC, guarantee)
48520 : if (pWin->backStorage)
48522 : pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
48524 : (void) miBSCreateGCPrivate (pGC);
48525 : pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
48529 : * XXX KLUDGE ALERT
48531 : * when the GC is Cheap pPriv will point
48532 : * at some device's gc func structure. guarantee
48533 : * will point at the ChangeGC entry of that struct
48534 : * and will never match a valid guarantee value.
48536 : switch (pPriv->guarantee)
48538 : case GuaranteeNothing:
48539 : case GuaranteeVisBack:
48540 : pPriv->guarantee = guarantee;
48547 :#define noBackingCopy (GCGraphicsExposures|GCClipXOrigin|GCClipYOrigin| \
48548 : GCClipMask|GCSubwindowMode| \
48549 : GCTileStipXOrigin|GCTileStipYOrigin)
48552 : *-----------------------------------------------------------------------
48553 : * miBSValidateGC --
48554 : * Wrapper around output-library's ValidateGC routine
48562 : * The idea here is to perform several functions:
48563 : * - All the output calls must be intercepted and routed to
48564 : * backing-store as necessary.
48565 : * - pGC in the window's devBackingStore must be set up with the
48566 : * clip list appropriate for writing to pBackingPixmap (i.e.
48567 : * the inverse of the window's clipList intersected with the
48568 : * clientClip of the GC). Since the destination for this GC is
48569 : * a pixmap, it is sufficient to set the clip list as its
48571 : *-----------------------------------------------------------------------
48575 :miBSValidateGC (pGC, stateChanges, pDrawable)
48577 : unsigned long stateChanges;
48578 : DrawablePtr pDrawable;
48580 : GCPtr pBackingGC;
48581 : miBSWindowPtr pWindowPriv = NULL;
48584 : int lift_functions;
48585 : RegionPtr backingCompositeClip = NULL;
48587 : if (pDrawable->type != DRAWABLE_PIXMAP)
48589 : pWin = (WindowPtr) pDrawable;
48590 : pWindowPriv = (miBSWindowPtr) pWin->backStorage;
48591 : lift_functions = (pWindowPriv == (miBSWindowPtr) NULL);
48595 : pWin = (WindowPtr) NULL;
48596 : lift_functions = TRUE;
48599 : pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
48601 : FUNC_PROLOGUE (pGC, pPriv);
48603 : (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
48606 : * rewrap funcs and ops as Validate may have changed them
48609 : pPriv->wrapFuncs = pGC->funcs;
48610 : pPriv->wrapOps = pGC->ops;
48612 : if (!lift_functions && ((pPriv->guarantee == GuaranteeVisBack) ||
48613 : (pWindowPriv->status == StatusNoPixmap) ||
48614 : (pWindowPriv->status == StatusBadAlloc)))
48615 : lift_functions = TRUE;
48618 : * check to see if a new backingCompositeClip region must
48622 : if (!lift_functions &&
48623 : ((pDrawable->serialNumber != pPriv->serialNumber) ||
48624 : (stateChanges&(GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode))))
48626 : if (REGION_NOTEMPTY(pGC->pScreen, &pWindowPriv->SavedRegion))
48628 : backingCompositeClip = REGION_CREATE(pGC->pScreen, NULL, 1);
48629 : if ((pGC->clientClipType == CT_NONE) ||
48630 : (pGC->clientClipType == CT_PIXMAP))
48632 : REGION_COPY(pGC->pScreen, backingCompositeClip,
48633 : &pWindowPriv->SavedRegion);
48638 : * Make a new copy of the client clip, translated to
48639 : * its proper origin.
48642 : REGION_COPY(pGC->pScreen, backingCompositeClip,
48643 : pGC->clientClip);
48644 : REGION_TRANSLATE(pGC->pScreen, backingCompositeClip,
48647 : REGION_INTERSECT(pGC->pScreen, backingCompositeClip,
48648 : backingCompositeClip,
48649 : &pWindowPriv->SavedRegion);
48651 : if (pGC->subWindowMode == IncludeInferiors)
48653 : RegionPtr translatedClip;
48656 : * any output in IncludeInferiors mode will not
48657 : * be redirected to Inferiors backing store. This
48658 : * can be fixed only at great cost to the shadow routines.
48660 : translatedClip = NotClippedByChildren (pWin);
48661 : REGION_TRANSLATE(pGC->pScreen, translatedClip,
48664 : REGION_SUBTRACT(pGC->pScreen, backingCompositeClip,
48665 : backingCompositeClip, translatedClip);
48666 : REGION_DESTROY(pGC->pScreen, translatedClip);
48668 : if (!REGION_NOTEMPTY(pGC->pScreen, backingCompositeClip))
48669 : lift_functions = TRUE;
48673 : lift_functions = TRUE;
48676 : /* Reset the status when drawing to an unoccluded window so that
48677 : * future SaveAreas will actually copy bits from the screen. Note that
48678 : * output to root window in IncludeInferiors mode will not cause this
48679 : * to change. This causes all transient graphics by the window
48680 : * manager to the root window to not enable backing store.
48682 : if (lift_functions && (pWindowPriv->status == StatusVirtual) &&
48683 : (pWin->parent || pGC->subWindowMode != IncludeInferiors))
48684 : pWindowPriv->status = StatusVDirty;
48688 : * if no backing store has been allocated, and it's needed,
48692 : if (!lift_functions && !pWindowPriv->pBackingPixmap)
48694 : miCreateBSPixmap (pWin, NullBox);
48695 : if (!pWindowPriv->pBackingPixmap)
48696 : lift_functions = TRUE;
48700 : * create the backing GC if needed, lift functions
48701 : * if the creation fails
48704 : if (!lift_functions && !pPriv->pBackingGC)
48707 : XID noexpose = xFalse;
48709 : /* We never want ops with the backingGC to generate GraphicsExpose */
48710 : pBackingGC = CreateGC ((DrawablePtr)pWindowPriv->pBackingPixmap,
48711 : GCGraphicsExposures, &noexpose, &status);
48712 : if (status != Success)
48713 : lift_functions = TRUE;
48715 : pPriv->pBackingGC = pBackingGC;
48718 : pBackingGC = pPriv->pBackingGC;
48720 : pPriv->stateChanges |= stateChanges;
48722 : if (lift_functions)
48724 : if (backingCompositeClip)
48725 : REGION_DESTROY( pGC->pScreen, backingCompositeClip);
48727 : /* unwrap the GC again */
48728 : miBSDestroyGCPrivate (pGC);
48734 : * the rest of this function gets the pBackingGC
48735 : * into shape for possible draws
48738 : pPriv->stateChanges &= ~noBackingCopy;
48739 : if (pPriv->stateChanges)
48740 : CopyGC(pGC, pBackingGC, pPriv->stateChanges);
48741 : if ((pGC->patOrg.x - pWindowPriv->x) != pBackingGC->patOrg.x ||
48742 : (pGC->patOrg.y - pWindowPriv->y) != pBackingGC->patOrg.y)
48745 : vals[0] = pGC->patOrg.x - pWindowPriv->x;
48746 : vals[1] = pGC->patOrg.y - pWindowPriv->y;
48747 : DoChangeGC(pBackingGC, GCTileStipXOrigin|GCTileStipYOrigin, vals, 0);
48749 : pPriv->stateChanges = 0;
48751 : if (backingCompositeClip)
48755 : if (pGC->clientClipType == CT_PIXMAP)
48757 : (*pBackingGC->funcs->CopyClip)(pBackingGC, pGC);
48758 : REGION_TRANSLATE(pGC->pScreen, backingCompositeClip,
48759 : -pGC->clipOrg.x, -pGC->clipOrg.y);
48760 : vals[0] = pGC->clipOrg.x - pWindowPriv->x;
48761 : vals[1] = pGC->clipOrg.y - pWindowPriv->y;
48762 : DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
48763 : (* pGC->pScreen->BackingStoreFuncs.SetClipmaskRgn)
48764 : (pBackingGC, backingCompositeClip);
48765 : REGION_DESTROY( pGC->pScreen, backingCompositeClip);
48769 : vals[0] = -pWindowPriv->x;
48770 : vals[1] = -pWindowPriv->y;
48771 : DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
48772 : (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, backingCompositeClip, 0);
48774 : pPriv->serialNumber = pDrawable->serialNumber;
48777 : if (pWindowPriv->pBackingPixmap->drawable.serialNumber
48778 : != pBackingGC->serialNumber)
48780 : ValidateGC((DrawablePtr)pWindowPriv->pBackingPixmap, pBackingGC);
48783 : if (pBackingGC->clientClip == 0)
48784 : ErrorF ("backing store clip list nil");
48786 : FUNC_EPILOGUE (pGC, pPriv);
48790 :miBSChangeGC (pGC, mask)
48792 : unsigned long mask;
48794 : miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
48796 : FUNC_PROLOGUE (pGC, pPriv);
48798 : (*pGC->funcs->ChangeGC) (pGC, mask);
48800 : FUNC_EPILOGUE (pGC, pPriv);
48804 :miBSCopyGC (pGCSrc, mask, pGCDst)
48805 : GCPtr pGCSrc, pGCDst;
48806 : unsigned long mask;
48808 : miBSGCPtr pPriv = (miBSGCPtr) (pGCDst)->devPrivates[miBSGCIndex].ptr;
48810 : FUNC_PROLOGUE (pGCDst, pPriv);
48812 : (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
48814 : FUNC_EPILOGUE (pGCDst, pPriv);
48818 :miBSDestroyGC (pGC)
48821 : miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
48823 : FUNC_PROLOGUE (pGC, pPriv);
48825 : if (pPriv->pBackingGC)
48826 : FreeGC(pPriv->pBackingGC, (GContext)0);
48828 : (*pGC->funcs->DestroyGC) (pGC);
48830 : FUNC_EPILOGUE (pGC, pPriv);
48836 :miBSChangeClip(pGC, type, pvalue, nrects)
48842 : miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
48844 : FUNC_PROLOGUE (pGC, pPriv);
48846 : (* pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
48848 : FUNC_EPILOGUE (pGC, pPriv);
48852 :miBSCopyClip(pgcDst, pgcSrc)
48853 : GCPtr pgcDst, pgcSrc;
48855 : miBSGCPtr pPriv = (miBSGCPtr) (pgcDst)->devPrivates[miBSGCIndex].ptr;
48857 : FUNC_PROLOGUE (pgcDst, pPriv);
48859 : (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
48861 : FUNC_EPILOGUE (pgcDst, pPriv);
48865 :miBSDestroyClip(pGC)
48868 : miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
48870 : FUNC_PROLOGUE (pGC, pPriv);
48872 : (* pGC->funcs->DestroyClip)(pGC);
48874 : FUNC_EPILOGUE (pGC, pPriv);
48878 :miDestroyBSPixmap (pWin)
48881 : miBSWindowPtr pBackingStore;
48882 : ScreenPtr pScreen;
48884 : pScreen = pWin->drawable.pScreen;
48885 : pBackingStore = (miBSWindowPtr) pWin->backStorage;
48886 : if (pBackingStore->pBackingPixmap)
48887 : (* pScreen->DestroyPixmap)(pBackingStore->pBackingPixmap);
48888 : pBackingStore->pBackingPixmap = NullPixmap;
48889 : pBackingStore->x = 0;
48890 : pBackingStore->y = 0;
48891 : if (pBackingStore->backgroundState == BackgroundPixmap)
48892 : (* pScreen->DestroyPixmap)(pBackingStore->background.pixmap);
48893 : pBackingStore->backgroundState = None;
48894 : pBackingStore->status = StatusNoPixmap;
48895 : pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
48899 :miTileVirtualBS (pWin)
48902 : miBSWindowPtr pBackingStore;
48904 : pBackingStore = (miBSWindowPtr) pWin->backStorage;
48905 : if (pBackingStore->backgroundState == BackgroundPixmap)
48906 : (* pWin->drawable.pScreen->DestroyPixmap)
48907 : (pBackingStore->background.pixmap);
48908 : pBackingStore->backgroundState = pWin->backgroundState;
48909 : pBackingStore->background = pWin->background;
48910 : if (pBackingStore->backgroundState == BackgroundPixmap)
48911 : pBackingStore->background.pixmap->refcnt++;
48913 : if (pBackingStore->status != StatusVDirty)
48914 : pBackingStore->status = StatusVirtual;
48917 : * punt parent relative tiles and do it now
48919 : if (pBackingStore->backgroundState == ParentRelative)
48920 : miCreateBSPixmap (pWin, NullBox);
48924 :static int BSAllocationsFailed = 0;
48925 :#define FAILEDSIZE 32
48926 :static struct { int w, h; } failedRecord[FAILEDSIZE];
48927 :static int failedIndex;
48931 :miCreateBSPixmap (pWin, pExtents)
48935 : miBSWindowPtr pBackingStore;
48936 : ScreenPtr pScreen;
48937 : PixUnion background;
48938 : char backgroundState = 0;
48942 : pScreen = pWin->drawable.pScreen;
48943 : pBackingStore = (miBSWindowPtr) pWin->backStorage;
48944 : if (pBackingStore->status == StatusBadAlloc)
48946 : backSet = ((pBackingStore->status == StatusVirtual) ||
48947 : (pBackingStore->status == StatusVDirty));
48949 : extents = REGION_EXTENTS( pScreen, &pBackingStore->SavedRegion);
48951 : if (!pBackingStore->pBackingPixmap &&
48952 : extents->x2 != extents->x1 &&
48953 : extents->y2 != extents->y1)
48955 : /* the policy here could be more sophisticated */
48956 : pBackingStore->x = extents->x1;
48957 : pBackingStore->y = extents->y1;
48958 : pBackingStore->pBackingPixmap =
48959 : (PixmapPtr)(* pScreen->CreatePixmap)
48961 : extents->x2 - extents->x1,
48962 : extents->y2 - extents->y1,
48963 : pWin->drawable.depth);
48965 : if (!pBackingStore->pBackingPixmap)
48968 : BSAllocationsFailed++;
48970 : * record failed allocations
48972 : failedRecord[failedIndex].w = pWin->drawable.width;
48973 : failedRecord[failedIndex].h = pWin->drawable.height;
48975 : if (failedIndex == FAILEDSIZE)
48979 : pBackingStore->status = StatusNoPixmap;
48981 : pBackingStore->status = StatusBadAlloc;
48986 : pBackingStore->status = StatusContents;
48990 : backgroundState = pWin->backgroundState;
48991 : background = pWin->background;
48993 : pWin->backgroundState = pBackingStore->backgroundState;
48994 : pWin->background = pBackingStore->background;
48995 : if (pWin->backgroundState == BackgroundPixmap)
48996 : pWin->background.pixmap->refcnt++;
49000 : pExtents = extents;
49002 : if (pExtents->y1 != pExtents->y2)
49004 : RegionPtr exposed;
49006 : exposed = miBSClearBackingStore(pWin,
49007 : pExtents->x1, pExtents->y1,
49008 : pExtents->x2 - pExtents->x1,
49009 : pExtents->y2 - pExtents->y1,
49013 : miSendExposures(pWin, exposed, pWin->drawable.x, pWin->drawable.y);
49014 : REGION_DESTROY( pScreen, exposed);
49020 : if (pWin->backgroundState == BackgroundPixmap)
49021 : (* pScreen->DestroyPixmap) (pWin->background.pixmap);
49022 : pWin->backgroundState = backgroundState;
49023 : pWin->background = background;
49024 : if (pBackingStore->backgroundState == BackgroundPixmap)
49025 : (* pScreen->DestroyPixmap) (pBackingStore->background.pixmap);
49026 : pBackingStore->backgroundState = None;
49031 : *-----------------------------------------------------------------------
49032 : * miBSExposeCopy --
49033 : * Handle the restoration of areas exposed by graphics operations.
49039 : * prgnExposed has the areas exposed from backing-store removed
49042 : *-----------------------------------------------------------------------
49045 :miBSExposeCopy (pSrc, pDst, pGC, prgnExposed, srcx, srcy, dstx, dsty, plane)
49047 : DrawablePtr pDst;
49049 : RegionPtr prgnExposed;
49052 : unsigned long plane;
49054 : RegionRec tempRgn;
49055 : miBSWindowPtr pBackingStore;
49056 : CopyPlaneProcPtr copyProc;
49057 : GCPtr pScratchGC;
49063 : if (!REGION_NOTEMPTY(pGC->pScreen, prgnExposed))
49065 : pBackingStore = (miBSWindowPtr)pSrc->backStorage;
49067 : if ((pBackingStore->status == StatusNoPixmap) ||
49068 : (pBackingStore->status == StatusBadAlloc))
49071 : REGION_NULL( pGC->pScreen, &tempRgn);
49072 : REGION_INTERSECT( pGC->pScreen, &tempRgn, prgnExposed,
49073 : &pBackingStore->SavedRegion);
49074 : REGION_SUBTRACT( pGC->pScreen, prgnExposed, prgnExposed, &tempRgn);
49076 : if (plane != 0) {
49077 : copyProc = pGC->ops->CopyPlane;
49079 : copyProc = (CopyPlaneProcPtr)pGC->ops->CopyArea;
49082 : dx = dstx - srcx;
49083 : dy = dsty - srcy;
49085 : switch (pBackingStore->status) {
49086 : case StatusVirtual:
49087 : case StatusVDirty:
49088 : pScratchGC = GetScratchGC (pDst->depth, pDst->pScreen);
49092 : if (pGC->alu != pScratchGC->alu)
49093 : gcMask = GCFunction;
49094 : if (pGC->planemask != pScratchGC->planemask)
49095 : gcMask |= GCPlaneMask;
49097 : CopyGC (pGC, pScratchGC, gcMask);
49098 : miBSFillVirtualBits (pDst, pScratchGC, &tempRgn, dx, dy,
49099 : (int) pBackingStore->backgroundState,
49100 : pBackingStore->background,
49102 : FreeScratchGC (pScratchGC);
49105 : case StatusContents:
49106 : for (i = REGION_NUM_RECTS(&tempRgn), pBox = REGION_RECTS(&tempRgn);
49110 : (* copyProc) (&(pBackingStore->pBackingPixmap->drawable), pDst, pGC,
49111 : pBox->x1 - pBackingStore->x,
49112 : pBox->y1 - pBackingStore->y,
49113 : pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
49114 : pBox->x1 + dx, pBox->y1 + dy, plane);
49118 : REGION_UNINIT( pGC->pScreen, &tempRgn);
49121 * Total samples for file : "/home/cworth/src/xorg/xserver/dix/devices.c"
49127 :/************************************************************
49129 :Copyright 1987, 1998 The Open Group
49131 :Permission to use, copy, modify, distribute, and sell this software and its
49132 :documentation for any purpose is hereby granted without fee, provided that
49133 :the above copyright notice appear in all copies and that both that
49134 :copyright notice and this permission notice appear in supporting
49137 :The above copyright notice and this permission notice shall be included in
49138 :all copies or substantial portions of the Software.
49140 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49141 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49142 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49143 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
49144 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49145 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
49147 :Except as contained in this notice, the name of The Open Group shall not be
49148 :used in advertising or otherwise to promote the sale, use or other dealings
49149 :in this Software without prior written authorization from The Open Group.
49152 :Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
49154 : All Rights Reserved
49156 :Permission to use, copy, modify, and distribute this software and its
49157 :documentation for any purpose and without fee is hereby granted,
49158 :provided that the above copyright notice appear in all copies and that
49159 :both that copyright notice and this permission notice appear in
49160 :supporting documentation, and that the name of Digital not be
49161 :used in advertising or publicity pertaining to distribution of the
49162 :software without specific, written prior permission.
49164 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
49165 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
49166 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
49167 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
49168 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
49169 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49172 :********************************************************/
49176 :#ifdef HAVE_DIX_CONFIG_H
49177 :#include <dix-config.h>
49180 :#include <X11/X.h>
49182 :#include "resource.h"
49183 :#define NEED_EVENTS
49184 :#define NEED_REPLIES
49185 :#include <X11/Xproto.h>
49186 :#include "windowstr.h"
49187 :#include "inputstr.h"
49188 :#include "scrnintstr.h"
49189 :#include "cursorstr.h"
49190 :#include "dixstruct.h"
49192 :#ifndef XKB_IN_SERVER
49193 :#define XKB_IN_SERVER
49196 :#include <xkbsrv.h>
49200 :#include "dispatch.h"
49201 :#include "swaprep.h"
49202 :#include "dixevents.h"
49204 :#include <X11/extensions/XI.h>
49205 :#include <X11/extensions/XIproto.h>
49206 :#include "exglobals.h"
49207 :#include "exevents.h"
49210 : * This file handles input device-related stuff.
49213 :int CoreDevicePrivatesIndex = 0;
49214 :static int CoreDevicePrivatesGeneration = -1;
49217 : * Create a new input device and init it to sane values. The device is added
49218 : * to the server's off_devices list.
49220 : * @param deviceProc Callback for device control function (switch dev on/off).
49221 : * @return The newly created device.
49224 :AddInputDevice(DeviceProc deviceProc, Bool autoStart)
49226 : DeviceIntPtr dev, *prev; /* not a typo */
49227 : DeviceIntPtr devtmp;
49229 : char devind[MAX_DEVICES];
49231 : /* Find next available id */
49232 : memset(devind, 0, sizeof(char)*MAX_DEVICES);
49233 : for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
49234 : devind[devtmp->id]++;
49235 : for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
49236 : devind[devtmp->id]++;
49237 : for (devid = 0; devid < MAX_DEVICES && devind[devid]; devid++)
49240 : if (devid >= MAX_DEVICES)
49241 : return (DeviceIntPtr)NULL;
49242 : dev = (DeviceIntPtr) xcalloc(sizeof(DeviceIntRec), 1);
49244 : return (DeviceIntPtr)NULL;
49245 : dev->name = (char *)NULL;
49248 : inputInfo.numDevices++;
49249 : dev->public.on = FALSE;
49250 : dev->public.processInputProc = (ProcessInputProc)NoopDDA;
49251 : dev->public.realInputProc = (ProcessInputProc)NoopDDA;
49252 : dev->public.enqueueInputProc = EnqueueEvent;
49253 : dev->deviceProc = deviceProc;
49254 : dev->startup = autoStart;
49255 : dev->sync.frozen = FALSE;
49256 : dev->sync.other = NullGrab;
49257 : dev->sync.state = NOT_GRABBED;
49258 : dev->sync.event = (xEvent *) NULL;
49259 : dev->sync.evcount = 0;
49260 : dev->grab = NullGrab;
49261 : dev->grabTime = currentTime;
49262 : dev->fromPassiveGrab = FALSE;
49263 : dev->key = (KeyClassPtr)NULL;
49264 : dev->valuator = (ValuatorClassPtr)NULL;
49265 : dev->button = (ButtonClassPtr)NULL;
49266 : dev->focus = (FocusClassPtr)NULL;
49267 : dev->proximity = (ProximityClassPtr)NULL;
49268 : dev->absolute = (AbsoluteClassPtr)NULL;
49269 : dev->kbdfeed = (KbdFeedbackPtr)NULL;
49270 : dev->ptrfeed = (PtrFeedbackPtr)NULL;
49271 : dev->intfeed = (IntegerFeedbackPtr)NULL;
49272 : dev->stringfeed = (StringFeedbackPtr)NULL;
49273 : dev->bell = (BellFeedbackPtr)NULL;
49274 : dev->leds = (LedFeedbackPtr)NULL;
49276 : dev->xkb_interest = NULL;
49278 : dev->nPrivates = 0;
49279 : dev->devPrivates = NULL;
49280 : dev->unwrapProc = NULL;
49281 : dev->coreEvents = TRUE;
49282 : dev->inited = FALSE;
49283 : dev->enabled = FALSE;
49285 : for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next)
49288 : dev->next = NULL;
49294 : * Switch device ON through the driver and push it onto the global device
49295 : * list. All clients are notified about the device being enabled.
49297 : * A device will send events once enabled.
49299 : * @param The device to be enabled.
49300 : * @return TRUE on success or FALSE otherwise.
49303 :EnableDevice(DeviceIntPtr dev)
49305 : DeviceIntPtr *prev;
49307 : DeviceIntRec dummyDev;
49308 : devicePresenceNotify ev;
49310 : for (prev = &inputInfo.off_devices;
49311 : *prev && (*prev != dev);
49312 : prev = &(*prev)->next)
49314 : if ((*prev != dev) || !dev->inited ||
49315 : ((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
49316 : ErrorF("couldn't enable device %d\n", dev->id);
49319 : dev->enabled = TRUE;
49320 : *prev = dev->next;
49322 : for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
49325 : dev->next = NULL;
49327 : ev.type = DevicePresenceNotify;
49328 : ev.time = currentTime.milliseconds;
49329 : ev.devchange = DeviceEnabled;
49330 : ev.deviceid = dev->id;
49332 : SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
49333 : (xEvent *) &ev, 1);
49339 : * Switch a device off through the driver and push it onto the off_devices
49340 : * list. A device will not send events while disabled. All clients are
49341 : * notified about the device being disabled.
49343 : * @return TRUE on success or FALSE otherwise.
49346 :DisableDevice(DeviceIntPtr dev)
49348 : DeviceIntPtr *prev;
49349 : DeviceIntRec dummyDev;
49350 : devicePresenceNotify ev;
49352 : for (prev = &inputInfo.devices;
49353 : *prev && (*prev != dev);
49354 : prev = &(*prev)->next)
49356 : if (*prev != dev)
49358 : (void)(*dev->deviceProc)(dev, DEVICE_OFF);
49359 : dev->enabled = FALSE;
49360 : *prev = dev->next;
49361 : dev->next = inputInfo.off_devices;
49362 : inputInfo.off_devices = dev;
49364 : ev.type = DevicePresenceNotify;
49365 : ev.time = currentTime.milliseconds;
49366 : ev.devchange = DeviceDisabled;
49367 : ev.deviceid = dev->id;
49369 : SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
49370 : (xEvent *) &ev, 1);
49376 : * Initialise a new device through the driver and tell all clients about the
49379 : * The device will NOT send events until it is enabled!
49381 : * @return Success or an error code on failure.
49384 :ActivateDevice(DeviceIntPtr dev)
49386 : int ret = Success;
49387 : devicePresenceNotify ev;
49388 : DeviceIntRec dummyDev;
49390 : if (!dev || !dev->deviceProc)
49391 : return BadImplementation;
49393 : ret = (*dev->deviceProc) (dev, DEVICE_INIT);
49394 : dev->inited = (ret == Success);
49396 : ev.type = DevicePresenceNotify;
49397 : ev.time = currentTime.milliseconds;
49398 : ev.devchange = DeviceAdded;
49399 : ev.deviceid = dev->id;
49401 : SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
49402 : (xEvent *) &ev, 1);
49409 : * The actual task of ringing the bell is the job of the DDX.
49412 :CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
49414 : KeybdCtrl *ctrl = arg;
49416 : DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
49420 :CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
49426 : * Device control function for the Virtual Core Keyboard.
49429 :CoreKeyboardProc(DeviceIntPtr pDev, int what)
49432 : KeySymsRec keySyms;
49434 : XkbComponentNamesRec names;
49438 : case DEVICE_INIT:
49439 : keySyms.minKeyCode = 8;
49440 : keySyms.maxKeyCode = 255;
49441 : keySyms.mapWidth = 4;
49442 : keySyms.map = (KeySym *)xcalloc(sizeof(KeySym),
49443 : (keySyms.maxKeyCode -
49444 : keySyms.minKeyCode + 1) *
49445 : keySyms.mapWidth);
49446 : if (!keySyms.map) {
49447 : ErrorF("Couldn't allocate core keymap\n");
49451 : modMap = (CARD8 *)xalloc(MAP_LENGTH);
49453 : ErrorF("Couldn't allocate core modifier map\n");
49456 : bzero((char *)modMap, MAP_LENGTH);
49459 : if (!noXkbExtension) {
49460 : bzero(&names, sizeof(names));
49461 : XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
49462 : XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modMap,
49463 : CoreKeyboardBell, CoreKeyboardCtl);
49468 : /* FIXME Our keymap here isn't exactly useful. */
49469 : InitKeyboardDeviceStruct((DevicePtr)pDev, &keySyms, modMap,
49470 : CoreKeyboardBell, CoreKeyboardCtl);
49473 : xfree(keySyms.map);
49478 : case DEVICE_CLOSE:
49479 : pDev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
49489 : * Device control function for the Virtual Core Pointer.
49492 :CorePointerProc(DeviceIntPtr pDev, int what)
49498 : case DEVICE_INIT:
49499 : for (i = 1; i <= 32; i++)
49501 : InitPointerDeviceStruct((DevicePtr)pDev, map, 32,
49502 : GetMotionHistory, (PtrCtrlProcPtr)NoopDDA,
49503 : GetMotionHistorySize(), 2);
49504 : pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
49505 : pDev->valuator->lastx = pDev->valuator->axisVal[0];
49506 : pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
49507 : pDev->valuator->lasty = pDev->valuator->axisVal[1];
49510 : case DEVICE_CLOSE:
49511 : pDev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
49522 : * Initialise the two core devices, VCP and VCK (see events.c).
49523 : * The devices are activated but not enabled.
49524 : * Note that the server MUST have two core devices at all times, even if there
49525 : * is no physical device connected.
49528 :InitCoreDevices(void)
49530 : DeviceIntPtr dev;
49532 : if (CoreDevicePrivatesGeneration != serverGeneration) {
49533 : CoreDevicePrivatesIndex = AllocateDevicePrivateIndex();
49534 : CoreDevicePrivatesGeneration = serverGeneration;
49537 : if (!inputInfo.keyboard) {
49538 : dev = AddInputDevice(CoreKeyboardProc, TRUE);
49540 : FatalError("Failed to allocate core keyboard");
49541 : dev->name = strdup("Virtual core keyboard");
49543 : dev->public.processInputProc = CoreProcessKeyboardEvent;
49544 : dev->public.realInputProc = CoreProcessKeyboardEvent;
49545 : if (!noXkbExtension)
49546 : XkbSetExtension(dev, ProcessKeyboardEvent);
49548 : dev->public.processInputProc = ProcessKeyboardEvent;
49549 : dev->public.realInputProc = ProcessKeyboardEvent;
49551 : dev->ActivateGrab = ActivateKeyboardGrab;
49552 : dev->DeactivateGrab = DeactivateKeyboardGrab;
49553 : dev->coreEvents = FALSE;
49554 : if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex))
49555 : FatalError("Couldn't allocate keyboard devPrivates\n");
49556 : dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
49557 : (void)ActivateDevice(dev);
49558 : inputInfo.keyboard = dev;
49561 : if (!inputInfo.pointer) {
49562 : dev = AddInputDevice(CorePointerProc, TRUE);
49564 : FatalError("Failed to allocate core pointer");
49565 : dev->name = strdup("Virtual core pointer");
49567 : dev->public.processInputProc = CoreProcessPointerEvent;
49568 : dev->public.realInputProc = CoreProcessPointerEvent;
49569 : if (!noXkbExtension)
49570 : XkbSetExtension(dev, ProcessPointerEvent);
49572 : dev->public.processInputProc = ProcessPointerEvent;
49573 : dev->public.realInputProc = ProcessPointerEvent;
49575 : dev->ActivateGrab = ActivatePointerGrab;
49576 : dev->DeactivateGrab = DeactivatePointerGrab;
49577 : dev->coreEvents = FALSE;
49578 : if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex))
49579 : FatalError("Couldn't allocate pointer devPrivates\n");
49580 : dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
49581 : (void)ActivateDevice(dev);
49582 : inputInfo.pointer = dev;
49587 : * Activate all switched-off devices and then enable all those devices.
49589 : * Will return an error if no core keyboard or core pointer is present.
49590 : * In theory this should never happen if you call InitCoreDevices() first.
49592 : * @return Success or error code on failure.
49595 :InitAndStartDevices(void)
49597 : DeviceIntPtr dev, next;
49599 : for (dev = inputInfo.off_devices; dev; dev = dev->next) {
49600 : DebugF("(dix) initialising device %d\n", dev->id);
49601 : ActivateDevice(dev);
49603 : for (dev = inputInfo.off_devices; dev; dev = next)
49605 : DebugF("(dix) enabling device %d\n", dev->id);
49606 : next = dev->next;
49607 : if (dev->inited && dev->startup)
49608 : (void)EnableDevice(dev);
49610 : for (dev = inputInfo.devices;
49611 : dev && (dev != inputInfo.keyboard);
49614 : if (!dev || (dev != inputInfo.keyboard)) {
49615 : ErrorF("No core keyboard\n");
49616 : return BadImplementation;
49618 : for (dev = inputInfo.devices;
49619 : dev && (dev != inputInfo.pointer);
49622 : if (!dev || (dev != inputInfo.pointer)) {
49623 : ErrorF("No core pointer\n");
49624 : return BadImplementation;
49630 : * Close down a device and free all resources.
49631 : * Once closed down, the driver will probably not expect you that you'll ever
49632 : * enable it again and free associated structs. If you want the device to just
49633 : * be disabled, DisableDevice().
49634 : * Don't call this function directly, use RemoveDevice() instead.
49637 :CloseDevice(DeviceIntPtr dev)
49639 : KbdFeedbackPtr k, knext;
49640 : PtrFeedbackPtr p, pnext;
49641 : IntegerFeedbackPtr i, inext;
49642 : StringFeedbackPtr s, snext;
49643 : BellFeedbackPtr b, bnext;
49644 : LedFeedbackPtr l, lnext;
49647 : (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
49649 : xfree(dev->name);
49653 : if (dev->key->xkbInfo)
49654 : XkbFreeInfo(dev->key->xkbInfo);
49656 : xfree(dev->key->curKeySyms.map);
49657 : xfree(dev->key->modifierKeyMap);
49661 : if (dev->valuator) {
49662 : /* Counterpart to 'biggest hack ever' in init. */
49663 : if (dev->valuator->motion &&
49664 : dev->valuator->GetMotionProc == GetMotionHistory)
49665 : xfree(dev->valuator->motion);
49666 : xfree(dev->valuator);
49669 : if (dev->button) {
49671 : if (dev->button->xkb_acts)
49672 : xfree(dev->button->xkb_acts);
49674 : xfree(dev->button);
49677 : if (dev->focus) {
49678 : xfree(dev->focus->trace);
49679 : xfree(dev->focus);
49682 : if (dev->proximity)
49683 : xfree(dev->proximity);
49685 : for (k = dev->kbdfeed; k; k = knext) {
49689 : XkbFreeSrvLedInfo(k->xkb_sli);
49694 : for (p = dev->ptrfeed; p; p = pnext) {
49699 : for (i = dev->intfeed; i; i = inext) {
49704 : for (s = dev->stringfeed; s; s = snext) {
49706 : xfree(s->ctrl.symbols_supported);
49707 : xfree(s->ctrl.symbols_displayed);
49711 : for (b = dev->bell; b; b = bnext) {
49716 : for (l = dev->leds; l; l = lnext) {
49720 : XkbFreeSrvLedInfo(l->xkb_sli);
49726 : while (dev->xkb_interest)
49727 : XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
49730 : if (dev->devPrivates)
49731 : xfree(dev->devPrivates);
49733 : xfree(dev->sync.event);
49738 : * Shut down all devices, free all resources, etc.
49739 : * Only useful if you're shutting down the server!
49742 :CloseDownDevices(void)
49744 : DeviceIntPtr dev, next;
49746 : for (dev = inputInfo.devices; dev; dev = next)
49748 : next = dev->next;
49749 : CloseDevice(dev);
49751 : for (dev = inputInfo.off_devices; dev; dev = next)
49753 : next = dev->next;
49754 : CloseDevice(dev);
49756 : inputInfo.devices = NULL;
49757 : inputInfo.off_devices = NULL;
49758 : inputInfo.keyboard = NULL;
49759 : inputInfo.pointer = NULL;
49763 : * Remove a device from the device list, closes it and thus frees all
49765 : * Removes both enabled and disabled devices and notifies all devices about
49766 : * the removal of the device.
49769 :RemoveDevice(DeviceIntPtr dev)
49771 : DeviceIntPtr prev,tmp,next;
49772 : int ret = BadMatch;
49773 : devicePresenceNotify ev;
49774 : DeviceIntRec dummyDev;
49777 : DebugF("(dix) removing device %d\n", dev->id);
49779 : if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
49780 : return BadImplementation;
49782 : deviceid = dev->id;
49783 : DisableDevice(dev);
49786 : for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
49787 : next = tmp->next;
49788 : if (tmp == dev) {
49789 : CloseDevice(tmp);
49792 : inputInfo.devices = next;
49794 : prev->next = next;
49801 : for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
49802 : next = tmp->next;
49803 : if (tmp == dev) {
49804 : CloseDevice(tmp);
49806 : if (prev == NULL)
49807 : inputInfo.off_devices = next;
49809 : prev->next = next;
49815 : if (ret == Success) {
49816 : inputInfo.numDevices--;
49817 : ev.type = DevicePresenceNotify;
49818 : ev.time = currentTime.milliseconds;
49819 : ev.devchange = DeviceRemoved;
49820 : ev.deviceid = deviceid;
49822 : SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
49823 : (xEvent *) &ev, 1);
49830 :NumMotionEvents(void)
49832 : return inputInfo.pointer->valuator->numMotionEvents;
49836 :RegisterPointerDevice(DeviceIntPtr device)
49838 : RegisterOtherDevice(device);
49842 :RegisterKeyboardDevice(DeviceIntPtr device)
49844 : RegisterOtherDevice(device);
49847 :_X_EXPORT DevicePtr
49848 :LookupKeyboardDevice(void)
49850 : return inputInfo.keyboard ? &inputInfo.keyboard->public : NULL;
49853 :_X_EXPORT DevicePtr
49854 :LookupPointerDevice(void)
49856 : return inputInfo.pointer ? &inputInfo.pointer->public : NULL;
49860 :LookupDevice(int id)
49862 : DeviceIntPtr dev;
49864 : for (dev=inputInfo.devices; dev; dev=dev->next) {
49865 : if (dev->id == (CARD8)id)
49866 : return (DevicePtr)dev;
49868 : for (dev=inputInfo.off_devices; dev; dev=dev->next) {
49869 : if (dev->id == (CARD8)id)
49870 : return (DevicePtr)dev;
49876 :QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
49878 : if (inputInfo.keyboard) {
49879 : *minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode;
49880 : *maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode;
49885 :SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
49888 : int rowDif = src->minKeyCode - dst->minKeyCode;
49890 : /* if keysym map size changes, grow map first */
49891 : if (src->mapWidth < dst->mapWidth)
49893 : for (i = src->minKeyCode; i <= src->maxKeyCode; i++)
49895 :#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c))
49896 :#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c))
49897 : for (j = 0; j < src->mapWidth; j++)
49898 : dst->map[DI(i, j)] = src->map[SI(i, j)];
49899 : for (j = src->mapWidth; j < dst->mapWidth; j++)
49900 : dst->map[DI(i, j)] = NoSymbol;
49906 : else if (src->mapWidth > dst->mapWidth)
49909 : int bytes = sizeof(KeySym) * src->mapWidth *
49910 : (dst->maxKeyCode - dst->minKeyCode + 1);
49911 : map = (KeySym *)xalloc(bytes);
49914 : bzero((char *)map, bytes);
49917 : for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
49918 : memmove((char *)&map[i*src->mapWidth],
49919 : (char *)&dst->map[i*dst->mapWidth],
49920 : dst->mapWidth * sizeof(KeySym));
49923 : dst->mapWidth = src->mapWidth;
49926 : memmove((char *)&dst->map[rowDif * dst->mapWidth],
49927 : (char *)src->map,
49928 : (int)(src->maxKeyCode - src->minKeyCode + 1) *
49929 : dst->mapWidth * sizeof(KeySym));
49934 :InitModMap(KeyClassPtr keyc)
49937 : CARD8 keysPerModifier[8];
49940 : keyc->maxKeysPerModifier = 0;
49941 : for (i = 0; i < 8; i++)
49942 : keysPerModifier[i] = 0;
49943 : for (i = 8; i < MAP_LENGTH; i++)
49945 : for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
49947 : if (mask & keyc->modifierMap[i])
49949 : if (++keysPerModifier[j] > keyc->maxKeysPerModifier)
49950 : keyc->maxKeysPerModifier = keysPerModifier[j];
49954 : keyc->modifierKeyMap = (KeyCode *)xalloc(8*keyc->maxKeysPerModifier);
49955 : if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier)
49957 : bzero((char *)keyc->modifierKeyMap, 8*(int)keyc->maxKeysPerModifier);
49958 : for (i = 0; i < 8; i++)
49959 : keysPerModifier[i] = 0;
49960 : for (i = 8; i < MAP_LENGTH; i++)
49962 : for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
49964 : if (mask & keyc->modifierMap[i])
49966 : keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) +
49967 : keysPerModifier[j]] = i;
49968 : keysPerModifier[j]++;
49976 :InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[])
49979 : KeyClassPtr keyc;
49981 : keyc = (KeyClassPtr)xalloc(sizeof(KeyClassRec));
49984 : keyc->curKeySyms.map = (KeySym *)NULL;
49985 : keyc->curKeySyms.mapWidth = 0;
49986 : keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode;
49987 : keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode;
49988 : keyc->modifierKeyMap = (KeyCode *)NULL;
49990 : keyc->prev_state = 0;
49992 : memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH);
49994 : bzero((char *)keyc->modifierMap, MAP_LENGTH);
49995 : bzero((char *)keyc->down, DOWN_LENGTH);
49996 : for (i = 0; i < 8; i++)
49997 : keyc->modifierKeyCount[i] = 0;
49998 : if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
50000 : xfree(keyc->curKeySyms.map);
50001 : xfree(keyc->modifierKeyMap);
50007 : dev->key->xkbInfo= NULL;
50008 : if (!noXkbExtension) XkbInitDevice(dev);
50014 :InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons,
50017 : ButtonClassPtr butc;
50020 : butc = (ButtonClassPtr)xalloc(sizeof(ButtonClassRec));
50023 : butc->numButtons = numButtons;
50024 : for (i = 1; i <= numButtons; i++)
50025 : butc->map[i] = map[i];
50026 : butc->buttonsDown = 0;
50028 : butc->motionMask = 0;
50029 : bzero((char *)butc->down, DOWN_LENGTH);
50031 : butc->xkb_acts= NULL;
50033 : dev->button = butc;
50038 :InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
50039 : ValuatorMotionProcPtr motionProc,
50040 : int numMotionEvents, int mode)
50043 : ValuatorClassPtr valc;
50048 : valc = (ValuatorClassPtr)xalloc(sizeof(ValuatorClassRec) +
50049 : numAxes * sizeof(AxisInfo) +
50050 : numAxes * sizeof(unsigned int));
50054 : valc->motion = NULL;
50055 : valc->first_motion = 0;
50056 : valc->last_motion = 0;
50057 : valc->GetMotionProc = motionProc;
50059 : valc->numMotionEvents = numMotionEvents;
50060 : valc->motionHintWindow = NullWindow;
50061 : valc->numAxes = numAxes;
50062 : valc->mode = mode;
50063 : valc->axes = (AxisInfoPtr)(valc + 1);
50064 : valc->axisVal = (int *)(valc->axes + numAxes);
50067 : valc->dxremaind = 0;
50068 : valc->dyremaind = 0;
50069 : dev->valuator = valc;
50071 : /* biggest hack ever. */
50072 : if (motionProc == GetMotionHistory)
50073 : AllocateMotionHistory(dev);
50075 : for (i=0; i<numAxes; i++) {
50076 : InitValuatorAxisStruct(dev, i, 0, -1, 0, 0, 0);
50077 : valc->axisVal[i]=0;
50083 :InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
50085 : AbsoluteClassPtr abs;
50087 : abs = (AbsoluteClassPtr)xalloc(sizeof(AbsoluteClassRec));
50091 : /* we don't do anything sensible with these, but should */
50098 : abs->rotation = 0;
50099 : abs->button_threshold = 0;
50101 : abs->offset_x = 0;
50102 : abs->offset_y = 0;
50104 : abs->height = -1;
50105 : abs->following = 0;
50108 : dev->absolute = abs;
50114 :InitFocusClassDeviceStruct(DeviceIntPtr dev)
50116 : FocusClassPtr focc;
50118 : focc = (FocusClassPtr)xalloc(sizeof(FocusClassRec));
50121 : focc->win = PointerRootWin;
50122 : focc->revert = None;
50123 : focc->time = currentTime;
50124 : focc->trace = (WindowPtr *)NULL;
50125 : focc->traceSize = 0;
50126 : focc->traceGood = 0;
50127 : dev->focus = focc;
50132 :InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
50133 : KbdCtrlProcPtr controlProc)
50135 : KbdFeedbackPtr feedc;
50137 : feedc = (KbdFeedbackPtr)xalloc(sizeof(KbdFeedbackClassRec));
50140 : feedc->BellProc = bellProc;
50141 : feedc->CtrlProc = controlProc;
50143 : defaultKeyboardControl.autoRepeat = TRUE;
50145 : feedc->ctrl = defaultKeyboardControl;
50146 : feedc->ctrl.id = 0;
50147 : if ((feedc->next = dev->kbdfeed) != 0)
50148 : feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1;
50149 : dev->kbdfeed = feedc;
50151 : feedc->xkb_sli= NULL;
50152 : if (!noXkbExtension)
50153 : XkbFinishDeviceInit(dev);
50155 : (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
50160 :InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
50162 : PtrFeedbackPtr feedc;
50164 : feedc = (PtrFeedbackPtr)xalloc(sizeof(PtrFeedbackClassRec));
50167 : feedc->CtrlProc = controlProc;
50168 : feedc->ctrl = defaultPointerControl;
50169 : feedc->ctrl.id = 0;
50170 : if ( (feedc->next = dev->ptrfeed) )
50171 : feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
50172 : dev->ptrfeed = feedc;
50173 : (*controlProc)(dev, &feedc->ctrl);
50178 :static LedCtrl defaultLedControl = {
50179 : DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
50181 :static BellCtrl defaultBellControl = {
50183 : DEFAULT_BELL_PITCH,
50184 : DEFAULT_BELL_DURATION,
50187 :static IntegerCtrl defaultIntegerControl = {
50188 : DEFAULT_INT_RESOLUTION,
50189 : DEFAULT_INT_MIN_VALUE,
50190 : DEFAULT_INT_MAX_VALUE,
50191 : DEFAULT_INT_DISPLAYED,
50195 :InitStringFeedbackClassDeviceStruct (
50196 : DeviceIntPtr dev, StringCtrlProcPtr controlProc,
50197 : int max_symbols, int num_symbols_supported, KeySym *symbols)
50200 : StringFeedbackPtr feedc;
50202 : feedc = (StringFeedbackPtr)xalloc(sizeof(StringFeedbackClassRec));
50205 : feedc->CtrlProc = controlProc;
50206 : feedc->ctrl.num_symbols_supported = num_symbols_supported;
50207 : feedc->ctrl.num_symbols_displayed = 0;
50208 : feedc->ctrl.max_symbols = max_symbols;
50209 : feedc->ctrl.symbols_supported = (KeySym *)
50210 : xalloc (sizeof (KeySym) * num_symbols_supported);
50211 : feedc->ctrl.symbols_displayed = (KeySym *)
50212 : xalloc (sizeof (KeySym) * max_symbols);
50213 : if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
50215 : if (feedc->ctrl.symbols_supported)
50216 : xfree(feedc->ctrl.symbols_supported);
50217 : if (feedc->ctrl.symbols_displayed)
50218 : xfree(feedc->ctrl.symbols_displayed);
50222 : for (i=0; i<num_symbols_supported; i++)
50223 : *(feedc->ctrl.symbols_supported+i) = *symbols++;
50224 : for (i=0; i<max_symbols; i++)
50225 : *(feedc->ctrl.symbols_displayed+i) = (KeySym) NULL;
50226 : feedc->ctrl.id = 0;
50227 : if ( (feedc->next = dev->stringfeed) )
50228 : feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
50229 : dev->stringfeed = feedc;
50230 : (*controlProc)(dev, &feedc->ctrl);
50235 :InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
50236 : BellCtrlProcPtr controlProc)
50238 : BellFeedbackPtr feedc;
50240 : feedc = (BellFeedbackPtr)xalloc(sizeof(BellFeedbackClassRec));
50243 : feedc->CtrlProc = controlProc;
50244 : feedc->BellProc = bellProc;
50245 : feedc->ctrl = defaultBellControl;
50246 : feedc->ctrl.id = 0;
50247 : if ( (feedc->next = dev->bell) )
50248 : feedc->ctrl.id = dev->bell->ctrl.id + 1;
50249 : dev->bell = feedc;
50250 : (*controlProc)(dev, &feedc->ctrl);
50255 :InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
50257 : LedFeedbackPtr feedc;
50259 : feedc = (LedFeedbackPtr)xalloc(sizeof(LedFeedbackClassRec));
50262 : feedc->CtrlProc = controlProc;
50263 : feedc->ctrl = defaultLedControl;
50264 : feedc->ctrl.id = 0;
50265 : if ( (feedc->next = dev->leds) )
50266 : feedc->ctrl.id = dev->leds->ctrl.id + 1;
50268 : feedc->xkb_sli= NULL;
50270 : dev->leds = feedc;
50271 : (*controlProc)(dev, &feedc->ctrl);
50276 :InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
50278 : IntegerFeedbackPtr feedc;
50280 : feedc = (IntegerFeedbackPtr)xalloc(sizeof(IntegerFeedbackClassRec));
50283 : feedc->CtrlProc = controlProc;
50284 : feedc->ctrl = defaultIntegerControl;
50285 : feedc->ctrl.id = 0;
50286 : if ( (feedc->next = dev->intfeed) )
50287 : feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
50288 : dev->intfeed = feedc;
50289 : (*controlProc)(dev, &feedc->ctrl);
50294 :InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
50295 : ValuatorMotionProcPtr motionProc,
50296 : PtrCtrlProcPtr controlProc, int numMotionEvents,
50299 : DeviceIntPtr dev = (DeviceIntPtr)device;
50301 : return(InitButtonClassDeviceStruct(dev, numButtons, map) &&
50302 : InitValuatorClassDeviceStruct(dev, numAxes, motionProc,
50303 : numMotionEvents, 0) &&
50304 : InitPtrFeedbackClassDeviceStruct(dev, controlProc));
50308 :InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
50309 : CARD8 pModifiers[], BellProcPtr bellProc,
50310 : KbdCtrlProcPtr controlProc)
50312 : DeviceIntPtr dev = (DeviceIntPtr)device;
50314 : return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) &&
50315 : InitFocusClassDeviceStruct(dev) &&
50316 : InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc));
50320 :SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
50321 : ClientPtr client)
50326 : event.u.u.type = MappingNotify;
50327 : event.u.mappingNotify.request = request;
50328 : if (request == MappingKeyboard)
50330 : event.u.mappingNotify.firstKeyCode = firstKeyCode;
50331 : event.u.mappingNotify.count = count;
50334 : if (!noXkbExtension &&
50335 : ((request == MappingKeyboard) || (request == MappingModifier))) {
50336 : XkbApplyMappingChange(inputInfo.keyboard,request,firstKeyCode,count,
50341 : /* 0 is the server client */
50342 : for (i=1; i<currentMaxClients; i++)
50344 : if (clients[i] && clients[i]->clientState == ClientStateRunning)
50347 : if (!noXkbExtension &&
50348 : (request == MappingKeyboard) &&
50349 : (clients[i]->xkbClientFlags != 0) &&
50350 : (clients[i]->mapNotifyMask&XkbKeySymsMask))
50353 : event.u.u.sequenceNumber = clients[i]->sequence;
50354 : WriteEventsToClient(clients[i], 1, &event);
50360 : * n-squared algorithm. n < 255 and don't want to copy the whole thing and
50361 : * sort it to do the checking. How often is it called? Just being lazy?
50364 :BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
50368 : for (i = 0; i < length; i++)
50369 : if (buff[i]) /* only check non-zero elements */
50371 : if ((low > buff[i]) || (high < buff[i]))
50373 : *errval = buff[i];
50376 : for (j = i + 1; j < length; j++)
50377 : if (buff[i] == buff[j])
50379 : *errval = buff[i];
50387 :AllModifierKeysAreUp(dev, map1, per1, map2, per2)
50388 : DeviceIntPtr dev;
50389 : CARD8 *map1, *map2;
50393 : CARD8 *down = dev->key->down;
50395 : for (i = 8; --i >= 0; map2 += per2)
50397 : for (j = per1; --j >= 0; map1++)
50399 : if (*map1 && BitIsOn(down, *map1))
50401 : for (k = per2; (--k >= 0) && (*map1 != map2[k]);)
50412 :DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
50413 : int numKeyPerModifier)
50415 : DeviceIntPtr pDev = NULL;
50416 : int i = 0, inputMapLen = numKeyPerModifier * 8;
50418 : for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
50419 : if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
50420 : for (i = 0; i < inputMapLen; i++) {
50421 : /* Check that all the new modifiers fall within the advertised
50422 : * keycode range, and are okay with the DDX. */
50423 : if (inputMap[i] && ((inputMap[i] < pDev->key->curKeySyms.minKeyCode ||
50424 : inputMap[i] > pDev->key->curKeySyms.maxKeyCode) ||
50425 : !LegalModifier(inputMap[i], pDev))) {
50426 : client->errorValue = inputMap[i];
50431 : if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
50432 : return BadAccess;
50434 : /* None of the modifiers (old or new) may be down while we change
50436 : if (!AllModifierKeysAreUp(pDev, pDev->key->modifierKeyMap,
50437 : pDev->key->maxKeysPerModifier,
50438 : inputMap, numKeyPerModifier) ||
50439 : !AllModifierKeysAreUp(pDev, inputMap, numKeyPerModifier,
50440 : pDev->key->modifierKeyMap,
50441 : pDev->key->maxKeysPerModifier)) {
50442 : return MappingBusy;
50447 : for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
50449 : if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
50450 : bzero(pDev->key->modifierMap, MAP_LENGTH);
50452 : /* Annoyingly, we lack a modifierKeyMap size, so we have to just free
50453 : * and re-alloc it every time. */
50454 : if (pDev->key->modifierKeyMap)
50455 : xfree(pDev->key->modifierKeyMap);
50457 : if (inputMapLen) {
50458 : pDev->key->modifierKeyMap = (KeyCode *) xalloc(inputMapLen);
50459 : if (!pDev->key->modifierKeyMap)
50462 : memcpy(pDev->key->modifierKeyMap, inputMap, inputMapLen);
50463 : pDev->key->maxKeysPerModifier = numKeyPerModifier;
50465 : for (i = 0; i < inputMapLen; i++) {
50466 : if (inputMap[i]) {
50467 : pDev->key->modifierMap[inputMap[i]] |=
50468 : (1 << (((unsigned int)i) / numKeyPerModifier));
50473 : pDev->key->modifierKeyMap = NULL;
50474 : pDev->key->maxKeysPerModifier = 0;
50483 :ProcSetModifierMapping(ClientPtr client)
50485 : xSetModifierMappingReply rep;
50486 : REQUEST(xSetModifierMappingReq);
50488 : REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
50490 : if (client->req_len != ((stuff->numKeyPerModifier << 1) +
50491 : (sizeof (xSetModifierMappingReq) >> 2)))
50492 : return BadLength;
50494 : rep.type = X_Reply;
50496 : rep.sequenceNumber = client->sequence;
50498 : rep.success = DoSetModifierMapping(client, (KeyCode *)&stuff[1],
50499 : stuff->numKeyPerModifier);
50501 : /* FIXME: Send mapping notifies for all the extended devices as well. */
50502 : SendMappingNotify(MappingModifier, 0, 0, client);
50503 : WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
50504 : return client->noClientException;
50508 :ProcGetModifierMapping(ClientPtr client)
50510 : xGetModifierMappingReply rep;
50511 : KeyClassPtr keyc = inputInfo.keyboard->key;
50513 : REQUEST_SIZE_MATCH(xReq);
50514 : rep.type = X_Reply;
50515 : rep.numKeyPerModifier = keyc->maxKeysPerModifier;
50516 : rep.sequenceNumber = client->sequence;
50517 : /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
50518 : rep.length = keyc->maxKeysPerModifier << 1;
50520 : WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
50522 : /* Use the (modified by DDX) map that SetModifierMapping passed in */
50523 : (void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3),
50524 : (char *)keyc->modifierKeyMap);
50525 : return client->noClientException;
50529 :ProcChangeKeyboardMapping(ClientPtr client)
50531 : REQUEST(xChangeKeyboardMappingReq);
50533 : KeySymsRec keysyms;
50534 : KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
50535 : DeviceIntPtr pDev = NULL;
50536 : REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
50538 : len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);
50539 : if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
50540 : return BadLength;
50542 : if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
50543 : (stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
50544 : client->errorValue = stuff->firstKeyCode;
50548 : if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
50549 : curKeySyms->maxKeyCode) || (stuff->keySymsPerKeyCode == 0)) {
50550 : client->errorValue = stuff->keySymsPerKeyCode;
50554 : for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
50555 : if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
50556 : if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
50557 : return BadAccess;
50561 : keysyms.minKeyCode = stuff->firstKeyCode;
50562 : keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
50563 : keysyms.mapWidth = stuff->keySymsPerKeyCode;
50564 : keysyms.map = (KeySym *)&stuff[1];
50565 : for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
50566 : if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
50567 : if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms))
50572 : /* FIXME: Send mapping notifies for all the extended devices as well. */
50573 : SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
50575 : return client->noClientException;
50579 :DoSetPointerMapping(DeviceIntPtr device, BYTE *map, int n)
50582 : DeviceIntPtr dev = NULL;
50584 : if (!device || !device->button)
50585 : return BadDevice;
50587 : for (dev = inputInfo.devices; dev; dev = dev->next) {
50588 : if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
50589 : for (i = 0; i < n; i++) {
50590 : if ((device->button->map[i + 1] != map[i]) &&
50591 : BitIsOn(device->button->down, i + 1)) {
50592 : return MappingBusy;
50598 : for (dev = inputInfo.devices; dev; dev = dev->next) {
50599 : if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
50600 : for (i = 0; i < n; i++)
50601 : dev->button->map[i + 1] = map[i];
50609 :ProcSetPointerMapping(ClientPtr client)
50611 : REQUEST(xSetPointerMappingReq);
50614 : xSetPointerMappingReply rep;
50616 : REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
50617 : if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2)
50618 : return BadLength;
50619 : rep.type = X_Reply;
50621 : rep.sequenceNumber = client->sequence;
50622 : rep.success = MappingSuccess;
50623 : map = (BYTE *)&stuff[1];
50625 : /* So we're bounded here by the number of core buttons. This check
50626 : * probably wants disabling through XFixes. */
50627 : if (stuff->nElts != inputInfo.pointer->button->numButtons) {
50628 : client->errorValue = stuff->nElts;
50631 : if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
50634 : ret = DoSetPointerMapping(inputInfo.pointer, map, stuff->nElts);
50635 : if (ret != Success) {
50636 : rep.success = ret;
50637 : WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
50641 : /* FIXME: Send mapping notifies for all the extended devices as well. */
50642 : SendMappingNotify(MappingPointer, 0, 0, client);
50643 : WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
50648 :ProcGetKeyboardMapping(ClientPtr client)
50650 : xGetKeyboardMappingReply rep;
50651 : REQUEST(xGetKeyboardMappingReq);
50652 : KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
50654 : REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
50656 : if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
50657 : (stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
50658 : client->errorValue = stuff->firstKeyCode;
50661 : if (stuff->firstKeyCode + stuff->count >
50662 : (unsigned)(curKeySyms->maxKeyCode + 1)) {
50663 : client->errorValue = stuff->count;
50667 : rep.type = X_Reply;
50668 : rep.sequenceNumber = client->sequence;
50669 : rep.keySymsPerKeyCode = curKeySyms->mapWidth;
50670 : /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
50671 : rep.length = (curKeySyms->mapWidth * stuff->count);
50672 : WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
50673 : client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
50674 : WriteSwappedDataToClient(
50676 : curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
50677 : &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
50678 : curKeySyms->mapWidth]);
50680 : return client->noClientException;
50684 :ProcGetPointerMapping(ClientPtr client)
50686 : xGetPointerMappingReply rep;
50687 : ButtonClassPtr butc = inputInfo.pointer->button;
50689 : REQUEST_SIZE_MATCH(xReq);
50690 : rep.type = X_Reply;
50691 : rep.sequenceNumber = client->sequence;
50692 : rep.nElts = butc->numButtons;
50693 : rep.length = ((unsigned)rep.nElts + (4-1))/4;
50694 : WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
50695 : (void)WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
50700 :NoteLedState(DeviceIntPtr keybd, int led, Bool on)
50702 : KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
50704 : ctrl->leds |= ((Leds)1 << (led - 1));
50706 : ctrl->leds &= ~((Leds)1 << (led - 1));
50710 :Ones(unsigned long mask) /* HACKMEM 169 */
50711 3 0.0033 :{ /* Ones total: 9 0.0098 */
50714 : y = (mask >> 1) &033333333333;
50715 4 0.0044 : y = mask - y - ((y >>1) & 033333333333);
50716 : return (((y + (y >> 3)) & 030707070707) % 077);
50720 :DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
50723 :#define DO_ALL (-1)
50726 : int led = DO_ALL;
50727 : int key = DO_ALL;
50729 : int mask = vmask, i;
50731 : ctrl = keybd->kbdfeed->ctrl;
50733 : index2 = (BITS32) lowbit (vmask);
50734 : vmask &= ~index2;
50735 : switch (index2) {
50736 : case KBKeyClickPercent:
50737 : t = (INT8)*vlist;
50740 : t = defaultKeyboardControl.click;
50742 : else if (t < 0 || t > 100) {
50743 : client->errorValue = t;
50748 : case KBBellPercent:
50749 : t = (INT8)*vlist;
50752 : t = defaultKeyboardControl.bell;
50754 : else if (t < 0 || t > 100) {
50755 : client->errorValue = t;
50760 : case KBBellPitch:
50761 : t = (INT16)*vlist;
50764 : t = defaultKeyboardControl.bell_pitch;
50766 : else if (t < 0) {
50767 : client->errorValue = t;
50770 : ctrl.bell_pitch = t;
50772 : case KBBellDuration:
50773 : t = (INT16)*vlist;
50776 : t = defaultKeyboardControl.bell_duration;
50777 : else if (t < 0) {
50778 : client->errorValue = t;
50781 : ctrl.bell_duration = t;
50784 : led = (CARD8)*vlist;
50786 : if (led < 1 || led > 32) {
50787 : client->errorValue = led;
50790 : if (!(mask & KBLedMode))
50794 : t = (CARD8)*vlist;
50796 : if (t == LedModeOff) {
50797 : if (led == DO_ALL)
50800 : ctrl.leds &= ~(((Leds)(1)) << (led - 1));
50802 : else if (t == LedModeOn) {
50803 : if (led == DO_ALL)
50806 : ctrl.leds |= (((Leds)(1)) << (led - 1));
50809 : client->errorValue = t;
50813 : if (!noXkbExtension) {
50814 : XkbEventCauseRec cause;
50815 : XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
50816 : XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
50817 : ctrl.leds, &cause);
50818 : ctrl.leds = keybd->kbdfeed->ctrl.leds;
50823 : key = (KeyCode)*vlist;
50825 : if ((KeyCode)key < inputInfo.keyboard->key->curKeySyms.minKeyCode ||
50826 : (KeyCode)key > inputInfo.keyboard->key->curKeySyms.maxKeyCode) {
50827 : client->errorValue = key;
50830 : if (!(mask & KBAutoRepeatMode))
50833 : case KBAutoRepeatMode:
50835 : mask = (1 << (key & 7));
50836 : t = (CARD8)*vlist;
50839 : if (!noXkbExtension && key != DO_ALL)
50840 : XkbDisableComputedAutoRepeats(keybd,key);
50842 : if (t == AutoRepeatModeOff) {
50843 : if (key == DO_ALL)
50844 : ctrl.autoRepeat = FALSE;
50846 : ctrl.autoRepeats[i] &= ~mask;
50848 : else if (t == AutoRepeatModeOn) {
50849 : if (key == DO_ALL)
50850 : ctrl.autoRepeat = TRUE;
50852 : ctrl.autoRepeats[i] |= mask;
50854 : else if (t == AutoRepeatModeDefault) {
50855 : if (key == DO_ALL)
50856 : ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
50858 : ctrl.autoRepeats[i] =
50859 : (ctrl.autoRepeats[i] & ~mask) |
50860 : (defaultKeyboardControl.autoRepeats[i] & mask);
50863 : client->errorValue = t;
50868 : client->errorValue = mask;
50872 : keybd->kbdfeed->ctrl = ctrl;
50875 : /* The XKB RepeatKeys control and core protocol global autorepeat */
50876 : /* value are linked */
50877 : if (!noXkbExtension)
50878 : XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
50881 : (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl);
50889 :ProcChangeKeyboardControl (ClientPtr client)
50893 : int ret = Success, error = Success;
50894 : DeviceIntPtr pDev = NULL;
50895 : REQUEST(xChangeKeyboardControlReq);
50897 : REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
50899 : vmask = stuff->mask;
50900 : vlist = (XID *)&stuff[1];
50902 : if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
50903 : return BadLength;
50905 : for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
50906 : if ((pDev->coreEvents || pDev == inputInfo.keyboard) &&
50907 : pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
50908 : if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
50909 : return BadAccess;
50913 : for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
50914 : if ((pDev->coreEvents || pDev == inputInfo.keyboard) &&
50915 : pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
50916 : ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
50917 : if (ret != Success)
50926 :ProcGetKeyboardControl (ClientPtr client)
50929 : KeybdCtrl *ctrl = &inputInfo.keyboard->kbdfeed->ctrl;
50930 : xGetKeyboardControlReply rep;
50932 : REQUEST_SIZE_MATCH(xReq);
50933 : rep.type = X_Reply;
50935 : rep.sequenceNumber = client->sequence;
50936 : rep.globalAutoRepeat = ctrl->autoRepeat;
50937 : rep.keyClickPercent = ctrl->click;
50938 : rep.bellPercent = ctrl->bell;
50939 : rep.bellPitch = ctrl->bell_pitch;
50940 : rep.bellDuration = ctrl->bell_duration;
50941 : rep.ledMask = ctrl->leds;
50942 : for (i = 0; i < 32; i++)
50943 : rep.map[i] = ctrl->autoRepeats[i];
50944 : WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
50949 :ProcBell(ClientPtr client)
50951 : DeviceIntPtr keybd = inputInfo.keyboard;
50952 : int base = keybd->kbdfeed->ctrl.bell;
50954 : REQUEST(xBellReq);
50955 : REQUEST_SIZE_MATCH(xBellReq);
50957 : if (!keybd->kbdfeed->BellProc)
50958 : return BadDevice;
50960 : if (stuff->percent < -100 || stuff->percent > 100) {
50961 : client->errorValue = stuff->percent;
50965 : newpercent = (base * stuff->percent) / 100;
50966 : if (stuff->percent < 0)
50967 : newpercent = base + newpercent;
50969 : newpercent = base - newpercent + stuff->percent;
50971 : for (keybd = inputInfo.devices; keybd; keybd = keybd->next) {
50972 : if ((keybd->coreEvents || keybd == inputInfo.keyboard) &&
50973 : keybd->kbdfeed && keybd->kbdfeed->BellProc) {
50975 : if (!noXkbExtension)
50976 : XkbHandleBell(FALSE, FALSE, keybd, newpercent,
50977 : &keybd->kbdfeed->ctrl, 0, None, NULL, client);
50980 : (*keybd->kbdfeed->BellProc)(newpercent, keybd,
50981 : &keybd->kbdfeed->ctrl, 0);
50989 :ProcChangePointerControl(ClientPtr client)
50991 : DeviceIntPtr mouse = inputInfo.pointer;
50992 : PtrCtrl ctrl; /* might get BadValue part way through */
50993 : REQUEST(xChangePointerControlReq);
50995 : REQUEST_SIZE_MATCH(xChangePointerControlReq);
50997 : if (!mouse->ptrfeed->CtrlProc)
50998 : return BadDevice;
51000 : ctrl = mouse->ptrfeed->ctrl;
51001 : if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
51002 : client->errorValue = stuff->doAccel;
51003 : return(BadValue);
51005 : if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
51006 : client->errorValue = stuff->doThresh;
51007 : return(BadValue);
51009 : if (stuff->doAccel) {
51010 : if (stuff->accelNum == -1) {
51011 : ctrl.num = defaultPointerControl.num;
51013 : else if (stuff->accelNum < 0) {
51014 : client->errorValue = stuff->accelNum;
51018 : ctrl.num = stuff->accelNum;
51021 : if (stuff->accelDenum == -1) {
51022 : ctrl.den = defaultPointerControl.den;
51024 : else if (stuff->accelDenum <= 0) {
51025 : client->errorValue = stuff->accelDenum;
51029 : ctrl.den = stuff->accelDenum;
51032 : if (stuff->doThresh) {
51033 : if (stuff->threshold == -1) {
51034 : ctrl.threshold = defaultPointerControl.threshold;
51036 : else if (stuff->threshold < 0) {
51037 : client->errorValue = stuff->threshold;
51041 : ctrl.threshold = stuff->threshold;
51046 : for (mouse = inputInfo.devices; mouse; mouse = mouse->next) {
51047 : if ((mouse->coreEvents || mouse == inputInfo.pointer) &&
51048 : mouse->ptrfeed && mouse->ptrfeed->CtrlProc) {
51049 : mouse->ptrfeed->ctrl = ctrl;
51050 : (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl);
51058 :ProcGetPointerControl(ClientPtr client)
51060 : PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl;
51061 : xGetPointerControlReply rep;
51063 : REQUEST_SIZE_MATCH(xReq);
51064 : rep.type = X_Reply;
51066 : rep.sequenceNumber = client->sequence;
51067 : rep.threshold = ctrl->threshold;
51068 : rep.accelNumerator = ctrl->num;
51069 : rep.accelDenominator = ctrl->den;
51070 : WriteReplyToClient(client, sizeof(xGenericReply), &rep);
51075 :MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
51077 : GrabPtr grab = dev->grab;
51079 : if ((grab && SameClient(grab, client) &&
51080 : ((grab->eventMask & PointerMotionHintMask) ||
51081 : (grab->ownerEvents &&
51082 : (EventMaskForClient(dev->valuator->motionHintWindow, client) &
51083 : PointerMotionHintMask)))) ||
51085 : (EventMaskForClient(dev->valuator->motionHintWindow, client) &
51086 : PointerMotionHintMask)))
51087 : dev->valuator->motionHintWindow = NullWindow;
51091 :ProcGetMotionEvents(ClientPtr client)
51094 : xTimecoord * coords = (xTimecoord *) NULL;
51095 : xGetMotionEventsReply rep;
51096 : int i, count, xmin, xmax, ymin, ymax, rc;
51097 : unsigned long nEvents;
51098 : DeviceIntPtr mouse = inputInfo.pointer;
51099 : TimeStamp start, stop;
51100 : REQUEST(xGetMotionEventsReq);
51102 : REQUEST_SIZE_MATCH(xGetMotionEventsReq);
51103 : rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess);
51104 : if (rc != Success)
51106 : if (mouse->valuator->motionHintWindow)
51107 : MaybeStopHint(mouse, client);
51108 : rep.type = X_Reply;
51109 : rep.sequenceNumber = client->sequence;
51111 : start = ClientTimeToServerTime(stuff->start);
51112 : stop = ClientTimeToServerTime(stuff->stop);
51113 : if ((CompareTimeStamps(start, stop) != LATER) &&
51114 : (CompareTimeStamps(start, currentTime) != LATER) &&
51115 : mouse->valuator->numMotionEvents)
51117 : if (CompareTimeStamps(stop, currentTime) == LATER)
51118 : stop = currentTime;
51119 : coords = (xTimecoord *)ALLOCATE_LOCAL(mouse->valuator->numMotionEvents
51120 : * sizeof(xTimecoord));
51123 : count = (*mouse->valuator->GetMotionProc) (mouse, coords,
51124 : start.milliseconds,
51125 : stop.milliseconds,
51126 : pWin->drawable.pScreen);
51127 : xmin = pWin->drawable.x - wBorderWidth (pWin);
51128 : xmax = pWin->drawable.x + (int)pWin->drawable.width +
51129 : wBorderWidth (pWin);
51130 : ymin = pWin->drawable.y - wBorderWidth (pWin);
51131 : ymax = pWin->drawable.y + (int)pWin->drawable.height +
51132 : wBorderWidth (pWin);
51133 : for (i = 0; i < count; i++)
51134 : if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
51135 : (ymin <= coords[i].y) && (coords[i].y < ymax))
51137 : coords[nEvents].time = coords[i].time;
51138 : coords[nEvents].x = coords[i].x - pWin->drawable.x;
51139 : coords[nEvents].y = coords[i].y - pWin->drawable.y;
51143 : rep.length = nEvents * (sizeof(xTimecoord) >> 2);
51144 : rep.nEvents = nEvents;
51145 : WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
51148 : client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
51149 : WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
51153 : DEALLOCATE_LOCAL(coords);
51158 :ProcQueryKeymap(ClientPtr client)
51160 : xQueryKeymapReply rep;
51162 : CARD8 *down = inputInfo.keyboard->key->down;
51164 : REQUEST_SIZE_MATCH(xReq);
51165 : rep.type = X_Reply;
51166 : rep.sequenceNumber = client->sequence;
51169 : if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
51170 : for (i = 0; i<32; i++)
51171 : rep.map[i] = down[i];
51173 : bzero((char *)&rep.map[0], 32);
51175 : WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
51179 * Total samples for file : "xf86dri.c"
51184 <credited to line zero> 8 0.0087 :
51185 /* __i686.get_pc_thunk.cx total: 8 0.0087 */
51187 * Total samples for file : "/home/cworth/src/xorg/xserver/dix/extension.c"
51193 :/***********************************************************
51195 :Copyright 1987, 1998 The Open Group
51197 :Permission to use, copy, modify, distribute, and sell this software and its
51198 :documentation for any purpose is hereby granted without fee, provided that
51199 :the above copyright notice appear in all copies and that both that
51200 :copyright notice and this permission notice appear in supporting
51203 :The above copyright notice and this permission notice shall be included in
51204 :all copies or substantial portions of the Software.
51206 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51207 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51208 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51209 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
51210 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
51211 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51213 :Except as contained in this notice, the name of The Open Group shall not be
51214 :used in advertising or otherwise to promote the sale, use or other dealings
51215 :in this Software without prior written authorization from The Open Group.
51218 :Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
51220 : All Rights Reserved
51222 :Permission to use, copy, modify, and distribute this software and its
51223 :documentation for any purpose and without fee is hereby granted,
51224 :provided that the above copyright notice appear in all copies and that
51225 :both that copyright notice and this permission notice appear in
51226 :supporting documentation, and that the name of Digital not be
51227 :used in advertising or publicity pertaining to distribution of the
51228 :software without specific, written prior permission.
51230 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
51231 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
51232 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
51233 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
51234 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
51235 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51238 :******************************************************************/
51240 :#ifdef HAVE_DIX_CONFIG_H
51241 :#include <dix-config.h>
51244 :#include <X11/X.h>
51245 :#define NEED_EVENTS
51246 :#define NEED_REPLIES
51247 :#include <X11/Xproto.h>
51249 :#include "dixstruct.h"
51250 :#include "extnsionst.h"
51251 :#include "gcstruct.h"
51252 :#include "scrnintstr.h"
51253 :#include "dispatch.h"
51256 :#define EXTENSION_BASE 128
51257 :#define EXTENSION_EVENT_BASE 64
51258 :#define LAST_EVENT 128
51259 :#define LAST_ERROR 255
51261 :static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
51263 :int lastEvent = EXTENSION_EVENT_BASE;
51264 :static int lastError = FirstExtensionError;
51265 :static unsigned int NumExtensions = 0;
51267 :extern int extensionPrivateLen;
51268 :extern unsigned *extensionPrivateSizes;
51269 :extern unsigned totalExtensionSize;
51272 :InitExtensionPrivates(ExtensionEntry *ext)
51280 : if (totalExtensionSize == sizeof(ExtensionEntry))
51281 : ppriv = (DevUnion *)NULL;
51283 : ppriv = (DevUnion *)(ext + 1);
51285 : ext->devPrivates = ppriv;
51286 : sizes = extensionPrivateSizes;
51287 : ptr = (char *)(ppriv + extensionPrivateLen);
51288 : for (i = extensionPrivateLen; --i >= 0; ppriv++, sizes++)
51290 : if ( (size = *sizes) )
51292 : ppriv->ptr = (pointer)ptr;
51296 : ppriv->ptr = (pointer)NULL;
51300 :_X_EXPORT ExtensionEntry *
51301 :AddExtension(char *name, int NumEvents, int NumErrors,
51302 : int (*MainProc)(ClientPtr c1),
51303 : int (*SwappedMainProc)(ClientPtr c2),
51304 : void (*CloseDownProc)(ExtensionEntry *e),
51305 : unsigned short (*MinorOpcodeProc)(ClientPtr c3))
51308 : ExtensionEntry *ext, **newexts;
51310 : if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
51311 : return((ExtensionEntry *) NULL);
51312 : if ((lastEvent + NumEvents > LAST_EVENT) ||
51313 : (unsigned)(lastError + NumErrors > LAST_ERROR))
51314 : return((ExtensionEntry *) NULL);
51316 : ext = (ExtensionEntry *) xalloc(totalExtensionSize);
51318 : return((ExtensionEntry *) NULL);
51319 : bzero(ext, totalExtensionSize);
51320 : InitExtensionPrivates(ext);
51321 : ext->name = (char *)xalloc(strlen(name) + 1);
51322 : ext->num_aliases = 0;
51323 : ext->aliases = (char **)NULL;
51327 : return((ExtensionEntry *) NULL);
51329 : strcpy(ext->name, name);
51330 : i = NumExtensions;
51331 : newexts = (ExtensionEntry **) xrealloc(extensions,
51332 : (i + 1) * sizeof(ExtensionEntry *));
51335 : xfree(ext->name);
51337 : return((ExtensionEntry *) NULL);
51340 : extensions = newexts;
51341 : extensions[i] = ext;
51343 : ext->base = i + EXTENSION_BASE;
51344 : ext->CloseDown = CloseDownProc;
51345 : ext->MinorOpcode = MinorOpcodeProc;
51346 : ProcVector[i + EXTENSION_BASE] = MainProc;
51347 : SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
51350 : ext->eventBase = lastEvent;
51351 : ext->eventLast = lastEvent + NumEvents;
51352 : lastEvent += NumEvents;
51356 : ext->eventBase = 0;
51357 : ext->eventLast = 0;
51361 : ext->errorBase = lastError;
51362 : ext->errorLast = lastError + NumErrors;
51363 : lastError += NumErrors;
51367 : ext->errorBase = 0;
51368 : ext->errorLast = 0;
51374 :_X_EXPORT Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
51379 : aliases = (char **)xrealloc(ext->aliases,
51380 : (ext->num_aliases + 1) * sizeof(char *));
51383 : ext->aliases = aliases;
51384 : name = (char *)xalloc(strlen(alias) + 1);
51387 : strcpy(name, alias);
51388 : ext->aliases[ext->num_aliases] = name;
51389 : ext->num_aliases++;
51394 :FindExtension(char *extname, int len)
51398 : for (i=0; i<NumExtensions; i++)
51400 : if ((strlen(extensions[i]->name) == len) &&
51401 : !strncmp(extname, extensions[i]->name, len))
51403 : for (j = extensions[i]->num_aliases; --j >= 0;)
51405 : if ((strlen(extensions[i]->aliases[j]) == len) &&
51406 : !strncmp(extname, extensions[i]->aliases[j], len))
51409 : if (j >= 0) break;
51411 : return ((i == NumExtensions) ? -1 : i);
51415 : * CheckExtension returns the extensions[] entry for the requested
51416 : * extension name. Maybe this could just return a Bool instead?
51418 :_X_EXPORT ExtensionEntry *
51419 :CheckExtension(const char *extname)
51423 : n = FindExtension((char*)extname, strlen(extname));
51425 : return extensions[n];
51431 : * Added as part of Xace.
51434 :GetExtensionEntry(int major)
51435 5 0.0054 :{ /* GetExtensionEntry total: 5 0.0054 */
51436 : if (major < EXTENSION_BASE)
51438 : major -= EXTENSION_BASE;
51439 : if (major >= NumExtensions)
51441 : return extensions[major];
51445 :DeclareExtensionSecurity(char *extname, Bool secure)
51447 : int i = FindExtension(extname, strlen(extname));
51449 : XaceHook(XACE_DECLARE_EXT_SECURE, extensions[i], secure);
51452 :_X_EXPORT unsigned short
51453 :StandardMinorOpcode(ClientPtr client)
51455 : return ((xReq *)client->requestBuffer)->data;
51458 :_X_EXPORT unsigned short
51459 :MinorOpcodeOfRequest(ClientPtr client)
51461 : unsigned char major;
51463 : major = ((xReq *)client->requestBuffer)->reqType;
51464 : if (major < EXTENSION_BASE)
51466 : major -= EXTENSION_BASE;
51467 : if (major >= NumExtensions)
51469 : return (*extensions[major]->MinorOpcode)(client);
51473 :CloseDownExtensions(void)
51477 : for (i = NumExtensions - 1; i >= 0; i--)
51479 : (* extensions[i]->CloseDown)(extensions[i]);
51480 : NumExtensions = i;
51481 : xfree(extensions[i]->name);
51482 : for (j = extensions[i]->num_aliases; --j >= 0;)
51483 : xfree(extensions[i]->aliases[j]);
51484 : xfree(extensions[i]->aliases);
51485 : xfree(extensions[i]);
51487 : xfree(extensions);
51488 : extensions = (ExtensionEntry **)NULL;
51489 : lastEvent = EXTENSION_EVENT_BASE;
51490 : lastError = FirstExtensionError;
51494 :ProcQueryExtension(ClientPtr client)
51496 : xQueryExtensionReply reply;
51498 : REQUEST(xQueryExtensionReq);
51500 : REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
51502 : reply.type = X_Reply;
51503 : reply.length = 0;
51504 : reply.major_opcode = 0;
51505 : reply.sequenceNumber = client->sequence;
51507 : if ( ! NumExtensions )
51508 : reply.present = xFalse;
51511 : i = FindExtension((char *)&stuff[1], stuff->nbytes);
51512 : if (i < 0 || !XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
51513 : reply.present = xFalse;
51516 : reply.present = xTrue;
51517 : reply.major_opcode = extensions[i]->base;
51518 : reply.first_event = extensions[i]->eventBase;
51519 : reply.first_error = extensions[i]->errorBase;
51522 : WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
51523 : return(client->noClientException);
51527 :ProcListExtensions(ClientPtr client)
51529 : xListExtensionsReply reply;
51530 : char *bufptr, *buffer;
51531 : int total_length = 0;
51533 : REQUEST_SIZE_MATCH(xReq);
51535 : reply.type = X_Reply;
51536 : reply.nExtensions = 0;
51537 : reply.length = 0;
51538 : reply.sequenceNumber = client->sequence;
51541 : if ( NumExtensions )
51545 : for (i=0; i<NumExtensions; i++)
51547 : /* call callbacks to find out whether to show extension */
51548 : if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
51551 : total_length += strlen(extensions[i]->name) + 1;
51552 : reply.nExtensions += 1 + extensions[i]->num_aliases;
51553 : for (j = extensions[i]->num_aliases; --j >= 0;)
51554 : total_length += strlen(extensions[i]->aliases[j]) + 1;
51556 : reply.length = (total_length + 3) >> 2;
51557 : buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
51559 : return(BadAlloc);
51560 : for (i=0; i<NumExtensions; i++)
51563 : if (!XaceHook(XACE_EXT_ACCESS, client, extensions[i]))
51566 : *bufptr++ = len = strlen(extensions[i]->name);
51567 : memmove(bufptr, extensions[i]->name, len);
51569 : for (j = extensions[i]->num_aliases; --j >= 0;)
51571 : *bufptr++ = len = strlen(extensions[i]->aliases[j]);
51572 : memmove(bufptr, extensions[i]->aliases[j], len);
51577 : WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
51578 : if (reply.length)
51580 : WriteToClient(client, total_length, buffer);
51581 : DEALLOCATE_LOCAL(buffer);
51583 : return(client->noClientException);
51586 :#ifdef XSERVER_DTRACE
51587 :void LoadExtensionNames(char **RequestNames) {
51590 : for (i=0; i<NumExtensions; i++) {
51591 : int r = extensions[i]->base;
51593 : if (RequestNames[r] == NULL) {
51594 : RequestNames[r] = strdup(extensions[i]->name);
51600 * Total samples for file : "/home/cworth/src/pixman/pixman/pixman-trap.c"
51609 : * Copyright © 2004 Keith Packard
51611 : * Permission to use, copy, modify, distribute, and sell this software and its
51612 : * documentation for any purpose is hereby granted without fee, provided that
51613 : * the above copyright notice appear in all copies and that both that
51614 : * copyright notice and this permission notice appear in supporting
51615 : * documentation, and that the name of Keith Packard not be used in
51616 : * advertising or publicity pertaining to distribution of the software without
51617 : * specific, written prior permission. Keith Packard makes no
51618 : * representations about the suitability of this software for any purpose. It
51619 : * is provided "as is" without express or implied warranty.
51621 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
51622 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
51623 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
51624 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
51625 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
51626 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
51627 : * PERFORMANCE OF THIS SOFTWARE.
51630 :#include <config.h>
51631 :#include <stdio.h>
51632 :#include "pixman-private.h"
51634 :typedef uint32_t FbBits;
51637 :pixman_add_traps (pixman_image_t * image,
51641 : pixman_trap_t *traps)
51647 : pixman_fixed_t x_off_fixed;
51648 : pixman_fixed_t y_off_fixed;
51649 : pixman_edge_t l, r;
51650 : pixman_fixed_t t, b;
51652 : width = image->bits.width;
51653 : height = image->bits.height;
51654 : bpp = PIXMAN_FORMAT_BPP (image->bits.format);
51656 : x_off_fixed = pixman_int_to_fixed(y_off);
51657 : y_off_fixed = pixman_int_to_fixed(y_off);
51661 : t = traps->top.y + y_off_fixed;
51664 : t = pixman_sample_ceil_y (t, bpp);
51666 : b = traps->bot.y + y_off_fixed;
51667 : if (pixman_fixed_to_int (b) >= height)
51668 : b = pixman_int_to_fixed (height) - 1;
51669 : b = pixman_sample_floor_y (b, bpp);
51673 : /* initialize edge walkers */
51674 : pixman_edge_init (&l, bpp, t,
51675 : traps->top.l + x_off_fixed,
51676 : traps->top.y + y_off_fixed,
51677 : traps->bot.l + x_off_fixed,
51678 : traps->bot.y + y_off_fixed);
51680 : pixman_edge_init (&r, bpp, t,
51681 : traps->top.r + x_off_fixed,
51682 : traps->top.y + y_off_fixed,
51683 : traps->bot.r + x_off_fixed,
51684 : traps->bot.y + y_off_fixed);
51686 : pixman_rasterize_edges (image, &l, &r, t, b);
51691 : fbFinishAccess (pPicture->pDrawable);
51695 :dump_image (pixman_image_t *image,
51696 : const char *title)
51700 : if (!image->type == BITS)
51702 : printf ("%s is not a regular image\n", title);
51705 : if (!image->bits.format == PIXMAN_a8)
51707 : printf ("%s is not an alpha mask\n", title);
51710 : printf ("\n\n\n%s: \n", title);
51712 : for (i = 0; i < image->bits.height; ++i)
51715 : (uint8_t *)&(image->bits.bits[i * image->bits.rowstride]);
51717 : for (j = 0; j < image->bits.width; ++j)
51718 : printf ("%c", line[j]? '#' : ' ');
51725 :pixman_add_trapezoids (pixman_image_t *image,
51729 : const pixman_trapezoid_t *traps)
51734 : dump_image (image, "before");
51737 : for (i = 0; i < ntraps; ++i)
51739 : const pixman_trapezoid_t *trap = &(traps[i]);
51741 : if (!pixman_trapezoid_valid (trap))
51744 : pixman_rasterize_trapezoid (image, trap, x_off, y_off);
51748 : dump_image (image, "after");
51753 :pixman_rasterize_trapezoid (pixman_image_t * image,
51754 : const pixman_trapezoid_t *trap,
51757 :{ /* pixman_rasterize_trapezoid total: 5 0.0054 */
51762 : pixman_fixed_t x_off_fixed;
51763 : pixman_fixed_t y_off_fixed;
51764 : pixman_edge_t l, r;
51765 : pixman_fixed_t t, b;
51767 : return_if_fail (image->type == BITS);
51769 2 0.0022 : if (!pixman_trapezoid_valid (trap))
51772 : width = image->bits.width;
51773 : height = image->bits.height;
51774 : bpp = PIXMAN_FORMAT_BPP (image->bits.format);
51776 : x_off_fixed = pixman_int_to_fixed(x_off);
51777 : y_off_fixed = pixman_int_to_fixed(y_off);
51778 : t = trap->top + y_off_fixed;
51781 : t = pixman_sample_ceil_y (t, bpp);
51783 : b = trap->bottom + y_off_fixed;
51784 : if (pixman_fixed_to_int (b) >= height)
51785 : b = pixman_int_to_fixed (height) - 1;
51786 : b = pixman_sample_floor_y (b, bpp);
51790 : /* initialize edge walkers */
51791 : pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off);
51792 3 0.0033 : pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
51794 : pixman_rasterize_edges (image, &l, &r, t, b);
51800 :_GreaterY (pixman_point_fixed_t *a, pixman_point_fixed_t *b)
51802 : if (a->y == b->y)
51803 : return a->x > b->x;
51804 : return a->y > b->y;
51808 : * Note that the definition of this function is a bit odd because
51809 : * of the X coordinate space (y increasing downwards).
51812 :_Clockwise (pixman_point_fixed_t *ref, pixman_point_fixed_t *a, pixman_point_fixed_t *b)
51814 : pixman_point_fixed_t ad, bd;
51816 : ad.x = a->x - ref->x;
51817 : ad.y = a->y - ref->y;
51818 : bd.x = b->x - ref->x;
51819 : bd.y = b->y - ref->y;
51821 : return ((pixman_fixed_32_32_t) bd.y * ad.x - (pixman_fixed_32_32_t) ad.y * bd.x) < 0;
51824 :/* FIXME -- this could be made more efficient */
51826 :fbAddTriangles (pixman_image_t * pPicture,
51832 : pixman_point_fixed_t *top, *left, *right, *tmp;
51835 : for (; ntri; ntri--, tris++)
51838 : left = &tris->p2;
51839 : right = &tris->p3;
51840 : if (_GreaterY (top, left)) {
51841 : tmp = left; left = top; top = tmp;
51843 : if (_GreaterY (top, right)) {
51844 : tmp = right; right = top; top = tmp;
51846 : if (_Clockwise (top, right, left)) {
51847 : tmp = right; right = left; left = tmp;
51863 : trap.top = top->y;
51864 : trap.left.p1 = *top;
51865 : trap.left.p2 = *left;
51866 : trap.right.p1 = *top;
51867 : trap.right.p2 = *right;
51868 : if (right->y < left->y)
51869 : trap.bottom = right->y;
51871 : trap.bottom = left->y;
51872 : fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
51873 : if (right->y < left->y)
51875 : trap.top = right->y;
51876 : trap.bottom = left->y;
51877 : trap.right.p1 = *right;
51878 : trap.right.p2 = *left;
51882 : trap.top = left->y;
51883 : trap.bottom = right->y;
51884 : trap.left.p1 = *left;
51885 : trap.left.p2 = *right;
51887 : fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
51892 * Total samples for file : "memcpy.c"
51897 <credited to line zero> 4 0.0044 :
51898 /* _dl_load_cache_lookup total: 1 0.0011 */
51899 /* _dl_lookup_symbol_x total: 1 0.0011 */
51900 /* _dl_relocate_object total: 1 0.0011 */
51901 /* strcmp total: 2 0.0022 */
51903 * Total samples for file : "/home/cworth/src/xorg/xserver/fb/fbpict.c"
51911 : * Copyright © 2000 SuSE, Inc.
51912 : * Copyright © 2007 Red Hat, Inc.
51914 : * Permission to use, copy, modify, distribute, and sell this software and its
51915 : * documentation for any purpose is hereby granted without fee, provided that
51916 : * the above copyright notice appear in all copies and that both that
51917 : * copyright notice and this permission notice appear in supporting
51918 : * documentation, and that the name of SuSE not be used in advertising or
51919 : * publicity pertaining to distribution of the software without specific,
51920 : * written prior permission. SuSE makes no representations about the
51921 : * suitability of this software for any purpose. It is provided "as is"
51922 : * without express or implied warranty.
51924 : * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
51925 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
51926 : * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
51927 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
51928 : * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
51929 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51931 : * Author: Keith Packard, SuSE, Inc.
51934 :#ifdef HAVE_DIX_CONFIG_H
51935 :#include <dix-config.h>
51938 :#include <string.h>
51944 :#include "picturestr.h"
51945 :#include "mipict.h"
51946 :#include "fbpict.h"
51948 :#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
51951 :fbWalkCompositeRegion (CARD8 op,
51953 : PicturePtr pMask,
51965 : CompositeFunc compositeRect)
51967 : RegionRec region;
51970 : int w, h, w_this, h_this;
51971 : int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
51973 : xDst += pDst->pDrawable->x;
51974 : yDst += pDst->pDrawable->y;
51975 : if (pSrc->pDrawable)
51977 : xSrc += pSrc->pDrawable->x;
51978 : ySrc += pSrc->pDrawable->y;
51980 : if (pMask && pMask->pDrawable)
51982 : xMask += pMask->pDrawable->x;
51983 : yMask += pMask->pDrawable->y;
51986 : if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc,
51987 : xMask, yMask, xDst, yDst, width, height))
51990 : n = REGION_NUM_RECTS (®ion);
51991 : pbox = REGION_RECTS (®ion);
51994 : h = pbox->y2 - pbox->y1;
51995 : y_src = pbox->y1 - yDst + ySrc;
51996 : y_msk = pbox->y1 - yDst + yMask;
51997 : y_dst = pbox->y1;
52001 : w = pbox->x2 - pbox->x1;
52002 : x_src = pbox->x1 - xDst + xSrc;
52003 : x_msk = pbox->x1 - xDst + xMask;
52004 : x_dst = pbox->x1;
52007 : y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height);
52008 : if (h_this > pMask->pDrawable->height - y_msk)
52009 : h_this = pMask->pDrawable->height - y_msk;
52010 : y_msk += pMask->pDrawable->y;
52014 : y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
52015 : if (h_this > pSrc->pDrawable->height - y_src)
52016 : h_this = pSrc->pDrawable->height - y_src;
52017 : y_src += pSrc->pDrawable->y;
52024 : x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width);
52025 : if (w_this > pMask->pDrawable->width - x_msk)
52026 : w_this = pMask->pDrawable->width - x_msk;
52027 : x_msk += pMask->pDrawable->x;
52031 : x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
52032 : if (w_this > pSrc->pDrawable->width - x_src)
52033 : w_this = pSrc->pDrawable->width - x_src;
52034 : x_src += pSrc->pDrawable->x;
52036 : (*compositeRect) (op, pSrc, pMask, pDst,
52037 : x_src, y_src, x_msk, y_msk, x_dst, y_dst,
52051 : REGION_UNINIT (pDst->pDrawable->pScreen, ®ion);
52055 :fbComposite (CARD8 op,
52057 : PicturePtr pMask,
52068 : pixman_image_t *src, *mask, *dest;
52070 : xDst += pDst->pDrawable->x;
52071 : yDst += pDst->pDrawable->y;
52072 : if (pSrc->pDrawable)
52074 : xSrc += pSrc->pDrawable->x;
52075 : ySrc += pSrc->pDrawable->y;
52077 : if (pMask && pMask->pDrawable)
52079 : xMask += pMask->pDrawable->x;
52080 : yMask += pMask->pDrawable->y;
52083 : miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
52085 : miCompositeSourceValidate (pMask, xMask, yMask, width, height);
52087 : src = image_from_pict (pSrc, TRUE);
52088 : mask = image_from_pict (pMask, TRUE);
52089 : dest = image_from_pict (pDst, TRUE);
52091 : if (src && dest && !(pMask && !mask))
52093 : pixman_image_composite (op, src, mask, dest,
52094 : xSrc, ySrc, xMask, yMask, xDst, yDst,
52100 : pixman_image_unref (src);
52102 : pixman_image_unref (mask);
52104 : pixman_image_unref (dest);
52108 :fbCompositeGeneral (CARD8 op,
52110 : PicturePtr pMask,
52121 : return fbComposite (op, pSrc, pMask, pDst,
52122 : xSrc, ySrc, xMask, yMask, xDst, yDst,
52126 :#endif /* RENDER */
52128 :static pixman_image_t *
52129 :create_solid_fill_image (PicturePtr pict)
52131 : PictSolidFill *solid = &pict->pSourcePict->solidFill;
52132 : pixman_color_t color;
52133 : CARD32 a, r, g, b;
52135 : a = (solid->color & 0xff000000) >> 24;
52136 : r = (solid->color & 0x00ff0000) >> 16;
52137 : g = (solid->color & 0x0000ff00) >> 8;
52138 : b = (solid->color & 0x000000ff) >> 0;
52140 : color.alpha = (a << 8) | a;
52141 : color.red = (r << 8) | r;
52142 : color.green = (g << 8) | g;
52143 : color.blue = (b << 8) | b;
52145 : return pixman_image_create_solid_fill (&color);
52148 :static pixman_image_t *
52149 :create_linear_gradient_image (PictGradient *gradient)
52151 : PictLinearGradient *linear = (PictLinearGradient *)gradient;
52152 : pixman_point_fixed_t p1;
52153 : pixman_point_fixed_t p2;
52155 : p1.x = linear->p1.x;
52156 : p1.y = linear->p1.y;
52157 : p2.x = linear->p2.x;
52158 : p2.y = linear->p2.y;
52160 : return pixman_image_create_linear_gradient (
52161 : &p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
52164 :static pixman_image_t *
52165 :create_radial_gradient_image (PictGradient *gradient)
52167 : PictRadialGradient *radial = (PictRadialGradient *)gradient;
52168 : pixman_point_fixed_t c1;
52169 : pixman_point_fixed_t c2;
52171 : c1.x = radial->c1.x;
52172 : c1.y = radial->c1.y;
52173 : c2.x = radial->c2.x;
52174 : c2.y = radial->c2.y;
52176 : return pixman_image_create_radial_gradient (
52177 : &c1, &c2, radial->c1.radius,
52178 : radial->c2.radius,
52179 : (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
52182 :static pixman_image_t *
52183 :create_conical_gradient_image (PictGradient *gradient)
52185 : PictConicalGradient *conical = (PictConicalGradient *)gradient;
52186 : pixman_point_fixed_t center;
52188 : center.x = conical->center.x;
52189 : center.y = conical->center.y;
52191 : return pixman_image_create_conical_gradient (
52192 : ¢er, conical->angle, (pixman_gradient_stop_t *)gradient->stops,
52193 : gradient->nstops);
52196 :static pixman_image_t *
52197 :create_bits_picture (PicturePtr pict,
52202 : int bpp, xoff, yoff;
52203 : pixman_image_t *image;
52205 : fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
52207 : bits += yoff * stride + xoff;
52209 : image = pixman_image_create_bits (
52211 : pict->pDrawable->width, pict->pDrawable->height,
52212 : (uint32_t *)bits, stride * sizeof (FbStride));
52215 :#ifdef FB_ACCESS_WRAPPER
52218 : pixman_image_set_accessors (image,
52219 : (pixman_read_memory_func_t)wfbReadMemory,
52220 : (pixman_write_memory_func_t)wfbWriteMemory);
52224 :#error The pixman library only works when FbBits is 32 bits wide
52229 : /* pCompositeClip is undefined for source pictures, so
52230 : * only set the clip region for pictures with drawables
52234 : if (pict->clientClipType != CT_NONE)
52235 : pixman_image_set_has_client_clip (image, TRUE);
52237 : pixman_image_set_clip_region (image, pict->pCompositeClip);
52240 : /* Indexed table */
52241 : if (pict->pFormat->index.devPrivate)
52242 : pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
52244 : fbFinishAccess (pict->pDrawable);
52250 :set_image_properties (pixman_image_t *image, PicturePtr pict)
52252 : pixman_repeat_t repeat;
52253 : pixman_filter_t filter;
52255 : if (pict->transform)
52257 : pixman_image_set_transform (
52258 : image, (pixman_transform_t *)pict->transform);
52261 : switch (pict->repeatType)
52265 : repeat = PIXMAN_REPEAT_NONE;
52269 : repeat = PIXMAN_REPEAT_PAD;
52272 : case RepeatNormal:
52273 : repeat = PIXMAN_REPEAT_NORMAL;
52276 : case RepeatReflect:
52277 : repeat = PIXMAN_REPEAT_REFLECT;
52281 : pixman_image_set_repeat (image, repeat);
52283 : if (pict->alphaMap)
52285 : pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, TRUE);
52287 : pixman_image_set_alpha_map (
52288 : image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
52290 : pixman_image_unref (alpha_map);
52293 : pixman_image_set_component_alpha (image, pict->componentAlpha);
52295 : switch (pict->filter)
52298 : case PictFilterNearest:
52299 : case PictFilterFast:
52300 : filter = PIXMAN_FILTER_NEAREST;
52303 : case PictFilterBilinear:
52304 : case PictFilterGood:
52305 : filter = PIXMAN_FILTER_BILINEAR;
52308 : case PictFilterConvolution:
52309 : filter = PIXMAN_FILTER_CONVOLUTION;
52313 : pixman_image_set_filter (image, filter, (pixman_fixed_t *)pict->filter_params, pict->filter_nparams);
52317 :image_from_pict (PicturePtr pict,
52319 3 0.0033 :{ /* image_from_pict total: 4 0.0044 */
52320 : pixman_image_t *image = NULL;
52325 : if (pict->pDrawable)
52327 : image = create_bits_picture (pict, has_clip);
52329 : else if (pict->pSourcePict)
52331 : SourcePict *sp = pict->pSourcePict;
52333 : if (sp->type == SourcePictTypeSolidFill)
52335 : image = create_solid_fill_image (pict);
52339 : PictGradient *gradient = &pict->pSourcePict->gradient;
52341 : if (sp->type == SourcePictTypeLinear)
52342 : image = create_linear_gradient_image (gradient);
52343 : else if (sp->type == SourcePictTypeRadial)
52344 : image = create_radial_gradient_image (gradient);
52345 : else if (sp->type == SourcePictTypeConical)
52346 : image = create_conical_gradient_image (gradient);
52351 : set_image_properties (image, pict);
52357 :fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
52362 : PictureScreenPtr ps;
52364 : if (!miPictureInit (pScreen, formats, nformats))
52366 : ps = GetPictureScreen(pScreen);
52367 : ps->Composite = fbComposite;
52368 : ps->Glyphs = miGlyphs;
52369 : ps->CompositeRects = miCompositeRects;
52370 : ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
52371 : ps->AddTraps = fbAddTraps;
52372 : ps->AddTriangles = fbAddTriangles;
52374 :#endif /* RENDER */
52379 * Total samples for file : "/home/cworth/src/xorg/driver/xf86-video-intel/src/i830_render.c"
52386 : * Copyright © 2006 Intel Corporation
52388 : * Permission is hereby granted, free of charge, to any person obtaining a
52389 : * copy of this software and associated documentation files (the "Software"),
52390 : * to deal in the Software without restriction, including without limitation
52391 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
52392 : * and/or sell copies of the Software, and to permit persons to whom the
52393 : * Software is furnished to do so, subject to the following conditions:
52395 : * The above copyright notice and this permission notice (including the next
52396 : * paragraph) shall be included in all copies or substantial portions of the
52399 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52400 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52401 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
52402 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52403 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52404 : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
52408 : * Wang Zhenyu <zhenyu.z.wang@intel.com>
52409 : * Eric Anholt <eric@anholt.net>
52413 :#ifdef HAVE_CONFIG_H
52414 :#include "config.h"
52419 :#include "i830_reg.h"
52422 :#define DEBUG_I830FALLBACK 1
52425 :#ifdef DEBUG_I830FALLBACK
52426 :#define I830FALLBACK(s, arg...) \
52428 : DPRINTF(PFX, "EXA fallback: " s "\n", ##arg); \
52432 :#define I830FALLBACK(s, arg...) \
52438 :struct blendinfo {
52441 : CARD32 src_blend;
52442 : CARD32 dst_blend;
52445 :struct formatinfo {
52450 :#define TB0C_LAST_STAGE (1 << 31)
52451 :#define TB0C_RESULT_SCALE_1X (0 << 29)
52452 :#define TB0C_RESULT_SCALE_2X (1 << 29)
52453 :#define TB0C_RESULT_SCALE_4X (2 << 29)
52454 :#define TB0C_OP_MODULE (3 << 25)
52455 :#define TB0C_OUTPUT_WRITE_CURRENT (0 << 24)
52456 :#define TB0C_OUTPUT_WRITE_ACCUM (1 << 24)
52457 :#define TB0C_ARG3_REPLICATE_ALPHA (1<<23)
52458 :#define TB0C_ARG3_INVERT (1<<22)
52459 :#define TB0C_ARG3_SEL_XXX
52460 :#define TB0C_ARG2_REPLICATE_ALPHA (1<<17)
52461 :#define TB0C_ARG2_INVERT (1<<16)
52462 :#define TB0C_ARG2_SEL_ONE (0 << 12)
52463 :#define TB0C_ARG2_SEL_FACTOR (1 << 12)
52464 :#define TB0C_ARG2_SEL_TEXEL0 (6 << 12)
52465 :#define TB0C_ARG2_SEL_TEXEL1 (7 << 12)
52466 :#define TB0C_ARG2_SEL_TEXEL2 (8 << 12)
52467 :#define TB0C_ARG2_SEL_TEXEL3 (9 << 12)
52468 :#define TB0C_ARG1_REPLICATE_ALPHA (1<<11)
52469 :#define TB0C_ARG1_INVERT (1<<10)
52470 :#define TB0C_ARG1_SEL_ONE (0 << 6)
52471 :#define TB0C_ARG1_SEL_TEXEL0 (6 << 6)
52472 :#define TB0C_ARG1_SEL_TEXEL1 (7 << 6)
52473 :#define TB0C_ARG1_SEL_TEXEL2 (8 << 6)
52474 :#define TB0C_ARG1_SEL_TEXEL3 (9 << 6)
52475 :#define TB0C_ARG0_REPLICATE_ALPHA (1<<5)
52476 :#define TB0C_ARG0_SEL_XXX
52478 :#define TB0A_CTR_STAGE_ENABLE (1<<31)
52479 :#define TB0A_RESULT_SCALE_1X (0 << 29)
52480 :#define TB0A_RESULT_SCALE_2X (1 << 29)
52481 :#define TB0A_RESULT_SCALE_4X (2 << 29)
52482 :#define TB0A_OP_MODULE (3 << 25)
52483 :#define TB0A_OUTPUT_WRITE_CURRENT (0<<24)
52484 :#define TB0A_OUTPUT_WRITE_ACCUM (1<<24)
52485 :#define TB0A_CTR_STAGE_SEL_BITS_XXX
52486 :#define TB0A_ARG3_SEL_XXX
52487 :#define TB0A_ARG3_INVERT (1<<17)
52488 :#define TB0A_ARG2_INVERT (1<<16)
52489 :#define TB0A_ARG2_SEL_ONE (0 << 12)
52490 :#define TB0A_ARG2_SEL_TEXEL0 (6 << 12)
52491 :#define TB0A_ARG2_SEL_TEXEL1 (7 << 12)
52492 :#define TB0A_ARG2_SEL_TEXEL2 (8 << 12)
52493 :#define TB0A_ARG2_SEL_TEXEL3 (9 << 12)
52494 :#define TB0A_ARG1_INVERT (1<<10)
52495 :#define TB0A_ARG1_SEL_ONE (0 << 6)
52496 :#define TB0A_ARG1_SEL_TEXEL0 (6 << 6)
52497 :#define TB0A_ARG1_SEL_TEXEL1 (7 << 6)
52498 :#define TB0A_ARG1_SEL_TEXEL2 (8 << 6)
52499 :#define TB0A_ARG1_SEL_TEXEL3 (9 << 6)
52501 :static struct blendinfo i830_blend_op[] = {
52503 : {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO},
52505 : {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO},
52507 : {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE},
52509 : {0, 1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA},
52510 : /* OverReverse */
52511 : {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE},
52513 : {1, 0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO},
52515 : {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA},
52517 : {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO},
52519 : {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA},
52521 : {1, 1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
52522 : /* AtopReverse */
52523 : {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA},
52525 : {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA},
52527 : {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ONE},
52530 :static struct formatinfo i830_tex_formats[] = {
52531 : {PICT_a8r8g8b8, MT_32BIT_ARGB8888 },
52532 : {PICT_x8r8g8b8, MT_32BIT_XRGB8888 },
52533 : {PICT_a8b8g8r8, MT_32BIT_ABGR8888 },
52534 : {PICT_x8b8g8r8, MT_32BIT_XBGR8888 },
52535 : {PICT_r5g6b5, MT_16BIT_RGB565 },
52536 : {PICT_a1r5g5b5, MT_16BIT_ARGB1555 },
52537 : {PICT_x1r5g5b5, MT_16BIT_ARGB1555 },
52538 : {PICT_a8, MT_8BIT_A8 },
52541 :static Bool i830_get_dest_format(PicturePtr pDstPicture, CARD32 *dst_format)
52543 : switch (pDstPicture->format) {
52544 : case PICT_a8r8g8b8:
52545 : case PICT_x8r8g8b8:
52546 : *dst_format = COLR_BUF_ARGB8888;
52548 : case PICT_r5g6b5:
52549 : *dst_format = COLR_BUF_RGB565;
52551 : case PICT_a1r5g5b5:
52552 : case PICT_x1r5g5b5:
52553 : *dst_format = COLR_BUF_ARGB1555;
52557 : *dst_format = COLR_BUF_8BIT;
52560 : case PICT_a4r4g4b4:
52561 : case PICT_x4r4g4b4:
52562 : *dst_format = COLR_BUF_ARGB4444;
52565 : I830FALLBACK("Unsupported dest format 0x%x\n",
52566 : (int)pDstPicture->format);
52573 :static CARD32 i830_get_blend_cntl(int op, PicturePtr pMask, CARD32 dst_format)
52575 : CARD32 sblend, dblend;
52577 : sblend = i830_blend_op[op].src_blend;
52578 : dblend = i830_blend_op[op].dst_blend;
52580 : /* If there's no dst alpha channel, adjust the blend op so that we'll treat
52581 : * it as always 1.
52583 : if (PICT_FORMAT_A(dst_format) == 0 && i830_blend_op[op].dst_alpha) {
52584 : if (sblend == BLENDFACTOR_DST_ALPHA)
52585 : sblend = BLENDFACTOR_ONE;
52586 : else if (sblend == BLENDFACTOR_INV_DST_ALPHA)
52587 : sblend = BLENDFACTOR_ZERO;
52590 : /* If the source alpha is being used, then we should only be in a case
52591 : * where the source blend factor is 0, and the source blend value is the
52592 : * mask channels multiplied by the source picture's alpha.
52594 : if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format)
52595 : && i830_blend_op[op].src_alpha) {
52596 : if (dblend == BLENDFACTOR_SRC_ALPHA) {
52597 : dblend = BLENDFACTOR_SRC_COLR;
52598 : } else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) {
52599 : dblend = BLENDFACTOR_INV_SRC_COLR;
52603 : return (sblend << S8_SRC_BLEND_FACTOR_SHIFT) |
52604 : (dblend << S8_DST_BLEND_FACTOR_SHIFT);
52607 :static Bool i830_check_composite_texture(PicturePtr pPict, int unit)
52609 : ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
52610 : I830Ptr pI830 = I830PTR(pScrn);
52611 : int w = pPict->pDrawable->width;
52612 : int h = pPict->pDrawable->height;
52615 : if ((w > 0x7ff) || (h > 0x7ff))
52616 : I830FALLBACK("Picture w/h too large (%dx%d)\n", w, h);
52618 : for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
52621 : if (i830_tex_formats[i].fmt == pPict->format)
52624 : if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]))
52625 : I830FALLBACK("Unsupported picture format 0x%x\n",
52626 : (int)pPict->format);
52628 : if (IS_I830(pI830) || IS_845G(pI830)) {
52629 : if (pPict->format == PICT_x8r8g8b8 ||
52630 : pPict->format == PICT_x8b8g8r8 ||
52631 : pPict->format == PICT_a8)
52632 : I830FALLBACK("830/845G don't support a8, x8r8g8b8, x8b8g8r8\n");
52635 : if (pPict->repeat && pPict->repeatType != RepeatNormal)
52636 : I830FALLBACK("unsupport repeat type\n");
52638 : if (pPict->filter != PictFilterNearest &&
52639 : pPict->filter != PictFilterBilinear)
52641 : I830FALLBACK("Unsupported filter 0x%x\n", pPict->filter);
52648 :i8xx_get_card_format(PicturePtr pPict)
52651 : for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
52654 : if (i830_tex_formats[i].fmt == pPict->format)
52657 : return i830_tex_formats[i].card_fmt;
52661 :i830_texture_setup(PicturePtr pPict, PixmapPtr pPix, int unit)
52664 : ScrnInfoPtr pScrn = xf86Screens[pPict->pDrawable->pScreen->myNum];
52665 : I830Ptr pI830 = I830PTR(pScrn);
52666 : CARD32 format, offset, pitch, filter;
52667 : CARD32 wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
52669 : offset = intel_get_pixmap_offset(pPix);
52670 : pitch = intel_get_pixmap_pitch(pPix);
52671 : pI830->scale_units[unit][0] = pPix->drawable.width;
52672 : pI830->scale_units[unit][1] = pPix->drawable.height;
52673 : pI830->transform[unit] = pPict->transform;
52675 : format = i8xx_get_card_format(pPict);
52677 : if (pPict->repeat)
52678 : wrap_mode = TEXCOORDMODE_WRAP;
52680 : switch (pPict->filter) {
52681 : case PictFilterNearest:
52682 : filter = ((FILTER_NEAREST<<TM0S3_MAG_FILTER_SHIFT) |
52683 : (FILTER_NEAREST<<TM0S3_MIN_FILTER_SHIFT));
52685 : case PictFilterBilinear:
52686 : filter = ((FILTER_LINEAR<<TM0S3_MAG_FILTER_SHIFT) |
52687 : (FILTER_LINEAR<<TM0S3_MIN_FILTER_SHIFT));
52691 : I830FALLBACK("Bad filter 0x%x\n", pPict->filter);
52693 : filter |= (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT);
52696 : if (pPix->drawable.bitsPerPixel == 8)
52697 : format |= MAPSURF_8BIT;
52698 : else if (pPix->drawable.bitsPerPixel == 16)
52699 : format |= MAPSURF_16BIT;
52701 : format |= MAPSURF_32BIT;
52703 : BEGIN_LP_RING(10);
52704 : OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_MAP(unit) | 4);
52705 : OUT_RING((offset & TM0S0_ADDRESS_MASK) | TM0S0_USE_FENCE);
52706 : OUT_RING(((pPix->drawable.height - 1) << TM0S1_HEIGHT_SHIFT) |
52707 : ((pPix->drawable.width - 1) << TM0S1_WIDTH_SHIFT) | format);
52708 : OUT_RING((pitch/4 - 1) << TM0S2_PITCH_SHIFT | TM0S2_MAP_2D);
52709 : OUT_RING(filter);
52710 : OUT_RING(0); /* default color */
52711 : OUT_RING(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) |
52712 : ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL |
52713 : TEXCOORDTYPE_CARTESIAN | ENABLE_ADDR_V_CNTL |
52714 : TEXCOORD_ADDR_V_MODE(wrap_mode) |
52715 : ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode));
52716 : /* map texel stream */
52717 : OUT_RING(_3DSTATE_MAP_COORD_SETBIND_CMD);
52719 : OUT_RING(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) |
52720 : TEXBIND_SET1(TEXCOORDSRC_KEEP) |
52721 : TEXBIND_SET2(TEXCOORDSRC_KEEP) |
52722 : TEXBIND_SET3(TEXCOORDSRC_KEEP));
52724 : OUT_RING(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) |
52725 : TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
52726 : TEXBIND_SET2(TEXCOORDSRC_KEEP) |
52727 : TEXBIND_SET3(TEXCOORDSRC_KEEP));
52728 : OUT_RING(_3DSTATE_MAP_TEX_STREAM_CMD | (unit << 16) |
52729 : DISABLE_TEX_STREAM_BUMP |
52730 : ENABLE_TEX_STREAM_COORD_SET |
52731 : TEX_STREAM_COORD_SET(unit) |
52732 : ENABLE_TEX_STREAM_MAP_IDX |
52733 : TEX_STREAM_MAP_IDX(unit));
52734 : ADVANCE_LP_RING();
52738 : ErrorF("try to sync to show any errors...");
52746 :i830_check_composite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
52747 : PicturePtr pDstPicture)
52751 : /* Check for unsupported compositing operations. */
52752 : if (op >= sizeof(i830_blend_op) / sizeof(i830_blend_op[0]))
52753 : I830FALLBACK("Unsupported Composite op 0x%x\n", op);
52755 : if (pMaskPicture != NULL && pMaskPicture->componentAlpha &&
52756 : PICT_FORMAT_RGB(pMaskPicture->format)) {
52757 : /* Check if it's component alpha that relies on a source alpha and on
52758 : * the source value. We can only get one of those into the single
52759 : * source value that we get to blend with.
52761 : if (i830_blend_op[op].src_alpha &&
52762 : (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO))
52763 : I830FALLBACK("Component alpha not supported with source "
52764 : "alpha and source value blending.\n");
52767 : if (!i830_check_composite_texture(pSrcPicture, 0))
52768 : I830FALLBACK("Check Src picture texture\n");
52769 : if (pMaskPicture != NULL && !i830_check_composite_texture(pMaskPicture, 1))
52770 : I830FALLBACK("Check Mask picture texture\n");
52772 : if (!i830_get_dest_format(pDstPicture, &tmp1))
52773 : I830FALLBACK("Get Color buffer format\n");
52779 :i830_prepare_composite(int op, PicturePtr pSrcPicture,
52780 : PicturePtr pMaskPicture, PicturePtr pDstPicture,
52781 : PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
52783 : ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
52784 : I830Ptr pI830 = I830PTR(pScrn);
52785 : CARD32 dst_format, dst_offset, dst_pitch;
52787 : IntelEmitInvarientState(pScrn);
52788 : *pI830->last_3d = LAST_3D_RENDER;
52790 : i830_get_dest_format(pDstPicture, &dst_format);
52791 : dst_offset = intel_get_pixmap_offset(pDst);
52792 : dst_pitch = intel_get_pixmap_pitch(pDst);
52794 : if (!i830_texture_setup(pSrcPicture, pSrc, 0))
52795 : I830FALLBACK("fail to setup src texture\n");
52796 : if (pMask != NULL) {
52797 : if (!i830_texture_setup(pMaskPicture, pMask, 1))
52798 : I830FALLBACK("fail to setup mask texture\n");
52800 : pI830->transform[1] = NULL;
52801 : pI830->scale_units[1][0] = -1;
52802 : pI830->scale_units[1][1] = -1;
52806 : CARD32 cblend, ablend, blendctl, vf2;
52808 : BEGIN_LP_RING(30);
52810 : /* color buffer */
52811 : OUT_RING(_3DSTATE_BUF_INFO_CMD);
52812 : OUT_RING(BUF_3D_ID_COLOR_BACK| BUF_3D_PITCH(dst_pitch));
52813 : OUT_RING(BUF_3D_ADDR(dst_offset));
52814 : OUT_RING(MI_NOOP);
52816 : OUT_RING(_3DSTATE_DST_BUF_VARS_CMD);
52817 : OUT_RING(dst_format);
52820 : OUT_RING(_3DSTATE_DFLT_Z_CMD);
52823 : OUT_RING(_3DSTATE_DFLT_DIFFUSE_CMD);
52826 : OUT_RING(_3DSTATE_DFLT_SPEC_CMD);
52829 : OUT_RING(_3DSTATE_DRAW_RECT_CMD);
52831 : OUT_RING(0); /* ymin, xmin */
52832 : OUT_RING(DRAW_YMAX(pDst->drawable.height - 1) |
52833 : DRAW_XMAX(pDst->drawable.width - 1));
52834 : OUT_RING(0); /* yorig, xorig */
52836 : OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) |
52837 : I1_LOAD_S(3) | 1);
52839 : vf2 = 2 << 12; /* 2 texture coord sets */
52842 : OUT_RING(vf2); /* TEXCOORDFMT_2D */
52843 : OUT_RING(S3_CULLMODE_NONE | S3_VERTEXHAS_XY);
52845 : /* We use two pipes for color and alpha, and do (src In mask)
52846 : in one stage. Arg1 is from src pict, and arg2 is from mask pict.
52847 : Be sure to force 1.0 when src or mask pict has no alpha channel.
52849 : cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
52850 : TB0C_OUTPUT_WRITE_CURRENT;
52851 : ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE |
52852 : TB0A_OUTPUT_WRITE_CURRENT;
52854 : if (PICT_FORMAT_A(pSrcPicture->format) != 0) {
52855 : ablend |= TB0A_ARG1_SEL_TEXEL0;
52856 : cblend |= TB0C_ARG1_SEL_TEXEL0;
52858 : ablend |= TB0A_ARG1_SEL_ONE;
52859 : if (pMask && pMaskPicture->componentAlpha
52860 : && PICT_FORMAT_RGB(pMaskPicture->format)
52861 : && i830_blend_op[op].src_alpha)
52862 : cblend |= TB0C_ARG1_SEL_ONE;
52864 : cblend |= TB0C_ARG1_SEL_TEXEL0;
52868 : if (pMaskPicture->componentAlpha &&
52869 : PICT_FORMAT_RGB(pMaskPicture->format)) {
52870 : if (i830_blend_op[op].src_alpha)
52871 : cblend |= (TB0C_ARG2_SEL_TEXEL1 |
52872 : TB0C_ARG1_REPLICATE_ALPHA);
52874 : cblend |= TB0C_ARG2_SEL_TEXEL1;
52876 : if (PICT_FORMAT_A(pMaskPicture->format) != 0)
52877 : cblend |= (TB0C_ARG2_SEL_TEXEL1 |
52878 : TB0C_ARG2_REPLICATE_ALPHA);
52880 : cblend |= TB0C_ARG2_SEL_ONE;
52882 : if (PICT_FORMAT_A(pMaskPicture->format) != 0)
52883 : ablend |= TB0A_ARG2_SEL_TEXEL1;
52885 : ablend |= TB0A_ARG2_SEL_ONE;
52887 : cblend |= TB0C_ARG2_SEL_ONE;
52888 : ablend |= TB0A_ARG2_SEL_ONE;
52891 : OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
52892 : LOAD_TEXTURE_BLEND_STAGE(0)|1);
52893 : OUT_RING(cblend);
52894 : OUT_RING(ablend);
52897 : blendctl = i830_get_blend_cntl(op, pMaskPicture, pDstPicture->format);
52898 : OUT_RING(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND);
52899 : OUT_RING(MI_NOOP);
52900 : OUT_RING(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
52901 : OUT_RING(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | blendctl |
52902 : S8_ENABLE_COLOR_BUFFER_WRITE);
52904 : OUT_RING(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP |
52905 : DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS |
52906 : DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST |
52907 : ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST);
52908 : /* We have to explicitly say we don't want write disabled */
52909 : OUT_RING(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK |
52910 : DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE |
52911 : DISABLE_DITHER | ENABLE_COLOR_WRITE |
52912 : DISABLE_DEPTH_WRITE);
52913 : ADVANCE_LP_RING();
52917 : Error("try to sync to show any errors...");
52926 : * Do a single rectangle composite operation.
52928 : * This function is shared between i830 and i915 generation code.
52931 :i830_composite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
52932 : int dstX, int dstY, int w, int h)
52934 : ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
52935 : I830Ptr pI830 = I830PTR(pScrn);
52937 : float src_x[3], src_y[3], mask_x[3], mask_y[3];
52939 : i830_get_transformed_coordinates(srcX, srcY,
52940 : pI830->transform[0],
52941 : &src_x[0], &src_y[0]);
52942 : i830_get_transformed_coordinates(srcX, srcY + h,
52943 : pI830->transform[0],
52944 : &src_x[1], &src_y[1]);
52945 : i830_get_transformed_coordinates(srcX + w, srcY + h,
52946 : pI830->transform[0],
52947 : &src_x[2], &src_y[2]);
52949 : if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) {
52950 : has_mask = FALSE;
52953 : i830_get_transformed_coordinates(maskX, maskY,
52954 : pI830->transform[1],
52955 : &mask_x[0], &mask_y[0]);
52956 : i830_get_transformed_coordinates(maskX, maskY + h,
52957 : pI830->transform[1],
52958 : &mask_x[1], &mask_y[1]);
52959 : i830_get_transformed_coordinates(maskX + w, maskY + h,
52960 : pI830->transform[1],
52961 : &mask_x[2], &mask_y[2]);
52965 : int vertex_count;
52968 : vertex_count = 3*6;
52970 : vertex_count = 3*4;
52972 : BEGIN_LP_RING(6+vertex_count);
52974 : OUT_RING(MI_NOOP);
52975 : OUT_RING(MI_NOOP);
52976 : OUT_RING(MI_NOOP);
52977 : OUT_RING(MI_NOOP);
52978 : OUT_RING(MI_NOOP);
52980 : OUT_RING(PRIM3D_INLINE | PRIM3D_RECTLIST | (vertex_count-1));
52982 : OUT_RING_F(-0.125 + dstX + w);
52983 : OUT_RING_F(-0.125 + dstY + h);
52984 : OUT_RING_F(src_x[2] / pI830->scale_units[0][0]);
52985 : OUT_RING_F(src_y[2] / pI830->scale_units[0][1]);
52987 : OUT_RING_F(mask_x[2] / pI830->scale_units[1][0]);
52988 : OUT_RING_F(mask_y[2] / pI830->scale_units[1][1]);
52991 : OUT_RING_F(-0.125 + dstX);
52992 : OUT_RING_F(-0.125 + dstY + h);
52993 : OUT_RING_F(src_x[1] / pI830->scale_units[0][0]);
52994 : OUT_RING_F(src_y[1] / pI830->scale_units[0][1]);
52996 : OUT_RING_F(mask_x[1] / pI830->scale_units[1][0]);
52997 : OUT_RING_F(mask_y[1] / pI830->scale_units[1][1]);
53000 : OUT_RING_F(-0.125 + dstX);
53001 : OUT_RING_F(-0.125 + dstY);
53002 : OUT_RING_F(src_x[0] / pI830->scale_units[0][0]);
53003 : OUT_RING_F(src_y[0] / pI830->scale_units[0][1]);
53005 : OUT_RING_F(mask_x[0] / pI830->scale_units[1][0]);
53006 : OUT_RING_F(mask_y[0] / pI830->scale_units[1][1]);
53008 : ADVANCE_LP_RING();
53013 : * Do any cleanup from the Composite operation.
53015 : * This is shared between i830 through i965.
53018 :i830_done_composite(PixmapPtr pDst)
53019 2 0.0022 :{ /* i830_done_composite total: 3 0.0033 */
53023 * Total samples for file : "/home/cworth/src/pixman/pixman/pixman-edge.c"
53032 : * Copyright © 2004 Keith Packard
53034 : * Permission to use, copy, modify, distribute, and sell this software and its
53035 : * documentation for any purpose is hereby granted without fee, provided that
53036 : * the above copyright notice appear in all copies and that both that
53037 : * copyright notice and this permission notice appear in supporting
53038 : * documentation, and that the name of Keith Packard not be used in
53039 : * advertising or publicity pertaining to distribution of the software without
53040 : * specific, written prior permission. Keith Packard makes no
53041 : * representations about the suitability of this software for any purpose. It
53042 : * is provided "as is" without express or implied warranty.
53044 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
53045 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
53046 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
53047 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
53048 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
53049 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
53050 : * PERFORMANCE OF THIS SOFTWARE.
53052 :#include <config.h>
53053 :#include <string.h>
53054 :#include "pixman.h"
53055 :#include "pixman-private.h"
53057 :#ifdef PIXMAN_FB_ACCESSORS
53058 :#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors
53060 :#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_no_accessors
53068 :#define rasterizeEdges fbRasterizeEdges4
53070 :#if BITMAP_BIT_ORDER == LSBFirst
53071 :#define Shift4(o) ((o) << 2)
53073 :#define Shift4(o) ((1-(o)) << 2)
53076 :#define Get4(x,o) (((x) >> Shift4(o)) & 0xf)
53077 :#define Put4(x,o,v) (((x) & ~(0xf << Shift4(o))) | (((v) & 0xf) << Shift4(o)))
53079 :#define DefineAlpha(line,x) \
53080 : uint8_t *__ap = (uint8_t *) line + ((x) >> 1); \
53081 : int __ao = (x) & 1
53083 :#define StepAlpha ((__ap += __ao), (__ao ^= 1))
53085 :#define AddAlpha(a) { \
53086 : uint8_t __o = READ(__ap); \
53087 : uint8_t __a = (a) + Get4(__o, __ao); \
53088 : WRITE(__ap, Put4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
53091 :#include "pixman-edge-imp.h"
53095 :#undef DefineAlpha
53096 :#undef rasterizeEdges
53105 :#define rasterizeEdges fbRasterizeEdges1
53107 :#include "pixman-edge-imp.h"
53109 :#undef rasterizeEdges
53116 :static inline uint8_t
53119 : if (x > 255) return 255;
53123 :#define add_saturate_8(buf,val,length) \
53125 : int i__ = (length); \
53126 : uint8_t *buf__ = (buf); \
53127 : int val__ = (val); \
53131 : WRITE((buf__), clip255 (READ((buf__)) + (val__))); \
53137 : * We want to detect the case where we add the same value to a long
53138 : * span of pixels. The triangles on the end are filled in while we
53139 : * count how many sub-pixel scanlines contribute to the middle section.
53141 : * +--------------------------+
53142 : * fill_height =| \ /
53143 : * +------------------+
53144 : * |================|
53145 : * fill_start fill_end
53148 :fbRasterizeEdges8 (pixman_image_t *image,
53149 : pixman_edge_t *l,
53150 : pixman_edge_t *r,
53151 : pixman_fixed_t t,
53152 : pixman_fixed_t b)
53154 : pixman_fixed_t y = t;
53156 : int fill_start = -1, fill_end = -1;
53157 : int fill_size = 0;
53158 : uint32_t *buf = (image)->bits.bits;
53159 : uint32_t stride = (image)->bits.rowstride;
53160 : uint32_t width = (image)->bits.width;
53162 : line = buf + pixman_fixed_to_int (y) * stride;
53166 : uint8_t *ap = (uint8_t *) line;
53167 : pixman_fixed_t lx, rx;
53175 : if (pixman_fixed_to_int (rx) >= width)
53176 : rx = pixman_int_to_fixed (width);
53178 : /* Skip empty (or backwards) sections */
53183 : /* Find pixel bounds for span. */
53184 : lxi = pixman_fixed_to_int (lx);
53185 : rxi = pixman_fixed_to_int (rx);
53187 : /* Sample coverage for edge pixels */
53188 : lxs = RenderSamplesX (lx, 8);
53189 : rxs = RenderSamplesX (rx, 8);
53191 : /* Add coverage across row */
53194 : WRITE(ap +lxi, clip255 (READ(ap + lxi) + rxs - lxs));
53198 : WRITE(ap + lxi, clip255 (READ(ap + lxi) + N_X_FRAC(8) - lxs));
53200 : /* Move forward so that lxi/rxi is the pixel span */
53203 : /* Don't bother trying to optimize the fill unless
53204 : * the span is longer than 4 pixels. */
53205 : if (rxi - lxi > 4)
53207 : if (fill_start < 0)
53209 : fill_start = lxi;
53215 : if (lxi >= fill_end || rxi < fill_start)
53217 : /* We're beyond what we saved, just fill it */
53218 : add_saturate_8 (ap + fill_start,
53219 : fill_size * N_X_FRAC(8),
53220 : fill_end - fill_start);
53221 : fill_start = lxi;
53227 : /* Update fill_start */
53228 : if (lxi > fill_start)
53230 : add_saturate_8 (ap + fill_start,
53231 : fill_size * N_X_FRAC(8),
53232 : lxi - fill_start);
53233 : fill_start = lxi;
53235 : else if (lxi < fill_start)
53237 : add_saturate_8 (ap + lxi, N_X_FRAC(8),
53238 : fill_start - lxi);
53241 : /* Update fill_end */
53242 : if (rxi < fill_end)
53244 : add_saturate_8 (ap + rxi,
53245 : fill_size * N_X_FRAC(8),
53249 : else if (fill_end < rxi)
53251 : add_saturate_8 (ap + fill_end,
53261 : add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi);
53264 : /* Do not add in a 0 alpha here. This check is
53265 : * necessary to avoid a buffer overrun, (when rx
53266 : * is exactly on a pixel boundary). */
53268 : WRITE(ap + rxi, clip255 (READ(ap + rxi) + rxs));
53273 : /* We're done, make sure we clean up any remaining fill. */
53274 : if (fill_start != fill_end) {
53275 : if (fill_size == N_Y_FRAC(8))
53277 : MEMSET_WRAPPED (ap + fill_start, 0xff, fill_end - fill_start);
53281 : add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
53282 : fill_end - fill_start);
53288 : if (pixman_fixed_frac (y) != Y_FRAC_LAST(8))
53290 : RenderEdgeStepSmall (l);
53291 : RenderEdgeStepSmall (r);
53292 : y += STEP_Y_SMALL(8);
53296 : RenderEdgeStepBig (l);
53297 : RenderEdgeStepBig (r);
53298 : y += STEP_Y_BIG(8);
53299 : if (fill_start != fill_end)
53301 : if (fill_size == N_Y_FRAC(8))
53303 : MEMSET_WRAPPED (ap + fill_start, 0xff, fill_end - fill_start);
53307 : add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
53308 : fill_end - fill_start);
53310 : fill_start = fill_end = -1;
53318 :#ifndef PIXMAN_FB_ACCESSORS
53322 :PIXMAN_RASTERIZE_EDGES (pixman_image_t *image,
53323 : pixman_edge_t *l,
53324 : pixman_edge_t *r,
53325 : pixman_fixed_t t,
53326 : pixman_fixed_t b)
53328 : switch (PIXMAN_FORMAT_BPP (image->bits.format))
53331 : fbRasterizeEdges1 (image, l, r, t, b);
53334 : fbRasterizeEdges4 (image, l, r, t, b);
53337 : fbRasterizeEdges8 (image, l, r, t, b);
53342 :#ifndef PIXMAN_FB_ACCESSORS
53345 :pixman_rasterize_edges (pixman_image_t *image,
53346 : pixman_edge_t *l,
53347 : pixman_edge_t *r,
53348 : pixman_fixed_t t,
53349 : pixman_fixed_t b)
53350 :{ /* pixman_rasterize_edges total: 5402 5.8849 */
53351 2 0.0022 : if (image->common.read_func || image->common.write_func)
53353 : return pixman_rasterize_edges_accessors (image, l, r, t, b);
53357 : return pixman_rasterize_edges_no_accessors (image, l, r, t, b);
53363 * Total samples for file : "/home/cworth/src/xorg/xserver/os/WaitFor.c"
53369 :/***********************************************************
53371 :Copyright 1987, 1998 The Open Group
53373 :Permission to use, copy, modify, distribute, and sell this software and its
53374 :documentation for any purpose is hereby granted without fee, provided that
53375 :the above copyright notice appear in all copies and that both that
53376 :copyright notice and this permission notice appear in supporting
53379 :The above copyright notice and this permission notice shall be included in
53380 :all copies or substantial portions of the Software.
53382 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53383 :IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53384 :FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53385 :OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
53386 :AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
53387 :CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
53389 :Except as contained in this notice, the name of The Open Group shall not be
53390 :used in advertising or otherwise to promote the sale, use or other dealings
53391 :in this Software without prior written authorization from The Open Group.
53394 :Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
53396 : All Rights Reserved
53398 :Permission to use, copy, modify, and distribute this software and its
53399 :documentation for any purpose and without fee is hereby granted,
53400 :provided that the above copyright notice appear in all copies and that
53401 :both that copyright notice and this permission notice appear in
53402 :supporting documentation, and that the name of Digital not be
53403 :used in advertising or publicity pertaining to distribution of the
53404 :software without specific, written prior permission.
53406 :DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
53407 :ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
53408 :DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
53409 :ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
53410 :WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
53411 :ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53414 :******************************************************************/
53417 :/*****************************************************************
53418 : * OS Dependent input routines:
53420 : * WaitForSomething
53421 : * TimerForce, TimerSet, TimerCheck, TimerFree
53423 : *****************************************************************/
53425 :#ifdef HAVE_DIX_CONFIG_H
53426 :#include <dix-config.h>
53430 :#include <X11/Xwinsock.h>
53432 :#include <X11/Xos.h> /* for strings, fcntl, time */
53433 :#include <errno.h>
53434 :#include <stdio.h>
53435 :#include <X11/X.h>
53438 :#include "osdep.h"
53439 :#include <X11/Xpoll.h>
53440 :#include "dixstruct.h"
53441 :#include "opaque.h"
53442 :#ifdef DPMSExtension
53443 :#include "dpmsproc.h"
53447 :/* Error codes from windows sockets differ from fileio error codes */
53449 :#define EINTR WSAEINTR
53451 :#define EINVAL WSAEINVAL
53453 :#define EBADF WSAENOTSOCK
53454 :/* Windows select does not set errno. Use GetErrno as wrapper for
53455 : WSAGetLastError */
53456 :#define GetErrno WSAGetLastError
53458 :/* This is just a fallback to errno to hide the differences between unix and
53459 : Windows in the code */
53460 :#define GetErrno() errno
53463 :/* modifications by raphael */
53465 :mffs(fd_mask mask)
53469 : if (!mask) return 0;
53471 : while (!(mask & 1))
53479 :#ifdef DPMSExtension
53480 :#define DPMS_SERVER
53481 :#include <X11/extensions/dpms.h>
53484 :struct _OsTimerRec {
53488 : OsTimerCallback callback;
53492 :static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
53493 :static void CheckAllTimers(void);
53494 :static OsTimerPtr timers = NULL;
53496 :/*****************
53497 : * WaitForSomething:
53498 : * Make the server suspend until there is
53499 : * 1. data from clients or
53500 : * 2. input events available or
53501 : * 3. ddx notices something of interest (graphics
53502 : * queue ready, etc.) or
53503 : * 4. clients that have buffered replies/events are ready
53505 : * If the time between INPUT events is
53506 : * greater than ScreenSaverTime, the display is turned off (or
53507 : * saved, depending on the hardware). So, WaitForSomething()
53508 : * has to handle this also (that's why the select() has a timeout.
53509 : * For more info on ClientsWithInput, see ReadRequestFromClient().
53510 : * pClientsReady is an array to store ready client->index values into.
53511 : *****************/
53514 :WaitForSomething(int *pClientsReady)
53515 :{ /* WaitForSomething total: 2 0.0022 */
53517 : struct timeval waittime, *wt;
53518 : INT32 timeout = 0;
53519 : fd_set clientsReadable;
53520 : fd_set clientsWritable;
53524 : fd_set devicesReadable;
53526 :#ifdef SMART_SCHEDULE
53527 : Bool someReady = FALSE;
53530 : FD_ZERO(&clientsReadable);
53532 : /* We need a while loop here to handle
53533 : crashed connections and the screen saver timeout */
53536 : /* deal with any blocked jobs */
53538 : ProcessWorkQueue();
53539 : if (XFD_ANYSET (&ClientsWithInput))
53541 :#ifdef SMART_SCHEDULE
53542 : if (!SmartScheduleDisable)
53544 : someReady = TRUE;
53545 : waittime.tv_sec = 0;
53546 : waittime.tv_usec = 0;
53552 : XFD_COPYSET (&ClientsWithInput, &clientsReadable);
53556 :#ifdef SMART_SCHEDULE
53559 : XFD_COPYSET(&AllSockets, &LastSelectMask);
53560 : XFD_UNSET(&LastSelectMask, &ClientsWithInput);
53568 : now = GetTimeInMillis();
53569 : timeout = timers->expires - now;
53570 : if (timeout > 0 && timeout > timers->delta + 250) {
53571 : /* time has rewound. reset the timers. */
53572 : CheckAllTimers();
53576 : timeout = timers->expires - now;
53579 : waittime.tv_sec = timeout / MILLI_PER_SECOND;
53580 : waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
53581 : (1000000 / MILLI_PER_SECOND);
53585 : XFD_COPYSET(&AllSockets, &LastSelectMask);
53586 :#ifdef SMART_SCHEDULE
53588 : SmartScheduleIdle = TRUE;
53590 : BlockHandler((pointer)&wt, (pointer)&LastSelectMask);
53591 : if (NewOutputPending)
53592 : FlushAllOutput();
53593 : /* keep this check close to select() call to minimize race */
53594 : if (dispatchException)
53596 : else if (AnyClientsWriteBlocked)
53598 : XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable);
53599 : i = Select (MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
53603 1 0.0011 : i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
53605 : selecterr = GetErrno();
53606 : WakeupHandler(i, (pointer)&LastSelectMask);
53607 :#ifdef SMART_SCHEDULE
53610 : SmartScheduleIdle = FALSE;
53611 : SmartScheduleIdleCount = 0;
53612 : if (SmartScheduleTimerStopped)
53613 : (void) SmartScheduleStartTimer ();
53616 : if (i <= 0) /* An error or timeout occurred */
53618 : if (dispatchException)
53622 : if (selecterr == EBADF) /* Some client disconnected */
53624 : CheckConnections ();
53625 : if (! XFD_ANYSET (&AllClients))
53628 : else if (selecterr == EINVAL)
53630 : FatalError("WaitForSomething(): select: errno=%d\n",
53633 : else if (selecterr != EINTR)
53635 : ErrorF("WaitForSomething(): select: errno=%d\n",
53639 :#ifdef SMART_SCHEDULE
53640 : else if (someReady)
53643 : * If no-one else is home, bail quickly
53645 : XFD_COPYSET(&ClientsWithInput, &LastSelectMask);
53646 : XFD_COPYSET(&ClientsWithInput, &clientsReadable);
53650 : if (*checkForInput[0] != *checkForInput[1])
53656 : now = GetTimeInMillis();
53657 : if ((int) (timers->expires - now) <= 0)
53660 : while (timers && (int) (timers->expires - now) <= 0)
53661 : DoTimer(timers, now, &timers);
53671 : if (*checkForInput[0] == *checkForInput[1]) {
53675 : now = GetTimeInMillis();
53676 : if ((int) (timers->expires - now) <= 0)
53679 : while (timers && (int) (timers->expires - now) <= 0)
53680 : DoTimer(timers, now, &timers);
53686 :#ifdef SMART_SCHEDULE
53688 : XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask);
53690 : if (AnyClientsWriteBlocked && XFD_ANYSET (&clientsWritable))
53692 : NewOutputPending = TRUE;
53693 : XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
53694 : XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
53695 : if (! XFD_ANYSET(&ClientsWriteBlocked))
53696 : AnyClientsWriteBlocked = FALSE;
53699 : XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices);
53700 : XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
53701 : XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections);
53702 : if (XFD_ANYSET(&tmp_set))
53703 : QueueWorkProc(EstablishNewConnections, NULL,
53704 : (pointer)&LastSelectMask);
53706 : if (XFD_ANYSET (&devicesReadable) || XFD_ANYSET (&clientsReadable))
53709 : /* Windows keyboard and mouse events are added to the input queue
53710 : in Block- and WakupHandlers. There is no device to check if
53711 : data is ready. So check here if new input is available */
53712 : if (*checkForInput[0] != *checkForInput[1])
53719 : if (XFD_ANYSET (&clientsReadable))
53722 : for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++)
53724 : int highest_priority = 0;
53726 : while (clientsReadable.fds_bits[i])
53728 : int client_priority, client_index;
53730 : curclient = ffs (clientsReadable.fds_bits[i]) - 1;
53731 1 0.0011 : client_index = /* raphael: modified */
53732 : ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))];
53734 : int highest_priority = 0;
53735 : fd_set savedClientsReadable;
53736 : XFD_COPYSET(&clientsReadable, &savedClientsReadable);
53737 : for (i = 0; i < XFD_SETCOUNT(&savedClientsReadable); i++)
53739 : int client_priority, client_index;
53741 : curclient = XFD_FD(&savedClientsReadable, i);
53742 : client_index = GetConnectionTranslation(curclient);
53745 : /* We implement "strict" priorities.
53746 : * Only the highest priority client is returned to
53747 : * dix. If multiple clients at the same priority are
53748 : * ready, they are all returned. This means that an
53749 : * aggressive client could take over the server.
53750 : * This was not considered a big problem because
53751 : * aggressive clients can hose the server in so many
53754 : client_priority = clients[client_index]->priority;
53755 : if (nready == 0 || client_priority > highest_priority)
53757 : /* Either we found the first client, or we found
53758 : * a client whose priority is greater than all others
53759 : * that have been found so far. Either way, we want
53760 : * to initialize the list of clients to contain just
53763 : pClientsReady[0] = client_index;
53764 : highest_priority = client_priority;
53767 : /* the following if makes sure that multiple same-priority
53768 : * clients get batched together
53770 : else if (client_priority == highest_priority)
53773 : pClientsReady[nready++] = client_index;
53776 : clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient);
53779 : FD_CLR(curclient, &clientsReadable);
53788 : * This is not always a macro.
53790 :ANYSET(FdMask *src)
53794 : for (i=0; i<mskcnt; i++)
53801 :/* If time has rewound, re-run every affected timer.
53802 : * Timers might drop out of the list, so we have to restart every time. */
53804 :CheckAllTimers(void)
53806 : OsTimerPtr timer;
53810 : now = GetTimeInMillis();
53812 : for (timer = timers; timer; timer = timer->next) {
53813 : if (timer->expires - now > timer->delta + 250) {
53814 : TimerForce(timer);
53821 :DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev)
53825 : *prev = timer->next;
53826 : timer->next = NULL;
53827 : newTime = (*timer->callback)(timer, now, timer->arg);
53829 : TimerSet(timer, 0, newTime, timer->callback, timer->arg);
53832 :_X_EXPORT OsTimerPtr
53833 :TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
53834 : OsTimerCallback func, pointer arg)
53836 : register OsTimerPtr *prev;
53837 : CARD32 now = GetTimeInMillis();
53841 : timer = (OsTimerPtr)xalloc(sizeof(struct _OsTimerRec));
53847 : for (prev = &timers; *prev; prev = &(*prev)->next)
53849 : if (*prev == timer)
53851 : *prev = timer->next;
53852 : if (flags & TimerForceOld)
53853 : (void)(*timer->callback)(timer, now, timer->arg);
53860 : if (flags & TimerAbsolute) {
53861 : timer->delta = millis - now;
53864 : timer->delta = millis;
53867 : timer->expires = millis;
53868 : timer->callback = func;
53869 : timer->arg = arg;
53870 : if ((int) (millis - now) <= 0)
53872 : timer->next = NULL;
53873 : millis = (*timer->callback)(timer, now, timer->arg);
53877 : for (prev = &timers;
53878 : *prev && (int) ((*prev)->expires - millis) <= 0;
53879 : prev = &(*prev)->next)
53881 : timer->next = *prev;
53887 :TimerForce(OsTimerPtr timer)
53889 : OsTimerPtr *prev;
53891 : for (prev = &timers; *prev; prev = &(*prev)->next)
53893 : if (*prev == timer)
53895 : DoTimer(timer, GetTimeInMillis(), prev);
53904 :TimerCancel(OsTimerPtr timer)
53906 : OsTimerPtr *prev;
53910 : for (prev = &timers; *prev; prev = &(*prev)->next)
53912 : if (*prev == timer)
53914 : *prev = timer->next;
53921 :TimerFree(OsTimerPtr timer)
53925 : TimerCancel(timer);
53932 : CARD32 now = GetTimeInMillis();
53934 : while (timers && (int) (timers->expires - now) <= 0)
53935 : DoTimer(timers, now, &timers);
53941 : OsTimerPtr timer;
53943 : while ((timer = timers))
53945 : timers = timer->next;
53950 :#ifdef DPMSExtension
53952 :#define DPMS_CHECK_MODE(mode,time)\
53953 : if (time > 0 && DPMSPowerLevel < mode && timeout >= time)\
53956 :#define DPMS_CHECK_TIMEOUT(time)\
53957 : if (time > 0 && (time - timeout) > 0)\
53958 : return time - timeout;
53961 :NextDPMSTimeout(INT32 timeout)
53964 : * Return the amount of time remaining until we should set
53965 : * the next power level. Fallthroughs are intentional.
53967 : switch (DPMSPowerLevel)
53970 : DPMS_CHECK_TIMEOUT(DPMSStandbyTime)
53972 : case DPMSModeStandby:
53973 : DPMS_CHECK_TIMEOUT(DPMSSuspendTime)
53975 : case DPMSModeSuspend:
53976 : DPMS_CHECK_TIMEOUT(DPMSOffTime)
53978 : default: /* DPMSModeOff */
53982 :#endif /* DPMSExtension */
53985 :ScreenSaverTimeoutExpire(OsTimerPtr timer,CARD32 now,pointer arg)
53987 : INT32 timeout = now - lastDeviceEventTime.milliseconds;
53988 : CARD32 nextTimeout = 0;
53990 :#ifdef DPMSExtension
53992 : * Check each mode lowest to highest, since a lower mode can
53993 : * have the same timeout as a higher one.
53997 : DPMS_CHECK_MODE(DPMSModeOff, DPMSOffTime)
53998 : DPMS_CHECK_MODE(DPMSModeSuspend, DPMSSuspendTime)
53999 : DPMS_CHECK_MODE(DPMSModeStandby, DPMSStandbyTime)
54001 : nextTimeout = NextDPMSTimeout(timeout);
54005 : * Only do the screensaver checks if we're not in a DPMS
54006 : * power saving mode
54008 : if (DPMSPowerLevel != DPMSModeOn)
54009 : return nextTimeout;
54010 :#endif /* DPMSExtension */
54012 : if (!ScreenSaverTime)
54013 : return nextTimeout;
54015 : if (timeout < ScreenSaverTime)
54017 : return nextTimeout > 0 ?
54018 : min(ScreenSaverTime - timeout, nextTimeout) :
54019 : ScreenSaverTime - timeout;
54022 : ResetOsBuffers(); /* not ideal, but better than nothing */
54023 : SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
54025 : if (ScreenSaverInterval > 0)
54027 : nextTimeout = nextTimeout > 0 ?
54028 : min(ScreenSaverInterval, nextTimeout) :
54029 : ScreenSaverInterval;
54032 : return nextTimeout;
54035 :static OsTimerPtr ScreenSaverTimer = NULL;
54038 :FreeScreenSaverTimer(void)
54040 : if (ScreenSaverTimer) {
54041 : TimerFree(ScreenSaverTimer);
54042 : ScreenSaverTimer = NULL;
54047 :SetScreenSaverTimer(void)
54049 : CARD32 timeout = 0;
54051 :#ifdef DPMSExtension
54055 : * A higher DPMS level has a timeout that's either less
54056 : * than or equal to that of a lower DPMS level.
54058 : if (DPMSStandbyTime > 0)
54059 : timeout = DPMSStandbyTime;
54061 : else if (DPMSSuspendTime > 0)
54062 : timeout = DPMSSuspendTime;
54064 : else if (DPMSOffTime > 0)
54065 : timeout = DPMSOffTime;
54069 : if (ScreenSaverTime > 0)
54071 : timeout = timeout > 0 ?
54072 : min(ScreenSaverTime, timeout) :
54076 :#ifdef SCREENSAVER
54077 : if (timeout && !screenSaverSuspended) {
54081 : ScreenSaverTimer = TimerSet(ScreenSaverTimer, 0, timeout,
54082 : ScreenSaverTimeoutExpire, NULL);
54084 : else if (ScreenSaverTimer) {
54085 : FreeScreenSaverTimer();
54090 * Total samples for file : "/home/cworth/src/xorg/xserver/fb/fballpriv.c"
54097 : * Copyright © 1998 Keith Packard
54099 : * Permission to use, copy, modify, distribute, and sell this software and its
54100 : * documentation for any purpose is hereby granted without fee, provided that
54101 : * the above copyright notice appear in all copies and that both that
54102 : * copyright notice and this permission notice appear in supporting
54103 : * documentation, and that the name of Keith Packard not be used in
54104 : * advertising or publicity pertaining to distribution of the software without
54105 : * specific, written prior permission. Keith Packard makes no
54106 : * representations about the suitability of this software for any purpose. It
54107 : * is provided "as is" without express or implied warranty.
54109 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
54110 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
54111 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
54112 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
54113 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
54114 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
54115 : * PERFORMANCE OF THIS SOFTWARE.
54118 :#ifdef HAVE_DIX_CONFIG_H
54119 :#include <dix-config.h>
54124 :#ifdef FB_SCREEN_PRIVATE
54125 :int fbScreenPrivateIndex;
54126 :int fbGetScreenPrivateIndex(void)
54128 : return fbScreenPrivateIndex;
54131 :int fbGCPrivateIndex;
54132 :int fbGetGCPrivateIndex(void)
54133 2 0.0022 :{ /* fbGetGCPrivateIndex total: 2 0.0022 */
54134 : return fbGCPrivateIndex;
54136 :#ifndef FB_NO_WINDOW_PIXMAPS
54137 :int fbWinPrivateIndex;
54138 :int fbGetWinPrivateIndex(void)
54140 : return fbWinPrivateIndex;
54145 :#ifdef FB_OLD_SCREEN
54146 :#define miAllocateGCPrivateIndex() AllocateGCPrivateIndex()
54150 :fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex)
54152 : if (fbGeneration != serverGeneration)
54154 : fbGCPrivateIndex = miAllocateGCPrivateIndex ();
54155 :#ifndef FB_NO_WINDOW_PIXMAPS
54156 : fbWinPrivateIndex = AllocateWindowPrivateIndex();
54158 :#ifdef FB_SCREEN_PRIVATE
54159 : fbScreenPrivateIndex = AllocateScreenPrivateIndex ();
54160 : if (fbScreenPrivateIndex == -1)
54164 : fbGeneration = serverGeneration;
54167 : *pGCIndex = fbGCPrivateIndex;
54168 : if (!AllocateGCPrivate(pScreen, fbGCPrivateIndex, sizeof(FbGCPrivRec)))
54170 :#ifndef FB_NO_WINDOW_PIXMAPS
54171 : if (!AllocateWindowPrivate(pScreen, fbWinPrivateIndex, 0))
54174 :#ifdef FB_SCREEN_PRIVATE
54176 : FbScreenPrivPtr pScreenPriv;
54178 : pScreenPriv = (FbScreenPrivPtr) xalloc (sizeof (FbScreenPrivRec));
54179 : if (!pScreenPriv)
54181 : pScreen->devPrivates[fbScreenPrivateIndex].ptr = (pointer) pScreenPriv;
54187 :#ifdef FB_ACCESS_WRAPPER
54188 :ReadMemoryProcPtr wfbReadMemory;
54189 :WriteMemoryProcPtr wfbWriteMemory;
54192 * Total samples for file : "/home/cworth/opt/xorg//include/X11/Xtrans/Xtranssock.c"
54198 :/* $XdotOrg: lib/xtrans/Xtranssock.c,v 1.11 2005/11/08 06:33:26 jkj Exp $ */
54199 :/* $Xorg: Xtranssock.c,v 1.11 2001/02/09 02:04:06 xorgcvs Exp $ */
54202 :Copyright 1993, 1994, 1998 The Open Group
54203 :Copyright 2002 Sun Microsystems, Inc. All rights reserved.
54205 :Permission to use, copy, modify, distribute, and sell this software and its
54206 :documentation for any purpose is hereby granted without fee, provided that
54207 :the above copyright notice appear in all copies and that both that
54208 :copyright notice and this permission notice appear in supporting
54211 :The above copyright notice and this permission notice shall be included
54212 :in all copies or substantial portions of the Software.
54214 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
54215 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54216 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
54217 :IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
54218 :OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
54219 :ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
54220 :OTHER DEALINGS IN THE SOFTWARE.
54222 :Except as contained in this notice, the name of the copyright holders shall
54223 :not be used in advertising or otherwise to promote the sale, use or
54224 :other dealings in this Software without prior written authorization
54225 :from the copyright holders.
54228 :/* $XFree86: xc/lib/xtrans/Xtranssock.c,v 3.68 2004/01/07 04:28:02 dawes Exp $ */
54230 :/* Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
54232 : * All Rights Reserved
54234 : * Permission to use, copy, modify, and distribute this software and its
54235 : * documentation for any purpose and without fee is hereby granted, provided
54236 : * that the above copyright notice appear in all copies and that both that
54237 : * copyright notice and this permission notice appear in supporting
54238 : * documentation, and that the name NCR not be used in advertising
54239 : * or publicity pertaining to distribution of the software without specific,
54240 : * written prior permission. NCR makes no representations about the
54241 : * suitability of this software for any purpose. It is provided "as is"
54242 : * without express or implied warranty.
54244 : * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
54245 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
54246 : * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
54247 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
54248 : * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
54249 : * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
54250 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
54253 :#include <ctype.h>
54255 :#include <X11/Xthreads.h>
54260 :#if defined(TCPCONN) || defined(UNIXCONN)
54261 :#include <sys/socket.h>
54262 :#include <netinet/in.h>
54263 :#include <arpa/inet.h>
54266 :#if defined(TCPCONN) || defined(UNIXCONN)
54267 :#define X_INCLUDE_NETDB_H
54268 :#define XOS_USE_NO_LOCKING
54269 :#include <X11/Xos_r.h>
54273 :#ifndef X_NO_SYS_UN
54275 :#include <sys/un.h>
54280 :#include <sys/stat.h>
54283 :#if defined(hpux) || (defined(MOTOROLA) && defined(SYSV))
54288 :#if defined(__osf__) || defined(linux) || defined(__GLIBC__) || defined(AIXV5)
54289 :#include <sys/param.h>
54291 :#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
54292 :#include <sys/param.h>
54293 :#include <machine/endian.h>
54294 :#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __DragonFly__ */
54295 :#include <netinet/tcp.h>
54296 :#endif /* !NO_TCP_H */
54298 :#include <sys/ioctl.h>
54299 :#if defined(SVR4) && !defined(DGUX) && !defined(_SEQUENT_)
54300 :#include <sys/filio.h>
54303 :#if (defined(i386) && defined(SYSV)) && !defined(SCO325) && !defined(sun)
54304 :#include <net/errno.h>
54307 :#if (defined(i386) && defined(SYSV)) && (!defined(ISC) || !defined(I_NREAD) || defined(SCO325)) || defined(_SEQUENT_)
54308 :#include <sys/stropts.h>
54311 :#else /* !WIN32 */
54313 :#include <X11/Xwinsock.h>
54314 :#include <X11/Xwindows.h>
54315 :#include <X11/Xw32defs.h>
54317 :#define close closesocket
54318 :#define ECONNREFUSED WSAECONNREFUSED
54319 :#define EADDRINUSE WSAEADDRINUSE
54320 :#define EPROTOTYPE WSAEPROTOTYPE
54321 :#undef EWOULDBLOCK
54322 :#define EWOULDBLOCK WSAEWOULDBLOCK
54323 :#define EINPROGRESS WSAEINPROGRESS
54325 :#define EINTR WSAEINTR
54326 :#define X_INCLUDE_NETDB_H
54327 :#define XOS_USE_MTSAFE_NETDBAPI
54328 :#include <X11/Xos_r.h>
54329 :#endif /* WIN32 */
54331 :#if defined(SO_DONTLINGER) && defined(SO_LINGER)
54332 :#undef SO_DONTLINGER
54335 :#if defined(__UNIXOS2__)
54336 :#if defined(NOT_EMX09A)
54337 :static int IBMsockInit = 0;
54338 :#define SocketInitOnce()\
54339 : if (!IBMsockInit) {\
54341 : IBMsockInit = 1;\
54344 :#define EINTR SOCEINTR
54346 :#define EINVAL SOCEINVAL
54348 :#define errno sock_errno()
54350 :#define close soclose
54352 :#define ioctl sockioctl
54354 :#define SocketInitOnce() /**/
54356 :/* this is still not there */
54357 :#define SOCKET int
54359 :/* others don't need this */
54360 :#define SocketInitOnce() /**/
54363 :#define MIN_BACKLOG 128
54365 :#if SOMAXCONN > MIN_BACKLOG
54366 :#define BACKLOG SOMAXCONN
54370 :#define BACKLOG MIN_BACKLOG
54373 : * This is the Socket implementation of the X Transport service layer
54375 : * This file contains the implementation for both the UNIX and INET domains,
54376 : * and can be built for either one, or both.
54380 :typedef struct _Sockettrans2dev {
54386 :} Sockettrans2dev;
54388 :static Sockettrans2dev Sockettrans2devtab[] = {
54390 : {"inet",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
54391 :#if !defined(IPv6) || !defined(AF_INET6)
54392 : {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
54394 : {"tcp",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0},
54395 : {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, /* fallback */
54396 : {"inet6",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0},
54398 :#endif /* TCPCONN */
54400 : {"unix",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
54401 :#if !defined(LOCALCONN)
54402 : {"local",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
54403 :#endif /* !LOCALCONN */
54404 :#endif /* UNIXCONN */
54407 :#define NUMSOCKETFAMILIES (sizeof(Sockettrans2devtab)/sizeof(Sockettrans2dev))
54410 :static int TRANS(SocketINETClose) (XtransConnInfo ciptr);
54417 :#if defined(X11_t)
54418 :#define UNIX_PATH "/usr/spool/sockets/X11/"
54419 :#define UNIX_DIR "/usr/spool/sockets/X11"
54420 :#define OLD_UNIX_PATH "/tmp/.X11-unix/X"
54421 :#endif /* X11_t */
54422 :#if defined(XIM_t)
54423 :#define UNIX_PATH "/usr/spool/sockets/XIM/"
54424 :#define UNIX_DIR "/usr/spool/sockets/XIM"
54425 :#define OLD_UNIX_PATH "/tmp/.XIM-unix/XIM"
54426 :#endif /* XIM_t */
54427 :#if defined(FS_t) || defined(FONT_t)
54428 :#define UNIX_PATH "/usr/spool/sockets/fontserv/"
54429 :#define UNIX_DIR "/usr/spool/sockets/fontserv"
54430 :#endif /* FS_t || FONT_t */
54431 :#if defined(ICE_t)
54432 :#define UNIX_PATH "/usr/spool/sockets/ICE/"
54433 :#define UNIX_DIR "/usr/spool/sockets/ICE"
54434 :#endif /* ICE_t */
54435 :#if defined(TEST_t)
54436 :#define UNIX_PATH "/usr/spool/sockets/xtrans_test/"
54437 :#define UNIX_DIR "/usr/spool/sockets/xtrans_test"
54439 :#if defined(LBXPROXY_t)
54440 :#define UNIX_PATH "/usr/spool/sockets/X11/"
54441 :#define UNIX_DIR "/usr/spool/sockets/X11"
54446 :#if defined(X11_t)
54447 :#define UNIX_PATH "/tmp/.X11-unix/X"
54448 :#define UNIX_DIR "/tmp/.X11-unix"
54449 :#endif /* X11_t */
54450 :#if defined(XIM_t)
54451 :#define UNIX_PATH "/tmp/.XIM-unix/XIM"
54452 :#define UNIX_DIR "/tmp/.XIM-unix"
54453 :#endif /* XIM_t */
54454 :#if defined(FS_t) || defined(FONT_t)
54455 :#define UNIX_PATH "/tmp/.font-unix/fs"
54456 :#define UNIX_DIR "/tmp/.font-unix"
54457 :#endif /* FS_t || FONT_t */
54458 :#if defined(ICE_t)
54459 :#define UNIX_PATH "/tmp/.ICE-unix/"
54460 :#define UNIX_DIR "/tmp/.ICE-unix"
54461 :#endif /* ICE_t */
54462 :#if defined(TEST_t)
54463 :#define UNIX_PATH "/tmp/.Test-unix/test"
54464 :#define UNIX_DIR "/tmp/.Test-unix"
54466 :#if defined(LBXPROXY_t)
54467 :#define UNIX_PATH "/tmp/.X11-unix/X"
54468 :#define UNIX_DIR "/tmp/.X11-unix"
54473 :#endif /* UNIXCONN */
54475 :#define PORTBUFSIZE 32
54477 :#ifndef MAXHOSTNAMELEN
54478 :#define MAXHOSTNAMELEN 255
54482 : * This provides compatibility for apps linked against system libraries
54483 : * that don't have IPv6 support.
54485 :#if defined(IPv6) && defined(AF_INET6)
54486 :static const struct in6_addr local_in6addr_any = IN6ADDR_ANY_INIT;
54487 :#pragma weak in6addr_any = local_in6addr_any
54489 :#pragma weak getaddrinfo
54491 :static int haveIPv6 = 1;
54495 : * These are some utility function used by the real interface function below.
54499 :TRANS(SocketSelectFamily) (int first, char *family)
54504 : PRMSG (3,"SocketSelectFamily(%s)\n", family, 0, 0);
54506 : for (i = first + 1; i < NUMSOCKETFAMILIES;i++)
54508 : if (!strcmp (family, Sockettrans2devtab[i].transname))
54512 : return (first == -1 ? -2 : -1);
54517 : * This function gets the local address of the socket and stores it in the
54518 : * XtransConnInfo structure for the connection.
54522 :TRANS(SocketINETGetAddr) (XtransConnInfo ciptr)
54525 :#if defined(IPv6) && defined(AF_INET6)
54526 : struct sockaddr_storage socknamev6;
54528 : struct sockaddr_in socknamev4;
54529 : void *socknamePtr;
54530 :#if defined(SVR4) || defined(__SCO__)
54536 : PRMSG (3,"SocketINETGetAddr(%p)\n", ciptr, 0, 0);
54538 :#if defined(IPv6) && defined(AF_INET6)
54541 : namelen = sizeof(socknamev6);
54542 : socknamePtr = &socknamev6;
54547 : namelen = sizeof(socknamev4);
54548 : socknamePtr = &socknamev4;
54551 : bzero(socknamePtr, namelen);
54553 : if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr,
54554 : (void *)&namelen) < 0)
54557 : errno = WSAGetLastError();
54559 : PRMSG (1,"SocketINETGetAddr: getsockname() failed: %d\n",
54565 : * Everything looks good: fill in the XtransConnInfo structure.
54568 : if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
54571 : "SocketINETGetAddr: Can't allocate space for the addr\n",
54576 :#if defined(IPv6) && defined(AF_INET6)
54579 : ciptr->family = ((struct sockaddr *)socknamePtr)->sa_family;
54584 : ciptr->family = socknamev4.sin_family;
54586 : ciptr->addrlen = namelen;
54587 : memcpy (ciptr->addr, socknamePtr, ciptr->addrlen);
54594 : * This function gets the remote address of the socket and stores it in the
54595 : * XtransConnInfo structure for the connection.
54599 :TRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr)
54602 :#if defined(IPv6) && defined(AF_INET6)
54603 : struct sockaddr_storage socknamev6;
54605 : struct sockaddr_in socknamev4;
54606 : void *socknamePtr;
54607 :#if defined(SVR4) || defined(__SCO__)
54613 :#if defined(IPv6) && defined(AF_INET6)
54614 : if (haveIPv6 && ciptr->family == AF_INET6)
54616 : namelen = sizeof(socknamev6);
54617 : socknamePtr = &socknamev6;
54622 : namelen = sizeof(socknamev4);
54623 : socknamePtr = &socknamev4;
54626 : bzero(socknamePtr, namelen);
54628 : PRMSG (3,"SocketINETGetPeerAddr(%p)\n", ciptr, 0, 0);
54630 : if (getpeername (ciptr->fd, (struct sockaddr *) socknamePtr,
54631 : (void *)&namelen) < 0)
54634 : errno = WSAGetLastError();
54636 : PRMSG (1,"SocketINETGetPeerAddr: getpeername() failed: %d\n",
54642 : * Everything looks good: fill in the XtransConnInfo structure.
54645 : if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
54648 : "SocketINETGetPeerAddr: Can't allocate space for the addr\n",
54653 : ciptr->peeraddrlen = namelen;
54654 : memcpy (ciptr->peeraddr, socknamePtr, ciptr->peeraddrlen);
54660 :static XtransConnInfo
54661 :TRANS(SocketOpen) (int i, int type)
54664 : XtransConnInfo ciptr;
54666 : PRMSG (3,"SocketOpen(%d,%d)\n", i, type, 0);
54668 :#if defined(IPv6) && defined(AF_INET6)
54669 : if (getaddrinfo == NULL)
54672 : if (!haveIPv6 && Sockettrans2devtab[i].family == AF_INET6)
54676 : if ((ciptr = (XtransConnInfo) xcalloc (
54677 : 1, sizeof(struct _XtransConnInfo))) == NULL)
54679 : PRMSG (1, "SocketOpen: malloc failed\n", 0, 0, 0);
54683 : if ((ciptr->fd = socket(Sockettrans2devtab[i].family, type,
54684 : Sockettrans2devtab[i].protocol)) < 0
54686 :#if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t)
54687 : || ciptr->fd >= TRANS_OPEN_MAX
54692 : errno = WSAGetLastError();
54694 : PRMSG (2, "SocketOpen: socket() failed for %s\n",
54695 : Sockettrans2devtab[i].transname, 0, 0);
54697 : xfree ((char *) ciptr);
54701 :#ifdef TCP_NODELAY
54702 : if (Sockettrans2devtab[i].family == AF_INET
54703 :#if defined(IPv6) && defined(AF_INET6)
54704 : || Sockettrans2devtab[i].family == AF_INET6
54709 : * turn off TCP coalescence for INET sockets
54713 : setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY,
54714 : (char *) &tmp, sizeof (int));
54722 :#ifdef TRANS_REOPEN
54724 :static XtransConnInfo
54725 :TRANS(SocketReopen) (int i, int type, int fd, char *port)
54728 : XtransConnInfo ciptr;
54730 : PRMSG (3,"SocketReopen(%d,%d,%s)\n", type, fd, port);
54732 : if ((ciptr = (XtransConnInfo) xcalloc (
54733 : 1, sizeof(struct _XtransConnInfo))) == NULL)
54735 : PRMSG (1, "SocketReopen: malloc failed\n", 0, 0, 0);
54744 :#endif /* TRANS_REOPEN */
54748 : * These functions are the interface supplied in the Xtransport structure
54751 :#ifdef TRANS_CLIENT
54753 :static XtransConnInfo
54754 :TRANS(SocketOpenCOTSClientBase) (char *transname, char *protocol,
54755 : char *host, char *port, int previndex)
54757 : XtransConnInfo ciptr;
54758 : int i = previndex;
54760 : PRMSG (2, "SocketOpenCOTSClient(%s,%s,%s)\n",
54761 : protocol, host, port);
54763 : SocketInitOnce();
54765 : while ((i = TRANS(SocketSelectFamily) (i, transname)) >= 0) {
54766 : if ((ciptr = TRANS(SocketOpen) (
54767 : i, Sockettrans2devtab[i].devcotsname)) != NULL)
54772 : PRMSG (1,"SocketOpenCOTSClient: Unable to open socket for %s\n",
54773 : transname, 0, 0);
54775 : PRMSG (1,"SocketOpenCOTSClient: Unable to determine socket type for %s\n",
54776 : transname, 0, 0);
54780 : /* Save the index for later use */
54782 : ciptr->index = i;
54787 :static XtransConnInfo
54788 :TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, char *protocol,
54789 : char *host, char *port)
54791 : return TRANS(SocketOpenCOTSClientBase)(
54792 : thistrans->TransName, protocol, host, port, -1);
54796 :#endif /* TRANS_CLIENT */
54799 :#ifdef TRANS_SERVER
54801 :static XtransConnInfo
54802 :TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, char *protocol,
54803 : char *host, char *port)
54806 : XtransConnInfo ciptr;
54809 : PRMSG (2,"SocketOpenCOTSServer(%s,%s,%s)\n", protocol, host, port);
54811 : SocketInitOnce();
54813 : while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
54814 : if ((ciptr = TRANS(SocketOpen) (
54815 : i, Sockettrans2devtab[i].devcotsname)) != NULL)
54820 : PRMSG (1,"SocketOpenCOTSServer: Unable to open socket for %s\n",
54821 : thistrans->TransName, 0, 0);
54823 : PRMSG (1,"SocketOpenCOTSServer: Unable to determine socket type for %s\n",
54824 : thistrans->TransName, 0, 0);
54829 : * Using this prevents the bind() check for an existing server listening
54830 : * on the same port, but it is required for other reasons.
54832 :#ifdef SO_REUSEADDR
54835 : * SO_REUSEADDR only applied to AF_INET && AF_INET6
54838 : if (Sockettrans2devtab[i].family == AF_INET
54839 :#if defined(IPv6) && defined(AF_INET6)
54840 : || Sockettrans2devtab[i].family == AF_INET6
54845 : setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR,
54846 : (char *) &one, sizeof (int));
54849 :#ifdef IPV6_V6ONLY
54850 : if (Sockettrans2devtab[i].family == AF_INET6)
54853 : setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int));
54856 : /* Save the index for later use */
54858 : ciptr->index = i;
54863 :#endif /* TRANS_SERVER */
54866 :#ifdef TRANS_CLIENT
54868 :static XtransConnInfo
54869 :TRANS(SocketOpenCLTSClient) (Xtransport *thistrans, char *protocol,
54870 : char *host, char *port)
54873 : XtransConnInfo ciptr;
54876 : PRMSG (2,"SocketOpenCLTSClient(%s,%s,%s)\n", protocol, host, port);
54878 : SocketInitOnce();
54880 : while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
54881 : if ((ciptr = TRANS(SocketOpen) (
54882 : i, Sockettrans2devtab[i].devcotsname)) != NULL)
54887 : PRMSG (1,"SocketOpenCLTSClient: Unable to open socket for %s\n",
54888 : thistrans->TransName, 0, 0);
54890 : PRMSG (1,"SocketOpenCLTSClient: Unable to determine socket type for %s\n",
54891 : thistrans->TransName, 0, 0);
54895 : /* Save the index for later use */
54897 : ciptr->index = i;
54902 :#endif /* TRANS_CLIENT */
54905 :#ifdef TRANS_SERVER
54907 :static XtransConnInfo
54908 :TRANS(SocketOpenCLTSServer) (Xtransport *thistrans, char *protocol,
54909 : char *host, char *port)
54912 : XtransConnInfo ciptr;
54915 : PRMSG (2,"SocketOpenCLTSServer(%s,%s,%s)\n", protocol, host, port);
54917 : SocketInitOnce();
54919 : while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
54920 : if ((ciptr = TRANS(SocketOpen) (
54921 : i, Sockettrans2devtab[i].devcotsname)) != NULL)
54926 : PRMSG (1,"SocketOpenCLTSServer: Unable to open socket for %s\n",
54927 : thistrans->TransName, 0, 0);
54929 : PRMSG (1,"SocketOpenCLTSServer: Unable to determine socket type for %s\n",
54930 : thistrans->TransName, 0, 0);
54934 :#ifdef IPV6_V6ONLY
54935 : if (Sockettrans2devtab[i].family == AF_INET6)
54938 : setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int));
54941 : /* Save the index for later use */
54943 : ciptr->index = i;
54948 :#endif /* TRANS_SERVER */
54951 :#ifdef TRANS_REOPEN
54953 :static XtransConnInfo
54954 :TRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, char *port)
54957 : XtransConnInfo ciptr;
54961 : "SocketReopenCOTSServer(%d, %s)\n", fd, port, 0);
54963 : SocketInitOnce();
54965 : while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
54966 : if ((ciptr = TRANS(SocketReopen) (
54967 : i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL)
54972 : PRMSG (1,"SocketReopenCOTSServer: Unable to open socket for %s\n",
54973 : thistrans->TransName, 0, 0);
54975 : PRMSG (1,"SocketReopenCOTSServer: Unable to determine socket type for %s\n",
54976 : thistrans->TransName, 0, 0);
54980 : /* Save the index for later use */
54982 : ciptr->index = i;
54987 :static XtransConnInfo
54988 :TRANS(SocketReopenCLTSServer) (Xtransport *thistrans, int fd, char *port)
54991 : XtransConnInfo ciptr;
54995 : "SocketReopenCLTSServer(%d, %s)\n", fd, port, 0);
54997 : SocketInitOnce();
54999 : while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
55000 : if ((ciptr = TRANS(SocketReopen) (
55001 : i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL)
55006 : PRMSG (1,"SocketReopenCLTSServer: Unable to open socket for %s\n",
55007 : thistrans->TransName, 0, 0);
55009 : PRMSG (1,"SocketReopenCLTSServer: Unable to determine socket type for %s\n",
55010 : thistrans->TransName, 0, 0);
55014 : /* Save the index for later use */
55016 : ciptr->index = i;
55021 :#endif /* TRANS_REOPEN */
55025 :TRANS(SocketSetOption) (XtransConnInfo ciptr, int option, int arg)
55028 : PRMSG (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg);
55035 :set_sun_path(const char *port, const char *upath, char *path)
55037 : struct sockaddr_un s;
55038 : int maxlen = sizeof(s.sun_path) - 1;
55040 : if (!port || !*port || !path)
55043 : if (*port == '/') { /* a full pathname */
55044 : if (strlen(port) > maxlen)
55046 : sprintf(path, "%s", port);
55048 : if (strlen(port) + strlen(upath) > maxlen)
55050 : sprintf(path, "%s%s", upath, port);
55056 :#ifdef TRANS_SERVER
55059 :TRANS(SocketCreateListener) (XtransConnInfo ciptr,
55060 : struct sockaddr *sockname,
55061 : int socknamelen, unsigned int flags)
55064 : int namelen = socknamelen;
55065 : int fd = ciptr->fd;
55068 : PRMSG (3, "SocketCreateListener(%x,%p)\n", ciptr, fd, 0);
55070 : if (Sockettrans2devtab[ciptr->index].family == AF_INET
55071 :#if defined(IPv6) && defined(AF_INET6)
55072 : || Sockettrans2devtab[ciptr->index].family == AF_INET6
55079 : while (bind (fd, (struct sockaddr *) sockname, namelen) < 0)
55081 : if (errno == EADDRINUSE) {
55082 : if (flags & ADDR_IN_USE_ALLOWED)
55085 : return TRANS_ADDR_IN_USE;
55088 : if (retry-- == 0) {
55089 : PRMSG (1, "SocketCreateListener: failed to bind listener\n",
55092 : return TRANS_CREATE_LISTENER_FAILED;
55094 :#ifdef SO_REUSEADDR
55098 :#endif /* SO_REUSEDADDR */
55101 : if (Sockettrans2devtab[ciptr->index].family == AF_INET
55102 :#if defined(IPv6) && defined(AF_INET6)
55103 : || Sockettrans2devtab[ciptr->index].family == AF_INET6
55106 :#ifdef SO_DONTLINGER
55107 : setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
55111 : static int linger[2] = { 0, 0 };
55112 : setsockopt (fd, SOL_SOCKET, SO_LINGER,
55113 : (char *) linger, sizeof (linger));
55119 : if (listen (fd, BACKLOG) < 0)
55121 : PRMSG (1, "SocketCreateListener: listen() failed\n", 0, 0, 0);
55123 : return TRANS_CREATE_LISTENER_FAILED;
55126 : /* Set a flag to indicate that this connection is a listener */
55128 : ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
55135 :TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags)
55138 :#if defined(IPv6) && defined(AF_INET6)
55139 : struct sockaddr_storage sockname;
55141 : struct sockaddr_in sockname;
55143 : unsigned short sport;
55144 : int namelen = sizeof(sockname);
55147 :#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
55148 : _Xgetservbynameparams sparams;
55150 : struct servent *servp;
55153 : char portbuf[PORTBUFSIZE];
55156 : PRMSG (2, "SocketINETCreateListener(%s)\n", port, 0, 0);
55160 : * X has a well known port, that is transport dependent. It is easier
55161 : * to handle it here, than try and come up with a transport independent
55162 : * representation that can be passed in and resolved the usual way.
55164 : * The port that is passed here is really a string containing the idisplay
55165 : * from ConnectDisplay().
55168 : if (is_numeric (port))
55170 : /* fixup the server port address */
55171 : tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
55172 : sprintf (portbuf,"%lu", tmpport);
55177 : if (port && *port)
55179 : /* Check to see if the port string is just a number (handles X11) */
55181 : if (!is_numeric (port))
55183 : if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL)
55186 : "SocketINETCreateListener: Unable to get service for %s\n",
55188 : return TRANS_CREATE_LISTENER_FAILED;
55190 : /* we trust getservbyname to return a valid number */
55191 : sport = servp->s_port;
55195 : tmpport = strtol (port, (char**)NULL, 10);
55197 : * check that somehow the port address isn't negative or in
55198 : * the range of reserved port addresses. This can happen and
55199 : * be very bad if the server is suid-root and the user does
55200 : * something (dumb) like `X :60049`.
55202 : if (tmpport < 1024 || tmpport > USHRT_MAX)
55203 : return TRANS_CREATE_LISTENER_FAILED;
55205 : sport = (unsigned short) tmpport;
55211 : bzero(&sockname, sizeof(sockname));
55212 :#if defined(IPv6) && defined(AF_INET6)
55213 : if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
55214 : namelen = sizeof (struct sockaddr_in);
55215 :#ifdef BSD44SOCKETS
55216 : ((struct sockaddr_in *)&sockname)->sin_len = namelen;
55218 : ((struct sockaddr_in *)&sockname)->sin_family = AF_INET;
55219 : ((struct sockaddr_in *)&sockname)->sin_port = htons(sport);
55220 : ((struct sockaddr_in *)&sockname)->sin_addr.s_addr = htonl(INADDR_ANY);
55222 : namelen = sizeof (struct sockaddr_in6);
55224 : ((struct sockaddr_in6 *)&sockname)->sin6_len = sizeof(sockname);
55226 : ((struct sockaddr_in6 *)&sockname)->sin6_family = AF_INET6;
55227 : ((struct sockaddr_in6 *)&sockname)->sin6_port = htons(sport);
55228 : ((struct sockaddr_in6 *)&sockname)->sin6_addr = in6addr_any;
55231 :#ifdef BSD44SOCKETS
55232 : sockname.sin_len = sizeof (sockname);
55234 : sockname.sin_family = AF_INET;
55235 : sockname.sin_port = htons (sport);
55236 : sockname.sin_addr.s_addr = htonl (INADDR_ANY);
55239 : if ((status = TRANS(SocketCreateListener) (ciptr,
55240 : (struct sockaddr *) &sockname, namelen, flags)) < 0)
55243 : "SocketINETCreateListener: ...SocketCreateListener() failed\n",
55248 : if (TRANS(SocketINETGetAddr) (ciptr) < 0)
55251 : "SocketINETCreateListener: ...SocketINETGetAddr() failed\n",
55253 : return TRANS_CREATE_LISTENER_FAILED;
55259 :#endif /* TCPCONN */
55265 :TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, char *port,
55266 : unsigned int flags)
55269 : struct sockaddr_un sockname;
55273 : unsigned int mode;
55275 : PRMSG (2, "SocketUNIXCreateListener(%s)\n",
55276 : port ? port : "NULL", 0, 0);
55278 : /* Make sure the directory is created */
55280 : oldUmask = umask (0);
55283 :#ifdef HAS_STICKY_DIR_BIT
55288 : if (trans_mkdir(UNIX_DIR, mode) == -1) {
55289 : PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n",
55290 : UNIX_DIR, errno, 0);
55291 : (void) umask (oldUmask);
55292 : return TRANS_CREATE_LISTENER_FAILED;
55296 : sockname.sun_family = AF_UNIX;
55298 : if (port && *port) {
55299 : if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) {
55300 : PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0);
55301 : return TRANS_CREATE_LISTENER_FAILED;
55304 : snprintf (sockname.sun_path, sizeof(sockname.sun_path),
55305 : "%s%ld", UNIX_PATH, (long)getpid());
55308 :#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) && !defined(Lynx)
55309 : sockname.sun_len = strlen(sockname.sun_path);
55312 :#if defined(BSD44SOCKETS) || defined(SUN_LEN)
55313 : namelen = SUN_LEN(&sockname);
55315 : namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path);
55318 : unlink (sockname.sun_path);
55320 : if ((status = TRANS(SocketCreateListener) (ciptr,
55321 : (struct sockaddr *) &sockname, namelen, flags)) < 0)
55324 : "SocketUNIXCreateListener: ...SocketCreateListener() failed\n",
55326 : (void) umask (oldUmask);
55331 : * Now that the listener is esablished, create the addr info for
55332 : * this connection. getpeername() doesn't work for UNIX Domain Sockets
55333 : * on some systems (hpux at least), so we will just do it manually, instead
55334 : * of calling something like TRANS(SocketUNIXGetAddr).
55337 : namelen = sizeof (sockname); /* this will always make it the same size */
55339 : if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
55342 : "SocketUNIXCreateListener: Can't allocate space for the addr\n",
55344 : (void) umask (oldUmask);
55345 : return TRANS_CREATE_LISTENER_FAILED;
55348 : ciptr->family = sockname.sun_family;
55349 : ciptr->addrlen = namelen;
55350 : memcpy (ciptr->addr, &sockname, ciptr->addrlen);
55352 : (void) umask (oldUmask);
55359 :TRANS(SocketUNIXResetListener) (XtransConnInfo ciptr)
55363 : * See if the unix domain socket has disappeared. If it has, recreate it.
55366 : struct sockaddr_un *unsock = (struct sockaddr_un *) ciptr->addr;
55367 : struct stat statb;
55368 : int status = TRANS_RESET_NOOP;
55369 : unsigned int mode;
55371 : PRMSG (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd, 0);
55373 : if (stat (unsock->sun_path, &statb) == -1 ||
55374 : ((statb.st_mode & S_IFMT) !=
55375 :#if (defined (sun) && defined(SVR4)) || defined(NCR) || defined(SCO325) || !defined(S_IFSOCK)
55381 : int oldUmask = umask (0);
55384 :#ifdef HAS_STICKY_DIR_BIT
55389 : if (trans_mkdir(UNIX_DIR, mode) == -1) {
55390 : PRMSG (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n",
55391 : UNIX_DIR, errno, 0);
55392 : (void) umask (oldUmask);
55393 : return TRANS_RESET_FAILURE;
55397 : close (ciptr->fd);
55398 : unlink (unsock->sun_path);
55400 : if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
55402 : TRANS(FreeConnInfo) (ciptr);
55403 : (void) umask (oldUmask);
55404 : return TRANS_RESET_FAILURE;
55407 : if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0)
55409 : close (ciptr->fd);
55410 : TRANS(FreeConnInfo) (ciptr);
55411 : return TRANS_RESET_FAILURE;
55414 : if (listen (ciptr->fd, BACKLOG) < 0)
55416 : close (ciptr->fd);
55417 : TRANS(FreeConnInfo) (ciptr);
55418 : (void) umask (oldUmask);
55419 : return TRANS_RESET_FAILURE;
55422 : umask (oldUmask);
55424 : status = TRANS_RESET_NEW_FD;
55430 :#endif /* UNIXCONN */
55435 :static XtransConnInfo
55436 :TRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status)
55439 : XtransConnInfo newciptr;
55440 : struct sockaddr_in sockname;
55441 : int namelen = sizeof(sockname);
55443 : PRMSG (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd, 0);
55445 : if ((newciptr = (XtransConnInfo) xcalloc (
55446 : 1, sizeof(struct _XtransConnInfo))) == NULL)
55448 : PRMSG (1, "SocketINETAccept: malloc failed\n", 0, 0, 0);
55449 : *status = TRANS_ACCEPT_BAD_MALLOC;
55453 : if ((newciptr->fd = accept (ciptr->fd,
55454 : (struct sockaddr *) &sockname, (void *)&namelen)) < 0)
55457 : errno = WSAGetLastError();
55459 : PRMSG (1, "SocketINETAccept: accept() failed\n", 0, 0, 0);
55460 : xfree (newciptr);
55461 : *status = TRANS_ACCEPT_FAILED;
55465 :#ifdef TCP_NODELAY
55468 : * turn off TCP coalescence for INET sockets
55472 : setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY,
55473 : (char *) &tmp, sizeof (int));
55478 : * Get this address again because the transport may give a more
55479 : * specific address now that a connection is established.
55482 : if (TRANS(SocketINETGetAddr) (newciptr) < 0)
55485 : "SocketINETAccept: ...SocketINETGetAddr() failed:\n",
55487 : close (newciptr->fd);
55488 : xfree (newciptr);
55489 : *status = TRANS_ACCEPT_MISC_ERROR;
55493 : if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0)
55496 : "SocketINETAccept: ...SocketINETGetPeerAddr() failed:\n",
55498 : close (newciptr->fd);
55499 : if (newciptr->addr) xfree (newciptr->addr);
55500 : xfree (newciptr);
55501 : *status = TRANS_ACCEPT_MISC_ERROR;
55510 :#endif /* TCPCONN */
55514 :static XtransConnInfo
55515 :TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status)
55518 : XtransConnInfo newciptr;
55519 : struct sockaddr_un sockname;
55520 :#if defined(SVR4) || defined(__SCO__)
55521 : size_t namelen = sizeof sockname;
55523 : int namelen = sizeof sockname;
55526 : PRMSG (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd, 0);
55528 : if ((newciptr = (XtransConnInfo) xcalloc (
55529 : 1, sizeof(struct _XtransConnInfo))) == NULL)
55531 : PRMSG (1, "SocketUNIXAccept: malloc() failed\n", 0, 0, 0);
55532 : *status = TRANS_ACCEPT_BAD_MALLOC;
55536 : if ((newciptr->fd = accept (ciptr->fd,
55537 : (struct sockaddr *) &sockname, (void *)&namelen)) < 0)
55539 : PRMSG (1, "SocketUNIXAccept: accept() failed\n", 0, 0, 0);
55540 : xfree (newciptr);
55541 : *status = TRANS_ACCEPT_FAILED;
55546 : * Get the socket name and the peer name from the listener socket,
55547 : * since this is unix domain.
55550 : if ((newciptr->addr = (char *) xalloc (ciptr->addrlen)) == NULL)
55553 : "SocketUNIXAccept: Can't allocate space for the addr\n",
55555 : close (newciptr->fd);
55556 : xfree (newciptr);
55557 : *status = TRANS_ACCEPT_BAD_MALLOC;
55562 : newciptr->addrlen = ciptr->addrlen;
55563 : memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen);
55565 : if ((newciptr->peeraddr = (char *) xalloc (ciptr->addrlen)) == NULL)
55568 : "SocketUNIXAccept: Can't allocate space for the addr\n",
55570 : close (newciptr->fd);
55571 : if (newciptr->addr) xfree (newciptr->addr);
55572 : xfree (newciptr);
55573 : *status = TRANS_ACCEPT_BAD_MALLOC;
55577 : newciptr->peeraddrlen = ciptr->addrlen;
55578 : memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen);
55580 : newciptr->family = AF_UNIX;
55587 :#endif /* UNIXCONN */
55589 :#endif /* TRANS_SERVER */
55592 :#ifdef TRANS_CLIENT
55596 :#if defined(IPv6) && defined(AF_INET6)
55598 : struct addrinfo * addr;
55599 : struct addrinfo * firstaddr;
55600 : char port[PORTBUFSIZE];
55601 : char host[MAXHOSTNAMELEN];
55603 :static struct addrlist *addrlist = NULL;
55608 :TRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port)
55611 : struct sockaddr * socketaddr = NULL;
55612 : int socketaddrlen = 0;
55614 :#if defined(IPv6) && defined(AF_INET6)
55615 : struct addrinfo hints;
55616 : char ntopbuf[INET6_ADDRSTRLEN];
55617 : int resetonce = 0;
55619 : struct sockaddr_in sockname;
55620 :#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
55621 : _Xgethostbynameparams hparams;
55622 : _Xgetservbynameparams sparams;
55624 : struct hostent *hostp;
55625 : struct servent *servp;
55626 : unsigned long tmpaddr;
55628 : char portbuf[PORTBUFSIZE];
55632 : char hostnamebuf[256]; /* tmp space */
55634 : PRMSG (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port);
55638 : hostnamebuf[0] = '\0';
55639 : (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
55640 : host = hostnamebuf;
55645 : * X has a well known port, that is transport dependent. It is easier
55646 : * to handle it here, than try and come up with a transport independent
55647 : * representation that can be passed in and resolved the usual way.
55649 : * The port that is passed here is really a string containing the idisplay
55650 : * from ConnectDisplay().
55653 : if (is_numeric (port))
55655 : tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
55656 : sprintf (portbuf, "%lu", tmpport);
55661 :#if defined(IPv6) && defined(AF_INET6)
55663 : if (addrlist != NULL) {
55664 : if (strcmp(host,addrlist->host) || strcmp(port,addrlist->port)) {
55665 : if (addrlist->firstaddr)
55666 : freeaddrinfo(addrlist->firstaddr);
55667 : addrlist->firstaddr = NULL;
55670 : addrlist = malloc(sizeof(struct addrlist));
55671 : addrlist->firstaddr = NULL;
55674 : if (addrlist->firstaddr == NULL) {
55675 : strncpy(addrlist->port, port, sizeof(addrlist->port));
55676 : addrlist->port[sizeof(addrlist->port) - 1] = '\0';
55677 : strncpy(addrlist->host, host, sizeof(addrlist->host));
55678 : addrlist->host[sizeof(addrlist->host) - 1] = '\0';
55680 : bzero(&hints,sizeof(hints));
55681 : hints.ai_socktype = Sockettrans2devtab[ciptr->index].devcotsname;
55683 : res = getaddrinfo(host,port,&hints,&addrlist->firstaddr);
55685 : PRMSG (1, "SocketINETConnect() can't get address "
55686 : "for %s:%s: %s\n", host, port, gai_strerror(res));
55688 : return TRANS_CONNECT_FAILED;
55690 : for (res = 0, addrlist->addr = addrlist->firstaddr;
55691 : addrlist->addr ; res++) {
55692 : addrlist->addr = addrlist->addr->ai_next;
55694 : PRMSG(4,"Got New Address list with %d addresses\n", res, 0, 0);
55696 : addrlist->addr = NULL;
55699 : while (socketaddr == NULL) {
55700 : if (addrlist->addr == NULL) {
55702 : /* Already checked entire list - no usable addresses */
55703 : PRMSG (1, "SocketINETConnect() no usable address "
55704 : "for %s:%s\n", host, port, 0);
55705 : return TRANS_CONNECT_FAILED;
55707 : /* Go back to beginning of list */
55709 : addrlist->addr = addrlist->firstaddr;
55713 : socketaddr = addrlist->addr->ai_addr;
55714 : socketaddrlen = addrlist->addr->ai_addrlen;
55716 : if (addrlist->addr->ai_family == AF_INET) {
55717 : struct sockaddr_in *sin = (struct sockaddr_in *) socketaddr;
55719 : PRMSG (4,"SocketINETConnect() sockname.sin_addr = %s\n",
55720 : inet_ntop(addrlist->addr->ai_family,&sin->sin_addr,
55721 : ntopbuf,sizeof(ntopbuf)), 0, 0);
55723 : PRMSG (4,"SocketINETConnect() sockname.sin_port = %d\n",
55724 : ntohs(sin->sin_port), 0, 0);
55726 : if (Sockettrans2devtab[ciptr->index].family == AF_INET6) {
55727 : if (strcmp(Sockettrans2devtab[ciptr->index].transname,
55729 : XtransConnInfo newciptr;
55732 : * Our socket is an IPv6 socket, but the address is
55733 : * IPv4. Close it and get an IPv4 socket. This is
55734 : * needed for IPv4 connections to work on platforms
55735 : * that don't allow IPv4 over IPv6 sockets.
55737 : TRANS(SocketINETClose)(ciptr);
55738 : newciptr = TRANS(SocketOpenCOTSClientBase)(
55739 : "tcp", "tcp", host, port, ciptr->index);
55741 : ciptr->fd = newciptr->fd;
55743 : Sockettrans2devtab[newciptr->index].family !=
55745 : socketaddr = NULL;
55746 : PRMSG (4,"SocketINETConnect() Cannot get IPv4 "
55747 : " socketfor IPv4 address\n", 0,0,0);
55752 : socketaddr = NULL;
55753 : PRMSG (4,"SocketINETConnect Skipping IPv4 address\n",
55757 : } else if (addrlist->addr->ai_family == AF_INET6) {
55758 : struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) socketaddr;
55760 : PRMSG (4,"SocketINETConnect() sockname.sin6_addr = %s\n",
55761 : inet_ntop(addrlist->addr->ai_family,
55762 : &sin6->sin6_addr,ntopbuf,sizeof(ntopbuf)),
55764 : PRMSG (4,"SocketINETConnect() sockname.sin6_port = %d\n",
55765 : ntohs(sin6->sin6_port), 0, 0);
55767 : if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
55768 : if (strcmp(Sockettrans2devtab[ciptr->index].transname,
55770 : XtransConnInfo newciptr;
55773 : * Close the IPv4 socket and try to open an IPv6 socket.
55775 : TRANS(SocketINETClose)(ciptr);
55776 : newciptr = TRANS(SocketOpenCOTSClientBase)(
55777 : "tcp", "tcp", host, port, -1);
55779 : ciptr->fd = newciptr->fd;
55781 : Sockettrans2devtab[newciptr->index].family !=
55783 : socketaddr = NULL;
55784 : PRMSG (4,"SocketINETConnect() Cannot get IPv6 "
55785 : "socket for IPv6 address\n", 0,0,0);
55792 : socketaddr = NULL;
55793 : PRMSG (4,"SocketINETConnect() Skipping IPv6 address\n",
55798 : socketaddr = NULL; /* Unsupported address type */
55800 : if (socketaddr == NULL) {
55801 : addrlist->addr = addrlist->addr->ai_next;
55808 : * Build the socket name.
55811 :#ifdef BSD44SOCKETS
55812 : sockname.sin_len = sizeof (struct sockaddr_in);
55814 : sockname.sin_family = AF_INET;
55817 : * fill in sin_addr
55820 :#ifndef INADDR_NONE
55821 :#define INADDR_NONE ((in_addr_t) 0xffffffff)
55824 : /* check for ww.xx.yy.zz host string */
55826 : if (isascii (host[0]) && isdigit (host[0])) {
55827 : tmpaddr = inet_addr (host); /* returns network byte order */
55829 : tmpaddr = INADDR_NONE;
55832 : PRMSG (4,"SocketINETConnect() inet_addr(%s) = %x\n", host, tmpaddr, 0);
55834 : if (tmpaddr == INADDR_NONE) {
55835 : if ((hostp = _XGethostbyname(host,hparams)) == NULL) {
55836 : PRMSG (1,"SocketINETConnect: Can't get address for %s\n",
55839 : return TRANS_CONNECT_FAILED;
55841 : if (hostp->h_addrtype != AF_INET) { /* is IP host? */
55842 : PRMSG (1,"SocketINETConnect: not INET host%s\n", host, 0, 0);
55843 : ESET(EPROTOTYPE);
55844 : return TRANS_CONNECT_FAILED;
55847 :#if defined(CRAY) && defined(OLDTCP)
55848 : /* Only Cray UNICOS3 and UNICOS4 will define this */
55851 : memcpy ((char *)&t, (char *) hostp->h_addr, sizeof (t));
55852 : sockname.sin_addr = t;
55855 : memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr,
55856 : sizeof (sockname.sin_addr));
55857 :#endif /* CRAY and OLDTCP */
55860 :#if defined(CRAY) && defined(OLDTCP)
55861 : /* Only Cray UNICOS3 and UNICOS4 will define this */
55862 : sockname.sin_addr = tmpaddr;
55864 : sockname.sin_addr.s_addr = tmpaddr;
55865 :#endif /* CRAY and OLDTCP */
55869 : * fill in sin_port
55872 : /* Check for number in the port string */
55874 : if (!is_numeric (port)) {
55875 : if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) {
55876 : PRMSG (1,"SocketINETConnect: can't get service for %s\n",
55878 : return TRANS_CONNECT_FAILED;
55880 : sockname.sin_port = htons (servp->s_port);
55882 : tmpport = strtol (port, (char**)NULL, 10);
55883 : if (tmpport < 1024 || tmpport > USHRT_MAX)
55884 : return TRANS_CONNECT_FAILED;
55885 : sockname.sin_port = htons (((unsigned short) tmpport));
55888 : PRMSG (4,"SocketINETConnect: sockname.sin_port = %d\n",
55889 : ntohs(sockname.sin_port), 0, 0);
55890 : socketaddr = (struct sockaddr *) &sockname;
55891 : socketaddrlen = sizeof(sockname);
55895 : * Turn on socket keepalive so the client process will eventually
55896 : * be notified with a SIGPIPE signal if the display server fails
55897 : * to respond to a periodic transmission of messages
55898 : * on the connected socket.
55899 : * This is useful to avoid hung application processes when the
55900 : * processes are not spawned from the xdm session and
55901 : * the display server terminates abnormally.
55902 : * (Someone turned off the power switch.)
55907 : setsockopt (ciptr->fd, SOL_SOCKET, SO_KEEPALIVE,
55908 : (char *) &tmp, sizeof (int));
55912 : * Do the connect()
55915 : if (connect (ciptr->fd, socketaddr, socketaddrlen ) < 0)
55918 : int olderrno = WSAGetLastError();
55920 : int olderrno = errno;
55924 : * If the error was ECONNREFUSED, the server may be overloaded
55925 : * and we should try again.
55927 : * If the error was EWOULDBLOCK or EINPROGRESS then the socket
55928 : * was non-blocking and we should poll using select
55930 : * If the error was EINTR, the connect was interrupted and we
55931 : * should try again.
55933 : * If multiple addresses are found for a host then we should
55934 : * try to connect again with a different address for a larger
55935 : * number of errors that made us quit before, since those
55936 : * could be caused by trying to use an IPv6 address to contact
55937 : * a machine with an IPv4-only server or other reasons that
55938 : * only affect one of a set of addresses.
55941 : if (olderrno == ECONNREFUSED || olderrno == EINTR
55942 :#if defined(IPv6) && defined(AF_INET6)
55943 : || (haveIPv6 && ((addrlist->addr->ai_next != NULL) ||
55944 : (addrlist->addr != addrlist->firstaddr)) &&
55945 : (olderrno == ENETUNREACH || olderrno == EAFNOSUPPORT ||
55946 : olderrno == EADDRNOTAVAIL || olderrno == ETIMEDOUT
55947 :#if defined(EHOSTDOWN)
55948 : || olderrno == EHOSTDOWN
55953 : res = TRANS_TRY_CONNECT_AGAIN;
55954 : else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS)
55955 : res = TRANS_IN_PROGRESS;
55958 : PRMSG (2,"SocketINETConnect: Can't connect: errno = %d\n",
55961 : res = TRANS_CONNECT_FAILED;
55968 : * Sync up the address fields of ciptr.
55971 : if (TRANS(SocketINETGetAddr) (ciptr) < 0)
55974 : "SocketINETConnect: ...SocketINETGetAddr() failed:\n",
55976 : res = TRANS_CONNECT_FAILED;
55979 : else if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0)
55982 : "SocketINETConnect: ...SocketINETGetPeerAddr() failed:\n",
55984 : res = TRANS_CONNECT_FAILED;
55988 :#if defined(IPv6) && defined(AF_INET6)
55989 : if (haveIPv6 && res != 0) {
55990 : addrlist->addr = addrlist->addr->ai_next;
55997 :#endif /* TCPCONN */
56004 : * Make sure 'host' is really local.
56008 :UnixHostReallyLocal (char *host)
56011 : char hostnamebuf[256];
56013 :#if defined(IPv6) && defined(AF_INET6)
56014 : if (getaddrinfo == NULL)
56018 : TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
56020 : if (strcmp (hostnamebuf, host) == 0)
56024 :#if defined(IPv6) && defined(AF_INET6)
56025 : else if (haveIPv6)
56027 : struct addrinfo *localhostaddr;
56028 : struct addrinfo *otherhostaddr;
56029 : struct addrinfo *i, *j;
56032 : if (getaddrinfo(hostnamebuf, NULL, NULL, &localhostaddr) != 0)
56034 : if (getaddrinfo(host, NULL, NULL, &otherhostaddr) != 0) {
56035 : freeaddrinfo(localhostaddr);
56039 : for (i = localhostaddr; i != NULL && equiv == 0; i = i->ai_next) {
56040 : for (j = otherhostaddr; j != NULL && equiv == 0; j = j->ai_next) {
56041 : if (i->ai_family == j->ai_family) {
56042 : if (i->ai_family == AF_INET) {
56043 : struct sockaddr_in *sinA
56044 : = (struct sockaddr_in *) i->ai_addr;
56045 : struct sockaddr_in *sinB
56046 : = (struct sockaddr_in *) j->ai_addr;
56047 : struct in_addr *A = &sinA->sin_addr;
56048 : struct in_addr *B = &sinB->sin_addr;
56050 : if (memcmp(A,B,sizeof(struct in_addr)) == 0) {
56053 : } else if (i->ai_family == AF_INET6) {
56054 : struct sockaddr_in6 *sinA
56055 : = (struct sockaddr_in6 *) i->ai_addr;
56056 : struct sockaddr_in6 *sinB
56057 : = (struct sockaddr_in6 *) j->ai_addr;
56058 : struct in6_addr *A = &sinA->sin6_addr;
56059 : struct in6_addr *B = &sinB->sin6_addr;
56061 : if (memcmp(A,B,sizeof(struct in6_addr)) == 0) {
56069 : freeaddrinfo(localhostaddr);
56070 : freeaddrinfo(otherhostaddr);
56077 : * A host may have more than one network address. If any of the
56078 : * network addresses of 'host' (specified to the connect call)
56079 : * match any of the network addresses of 'hostname' (determined
56080 : * by TRANS(GetHostname)), then the two hostnames are equivalent,
56081 : * and we know that 'host' is really a local host.
56083 : char specified_local_addr_list[10][4];
56084 : int scount, equiv, i, j;
56085 :#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
56086 : _Xgethostbynameparams hparams;
56088 : struct hostent *hostp;
56090 : if ((hostp = _XGethostbyname (host,hparams)) == NULL)
56094 : while (hostp->h_addr_list[scount] && scount <= 8)
56097 : * The 2nd call to gethostname() overrides the data
56098 : * from the 1st call, so we must save the address list.
56101 : specified_local_addr_list[scount][0] =
56102 : hostp->h_addr_list[scount][0];
56103 : specified_local_addr_list[scount][1] =
56104 : hostp->h_addr_list[scount][1];
56105 : specified_local_addr_list[scount][2] =
56106 : hostp->h_addr_list[scount][2];
56107 : specified_local_addr_list[scount][3] =
56108 : hostp->h_addr_list[scount][3];
56111 : if ((hostp = _XGethostbyname (hostnamebuf,hparams)) == NULL)
56117 : while (i < scount && !equiv)
56121 : while (hostp->h_addr_list[j])
56123 : if ((specified_local_addr_list[i][0] ==
56124 : hostp->h_addr_list[j][0]) &&
56125 : (specified_local_addr_list[i][1] ==
56126 : hostp->h_addr_list[j][1]) &&
56127 : (specified_local_addr_list[i][2] ==
56128 : hostp->h_addr_list[j][2]) &&
56129 : (specified_local_addr_list[i][3] ==
56130 : hostp->h_addr_list[j][3]))
56132 : /* They're equal, so we're done */
56148 :TRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port)
56151 : struct sockaddr_un sockname;
56154 :#if defined(hpux) && defined(X11_t)
56155 : struct sockaddr_un old_sockname;
56160 : PRMSG (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port);
56163 : * Make sure 'host' is really local. If not, we return failure.
56164 : * The reason we make this check is because a process may advertise
56165 : * a "local" network ID for which it can accept connections, but if
56166 : * a process on a remote machine tries to connect to this network ID,
56167 : * we know for sure it will fail.
56170 : if (strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
56173 : "SocketUNIXConnect: Cannot connect to non-local host %s\n",
56175 : return TRANS_CONNECT_FAILED;
56180 : * Check the port.
56183 : if (!port || !*port)
56185 : PRMSG (1,"SocketUNIXConnect: Missing port specification\n",
56187 : return TRANS_CONNECT_FAILED;
56191 : * Build the socket name.
56194 : sockname.sun_family = AF_UNIX;
56196 : if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) {
56197 : PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0);
56198 : return TRANS_CONNECT_FAILED;
56201 :#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) && !defined(Lynx)
56202 : sockname.sun_len = strlen (sockname.sun_path);
56205 :#if defined(BSD44SOCKETS) || defined(SUN_LEN)
56206 : namelen = SUN_LEN (&sockname);
56208 : namelen = strlen (sockname.sun_path) + offsetof(struct sockaddr_un, sun_path);
56212 :#if defined(hpux) && defined(X11_t)
56214 : * This is gross, but it was in Xlib
56216 : old_sockname.sun_family = AF_UNIX;
56217 : if (set_sun_path(port, OLD_UNIX_PATH, old_sockname.sun_path) != 0) {
56218 : PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0);
56219 : return TRANS_CONNECT_FAILED;
56221 : old_namelen = strlen (old_sockname.sun_path) +
56222 : offsetof(struct sockaddr_un, sun_path);
56227 : * Do the connect()
56230 : if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0)
56232 : int olderrno = errno;
56233 : int connected = 0;
56235 :#if defined(hpux) && defined(X11_t)
56236 : if (olderrno == ENOENT)
56238 : if (connect (ciptr->fd,
56239 : (struct sockaddr *) &old_sockname, old_namelen) >= 0)
56244 : olderrno = errno;
56249 : errno = olderrno;
56252 : * If the error was ENOENT, the server may be starting up
56253 : * and we should try again.
56255 : * If the error was EWOULDBLOCK or EINPROGRESS then the socket
56256 : * was non-blocking and we should poll using select
56258 : * If the error was EINTR, the connect was interrupted and we
56259 : * should try again.
56262 : if (olderrno == ENOENT || olderrno == EINTR)
56263 : return TRANS_TRY_CONNECT_AGAIN;
56264 : else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS)
56265 : return TRANS_IN_PROGRESS;
56268 : PRMSG (2,"SocketUNIXConnect: Can't connect: errno = %d\n",
56271 : return TRANS_CONNECT_FAILED;
56277 : * Get the socket name and the peer name from the connect socket,
56278 : * since this is unix domain.
56281 : if ((ciptr->addr = (char *) xalloc(namelen)) == NULL ||
56282 : (ciptr->peeraddr = (char *) xalloc(namelen)) == NULL)
56285 : "SocketUNIXCreateListener: Can't allocate space for the addr\n",
56287 : return TRANS_CONNECT_FAILED;
56290 : ciptr->family = AF_UNIX;
56291 : ciptr->addrlen = namelen;
56292 : ciptr->peeraddrlen = namelen;
56293 : memcpy (ciptr->addr, &sockname, ciptr->addrlen);
56294 : memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
56299 :#endif /* UNIXCONN */
56301 :#endif /* TRANS_CLIENT */
56305 :TRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
56308 : PRMSG (2,"SocketBytesReadable(%p,%d,%p)\n",
56309 : ciptr, ciptr->fd, pend);
56311 : *pend = 0L; /* FIONREAD only returns a short. Zero out upper bits */
56315 : int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
56316 : errno = WSAGetLastError();
56320 :#if (defined(i386) && defined(SYSV) && !defined(SCO325)) || (defined(_SEQUENT_) && _SOCKET_VERSION == 1)
56321 : return ioctl (ciptr->fd, I_NREAD, (char *) pend);
56323 :#if defined(__UNIXOS2__)
56324 : return ioctl (ciptr->fd, FIONREAD, (char*) pend, sizeof(int));
56326 : return ioctl (ciptr->fd, FIONREAD, (char *) pend);
56327 :#endif /* __UNIXOS2__ */
56328 :#endif /* i386 && SYSV || _SEQUENT_ && _SOCKET_VERSION == 1 */
56329 :#endif /* WIN32 */
56334 :TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
56336 1 0.0011 :{ /* _XSERVTransSocketRead total: 2 0.0022 */
56337 : PRMSG (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size);
56339 :#if defined(WIN32) || defined(__UNIXOS2__)
56341 : int ret = recv ((SOCKET)ciptr->fd, buf, size, 0);
56343 : errno = WSAGetLastError();
56348 1 0.0011 : return read (ciptr->fd, buf, size);
56349 :#endif /* WIN32 */
56354 :TRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size)
56357 : PRMSG (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size);
56359 :#if defined(WIN32) || defined(__UNIXOS2__)
56361 : int ret = send ((SOCKET)ciptr->fd, buf, size, 0);
56363 : errno = WSAGetLastError();
56368 : return write (ciptr->fd, buf, size);
56369 :#endif /* WIN32 */
56374 :TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
56377 : PRMSG (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size);
56379 : return READV (ciptr, buf, size);
56384 :TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
56387 : PRMSG (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size);
56389 : return WRITEV (ciptr, buf, size);
56394 :TRANS(SocketDisconnect) (XtransConnInfo ciptr)
56397 : PRMSG (2,"SocketDisconnect(%p,%d)\n", ciptr, ciptr->fd, 0);
56401 : int ret = shutdown (ciptr->fd, 2);
56402 : errno = WSAGetLastError();
56406 : return shutdown (ciptr->fd, 2); /* disallow further sends and receives */
56413 :TRANS(SocketINETClose) (XtransConnInfo ciptr)
56416 : PRMSG (2,"SocketINETClose(%p,%d)\n", ciptr, ciptr->fd, 0);
56420 : int ret = close (ciptr->fd);
56421 : errno = WSAGetLastError();
56425 : return close (ciptr->fd);
56429 :#endif /* TCPCONN */
56434 :TRANS(SocketUNIXClose) (XtransConnInfo ciptr)
56438 : * If this is the server side, then once the socket is closed,
56439 : * it must be unlinked to completely close it
56442 : struct sockaddr_un *sockname = (struct sockaddr_un *) ciptr->addr;
56445 : PRMSG (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd, 0);
56447 : ret = close(ciptr->fd);
56451 : && sockname->sun_family == AF_UNIX
56452 : && sockname->sun_path[0])
56454 : if (!(ciptr->flags & TRANS_NOUNLINK))
56455 : unlink (sockname->sun_path);
56462 :TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr)
56466 : * Don't unlink path.
56471 : PRMSG (2,"SocketUNIXCloseForCloning(%p,%d)\n",
56472 : ciptr, ciptr->fd, 0);
56474 : ret = close(ciptr->fd);
56479 :#endif /* UNIXCONN */
56483 :# ifdef TRANS_SERVER
56484 :static char* tcp_nolisten[] = {
56486 :#if defined(IPv6) && defined(AF_INET6)
56493 :Xtransport TRANS(SocketTCPFuncs) = {
56494 : /* Socket Interface */
56497 :#ifdef TRANS_CLIENT
56498 : TRANS(SocketOpenCOTSClient),
56499 :#endif /* TRANS_CLIENT */
56500 :#ifdef TRANS_SERVER
56502 : TRANS(SocketOpenCOTSServer),
56503 :#endif /* TRANS_SERVER */
56504 :#ifdef TRANS_CLIENT
56505 : TRANS(SocketOpenCLTSClient),
56506 :#endif /* TRANS_CLIENT */
56507 :#ifdef TRANS_SERVER
56508 : TRANS(SocketOpenCLTSServer),
56509 :#endif /* TRANS_SERVER */
56510 :#ifdef TRANS_REOPEN
56511 : TRANS(SocketReopenCOTSServer),
56512 : TRANS(SocketReopenCLTSServer),
56514 : TRANS(SocketSetOption),
56515 :#ifdef TRANS_SERVER
56516 : TRANS(SocketINETCreateListener),
56517 : NULL, /* ResetListener */
56518 : TRANS(SocketINETAccept),
56519 :#endif /* TRANS_SERVER */
56520 :#ifdef TRANS_CLIENT
56521 : TRANS(SocketINETConnect),
56522 :#endif /* TRANS_CLIENT */
56523 : TRANS(SocketBytesReadable),
56524 : TRANS(SocketRead),
56525 : TRANS(SocketWrite),
56526 : TRANS(SocketReadv),
56527 : TRANS(SocketWritev),
56528 : TRANS(SocketDisconnect),
56529 : TRANS(SocketINETClose),
56530 : TRANS(SocketINETClose),
56533 :Xtransport TRANS(SocketINETFuncs) = {
56534 : /* Socket Interface */
56537 :#ifdef TRANS_CLIENT
56538 : TRANS(SocketOpenCOTSClient),
56539 :#endif /* TRANS_CLIENT */
56540 :#ifdef TRANS_SERVER
56542 : TRANS(SocketOpenCOTSServer),
56543 :#endif /* TRANS_SERVER */
56544 :#ifdef TRANS_CLIENT
56545 : TRANS(SocketOpenCLTSClient),
56546 :#endif /* TRANS_CLIENT */
56547 :#ifdef TRANS_SERVER
56548 : TRANS(SocketOpenCLTSServer),
56549 :#endif /* TRANS_SERVER */
56550 :#ifdef TRANS_REOPEN
56551 : TRANS(SocketReopenCOTSServer),
56552 : TRANS(SocketReopenCLTSServer),
56554 : TRANS(SocketSetOption),
56555 :#ifdef TRANS_SERVER
56556 : TRANS(SocketINETCreateListener),
56557 : NULL, /* ResetListener */
56558 : TRANS(SocketINETAccept),
56559 :#endif /* TRANS_SERVER */
56560 :#ifdef TRANS_CLIENT
56561 : TRANS(SocketINETConnect),
56562 :#endif /* TRANS_CLIENT */
56563 : TRANS(SocketBytesReadable),
56564 : TRANS(SocketRead),
56565 : TRANS(SocketWrite),
56566 : TRANS(SocketReadv),
56567 : TRANS(SocketWritev),
56568 : TRANS(SocketDisconnect),
56569 : TRANS(SocketINETClose),
56570 : TRANS(SocketINETClose),
56573 :#if defined(IPv6) && defined(AF_INET6)
56574 :Xtransport TRANS(SocketINET6Funcs) = {
56575 : /* Socket Interface */
56578 :#ifdef TRANS_CLIENT
56579 : TRANS(SocketOpenCOTSClient),
56580 :#endif /* TRANS_CLIENT */
56581 :#ifdef TRANS_SERVER
56583 : TRANS(SocketOpenCOTSServer),
56584 :#endif /* TRANS_SERVER */
56585 :#ifdef TRANS_CLIENT
56586 : TRANS(SocketOpenCLTSClient),
56587 :#endif /* TRANS_CLIENT */
56588 :#ifdef TRANS_SERVER
56589 : TRANS(SocketOpenCLTSServer),
56590 :#endif /* TRANS_SERVER */
56591 :#ifdef TRANS_REOPEN
56592 : TRANS(SocketReopenCOTSServer),
56593 : TRANS(SocketReopenCLTSServer),
56595 : TRANS(SocketSetOption),
56596 :#ifdef TRANS_SERVER
56597 : TRANS(SocketINETCreateListener),
56598 : NULL, /* ResetListener */
56599 : TRANS(SocketINETAccept),
56600 :#endif /* TRANS_SERVER */
56601 :#ifdef TRANS_CLIENT
56602 : TRANS(SocketINETConnect),
56603 :#endif /* TRANS_CLIENT */
56604 : TRANS(SocketBytesReadable),
56605 : TRANS(SocketRead),
56606 : TRANS(SocketWrite),
56607 : TRANS(SocketReadv),
56608 : TRANS(SocketWritev),
56609 : TRANS(SocketDisconnect),
56610 : TRANS(SocketINETClose),
56611 : TRANS(SocketINETClose),
56614 :#endif /* TCPCONN */
56617 :#if !defined(LOCALCONN)
56618 :Xtransport TRANS(SocketLocalFuncs) = {
56619 : /* Socket Interface */
56622 :#ifdef TRANS_CLIENT
56623 : TRANS(SocketOpenCOTSClient),
56624 :#endif /* TRANS_CLIENT */
56625 :#ifdef TRANS_SERVER
56627 : TRANS(SocketOpenCOTSServer),
56628 :#endif /* TRANS_SERVER */
56629 :#ifdef TRANS_CLIENT
56630 : TRANS(SocketOpenCLTSClient),
56631 :#endif /* TRANS_CLIENT */
56632 :#ifdef TRANS_SERVER
56633 : TRANS(SocketOpenCLTSServer),
56634 :#endif /* TRANS_SERVER */
56635 :#ifdef TRANS_REOPEN
56636 : TRANS(SocketReopenCOTSServer),
56637 : TRANS(SocketReopenCLTSServer),
56639 : TRANS(SocketSetOption),
56640 :#ifdef TRANS_SERVER
56641 : TRANS(SocketUNIXCreateListener),
56642 : TRANS(SocketUNIXResetListener),
56643 : TRANS(SocketUNIXAccept),
56644 :#endif /* TRANS_SERVER */
56645 :#ifdef TRANS_CLIENT
56646 : TRANS(SocketUNIXConnect),
56647 :#endif /* TRANS_CLIENT */
56648 : TRANS(SocketBytesReadable),
56649 : TRANS(SocketRead),
56650 : TRANS(SocketWrite),
56651 : TRANS(SocketReadv),
56652 : TRANS(SocketWritev),
56653 : TRANS(SocketDisconnect),
56654 : TRANS(SocketUNIXClose),
56655 : TRANS(SocketUNIXCloseForCloning),
56657 :#endif /* !LOCALCONN */
56658 :# ifdef TRANS_SERVER
56659 :# if !defined(LOCALCONN)
56660 :static char* unix_nolisten[] = { "local" , NULL };
56664 :Xtransport TRANS(SocketUNIXFuncs) = {
56665 : /* Socket Interface */
56667 :#if !defined(LOCALCONN)
56672 :#ifdef TRANS_CLIENT
56673 : TRANS(SocketOpenCOTSClient),
56674 :#endif /* TRANS_CLIENT */
56675 :#ifdef TRANS_SERVER
56676 :#if !defined(LOCALCONN)
56681 : TRANS(SocketOpenCOTSServer),
56682 :#endif /* TRANS_SERVER */
56683 :#ifdef TRANS_CLIENT
56684 : TRANS(SocketOpenCLTSClient),
56685 :#endif /* TRANS_CLIENT */
56686 :#ifdef TRANS_SERVER
56687 : TRANS(SocketOpenCLTSServer),
56688 :#endif /* TRANS_SERVER */
56689 :#ifdef TRANS_REOPEN
56690 : TRANS(SocketReopenCOTSServer),
56691 : TRANS(SocketReopenCLTSServer),
56693 : TRANS(SocketSetOption),
56694 :#ifdef TRANS_SERVER
56695 : TRANS(SocketUNIXCreateListener),
56696 : TRANS(SocketUNIXResetListener),
56697 : TRANS(SocketUNIXAccept),
56698 :#endif /* TRANS_SERVER */
56699 :#ifdef TRANS_CLIENT
56700 : TRANS(SocketUNIXConnect),
56701 :#endif /* TRANS_CLIENT */
56702 : TRANS(SocketBytesReadable),
56703 : TRANS(SocketRead),
56704 : TRANS(SocketWrite),
56705 : TRANS(SocketReadv),
56706 : TRANS(SocketWritev),
56707 : TRANS(SocketDisconnect),
56708 : TRANS(SocketUNIXClose),
56709 : TRANS(SocketUNIXCloseForCloning),
56712 :#endif /* UNIXCONN */
56714 * Total samples for file : "/home/cworth/src/xorg/xserver/fb/fbtrap.c"
56721 : * Copyright © 2004 Keith Packard
56723 : * Permission to use, copy, modify, distribute, and sell this software and its
56724 : * documentation for any purpose is hereby granted without fee, provided that
56725 : * the above copyright notice appear in all copies and that both that
56726 : * copyright notice and this permission notice appear in supporting
56727 : * documentation, and that the name of Keith Packard not be used in
56728 : * advertising or publicity pertaining to distribution of the software without
56729 : * specific, written prior permission. Keith Packard makes no
56730 : * representations about the suitability of this software for any purpose. It
56731 : * is provided "as is" without express or implied warranty.
56733 : * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
56734 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
56735 : * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
56736 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
56737 : * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
56738 : * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
56739 : * PERFORMANCE OF THIS SOFTWARE.
56742 :#ifdef HAVE_DIX_CONFIG_H
56743 :#include <dix-config.h>
56750 :#include "picturestr.h"
56751 :#include "mipict.h"
56752 :#include "renderedge.h"
56753 :#include "fbpict.h"
56756 :fbAddTraps (PicturePtr pPicture,
56762 : pixman_image_t *image = image_from_pict (pPicture, FALSE);
56767 : pixman_add_traps (image, x_off, y_off, ntrap, (pixman_trap_t *)traps);
56769 : fbFinishAccess (pPicture->pDrawable);
56771 : pixman_image_unref (image);
56775 :fbRasterizeTrapezoid (PicturePtr pPicture,
56776 : xTrapezoid *trap,
56779 :{ /* fbRasterizeTrapezoid total: 1 0.0011 */
56780 : pixman_image_t *image = image_from_pict (pPicture, FALSE);
56785 : pixman_rasterize_trapezoid (image, (pixman_trapezoid_t *)trap, x_off, y_off);
56787 : fbFinishAccess (pPicture->pDrawable);
56789 1 0.0011 : pixman_image_unref (image);
56793 :_GreaterY (xPointFixed *a, xPointFixed *b)
56795 : if (a->y == b->y)
56796 : return a->x > b->x;
56797 : return a->y > b->y;
56801 : * Note that the definition of this function is a bit odd because
56802 : * of the X coordinate space (y increasing downwards).
56805 :_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b)
56807 : xPointFixed ad, bd;
56809 : ad.x = a->x - ref->x;
56810 : ad.y = a->y - ref->y;
56811 : bd.x = b->x - ref->x;
56812 : bd.y = b->y - ref->y;
56814 : return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
56817 :/* FIXME -- this could be made more efficient */
56819 :fbAddTriangles (PicturePtr pPicture,
56825 : xPointFixed *top, *left, *right, *tmp;
56828 : for (; ntri; ntri--, tris++)
56831 : left = &tris->p2;
56832 : right = &tris->p3;
56833 : if (_GreaterY (top, left)) {
56834 : tmp = left; left = top; top = tmp;
56836 : if (_GreaterY (top, right)) {
56837 : tmp = right; right = top; top = tmp;
56839 : if (_Clockwise (top, right, left)) {
56840 : tmp = right; right = left; left = tmp;
56856 : trap.top = top->y;
56857 : trap.left.p1 = *top;
56858 : trap.left.p2 = *left;
56859 : trap.right.p1 = *top;
56860 : trap.right.p2 = *right;
56861 : if (right->y < left->y)
56862 : trap.bottom = right->y;
56864 : trap.bottom = left->y;
56865 : fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
56866 : if (right->y < left->y)
56868 : trap.top = right->y;
56869 : trap.bottom = left->y;
56870 : trap.right.p1 = *right;
56871 : trap.right.p2 = *left;
56875 : trap.top = left->y;
56876 : trap.bottom = right->y;
56877 : trap.left.p1 = *left;
56878 : trap.left.p2 = *right;
56880 : fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
56884 :#endif /* RENDER */
56886 * Total samples for file : "/home/cworth/opt/xorg//include/X11/Xtrans/Xtrans.c"
56892 :/* $XdotOrg: xc/lib/xtrans/Xtrans.c,v 1.4 2004/11/15 15:06:56 ago Exp $ */
56893 :/* $Xorg: Xtrans.c,v 1.4 2001/02/09 02:04:06 xorgcvs Exp $ */
56896 :Copyright 1993, 1994, 1998 The Open Group
56898 :Permission to use, copy, modify, distribute, and sell this software and its
56899 :documentation for any purpose is hereby granted without fee, provided that
56900 :the above copyright notice appear in all copies and that both that
56901 :copyright notice and this permission notice appear in supporting
56904 :The above copyright notice and this permission notice shall be included
56905 :in all copies or substantial portions of the Software.
56907 :THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
56908 :OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
56909 :MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
56910 :IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
56911 :OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
56912 :ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
56913 :OTHER DEALINGS IN THE SOFTWARE.
56915 :Except as contained in this notice, the name of The Open Group shall
56916 :not be used in advertising or otherwise to promote the sale, use or
56917 :other dealings in this Software without prior written authorization
56918 :from The Open Group.
56921 :/* $XFree86: xc/lib/xtrans/Xtrans.c,v 3.33 2003/08/11 17:41:29 eich Exp $ */
56923 :/* Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
56925 : * All Rights Reserved
56927 : * Permission to use, copy, modify, and distribute this software and its
56928 : * documentation for any purpose and without fee is hereby granted, provided
56929 : * that the above copyright notice appear in all copies and that both that
56930 : * copyright notice and this permission notice appear in supporting
56931 : * documentation, and that the name NCR not be used in advertising
56932 : * or publicity pertaining to distribution of the software without specific,
56933 : * written prior permission. NCR makes no representations about the
56934 : * suitability of this software for any purpose. It is provided "as is"
56935 : * without express or implied warranty.
56937 : * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
56938 : * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
56939 : * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
56940 : * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
56941 : * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
56942 : * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
56943 : * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
56946 :#include <ctype.h>
56949 : * The transport table contains a definition for every transport (protocol)
56950 : * family. All operations that can be made on the transport go through this
56953 : * Each transport is assigned a unique transport id.
56955 : * New transports can be added by adding an entry in this table.
56956 : * For compatiblity, the transport ids should never be renumbered.
56957 : * Always add to the end of the list.
56960 :#define TRANS_TLI_INET_INDEX 1
56961 :#define TRANS_TLI_TCP_INDEX 2
56962 :#define TRANS_TLI_TLI_INDEX 3
56963 :#define TRANS_SOCKET_UNIX_INDEX 4
56964 :#define TRANS_SOCKET_LOCAL_INDEX 5
56965 :#define TRANS_SOCKET_INET_INDEX 6
56966 :#define TRANS_SOCKET_TCP_INDEX 7
56967 :#define TRANS_DNET_INDEX 8
56968 :#define TRANS_LOCAL_LOCAL_INDEX 9
56969 :#define TRANS_LOCAL_PTS_INDEX 10
56970 :#define TRANS_LOCAL_NAMED_INDEX 11
56971 :#define TRANS_LOCAL_ISC_INDEX 12
56972 :#define TRANS_LOCAL_SCO_INDEX 13
56973 :#define TRANS_SOCKET_INET6_INDEX 14
56974 :#define TRANS_LOCAL_PIPE_INDEX 15
56978 :Xtransport_table Xtransports[] = {
56979 :#if defined(STREAMSCONN)
56980 : { &TRANS(TLITCPFuncs), TRANS_TLI_TCP_INDEX },
56981 : { &TRANS(TLIINETFuncs), TRANS_TLI_INET_INDEX },
56982 : { &TRANS(TLITLIFuncs), TRANS_TLI_TLI_INDEX },
56983 :#endif /* STREAMSCONN */
56984 :#if defined(TCPCONN)
56985 : { &TRANS(SocketTCPFuncs), TRANS_SOCKET_TCP_INDEX },
56986 :#if defined(IPv6) && defined(AF_INET6)
56987 : { &TRANS(SocketINET6Funcs), TRANS_SOCKET_INET6_INDEX },
56989 : { &TRANS(SocketINETFuncs), TRANS_SOCKET_INET_INDEX },
56990 :#endif /* TCPCONN */
56991 :#if defined(DNETCONN)
56992 : { &TRANS(DNETFuncs), TRANS_DNET_INDEX },
56993 :#endif /* DNETCONN */
56994 :#if defined(UNIXCONN)
56995 :#if !defined(LOCALCONN)
56996 : { &TRANS(SocketLocalFuncs), TRANS_SOCKET_LOCAL_INDEX },
56997 :#endif /* !LOCALCONN */
56998 : { &TRANS(SocketUNIXFuncs), TRANS_SOCKET_UNIX_INDEX },
56999 :#endif /* UNIXCONN */
57000 :#if defined(OS2PIPECONN)
57001 : { &TRANS(OS2LocalFuncs), TRANS_LOCAL_LOCAL_INDEX },
57002 :#endif /* OS2PIPECONN */
57003 :#if defined(LOCALCONN)
57004 : { &TRANS(LocalFuncs), TRANS_LOCAL_LOCAL_INDEX },
57006 : { &TRANS(PTSFuncs), TRANS_LOCAL_PTS_INDEX },
57009 : { &TRANS(NAMEDFuncs), TRANS_LOCAL_NAMED_INDEX },
57012 : { &TRANS(PIPEFuncs), TRANS_LOCAL_PIPE_INDEX },
57014 :#if !defined(__SCO__) && !defined(__UNIXWARE__)
57015 : { &TRANS(ISCFuncs), TRANS_LOCAL_ISC_INDEX },
57017 : { &TRANS(SCOFuncs), TRANS_LOCAL_SCO_INDEX },
57019 :#endif /* LOCALCONN */
57022 :#define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table))
57026 :#define ioctl ioctlsocket
57032 : * These are a few utility function used by the public interface functions.
57036 :TRANS(FreeConnInfo) (XtransConnInfo ciptr)
57039 : PRMSG (3,"FreeConnInfo(%p)\n", ciptr, 0, 0);
57042 : xfree (ciptr->addr);
57044 : if (ciptr->peeraddr)
57045 : xfree (ciptr->peeraddr);
57048 : xfree (ciptr->port);
57050 : xfree ((char *) ciptr);
57054 :#define PROTOBUFSIZE 20
57056 :static Xtransport *
57057 :TRANS(SelectTransport) (char *protocol)
57060 : char protobuf[PROTOBUFSIZE];
57063 : PRMSG (3,"SelectTransport(%s)\n", protocol, 0, 0);
57066 : * Force Protocol to be lowercase as a way of doing
57067 : * a case insensitive match.
57070 : strncpy (protobuf, protocol, PROTOBUFSIZE - 1);
57071 : protobuf[PROTOBUFSIZE-1] = '\0';
57073 : for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++)
57074 : if (isupper (protobuf[i]))
57075 : protobuf[i] = tolower (protobuf[i]);
57077 : /* Look at all of the configured protocols */
57079 : for (i = 0; i < NUMTRANS; i++)
57081 : if (!strcmp (protobuf, Xtransports[i].transport->TransName))
57082 : return Xtransports[i].transport;
57090 :#endif /* TEST_t */
57092 :TRANS(ParseAddress) (char *address, char **protocol, char **host, char **port)
57096 : * For the font library, the address is a string formatted
57097 : * as "protocol/host:port[/catalogue]". Note that the catologue
57098 : * is optional. At this time, the catologue info is ignored, but
57099 : * we have to parse it anyways.
57101 : * Other than fontlib, the address is a string formatted
57102 : * as "protocol/host:port".
57104 : * If the protocol part is missing, then assume TCP.
57105 : * If the protocol part and host part are missing, then assume local.
57106 : * If a "::" is found then assume DNET.
57109 : char *mybuf, *tmpptr;
57110 : char *_protocol, *_host, *_port;
57111 : char hostnamebuf[256];
57114 : PRMSG (3,"ParseAddress(%s)\n", address, 0, 0);
57116 : /* Copy the string so it can be changed */
57118 : tmpptr = mybuf = (char *) xalloc (strlen (address) + 1);
57119 : strcpy (mybuf, address);
57121 : /* Parse the string to get each component */
57123 : /* Get the protocol part */
57125 : _protocol = mybuf;
57128 : if ( ((mybuf = strchr (mybuf,'/')) == NULL) &&
57129 : ((mybuf = strrchr (tmpptr,':')) == NULL) )
57131 : /* address is in a bad format */
57132 : *protocol = NULL;
57139 : if (*mybuf == ':')
57142 : * If there is a hostname, then assume tcp, otherwise
57143 : * it must be local.
57145 : if (mybuf == tmpptr)
57147 : /* There is neither a protocol or host specified */
57148 : _protocol = "local";
57152 : /* There is a hostname specified */
57153 : _protocol = "tcp";
57154 : mybuf = tmpptr; /* reset to the begining of the host ptr */
57159 : /* *mybuf == '/' */
57161 : *mybuf ++= '\0'; /* put a null at the end of the protocol */
57163 : if (strlen(_protocol) == 0)
57166 : * If there is a hostname, then assume tcp, otherwise
57167 : * it must be local.
57169 : if (*mybuf != ':')
57170 : _protocol = "tcp";
57172 : _protocol = "local";
57176 : /* Get the host part */
57180 : if ((mybuf = strrchr (mybuf,':')) == NULL)
57182 : *protocol = NULL;
57189 : /* Check for DECnet */
57191 : if ((mybuf != _host) && (*(mybuf - 1) == ':')
57192 :#if defined(IPv6) && defined(AF_INET6)
57193 : /* An IPv6 address can end in :: so three : in a row is assumed to be
57194 : an IPv6 host and not a DECnet node with a : in it's name, unless
57195 : DECnet is specifically requested */
57196 : && ( ((mybuf - 1) == _host) || (*(mybuf - 2) != ':') ||
57197 : ((_protocol != NULL) && (strcmp(_protocol, "dnet") == 0)) )
57201 : _protocol = "dnet";
57202 : *(mybuf - 1) = '\0';
57207 : _host_len = strlen(_host);
57208 : if (_host_len == 0)
57210 : TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
57211 : _host = hostnamebuf;
57213 :#if defined(IPv6) && defined(AF_INET6)
57214 : /* hostname in IPv6 [numeric_addr]:0 form? */
57215 : else if ( (_host_len > 3) &&
57216 : ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0))
57217 : && (*_host == '[') && (*(_host + _host_len - 1) == ']') ) {
57218 : struct sockaddr_in6 sin6;
57220 : *(_host + _host_len - 1) = '\0';
57222 : /* Verify address is valid IPv6 numeric form */
57223 : if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) {
57224 : /* It is. Use it as such. */
57226 : _protocol = "inet6";
57228 : /* It's not, restore it just in case some other code can use it. */
57229 : *(_host + _host_len - 1) = ']';
57235 : /* Get the port */
57239 :#if defined(FONT_t) || defined(FS_t)
57241 : * Is there an optional catalogue list?
57244 : if ((mybuf = strchr (mybuf,'/')) != NULL)
57248 : * The rest, if any, is the (currently unused) catalogue list.
57250 : * _catalogue = mybuf;
57255 : * Now that we have all of the components, allocate new
57256 : * string space for them.
57259 : if ((*protocol = (char *) xalloc(strlen (_protocol) + 1)) == NULL)
57261 : /* Malloc failed */
57264 : *protocol = NULL;
57269 : strcpy (*protocol, _protocol);
57271 : if ((*host = (char *) xalloc (strlen (_host) + 1)) == NULL)
57273 : /* Malloc failed */
57276 : xfree (*protocol);
57277 : *protocol = NULL;
57282 : strcpy (*host, _host);
57284 : if ((*port = (char *) xalloc (strlen (_port) + 1)) == NULL)
57286 : /* Malloc failed */
57290 : xfree (*protocol);
57291 : *protocol = NULL;
57296 : strcpy (*port, _port);
57305 : * TRANS(Open) does all of the real work opening a connection. The only
57306 : * funny part about this is the type parameter which is used to decide which
57307 : * type of open to perform.
57310 :static XtransConnInfo
57311 :TRANS(Open) (int type, char *address)
57314 : char *protocol = NULL, *host = NULL, *port = NULL;
57315 : XtransConnInfo ciptr = NULL;
57316 : Xtransport *thistrans;
57318 : PRMSG (2,"Open(%d,%s)\n", type, address, 0);
57320 :#if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
57321 : if (TRANS(WSAStartup)())
57323 : PRMSG (1,"Open: WSAStartup failed\n", 0, 0, 0);
57328 : /* Parse the Address */
57330 : if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
57332 : PRMSG (1,"Open: Unable to Parse address %s\n", address, 0, 0);
57336 : /* Determine the transport type */
57338 : if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL)
57340 : PRMSG (1,"Open: Unable to find transport for %s\n",
57343 : xfree (protocol);
57349 : /* Open the transport */
57353 : case XTRANS_OPEN_COTS_CLIENT:
57354 :#ifdef TRANS_CLIENT
57355 : ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port);
57356 :#endif /* TRANS_CLIENT */
57358 : case XTRANS_OPEN_COTS_SERVER:
57359 :#ifdef TRANS_SERVER
57360 : ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port);
57361 :#endif /* TRANS_SERVER */
57363 : case XTRANS_OPEN_CLTS_CLIENT:
57364 :#ifdef TRANS_CLIENT
57365 : ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port);
57366 :#endif /* TRANS_CLIENT */
57368 : case XTRANS_OPEN_CLTS_SERVER:
57369 :#ifdef TRANS_SERVER
57370 : ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port);
57371 :#endif /* TRANS_SERVER */
57374 : PRMSG (1,"Open: Unknown Open type %d\n", type, 0, 0);
57377 : if (ciptr == NULL)
57379 : if (!(thistrans->flags & TRANS_DISABLED))
57381 : PRMSG (1,"Open: transport open failed for %s/%s:%s\n",
57382 : protocol, host, port);
57384 : xfree (protocol);
57390 : ciptr->transptr = thistrans;
57391 : ciptr->port = port; /* We need this for TRANS(Reopen) */
57393 : xfree (protocol);
57400 :#ifdef TRANS_REOPEN
57403 : * We might want to create an XtransConnInfo object based on a previously
57404 : * opened connection. For example, the font server may clone itself and
57405 : * pass file descriptors to the parent.
57408 :static XtransConnInfo
57409 :TRANS(Reopen) (int type, int trans_id, int fd, char *port)
57412 : XtransConnInfo ciptr = NULL;
57413 : Xtransport *thistrans = NULL;
57417 : PRMSG (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port);
57419 : /* Determine the transport type */
57421 : for (i = 0; i < NUMTRANS; i++)
57422 : if (Xtransports[i].transport_id == trans_id)
57424 : thistrans = Xtransports[i].transport;
57428 : if (thistrans == NULL)
57430 : PRMSG (1,"Reopen: Unable to find transport id %d\n",
57436 : if ((save_port = (char *) xalloc (strlen (port) + 1)) == NULL)
57438 : PRMSG (1,"Reopen: Unable to malloc port string\n", 0, 0, 0);
57443 : strcpy (save_port, port);
57445 : /* Get a new XtransConnInfo object */
57449 : case XTRANS_OPEN_COTS_SERVER:
57450 : ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port);
57452 : case XTRANS_OPEN_CLTS_SERVER:
57453 : ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port);
57456 : PRMSG (1,"Reopen: Bad Open type %d\n", type, 0, 0);
57459 : if (ciptr == NULL)
57461 : PRMSG (1,"Reopen: transport open failed\n", 0, 0, 0);
57465 : ciptr->transptr = thistrans;
57466 : ciptr->port = save_port;
57471 :#endif /* TRANS_REOPEN */
57476 : * These are the public interfaces to this Transport interface.
57477 : * These are the only functions that should have knowledge of the transport
57481 :#ifdef TRANS_CLIENT
57484 :TRANS(OpenCOTSClient) (char *address)
57487 : PRMSG (2,"OpenCOTSClient(%s)\n", address, 0, 0);
57488 : return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address);
57491 :#endif /* TRANS_CLIENT */
57494 :#ifdef TRANS_SERVER
57497 :TRANS(OpenCOTSServer) (char *address)
57500 : PRMSG (2,"OpenCOTSServer(%s)\n", address, 0, 0);
57501 : return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address);
57504 :#endif /* TRANS_SERVER */
57507 :#ifdef TRANS_CLIENT
57510 :TRANS(OpenCLTSClient) (char *address)
57513 : PRMSG (2,"OpenCLTSClient(%s)\n", address, 0, 0);
57514 : return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address);
57517 :#endif /* TRANS_CLIENT */
57520 :#ifdef TRANS_SERVER
57523 :TRANS(OpenCLTSServer) (char *address)
57526 : PRMSG (2,"OpenCLTSServer(%s)\n", address, 0, 0);
57527 : return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address);
57530 :#endif /* TRANS_SERVER */
57533 :#ifdef TRANS_REOPEN
57536 :TRANS(ReopenCOTSServer) (int trans_id, int fd, char *port)
57539 : PRMSG (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port);
57540 : return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port);
57544 :TRANS(ReopenCLTSServer) (int trans_id, int fd, char *port)
57547 : PRMSG (2,"ReopenCLTSServer(%d, %d, %s)\n", trans_id, fd, port);
57548 : return TRANS(Reopen) (XTRANS_OPEN_CLTS_SERVER, trans_id, fd, port);
57553 :TRANS(GetReopenInfo) (XtransConnInfo ciptr,
57554 : int *trans_id, int *fd, char **port)
57559 : for (i = 0; i < NUMTRANS; i++)
57560 : if (Xtransports[i].transport == ciptr->transptr)
57562 : *trans_id = Xtransports[i].transport_id;
57565 : if ((*port = (char *) xalloc (strlen (ciptr->port) + 1)) == NULL)
57569 : strcpy (*port, ciptr->port);
57577 :#endif /* TRANS_REOPEN */
57581 :TRANS(SetOption) (XtransConnInfo ciptr, int option, int arg)
57584 : int fd = ciptr->fd;
57587 : PRMSG (2,"SetOption(%d,%d,%d)\n", fd, option, arg);
57590 : * For now, all transport type use the same stuff for setting options.
57591 : * As long as this is true, we can put the common code here. Once a more
57592 : * complicated transport such as shared memory or an OSI implementation
57593 : * that uses the session and application libraries is implemented, this
57594 : * code may have to move to a transport dependent function.
57596 : * ret = ciptr->transptr->SetOption (ciptr, option, arg);
57601 : case TRANS_NONBLOCKING:
57605 : /* Set to blocking mode */
57607 : case 1: /* Set to non-blocking mode */
57609 :#if defined(O_NONBLOCK) && (!defined(ultrix) && !defined(hpux) && !defined(AIXV3) && !defined(uniosu) && !defined(__UNIXOS2__) && !defined(SCO325)) && !defined(__QNX__)
57610 : ret = fcntl (fd, F_GETFL, 0);
57612 : ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK);
57618 : ret = ioctl (fd, FIOSNBIO, &arg);
57621 :#if (defined(AIXV3) || defined(uniosu) || defined(WIN32) || defined(__UNIXOS2__) || defined(__QNX__)) && defined(FIONBIO)
57629 :/* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail
57630 : * eventually with EWOULDBLOCK */
57631 :#ifndef __UNIXOS2__
57632 : ret = ioctl (fd, FIONBIO, &arg);
57634 :/* ret = ioctl(fd, FIONBIO, &arg, sizeof(int));*/
57638 : ret = fcntl (fd, F_GETFL, 0);
57640 : ret = fcntl (fd, F_SETFL, ret | FNDELAY);
57642 : ret = fcntl (fd, F_SETFL, ret | O_NDELAY);
57644 :#endif /* AIXV3 || uniosu */
57645 :#endif /* FIOSNBIO */
57646 :#endif /* O_NONBLOCK */
57649 : /* Unknown option */
57653 : case TRANS_CLOSEONEXEC:
57656 : ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
57658 : ret = fcntl (fd, F_SETFD, 1);
57659 :#endif /* FD_CLOEXEC */
57660 :#endif /* F_SETFD */
57667 :#ifdef TRANS_SERVER
57670 :TRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags)
57673 : return ciptr->transptr->CreateListener (ciptr, port, flags);
57677 :TRANS(NoListen) (char * protocol)
57680 : Xtransport *trans;
57681 : int i = 0, ret = 0;
57683 : if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
57685 : PRMSG (1,"TransNoListen: unable to find transport: %s\n",
57690 : if (trans->flags & TRANS_ALIAS) {
57691 : if (trans->nolisten)
57692 : while (trans->nolisten[i]) {
57693 : ret |= TRANS(NoListen)(trans->nolisten[i]);
57698 : trans->flags |= TRANS_NOLISTEN;
57703 :TRANS(ResetListener) (XtransConnInfo ciptr)
57706 : if (ciptr->transptr->ResetListener)
57707 : return ciptr->transptr->ResetListener (ciptr);
57709 : return TRANS_RESET_NOOP;
57714 :TRANS(Accept) (XtransConnInfo ciptr, int *status)
57717 : XtransConnInfo newciptr;
57719 : PRMSG (2,"Accept(%d)\n", ciptr->fd, 0, 0);
57721 : newciptr = ciptr->transptr->Accept (ciptr, status);
57724 : newciptr->transptr = ciptr->transptr;
57729 :#endif /* TRANS_SERVER */
57732 :#ifdef TRANS_CLIENT
57735 :TRANS(Connect) (XtransConnInfo ciptr, char *address)
57743 : PRMSG (2,"Connect(%d,%s)\n", ciptr->fd, address, 0);
57745 : if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
57747 : PRMSG (1,"Connect: Unable to Parse address %s\n",
57752 : if (!port || !*port)
57754 : PRMSG (1,"Connect: Missing port specification in %s\n",
57756 : if (protocol) xfree (protocol);
57757 : if (host) xfree (host);
57761 : ret = ciptr->transptr->Connect (ciptr, host, port);
57763 : if (protocol) xfree (protocol);
57764 : if (host) xfree (host);
57765 : if (port) xfree (port);
57770 :#endif /* TRANS_CLIENT */
57774 :TRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
57777 : return ciptr->transptr->BytesReadable (ciptr, pend);
57781 :TRANS(Read) (XtransConnInfo ciptr, char *buf, int size)
57783 :{ /* _XSERVTransRead total: 1 0.0011 */
57784 1 0.0011 : return ciptr->transptr->Read (ciptr, buf, size);
57788 :TRANS(Write) (XtransConnInfo ciptr, char *buf, int size)
57791 : return ciptr->transptr->Write (ciptr, buf, size);
57795 :TRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size)
57798 : return ciptr->transptr->Readv (ciptr, buf, size);
57802 :TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size)
57805 : return ciptr->transptr->Writev (ciptr, buf, size);
57809 :TRANS(Disconnect) (XtransConnInfo ciptr)
57812 : return ciptr->transptr->Disconnect (ciptr);
57816 :TRANS(Close) (XtransConnInfo ciptr)
57821 : PRMSG (2,"Close(%d)\n", ciptr->fd, 0, 0);
57823 : ret = ciptr->transptr->Close (ciptr);
57825 : TRANS(FreeConnInfo) (ciptr);
57831 :TRANS(CloseForCloning) (XtransConnInfo ciptr)
57836 : PRMSG (2,"CloseForCloning(%d)\n", ciptr->fd, 0, 0);
57838 : ret = ciptr->transptr->CloseForCloning (ciptr);
57840 : TRANS(FreeConnInfo) (ciptr);
57846 :TRANS(IsLocal) (XtransConnInfo ciptr)
57849 : return (ciptr->family == AF_UNIX);
57854 :TRANS(GetMyAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
57855 : Xtransaddr **addrp)
57858 : PRMSG (2,"GetMyAddr(%d)\n", ciptr->fd, 0, 0);
57860 : *familyp = ciptr->family;
57861 : *addrlenp = ciptr->addrlen;
57863 : if ((*addrp = (Xtransaddr *) xalloc (ciptr->addrlen)) == NULL)
57865 : PRMSG (1,"GetMyAddr: malloc failed\n", 0, 0, 0);
57868 : memcpy(*addrp, ciptr->addr, ciptr->addrlen);
57874 :TRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
57875 : Xtransaddr **addrp)
57878 : PRMSG (2,"GetPeerAddr(%d)\n", ciptr->fd, 0, 0);
57880 : *familyp = ciptr->family;
57881 : *addrlenp = ciptr->peeraddrlen;
57883 : if ((*addrp = (Xtransaddr *) xalloc (ciptr->peeraddrlen)) == NULL)
57885 : PRMSG (1,"GetPeerAddr: malloc failed\n", 0, 0, 0);
57888 : memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen);
57895 :TRANS(GetConnectionNumber) (XtransConnInfo ciptr)
57898 : return ciptr->fd;
57903 : * These functions are really utility functions, but they require knowledge
57904 : * of the internal data structures, so they have to be part of the Transport
57905 : * Independant API.
57908 :#ifdef TRANS_SERVER
57911 :complete_network_count (void)
57915 : int found_local = 0;
57919 : * For a complete network, we only need one LOCALCONN transport to work
57922 : for (i = 0; i < NUMTRANS; i++)
57924 : if (Xtransports[i].transport->flags & TRANS_ALIAS
57925 : || Xtransports[i].transport->flags & TRANS_NOLISTEN)
57928 : if (Xtransports[i].transport->flags & TRANS_LOCAL)
57934 : return (count + found_local);
57940 :TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret,
57941 : XtransConnInfo **ciptrs_ret)
57944 : char buffer[256]; /* ??? What size ?? */
57945 : XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
57946 : int status, i, j;
57947 :#if defined(IPv6) && defined(AF_INET6)
57948 : int ipv6_succ = 0;
57951 : PRMSG (2,"MakeAllCOTSServerListeners(%s,%p)\n",
57952 : port ? port : "NULL", ciptrs_ret, 0);
57956 : for (i = 0; i < NUMTRANS; i++)
57958 : Xtransport *trans = Xtransports[i].transport;
57959 : unsigned int flags = 0;
57961 : if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
57964 : snprintf(buffer, sizeof(buffer), "%s/:%s",
57965 : trans->TransName, port ? port : "");
57967 : PRMSG (5,"MakeAllCOTSServerListeners: opening %s\n",
57970 : if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
57972 : if (trans->flags & TRANS_DISABLED)
57976 : "MakeAllCOTSServerListeners: failed to open listener for %s\n",
57977 : trans->TransName, 0, 0);
57980 :#if defined(IPv6) && defined(AF_INET6)
57981 : if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX
57983 : flags |= ADDR_IN_USE_ALLOWED;
57986 : if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0)
57988 : if (status == TRANS_ADDR_IN_USE)
57991 : * We failed to bind to the specified address because the
57992 : * address is in use. It must be that a server is already
57993 : * running at this address, and this function should fail.
57997 : "MakeAllCOTSServerListeners: server already running\n",
58000 : for (j = 0; j < *count_ret; j++)
58001 : TRANS(Close) (temp_ciptrs[j]);
58004 : *ciptrs_ret = NULL;
58011 : "MakeAllCOTSServerListeners: failed to create listener for %s\n",
58012 : trans->TransName, 0, 0);
58018 :#if defined(IPv6) && defined(AF_INET6)
58019 : if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX)
58024 : "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
58025 : trans->TransName, ciptr->fd, 0);
58027 : temp_ciptrs[*count_ret] = ciptr;
58031 : *partial = (*count_ret < complete_network_count());
58034 : "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
58035 : *partial, *count_ret, complete_network_count());
58037 : if (*count_ret > 0)
58039 : if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
58040 : *count_ret * sizeof (XtransConnInfo))) == NULL)
58045 : for (i = 0; i < *count_ret; i++)
58047 : (*ciptrs_ret)[i] = temp_ciptrs[i];
58051 : *ciptrs_ret = NULL;
58057 :TRANS(MakeAllCLTSServerListeners) (char *port, int *partial, int *count_ret,
58058 : XtransConnInfo **ciptrs_ret)
58061 : char buffer[256]; /* ??? What size ?? */
58062 : XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
58063 : int status, i, j;
58065 : PRMSG (2,"MakeAllCLTSServerListeners(%s,%p)\n",
58066 : port ? port : "NULL", ciptrs_ret, 0);
58070 : for (i = 0; i < NUMTRANS; i++)
58072 : Xtransport *trans = Xtransports[i].transport;
58074 : if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
58077 : snprintf(buffer, sizeof(buffer), "%s/:%s",
58078 : trans->TransName, port ? port : "");
58080 : PRMSG (5,"MakeAllCLTSServerListeners: opening %s\n",
58083 : if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL)
58086 : "MakeAllCLTSServerListeners: failed to open listener for %s\n",
58087 : trans->TransName, 0, 0);
58091 : if ((status = TRANS(CreateListener (ciptr, port, 0))) < 0)
58093 : if (status == TRANS_ADDR_IN_USE)
58096 : * We failed to bind to the specified address because the
58097 : * address is in use. It must be that a server is already
58098 : * running at this address, and this function should fail.
58102 : "MakeAllCLTSServerListeners: server already running\n",
58105 : for (j = 0; j < *count_ret; j++)
58106 : TRANS(Close) (temp_ciptrs[j]);
58109 : *ciptrs_ret = NULL;
58116 : "MakeAllCLTSServerListeners: failed to create listener for %s\n",
58117 : trans->TransName, 0, 0);
58124 : "MakeAllCLTSServerListeners: opened listener for %s, %d\n",
58125 : trans->TransName, ciptr->fd, 0);
58126 : temp_ciptrs[*count_ret] = ciptr;
58130 : *partial = (*count_ret < complete_network_count());
58133 : "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n",
58134 : *partial, *count_ret, complete_network_count());
58136 : if (*count_ret > 0)
58138 : if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
58139 : *count_ret * sizeof (XtransConnInfo))) == NULL)
58144 : for (i = 0; i < *count_ret; i++)
58146 : (*ciptrs_ret)[i] = temp_ciptrs[i];
58150 : *ciptrs_ret = NULL;
58155 :#endif /* TRANS_SERVER */
58160 : * These routines are not part of the X Transport Interface, but they
58161 : * may be used by it.
58167 : * Cray UniCOS does not have readv and writev so we emulate
58170 :static int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
58173 : struct msghdr hdr;
58175 : hdr.msg_iov = iov;
58176 : hdr.msg_iovlen = iovcnt;
58177 : hdr.msg_accrights = 0;
58178 : hdr.msg_accrightslen = 0;
58179 : hdr.msg_name = 0;
58180 : hdr.msg_namelen = 0;
58182 : return (recvmsg (ciptr->fd, &hdr, 0));
58185 :static int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
58188 : struct msghdr hdr;
58190 : hdr.msg_iov = iov;
58191 : hdr.msg_iovlen = iovcnt;
58192 : hdr.msg_accrights = 0;
58193 : hdr.msg_accrightslen = 0;
58194 : hdr.msg_name = 0;
58195 : hdr.msg_namelen = 0;
58197 : return (sendmsg (ciptr->fd, &hdr, 0));
58202 :#if (defined(SYSV) && defined(i386) && !defined(__SCO__) && !defined(sun)) || defined(WIN32) || defined(__sxg__) || defined(__UNIXOS2__)
58208 :static int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
58211 : int i, len, total;
58215 : for (i = 0, total = 0; i < iovcnt; i++, iov++) {
58216 : len = iov->iov_len;
58217 : base = iov->iov_base;
58218 : while (len > 0) {
58219 : register int nbytes;
58220 : nbytes = TRANS(Read) (ciptr, base, len);
58221 : if (nbytes < 0 && total == 0) return -1;
58222 : if (nbytes <= 0) return total;
58232 :#endif /* SYSV && i386 || WIN32 || __sxg__ */
58234 :#if (defined(SYSV) && defined(i386) && !defined(__SCO__) && !defined(sun)) || defined(WIN32) || defined(__sxg__) || defined(__UNIXOS2__)
58240 :static int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
58243 : int i, len, total;
58247 : for (i = 0, total = 0; i < iovcnt; i++, iov++) {
58248 : len = iov->iov_len;
58249 : base = iov->iov_base;
58250 : while (len > 0) {
58251 : register int nbytes;
58252 : nbytes = TRANS(Write) (ciptr, base, len);
58253 : if (nbytes < 0 && total == 0) return -1;
58254 : if (nbytes <= 0) return total;
58264 :#endif /* SYSV && i386 || WIN32 || __sxg__ */
58267 :#if (defined(_POSIX_SOURCE) && !defined(AIXV3) && !defined(__QNX__)) || defined(hpux) || defined(USG) || defined(SVR4) || defined(__SCO__)
58268 :#ifndef NEED_UTSNAME
58269 :#define NEED_UTSNAME
58271 :#include <sys/utsname.h>
58275 : * TRANS(GetHostname) - similar to gethostname but allows special processing.
58278 :int TRANS(GetHostname) (char *buf, int maxlen)
58283 :#ifdef NEED_UTSNAME
58284 : struct utsname name;
58287 : len = strlen (name.nodename);
58288 : if (len >= maxlen) len = maxlen - 1;
58289 : strncpy (buf, name.nodename, len);
58293 : (void) gethostname (buf, maxlen);
58294 : buf [maxlen - 1] = '\0';
58295 : len = strlen(buf);
58296 :#endif /* NEED_UTSNAME */