Commit 97c81738 authored by Sam Lantinga's avatar Sam Lantinga

Date: Thu, 16 Jan 2003 13:48:31 +0200

From: "Mike Gorchak"
Subject: All QNX patches

whole patches concerning QNX. Almost all code has been rewritten by Julian
and me. Added initial support for hw overlays in QNX and many many others
fixes.

P.S. This patches has been reviewed by Dave Rempel from QSSL and included in
SDL 1.2.5 distribution, which coming on 3rd party CD for newest 6.2.1
version of QNX, which will be available soon.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40572
parent b38a873c
...@@ -188,14 +188,8 @@ QNX: -= NOT YET SUPPORTED =- ...@@ -188,14 +188,8 @@ QNX: -= NOT YET SUPPORTED =-
The only hardware surface is the primary view surface. The only hardware surface is the primary view surface.
Mouse events don't seem to be working right.
Fullscreen doesn't display correctly. Fullscreen doesn't display correctly.
The software surfaces could use some speed up.
The mouse cursor doesn't look right.
AmigaOS: -= NOT YET SUPPORTED =- AmigaOS: -= NOT YET SUPPORTED =-
The OpenGL support isn't implemented yet. The OpenGL support isn't implemented yet.
......
...@@ -33,24 +33,26 @@ static char rcsid = ...@@ -33,24 +33,26 @@ static char rcsid =
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <sys/cdrom.h> #include <sys/cdrom.h>
#include <sys/dcmd_cam.h> #include <sys/dcmd_cam.h>
#include "SDL_error.h" #include "SDL_error.h"
#include "SDL_cdrom.h" #include "SDL_cdrom.h"
#include "SDL_timer.h"
#include "SDL_syscdrom.h" #include "SDL_syscdrom.h"
/* The maximum number of CD-ROM drives we'll detect */ /* The maximum number of CD-ROM drives we'll detect */
#define MAX_DRIVES 16 #define MAX_DRIVES 16
#define QNX_CD_OPENMODE O_RDONLY | O_EXCL
/* A list of available CD-ROM drives */ /* A list of available CD-ROM drives */
static char *SDL_cdlist[MAX_DRIVES]; static char *SDL_cdlist[MAX_DRIVES];
static dev_t SDL_cdmode[MAX_DRIVES]; static dev_t SDL_cdmode[MAX_DRIVES];
static int SDL_cdopen[MAX_DRIVES];
/* The system-dependent CD control functions */ /* The system-dependent CD control functions */
static const char *SDL_SYS_CDName(int drive); static const char *SDL_SYS_CDName(int drive);
...@@ -64,341 +66,491 @@ static int SDL_SYS_CDStop(SDL_CD *cdrom); ...@@ -64,341 +66,491 @@ static int SDL_SYS_CDStop(SDL_CD *cdrom);
static int SDL_SYS_CDEject(SDL_CD *cdrom); static int SDL_SYS_CDEject(SDL_CD *cdrom);
static void SDL_SYS_CDClose(SDL_CD *cdrom); static void SDL_SYS_CDClose(SDL_CD *cdrom);
/* Some ioctl() errno values which occur when the tray is empty */
#define ERRNO_TRAYEMPTY(errno) \
((errno == EIO) || (errno == ENOENT) || (errno == EINVAL))
/* Check a drive to see if it is a CD-ROM */ /* Check a drive to see if it is a CD-ROM */
static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) static int CheckDrive(char *drive, struct stat *stbuf)
{ {
int is_cd, cdfd; int is_cd, cdfd;
cdrom_subch_data_t info; cam_devinfo_t dinfo;
int devctlret=0;
/* If it doesn't exist, return -1 */
if ( stat(drive, stbuf) < 0 ) { int atapi;
return(-1); int removable;
} int cdb10;
/* If it does exist, verify that it's an available CD-ROM */ /* If it doesn't exist, return -1 */
is_cd = 0; if (stat(drive, stbuf) < 0)
if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { {
cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); return(-1);
if ( cdfd >= 0 ) { }
info.subch_command.data_format = CDROM_MSF;
/* Under Linux, EIO occurs when a disk is not present. /* If it does exist, verify that it's an available CD-ROM */
*/ is_cd = 0;
if ((devctl(cdfd,DCMD_CAM_CDROMSUBCHNL,&info,sizeof(info),0) == 0) ||
ERRNO_TRAYEMPTY(errno) ) if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode))
{ {
is_cd = 1; cdfd = open(drive, QNX_CD_OPENMODE);
} if ( cdfd >= 0 )
close(cdfd); {
} devctlret=devctl(cdfd, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL);
}
return(is_cd); if (devctlret==EOK)
{
atapi=dinfo.flags & DEV_ATAPI;
removable=dinfo.flags & DEV_REMOVABLE;
cdb10=dinfo.flags & DEV_CDB_10; /* I'm not sure about that flag */
/* in the near future need to add more checks for splitting cdroms from other devices */
if ((atapi)&&(removable))
{
is_cd = 1;
}
}
close(cdfd);
}
}
return(is_cd);
} }
/* Add a CD-ROM drive to our list of valid drives */ /* Add a CD-ROM drive to our list of valid drives */
static void AddDrive(char *drive, struct stat *stbuf) static void AddDrive(char *drive, struct stat *stbuf)
{ {
int i; int i;
if ( SDL_numcds < MAX_DRIVES ) { if (SDL_numcds < MAX_DRIVES)
/* Check to make sure it's not already in our list. {
This can happen when we see a drive via symbolic link. /* Check to make sure it's not already in our list.
*/ This can happen when we see a drive via symbolic link. */
for ( i=0; i<SDL_numcds; ++i ) {
if ( stbuf->st_rdev == SDL_cdmode[i] ) { for (i=0; i<SDL_numcds; ++i)
#ifdef DEBUG_CDROM {
fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); if (stbuf->st_rdev == SDL_cdmode[i])
#endif {
return; return;
} }
} }
/* Add this drive to our list */ /* Add this drive to our list */
i = SDL_numcds;
SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); i = SDL_numcds;
if ( SDL_cdlist[i] == NULL ) { SDL_cdlist[i] = (char *)malloc(strlen(drive)+1);
SDL_OutOfMemory(); if (SDL_cdlist[i] == NULL)
return; {
} SDL_OutOfMemory();
strcpy(SDL_cdlist[i], drive); return;
SDL_cdmode[i] = stbuf->st_rdev; }
++SDL_numcds; strcpy(SDL_cdlist[i], drive);
#ifdef DEBUG_CDROM SDL_cdmode[i] = stbuf->st_rdev;
fprintf(stderr, "Added CD-ROM drive: %s\n", drive); ++SDL_numcds;
#endif }
}
} }
int SDL_SYS_CDInit(void) int SDL_SYS_CDInit(void)
{ {
/* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ /* checklist: /dev/cdrom, /dev/cd?, /dev/scd? */
static char *checklist[] = { static char *checklist[]={"cdrom", "?0 cd?", "?1 cd?", "?0 scd?", NULL};
"cdrom", "?0 cd?", "?1 cd?", "?a hd?", "?0 scd?", "?0 sr?", NULL
}; char *SDLcdrom;
char *SDLcdrom; int i, j, exists;
int i, j, exists; char drive[32];
char drive[32]; struct stat stbuf;
struct stat stbuf;
/* Fill in our driver capabilities */
/* Fill in our driver capabilities */ SDL_CDcaps.Name = SDL_SYS_CDName;
SDL_CDcaps.Name = SDL_SYS_CDName; SDL_CDcaps.Open = SDL_SYS_CDOpen;
SDL_CDcaps.Open = SDL_SYS_CDOpen; SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; SDL_CDcaps.Status = SDL_SYS_CDStatus;
SDL_CDcaps.Status = SDL_SYS_CDStatus; SDL_CDcaps.Play = SDL_SYS_CDPlay;
SDL_CDcaps.Play = SDL_SYS_CDPlay; SDL_CDcaps.Pause = SDL_SYS_CDPause;
SDL_CDcaps.Pause = SDL_SYS_CDPause; SDL_CDcaps.Resume = SDL_SYS_CDResume;
SDL_CDcaps.Resume = SDL_SYS_CDResume; SDL_CDcaps.Stop = SDL_SYS_CDStop;
SDL_CDcaps.Stop = SDL_SYS_CDStop; SDL_CDcaps.Eject = SDL_SYS_CDEject;
SDL_CDcaps.Eject = SDL_SYS_CDEject; SDL_CDcaps.Close = SDL_SYS_CDClose;
SDL_CDcaps.Close = SDL_SYS_CDClose;
/* clearing device open status */
/* Look in the environment for our CD-ROM drive list */ for (i=0; i<MAX_DRIVES; i++)
SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ {
if ( SDLcdrom != NULL ) { SDL_cdopen[i]=0;
char *cdpath, *delim; }
cdpath = malloc(strlen(SDLcdrom)+1);
if ( cdpath != NULL ) { /* Look in the environment for our CD-ROM drive list */
strcpy(cdpath, SDLcdrom); SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */
SDLcdrom = cdpath; if ( SDLcdrom != NULL )
do { {
delim = strchr(SDLcdrom, ':'); char *cdpath, *delim;
if ( delim ) {
*delim++ = '\0'; cdpath = malloc(strlen(SDLcdrom)+1);
} if (cdpath != NULL)
#ifdef DEBUG_CDROM {
fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); strcpy(cdpath, SDLcdrom);
#endif SDLcdrom = cdpath;
if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { do {
AddDrive(SDLcdrom, &stbuf); delim = strchr(SDLcdrom, ':');
} if (delim)
if ( delim ) { {
SDLcdrom = delim; *delim++ = '\0';
} else { }
SDLcdrom = NULL; if (CheckDrive(SDLcdrom, &stbuf) > 0)
} {
} while ( SDLcdrom ); AddDrive(SDLcdrom, &stbuf);
free(cdpath); }
} if (delim)
{
/* If we found our drives, there's nothing left to do */ SDLcdrom = delim;
if ( SDL_numcds > 0 ) { }
return(0); else
} {
} SDLcdrom = NULL;
}
/* Scan the system for CD-ROM drives */ } while (SDLcdrom);
for ( i=0; checklist[i]; ++i ) { free(cdpath);
if ( checklist[i][0] == '?' ) { }
char *insert;
exists = 1; /* If we found our drives, there's nothing left to do */
for ( j=checklist[i][1]; exists; ++j ) { if (SDL_numcds > 0)
sprintf(drive, "/dev/%s", &checklist[i][3]); {
insert = strchr(drive, '?'); return(0);
if ( insert != NULL ) { }
*insert = j; }
}
#ifdef DEBUG_CDROM /* Scan the system for CD-ROM drives */
fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); for ( i=0; checklist[i]; ++i )
#endif {
switch (CheckDrive(drive, NULL, &stbuf)) { if (checklist[i][0] == '?')
/* Drive exists and is a CD-ROM */ {
case 1: char* insert;
AddDrive(drive, &stbuf); exists = 1;
break;
/* Drive exists, but isn't a CD-ROM */ for ( j=checklist[i][1]; exists; ++j )
case 0: {
break; sprintf(drive, "/dev/%s", &checklist[i][3]);
/* Drive doesn't exist */ insert = strchr(drive, '?');
case -1: if (insert != NULL)
exists = 0; {
break; *insert = j;
} }
} switch (CheckDrive(drive, &stbuf))
} else { {
sprintf(drive, "/dev/%s", checklist[i]); /* Drive exists and is a CD-ROM */
#ifdef DEBUG_CDROM case 1:
fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); AddDrive(drive, &stbuf);
#endif break;
if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { /* Drive exists, but isn't a CD-ROM */
AddDrive(drive, &stbuf); case 0:
} break;
} /* Drive doesn't exist */
} case -1:
return(0); exists = 0;
break;
}
}
}
else
{
sprintf(drive, "/dev/%s", checklist[i]);
if (CheckDrive(drive, &stbuf) > 0)
{
AddDrive(drive, &stbuf);
}
}
}
return(0);
} }
static const char *SDL_SYS_CDName(int drive) static const char *SDL_SYS_CDName(int drive)
{ {
return(SDL_cdlist[drive]); return(SDL_cdlist[drive]);
} }
static int SDL_SYS_CDOpen(int drive) static int SDL_SYS_CDOpen(int drive)
{ {
return(open(SDL_cdlist[drive], (O_RDONLY|O_EXCL|O_NONBLOCK), 0)); int handle;
handle=open(SDL_cdlist[drive], QNX_CD_OPENMODE);
if (handle>0)
{
SDL_cdopen[drive]=handle;
}
return (handle);
} }
static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) static int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
{ {
cdrom_read_toc_t toc; cdrom_read_toc_t toc;
int i, okay; int i, okay;
okay = 0; okay = 0;
if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0) == 0) { if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL) == 0)
cdrom->numtracks = toc.last_track - toc.first_track + 1; {
if ( cdrom->numtracks > SDL_MAX_TRACKS ) { cdrom->numtracks = toc.last_track - toc.first_track + 1;
cdrom->numtracks = SDL_MAX_TRACKS; if (cdrom->numtracks > SDL_MAX_TRACKS)
} {
/* Read all the track TOC entries */ cdrom->numtracks = SDL_MAX_TRACKS;
for ( i=0; i<=cdrom->numtracks; ++i ) { }
if ( i == cdrom->numtracks ) { /* Read all the track TOC entries */
cdrom->track[i].id = CDROM_LEADOUT; for (i=0; i<=cdrom->numtracks; ++i)
} else { {
#if 0 /* Sam 11/6/00 - an obsolete field? */ if (i == cdrom->numtracks)
cdrom->track[i].id = toc.cdth_trk0+i; {
#else cdrom->track[i].id = CDROM_LEADOUT;
cdrom->track[i].id = toc.first_track+i; }
#endif else
} {
cdrom->track[i].type = toc.toc_entry[i].control_adr; cdrom->track[i].id = toc.first_track+i;
cdrom->track[i].offset = MSF_TO_FRAMES( }
toc.toc_entry[i].addr.msf.minute,
toc.toc_entry[i].addr.msf.second, cdrom->track[i].type = toc.toc_entry[i].control_adr & 0x0F;
toc.toc_entry[i].addr.msf.frame); cdrom->track[i].offset = toc.toc_entry[i].addr.lba;
cdrom->track[i].length = 0; cdrom->track[i].length = 0;
if ( i > 0 ) {
cdrom->track[i-1].length = if (i > 0)
cdrom->track[i].offset- {
cdrom->track[i-1].offset; cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset;
} }
} }
if ( i == (cdrom->numtracks+1) ) { if (i == (cdrom->numtracks+1))
okay = 1; {
} okay = 1;
} }
return(okay ? 0 : -1); }
return (okay ? 0 : -1);
} }
/* Get CD-ROM status */ /* Get CD-ROM status */
static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
{ {
CDstatus status; CDstatus status;
cdrom_read_toc_t toc;
subch_current_position_t info; cdrom_read_toc_t toc;
cdrom_subch_data_t info;
#if 0 /* Sam 11/6/00 - an obsolete field? */ cam_devinfo_t dinfo;
info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION;
info.subch_command.track_number = 0; int devctlret=0;
#else int drive=-1;
info.data_format = CDROM_SUBCH_CURRENT_POSITION; int i;
info.track_number = 0; int eagaincnt=0;
#endif
if (devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), 0) != 0) { /* check media presence before read subchannel call, some cdroms can lockups */
if ( ERRNO_TRAYEMPTY(errno) ) { /* if no media, while calling read subchannel functions. */
status = CD_TRAYEMPTY; devctlret=devctl(cdrom->id, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL);
} else {
status = CD_ERROR; if (devctlret==EOK)
} {
} else { if ((dinfo.flags & DEV_NO_MEDIA)!=0)
switch (info.header.audio_status) { {
case CDROM_AUDIO_INVALID: status = CD_TRAYEMPTY;
case CDROM_AUDIO_NO_STATUS: if (position)
/* Try to determine if there's a CD available */ {
if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0)==0) *position = 0;
status = CD_STOPPED; }
else return (status);
status = CD_TRAYEMPTY; }
break; }
case CDROM_AUDIO_COMPLETED:
status = CD_STOPPED; /* if media exists, then do other stuff */
break;
case CDROM_AUDIO_PLAY: memset(&info, 0x00, sizeof(info));
status = CD_PLAYING; info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION;
break;
case CDROM_AUDIO_PAUSED: do {
/* Workaround buggy CD-ROM drive */ devctlret=devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), NULL);
if ( info.data_format == CDROM_LEADOUT ) { if (devctlret==EIO)
status = CD_STOPPED; {
} else { /* big workaround for media change, handle is unusable after that,
status = CD_PAUSED; that bug was found in QNX 6.2, 6.2.1 is not released yet. */
}
break; for (i=0; i<MAX_DRIVES; i++)
default: {
status = CD_ERROR; if (SDL_cdopen[i]==cdrom->id)
break; {
} drive=i;
} break;
if ( position ) { }
if ( status == CD_PLAYING || (status == CD_PAUSED) ) { }
*position = MSF_TO_FRAMES( if (drive==-1)
info.addr.msf.minute, {
info.addr.msf.second, /* that cannot happen, but ... */
info.addr.msf.frame); break;
} else { }
*position = 0; close(cdrom->id);
} cdrom->id=open(SDL_cdlist[drive], QNX_CD_OPENMODE);
} devctlret=EAGAIN;
return(status); }
if (devctlret==EAGAIN)
{
eagaincnt++;
}
if (eagaincnt==2)
{
/* workaround for broken cdroms, which can return always EAGAIN when its not ready, */
/* that mean errornous media or just no media avail */
devctlret=ENXIO;
break;
}
} while ((devctlret==EAGAIN)||(devctlret==ESTALE));
if (devctlret != 0)
{
if (devctlret==ENXIO)
{
status = CD_TRAYEMPTY;
}
else
{
status = CD_ERROR;
}
}
else
{
switch (info.current_position.header.audio_status)
{
case CDROM_AUDIO_INVALID:
case CDROM_AUDIO_NO_STATUS:
/* Try to determine if there's a CD available */
if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL)==0)
status = CD_STOPPED;
else
status = CD_TRAYEMPTY;
break;
case CDROM_AUDIO_COMPLETED:
status = CD_STOPPED;
break;
case CDROM_AUDIO_PLAY:
status = CD_PLAYING;
break;
case CDROM_AUDIO_PAUSED:
/* Workaround buggy CD-ROM drive */
if (info.current_position.data_format == CDROM_LEADOUT)
{
status = CD_STOPPED;
}
else
{
status = CD_PAUSED;
}
break;
default:
status = CD_ERROR;
break;
}
}
if (position)
{
if (status==CD_PLAYING || (status==CD_PAUSED))
{
*position = MSF_TO_FRAMES(info.current_position.addr.msf.minute,
info.current_position.addr.msf.second,
info.current_position.addr.msf.frame);
}
else
{
*position = 0;
}
}
return (status);
} }
/* Start play */ /* Start play */
static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length)
{ {
cdrom_playmsf_t playtime; cdrom_playmsf_t playtime;
FRAMES_TO_MSF(start, FRAMES_TO_MSF(start, &playtime.start_minute, &playtime.start_second, &playtime.start_frame);
&playtime.start_minute, &playtime.start_second, &playtime.start_frame); FRAMES_TO_MSF(start+length, &playtime.end_minute, &playtime.end_second, &playtime.end_frame);
FRAMES_TO_MSF(start+length,
&playtime.end_minute, &playtime.end_second, &playtime.end_frame); if (devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), NULL) != 0)
#ifdef DEBUG_CDROM {
fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", return -1;
playtime.start_minute, playtime.start_second, playtime.start_frame, }
playtime.end_minute, playtime.end_second, playtime.end_frame); else
#endif {
return(devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), 0)); return 0;
}
} }
/* Pause play */ /* Pause play */
static int SDL_SYS_CDPause(SDL_CD *cdrom) static int SDL_SYS_CDPause(SDL_CD *cdrom)
{ {
return(devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, 0)); if (devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, NULL)!=0)
{
return -1;
}
else
{
return 0;
}
} }
/* Resume play */ /* Resume play */
static int SDL_SYS_CDResume(SDL_CD *cdrom) static int SDL_SYS_CDResume(SDL_CD *cdrom)
{ {
return(devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, 0)); if (devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, NULL)!=0)
{
return -1;
}
else
{
return 0;
}
} }
/* Stop play */ /* Stop play */
static int SDL_SYS_CDStop(SDL_CD *cdrom) static int SDL_SYS_CDStop(SDL_CD *cdrom)
{ {
return(devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, 0)); if (devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, NULL)!=0)
{
return -1;
}
else
{
return 0;
}
} }
/* Eject the CD-ROM */ /* Eject the CD-ROM */
static int SDL_SYS_CDEject(SDL_CD *cdrom) static int SDL_SYS_CDEject(SDL_CD *cdrom)
{ {
return(devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, 0)); if (devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, NULL)!=0)
{
return -1;
}
else
{
return 0;
}
} }
/* Close the CD-ROM handle */ /* Close the CD-ROM handle */
static void SDL_SYS_CDClose(SDL_CD *cdrom) static void SDL_SYS_CDClose(SDL_CD *cdrom)
{ {
close(cdrom->id); int i;
for (i=0; i<MAX_DRIVES; i++)
{
if (SDL_cdopen[i]==cdrom->id)
{
SDL_cdopen[i]=0;
break;
}
}
close(cdrom->id);
} }
void SDL_SYS_CDQuit(void) void SDL_SYS_CDQuit(void)
{ {
int i; int i;
if ( SDL_numcds > 0 ) { if (SDL_numcds > 0)
for ( i=0; i<SDL_numcds; ++i ) { {
free(SDL_cdlist[i]); for (i=0; i<SDL_numcds; ++i)
} {
SDL_numcds = 0; free(SDL_cdlist[i]);
} }
SDL_numcds = 0;
}
} }
...@@ -55,67 +55,28 @@ SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym); ...@@ -55,67 +55,28 @@ SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym);
(idea shamelessly lifted from GII -- thanks guys! :) (idea shamelessly lifted from GII -- thanks guys! :)
*/ */
#if 0
static int ph_KeyRepeat(_THIS, PhKeyEvent_t* keyevent)
{
// PhEvent_t* peekevent;
PhKeyEvent_t* keyEvent;
int repeated;
repeated = 0;
switch (PhEventPeek( peekevent, EVENT_SIZE ))
{
case Ph_EVENT_MSG: {
if(peekevent->type == Ph_EV_KEY)
{
keyEvent = PhGetData( peekevent );
if ( !(Pk_KF_Key_Down & keyEvent->key_flags) &&
(keyEvent->key_cap == keyevent->key_cap) &&
(peekevent->timestamp == event->timestamp)
) {
repeated = 1;
/* PhEventNext( peekevent, EVENT_SIZE ); */
}
}
}
break;
case -1: {
perror( "PhEventPeek failed" );
}
break;
default: /* no events pending */
}
return(repeated);
}
#endif
static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent) static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent)
{ {
/* PhPointerEvent_t *pointer = PhGetData( winEvent ); */ PhRect_t *rect = PhGetRects( winEvent );
PhRect_t *rect = PhGetRects( winEvent );
int centre_x, centre_y; int centre_x, centre_y;
int dx, dy; int dx, dy;
short abs_x, abs_y; short abs_x, abs_y;
int posted; int posted;
centre_x = SDL_VideoSurface->w / 2; centre_x = SDL_VideoSurface->w / 2;
centre_y = SDL_VideoSurface->h / 2; centre_y = SDL_VideoSurface->h / 2;
dx = rect->ul.x - centre_x; dx = rect->ul.x - centre_x;
dy = rect->ul.y - centre_y; dy = rect->ul.y - centre_y;
posted = SDL_PrivateMouseMotion( 0, 1, dx, dy ); posted = SDL_PrivateMouseMotion( 0, 1, dx, dy );
/* Move mouse cursor to middle of the window */ /* Move mouse cursor to middle of the window */
PtGetAbsPosition( window, &abs_x, &abs_y ); PtGetAbsPosition( window, &abs_x, &abs_y );
PhMoveCursorAbs( PhInputGroup(NULL), PhMoveCursorAbs(PhInputGroup(NULL), abs_x + centre_x, abs_y + centre_y);
abs_x + centre_x,
abs_y + centre_y );
return(posted); return (posted);
} }
/* Control which motion flags the window has set, a flags value of -1 sets /* Control which motion flags the window has set, a flags value of -1 sets
...@@ -123,35 +84,34 @@ static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent) ...@@ -123,35 +84,34 @@ static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent)
static void set_motion_sensitivity(_THIS, unsigned int flags) static void set_motion_sensitivity(_THIS, unsigned int flags)
{ {
int rid, fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON; int rid;
PhRegion_t region; int fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON;
PhRegion_t region;
if( window ) if( window )
{ {
rid = PtWidgetRid( window ); rid = PtWidgetRid( window );
if( rid != 0 && PhRegionQuery( rid, &region, NULL, NULL, 0 ) == 0 ) if( rid != 0 && PhRegionQuery( rid, &region, NULL, NULL, 0 ) == 0 )
{ {
region.events_sense = ( region.events_sense & ~fields ) | region.events_sense=(region.events_sense & ~fields)|(flags & fields);
( flags & fields ); PhRegionChange(Ph_REGION_EV_SENSE, 0, &region, NULL, NULL);
PhRegionChange( Ph_REGION_EV_SENSE, 0, &region, }
NULL, NULL ); }
}
}
} }
/* Convert the photon button state value to an SDL value */ /* Convert the photon button state value to an SDL value */
static Uint8 ph2sdl_mousebutton( unsigned short button_state ) static Uint8 ph2sdl_mousebutton(unsigned short button_state)
{ {
Uint8 mouse_button = 0; Uint8 mouse_button = 0;
if( button_state & Ph_BUTTON_SELECT ) if (button_state & Ph_BUTTON_SELECT)
mouse_button |= SDL_BUTTON_LEFT; mouse_button |= SDL_BUTTON_LEFT;
if( button_state & Ph_BUTTON_MENU ) if (button_state & Ph_BUTTON_MENU)
mouse_button |= SDL_BUTTON_RIGHT; mouse_button |= SDL_BUTTON_RIGHT;
if( button_state & Ph_BUTTON_ADJUST ) if (button_state & Ph_BUTTON_ADJUST)
mouse_button |= SDL_BUTTON_MIDDLE; mouse_button |= SDL_BUTTON_MIDDLE;
return( mouse_button ); return (mouse_button);
} }
static int ph_DispatchEvent(_THIS) static int ph_DispatchEvent(_THIS)
...@@ -245,10 +205,6 @@ static int ph_DispatchEvent(_THIS) ...@@ -245,10 +205,6 @@ static int ph_DispatchEvent(_THIS)
{ {
set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON); set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON);
posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
/* Queue leaving fullscreen mode */
switch_waiting = 0x01;
switch_time = SDL_GetTicks() + 200;
} }
/* gaining focus */ /* gaining focus */
else if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUS)) else if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUS))
...@@ -323,271 +279,187 @@ static int ph_DispatchEvent(_THIS) ...@@ -323,271 +279,187 @@ static int ph_DispatchEvent(_THIS)
/* perform a blocking read if no events available */ /* perform a blocking read if no events available */
int ph_Pending(_THIS) int ph_Pending(_THIS)
{ {
/* Flush the display connection and look to see if events are queued */ /* Flush the display connection and look to see if events are queued */
PgFlush(); PgFlush();
while( 1 ) while( 1 )
{ //note this is a non-blocking call { /* note this is a non-blocking call */
switch( PhEventPeek( event, EVENT_SIZE ) ) switch( PhEventPeek( event, EVENT_SIZE ) )
{ {
case Ph_EVENT_MSG: case Ph_EVENT_MSG:
return 1; return 1;
break; break;
case -1: case -1:
perror( "PhEventNext failed" ); perror("ph_Pending(): PhEventNext failed");
break; break;
default: default:
return 0;
return 0;
}
}
/* Oh well, nothing is ready .. */
return(0);
}
/*
SAMPLE EVENT PUMP
=================
static void update( int block ){
int ch,fl;
PhKeyEvent_t *key;
for( ;; ){
if( block ){
do{
fl=PhEventNext( event,EVENT_SIZE );
}while( fl!=Ph_EVENT_MSG );
block=0;
}else{
do{
fl=PhEventPeek( event,EVENT_SIZE );
if( !fl ) return;
}while( fl!=Ph_EVENT_MSG );
}
switch( event->type ){
case Ph_EV_KEY:
key=PhGetData( event );
ch=key->key_cap; // & 127;
fl=key->key_flags;
if( ch<32 || ch>127 ) break;
if( fl & Pk_KF_Key_Down ){
if( !(fl & Pk_KF_Key_Repeat) ){
if( queput-queget<QUE_SIZE ) keyque[ queput++ & QUE_MASK ]=ch;
keyMatrix[ch]=1;
}
}else{
keyMatrix[ch]=0;
}
break;
default:
PtEventHandler( event );
} }
} }
/* Oh well, nothing is ready .. */
return(0);
} }
*/
void ph_PumpEvents(_THIS) void ph_PumpEvents(_THIS)
{ {
int pending; /* Flush the display connection and look to see if events are queued */
PgFlush();
/* Keep processing pending events */
pending = 0; while (ph_Pending(this))
while ( ph_Pending(this) ) { {
ph_DispatchEvent(this); ph_DispatchEvent(this);
++pending; }
}
if ( switch_waiting ) {
Uint32 now;
now = SDL_GetTicks();
#if 0
if ( pending || !SDL_VideoSurface ) {
/* Try again later... */
if ( switch_waiting & SDL_FULLSCREEN ) {
switch_time = now + 1500;
} else {
switch_time = now + 200;
}
} else if ( now >= switch_time ) {
Uint32 go_fullscreen;
go_fullscreen = switch_waiting & SDL_FULLSCREEN;
switch_waiting = 0;
if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) {
if ( go_fullscreen ) {
ph_EnterFullScreen(this);
} else {
ph_LeaveFullScreen(this);
}
}
/* Handle focus in/out when grabbed */
/*
if ( go_fullscreen ) {
ph_GrabInputNoLock(this, this->input_grab);
} else {
ph_GrabInputNoLock(this, SDL_GRAB_OFF);
}
*/
}
#endif
}
} }
void ph_InitKeymap(void) void ph_InitKeymap(void)
{ {
int i; int i;
/* Odd keys used in international keyboards */ /* Odd keys used in international keyboards */
for ( i=0; i<SDL_TABLESIZE(ODD_keymap); ++i ) for (i=0; i<SDL_TABLESIZE(ODD_keymap); ++i)
ODD_keymap[i] = SDLK_UNKNOWN; ODD_keymap[i] = SDLK_UNKNOWN;
/* Map the miscellaneous keys */ /* Map the miscellaneous keys */
for ( i=0; i<SDL_TABLESIZE(MISC_keymap); ++i ) for (i=0; i<SDL_TABLESIZE(MISC_keymap); ++i)
MISC_keymap[i] = SDLK_UNKNOWN; MISC_keymap[i] = SDLK_UNKNOWN;
MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE; MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE;
MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB; MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB;
MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR; MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR;
MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN; MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN;
MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE; MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE;
MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE; MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE;
MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE; MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE;
MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0; MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0;
MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1; MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1;
MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2; MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2;
MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3; MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3;
MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4; MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4;
MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5; MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5;
MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6; MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6;
MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7; MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7;
MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8; MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8;
MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9; MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9;
MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD; MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD;
MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE; MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE;
MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY; MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY;
MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS; MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS;
MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS; MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS;
MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER; MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER;
MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS; MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS;
MISC_keymap[Pk_Up&0xFF] = SDLK_UP; MISC_keymap[Pk_Up&0xFF] = SDLK_UP;
MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN; MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN;
MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT; MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT;
MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT; MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT;
MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT; MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT;
MISC_keymap[Pk_Home&0xFF] = SDLK_HOME; MISC_keymap[Pk_Home&0xFF] = SDLK_HOME;
MISC_keymap[Pk_End&0xFF] = SDLK_END; MISC_keymap[Pk_End&0xFF] = SDLK_END;
MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP; MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP;
MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN; MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN;
MISC_keymap[Pk_F1&0xFF] = SDLK_F1; MISC_keymap[Pk_F1&0xFF] = SDLK_F1;
MISC_keymap[Pk_F2&0xFF] = SDLK_F2; MISC_keymap[Pk_F2&0xFF] = SDLK_F2;
MISC_keymap[Pk_F3&0xFF] = SDLK_F3; MISC_keymap[Pk_F3&0xFF] = SDLK_F3;
MISC_keymap[Pk_F4&0xFF] = SDLK_F4; MISC_keymap[Pk_F4&0xFF] = SDLK_F4;
MISC_keymap[Pk_F5&0xFF] = SDLK_F5; MISC_keymap[Pk_F5&0xFF] = SDLK_F5;
MISC_keymap[Pk_F6&0xFF] = SDLK_F6; MISC_keymap[Pk_F6&0xFF] = SDLK_F6;
MISC_keymap[Pk_F7&0xFF] = SDLK_F7; MISC_keymap[Pk_F7&0xFF] = SDLK_F7;
MISC_keymap[Pk_F8&0xFF] = SDLK_F8; MISC_keymap[Pk_F8&0xFF] = SDLK_F8;
MISC_keymap[Pk_F9&0xFF] = SDLK_F9; MISC_keymap[Pk_F9&0xFF] = SDLK_F9;
MISC_keymap[Pk_F10&0xFF] = SDLK_F10; MISC_keymap[Pk_F10&0xFF] = SDLK_F10;
MISC_keymap[Pk_F11&0xFF] = SDLK_F11; MISC_keymap[Pk_F11&0xFF] = SDLK_F11;
MISC_keymap[Pk_F12&0xFF] = SDLK_F12; MISC_keymap[Pk_F12&0xFF] = SDLK_F12;
MISC_keymap[Pk_F13&0xFF] = SDLK_F13; MISC_keymap[Pk_F13&0xFF] = SDLK_F13;
MISC_keymap[Pk_F14&0xFF] = SDLK_F14; MISC_keymap[Pk_F14&0xFF] = SDLK_F14;
MISC_keymap[Pk_F15&0xFF] = SDLK_F15; MISC_keymap[Pk_F15&0xFF] = SDLK_F15;
MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK; MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK;
MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK; MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK;
MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK; MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT; MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT;
MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT; MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT;
MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL; MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL;
MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL; MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL;
MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT; MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT;
MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT; MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT;
MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA; MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA;
MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA; MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA;
MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */ MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */
MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */ MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows" */
MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */ MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */
MISC_keymap[Pk_Help&0xFF] = SDLK_HELP; MISC_keymap[Pk_Help&0xFF] = SDLK_HELP;
MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT; MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT;
// MISC_keymap[Pk_Sys_Req] = SDLK_SYSREQ; MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK;
MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK; MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU;
MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU; MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */
MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_MENU; /* Windows "Menu" key */
} }
static unsigned long cap; static unsigned long cap;
SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym) SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym)
{ {
/* /* 'sym' is set to the value of the key with modifiers applied to it.
'sym' is set to the value of the key with modifiers applied to it. This member is valid only if Pk_KF_Sym_Valid is set in the key_flags.
This member is valid only if Pk_KF_Sym_Valid is set in the key_flags. We will assume it is valid. */
We will assume it is valid.
*/ /* FIXME: This needs to check whether the cap & scancode is valid */
/* FIXME: This needs to check whether the cap & scancode is valid */
cap = key->key_cap; cap = key->key_cap;
switch (cap>>8) {
case 0x00: /* Latin 1 */
case 0x01: /* Latin 2 */
case 0x02: /* Latin 3 */
case 0x03: /* Latin 4 */
case 0x04: /* Katakana */
case 0x05: /* Arabic */
case 0x06: /* Cyrillic */
case 0x07: /* Greek */
case 0x08: /* Technical */
case 0x0A: /* Publishing */
case 0x0C: /* Hebrew */
case 0x0D: /* Thai */
keysym->sym = (SDLKey)(cap&0xFF);
/* Map capital letter syms to lowercase */
if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
keysym->sym += ('a'-'A');
break;
// case 0xFE:
// keysym->sym = ODD_keymap[sym&0xFF];
// break;
case 0xF0:
keysym->sym = MISC_keymap[cap&0xFF];
break;
default:
/* fprintf(stderr,"Photon: Unknown key_cap, cap = 0x%.4x\n", (unsigned int)cap); */
keysym->sym = SDLK_UNKNOWN;
break;
}
keysym->scancode = key->key_scan;
keysym->unicode = 0;
if( SDL_TranslateUNICODE )
{
char utf8[MB_CUR_MAX];
int utf8len;
wchar_t unicode;
utf8len = PhKeyToMb( utf8, key );
if( utf8len > 0 )
{
utf8len = mbtowc( &unicode, utf8, utf8len );
if( utf8len > 0)
keysym->unicode = unicode;
}
}
return (keysym); switch (cap>>8)
{
case 0x00: /* Latin 1 */
case 0x01: /* Latin 2 */
case 0x02: /* Latin 3 */
case 0x03: /* Latin 4 */
case 0x04: /* Katakana */
case 0x05: /* Arabic */
case 0x06: /* Cyrillic */
case 0x07: /* Greek */
case 0x08: /* Technical */
case 0x0A: /* Publishing */
case 0x0C: /* Hebrew */
case 0x0D: /* Thai */
keysym->sym = (SDLKey)(cap&0xFF);
/* Map capital letter syms to lowercase */
if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
keysym->sym += ('a'-'A');
break;
case 0xF0:
keysym->sym = MISC_keymap[cap&0xFF];
break;
default:
keysym->sym = SDLK_UNKNOWN;
break;
}
keysym->scancode = key->key_scan;
keysym->unicode = 0;
if (SDL_TranslateUNICODE)
{
char utf8[MB_CUR_MAX];
int utf8len;
wchar_t unicode;
utf8len = PhKeyToMb(utf8, key);
if (utf8len > 0)
{
utf8len = mbtowc(&unicode, utf8, utf8len);
if (utf8len > 0)
keysym->unicode = unicode;
}
}
return (keysym);
} }
void ph_InitOSKeymap(_THIS) void ph_InitOSKeymap(_THIS)
{ {
ph_InitKeymap(); ph_InitKeymap();
} }
...@@ -27,7 +27,7 @@ static char rcsid = ...@@ -27,7 +27,7 @@ static char rcsid =
#include "SDL_ph_video.h" #include "SDL_ph_video.h"
#define EVENT_SIZE sizeof( PhEvent_t ) + 1000 #define EVENT_SIZE sizeof(PhEvent_t) + 1000
/* Functions to be exported */ /* Functions to be exported */
extern void ph_InitOSKeymap(_THIS); extern void ph_InitOSKeymap(_THIS);
......
...@@ -29,16 +29,60 @@ static char rcsid = ...@@ -29,16 +29,60 @@ static char rcsid =
#include <Ph.h> #include <Ph.h>
#include <photon/Pg.h> #include <photon/Pg.h>
#include "SDL.h"
#include "SDL_error.h" #include "SDL_error.h"
#include "SDL_endian.h" #include "SDL_endian.h"
#include "SDL_video.h"
#include "SDL_pixels_c.h"
#include "SDL_ph_image_c.h" #include "SDL_ph_image_c.h"
/* remove this line, if photon headers updates */ /* Mask values for SDL_ReallocFormat() */
int PgWaitHWIdle(void); struct ColourMasks
{
Uint32 red;
Uint32 green;
Uint32 blue;
Uint32 alpha;
Uint32 bpp;
};
static const struct ColourMasks *ph_GetColourMasks( int format )
{
/* The alpha mask doesn't appear to be needed */
static const struct ColourMasks phColorMasks[5] = {
/* 8 bit */ {0, 0, 0, 0, 8},
/* 15 bit ARGB */ {0x7C00, 0x03E0, 0x001F, 0x8000, 16},
/* 16 bit RGB */ {0xF800, 0x07E0, 0x001F, 0x0000, 16},
/* 24 bit RGB */ {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
/* 32 bit ARGB */ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
};
switch( format )
{
case Pg_IMAGE_PALETTE_BYTE:
return &phColorMasks[0];
break;
case Pg_IMAGE_DIRECT_1555:
case Pg_IMAGE_DIRECT_555:
return &phColorMasks[1];
break;
case Pg_IMAGE_DIRECT_565:
return &phColorMasks[2];
break;
case Pg_IMAGE_DIRECT_888:
return &phColorMasks[3];
break;
case Pg_IMAGE_DIRECT_8888:
return &phColorMasks[4];
break;
}
return NULL;
}
int ph_SetupImage(_THIS, SDL_Surface *screen) int ph_SetupImage(_THIS, SDL_Surface *screen)
{ {
PgColor_t* palette=NULL; PgColor_t* palette=NULL;
const struct ColourMasks* mask;
int type=0; int type=0;
int bpp; int bpp;
...@@ -68,7 +112,7 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) ...@@ -68,7 +112,7 @@ int ph_SetupImage(_THIS, SDL_Surface *screen)
} }
break; break;
default:{ default:{
fprintf(stderr,"ph_SetupImage(): unsupported bbp = %d\n", bpp); fprintf(stderr,"ph_SetupImage(): unsupported bpp=%d !\n", bpp);
return -1; return -1;
} }
break; break;
...@@ -84,7 +128,7 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) ...@@ -84,7 +128,7 @@ int ph_SetupImage(_THIS, SDL_Surface *screen)
/* using shared memory for speed (set last param to 1) */ /* using shared memory for speed (set last param to 1) */
if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL) if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL)
{ {
fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8.\n"); fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8 !\n");
return -1; return -1;
} }
} }
...@@ -93,14 +137,20 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) ...@@ -93,14 +137,20 @@ int ph_SetupImage(_THIS, SDL_Surface *screen)
/* using shared memory for speed (set last param to 1) */ /* using shared memory for speed (set last param to 1) */
if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL) if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL)
{ {
fprintf(stderr,"ph_SetupImage: PhCreateImage failed.\n"); fprintf(stderr,"ph_SetupImage: PhCreateImage failed !\n");
return -1; return -1;
} }
} }
screen->pixels = SDL_Image->image; screen->pixels = SDL_Image->image;
screen->pitch = SDL_Image->bpl; /* Recalculated pitch, created by PhCreateImage */ screen->pitch = SDL_Image->bpl; /* Recalculated pitch, created by PhCreateImage */
mask = ph_GetColourMasks(type);
if (mask != NULL)
{
SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
}
this->UpdateRects = ph_NormalUpdate; this->UpdateRects = ph_NormalUpdate;
return 0; return 0;
...@@ -108,8 +158,12 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) ...@@ -108,8 +158,12 @@ int ph_SetupImage(_THIS, SDL_Surface *screen)
int ph_SetupOCImage(_THIS, SDL_Surface *screen) int ph_SetupOCImage(_THIS, SDL_Surface *screen)
{ {
const struct ColourMasks *mask;
int type = 0; int type = 0;
int bpp; int bpp;
screen->flags &= ~SDL_DOUBLEBUF;
OCImage.flags = screen->flags;
bpp=screen->format->BitsPerPixel; bpp=screen->format->BitsPerPixel;
...@@ -137,22 +191,14 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) ...@@ -137,22 +191,14 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen)
} }
break; break;
default:{ default:{
fprintf(stderr,"ph_SetupOCImage(): unsupported bpp = %d\n", bpp); fprintf(stderr,"ph_SetupOCImage(): unsupported bpp=%d !\n", bpp);
return -1; return -1;
} }
break; break;
} }
OCImage.FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA))); /* Currently only offscreen contexts with the same bit depth as the
OCImage.FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA))); * display can be created. */
memset(OCImage.FrameData0, 0x00, (size_t)(sizeof(FRAMEDATA)));
memset(OCImage.FrameData1, 0x00, (size_t)(sizeof(FRAMEDATA)));
if(OCImage.direct_context == NULL)
{
OCImage.direct_context = PdCreateDirectContext();
}
OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN); OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN);
if (OCImage.offscreen_context == NULL) if (OCImage.offscreen_context == NULL)
...@@ -161,13 +207,22 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) ...@@ -161,13 +207,22 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen)
return -1; return -1;
} }
screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */ /* If the bit depth of the context is different than was requested,
* these values need to be updated accordingly. SDL will
if (OCImage.flags & SDL_DOUBLEBUF) * allocate a shadow surface if it needs to. */
mask = ph_GetColourMasks(OCImage.offscreen_context->format);
if (mask != NULL)
{ {
fprintf(stderr, "ph_SetupOCImage(): Hardware flag for doublebuf offscreen context\n"); SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
if (mask->bpp > 8)
{
screen->flags &= ~SDL_HWPALETTE;
}
} }
screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context); OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
if (OCImage.dc_ptr.ptr8 == NULL) if (OCImage.dc_ptr.ptr8 == NULL)
...@@ -176,15 +231,13 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) ...@@ -176,15 +231,13 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen)
return -1; return -1;
} }
OCImage.FrameData0 = OCImage.dc_ptr.ptr8;
OCImage.CurrentFrameData = OCImage.FrameData0; OCImage.CurrentFrameData = OCImage.FrameData0;
OCImage.CurrentFrameData->Y = OCImage.dc_ptr.ptr8;
OCImage.CurrentFrameData->U = NULL;
OCImage.CurrentFrameData->V = NULL;
OCImage.current = 0; OCImage.current = 0;
PhDCSetCurrent(OCImage.offscreen_context); PhDCSetCurrent(OCImage.offscreen_context);
screen->pixels = OCImage.CurrentFrameData->Y; screen->pixels = OCImage.CurrentFrameData;
this->UpdateRects = ph_OCUpdate; this->UpdateRects = ph_OCUpdate;
...@@ -198,15 +251,67 @@ int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen) ...@@ -198,15 +251,67 @@ int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen)
return 0; return 0;
} }
int ph_SetupFullScreenImage(_THIS, SDL_Surface* screen)
{
const struct ColourMasks *mask;
screen->flags &= ~SDL_DOUBLEBUF;
OCImage.flags = screen->flags;
OCImage.offscreen_context = PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY);
if (OCImage.offscreen_context == NULL)
{
fprintf(stderr, "ph_SetupFullScreenImage(): PdCreateOffscreenContext failed !\n");
return -1;
}
/* If the bit depth of the context is different than was requested,
* these values need to be updated accordingly. SDL will
* allocate a shadow surface if it needs to. */
mask = ph_GetColourMasks(OCImage.offscreen_context->format);
if (mask != NULL)
{
SDL_ReallocFormat(screen, mask->bpp, mask->red, mask->green, mask->blue, 0);
if (mask->bpp > 8)
{
screen->flags &= ~SDL_HWPALETTE;
}
}
screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
OCImage.dc_ptr.ptr8 = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
if (OCImage.dc_ptr.ptr8 == NULL)
{
fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n");
return -1;
}
/* wait for hw */
PgWaitHWIdle();
OCImage.FrameData0 = OCImage.dc_ptr.ptr8;
OCImage.CurrentFrameData = OCImage.FrameData0;
OCImage.current = 0;
PhDCSetCurrent(OCImage.offscreen_context);
screen->pixels = OCImage.CurrentFrameData;
this->UpdateRects = ph_OCUpdate;
return 0;
}
void ph_DestroyImage(_THIS, SDL_Surface *screen) void ph_DestroyImage(_THIS, SDL_Surface *screen)
{ {
if (OCImage.offscreen_context != NULL) if (OCImage.offscreen_context != NULL)
{ {
PhDCRelease(OCImage.offscreen_context); PhDCRelease(OCImage.offscreen_context);
OCImage.offscreen_context = NULL; OCImage.offscreen_context = NULL;
free(OCImage.FrameData0);
OCImage.FrameData0 = NULL; OCImage.FrameData0 = NULL;
free(OCImage.FrameData1);
OCImage.FrameData1 = NULL; OCImage.FrameData1 = NULL;
} }
...@@ -230,23 +335,24 @@ void ph_DestroyImage(_THIS, SDL_Surface *screen) ...@@ -230,23 +335,24 @@ void ph_DestroyImage(_THIS, SDL_Surface *screen)
} }
} }
int ph_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) int ph_SetupUpdateFunction(_THIS, SDL_Surface *screen, Uint32 flags)
{ {
ph_DestroyImage(this, screen); ph_DestroyImage(this, screen);
if (flags & SDL_HWSURFACE) if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)
{
return ph_SetupFullScreenImage(this, screen);
}
if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE)
{ {
OCImage.flags = flags; /* needed for SDL_DOUBLEBUF check */
return ph_SetupOCImage(this, screen); return ph_SetupOCImage(this, screen);
} }
else if (flags & SDL_OPENGL) if ((flags & SDL_OPENGL)==SDL_OPENGL)
{ {
return ph_SetupOpenGLImage(this, screen); return ph_SetupOpenGLImage(this, screen);
} }
else
{ return ph_SetupImage(this, screen);
return ph_SetupImage(this, screen);
}
} }
int ph_AllocHWSurface(_THIS, SDL_Surface *surface) int ph_AllocHWSurface(_THIS, SDL_Surface *surface)
{ {
...@@ -265,11 +371,6 @@ int ph_FlipHWSurface(_THIS, SDL_Surface *surface) ...@@ -265,11 +371,6 @@ int ph_FlipHWSurface(_THIS, SDL_Surface *surface)
int ph_LockHWSurface(_THIS, SDL_Surface *surface) int ph_LockHWSurface(_THIS, SDL_Surface *surface)
{ {
if ((surface == SDL_VideoSurface) && blit_queued) {
PgFlush();
blit_queued = 0;
}
return(0); return(0);
} }
...@@ -307,7 +408,7 @@ void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) ...@@ -307,7 +408,7 @@ void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0) if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
{ {
fprintf(stderr,"ph_NormalUpdate(): PgDrawPhImageRectmx failed.\n"); fprintf(stderr,"ph_NormalUpdate(): PgDrawPhImageRectmx failed !\n");
} }
} }
...@@ -325,11 +426,6 @@ void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects) ...@@ -325,11 +426,6 @@ void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects)
PhArea_t src_rect; PhArea_t src_rect;
PhArea_t dest_rect; PhArea_t dest_rect;
if(OCImage.direct_context == NULL)
{
return;
}
PgSetRegion(PtWidgetRid(window)); PgSetRegion(PtWidgetRid(window));
PgSetClipping(0, NULL); PgSetClipping(0, NULL);
PgWaitHWIdle(); PgWaitHWIdle();
......
...@@ -29,7 +29,7 @@ static char rcsid = ...@@ -29,7 +29,7 @@ static char rcsid =
extern int ph_SetupImage(_THIS, SDL_Surface *screen); extern int ph_SetupImage(_THIS, SDL_Surface *screen);
extern void ph_DestroyImage(_THIS, SDL_Surface *screen); extern void ph_DestroyImage(_THIS, SDL_Surface *screen);
extern int ph_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags); extern int ph_SetupUpdateFunction(_THIS, SDL_Surface *screen, Uint32 flags);
extern int ph_AllocHWSurface(_THIS, SDL_Surface *surface); extern int ph_AllocHWSurface(_THIS, SDL_Surface *surface);
extern void ph_FreeHWSurface(_THIS, SDL_Surface *surface); extern void ph_FreeHWSurface(_THIS, SDL_Surface *surface);
......
...@@ -31,35 +31,36 @@ static unsigned long key1, key2; ...@@ -31,35 +31,36 @@ static unsigned long key1, key2;
static PgVideoModeInfo_t mode_info; static PgVideoModeInfo_t mode_info;
static PgVideoModes_t mode_list; static PgVideoModes_t mode_list;
/* The current list of available video modes */ /* The current list of available video modes */
SDL_Rect SDL_modelist[PH_MAX_VIDEOMODES]; SDL_Rect SDL_modelist[PH_MAX_VIDEOMODES];
SDL_Rect* SDL_modearray[PH_MAX_VIDEOMODES]; SDL_Rect* SDL_modearray[PH_MAX_VIDEOMODES];
static int compare_modes_by_res(const void* mode1, const void* mode2) static int compare_modes_by_res(const void* mode1, const void* mode2)
{ {
if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode_info) < 0)
{
fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
*(unsigned short*)mode1);
return 0;
}
if (PgGetVideoModeInfo(*(unsigned short*)mode1, &mode_info) < 0) key1 = mode_info.width * mode_info.height;
{
fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
*(unsigned short*)mode1);
return 0;
}
key1 = mode_info.width * mode_info.height;
if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0) if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0)
{ {
fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n", fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n",
*(unsigned short*)mode2); *(unsigned short*)mode2);
return 0; return 0;
} }
key2 = mode_info.width * mode_info.height;
if (key1 > key2) key2 = mode_info.width * mode_info.height;
return 1;
else if (key1 == key2) if (key1 > key2)
return 0; return 1;
else else if (key1 == key2)
return -1; return 0;
else
return -1;
} }
SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
...@@ -117,89 +118,6 @@ void ph_FreeVideoModes(_THIS) ...@@ -117,89 +118,6 @@ void ph_FreeVideoModes(_THIS)
return; return;
} }
#if 0
static void set_best_resolution(_THIS, int width, int height)
{
/* warning ! dead variable use_vidmode ! */
if ( use_vidmode ) {
PgDisplaySettings_t settings;
PgVideoModeInfo_t current_mode_info;
PgHWCaps_t my_hwcaps;
unsigned short current_bpp;
int i;
/*
if (PgGetVideoMode( &settings ) < 0)
{
fprintf(stderr,"error: PgGetVideoMode failed\n");
return;
}
if (PgGetVideoModeInfo( settings.mode, &current_mode_info ) < 0)
{
fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
return;
}
*/
//lu_zero
if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
{
fprintf(stderr,"set_best_resolution: GetGraphicsHWCaps failed!! \n");
//that HAVE to work
}
if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &current_mode_info) < 0)
{
fprintf(stderr,"set_best_resolution: PgGetVideoModeInfo failed\n");
}
current_bpp = current_mode_info.bits_per_pixel;
if (PgGetVideoModeList(&mode_list) >= 0)
{
qsort(mode_list.modes, mode_list.num_modes, sizeof(unsigned short), compare_modes_by_res);
#ifdef PH_DEBUG
printf("Available modes:\n");
for ( i = 0; i < mode_list.num_modes; ++i )
{
PgGetVideoModeInfo(mode_list.modes[i], &mode_info);
printf("Mode %d: %dx%d\n", i, mode_info.width, mode_info.height);
}
#endif
for ( i = mode_list.num_modes-1; i >= 0 ; --i )
{
if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
{
fprintf(stderr,"error: PgGetVideoModeInfo failed\n");
}
if ( (mode_info.width >= width) &&
(mode_info.height >= height) &&
(mode_info.bits_per_pixel == current_bpp) )
break;
}
if (i >= 0)
{
if ( (mode_info.width != current_mode_info.width) ||
(mode_info.height != current_mode_info.height) )
{
settings.mode = mode_list.modes[i];
if(PgSetVideoMode( &settings ) < 0)
{
fprintf(stderr,"error: PgSetVideoMode failed\n");
}
}
}
}
}
}
int ph_ResizeFullScreen(_THIS)
{
if (currently_fullscreen)
{
set_best_resolution(this, current_w, current_h);
}
return (1);
}
#endif /* 0 */
/* return the mode associated with width, height and bpp */ /* return the mode associated with width, height and bpp */
/* if there is no mode then zero is returned */ /* if there is no mode then zero is returned */
int get_mode(int width, int height, int bpp) int get_mode(int width, int height, int bpp)
...@@ -270,7 +188,7 @@ int get_mode_any_format(int width, int height, int bpp) ...@@ -270,7 +188,7 @@ int get_mode_any_format(int width, int height, int bpp)
/* get closest bpp */ /* get closest bpp */
closest = i++; closest = i++;
if (mode_info.bits_per_pixel == bpp) if (mode_info.bits_per_pixel == bpp)
return mode_list.modes[ closest ]; return mode_list.modes[closest];
min_delta = abs(mode_info.bits_per_pixel - bpp); min_delta = abs(mode_info.bits_per_pixel - bpp);
while(1) while(1)
...@@ -300,16 +218,12 @@ int get_mode_any_format(int width, int height, int bpp) ...@@ -300,16 +218,12 @@ int get_mode_any_format(int width, int height, int bpp)
i++; i++;
} }
} }
return mode_list.modes[ closest ]; return mode_list.modes[closest];
} }
else else
return 0; return 0;
} }
void ph_WaitMapped(_THIS);
void ph_WaitUnmapped(_THIS);
void ph_QueueEnterFullScreen(_THIS);
int ph_ToggleFullScreen(_THIS, int on) int ph_ToggleFullScreen(_THIS, int on)
{ {
if (currently_fullscreen) if (currently_fullscreen)
...@@ -338,17 +252,18 @@ int ph_EnterFullScreen(_THIS) ...@@ -338,17 +252,18 @@ int ph_EnterFullScreen(_THIS)
} }
} }
if (OCImage.direct_context == NULL) if (OCImage.direct_context==NULL)
{ {
OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext(); OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext();
} }
if (!OCImage.direct_context) if (!OCImage.direct_context)
{ {
fprintf(stderr, "ph_EnterFullScreen: Can't create direct context\n" ); fprintf(stderr, "ph_EnterFullScreen(): Can't create direct context !\n");
return 0;
} }
PdDirectStart(OCImage.direct_context); OCImage.oldDC=PdDirectStart(OCImage.direct_context);
currently_fullscreen = 1; currently_fullscreen = 1;
} }
...@@ -372,7 +287,8 @@ int ph_LeaveFullScreen(_THIS) ...@@ -372,7 +287,8 @@ int ph_LeaveFullScreen(_THIS)
{ {
PdDirectStop(OCImage.direct_context); PdDirectStop(OCImage.direct_context);
PdReleaseDirectContext(OCImage.direct_context); PdReleaseDirectContext(OCImage.direct_context);
PhDCSetCurrent(OCImage.oldDC);
currently_fullscreen=0; currently_fullscreen=0;
/* Restore old video mode */ /* Restore old video mode */
...@@ -384,7 +300,8 @@ int ph_LeaveFullScreen(_THIS) ...@@ -384,7 +300,8 @@ int ph_LeaveFullScreen(_THIS)
if (PgSetVideoMode(&mymode_settings) < 0) if (PgSetVideoMode(&mymode_settings) < 0)
{ {
fprintf(stderr,"error: PgSetVideoMode failed\n"); fprintf(stderr, "Ph_LeaveFullScreen(): PgSetVideoMode failed !\n");
return 0;
} }
} }
......
...@@ -36,9 +36,6 @@ static char rcsid = ...@@ -36,9 +36,6 @@ static char rcsid =
extern SDL_Rect **ph_ListModes(_THIS,SDL_PixelFormat *format, Uint32 flags); extern SDL_Rect **ph_ListModes(_THIS,SDL_PixelFormat *format, Uint32 flags);
extern void ph_FreeVideoModes(_THIS); extern void ph_FreeVideoModes(_THIS);
extern int ph_ResizeFullScreen(_THIS); extern int ph_ResizeFullScreen(_THIS);
extern void ph_WaitMapped(_THIS);
extern void ph_WaitUnmapped(_THIS);
extern void ph_QueueEnterFullScreen(_THIS);
extern int ph_EnterFullScreen(_THIS); extern int ph_EnterFullScreen(_THIS);
extern int ph_LeaveFullScreen(_THIS); extern int ph_LeaveFullScreen(_THIS);
extern int get_mode(int width, int height, int bpp); extern int get_mode(int width, int height, int bpp);
......
...@@ -35,18 +35,18 @@ static char rcsid = ...@@ -35,18 +35,18 @@ static char rcsid =
#include "SDL_cursor_c.h" #include "SDL_cursor_c.h"
#include "SDL_ph_mouse_c.h" #include "SDL_ph_mouse_c.h"
struct WMcursor { struct WMcursor
{
PhCursorDef_t *ph_cursor ; PhCursorDef_t *ph_cursor ;
}; };
void ph_FreeWMCursor(_THIS, WMcursor *cursor) void ph_FreeWMCursor(_THIS, WMcursor *cursor)
{ {
if (window != NULL) if (window != NULL)
{ {
SDL_Lock_EventThread(); SDL_Lock_EventThread();
if (PtSetResource( window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_INHERIT, 0 ) < 0) if (PtSetResource( window, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_INHERIT, 0) < 0)
{ {
/* TODO: output error msg */ /* TODO: output error msg */
} }
...@@ -60,63 +60,60 @@ void ph_FreeWMCursor(_THIS, WMcursor *cursor) ...@@ -60,63 +60,60 @@ void ph_FreeWMCursor(_THIS, WMcursor *cursor)
WMcursor *ph_CreateWMCursor(_THIS, WMcursor *ph_CreateWMCursor(_THIS,
Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
{ {
WMcursor* cursor; WMcursor* cursor;
int clen, i; int clen, i;
unsigned char bit, databit, maskbit; unsigned char bit, databit, maskbit;
/* Allocate and initialize the cursor memory */ /* Allocate and initialize the cursor memory */
if ((cursor = (WMcursor*)malloc(sizeof(WMcursor))) == NULL) if ((cursor = (WMcursor*)malloc(sizeof(WMcursor))) == NULL)
{ {
SDL_OutOfMemory(); SDL_OutOfMemory();
return(NULL); return(NULL);
} }
memset(cursor,0,sizeof(WMcursor)); memset(cursor,0,sizeof(WMcursor));
cursor->ph_cursor = (PhCursorDef_t *) malloc(sizeof(PhCursorDef_t) + 32*4*2); cursor->ph_cursor = (PhCursorDef_t *) malloc(sizeof(PhCursorDef_t) + 32*4*2);
if(cursor->ph_cursor == NULL) if (cursor->ph_cursor == NULL)
printf("cursor malloc failed\n"); printf("cursor malloc failed\n");
memset(cursor->ph_cursor,0,(sizeof(PhCursorDef_t) + 32*4*2)); memset(cursor->ph_cursor,0,(sizeof(PhCursorDef_t) + 32*4*2));
cursor->ph_cursor->hdr.type =Ph_RDATA_CURSOR; cursor->ph_cursor->hdr.type =Ph_RDATA_CURSOR;
cursor->ph_cursor->size1.x = (short)w; cursor->ph_cursor->size1.x = (short)w;
cursor->ph_cursor->size1.y = (short)h; cursor->ph_cursor->size1.y = (short)h;
cursor->ph_cursor->offset1.x = (short)hot_x; cursor->ph_cursor->offset1.x = (short)hot_x;
cursor->ph_cursor->offset1.y = (short)hot_y; cursor->ph_cursor->offset1.y = (short)hot_y;
cursor->ph_cursor->bytesperline1 = (char)w/8; cursor->ph_cursor->bytesperline1 = (char)w/8;
cursor->ph_cursor->color1 = Pg_WHITE; cursor->ph_cursor->color1 = Pg_WHITE;
cursor->ph_cursor->size2.x = (short)w; cursor->ph_cursor->size2.x = (short)w;
cursor->ph_cursor->size2.y = (short)h; cursor->ph_cursor->size2.y = (short)h;
cursor->ph_cursor->offset2.x = (short)hot_x; cursor->ph_cursor->offset2.x = (short)hot_x;
cursor->ph_cursor->offset2.y = (short)hot_y; cursor->ph_cursor->offset2.y = (short)hot_y;
cursor->ph_cursor->bytesperline2 = (char)w/8; cursor->ph_cursor->bytesperline2 = (char)w/8;
cursor->ph_cursor->color2 = Pg_BLACK; cursor->ph_cursor->color2 = Pg_BLACK;
clen = (w/8)*h; clen = (w/8)*h;
/* Copy the mask and the data to different /* Copy the mask and the data to different bitmap planes */
bitmap planes */ for (i=0; i<clen; ++i)
for ( i=0; i<clen; ++i ) {
{ for (bit = 0; bit < 8; bit++)
for ( bit = 0; bit < 8; bit++ ) {
{ databit = data[i] & (1 << bit);
databit = data[i] & (1 << bit); maskbit = mask[i] & (1 << bit);
maskbit = mask[i] & (1 << bit);
cursor->ph_cursor->images[i] |=
(databit == 0) ? maskbit : 0;
/* If the databit != 0, treat it as a black pixel and
* ignore the maskbit (can't do an inverted color) */
cursor->ph_cursor->images[i+clen] |= databit;
}
}
/* #bytes following the hdr struct */
cursor->ph_cursor->hdr.len =sizeof(PhCursorDef_t) + clen*2 - sizeof(PhRegionDataHdr_t);
return (cursor);
}
cursor->ph_cursor->images[i] |= (databit == 0) ? maskbit : 0;
/* If the databit != 0, treat it as a black pixel and
* ignore the maskbit (can't do an inverted color) */
cursor->ph_cursor->images[i+clen] |= databit;
}
}
/* #bytes following the hdr struct */
cursor->ph_cursor->hdr.len =sizeof(PhCursorDef_t) + clen*2 - sizeof(PhRegionDataHdr_t);
return (cursor);
}
PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor) PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor)
{ {
...@@ -125,47 +122,46 @@ PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor) ...@@ -125,47 +122,46 @@ PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor)
int ph_ShowWMCursor(_THIS, WMcursor *cursor) int ph_ShowWMCursor(_THIS, WMcursor *cursor)
{ {
PtArg_t args[3]; PtArg_t args[3];
int nargs = 0; int nargs = 0;
short cursor_is_defined = 0;
/* Don't do anything if the display is gone */
/* Don't do anything if the display is gone */ if (window == NULL)
if ( window == NULL ) { {
return(0); return (0);
} }
/* Set the photon cursor cursor, or blank if cursor is NULL */ /* looks like photon can't draw mouse cursor in direct mode */
if ( window ) { if ((this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
{
if ( cursor != NULL ) { return (0);
PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0 ); }
/* Could set next to any PgColor_t value */
PtSetArg( &args[1], Pt_ARG_CURSOR_COLOR,Ph_CURSOR_DEFAULT_COLOR , 0 ); /* Set the photon cursor cursor, or blank if cursor is NULL */
PtSetArg( &args[2], Pt_ARG_BITMAP_CURSOR, cursor->ph_cursor, (cursor->ph_cursor->hdr.len + sizeof(PhRegionDataHdr_t)) ); if (cursor!=NULL)
nargs = 3; {
cursor_is_defined = 1; PtSetArg(&args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_BITMAP, 0);
} /* Could set next to any PgColor_t value */
else /* Ph_CURSOR_NONE */ PtSetArg(&args[1], Pt_ARG_CURSOR_COLOR, Ph_CURSOR_DEFAULT_COLOR , 0);
{ PtSetArg(&args[2], Pt_ARG_BITMAP_CURSOR, cursor->ph_cursor, (cursor->ph_cursor->hdr.len + sizeof(PhRegionDataHdr_t)));
PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE,Ph_CURSOR_NONE, 0); nargs = 3;
nargs = 1; }
cursor_is_defined = 1; else /* Ph_CURSOR_NONE */
} {
if (cursor_is_defined) PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0);
{ nargs = 1;
SDL_Lock_EventThread(); }
if (PtSetResources( window, nargs, args ) < 0 ) SDL_Lock_EventThread();
{
return(0); if (PtSetResources(window, nargs, args) < 0 )
} {
return (0);
SDL_Unlock_EventThread(); }
}
else SDL_Unlock_EventThread();
return(0);
} return (1);
return(1);
} }
void ph_WarpWMCursor(_THIS, Uint16 x, Uint16 y) void ph_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
......
...@@ -56,6 +56,7 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -56,6 +56,7 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
static void ph_VideoQuit(_THIS); static void ph_VideoQuit(_THIS);
static void ph_DeleteDevice(SDL_VideoDevice *device); static void ph_DeleteDevice(SDL_VideoDevice *device);
static void ph_UpdateMouse(_THIS);
#ifdef HAVE_OPENGL #ifdef HAVE_OPENGL
int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags); int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags);
...@@ -90,7 +91,7 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) ...@@ -90,7 +91,7 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex)
malloc((sizeof *device->hidden)); malloc((sizeof *device->hidden));
device->gl_data = NULL; device->gl_data = NULL;
} }
if ( (device == NULL) || (device->hidden == NULL) ) { if ((device == NULL) || (device->hidden == NULL)) {
SDL_OutOfMemory(); SDL_OutOfMemory();
ph_DeleteDevice(device); ph_DeleteDevice(device);
return(0); return(0);
...@@ -106,9 +107,9 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) ...@@ -106,9 +107,9 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex)
device->ListModes = ph_ListModes; device->ListModes = ph_ListModes;
device->SetVideoMode = ph_SetVideoMode; device->SetVideoMode = ph_SetVideoMode;
device->ToggleFullScreen = ph_ToggleFullScreen; device->ToggleFullScreen = ph_ToggleFullScreen;
device->UpdateMouse = NULL; device->UpdateMouse = ph_UpdateMouse;
device->SetColors = ph_SetColors; device->SetColors = ph_SetColors;
device->UpdateRects = NULL; /* ph_ResizeImage */ device->UpdateRects = NULL; /* ph_SetupUpdateFunction */
device->VideoQuit = ph_VideoQuit; device->VideoQuit = ph_VideoQuit;
device->AllocHWSurface = ph_AllocHWSurface; device->AllocHWSurface = ph_AllocHWSurface;
device->CheckHWBlit = NULL; device->CheckHWBlit = NULL;
...@@ -173,6 +174,72 @@ static void ph_DeleteDevice(SDL_VideoDevice *device) ...@@ -173,6 +174,72 @@ static void ph_DeleteDevice(SDL_VideoDevice *device)
} }
} }
static PtWidget_t *ph_CreateWindow(_THIS)
{
PtWidget_t *widget;
widget = PtCreateWidget(PtWindow, NULL, 0, 0);
if (widget == NULL)
{
SDL_SetError("Couldn't create video window");
}
return widget;
}
static int ph_SetupWindow(_THIS, int w, int h, int flags)
{
PtArg_t args[32];
PhPoint_t pos = {0, 0};
PhDim_t dim = {w, h};
int nargs = 0;
PtSetArg(&args[nargs++], Pt_ARG_DIM, &dim, 0);
PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
if ((flags & SDL_RESIZABLE) == SDL_RESIZABLE)
{
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MAX);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX);
}
else
{
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE);
}
if (((flags & SDL_NOFRAME)==SDL_NOFRAME) || ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN))
{
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
}
else
{
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE |
Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN);
}
if (flags & SDL_FULLSCREEN)
{
PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_MAX);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISMAX |
Ph_WM_STATE_ISFOCUS | Ph_WM_STATE_ISALTKEY);
}
else
{
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISMAX | Ph_WM_STATE_ISALTKEY);
PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
}
PtSetResources(window, nargs, args);
PtRealizeWidget(window);
return 0;
}
static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
{ {
PgVideoModeInfo_t my_mode_info; PgVideoModeInfo_t my_mode_info;
...@@ -184,16 +251,22 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) ...@@ -184,16 +251,22 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
oglctx=NULL; oglctx=NULL;
#endif /* HAVE_OPENGL */ #endif /* HAVE_OPENGL */
captionflag=0;
old_video_mode=-1; old_video_mode=-1;
old_refresh_rate=-1; old_refresh_rate=-1;
if (NULL == (event = malloc(EVENT_SIZE))) if (NULL == (event = malloc(EVENT_SIZE)))
{ {
exit(EXIT_FAILURE); SDL_OutOfMemory();
return -1;
} }
memset(event, 0x00, EVENT_SIZE); memset(event, 0x00, EVENT_SIZE);
window = ph_CreateWindow(this);
if (window == NULL)
{
return -1;
}
/* Create the blank cursor */ /* Create the blank cursor */
SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
(int)BLANK_CWIDTH, (int)BLANK_CHEIGHT, (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
...@@ -201,7 +274,7 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) ...@@ -201,7 +274,7 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
if (SDL_BlankCursor == NULL) if (SDL_BlankCursor == NULL)
{ {
printf("ph_VideoInit(): could not create blank cursor !\n"); fprintf(stderr, "ph_VideoInit(): could not create blank cursor !\n");
} }
if (PgGetGraphicsHWCaps(&my_hwcaps) < 0) if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
...@@ -222,7 +295,8 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) ...@@ -222,7 +295,8 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
/* save current palette */ /* save current palette */
if (desktopbpp==8) if (desktopbpp==8)
{ {
PgGetPalette(ph_palette); PgGetPalette(savedpal);
PgGetPalette(syspalph);
} }
currently_fullscreen = 0; currently_fullscreen = 0;
...@@ -236,110 +310,46 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -236,110 +310,46 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags) int width, int height, int bpp, Uint32 flags)
{ {
PgDisplaySettings_t settings; PgDisplaySettings_t settings;
SDL_Color* colors;
int mode; int mode;
PtArg_t arg[32];
PhDim_t dim;
int rtnval; int rtnval;
int i; int i;
unsigned long *tempptr;
int pargc;
dim.w=width;
dim.h=height;
/* Lock the event thread, in multi-threading environments */ /* Lock the event thread, in multi-threading environments */
SDL_Lock_EventThread(); SDL_Lock_EventThread();
current->flags = flags; current->flags = flags;
/* create window if no OpenGL support selected */ ph_SetupWindow(this, width, height, flags);
if ((flags & SDL_OPENGL)!=SDL_OPENGL)
{
pargc=0;
// prevent using HWSURFACE in window mode if desktop bpp != chosen bpp
if ((flags & SDL_HWSURFACE) && (!(flags & SDL_FULLSCREEN)))
{
if (desktopbpp!=bpp)
{
fprintf(stderr, "ph_SetVideoMode(): SDL_HWSURFACE available only with chosen bpp equal desktop bpp !\n");
return NULL;
}
}
PtSetArg(&arg[pargc++], Pt_ARG_DIM, &dim, 0);
PtSetArg(&arg[pargc++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
/* enable window minimizing */
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
/* remove border and caption if no frame flag selected */
if ((flags & SDL_NOFRAME) == SDL_NOFRAME)
{
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_TITLE | Ph_WM_RENDER_BORDER);
}
else
{
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_TITLE | Ph_WM_RENDER_BORDER);
}
/* if window is not resizable then remove resize handles and maximize button */
if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
{
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX);
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
}
else
{
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX);
/* it is need to be Pt_FALSE to allow the application to process the resize callback */
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MAX);
}
if (window!=NULL)
{
PtUnrealizeWidget(window);
PtDestroyWidget(window);
window=NULL;
}
window=PtCreateWidget(PtWindow, NULL, pargc, arg);
PtRealizeWidget(window);
PtFlush();
}
#ifdef HAVE_OPENGL #ifdef HAVE_OPENGL
if (flags & SDL_OPENGL) if (current->flags & SDL_OPENGL)
{ {
/* ph_SetupOpenGLContext creates also window as need */ /* ph_SetupOpenGLContext creates also window as need */
if (ph_SetupOpenGLContext(this, width, height, bpp, flags)==0) if (ph_SetupOpenGLContext(this, width, height, bpp, flags)==0)
{ {
/* setup OGL update function ... ugly method */ ph_SetupUpdateFunction(this, current, flags);
ph_ResizeImage(this, current, flags);
} }
else else
{ {
/* if context creation fail, report no OpenGL to high level */ /* if context creation fail, report no OpenGL to high level */
current->flags=(flags & (~SDL_OPENGL)); current->flags &= ~SDL_OPENGL;
} }
#else #else
if (flags & SDL_OPENGL) /* if no built-in OpenGL support */ if (current->flags & SDL_OPENGL) /* if no built-in OpenGL support */
{ {
fprintf(stderr, "ph_SetVideoMode(): no OpenGL support, try to recompile library.\n"); fprintf(stderr, "ph_SetVideoMode(): no OpenGL support, try to recompile library.\n");
current->flags=(flags & (~SDL_OPENGL)); current->flags &= ~SDL_OPENGL;
return NULL; return NULL;
#endif /* HAVE_OPENGL */ #endif /* HAVE_OPENGL */
} }
else else
{ {
/* Initialize the window */ /* Initialize the window */
if (flags & SDL_FULLSCREEN) /* Direct Context , assume SDL_HWSURFACE also set */ if (current->flags & SDL_FULLSCREEN) /* Direct Context , assume SDL_HWSURFACE also set */
{ {
/* Get the video mode and set it */ /* Get the video mode and set it */
if (flags & SDL_ANYFORMAT) if (current->flags & SDL_ANYFORMAT)
{ {
if ((mode = get_mode_any_format(width, height, bpp)) == 0) if ((mode = get_mode_any_format(width, height, bpp)) == 0)
{ {
...@@ -376,7 +386,8 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -376,7 +386,8 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
fprintf(stderr,"ph_SetVideoMode(): PgSetVideoMode failed !\n"); fprintf(stderr,"ph_SetVideoMode(): PgSetVideoMode failed !\n");
} }
current->flags = (flags & (~SDL_RESIZABLE)); /* no resize for Direct Context */ current->flags &= ~SDL_RESIZABLE; /* no resize for Direct Context */
current->flags |= SDL_HWSURFACE;
/* Begin direct mode */ /* Begin direct mode */
ph_EnterFullScreen(this); ph_EnterFullScreen(this);
...@@ -385,10 +396,10 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -385,10 +396,10 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
else else
{ {
/* Use offscreen memory iff SDL_HWSURFACE flag is set */ /* Use offscreen memory iff SDL_HWSURFACE flag is set */
if (flags & SDL_HWSURFACE) if (current->flags & SDL_HWSURFACE)
{ {
/* no stretch blit in offscreen context */ /* no stretch blit in offscreen context */
current->flags = (flags & (~SDL_RESIZABLE)); current->flags &= ~SDL_RESIZABLE;
} }
/* using palette emulation code in window mode */ /* using palette emulation code in window mode */
...@@ -402,55 +413,48 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -402,55 +413,48 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
{ {
desktoppal=SDLPH_PAL_SYSTEM; desktoppal=SDLPH_PAL_SYSTEM;
} }
}
else
{
desktoppal=SDLPH_PAL_NONE;
}
}
/* If we are setting video to use the palette make sure we have allocated memory for it */ /* fill the palette */
if (bpp==8) PgGetPalette(savedpal);
{ PgGetPalette(syspalph);
current->format->palette = malloc(sizeof(SDL_Palette));
memset(current->format->palette, 0, sizeof(SDL_Palette)); current->format->palette = calloc(1, sizeof(SDL_Palette));
current->format->palette->ncolors = 256; current->format->palette->ncolors = _Pg_MAX_PALETTE;
current->format->palette->colors = (SDL_Color *)malloc(256 *sizeof(SDL_Color)); current->format->palette->colors = (SDL_Color *)calloc(_Pg_MAX_PALETTE, sizeof(SDL_Color));
/* fill the palette */
rtnval = PgGetPalette(ph_palette);
tempptr = (unsigned long *)current->format->palette->colors; colors = current->format->palette->colors;
for(i=0; i<256; i++) for(i=0; i<256; i++)
{
colors[i].r = PgRedValue(syspalph[i]);
colors[i].g = PgGreenValue(syspalph[i]);
colors[i].b = PgBlueValue(syspalph[i]);
}
}
else
{ {
*tempptr = (((unsigned long)ph_palette[i]) << 8); desktoppal=SDLPH_PAL_NONE;
tempptr++;
} }
} }
} }
current->w = width; current->w = width;
current->h = height; current->h = height;
/* These values can be overridden in ph_SetupUpdateFunction() */
current->format->BitsPerPixel = bpp; current->format->BitsPerPixel = bpp;
current->format->BytesPerPixel = (bpp+7)/8; current->format->BytesPerPixel = (bpp+7)/8;
current->pitch = SDL_CalculatePitch(current); current->pitch = SDL_CalculatePitch(current);
/* Must call at least once it setup image planes */ /* Must call at least once it setup image planes */
rtnval = ph_ResizeImage(this, current, flags); rtnval = ph_SetupUpdateFunction(this, current, current->flags);
if (rtnval==-1) if (rtnval==-1)
{ {
fprintf(stderr,"ph_SetVideoMode(): ph_ResizeImage failed !\n"); fprintf(stderr,"ph_SetVideoMode(): ph_SetupUpdateFunction failed !\n");
return NULL; return NULL;
} }
/* delayed set caption call */
if (captionflag)
{
ph_SetCaption(this, this->wm_title, NULL);
}
/* finish window drawing */ /* finish window drawing */
PtFlush(); PtFlush();
...@@ -495,12 +499,6 @@ static void ph_VideoQuit(_THIS) ...@@ -495,12 +499,6 @@ static void ph_VideoQuit(_THIS)
PtDestroyWidget(window); PtDestroyWidget(window);
window=NULL; window=NULL;
} }
/* restore palette */
if (desktoppal!=SDLPH_PAL_NONE)
{
PgSetPalette(ph_palette, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
}
#ifdef HAVE_OPENGL #ifdef HAVE_OPENGL
if (oglctx) if (oglctx)
...@@ -510,13 +508,30 @@ static void ph_VideoQuit(_THIS) ...@@ -510,13 +508,30 @@ static void ph_VideoQuit(_THIS)
oglctx=NULL; oglctx=NULL;
} }
#endif /* HAVE_OPENGL */ #endif /* HAVE_OPENGL */
/* restore palette */
if (desktoppal!=SDLPH_PAL_NONE)
{
PgSetPalette(savedpal, 1, 0, _Pg_MAX_PALETTE, Pg_PALSET_HARD | Pg_PALSET_FORCE_EXPOSE, 0);
/* pass -1, to force release palette */
PgSetPalette(savedpal, 1, 0, -1, Pg_PALSET_HARD | Pg_PALSET_FORCE_EXPOSE, 0);
}
if (event!=NULL)
{
free(event);
event=NULL;
}
} }
static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{ {
int i; int i;
PhPoint_t point={0, 0}; SDL_Rect updaterect;
PgColor_t syspalph[_Pg_MAX_PALETTE];
updaterect.x = updaterect.y = 0;
updaterect.w = this->screen->w;
updaterect.h = this->screen->h;
/* palette emulation code, using palette of the PhImage_t struct */ /* palette emulation code, using palette of the PhImage_t struct */
if (desktoppal==SDLPH_PAL_EMULATE) if (desktoppal==SDLPH_PAL_EMULATE)
...@@ -525,14 +540,11 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ...@@ -525,14 +540,11 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{ {
for (i=firstcolor; i<firstcolor+ncolors; i++) for (i=firstcolor; i<firstcolor+ncolors; i++)
{ {
SDL_Image->palette[i] = 0x00000000UL; syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
SDL_Image->palette[i] |= colors[i-firstcolor].r<<16; SDL_Image->palette[i] = syspalph[i];
SDL_Image->palette[i] |= colors[i-firstcolor].g<<8;
SDL_Image->palette[i] |= colors[i-firstcolor].b;
} }
/* image needs to be redrawn */
/* image needs to be redrawed, very slow method */ this->UpdateRects(this, 1, &updaterect);
PgDrawPhImage(&point, SDL_Image, 0);
} }
} }
else else
...@@ -541,26 +553,20 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ...@@ -541,26 +553,20 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{ {
for (i=firstcolor; i<firstcolor+ncolors; i++) for (i=firstcolor; i<firstcolor+ncolors; i++)
{ {
syspalph[i] = 0x00000000UL; syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
syspalph[i] |= colors[i-firstcolor].r<<16;
syspalph[i] |= colors[i-firstcolor].g<<8;
syspalph[i] |= colors[i-firstcolor].b;
} }
if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
{ {
/* window mode must use soft palette */ /* window mode must use soft palette */
PgSetPalette((PgColor_t*)&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_SOFT, 0); PgSetPalette(&syspalph[firstcolor], 1, firstcolor, ncolors, Pg_PALSET_SOFT, 0);
/* image needs to be redrawed, very slow method */ /* image needs to be redrawn */
if (SDL_Image) this->UpdateRects(this, 1, &updaterect);
{
PgDrawPhImage(&point, SDL_Image, 0);
}
} }
else else
{ {
/* fullscreen mode must use hardware palette */ /* fullscreen mode must use hardware palette */
PgSetPalette((PgColor_t*)&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0); PgSetPalette(&syspalph[firstcolor], 1, firstcolor, ncolors, Pg_PALSET_HARDLOCKED, 0);
} }
} }
else else
...@@ -576,11 +582,9 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ...@@ -576,11 +582,9 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags) int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags)
{ {
PtArg_t args[8];
PhDim_t dim; PhDim_t dim;
uint64_t OGLAttrib[PH_OGL_MAX_ATTRIBS]; uint64_t OGLAttrib[PH_OGL_MAX_ATTRIBS];
int OGLargc; int OGLargc;
int pargc;
dim.w=width; dim.w=width;
dim.h=height; dim.h=height;
...@@ -630,51 +634,6 @@ int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags) ...@@ -630,51 +634,6 @@ int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags)
PhDCSetCurrent(oglctx); PhDCSetCurrent(oglctx);
pargc=0;
PtSetArg(&args[pargc++], Pt_ARG_DIM, &dim, 0);
PtSetArg(&args[pargc++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
PtSetArg(&args[pargc++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
if (flags & SDL_FULLSCREEN)
{
PhPoint_t pos;
pos.x=0;
pos.y=0;
PtSetArg(&args[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, ~0);
PtSetArg(&args[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_CLOSE | Ph_WM_TOFRONT | Ph_WM_CONSWITCH);
PtSetArg(&args[pargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISFOCUS);
PtSetArg(&args[pargc++], Pt_ARG_POS, &pos, 0);
}
else
{
/* remove border and caption if no frame flag selected */
if ((flags & SDL_NOFRAME) == SDL_NOFRAME)
{
PtSetArg(&args[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, 0, Ph_WM_RENDER_TITLE | Ph_WM_RENDER_BORDER);
}
else
{
/* if window is not resizable then remove resize handles */
if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
{
PtSetArg(&args[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, 0, Ph_WM_RENDER_RESIZE);
}
}
}
if (window!=NULL)
{
PtUnrealizeWidget(window);
PtDestroyWidget(window);
window=NULL;
}
window=PtCreateWidget(PtWindow, NULL, pargc, args);
PtRealizeWidget(window);
/* disable mouse for fullscreen */ /* disable mouse for fullscreen */
if (flags & SDL_FULLSCREEN) if (flags & SDL_FULLSCREEN)
{ {
...@@ -717,3 +676,30 @@ int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) ...@@ -717,3 +676,30 @@ int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
} }
#endif /* HAVE_OPENGL */ #endif /* HAVE_OPENGL */
static void ph_UpdateMouse(_THIS)
{
PhCursorInfo_t phcursor;
short abs_x;
short abs_y;
/* Lock the event thread, in multi-threading environments */
SDL_Lock_EventThread();
/* synchronizing photon mouse cursor position and SDL mouse position, if cursor appears over window. */
PtGetAbsPosition(window, &abs_x, &abs_y);
PhQueryCursor(PhInputGroup(NULL), &phcursor);
if (((phcursor.pos.x >= abs_x) && (phcursor.pos.x <= abs_x + this->screen->w)) &&
((phcursor.pos.y >= abs_y) && (phcursor.pos.y <= abs_y + this->screen->h)))
{
SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
SDL_PrivateMouseMotion(0, 0, phcursor.pos.x-abs_x, phcursor.pos.y-abs_y);
}
else
{
SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
}
/* Unlock the event thread, in multi-threading environments */
SDL_Unlock_EventThread();
}
...@@ -44,18 +44,16 @@ ...@@ -44,18 +44,16 @@
#define SDLPH_PAL_SYSTEM 0x00000002L #define SDLPH_PAL_SYSTEM 0x00000002L
typedef union vidptr{ typedef union vidptr{
uint8_t *volatile ptr8; uint8_t* volatile ptr8;
uint16_t *volatile ptr16; uint16_t* volatile ptr16;
uint32_t *volatile ptr32; uint32_t* volatile ptr32;
} VidPtr_t; } VidPtr_t;
typedef struct { typedef struct {
unsigned char *Y; unsigned char* Y;
unsigned char *V; unsigned char* V;
unsigned char *U; unsigned char* U;
}FRAMEDATA; } FRAMEDATA;
#define EVENT_SIZE sizeof( PhEvent_t ) + 1000
/* Private display data */ /* Private display data */
struct SDL_PrivateVideoData { struct SDL_PrivateVideoData {
...@@ -65,15 +63,17 @@ struct SDL_PrivateVideoData { ...@@ -65,15 +63,17 @@ struct SDL_PrivateVideoData {
#ifdef HAVE_OPENGL #ifdef HAVE_OPENGL
PdOpenGLContext_t* OGLContext; /* OpenGL context */ PdOpenGLContext_t* OGLContext; /* OpenGL context */
#endif /* HAVE_OPENGL */ #endif /* HAVE_OPENGL */
PgColor_t ph_palette[_Pg_MAX_PALETTE]; PgColor_t savedpal[_Pg_MAX_PALETTE];
PgColor_t syspalph[_Pg_MAX_PALETTE];
struct { struct {
PdDirectContext_t *direct_context; PdDirectContext_t* direct_context;
PdOffscreenContext_t *offscreen_context; PdOffscreenContext_t* offscreen_context;
PhDrawContext_t* oldDC;
VidPtr_t dc_ptr; VidPtr_t dc_ptr;
FRAMEDATA *CurrentFrameData; unsigned char* CurrentFrameData;
FRAMEDATA *FrameData0; unsigned char* FrameData0;
FRAMEDATA *FrameData1; unsigned char* FrameData1;
int current; int current;
long flags; long flags;
} ocimage; } ocimage;
...@@ -82,40 +82,15 @@ struct SDL_PrivateVideoData { ...@@ -82,40 +82,15 @@ struct SDL_PrivateVideoData {
int old_video_mode; /* Stored mode before fullscreen switch */ int old_video_mode; /* Stored mode before fullscreen switch */
int old_refresh_rate; /* Stored refresh rate befor fullscreen switch */ int old_refresh_rate; /* Stored refresh rate befor fullscreen switch */
/* The current width and height of the fullscreen mode */
int current_w;
int current_h;
/* Support for internal mouse warping */
struct {
int x;
int y;
} mouse_last;
struct {
int numerator;
int denominator;
int threshold;
} mouse_accel;
int mouse_relative; int mouse_relative;
WMcursor* BlankCursor; WMcursor* BlankCursor;
int depth; /* current visual depth (not bpp) */ int depth; /* current visual depth (not bpp) */
int desktopbpp; /* bpp of desktop at the moment of start */ int desktopbpp; /* bpp of desktop at the moment of start */
int desktoppal; /* palette mode emulation or system */ int desktoppal; /* palette mode emulation or system */
int captionflag; /* caption setting flag */
int use_vidmode;
int currently_fullscreen; int currently_fullscreen;
/* Automatic mode switching support (entering/leaving fullscreen) */
Uint32 switch_waiting;
Uint32 switch_time;
/* Prevent too many XSync() calls */
int blit_queued;
PhEvent_t* event; PhEvent_t* event;
}; };
...@@ -129,23 +104,13 @@ struct SDL_PrivateVideoData { ...@@ -129,23 +104,13 @@ struct SDL_PrivateVideoData {
#define graphics_card_caps (this->hidden->graphics_card_caps) #define graphics_card_caps (this->hidden->graphics_card_caps)
#define desktopbpp (this->hidden->desktopbpp) #define desktopbpp (this->hidden->desktopbpp)
#define desktoppal (this->hidden->desktoppal) #define desktoppal (this->hidden->desktoppal)
#define ph_palette (this->hidden->ph_palette) #define savedpal (this->hidden->savedpal)
#define syspalph (this->hidden->syspalph)
/* Old variable names */ /* Old variable names */
#define current_w (this->hidden->current_w)
#define current_h (this->hidden->current_h)
#define mouse_last (this->hidden->mouse_last)
#define mouse_accel (this->hidden->mouse_accel)
#define mouse_relative (this->hidden->mouse_relative) #define mouse_relative (this->hidden->mouse_relative)
#define saved_mode (this->hidden->saved_mode)
#define saved_view (this->hidden->saved_view)
#define use_vidmode (this->hidden->use_vidmode)
#define currently_fullscreen (this->hidden->currently_fullscreen) #define currently_fullscreen (this->hidden->currently_fullscreen)
#define switch_waiting (this->hidden->switch_waiting)
#define switch_time (this->hidden->switch_time)
#define blit_queued (this->hidden->blit_queued)
#define event (this->hidden->event) #define event (this->hidden->event)
#define SDL_BlankCursor (this->hidden->BlankCursor) #define SDL_BlankCursor (this->hidden->BlankCursor)
#define captionflag (this->hidden->captionflag)
#endif /* _SDL_x11video_h */ #endif /* _SDL_x11video_h */
...@@ -56,15 +56,11 @@ void ph_SetCaption(_THIS, const char *title, const char *icon) ...@@ -56,15 +56,11 @@ void ph_SetCaption(_THIS, const char *title, const char *icon)
{ {
SDL_Lock_EventThread(); SDL_Lock_EventThread();
/* check for set caption call before window init */ /* sanity check for set caption call before window init */
if (window!=NULL) if (window!=NULL)
{ {
PtSetResource(window, Pt_ARG_WINDOW_TITLE, title, 0); PtSetResource(window, Pt_ARG_WINDOW_TITLE, title, 0);
} }
else
{
captionflag=1;
}
SDL_Unlock_EventThread(); SDL_Unlock_EventThread();
} }
...@@ -88,36 +84,35 @@ int ph_IconifyWindow(_THIS) ...@@ -88,36 +84,35 @@ int ph_IconifyWindow(_THIS)
SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode) SDL_GrabMode ph_GrabInputNoLock(_THIS, SDL_GrabMode mode)
{ {
short abs_x, abs_y;
if( mode == SDL_GRAB_OFF )
{
PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISALTKEY);
}
else
{
PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY);
PtGetAbsPosition(window, &abs_x, &abs_y);
PhMoveCursorAbs(PhInputGroup(NULL), abs_x + SDL_VideoSurface->w/2, abs_y + SDL_VideoSurface->h/2);
}
SDL_Unlock_EventThread();
return(mode); return(mode);
} }
SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode) SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode)
{ {
short abs_x, abs_y; SDL_Lock_EventThread();
mode = ph_GrabInputNoLock(this, mode);
SDL_Lock_EventThread(); SDL_Unlock_EventThread();
/* mode = ph_GrabInputNoLock(this, mode);*/
return(mode);
if( mode == SDL_GRAB_OFF )
{
PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_FALSE,
Ph_WM_STATE_ISALTKEY );
}
else
{
PtSetResource(window, Pt_ARG_WINDOW_STATE, Pt_TRUE,
Ph_WM_STATE_ISALTKEY );
PtGetAbsPosition( window, &abs_x, &abs_y );
PhMoveCursorAbs( PhInputGroup( NULL ),
abs_x + SDL_VideoSurface->w/2,
abs_y + SDL_VideoSurface->h/2 );
}
SDL_Unlock_EventThread();
return(mode);
} }
int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info) int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info)
{ {
if (info->version.major <= SDL_MAJOR_VERSION) if (info->version.major <= SDL_MAJOR_VERSION)
......
...@@ -29,11 +29,6 @@ static char rcsid = ...@@ -29,11 +29,6 @@ static char rcsid =
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifndef bool
#define bool char
#define TRUE 1
#define FALSE 0
#endif
#include <errno.h> #include <errno.h>
#include <Ph.h> #include <Ph.h>
...@@ -44,606 +39,426 @@ static char rcsid = ...@@ -44,606 +39,426 @@ static char rcsid =
#include "SDL_phyuv_c.h" #include "SDL_phyuv_c.h"
#include "SDL_yuvfuncs.h" #include "SDL_yuvfuncs.h"
#if 0 //just for reference #define OVERLAY_STATE_UNINIT 0
/* YUV data formats FourCC Layout H sample (YUV) V sample (YUV) BPP */
#define Pg_VIDEO_FORMAT_IYU1 0x31555949 /* U2Y2Y2V2Y2Y2 144 111 12 */
#define Pg_VIDEO_FORMAT_IYU2 0x32555949 /* U4Y4V4U4Y4V4 111 111 24 */
#define Pg_VIDEO_FORMAT_UYVY 0x59565955 /* U8Y8V8Y8 122 111 16 */
#define Pg_VIDEO_FORMAT_YUY2 0x32595559 /* Y8U8Y8V8 122 111 16 */
#define Pg_VIDEO_FORMAT_YVYU 0x55595659 /* Y8V8Y8U8 122 111 16 */
#define Pg_VIDEO_FORMAT_V422 0x56343232 /* V8Y8U8Y8 122 111 16 */
#define Pg_VIDEO_FORMAT_CLJR 0x524a4c43 /* V6U6Y5Y5Y5Y5 133 111 8 */
#define Pg_VIDEO_FORMAT_YVU9 0x39555659 /* Planar YVU 144 144 9 */
#define Pg_VIDEO_FORMAT_YV12 0x32315659 /* Planar YUV 122 122 12 */
/* There seems to be no FourCC that matches this */
#define Pg_VIDEO_FORMAT_YUV420 0x00000100 /* Planar YUV 122 111 16 */
/* These formats are the same as YV12, except the U and V planes do not have to contiguously follow the Y plane */
/* but they're all the same to us, since we always have 3 plane pointers */
#define Pg_VIDEO_FORMAT_CLPL Pg_VIDEO_FORMAT_YV12 /* Cirrus Logic Planar format */
#define Pg_VIDEO_FORMAT_VBPL Pg_VIDEO_FORMAT_YV12 /* VooDoo Banshee planar format */
#define SDL_YV12_OVERLAY 0x32315659 /* Planar mode: Y + V + U */
#define SDL_IYUV_OVERLAY 0x56555949 /* Planar mode: Y + U + V */
#define SDL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 */
#define SDL_UYVY_OVERLAY 0x59565955 /* Packed mode: U0+Y0+V0+Y1 */
#define SDL_YVYU_OVERLAY 0x55595659 /* Packed mode: Y0+V0+Y1+U0 */
#endif
#define OVERLAY_STATE_UNINIT 0
#define OVERLAY_STATE_ACTIVE 1 #define OVERLAY_STATE_ACTIVE 1
/* The functions used to manipulate software video overlays */ /* The functions used to manipulate software video overlays */
static struct private_yuvhwfuncs ph_yuvfuncs = { static struct private_yuvhwfuncs ph_yuvfuncs = {
ph_LockYUVOverlay, ph_LockYUVOverlay,
ph_UnlockYUVOverlay, ph_UnlockYUVOverlay,
ph_DisplayYUVOverlay, ph_DisplayYUVOverlay,
ph_FreeYUVOverlay ph_FreeYUVOverlay
}; };
typedef struct {
int id;
int width, height;
int data_size; /* bytes */
int num_planes;
int *pitches; /* bytes */
int *offsets; /* bytes */
char *data;
void *obdata;
} XvImage;
struct private_yuvhwdata { struct private_yuvhwdata {
XvImage *image; FRAMEDATA* CurrentFrameData;
FRAMEDATA *CurrentFrameData; FRAMEDATA* FrameData0;
FRAMEDATA *FrameData0; FRAMEDATA* FrameData1;
FRAMEDATA *FrameData1; PgScalerProps_t props;
PgScalerProps_t props; PgScalerCaps_t caps;
PgScalerCaps_t caps; PgVideoChannel_t* channel;
PgVideoChannel_t *channel; PhArea_t CurrentWindow;
SDL_Rect CurrentWindow; long format;
long format; int planar;
int screen_width; int scaler_on;
int screen_height ; int current;
int screen_bpp ; //2 long YStride;
bool planar; long VStride;
bool scaler_on ; long UStride;
int current; int ischromakey;
long YStride; long chromakey;
long VStride; unsigned long State;
long UStride; long flags;
long chromakey; int locked;
unsigned long State;
long flags;
}; };
extern PgVideoChannel_t * PgCreateVideoChannel(unsigned type, unsigned flags); int grab_ptrs2(PgVideoChannel_t* channel, FRAMEDATA* Frame0, FRAMEDATA* Frame1 )
extern int PgGetScalerCapabilities( PgVideoChannel_t *channel, int format_index, PgScalerCaps_t *vcaps );
extern int PgConfigScalerChannel(PgVideoChannel_t *channel, PgScalerProps_t *props);
extern void PgDestroyVideoChannel(PgVideoChannel_t *channel);
extern PgColor_t PgGetOverlayChromaColor(void);
void
grab_ptrs2(PgVideoChannel_t *channel, FRAMEDATA *Frame0, FRAMEDATA *Frame1 )
{ {
int planes = 0;
/* Buffers have moved; re-obtain the pointers */
Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1);
Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2);
Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1);
Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2);
Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1);
Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2);
if (Frame0->Y)
planes++;
if (Frame0->U)
planes++;
/* Buffers have moved; re-obtain the pointers */ if (Frame0->V)
Frame0->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane1); planes++;
Frame1->Y = (unsigned char *)PdGetOffscreenContextPtr(channel->yplane2);
Frame0->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane1);
Frame1->U = (unsigned char *)PdGetOffscreenContextPtr(channel->uplane2);
Frame0->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane1);
Frame1->V = (unsigned char *)PdGetOffscreenContextPtr(channel->vplane2);
return planes;
} }
SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
{ {
SDL_Overlay *overlay; SDL_Overlay *overlay;
struct private_yuvhwdata *hwdata; struct private_yuvhwdata *hwdata;
int xv_port; int xv_port;
int rtncode; int rtncode;
// PhRect_t rect; int planes;
// PhSysInfo_t info; int i=0;
// PhRegion_t region; PhPoint_t pos;
// short x, y;
PtArg_t argt; /* Create the overlay structure */
int i =0; overlay = calloc(1, sizeof(SDL_Overlay));
// bool bCont = TRUE;
int Priority[20]; if (overlay == NULL) {
int Type[20]; SDL_OutOfMemory();
int entries, select, highest; return (NULL);
}
PhDCSetCurrent(0); //Need to set draw context to window esp. if we we in Offscreeen mode
/* Fill in the basic members */
/* Create the overlay structure */ overlay->format = format;
overlay = (SDL_Overlay *)malloc(sizeof(SDL_Overlay)); overlay->w = width;
memset(overlay, 0x00, sizeof(SDL_Overlay)); overlay->h = height;
if ( overlay == NULL ) {
SDL_OutOfMemory();
return(NULL);
}
memset(overlay, 0, (sizeof *overlay));
/* Fill in the basic members */
overlay->format = format;
overlay->w = width;
overlay->h = height;
/* Set up the YUV surface function structure */
overlay->hwfuncs = &ph_yuvfuncs;
/* Create the pixel data and lookup tables */
hwdata = (struct private_yuvhwdata *)malloc(sizeof(struct private_yuvhwdata));
memset(hwdata, 0x00, sizeof(struct private_yuvhwdata));
overlay->hwdata = hwdata;
if ( hwdata == NULL ) {
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return(NULL);
}
/* Set up the YUV surface function structure */
overlay->hwfuncs = &ph_yuvfuncs;
/* Create the pixel data and lookup tables */
hwdata = calloc(1, sizeof(struct private_yuvhwdata));
overlay->hwdata = hwdata;
if (hwdata == NULL) {
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return(NULL);
}
PhDCSetCurrent(0);
if (overlay->hwdata->channel == NULL) if (overlay->hwdata->channel == NULL)
{ {
if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL) if ((overlay->hwdata->channel = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL)
{ {
SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror( errno )); SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno));
free(overlay->hwdata); SDL_FreeYUVOverlay(overlay);
free(overlay);
return (NULL); return(NULL);
} }
} }
overlay->hwdata->CurrentWindow.x = 0; PtGetAbsPosition(window, &pos.x, &pos.y);
overlay->hwdata->CurrentWindow.y = 0; overlay->hwdata->CurrentWindow.pos.x = pos.x;
overlay->hwdata->CurrentWindow.w = 320; overlay->hwdata->CurrentWindow.pos.y = pos.y;
overlay->hwdata->CurrentWindow.h = 240; overlay->hwdata->CurrentWindow.size.w = width;
overlay->hwdata->CurrentWindow.size.h = height;
overlay->hwdata->State = OVERLAY_STATE_UNINIT; overlay->hwdata->State = OVERLAY_STATE_UNINIT;
overlay->hwdata->FrameData0 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
overlay->hwdata->screen_bpp = 2; overlay->hwdata->FrameData1 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA));
overlay->hwdata->scaler_on = FALSE;
overlay->hwdata->screen_width = 1024;
overlay->hwdata->screen_height = 768;
overlay->hwdata->FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
overlay->hwdata->FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
memset(overlay->hwdata->FrameData0, 0x00, (size_t)(sizeof(FRAMEDATA)));
memset(overlay->hwdata->FrameData1, 0x00, (size_t)(sizeof(FRAMEDATA)));
overlay->hwdata->caps.size = sizeof(overlay->hwdata->caps);
//Note you really don't need to do this for SDL as you are given a format, but this is a good example
xv_port = -1; xv_port = -1;
i=0; i=0;
overlay->hwdata->ischromakey=0;
do {
memset(&overlay->hwdata->caps, 0x00, sizeof(PgScalerCaps_t));
overlay->hwdata->caps.size = sizeof(PgScalerCaps_t);
rtncode = PgGetScalerCapabilities(overlay->hwdata->channel, i, &overlay->hwdata->caps);
if (rtncode==0)
{
if (overlay->hwdata->caps.format==format)
{
if ((overlay->hwdata->caps.flags & Pg_SCALER_CAP_DST_CHROMA_KEY) == Pg_SCALER_CAP_DST_CHROMA_KEY)
{
overlay->hwdata->ischromakey=1;
}
xv_port=1;
break;
}
}
else
{
break;
}
i++;
} while(1);
while(PgGetScalerCapabilities(overlay->hwdata->channel, i++, &(overlay->hwdata->caps)) == 0)
{
if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YV12) //in SDL
{
Priority[i-1] = 0;
Type[i-1] = Pg_VIDEO_FORMAT_YV12;
if(format == Pg_VIDEO_FORMAT_YV12)
{
overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YV12;
xv_port = 1; //supported
Priority[i-1] = 100; //force selected
}
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YVU9) //in SDL
{
Priority[i-1] = 0;
Type[i-1] = Pg_VIDEO_FORMAT_YVU9;
if(format == Pg_VIDEO_FORMAT_YVU9)
{
overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YVU9;
xv_port = 1; //supported
Priority[i-1] = 100; //force selected
}
}
#if 0 //this part of SDL is YUV specific
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB555)
{
Priority[i-1] = 3;
Type[i-1] = Pg_VIDEO_FORMAT_RGB555;
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB565)
{
Priority[i-1] = 2;
Type[i-1] = Pg_VIDEO_FORMAT_RGB565;
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_RGB8888)
{
Priority[i-1] = 1;
Type[i-1] = Pg_VIDEO_FORMAT_RGB8888;
}
#endif
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_IYU1)
{
Priority[i-1] = 0;
Type[i-1] = Pg_VIDEO_FORMAT_IYU1;
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_IYU2)
{
Priority[i-1] = 0;
Type[i-1] = Pg_VIDEO_FORMAT_IYU2;
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_UYVY) //in SDL
{
Priority[i-1] = 7;
Type[i-1] = Pg_VIDEO_FORMAT_UYVY;
if(format == Pg_VIDEO_FORMAT_UYVY)
{
overlay->hwdata->props.format = Pg_VIDEO_FORMAT_UYVY;
xv_port = 1; //supported
Priority[i-1] = 100; //force selected
}
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YUY2) //in SDL
{
Priority[i-1] = 8;
Type[i-1] = Pg_VIDEO_FORMAT_YUY2;
if(format == Pg_VIDEO_FORMAT_YUY2)
{
overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YUY2;
xv_port = 1; //supported
Priority[i-1] = 100; //force selected
}
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_YVYU) //in SDL
{
Priority[i-1] = 4;
Type[i-1] = Pg_VIDEO_FORMAT_YVYU;
if(format == Pg_VIDEO_FORMAT_YVYU)
{
overlay->hwdata->props.format = Pg_VIDEO_FORMAT_YVYU;
xv_port = 1; //supported
Priority[i-1] = 100; //force selected
}
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_V422)
{
Priority[i-1] = 5;
Type[i-1] = Pg_VIDEO_FORMAT_V422;
}
else if(overlay->hwdata->caps.format == Pg_VIDEO_FORMAT_CLJR)
{
Priority[i-1] = 6;
Type[i-1] = Pg_VIDEO_FORMAT_CLJR;
}
else
{
Priority[i-1] = 0;
}
overlay->hwdata->caps.size = sizeof(overlay->hwdata->caps);
}
if ( xv_port == -1 )
{
SDL_SetError("No available video ports for requested format");
return(NULL);
}
//Pick the highest priority format
entries = i -2;
highest = Priority[0]; //make first entry top at begining
select = 0;
for (i = 1; i < entries; i++)
{
if(Priority[i] > highest)
{
highest = Priority[i];
select = i;
}
}
if (xv_port == -1)
{
SDL_SetError("No available video ports for requested format\n");
SDL_FreeYUVOverlay(overlay);
return(NULL);
}
overlay->hwdata->format = format;
overlay->hwdata->caps.size = sizeof (overlay->hwdata->caps ); overlay->hwdata->props.format = format;
PgGetScalerCapabilities(overlay->hwdata->channel, select, &(overlay->hwdata->caps)); overlay->hwdata->props.size = sizeof(PgScalerProps_t);
overlay->hwdata->props.format = overlay->hwdata->caps.format ;
overlay->hwdata->format = overlay->hwdata->props.format; //to make easier for apps to use
overlay->hwdata->props.size = sizeof (overlay->hwdata->props);
overlay->hwdata->props.src_dim.w = width; overlay->hwdata->props.src_dim.w = width;
overlay->hwdata->props.src_dim.h = height; overlay->hwdata->props.src_dim.h = height;
overlay->hwdata->chromakey = PgGetOverlayChromaColor(); /* Don't use chromakey for now, blitting a surface will cover the window,
* and therefore the chroma. */
// Set chromakey in video widget so we can see overlay data overlay->hwdata->chromakey = 0;
/* I don't know where the container widget is!!!, I guess it is in hidden->window*/ PtSetResource(window, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0);
PtEnter(0);
PtSetArg( &argt, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0 );
PtSetResources( window, 1, &argt );
PtLeave(0);
PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
fflush( stderr ); overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER;
overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x; if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey))
overlay->hwdata->props.viewport.ul.y = overlay->hwdata->CurrentWindow.y; {
//Next line MIGHT have x and y reversed!!!!!!!!!!!! overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
overlay->hwdata->props.viewport.lr.x = overlay->hwdata->CurrentWindow.x +overlay->hwdata->CurrentWindow.w; overlay->hwdata->props.color_key = overlay->hwdata->chromakey;
overlay->hwdata->props.viewport.lr.y = overlay->hwdata->CurrentWindow.y + overlay->hwdata->CurrentWindow.h; overlay->hwdata->props.color_key_mask = 0x00FFFFFFUL;
}
else
{
overlay->hwdata->props.flags = overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE;
~Pg_SCALER_PROP_SCALER_ENABLE | Pg_SCALER_PROP_DOUBLE_BUFFER ; }
if (overlay->hwdata->chromakey) { rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &overlay->hwdata->props);
overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
overlay->hwdata->props.color_key = overlay->hwdata->chromakey;
overlay->hwdata->props.color_key_mask = 0xffffff;
}
else
{
overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE;
}
switch(rtncode)
{
case -1: SDL_SetError("PgConfigScalerChannel failed\n");
SDL_FreeYUVOverlay(overlay);
return(NULL);
break;
case 1:
case 0:
default:
break;
}
overlay->hwdata->scaler_on = FALSE; planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
if(overlay->hwdata->channel->yplane1 != NULL)
overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch;
if(overlay->hwdata->channel->uplane1 != NULL)
overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch;
if(overlay->hwdata->channel->vplane1 != NULL)
overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch;
overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); if(overlay->hwdata->current==0)
switch(rtncode) overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
{ else
case -1: overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
SDL_SetError("PgConfigScalerChannel failed\n");
SDL_FreeYUVOverlay(overlay);
return(NULL);
break;
case 1:
grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
break;
case 0:
default:
break;
}
overlay->hwdata->locked = 1;
grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); /* Find the pitch and offset values for the overlay */
overlay->planes = planes;
overlay->pitches = calloc(overlay->planes, sizeof(Uint16));
overlay->pixels = calloc(overlay->planes, sizeof(Uint8*));
if (!overlay->pitches || !overlay->pixels)
{
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return(NULL);
}
if(overlay->hwdata->channel->yplane1 != NULL) if (overlay->planes > 0)
overlay->hwdata->YStride = overlay->hwdata->channel->yplane1->pitch; {
if(overlay->hwdata->channel->uplane1 != NULL) overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
overlay->hwdata->UStride = overlay->hwdata->channel->uplane1->pitch; overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
if(overlay->hwdata->channel->vplane1 != NULL) }
overlay->hwdata->VStride = overlay->hwdata->channel->vplane1->pitch; if (overlay->planes > 1)
{
overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
}
if (overlay->planes > 2)
{
overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
}
overlay->hwdata->State = OVERLAY_STATE_ACTIVE;
overlay->hwdata->scaler_on = 0;
overlay->hw_overlay = 1;
overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); return (overlay);
}
int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
{
if (overlay == NULL)
return 0;
overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
if (overlay->hwdata->current == -1)
{
SDL_SetError("PgNextFrame failed, bailing out\n");
SDL_FreeYUVOverlay(overlay);
return(NULL);
}
if (overlay->hwdata->current == -1) overlay->hwdata->locked = 1;
{
SDL_SetError("PgNextFrame failed, bailing out\n");
SDL_FreeYUVOverlay(overlay);
return(NULL);
}
//set current frame for double buffering
if(overlay->hwdata->current == 0)
{
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
}
else
{
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
}
overlay->hwdata->State = OVERLAY_STATE_ACTIVE;
/* set current frame for double buffering */
if (overlay->hwdata->current == 0)
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
else
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
/* We're all done.. */ if (overlay->planes > 0)
return(overlay); {
} overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
}
if (overlay->planes > 1)
{
overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
}
if (overlay->planes > 2)
{
overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
}
int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay) return(0);
{
//int rtncode;
if(overlay == NULL)
return 0;
//set current frame for double buffering
if(overlay->hwdata->current == 0)
{
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
}
else
{
overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
}
//Lock gets the pointer and passes it to the app. The app writes all yuv data into overlay->pixels
//Note this is defined as Uint8 **pixels; /* Read-write */
overlay->pixels = &overlay->hwdata->CurrentFrameData->Y;
overlay->pitches = (Uint16*) &(overlay->hwdata->YStride);
return(0);
} }
void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
{ {
int rtncode; int rtncode;
if(overlay == NULL) if(overlay == NULL)
return ; return;
if(overlay->hwdata->scaler_on == FALSE) if(overlay->hwdata->scaler_on == 1)
{ {
overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE;
rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
switch(rtncode) switch(rtncode)
{ {
case -1: case -1:
SDL_SetError("PgConfigScalerChannel failed\n"); SDL_SetError("PgConfigScalerChannel failed\n");
SDL_FreeYUVOverlay(overlay); SDL_FreeYUVOverlay(overlay);
break; break;
case 1: case 1:
grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
overlay->hwdata->scaler_on = TRUE; break;
break; case 0:
case 0: default:
default: break;
overlay->hwdata->scaler_on = TRUE; }
break; }
}
//This would be the best place to draw chromakey but we do not have a SDL_Surface in the args /* This would be the best place to draw chromakey but we do not have a SDL_Surface in the args
//This means we might see a chromakey flicker at startup * This means we might see a chromakey flicker at startup. */
}
overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
if (overlay->hwdata->current == -1) {
SDL_SetError("PgNextVideoFrame failed\n");
SDL_FreeYUVOverlay(overlay);
return;
}
overlay->pixels = NULL;
} }
int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect)
{ {
int rtncode; int rtncode;
PhPoint_t pos;
if(overlay == NULL)
return 0; if(overlay == NULL)
return -1;
/* If CurrentWindow has change, move the viewport */
if((overlay->hwdata->CurrentWindow.pos.x != dstrect->x) ||
(overlay->hwdata->CurrentWindow.pos.y != dstrect->y) ||
(overlay->hwdata->CurrentWindow.size.w != dstrect->w) ||
(overlay->hwdata->CurrentWindow.size.h != dstrect->h) ||
(overlay->hwdata->scaler_on==0))
{
if(overlay->hwdata->State == OVERLAY_STATE_UNINIT)
return -1;
overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE;
overlay->hwdata->scaler_on = 1;
/*SDL_Rect CurrentWindow*/ PtGetAbsPosition(window, &pos.x, &pos.y);
//If CurrentWindow has change, move the viewport overlay->hwdata->CurrentWindow.pos.x = pos.x + dstrect->x;
if((overlay->hwdata->CurrentWindow.x != dstrect->x) || overlay->hwdata->CurrentWindow.pos.y = pos.y + dstrect->y;
(overlay->hwdata->CurrentWindow.y != dstrect->y) || overlay->hwdata->CurrentWindow.size.w = dstrect->w;
(overlay->hwdata->CurrentWindow.w != dstrect->w) || overlay->hwdata->CurrentWindow.size.h = dstrect->h;
(overlay->hwdata->CurrentWindow.h != dstrect->h))
{
if(overlay->hwdata->State == OVERLAY_STATE_UNINIT)
return -1;
overlay->hwdata->CurrentWindow.x = dstrect->x; PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport);
overlay->hwdata->CurrentWindow.y = dstrect->y;
overlay->hwdata->CurrentWindow.w = dstrect->w;
overlay->hwdata->CurrentWindow.h = dstrect->h;
overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x; rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
overlay->hwdata->props.viewport.ul.y = overlay->hwdata->CurrentWindow.y;
//Next line MIGHT have x and y reversed!!!!!!!!!!!!
overlay->hwdata->props.viewport.lr.x = overlay->hwdata->CurrentWindow.x +overlay->hwdata->CurrentWindow.w;
overlay->hwdata->props.viewport.lr.y = overlay->hwdata->CurrentWindow.y + overlay->hwdata->CurrentWindow.h;
rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
switch(rtncode)
{
case -1:
SDL_SetError("PgConfigScalerChannel failed\n");
SDL_FreeYUVOverlay(overlay);
return(0);
break;
case 1:
grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
break;
case 0:
default:
break;
}
}
switch(rtncode)
{
case -1:
SDL_SetError("PgConfigScalerChannel failed\n");
SDL_FreeYUVOverlay(overlay);
return (0);
case 1:
grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1);
break;
case 0:
default:
break;
}
}
//JB the X11 file did this. We do this in SDL_unlock, we need to confirm that lock and unlock are called for each frame! if (!overlay->hwdata->locked)
// XvShmPutImage(GFX_Display, hwdata->port, SDL_Window, SDL_GC, {
// hwdata->image, 0, 0, overlay->w, overlay->h, overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel);
// dstrect->x, dstrect->y, dstrect->w, dstrect->h, False); if (overlay->hwdata->current == -1)
/* This is what this call is {
int XvShmPutImage ( SDL_SetError("PgNextVideoFrame failed\n");
Display *dpy, SDL_FreeYUVOverlay(overlay);
XvPortID port, return 0;
Drawable d, }
GC gc, if (overlay->hwdata->current == 0)
XvImage *image, overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0;
int src_x, else
int src_y, overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1;
unsigned int src_w,
unsigned int src_h,
int dest_x,
int dest_y,
unsigned int dest_w,
unsigned int dest_h,
Bool send_event
)
*/
return(0); if (overlay->planes > 0)
{
overlay->pitches[0] = overlay->hwdata->channel->yplane1->pitch;
overlay->pixels[0] = overlay->hwdata->CurrentFrameData->Y;
}
if (overlay->planes > 1)
{
overlay->pitches[1] = overlay->hwdata->channel->uplane1->pitch;
overlay->pixels[1] = overlay->hwdata->CurrentFrameData->U;
}
if (overlay->planes > 2)
{
overlay->pitches[2] = overlay->hwdata->channel->vplane1->pitch;
overlay->pixels[2] = overlay->hwdata->CurrentFrameData->V;
}
}
return 0;
} }
void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
{ {
//struct private_yuvhwdata *hwdata; if (overlay == NULL)
return;
if(overlay == NULL) if (overlay->hwdata == NULL)
return; return;
if(overlay->hwdata == NULL)
return;
overlay->hwdata->State = OVERLAY_STATE_UNINIT;
if( overlay->hwdata->channel == NULL ) /* it is need for some buggy drivers, that can't hide overlay before */
{ /* freeing buffer, so we got trash on the srceen */
return; overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_SCALER_ENABLE;
} PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props));
PgDestroyVideoChannel(overlay->hwdata->channel); overlay->hwdata->scaler_on = 0;
overlay->hwdata->State = OVERLAY_STATE_UNINIT;
overlay->hwdata->channel = NULL; if (overlay->hwdata->channel != NULL)
overlay->hwdata->CurrentFrameData = NULL; {
PgDestroyVideoChannel(overlay->hwdata->channel);
free(overlay->hwdata->FrameData0); overlay->hwdata->channel = NULL;
free(overlay->hwdata->FrameData1); return;
overlay->hwdata->FrameData0 = NULL; }
overlay->hwdata->FrameData1 = NULL;
free(overlay->hwdata);
overlay->hwdata->CurrentFrameData = NULL;
free(overlay->hwdata->FrameData0);
free(overlay->hwdata->FrameData1);
overlay->hwdata->FrameData0 = NULL;
overlay->hwdata->FrameData1 = NULL;
free(overlay->hwdata);
} }
...@@ -31,11 +31,7 @@ static char rcsid = ...@@ -31,11 +31,7 @@ static char rcsid =
#include "SDL_ph_video.h" #include "SDL_ph_video.h"
extern SDL_Overlay *ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); extern SDL_Overlay *ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
extern int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay); extern int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay); extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect);
extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay); extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment