src/video/Xext/Xxf86dga/XF86DGA.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 10 Jul 2007 13:52:07 +0000
branchSDL-1.2
changeset 4033 24c3ca822658
parent 4031 f0b8bbaf8de5
child 4144 904defc0792e
permissions -rw-r--r--
Added a '*/' for whiney compilers that don't like comments-in-comments.
slouken@292
     1
/* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.19 2001/08/18 02:41:30 dawes Exp $ */
slouken@292
     2
/*
slouken@292
     3
slouken@292
     4
Copyright (c) 1995  Jon Tombs
slouken@292
     5
Copyright (c) 1995,1996  The XFree86 Project, Inc
slouken@292
     6
slouken@292
     7
*/
slouken@292
     8
slouken@292
     9
/* THIS IS NOT AN X CONSORTIUM STANDARD */
slouken@292
    10
slouken@292
    11
#ifdef __EMX__ /* needed here to override certain constants in X headers */
slouken@292
    12
#define INCL_DOS
slouken@292
    13
#define INCL_DOSIOCTL
slouken@292
    14
#include <os2.h>
slouken@292
    15
#endif
slouken@292
    16
slouken@292
    17
#if defined(linux)
slouken@292
    18
#define HAS_MMAP_ANON
slouken@292
    19
#include <sys/types.h>
slouken@292
    20
#include <sys/mman.h>
icculus@4033
    21
/*#include <asm/page.h>*/   /* PAGE_SIZE */
slouken@292
    22
#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
slouken@292
    23
#define HAS_GETPAGESIZE
slouken@292
    24
#endif /* linux */
slouken@292
    25
slouken@292
    26
#if defined(CSRG_BASED)
slouken@292
    27
#define HAS_MMAP_ANON
slouken@292
    28
#define HAS_GETPAGESIZE
slouken@292
    29
#include <sys/types.h>
slouken@292
    30
#include <sys/mman.h>
slouken@292
    31
#endif /* CSRG_BASED */
slouken@292
    32
slouken@292
    33
#if defined(DGUX)
slouken@292
    34
#define HAS_GETPAGESIZE
slouken@292
    35
#define MMAP_DEV_ZERO
slouken@292
    36
#include <sys/types.h>
slouken@292
    37
#include <sys/mman.h>
slouken@292
    38
#include <unistd.h>
slouken@292
    39
#endif /* DGUX */
slouken@292
    40
slouken@292
    41
#if defined(SVR4) && !defined(DGUX)
slouken@292
    42
#define MMAP_DEV_ZERO
slouken@292
    43
#include <sys/types.h>
slouken@292
    44
#include <sys/mman.h>
slouken@292
    45
#include <unistd.h>
slouken@292
    46
#endif /* SVR4 && !DGUX */
slouken@292
    47
slouken@292
    48
#if defined(sun) && !defined(SVR4) /* SunOS */
slouken@292
    49
#define MMAP_DEV_ZERO   /* doesn't SunOS have MAP_ANON ?? */
slouken@292
    50
#define HAS_GETPAGESIZE
slouken@292
    51
#include <sys/types.h>
slouken@292
    52
#include <sys/mman.h>
slouken@292
    53
#endif /* sun && !SVR4 */
slouken@292
    54
slouken@292
    55
#ifdef XNO_SYSCONF
slouken@292
    56
#undef _SC_PAGESIZE
slouken@292
    57
#endif
slouken@292
    58
slouken@292
    59
#define NEED_EVENTS
slouken@292
    60
#define NEED_REPLIES
slouken@1384
    61
icculus@1599
    62
#include <X11/Xlibint.h>
slouken@1361
    63
#include "../extensions/xf86dga.h"
slouken@1361
    64
#include "../extensions/xf86dgastr.h"
icculus@1599
    65
#include "../extensions/Xext.h"
slouken@1361
    66
#include "../extensions/extutil.h"
slouken@292
    67
slouken@292
    68
extern XExtDisplayInfo* SDL_NAME(xdga_find_display)(Display*);
slouken@292
    69
extern char *SDL_NAME(xdga_extension_name);
slouken@292
    70
slouken@292
    71
#define XF86DGACheckExtension(dpy,i,val) \
slouken@292
    72
  XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
slouken@292
    73
slouken@292
    74
/*****************************************************************************
slouken@292
    75
 *                                                                           *
slouken@292
    76
 *		    public XFree86-DGA Extension routines                    *
slouken@292
    77
 *                                                                           *
slouken@292
    78
 *****************************************************************************/
slouken@292
    79
slouken@292
    80
Bool SDL_NAME(XF86DGAQueryExtension) (
slouken@292
    81
    Display *dpy,
slouken@292
    82
    int *event_basep,
slouken@292
    83
    int *error_basep
slouken@292
    84
){
slouken@292
    85
    return SDL_NAME(XDGAQueryExtension)(dpy, event_basep, error_basep);
slouken@292
    86
}
slouken@292
    87
slouken@292
    88
Bool SDL_NAME(XF86DGAQueryVersion)(
slouken@292
    89
    Display* dpy,
slouken@292
    90
    int* majorVersion, 
slouken@292
    91
    int* minorVersion
slouken@292
    92
){
slouken@292
    93
    return SDL_NAME(XDGAQueryVersion)(dpy, majorVersion, minorVersion);
slouken@292
    94
}
slouken@292
    95
slouken@292
    96
Bool SDL_NAME(XF86DGAGetVideoLL)(
slouken@292
    97
    Display* dpy,
slouken@292
    98
    int screen,
slouken@292
    99
    int *offset,
slouken@292
   100
    int *width, 
slouken@292
   101
    int *bank_size, 
slouken@292
   102
    int *ram_size
slouken@292
   103
){
slouken@292
   104
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   105
    xXF86DGAGetVideoLLReply rep;
slouken@292
   106
    xXF86DGAGetVideoLLReq *req;
slouken@292
   107
slouken@292
   108
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   109
slouken@292
   110
    LockDisplay(dpy);
slouken@292
   111
    GetReq(XF86DGAGetVideoLL, req);
slouken@292
   112
    req->reqType = info->codes->major_opcode;
slouken@292
   113
    req->dgaReqType = X_XF86DGAGetVideoLL;
slouken@292
   114
    req->screen = screen;
icculus@1575
   115
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
slouken@292
   116
	UnlockDisplay(dpy);
slouken@292
   117
	SyncHandle();
slouken@292
   118
	return False;
slouken@292
   119
    }
slouken@292
   120
slouken@292
   121
    *offset = /*(char *)*/rep.offset;
slouken@292
   122
    *width = rep.width;
slouken@292
   123
    *bank_size = rep.bank_size;
slouken@292
   124
    *ram_size = rep.ram_size;
slouken@292
   125
	
slouken@292
   126
    UnlockDisplay(dpy);
slouken@292
   127
    SyncHandle();
slouken@292
   128
    return True;
slouken@292
   129
}
slouken@292
   130
slouken@292
   131
    
slouken@292
   132
Bool SDL_NAME(XF86DGADirectVideoLL)(
slouken@292
   133
    Display* dpy,
slouken@292
   134
    int screen,
slouken@292
   135
    int enable
slouken@292
   136
){
slouken@292
   137
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   138
    xXF86DGADirectVideoReq *req;
slouken@292
   139
slouken@292
   140
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   141
slouken@292
   142
    LockDisplay(dpy);
slouken@292
   143
    GetReq(XF86DGADirectVideo, req);
slouken@292
   144
    req->reqType = info->codes->major_opcode;
slouken@292
   145
    req->dgaReqType = X_XF86DGADirectVideo;
slouken@292
   146
    req->screen = screen;
slouken@292
   147
    req->enable = enable;
slouken@292
   148
    UnlockDisplay(dpy);
slouken@292
   149
    SyncHandle();
icculus@1575
   150
    XSync(dpy,False);
slouken@292
   151
    return True;
slouken@292
   152
}
slouken@292
   153
slouken@292
   154
Bool SDL_NAME(XF86DGAGetViewPortSize)(
slouken@292
   155
    Display* dpy,
slouken@292
   156
    int screen,
slouken@292
   157
    int *width, 
slouken@292
   158
    int *height
slouken@292
   159
){
slouken@292
   160
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   161
    xXF86DGAGetViewPortSizeReply rep;
slouken@292
   162
    xXF86DGAGetViewPortSizeReq *req;
slouken@292
   163
slouken@292
   164
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   165
slouken@292
   166
    LockDisplay(dpy);
slouken@292
   167
    GetReq(XF86DGAGetViewPortSize, req);
slouken@292
   168
    req->reqType = info->codes->major_opcode;
slouken@292
   169
    req->dgaReqType = X_XF86DGAGetViewPortSize;
slouken@292
   170
    req->screen = screen;
icculus@1575
   171
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
slouken@292
   172
	UnlockDisplay(dpy);
slouken@292
   173
	SyncHandle();
slouken@292
   174
	return False;
slouken@292
   175
    }
slouken@292
   176
slouken@292
   177
    *width = rep.width;
slouken@292
   178
    *height = rep.height;
slouken@292
   179
	
slouken@292
   180
    UnlockDisplay(dpy);
slouken@292
   181
    SyncHandle();
slouken@292
   182
    return True;
slouken@292
   183
}
slouken@292
   184
    
slouken@292
   185
    
slouken@292
   186
Bool SDL_NAME(XF86DGASetViewPort)(
slouken@292
   187
    Display* dpy,
slouken@292
   188
    int screen,
slouken@292
   189
    int x, 
slouken@292
   190
    int y
slouken@292
   191
){
slouken@292
   192
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   193
    xXF86DGASetViewPortReq *req;
slouken@292
   194
slouken@292
   195
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   196
slouken@292
   197
    LockDisplay(dpy);
slouken@292
   198
    GetReq(XF86DGASetViewPort, req);
slouken@292
   199
    req->reqType = info->codes->major_opcode;
slouken@292
   200
    req->dgaReqType = X_XF86DGASetViewPort;
slouken@292
   201
    req->screen = screen;
slouken@292
   202
    req->x = x;
slouken@292
   203
    req->y = y;
slouken@292
   204
    UnlockDisplay(dpy);
slouken@292
   205
    SyncHandle();
icculus@1575
   206
    XSync(dpy,False);
slouken@292
   207
    return True;
slouken@292
   208
}
slouken@292
   209
slouken@292
   210
    
slouken@292
   211
Bool SDL_NAME(XF86DGAGetVidPage)(
slouken@292
   212
    Display* dpy,
slouken@292
   213
    int screen,
slouken@292
   214
    int *vpage
slouken@292
   215
){
slouken@292
   216
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   217
    xXF86DGAGetVidPageReply rep;
slouken@292
   218
    xXF86DGAGetVidPageReq *req;
slouken@292
   219
slouken@292
   220
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   221
slouken@292
   222
    LockDisplay(dpy);
slouken@292
   223
    GetReq(XF86DGAGetVidPage, req);
slouken@292
   224
    req->reqType = info->codes->major_opcode;
slouken@292
   225
    req->dgaReqType = X_XF86DGAGetVidPage;
slouken@292
   226
    req->screen = screen;
icculus@1575
   227
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
slouken@292
   228
	UnlockDisplay(dpy);
slouken@292
   229
	SyncHandle();
slouken@292
   230
	return False;
slouken@292
   231
    }
slouken@292
   232
slouken@292
   233
    *vpage = rep.vpage;
slouken@292
   234
    UnlockDisplay(dpy);
slouken@292
   235
    SyncHandle();
slouken@292
   236
    return True;
slouken@292
   237
}
slouken@292
   238
slouken@292
   239
    
slouken@292
   240
Bool SDL_NAME(XF86DGASetVidPage)(
slouken@292
   241
    Display* dpy,
slouken@292
   242
    int screen,
slouken@292
   243
    int vpage
slouken@292
   244
){
slouken@292
   245
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   246
    xXF86DGASetVidPageReq *req;
slouken@292
   247
slouken@292
   248
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   249
slouken@292
   250
    LockDisplay(dpy);
slouken@292
   251
    GetReq(XF86DGASetVidPage, req);
slouken@292
   252
    req->reqType = info->codes->major_opcode;
slouken@292
   253
    req->dgaReqType = X_XF86DGASetVidPage;
slouken@292
   254
    req->screen = screen;
slouken@292
   255
    req->vpage = vpage;
slouken@292
   256
    UnlockDisplay(dpy);
slouken@292
   257
    SyncHandle();
icculus@1575
   258
    XSync(dpy,False);
slouken@292
   259
    return True;
slouken@292
   260
}
slouken@292
   261
slouken@292
   262
Bool SDL_NAME(XF86DGAInstallColormap)(
slouken@292
   263
    Display* dpy,
slouken@292
   264
    int screen,
slouken@292
   265
    Colormap cmap
slouken@292
   266
){
slouken@292
   267
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   268
    xXF86DGAInstallColormapReq *req;
slouken@292
   269
slouken@292
   270
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   271
slouken@292
   272
    LockDisplay(dpy);
slouken@292
   273
    GetReq(XF86DGAInstallColormap, req);
slouken@292
   274
    req->reqType = info->codes->major_opcode;
slouken@292
   275
    req->dgaReqType = X_XF86DGAInstallColormap;
slouken@292
   276
    req->screen = screen;
slouken@292
   277
    req->id = cmap;
slouken@292
   278
    UnlockDisplay(dpy);
slouken@292
   279
    SyncHandle();
icculus@1575
   280
    XSync(dpy,False);
slouken@292
   281
    return True;
slouken@292
   282
}
slouken@292
   283
slouken@292
   284
Bool SDL_NAME(XF86DGAQueryDirectVideo)(
slouken@292
   285
    Display *dpy,
slouken@292
   286
    int screen,
slouken@292
   287
    int *flags
slouken@292
   288
){
slouken@292
   289
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   290
    xXF86DGAQueryDirectVideoReply rep;
slouken@292
   291
    xXF86DGAQueryDirectVideoReq *req;
slouken@292
   292
slouken@292
   293
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   294
slouken@292
   295
    LockDisplay(dpy);
slouken@292
   296
    GetReq(XF86DGAQueryDirectVideo, req);
slouken@292
   297
    req->reqType = info->codes->major_opcode;
slouken@292
   298
    req->dgaReqType = X_XF86DGAQueryDirectVideo;
slouken@292
   299
    req->screen = screen;
icculus@1575
   300
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
slouken@292
   301
	UnlockDisplay(dpy);
slouken@292
   302
	SyncHandle();
slouken@292
   303
	return False;
slouken@292
   304
    }
slouken@292
   305
    *flags = rep.flags;
slouken@292
   306
    UnlockDisplay(dpy);
slouken@292
   307
    SyncHandle();
slouken@292
   308
    return True;
slouken@292
   309
}
slouken@292
   310
slouken@292
   311
Bool SDL_NAME(XF86DGAViewPortChanged)(
slouken@292
   312
    Display *dpy,
slouken@292
   313
    int screen,
slouken@292
   314
    int n
slouken@292
   315
){
slouken@292
   316
    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
slouken@292
   317
    xXF86DGAViewPortChangedReply rep;
slouken@292
   318
    xXF86DGAViewPortChangedReq *req;
slouken@292
   319
slouken@292
   320
    XF86DGACheckExtension (dpy, info, False);
slouken@292
   321
slouken@292
   322
    LockDisplay(dpy);
slouken@292
   323
    GetReq(XF86DGAViewPortChanged, req);
slouken@292
   324
    req->reqType = info->codes->major_opcode;
slouken@292
   325
    req->dgaReqType = X_XF86DGAViewPortChanged;
slouken@292
   326
    req->screen = screen;
slouken@292
   327
    req->n = n;
icculus@1575
   328
    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
slouken@292
   329
	UnlockDisplay(dpy);
slouken@292
   330
	SyncHandle();
slouken@292
   331
	return False;
slouken@292
   332
    }
slouken@292
   333
    UnlockDisplay(dpy);
slouken@292
   334
    SyncHandle();
slouken@292
   335
    return rep.result;
slouken@292
   336
}
slouken@292
   337
slouken@292
   338
slouken@292
   339
slouken@292
   340
/* Helper functions */
slouken@292
   341
slouken@292
   342
#include <X11/Xmd.h>
slouken@1361
   343
#include "../extensions/xf86dga.h"
slouken@292
   344
#include <stdlib.h>
slouken@292
   345
#include <stdio.h>
slouken@292
   346
#include <fcntl.h>
slouken@292
   347
#if defined(ISC) 
slouken@292
   348
# define HAS_SVR3_MMAP
slouken@292
   349
# include <sys/types.h>
slouken@292
   350
# include <errno.h>
slouken@292
   351
slouken@292
   352
# include <sys/at_ansi.h>
slouken@292
   353
# include <sys/kd.h>
slouken@292
   354
slouken@292
   355
# include <sys/sysmacros.h>
slouken@292
   356
# include <sys/immu.h>
slouken@292
   357
# include <sys/region.h>
slouken@292
   358
slouken@292
   359
# include <sys/mmap.h>
slouken@292
   360
#else
slouken@292
   361
# if !defined(Lynx)
slouken@292
   362
#  if !defined(__EMX__)
slouken@292
   363
#   include <sys/mman.h>
slouken@292
   364
#  endif
slouken@292
   365
# else
slouken@292
   366
#  include <sys/types.h>
slouken@292
   367
#  include <errno.h>
slouken@292
   368
#  include <smem.h>
slouken@292
   369
# endif
slouken@292
   370
#endif
slouken@292
   371
#include <sys/wait.h>
slouken@292
   372
#include <signal.h>
slouken@292
   373
#include <unistd.h>
slouken@292
   374
slouken@292
   375
#if defined(SVR4) && !defined(sun) && !defined(SCO325)
slouken@292
   376
#define DEV_MEM "/dev/pmem"
slouken@292
   377
#elif defined(SVR4) && defined(sun)
slouken@292
   378
#define DEV_MEM "/dev/xsvc"
slouken@292
   379
#else
slouken@292
   380
#define DEV_MEM "/dev/mem"
slouken@292
   381
#endif
slouken@292
   382
slouken@292
   383
typedef struct {
slouken@292
   384
    unsigned long physaddr;	/* actual requested physical address */
slouken@292
   385
    unsigned long size;		/* actual requested map size */
slouken@292
   386
    unsigned long delta;	/* delta to account for page alignment */
slouken@292
   387
    void *	  vaddr;	/* mapped address, without the delta */
slouken@292
   388
    int		  refcount;	/* reference count */
slouken@292
   389
} MapRec, *MapPtr;
slouken@292
   390
slouken@292
   391
typedef struct {
slouken@292
   392
    Display *	display;
slouken@292
   393
    int		screen;
slouken@292
   394
    MapPtr	map;
slouken@292
   395
} ScrRec, *ScrPtr;
slouken@292
   396
slouken@292
   397
static int mapFd = -1;
slouken@292
   398
static int numMaps = 0;
slouken@292
   399
static int numScrs = 0;
slouken@292
   400
static MapPtr *mapList = NULL;
slouken@292
   401
static ScrPtr *scrList = NULL;
slouken@292
   402
slouken@292
   403
static MapPtr
slouken@292
   404
AddMap(void)
slouken@292
   405
{
slouken@292
   406
    MapPtr *old;
slouken@292
   407
slouken@292
   408
    old = mapList;
slouken@1338
   409
    mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1));
slouken@292
   410
    if (!mapList) {
slouken@292
   411
	mapList = old;
slouken@292
   412
	return NULL;
slouken@292
   413
    }
slouken@1338
   414
    mapList[numMaps] = malloc(sizeof(MapRec));
slouken@292
   415
    if (!mapList[numMaps])
slouken@292
   416
	return NULL;
slouken@292
   417
    return mapList[numMaps++];
slouken@292
   418
}
slouken@292
   419
slouken@292
   420
static ScrPtr
slouken@292
   421
AddScr(void)
slouken@292
   422
{
slouken@292
   423
    ScrPtr *old;
slouken@292
   424
slouken@292
   425
    old = scrList;
slouken@1338
   426
    scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1));
slouken@292
   427
    if (!scrList) {
slouken@292
   428
	scrList = old;
slouken@292
   429
	return NULL;
slouken@292
   430
    }
slouken@1338
   431
    scrList[numScrs] = malloc(sizeof(ScrRec));
slouken@292
   432
    if (!scrList[numScrs])
slouken@292
   433
	return NULL;
slouken@292
   434
    return scrList[numScrs++];
slouken@292
   435
}
slouken@292
   436
slouken@292
   437
static MapPtr
slouken@292
   438
FindMap(unsigned long address, unsigned long size)
slouken@292
   439
{
slouken@292
   440
    int i;
slouken@292
   441
slouken@292
   442
    for (i = 0; i < numMaps; i++) {
slouken@292
   443
	if (mapList[i]->physaddr == address &&
slouken@292
   444
	    mapList[i]->size == size)
slouken@292
   445
	    return mapList[i];
slouken@292
   446
    }
slouken@292
   447
    return NULL;
slouken@292
   448
}
slouken@292
   449
slouken@292
   450
static ScrPtr
slouken@292
   451
FindScr(Display *display, int screen)
slouken@292
   452
{
slouken@292
   453
    int i;
slouken@292
   454
slouken@292
   455
    for (i = 0; i < numScrs; i++) {
slouken@292
   456
	if (scrList[i]->display == display &&
slouken@292
   457
	    scrList[i]->screen == screen)
slouken@292
   458
	    return scrList[i];
slouken@292
   459
    }
slouken@292
   460
    return NULL;
slouken@292
   461
}
slouken@292
   462
slouken@292
   463
static void *
slouken@292
   464
MapPhysAddress(unsigned long address, unsigned long size)
slouken@292
   465
{
slouken@292
   466
    unsigned long offset, delta;
slouken@292
   467
    int pagesize = -1;
slouken@292
   468
    void *vaddr;
slouken@292
   469
    MapPtr mp;
slouken@292
   470
#if defined(ISC) && defined(HAS_SVR3_MMAP)
slouken@292
   471
    struct kd_memloc mloc;
slouken@292
   472
#elif defined(__EMX__)
slouken@292
   473
    APIRET rc;
slouken@292
   474
    ULONG action;
slouken@292
   475
    HFILE hfd;
slouken@292
   476
#endif
slouken@292
   477
slouken@292
   478
    if ((mp = FindMap(address, size))) {
slouken@292
   479
	mp->refcount++;
slouken@292
   480
	return (void *)((unsigned long)mp->vaddr + mp->delta);
slouken@292
   481
    }
slouken@292
   482
slouken@292
   483
#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE)
slouken@292
   484
    pagesize = sysconf(_SC_PAGESIZE);
slouken@292
   485
#endif
slouken@292
   486
#ifdef _SC_PAGE_SIZE
slouken@292
   487
    if (pagesize == -1)
slouken@292
   488
	pagesize = sysconf(_SC_PAGE_SIZE);
slouken@292
   489
#endif
slouken@292
   490
#ifdef HAS_GETPAGESIZE
slouken@292
   491
    if (pagesize == -1)
slouken@292
   492
	pagesize = getpagesize();
slouken@292
   493
#endif
slouken@292
   494
#ifdef PAGE_SIZE
slouken@292
   495
    if (pagesize == -1)
slouken@292
   496
	pagesize = PAGE_SIZE;
slouken@292
   497
#endif
slouken@292
   498
    if (pagesize == -1)
slouken@292
   499
	pagesize = 4096;
slouken@292
   500
slouken@292
   501
   delta = address % pagesize;
slouken@292
   502
   offset = address - delta;
slouken@292
   503
slouken@292
   504
#if defined(ISC) && defined(HAS_SVR3_MMAP)
slouken@292
   505
    if (mapFd < 0) {
slouken@292
   506
	if ((mapFd = open("/dev/mmap", O_RDWR)) < 0)
slouken@292
   507
	    return NULL;
slouken@292
   508
    }
slouken@292
   509
    mloc.vaddr = (char *)0;
slouken@292
   510
    mloc.physaddr = (char *)offset;
slouken@292
   511
    mloc.length = size + delta;
slouken@292
   512
    mloc.ioflg=1;
slouken@292
   513
slouken@292
   514
    if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1)
slouken@292
   515
	return NULL;
slouken@292
   516
#elif defined (__EMX__)
slouken@292
   517
    /*
slouken@292
   518
     * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
slouken@292
   519
     * Consecutive calling of this routine will make PMAP$ driver run out
slouken@292
   520
     * of memory handles. Some umap/close mechanism should be provided
slouken@292
   521
     */
slouken@292
   522
slouken@292
   523
    rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
slouken@292
   524
		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
slouken@292
   525
    if (rc != 0)
slouken@292
   526
	return NULL;
slouken@292
   527
    {
slouken@292
   528
	struct map_ioctl {
slouken@292
   529
		union {
slouken@292
   530
			ULONG phys;
slouken@292
   531
			void* user;
slouken@292
   532
		} a;
slouken@292
   533
		ULONG size;
slouken@292
   534
	} pmap,dmap;
slouken@292
   535
	ULONG plen,dlen;
slouken@292
   536
#define XFREE86_PMAP	0x76
slouken@292
   537
#define PMAP_MAP	0x44
slouken@292
   538
slouken@292
   539
	pmap.a.phys = offset;
slouken@292
   540
	pmap.size = size + delta;
slouken@292
   541
	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
slouken@292
   542
			 (PULONG)&pmap, sizeof(pmap), &plen,
slouken@292
   543
			 (PULONG)&dmap, sizeof(dmap), &dlen);
slouken@292
   544
	if (rc == 0) {
slouken@292
   545
		vaddr = dmap.a.user;
slouken@292
   546
	}
slouken@292
   547
   }
slouken@292
   548
   if (rc != 0)
slouken@292
   549
	return NULL;
slouken@292
   550
#elif defined (Lynx)
slouken@292
   551
    vaddr = (void *)smem_create("XF86DGA", (char *)offset, 
slouken@292
   552
				size + delta, SM_READ|SM_WRITE);
slouken@292
   553
#else
slouken@292
   554
#ifndef MAP_FILE
slouken@292
   555
#define MAP_FILE 0
slouken@292
   556
#endif
slouken@292
   557
    if (mapFd < 0) {
slouken@292
   558
	if ((mapFd = open(DEV_MEM, O_RDWR)) < 0)
slouken@292
   559
	    return NULL;
slouken@292
   560
    }
slouken@292
   561
    vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE,
slouken@292
   562
                        MAP_FILE | MAP_SHARED, mapFd, (off_t)offset);
slouken@292
   563
    if (vaddr == (void *)-1)
slouken@292
   564
	return NULL;
slouken@292
   565
#endif
slouken@292
   566
slouken@292
   567
    if (!vaddr) {
slouken@292
   568
	if (!(mp = AddMap()))
slouken@292
   569
	    return NULL;
slouken@292
   570
	mp->physaddr = address;
slouken@292
   571
	mp->size = size;
slouken@292
   572
	mp->delta = delta;
slouken@292
   573
	mp->vaddr = vaddr;
slouken@292
   574
	mp->refcount = 1;
slouken@292
   575
    }
slouken@292
   576
    return (void *)((unsigned long)vaddr + delta);
slouken@292
   577
}
slouken@292
   578
slouken@292
   579
/*
slouken@292
   580
 * Still need to find a clean way of detecting the death of a DGA app
slouken@292
   581
 * and returning things to normal - Jon
slouken@292
   582
 * This is here to help debugging without rebooting... Also C-A-BS
slouken@292
   583
 * should restore text mode.
slouken@292
   584
 */
slouken@292
   585
slouken@292
   586
int
slouken@292
   587
SDL_NAME(XF86DGAForkApp)(int screen)
slouken@292
   588
{
slouken@292
   589
    pid_t pid;
slouken@292
   590
    int status;
slouken@292
   591
    int i;
slouken@292
   592
slouken@292
   593
     /* fork the app, parent hangs around to clean up */
slouken@292
   594
    if ((pid = fork()) > 0) {
slouken@292
   595
	ScrPtr sp;
slouken@292
   596
slouken@292
   597
	waitpid(pid, &status, 0);
slouken@292
   598
	for (i = 0; i < numScrs; i++) {
slouken@292
   599
	    sp = scrList[i];
slouken@292
   600
	    SDL_NAME(XF86DGADirectVideoLL)(sp->display, sp->screen, 0);
icculus@1575
   601
	    XSync(sp->display, False);
slouken@292
   602
	}
slouken@292
   603
        if (WIFEXITED(status))
slouken@292
   604
	    _exit(0);
slouken@292
   605
	else
slouken@292
   606
	    _exit(-1);
slouken@292
   607
    }
slouken@292
   608
    return pid;
slouken@292
   609
}
slouken@292
   610
slouken@292
   611
slouken@292
   612
Bool
slouken@292
   613
SDL_NAME(XF86DGADirectVideo)(
slouken@292
   614
    Display *dis,
slouken@292
   615
    int screen,
slouken@292
   616
    int enable
slouken@292
   617
){
slouken@292
   618
    ScrPtr sp;
slouken@292
   619
    MapPtr mp = NULL;
slouken@292
   620
slouken@292
   621
    if ((sp = FindScr(dis, screen)))
slouken@292
   622
	mp = sp->map;
slouken@292
   623
slouken@292
   624
    if (enable & XF86DGADirectGraphics) {
slouken@292
   625
#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
slouken@292
   626
	&& !defined(__EMX__)
slouken@292
   627
	if (mp && mp->vaddr)
slouken@292
   628
	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE);
slouken@292
   629
#endif
slouken@292
   630
    } else {
slouken@292
   631
#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
slouken@292
   632
	&& !defined(__EMX__)
slouken@292
   633
	if (mp && mp->vaddr)
slouken@292
   634
	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ);
slouken@292
   635
#elif defined(Lynx)
slouken@292
   636
	/* XXX this doesn't allow enable after disable */
slouken@292
   637
	smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH);
slouken@292
   638
	smem_remove("XF86DGA");
slouken@292
   639
#endif
slouken@292
   640
    }
slouken@292
   641
slouken@292
   642
    SDL_NAME(XF86DGADirectVideoLL)(dis, screen, enable);
slouken@292
   643
    return 1;
slouken@292
   644
}
slouken@292
   645
slouken@292
   646
slouken@292
   647
static void
slouken@292
   648
XF86cleanup(int sig)
slouken@292
   649
{
slouken@292
   650
    ScrPtr sp;
slouken@292
   651
    int i;
slouken@292
   652
    static char beenhere = 0;
slouken@292
   653
slouken@292
   654
    if (beenhere)
slouken@292
   655
	_exit(3);
slouken@292
   656
    beenhere = 1;
slouken@292
   657
slouken@292
   658
    for (i = 0; i < numScrs; i++) {
slouken@292
   659
	sp = scrList[i];
slouken@292
   660
	SDL_NAME(XF86DGADirectVideo)(sp->display, sp->screen, 0);
icculus@1575
   661
	XSync(sp->display, False);
slouken@292
   662
    }
slouken@292
   663
    _exit(3);
slouken@292
   664
}
slouken@292
   665
slouken@292
   666
Bool
slouken@292
   667
SDL_NAME(XF86DGAGetVideo)(
slouken@292
   668
    Display *dis,
slouken@292
   669
    int screen,
slouken@292
   670
    char **addr,
slouken@292
   671
    int *width, 
slouken@292
   672
    int *bank, 
slouken@292
   673
    int *ram
slouken@292
   674
){
slouken@292
   675
    /*unsigned long*/ int offset;
slouken@292
   676
    static int beenHere = 0;
slouken@292
   677
    ScrPtr sp;
slouken@292
   678
    MapPtr mp;
slouken@292
   679
slouken@292
   680
    if (!(sp = FindScr(dis, screen))) {
slouken@292
   681
	if (!(sp = AddScr())) {
slouken@292
   682
	    fprintf(stderr, "XF86DGAGetVideo: malloc failure\n");
slouken@292
   683
	    exit(-2);
slouken@292
   684
	}
slouken@292
   685
	sp->display = dis;
slouken@292
   686
	sp->screen = screen;
slouken@292
   687
	sp->map = NULL;
slouken@292
   688
    }
slouken@292
   689
slouken@292
   690
    SDL_NAME(XF86DGAGetVideoLL)(dis, screen , &offset, width, bank, ram);
slouken@292
   691
slouken@292
   692
    *addr = MapPhysAddress(offset, *bank);
slouken@292
   693
    if (*addr == NULL) {
slouken@292
   694
	fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n",
slouken@292
   695
		strerror(errno));
slouken@292
   696
	exit(-2);
slouken@292
   697
    }
slouken@292
   698
slouken@292
   699
    if ((mp = FindMap(offset, *bank)))
slouken@292
   700
	sp->map = mp;
slouken@292
   701
slouken@292
   702
    if (!beenHere) {
slouken@292
   703
	beenHere = 1;
slouken@292
   704
	atexit((void(*)(void))XF86cleanup);
slouken@292
   705
	/* one shot XF86cleanup attempts */
slouken@292
   706
	signal(SIGSEGV, XF86cleanup);
slouken@292
   707
#ifdef SIGBUS
slouken@292
   708
	signal(SIGBUS, XF86cleanup);
slouken@292
   709
#endif
slouken@292
   710
	signal(SIGHUP, XF86cleanup);
slouken@292
   711
	signal(SIGFPE, XF86cleanup);  
slouken@292
   712
    }
slouken@292
   713
slouken@292
   714
    return 1;
slouken@292
   715
}
slouken@292
   716