~ubuntu-branches/ubuntu/edgy/xorg-server/edgy-updates

« back to all changes in this revision

Viewing changes to hw/kdrive/i810/i810_video.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Parra Novo
  • Date: 2006-07-25 20:06:28 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060725200628-gjmmd9gxfxdc4ejs
Tags: 1:1.1.1-0ubuntu1
* New Upstream version
* Changed Build-Depends from mesa-swrast-source to mesa-swx11-source,
  following Debian package nomenclature
* Re-did 12_security_policy_in_etc.diff for 1.1.1
* Dropped 15_security_allocate_local.diff (applied upstream)
* Dropped 16_SECURITY_setuid.diff (applied upstream)
* Dropped 000_ubuntu_fix_read_kernel_mapping.patch (applied upstream)
* Dropped 002_ubuntu_fix_for_certain_intel_chipsets.patch (applied upstream)
* Updated versioned Build-Depends on mesa-swx11-source to version
  6.5.0.cvs.20060725-0ubuntu1
* Added arrayobj.c, arrayobj.h, bitset.h & rbadaptors.h to
  GL/symlink-mesa.sh (linked from mesa-swx11-source)
* Added arrayobj.c to default build target on GL/mesa/main

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* COPYRIGHT AND PERMISSION NOTICE
 
2
 
 
3
Copyright (c) 2000, 2001 Nokia Home Communications
 
4
 
 
5
All rights reserved.
 
6
 
 
7
Permission is hereby granted, free of charge, to any person obtaining
 
8
a copy of this software and associated documentation files (the
 
9
"Software"), to deal in the Software without restriction, including
 
10
without limitation the rights to use, copy, modify, merge, publish,
 
11
distribute, and/or sell copies of the Software, and to permit persons
 
12
to whom the Software is furnished to do so, provided that the above
 
13
copyright notice(s) and this permission notice appear in all copies of
 
14
the Software and that both the above copyright notice(s) and this
 
15
permission notice appear in supporting documentation.
 
16
 
 
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
18
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
19
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 
20
OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 
21
HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
 
22
SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
 
23
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 
24
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 
25
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
26
 
 
27
Except as contained in this notice, the name of a copyright holder
 
28
shall not be used in advertising or otherwise to promote the sale, use
 
29
or other dealings in this Software without prior written authorization
 
30
of the copyright holder.
 
31
 
 
32
X Window System is a trademark of The Open Group */
 
33
 
 
34
/***************************************************************************
 
35
 
 
36
Copyright 2000 Intel Corporation.  All Rights Reserved. 
 
37
 
 
38
Permission is hereby granted, free of charge, to any person obtaining a 
 
39
copy of this software and associated documentation files (the 
 
40
"Software"), to deal in the Software without restriction, including 
 
41
without limitation the rights to use, copy, modify, merge, publish, 
 
42
distribute, sub license, and/or sell copies of the Software, and to 
 
43
permit persons to whom the Software is furnished to do so, subject to 
 
44
the following conditions: 
 
45
 
 
46
The above copyright notice and this permission notice (including the 
 
47
next paragraph) shall be included in all copies or substantial portions 
 
48
of the Software. 
 
49
 
 
50
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 
51
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 
52
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 
 
53
IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 
 
54
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 
55
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 
 
56
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
57
 
 
58
**************************************************************************/
 
59
 
 
60
 
 
61
/*
 
62
 * i810_video.c: i810 KDrive Xv driver. 
 
63
 *               Based on the XFree86 i810 Xv driver by Jonathan Bian.
 
64
 *
 
65
 * Authors: 
 
66
 *      Jonathan Bian <jonathan.bian@intel.com>
 
67
 *      Pontus Lidman <pontus.lidman@nokia.com>
 
68
 *
 
69
 */
 
70
 
 
71
#ifdef HAVE_CONFIG_H
 
72
#include <kdrive-config.h>
 
73
#endif
 
74
#include "kdrive.h"
 
75
#include "kxv.h"
 
76
#include "i810.h"
 
77
 
 
78
#include <X11/extensions/Xv.h>
 
79
 
 
80
#include "fourcc.h"
 
81
 
 
82
typedef struct {
 
83
    CARD32 size;
 
84
    CARD32 offset;
 
85
} FBLinearRec, *FBLinearPtr;
 
86
 
 
87
#define OFF_DELAY       250  /* milliseconds */
 
88
#define FREE_DELAY      15000
 
89
 
 
90
#define OFF_TIMER       0x01
 
91
#define FREE_TIMER      0x02
 
92
#define CLIENT_VIDEO_ON 0x04
 
93
 
 
94
#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
 
95
 
 
96
static KdVideoAdaptorPtr i810SetupImageVideo(ScreenPtr);
 
97
static void i810StopVideo(KdScreenInfo *, pointer, Bool);
 
98
static int i810SetPortAttribute(KdScreenInfo *, Atom, int, pointer);
 
99
static int i810GetPortAttribute(KdScreenInfo *, Atom, int *, pointer);
 
100
static void i810QueryBestSize(KdScreenInfo *, Bool,
 
101
        short, short, short, short, unsigned int *, unsigned int *, pointer);
 
102
static int i810PutImage( KdScreenInfo *, DrawablePtr, 
 
103
        short, short, short, short, short, short, short, short,
 
104
        int, unsigned char*, short, short, Bool, RegionPtr, pointer);
 
105
static int i810QueryImageAttributes(KdScreenInfo *, 
 
106
        int, unsigned short *, unsigned short *,  int *, int *);
 
107
 
 
108
static void i810BlockHandler(int, pointer, pointer, pointer);
 
109
 
 
110
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
111
 
 
112
static Atom xvBrightness, xvContrast, xvColorKey;
 
113
 
 
114
#define IMAGE_MAX_WIDTH         720
 
115
#define IMAGE_MAX_HEIGHT        576
 
116
#define Y_BUF_SIZE              (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT)
 
117
 
 
118
#define OVERLAY_UPDATE(p)       OUTREG(0x30000, p | 0x80000000);
 
119
 
 
120
/*
 
121
 * OV0CMD - Overlay Command Register
 
122
 */
 
123
#define VERTICAL_CHROMINANCE_FILTER     0x70000000
 
124
#define VC_SCALING_OFF          0x00000000
 
125
#define VC_LINE_REPLICATION     0x10000000
 
126
#define VC_UP_INTERPOLATION     0x20000000
 
127
#define VC_PIXEL_DROPPING       0x50000000
 
128
#define VC_DOWN_INTERPOLATION   0x60000000
 
129
#define VERTICAL_LUMINANCE_FILTER       0x0E000000
 
130
#define VL_SCALING_OFF          0x00000000
 
131
#define VL_LINE_REPLICATION     0x02000000
 
132
#define VL_UP_INTERPOLATION     0x04000000
 
133
#define VL_PIXEL_DROPPING       0x0A000000
 
134
#define VL_DOWN_INTERPOLATION   0x0C000000
 
135
#define HORIZONTAL_CHROMINANCE_FILTER   0x01C00000
 
136
#define HC_SCALING_OFF          0x00000000
 
137
#define HC_LINE_REPLICATION     0x00400000
 
138
#define HC_UP_INTERPOLATION     0x00800000
 
139
#define HC_PIXEL_DROPPING       0x01400000
 
140
#define HC_DOWN_INTERPOLATION   0x01800000
 
141
#define HORIZONTAL_LUMINANCE_FILTER     0x00380000
 
142
#define HL_SCALING_OFF          0x00000000
 
143
#define HL_LINE_REPLICATION     0x00080000
 
144
#define HL_UP_INTERPOLATION     0x00100000
 
145
#define HL_PIXEL_DROPPING       0x00280000
 
146
#define HL_DOWN_INTERPOLATION   0x00300000
 
147
 
 
148
#define Y_ADJUST                0x00010000      
 
149
#define OV_BYTE_ORDER           0x0000C000
 
150
#define UV_SWAP                 0x00004000
 
151
#define Y_SWAP                  0x00008000
 
152
#define Y_AND_UV_SWAP           0x0000C000
 
153
#define SOURCE_FORMAT           0x00003C00
 
154
#define RGB_555                 0x00000800
 
155
#define RGB_565                 0x00000C00
 
156
#define YUV_422                 0x00002000
 
157
#define YUV_411                 0x00002400
 
158
#define YUV_420                 0x00003000
 
159
#define YUV_410                 0x00003800
 
160
#define BUFFER_AND_FIELD        0x00000006
 
161
#define BUFFER0_FIELD0          0x00000000
 
162
#define BUFFER1_FIELD0          0x00000004
 
163
#define OVERLAY_ENABLE          0x00000001
 
164
 
 
165
/*
 
166
 * DOV0STA - Display/Overlay 0 Status Register
 
167
 */
 
168
#define DOV0STA         0x30008
 
169
 
 
170
#define MINUV_SCALE     0x1
 
171
 
 
172
#define RGB16ToColorKey(c) \
 
173
        (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
 
174
 
 
175
#define RGB15ToColorKey(c) \
 
176
        (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
 
177
 
 
178
Bool i810InitVideo(ScreenPtr pScreen)
 
179
{
 
180
    KdScreenPriv(pScreen);
 
181
    KdScreenInfo *screen = pScreenPriv->screen;
 
182
    KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL;
 
183
    KdVideoAdaptorPtr newAdaptor = NULL;
 
184
    int num_adaptors;
 
185
 
 
186
/*     fprintf(stderr,"i810InitVideo\n"); */
 
187
        
 
188
    if (screen->fb[0].bitsPerPixel != 8) 
 
189
    {
 
190
        newAdaptor = i810SetupImageVideo(pScreen);
 
191
    }
 
192
 
 
193
    num_adaptors = KdXVListGenericAdaptors(screen, &adaptors);
 
194
 
 
195
    if(newAdaptor) {
 
196
        if(!num_adaptors) {
 
197
            num_adaptors = 1;
 
198
            adaptors = &newAdaptor;
 
199
        } else {
 
200
            newAdaptors =  /* need to free this someplace */
 
201
                xalloc((num_adaptors + 1) * sizeof(KdVideoAdaptorPtr*));
 
202
            if(newAdaptors) {
 
203
                memcpy(newAdaptors, adaptors, num_adaptors * 
 
204
                                        sizeof(KdVideoAdaptorPtr));
 
205
                newAdaptors[num_adaptors] = newAdaptor;
 
206
                adaptors = newAdaptors;
 
207
                num_adaptors++;
 
208
            }
 
209
        }
 
210
    }
 
211
 
 
212
    if(num_adaptors)
 
213
        KdXVScreenInit(pScreen, adaptors, num_adaptors);
 
214
 
 
215
    if(newAdaptors)
 
216
        xfree(newAdaptors);
 
217
    return TRUE;
 
218
}
 
219
 
 
220
/* client libraries expect an encoding */
 
221
static KdVideoEncodingRec DummyEncoding[1] =
 
222
{
 
223
 {
 
224
   0,
 
225
   "XV_IMAGE",
 
226
   IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
 
227
   {1, 1}
 
228
 }
 
229
};
 
230
 
 
231
#define NUM_FORMATS 3
 
232
 
 
233
static KdVideoFormatRec Formats[NUM_FORMATS] = 
 
234
{
 
235
  {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 
236
};
 
237
 
 
238
#define NUM_ATTRIBUTES 3
 
239
 
 
240
static KdAttributeRec Attributes[NUM_ATTRIBUTES] =
 
241
{
 
242
   {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
 
243
   {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
 
244
   {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
 
245
};
 
246
 
 
247
#define NUM_IMAGES 4
 
248
 
 
249
static KdImageRec Images[NUM_IMAGES] =
 
250
{
 
251
        XVIMAGE_YUY2,
 
252
        XVIMAGE_YV12,
 
253
        XVIMAGE_I420,
 
254
        XVIMAGE_UYVY
 
255
};
 
256
 
 
257
typedef struct {
 
258
    CARD32 OBUF_0Y;
 
259
    CARD32 OBUF_1Y;
 
260
    CARD32 OBUF_0U;
 
261
    CARD32 OBUF_0V;
 
262
    CARD32 OBUF_1U;
 
263
    CARD32 OBUF_1V;
 
264
    CARD32 OV0STRIDE;
 
265
    CARD32 YRGB_VPH;
 
266
    CARD32 UV_VPH;
 
267
    CARD32 HORZ_PH;
 
268
    CARD32 INIT_PH;
 
269
    CARD32 DWINPOS;
 
270
    CARD32 DWINSZ;
 
271
    CARD32 SWID;
 
272
    CARD32 SWIDQW;
 
273
    CARD32 SHEIGHT;
 
274
    CARD32 YRGBSCALE;
 
275
    CARD32 UVSCALE;
 
276
    CARD32 OV0CLRC0;
 
277
    CARD32 OV0CLRC1;
 
278
    CARD32 DCLRKV;
 
279
    CARD32 DCLRKM;
 
280
    CARD32 SCLRKVH;
 
281
    CARD32 SCLRKVL;
 
282
    CARD32 SCLRKM;
 
283
    CARD32 OV0CONF;
 
284
    CARD32 OV0CMD;
 
285
} I810OverlayRegRec, *I810OverlayRegPtr;
 
286
 
 
287
typedef struct {
 
288
        CARD32       YBuf0offset;
 
289
        CARD32       UBuf0offset;
 
290
        CARD32       VBuf0offset;
 
291
 
 
292
        CARD32       YBuf1offset;
 
293
        CARD32       UBuf1offset;
 
294
        CARD32       VBuf1offset;
 
295
 
 
296
        unsigned char currentBuf;
 
297
 
 
298
        unsigned char brightness;
 
299
        unsigned char contrast;
 
300
 
 
301
        RegionRec    clip;
 
302
        CARD32       colorKey;
 
303
 
 
304
        CARD32       videoStatus;
 
305
        Time         offTime;
 
306
        Time         freeTime;
 
307
    FBLinearPtr  linear;
 
308
} I810PortPrivRec, *I810PortPrivPtr;        
 
309
 
 
310
#define GET_PORT_PRIVATE(screen) \
 
311
   (I810PortPrivPtr)(((I810CardInfo *) (screen->card->driver))->adaptor->pPortPrivates[0].ptr)
 
312
 
 
313
static void i810ResetVideo(KdScreenInfo *screen) 
 
314
{
 
315
    ScreenPtr pScreen = screen->pScreen;
 
316
    KdScreenPriv(pScreen);
 
317
    KdCardInfo *card = pScreenPriv->card;
 
318
    I810CardInfo *i810c = (I810CardInfo *) card->driver;
 
319
 
 
320
    I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
 
321
    I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); 
 
322
 
 
323
    /*
 
324
     * Default to maximum image size in YV12
 
325
     */
 
326
 
 
327
    overlay->YRGB_VPH = 0;
 
328
    overlay->UV_VPH = 0;
 
329
    overlay->HORZ_PH = 0;
 
330
    overlay->INIT_PH = 0;
 
331
    overlay->DWINPOS = 0;
 
332
    overlay->DWINSZ = (IMAGE_MAX_HEIGHT << 16) | IMAGE_MAX_WIDTH; 
 
333
    overlay->SWID =  IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 15);       
 
334
    overlay->SWIDQW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12);
 
335
    overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15);
 
336
    overlay->YRGBSCALE = 0x80004000; /* scale factor 1 */
 
337
    overlay->UVSCALE = 0x80004000; /* scale factor 1 */
 
338
    overlay->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */
 
339
    overlay->OV0CLRC1 = 0x80; /* saturation: bypass */
 
340
 
 
341
    /*
 
342
     * Enable destination color keying
 
343
     */
 
344
    switch(screen->fb[0].depth) {
 
345
    case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
 
346
             overlay->DCLRKM = 0x80070307;
 
347
             break;
 
348
    case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
 
349
             overlay->DCLRKM = 0x80070707;
 
350
             break;
 
351
    default: overlay->DCLRKV = pPriv->colorKey;
 
352
             overlay->DCLRKM = 0x80000000;
 
353
             break;
 
354
    }
 
355
 
 
356
    overlay->SCLRKVH = 0;
 
357
    overlay->SCLRKVL = 0;
 
358
    overlay->SCLRKM = 0; /* source color key disable */
 
359
    overlay->OV0CONF = 0; /* two 720 pixel line buffers */ 
 
360
 
 
361
    overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST |
 
362
                      YUV_420;
 
363
 
 
364
    OVERLAY_UPDATE(i810c->OverlayPhysical);
 
365
}
 
366
 
 
367
 
 
368
static KdVideoAdaptorPtr 
 
369
i810SetupImageVideo(ScreenPtr pScreen)
 
370
{
 
371
    KdScreenPriv(pScreen);
 
372
    KdScreenInfo *screen = pScreenPriv->screen;
 
373
    KdCardInfo *card = pScreenPriv->card;
 
374
    I810CardInfo  *i810c = (I810CardInfo *) card->driver;
 
375
 
 
376
 
 
377
    KdVideoAdaptorPtr adapt;
 
378
    I810PortPrivPtr pPriv;
 
379
 
 
380
/*     fprintf(stderr,"i810SetupImageVideo\n"); */
 
381
 
 
382
    if(!(adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) +
 
383
                            sizeof(I810PortPrivRec) +
 
384
                            sizeof(DevUnion))))
 
385
        return NULL;
 
386
 
 
387
    adapt->type = XvWindowMask | XvInputMask | XvImageMask;
 
388
    adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
 
389
    adapt->name = "I810 Video Overlay";
 
390
    adapt->nEncodings = 1;
 
391
    adapt->pEncodings = DummyEncoding;
 
392
    adapt->nFormats = NUM_FORMATS;
 
393
    adapt->pFormats = Formats;
 
394
    adapt->nPorts = 1;
 
395
    adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
 
396
 
 
397
    pPriv = (I810PortPrivPtr)(&adapt->pPortPrivates[1]);
 
398
 
 
399
    adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
 
400
    adapt->pAttributes = Attributes;
 
401
    adapt->nImages = NUM_IMAGES;
 
402
    adapt->nAttributes = NUM_ATTRIBUTES;
 
403
    adapt->pImages = Images;
 
404
    adapt->PutVideo = NULL;
 
405
    adapt->PutStill = NULL;
 
406
    adapt->GetVideo = NULL;
 
407
    adapt->GetStill = NULL;
 
408
    adapt->StopVideo = i810StopVideo;
 
409
    adapt->SetPortAttribute = i810SetPortAttribute;
 
410
    adapt->GetPortAttribute = i810GetPortAttribute;
 
411
    adapt->QueryBestSize = i810QueryBestSize;
 
412
    adapt->PutImage = i810PutImage;
 
413
    adapt->QueryImageAttributes = i810QueryImageAttributes;
 
414
 
 
415
    pPriv->colorKey = i810c->colorKey & ((1 << screen->fb[0].depth) - 1);
 
416
    pPriv->videoStatus = 0;
 
417
    pPriv->brightness = 0;
 
418
    pPriv->contrast = 128;
 
419
    pPriv->linear = NULL;
 
420
    pPriv->currentBuf = 0;
 
421
 
 
422
    /* gotta uninit this someplace */
 
423
    REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); 
 
424
 
 
425
    i810c->adaptor = adapt;
 
426
 
 
427
    i810c->BlockHandler = pScreen->BlockHandler;
 
428
    pScreen->BlockHandler = i810BlockHandler;
 
429
 
 
430
    xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
 
431
    xvContrast   = MAKE_ATOM("XV_CONTRAST");
 
432
    xvColorKey   = MAKE_ATOM("XV_COLORKEY");
 
433
 
 
434
    i810ResetVideo(screen);
 
435
 
 
436
    return adapt;
 
437
}
 
438
 
 
439
 
 
440
/* I810ClipVideo -  
 
441
 
 
442
   Takes the dst box in standard X BoxRec form (top and left
 
443
   edges inclusive, bottom and right exclusive).  The new dst
 
444
   box is returned.  The source boundaries are given (x1, y1 
 
445
   inclusive, x2, y2 exclusive) and returned are the new source 
 
446
   boundaries in 16.16 fixed point. 
 
447
*/
 
448
 
 
449
static void
 
450
I810ClipVideo(
 
451
  BoxPtr dst, 
 
452
  INT32 *x1, 
 
453
  INT32 *x2, 
 
454
  INT32 *y1, 
 
455
  INT32 *y2,
 
456
  BoxPtr extents,            /* extents of the clip region */
 
457
  INT32 width, 
 
458
  INT32 height
 
459
){
 
460
    INT32 vscale, hscale, delta;
 
461
    int diff;
 
462
 
 
463
    hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
 
464
    vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
 
465
 
 
466
    *x1 <<= 16; *x2 <<= 16;
 
467
    *y1 <<= 16; *y2 <<= 16;
 
468
 
 
469
    diff = extents->x1 - dst->x1;
 
470
    if(diff > 0) {
 
471
        dst->x1 = extents->x1;
 
472
        *x1 += diff * hscale;     
 
473
    }
 
474
    diff = dst->x2 - extents->x2;
 
475
    if(diff > 0) {
 
476
        dst->x2 = extents->x2;
 
477
        *x2 -= diff * hscale;     
 
478
    }
 
479
    diff = extents->y1 - dst->y1;
 
480
    if(diff > 0) {
 
481
        dst->y1 = extents->y1;
 
482
        *y1 += diff * vscale;     
 
483
    }
 
484
    diff = dst->y2 - extents->y2;
 
485
    if(diff > 0) {
 
486
        dst->y2 = extents->y2;
 
487
        *y2 -= diff * vscale;     
 
488
    }
 
489
 
 
490
    if(*x1 < 0) {
 
491
        diff =  (- *x1 + hscale - 1)/ hscale;
 
492
        dst->x1 += diff;
 
493
        *x1 += diff * hscale;
 
494
    }
 
495
    delta = *x2 - (width << 16);
 
496
    if(delta > 0) {
 
497
        diff = (delta + hscale - 1)/ hscale;
 
498
        dst->x2 -= diff;
 
499
        *x2 -= diff * hscale;
 
500
    }
 
501
    if(*y1 < 0) {
 
502
        diff =  (- *y1 + vscale - 1)/ vscale;
 
503
        dst->y1 += diff;
 
504
        *y1 += diff * vscale;
 
505
    }
 
506
    delta = *y2 - (height << 16);
 
507
    if(delta > 0) {
 
508
        diff = (delta + vscale - 1)/ vscale;
 
509
        dst->y2 -= diff;
 
510
        *y2 -= diff * vscale;
 
511
    }
 
512
 
513
 
 
514
static void 
 
515
i810StopVideo(KdScreenInfo *screen, pointer data, Bool exit)
 
516
{
 
517
  I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
 
518
  KdCardInfo *card = screen->card;
 
519
  I810CardInfo  *i810c = (I810CardInfo *) card->driver;  
 
520
 
 
521
  I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); 
 
522
 
 
523
  REGION_EMPTY(screen->pScreen, &pPriv->clip);   
 
524
 
 
525
  if(exit) {
 
526
     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
 
527
        overlay->OV0CMD &= 0xFFFFFFFE;
 
528
        OVERLAY_UPDATE(i810c->OverlayPhysical);
 
529
     }
 
530
     if(pPriv->linear) {
 
531
         xfree(pPriv->linear);
 
532
         pPriv->linear = NULL;
 
533
     }
 
534
     pPriv->videoStatus = 0;
 
535
  } else {
 
536
     if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
 
537
        pPriv->videoStatus |= OFF_TIMER;
 
538
        pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 
 
539
     }
 
540
  }
 
541
 
 
542
}
 
543
 
 
544
static int 
 
545
i810SetPortAttribute(
 
546
  KdScreenInfo *screen, 
 
547
  Atom attribute,
 
548
  int value, 
 
549
  pointer data
 
550
){
 
551
  I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
 
552
  KdCardInfo *card = screen->card;
 
553
  I810CardInfo  *i810c = (I810CardInfo *) card->driver;
 
554
 
 
555
  I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); 
 
556
 
 
557
  if(attribute == xvBrightness) {
 
558
        if((value < -128) || (value > 127))
 
559
           return BadValue;
 
560
        pPriv->brightness = value;
 
561
        overlay->OV0CLRC0 &= 0xFFFFFF00;
 
562
        overlay->OV0CLRC0 |= value;
 
563
        OVERLAY_UPDATE(i810c->OverlayPhysical);
 
564
  } else
 
565
  if(attribute == xvContrast) {
 
566
        if((value < 0) || (value > 255))
 
567
           return BadValue;
 
568
        pPriv->contrast = value;
 
569
        overlay->OV0CLRC0 &= 0xFFFE00FF;
 
570
        overlay->OV0CLRC0 |= value << 9;
 
571
        OVERLAY_UPDATE(i810c->OverlayPhysical);
 
572
  } else
 
573
  if(attribute == xvColorKey) {
 
574
        pPriv->colorKey = value;
 
575
        switch(screen->fb[0].depth) {
 
576
        case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
 
577
                 break;
 
578
        case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
 
579
                 break;
 
580
        default: overlay->DCLRKV = pPriv->colorKey;
 
581
                 break;
 
582
        }
 
583
        OVERLAY_UPDATE(i810c->OverlayPhysical);
 
584
        REGION_EMPTY(screen->pScreen, &pPriv->clip);   
 
585
  } else return BadMatch;
 
586
 
 
587
  return Success;
 
588
}
 
589
 
 
590
static int 
 
591
i810GetPortAttribute(
 
592
  KdScreenInfo *screen, 
 
593
  Atom attribute,
 
594
  int *value, 
 
595
  pointer data
 
596
){
 
597
  I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
 
598
 
 
599
  if(attribute == xvBrightness) {
 
600
        *value = pPriv->brightness;
 
601
  } else
 
602
  if(attribute == xvContrast) {
 
603
        *value = pPriv->contrast;
 
604
  } else
 
605
  if(attribute == xvColorKey) {
 
606
        *value = pPriv->colorKey;
 
607
  } else return BadMatch;
 
608
 
 
609
  return Success;
 
610
}
 
611
 
 
612
static void 
 
613
i810QueryBestSize(
 
614
  KdScreenInfo *screen, 
 
615
  Bool motion,
 
616
  short vid_w, short vid_h, 
 
617
  short drw_w, short drw_h, 
 
618
  unsigned int *p_w, unsigned int *p_h, 
 
619
  pointer data
 
620
){
 
621
  *p_w = drw_w;
 
622
  *p_h = drw_h; 
 
623
}
 
624
 
 
625
 
 
626
static void
 
627
I810CopyPackedData(
 
628
   KdScreenInfo *screen, 
 
629
   unsigned char *buf,
 
630
   int srcPitch,
 
631
   int dstPitch,
 
632
   int top,
 
633
   int left,
 
634
   int h,
 
635
   int w
 
636
   )
 
637
{
 
638
  KdCardInfo *card = screen->card;
 
639
  I810CardInfo  *i810c = (I810CardInfo *) card->driver;
 
640
    I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
 
641
    unsigned char *src, *dst;
 
642
    
 
643
    src = buf + (top*srcPitch) + (left<<1);
 
644
 
 
645
    if (pPriv->currentBuf == 0)
 
646
        dst = i810c->FbBase + pPriv->YBuf0offset;
 
647
    else
 
648
        dst = i810c->FbBase + pPriv->YBuf1offset;
 
649
 
 
650
    w <<= 1;
 
651
    while(h--) {
 
652
        memcpy(dst, src, w);
 
653
        src += srcPitch;
 
654
        dst += dstPitch;
 
655
    }
 
656
}
 
657
 
 
658
static void
 
659
i810CopyPlanarData(
 
660
   KdScreenInfo *screen, 
 
661
   unsigned char *buf,
 
662
   int srcPitch,
 
663
   int dstPitch,  /* of chroma */
 
664
   int srcH,
 
665
   int top,
 
666
   int left,
 
667
   int h,
 
668
   int w,
 
669
   int id
 
670
   )
 
671
{
 
672
  KdCardInfo *card = screen->card;
 
673
  I810CardInfo  *i810c = (I810CardInfo *) card->driver;
 
674
    I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
 
675
    int i;
 
676
    unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
 
677
 
 
678
    /* Copy Y data */
 
679
    src1 = buf + (top*srcPitch) + left;
 
680
    if (pPriv->currentBuf == 0)
 
681
        dst1 = i810c->FbBase + pPriv->YBuf0offset;
 
682
    else
 
683
        dst1 = i810c->FbBase + pPriv->YBuf1offset;
 
684
 
 
685
    for (i = 0; i < h; i++) {
 
686
        memcpy(dst1, src1, w);
 
687
        src1 += srcPitch;
 
688
        dst1 += dstPitch << 1;
 
689
    }
 
690
 
 
691
    /* Copy V data for YV12, or U data for I420 */
 
692
    src2 = buf + (srcH*srcPitch) + ((top*srcPitch)>>2) + (left>>1);
 
693
    if (pPriv->currentBuf == 0) {
 
694
        if (id == FOURCC_I420)
 
695
            dst2 = i810c->FbBase + pPriv->UBuf0offset;
 
696
        else
 
697
            dst2 = i810c->FbBase + pPriv->VBuf0offset;
 
698
    } else {
 
699
        if (id == FOURCC_I420)
 
700
            dst2 = i810c->FbBase + pPriv->UBuf1offset;
 
701
        else
 
702
            dst2 = i810c->FbBase + pPriv->VBuf1offset;
 
703
    }
 
704
 
 
705
    for (i = 0; i < h/2; i++) {
 
706
        memcpy(dst2, src2, w/2);
 
707
        src2 += srcPitch>>1;
 
708
        dst2 += dstPitch;
 
709
    }
 
710
 
 
711
    /* Copy U data for YV12, or V data for I420 */
 
712
    src3 = buf + (srcH*srcPitch) + ((srcH*srcPitch)>>2) + ((top*srcPitch)>>2) + (left>>1);
 
713
    if (pPriv->currentBuf == 0) {
 
714
        if (id == FOURCC_I420) 
 
715
            dst3 = i810c->FbBase + pPriv->VBuf0offset;
 
716
        else
 
717
            dst3 = i810c->FbBase + pPriv->UBuf0offset;
 
718
    } else {
 
719
        if (id == FOURCC_I420) 
 
720
            dst3 = i810c->FbBase + pPriv->VBuf1offset;
 
721
        else
 
722
            dst3 = i810c->FbBase + pPriv->UBuf1offset;
 
723
    }
 
724
    
 
725
    for (i = 0; i < h/2; i++) {
 
726
        memcpy(dst3, src3, w/2);
 
727
        src3 += srcPitch>>1;
 
728
        dst3 += dstPitch;
 
729
    }
 
730
}
 
731
 
 
732
static void
 
733
i810DisplayVideo(
 
734
    KdScreenInfo *screen,
 
735
    int id,
 
736
    short width, short height,
 
737
    int dstPitch,  /* of chroma for 4:2:0 */
 
738
    int x1, int y1, int x2, int y2,
 
739
    BoxPtr dstBox,
 
740
    short src_w, short src_h,
 
741
    short drw_w, short drw_h
 
742
){
 
743
  KdCardInfo *card = screen->card;
 
744
  I810CardInfo  *i810c = (I810CardInfo *) card->driver;
 
745
    I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
 
746
    I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); 
 
747
    int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
 
748
    int xscaleIntUV = 0, xscaleFractUV = 0, yscaleIntUV = 0, yscaleFractUV = 0;
 
749
    unsigned int swidth;
 
750
 
 
751
    switch(id) {
 
752
    case FOURCC_YV12:
 
753
    case FOURCC_I420:
 
754
        swidth = (width + 7) & ~7;
 
755
        overlay->SWID = (swidth << 15) | swidth;
 
756
        overlay->SWIDQW = (swidth << 12) | (swidth >> 3);
 
757
        break;
 
758
    case FOURCC_UYVY:
 
759
    case FOURCC_YUY2:
 
760
    default:
 
761
        swidth = ((width + 3) & ~3) << 1;
 
762
        overlay->SWID = swidth;
 
763
        overlay->SWIDQW = swidth >> 3;
 
764
        break;
 
765
    }
 
766
 
 
767
    overlay->SHEIGHT = height | (height << 15);
 
768
    overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
 
769
    overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) | 
 
770
                      (dstBox->x2 - dstBox->x1);
 
771
 
 
772
    /* buffer locations */
 
773
    overlay->OBUF_0Y = pPriv->YBuf0offset;
 
774
    overlay->OBUF_1Y = pPriv->YBuf1offset;
 
775
    overlay->OBUF_0U = pPriv->UBuf0offset; 
 
776
    overlay->OBUF_0V = pPriv->VBuf0offset;
 
777
    overlay->OBUF_1U = pPriv->UBuf1offset;
 
778
    overlay->OBUF_1V = pPriv->VBuf1offset;
 
779
 
 
780
    /* 
 
781
     * Calculate horizontal and vertical scaling factors, default to 1:1
 
782
     */
 
783
    overlay->YRGBSCALE = 0x80004000;
 
784
    overlay->UVSCALE = 0x80004000;
 
785
 
 
786
    /* 
 
787
     * Initially, YCbCr and Overlay Enable and
 
788
     * vertical chrominance up interpolation and horozontal chrominance
 
789
     * up interpolation
 
790
     */
 
791
    overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | 
 
792
                      OVERLAY_ENABLE; 
 
793
 
 
794
    if ((drw_w != src_w) || (drw_h != src_h)) 
 
795
    {
 
796
        xscaleInt = (src_w / drw_w) & 0x3;
 
797
        xscaleFract = (src_w << 12) / drw_w;
 
798
        yscaleInt = (src_h / drw_h) & 0x3;
 
799
        yscaleFract = (src_h << 12) / drw_h;
 
800
 
 
801
        overlay->YRGBSCALE = (xscaleInt << 15) | 
 
802
                             ((xscaleFract & 0xFFF) << 3) |
 
803
                             (yscaleInt) |
 
804
                             ((yscaleFract & 0xFFF) << 20);
 
805
 
 
806
        if (drw_w > src_w) 
 
807
        {
 
808
            /* horizontal up-scaling */
 
809
            overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER;
 
810
            overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER;
 
811
            overlay->OV0CMD |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION);
 
812
        }
 
813
 
 
814
        if (drw_h > src_h) 
 
815
        { 
 
816
            /* vertical up-scaling */
 
817
            overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER;
 
818
            overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER;
 
819
            overlay->OV0CMD |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION);
 
820
        }
 
821
 
 
822
        if (drw_w < src_w) 
 
823
        { 
 
824
            /* horizontal down-scaling */
 
825
            overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER;
 
826
            overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER;
 
827
            overlay->OV0CMD |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION);
 
828
        }
 
829
 
 
830
        if (drw_h < src_h) 
 
831
        { 
 
832
            /* vertical down-scaling */
 
833
            overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER;
 
834
            overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER;
 
835
            overlay->OV0CMD |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION);
 
836
        }
 
837
 
 
838
        /* now calculate the UV scaling factor */
 
839
 
 
840
        if (xscaleFract)
 
841
        {
 
842
            xscaleFractUV = xscaleFract >> MINUV_SCALE;
 
843
            overlay->OV0CMD &= ~HC_DOWN_INTERPOLATION;
 
844
            overlay->OV0CMD |= HC_UP_INTERPOLATION;
 
845
        }
 
846
 
 
847
        if (xscaleInt)
 
848
        {
 
849
            xscaleIntUV = xscaleInt >> MINUV_SCALE;
 
850
            if (xscaleIntUV)
 
851
            {
 
852
                overlay->OV0CMD &= ~HC_UP_INTERPOLATION;
 
853
            }
 
854
        }
 
855
 
 
856
        if (yscaleFract)
 
857
        {
 
858
            yscaleFractUV = yscaleFract >> MINUV_SCALE;
 
859
            overlay->OV0CMD &= ~VC_DOWN_INTERPOLATION;
 
860
            overlay->OV0CMD |= VC_UP_INTERPOLATION;
 
861
        }
 
862
 
 
863
        if (yscaleInt)
 
864
        {
 
865
            yscaleIntUV = yscaleInt >> MINUV_SCALE;
 
866
            if (yscaleIntUV)
 
867
            {
 
868
                overlay->OV0CMD &= ~VC_UP_INTERPOLATION;
 
869
                overlay->OV0CMD |= VC_DOWN_INTERPOLATION;
 
870
            }
 
871
        }
 
872
 
 
873
        overlay->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) |
 
874
                           ((yscaleFractUV & 0xFFF) << 20);
 
875
    }
 
876
 
 
877
    switch(id) {
 
878
    case FOURCC_YV12:
 
879
    case FOURCC_I420:
 
880
        overlay->OV0STRIDE = (dstPitch << 1) | (dstPitch << 16);
 
881
        overlay->OV0CMD &= ~SOURCE_FORMAT;
 
882
        overlay->OV0CMD |= YUV_420;
 
883
        break;
 
884
    case FOURCC_UYVY:
 
885
    case FOURCC_YUY2:
 
886
    default:
 
887
        overlay->OV0STRIDE = dstPitch;
 
888
        overlay->OV0CMD &= ~SOURCE_FORMAT;
 
889
        overlay->OV0CMD |= YUV_422;
 
890
        overlay->OV0CMD &= ~OV_BYTE_ORDER;
 
891
        if (id == FOURCC_UYVY)
 
892
            overlay->OV0CMD |= Y_SWAP;
 
893
        break;
 
894
    }
 
895
 
 
896
    overlay->OV0CMD &= ~BUFFER_AND_FIELD;
 
897
    if (pPriv->currentBuf == 0)
 
898
        overlay->OV0CMD |= BUFFER0_FIELD0;
 
899
    else
 
900
        overlay->OV0CMD |= BUFFER1_FIELD0;
 
901
 
 
902
    OVERLAY_UPDATE(i810c->OverlayPhysical);
 
903
 
 
904
}
 
905
 
 
906
static FBLinearPtr
 
907
i810AllocateMemory(
 
908
  KdScreenInfo *screen,
 
909
  FBLinearPtr linear,
 
910
  int size
 
911
){
 
912
    KdCardInfo *card=screen->card;
 
913
    I810CardInfo *i810c = (I810CardInfo *) card->driver;
 
914
    FBLinearPtr new_linear;
 
915
  
 
916
    if(linear) {
 
917
        if(linear->size >= size)
 
918
            return linear;
 
919
        else
 
920
            ErrorF("Ran out of memory for overlay buffer, requested size = %d\n",size);
 
921
    }
 
922
    
 
923
   new_linear = xalloc(sizeof(FBLinearRec));
 
924
   new_linear->size = i810c->XvMem.Size;
 
925
   new_linear->offset = i810c->XvMem.Start;
 
926
 
 
927
/*    fprintf(stderr,"Overlay mem offset %lx\n",new_linear->offset); */
 
928
 
 
929
   return new_linear;
 
930
}
 
931
 
 
932
static int
 
933
i810PutImage(KdScreenInfo           *screen, 
 
934
               DrawablePtr          pDraw,
 
935
               short                src_x,
 
936
               short                src_y,
 
937
               short                drw_x,
 
938
               short                drw_y,
 
939
               short                src_w,
 
940
               short                src_h,
 
941
               short                drw_w,
 
942
               short                drw_h,
 
943
               int                   id,
 
944
               unsigned char        *buf,
 
945
               short                width,
 
946
               short                height,
 
947
               Bool                 sync,
 
948
               RegionPtr            clipBoxes,
 
949
               pointer              data)
 
950
{
 
951
    KdCardInfo *card = screen->card;
 
952
    I810CardInfo *i810c = (I810CardInfo *) card->driver;
 
953
    I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
 
954
    INT32 x1, x2, y1, y2;
 
955
    int srcPitch, dstPitch;
 
956
    int top, left, npixels, nlines, size;
 
957
    BoxRec dstBox;
 
958
 
 
959
    /* Clip */
 
960
    x1 = src_x;
 
961
    x2 = src_x + src_w;
 
962
    y1 = src_y;
 
963
    y2 = src_y + src_h;
 
964
 
 
965
    dstBox.x1 = drw_x;
 
966
    dstBox.x2 = drw_x + drw_w;
 
967
    dstBox.y1 = drw_y;
 
968
    dstBox.y2 = drw_y + drw_h;
 
969
 
 
970
    I810ClipVideo(&dstBox, &x1, &x2, &y1, &y2, 
 
971
                  REGION_EXTENTS(pScreen, clipBoxes), width, height);
 
972
 
 
973
    if((x1 >= x2) || (y1 >= y2))
 
974
       return Success;
 
975
 
 
976
    switch(id) {
 
977
    case FOURCC_YV12:
 
978
    case FOURCC_I420:
 
979
         srcPitch = (width + 3) & ~3;
 
980
         dstPitch = ((width >> 1) + 7) & ~7;  /* of chroma */
 
981
         size =  dstPitch * height * 3; 
 
982
         break;
 
983
    case FOURCC_UYVY:
 
984
    case FOURCC_YUY2:
 
985
    default:
 
986
         srcPitch = (width << 1);
 
987
         dstPitch = (srcPitch + 7) & ~7;
 
988
         size = dstPitch * height;
 
989
         break;
 
990
    }  
 
991
 
 
992
    if(!(pPriv->linear = i810AllocateMemory(screen, pPriv->linear, 
 
993
                (screen->fb[0].bitsPerPixel == 16) ? size : (size >> 1))))
 
994
        return BadAlloc;
 
995
 
 
996
    /* fixup pointers */
 
997
    pPriv->YBuf0offset = pPriv->linear->offset;
 
998
    pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
 
999
    pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height >> 1);
 
1000
    
 
1001
    pPriv->YBuf1offset = pPriv->linear->offset + size;
 
1002
    pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
 
1003
    pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height >> 1);
 
1004
 
 
1005
    /* wait for the last rendered buffer to be flipped in */
 
1006
    while (((INREG(DOV0STA)&0x00100000)>>20) != pPriv->currentBuf);
 
1007
 
 
1008
    /* buffer swap */
 
1009
    if (pPriv->currentBuf == 0)
 
1010
        pPriv->currentBuf = 1;
 
1011
    else
 
1012
        pPriv->currentBuf = 0;
 
1013
 
 
1014
    /* copy data */
 
1015
    top = y1 >> 16;
 
1016
    left = (x1 >> 16) & ~1;
 
1017
    npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
 
1018
 
 
1019
    switch(id) {
 
1020
    case FOURCC_YV12:
 
1021
    case FOURCC_I420:
 
1022
        top &= ~1;
 
1023
        nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
 
1024
        i810CopyPlanarData(screen, buf, srcPitch, dstPitch,  height, top, left, 
 
1025
                           nlines, npixels, id);
 
1026
        break;
 
1027
    case FOURCC_UYVY:
 
1028
    case FOURCC_YUY2:
 
1029
    default:
 
1030
        nlines = ((y2 + 0xffff) >> 16) - top;
 
1031
        I810CopyPackedData(screen, buf, srcPitch, dstPitch, top, left, nlines, 
 
1032
                                                              npixels);
 
1033
        break;
 
1034
    }
 
1035
 
 
1036
    /* update cliplist */
 
1037
    if(!REGION_EQUAL(screen->pScreen, &pPriv->clip, clipBoxes)) {
 
1038
        REGION_COPY(screen->pScreen, &pPriv->clip, clipBoxes);
 
1039
        KXVPaintRegion (pDraw, &pPriv->clip, pPriv->colorKey);
 
1040
    }
 
1041
 
 
1042
 
 
1043
    i810DisplayVideo(screen, id, width, height, dstPitch, 
 
1044
             x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
 
1045
 
 
1046
    pPriv->videoStatus = CLIENT_VIDEO_ON;
 
1047
 
 
1048
    return Success;
 
1049
}
 
1050
 
 
1051
 
 
1052
static int 
 
1053
i810QueryImageAttributes(
 
1054
  KdScreenInfo *screen, 
 
1055
  int id, 
 
1056
  unsigned short *w, unsigned short *h, 
 
1057
  int *pitches, int *offsets
 
1058
){
 
1059
    int size, tmp;
 
1060
 
 
1061
    if(*w > 720) *w = 720;
 
1062
    if(*h > 576) *h = 576;
 
1063
 
 
1064
    *w = (*w + 1) & ~1;
 
1065
    if(offsets) offsets[0] = 0;
 
1066
 
 
1067
    switch(id) {
 
1068
    case FOURCC_YV12:
 
1069
    case FOURCC_I420:
 
1070
        *h = (*h + 1) & ~1;
 
1071
        size = (*w + 3) & ~3;
 
1072
        if(pitches) pitches[0] = size;
 
1073
        size *= *h;
 
1074
        if(offsets) offsets[1] = size;
 
1075
        tmp = ((*w >> 1) + 3) & ~3;
 
1076
        if(pitches) pitches[1] = pitches[2] = tmp;
 
1077
        tmp *= (*h >> 1);
 
1078
        size += tmp;
 
1079
        if(offsets) offsets[2] = size;
 
1080
        size += tmp;
 
1081
        break;
 
1082
    case FOURCC_UYVY:
 
1083
    case FOURCC_YUY2:
 
1084
    default:
 
1085
        size = *w << 1;
 
1086
        if(pitches) pitches[0] = size;
 
1087
        size *= *h;
 
1088
        break;
 
1089
    }
 
1090
 
 
1091
    return size;
 
1092
}
 
1093
 
 
1094
static void
 
1095
i810BlockHandler (
 
1096
    int i,
 
1097
    pointer     blockData,
 
1098
    pointer     pTimeout,
 
1099
    pointer     pReadmask
 
1100
){
 
1101
    ScreenPtr   pScreen = screenInfo.screens[i];
 
1102
    KdScreenPriv(pScreen);
 
1103
    KdScreenInfo *screen = pScreenPriv->screen;
 
1104
    KdCardInfo *card = screen->card;
 
1105
    I810CardInfo        *i810c = (I810CardInfo *) card->driver;
 
1106
    I810PortPrivPtr pPriv = GET_PORT_PRIVATE(screen);
 
1107
    I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart); 
 
1108
 
 
1109
    pScreen->BlockHandler = i810c->BlockHandler;
 
1110
    
 
1111
    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
 
1112
 
 
1113
    pScreen->BlockHandler = i810BlockHandler;
 
1114
 
 
1115
    if(pPriv->videoStatus & TIMER_MASK) {
 
1116
        UpdateCurrentTime();
 
1117
        if(pPriv->videoStatus & OFF_TIMER) {
 
1118
            if(pPriv->offTime < currentTime.milliseconds) {
 
1119
                /* Turn off the overlay */
 
1120
                overlay->OV0CMD &= 0xFFFFFFFE;
 
1121
                OVERLAY_UPDATE(i810c->OverlayPhysical);
 
1122
 
 
1123
                pPriv->videoStatus = FREE_TIMER;
 
1124
                pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
 
1125
            }
 
1126
        } else {  /* FREE_TIMER */
 
1127
            if(pPriv->freeTime < currentTime.milliseconds) {
 
1128
                if(pPriv->linear) {
 
1129
                    xfree(pPriv->linear);
 
1130
                    pPriv->linear = NULL;
 
1131
                }
 
1132
                pPriv->videoStatus = 0;
 
1133
            }
 
1134
        }
 
1135
    }
 
1136
}