diff --git a/BUGS b/BUGS index f9518cad8..6b775e80d 100644 --- a/BUGS +++ b/BUGS @@ -188,14 +188,8 @@ QNX: -= NOT YET SUPPORTED =- The only hardware surface is the primary view surface. - Mouse events don't seem to be working right. - Fullscreen doesn't display correctly. - The software surfaces could use some speed up. - - The mouse cursor doesn't look right. - AmigaOS: -= NOT YET SUPPORTED =- The OpenGL support isn't implemented yet. diff --git a/src/cdrom/qnx/SDL_syscdrom.c b/src/cdrom/qnx/SDL_syscdrom.c index c21d497c8..fa208b4a1 100644 --- a/src/cdrom/qnx/SDL_syscdrom.c +++ b/src/cdrom/qnx/SDL_syscdrom.c @@ -33,24 +33,26 @@ static char rcsid = #include #include #include -#include #include +#include #include #include #include - #include "SDL_error.h" #include "SDL_cdrom.h" +#include "SDL_timer.h" #include "SDL_syscdrom.h" - /* 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 */ static char *SDL_cdlist[MAX_DRIVES]; static dev_t SDL_cdmode[MAX_DRIVES]; +static int SDL_cdopen[MAX_DRIVES]; /* The system-dependent CD control functions */ static const char *SDL_SYS_CDName(int drive); @@ -64,341 +66,491 @@ static int SDL_SYS_CDStop(SDL_CD *cdrom); static int SDL_SYS_CDEject(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 */ -static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) +static int CheckDrive(char *drive, struct stat *stbuf) { - int is_cd, cdfd; - cdrom_subch_data_t info; + int is_cd, cdfd; + cam_devinfo_t dinfo; + int devctlret=0; - /* If it doesn't exist, return -1 */ - if ( stat(drive, stbuf) < 0 ) { - return(-1); - } + int atapi; + int removable; + int cdb10; - /* If it does exist, verify that it's an available CD-ROM */ - is_cd = 0; - if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { - cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); - if ( cdfd >= 0 ) { - info.subch_command.data_format = CDROM_MSF; - /* Under Linux, EIO occurs when a disk is not present. - */ - if ((devctl(cdfd,DCMD_CAM_CDROMSUBCHNL,&info,sizeof(info),0) == 0) || - ERRNO_TRAYEMPTY(errno) ) - { - is_cd = 1; - } - close(cdfd); - } - } - return(is_cd); + /* If it doesn't exist, return -1 */ + if (stat(drive, stbuf) < 0) + { + return(-1); + } + + /* If it does exist, verify that it's an available CD-ROM */ + is_cd = 0; + + if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode)) + { + cdfd = open(drive, QNX_CD_OPENMODE); + if ( cdfd >= 0 ) + { + devctlret=devctl(cdfd, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL); + + 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 */ static void AddDrive(char *drive, struct stat *stbuf) { - int i; + int i; - 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. - */ - for ( i=0; ist_rdev == SDL_cdmode[i] ) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); -#endif - return; - } - } + 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. */ - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); - if ( SDL_cdlist[i] == NULL ) { - SDL_OutOfMemory(); - return; - } - strcpy(SDL_cdlist[i], drive); - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; -#ifdef DEBUG_CDROM - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } + for (i=0; ist_rdev == SDL_cdmode[i]) + { + return; + } + } + + /* Add this drive to our list */ + + i = SDL_numcds; + SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); + if (SDL_cdlist[i] == NULL) + { + SDL_OutOfMemory(); + return; + } + strcpy(SDL_cdlist[i], drive); + SDL_cdmode[i] = stbuf->st_rdev; + ++SDL_numcds; + } } -int SDL_SYS_CDInit(void) +int SDL_SYS_CDInit(void) { - /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ - static char *checklist[] = { - "cdrom", "?0 cd?", "?1 cd?", "?a hd?", "?0 scd?", "?0 sr?", NULL - }; - char *SDLcdrom; - int i, j, exists; - char drive[32]; - struct stat stbuf; + /* checklist: /dev/cdrom, /dev/cd?, /dev/scd? */ + static char *checklist[]={"cdrom", "?0 cd?", "?1 cd?", "?0 scd?", NULL}; - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; + char *SDLcdrom; + int i, j, exists; + char drive[32]; + struct stat stbuf; - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ - if ( SDLcdrom != NULL ) { - char *cdpath, *delim; - cdpath = malloc(strlen(SDLcdrom)+1); - if ( cdpath != NULL ) { - strcpy(cdpath, SDLcdrom); - SDLcdrom = cdpath; - do { - delim = strchr(SDLcdrom, ':'); - if ( delim ) { - *delim++ = '\0'; - } -#ifdef DEBUG_CDROM - fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); -#endif - if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { - AddDrive(SDLcdrom, &stbuf); - } - if ( delim ) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while ( SDLcdrom ); - free(cdpath); - } + /* Fill in our driver capabilities */ + SDL_CDcaps.Name = SDL_SYS_CDName; + SDL_CDcaps.Open = SDL_SYS_CDOpen; + SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; + SDL_CDcaps.Status = SDL_SYS_CDStatus; + SDL_CDcaps.Play = SDL_SYS_CDPlay; + SDL_CDcaps.Pause = SDL_SYS_CDPause; + SDL_CDcaps.Resume = SDL_SYS_CDResume; + SDL_CDcaps.Stop = SDL_SYS_CDStop; + SDL_CDcaps.Eject = SDL_SYS_CDEject; + SDL_CDcaps.Close = SDL_SYS_CDClose; - /* If we found our drives, there's nothing left to do */ - if ( SDL_numcds > 0 ) { - return(0); - } - } + /* clearing device open status */ + for (i=0; i 0 ) { - AddDrive(drive, &stbuf); - } - } - } - return(0); + /* Look in the environment for our CD-ROM drive list */ + SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ + if ( SDLcdrom != NULL ) + { + char *cdpath, *delim; + + cdpath = malloc(strlen(SDLcdrom)+1); + if (cdpath != NULL) + { + strcpy(cdpath, SDLcdrom); + SDLcdrom = cdpath; + do { + delim = strchr(SDLcdrom, ':'); + if (delim) + { + *delim++ = '\0'; + } + if (CheckDrive(SDLcdrom, &stbuf) > 0) + { + AddDrive(SDLcdrom, &stbuf); + } + if (delim) + { + SDLcdrom = delim; + } + else + { + SDLcdrom = NULL; + } + } while (SDLcdrom); + free(cdpath); + } + + /* If we found our drives, there's nothing left to do */ + if (SDL_numcds > 0) + { + return(0); + } + } + + /* Scan the system for CD-ROM drives */ + for ( i=0; checklist[i]; ++i ) + { + if (checklist[i][0] == '?') + { + char* insert; + exists = 1; + + for ( j=checklist[i][1]; exists; ++j ) + { + sprintf(drive, "/dev/%s", &checklist[i][3]); + insert = strchr(drive, '?'); + if (insert != NULL) + { + *insert = j; + } + switch (CheckDrive(drive, &stbuf)) + { + /* Drive exists and is a CD-ROM */ + case 1: + AddDrive(drive, &stbuf); + break; + /* Drive exists, but isn't a CD-ROM */ + case 0: + break; + /* Drive doesn't exist */ + case -1: + 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) { - return(SDL_cdlist[drive]); + return(SDL_cdlist[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) { - cdrom_read_toc_t toc; - int i, okay; + cdrom_read_toc_t toc; + int i, okay; - okay = 0; - if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0) == 0) { - cdrom->numtracks = toc.last_track - toc.first_track + 1; - if ( cdrom->numtracks > SDL_MAX_TRACKS ) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - /* Read all the track TOC entries */ - for ( i=0; i<=cdrom->numtracks; ++i ) { - if ( i == cdrom->numtracks ) { - cdrom->track[i].id = CDROM_LEADOUT; - } else { -#if 0 /* Sam 11/6/00 - an obsolete field? */ - cdrom->track[i].id = toc.cdth_trk0+i; -#else - cdrom->track[i].id = toc.first_track+i; -#endif - } - cdrom->track[i].type = toc.toc_entry[i].control_adr; - cdrom->track[i].offset = MSF_TO_FRAMES( - toc.toc_entry[i].addr.msf.minute, - toc.toc_entry[i].addr.msf.second, - toc.toc_entry[i].addr.msf.frame); - cdrom->track[i].length = 0; - if ( i > 0 ) { - cdrom->track[i-1].length = - cdrom->track[i].offset- - cdrom->track[i-1].offset; - } - } - if ( i == (cdrom->numtracks+1) ) { - okay = 1; - } - } - return(okay ? 0 : -1); + okay = 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 = SDL_MAX_TRACKS; + } + /* Read all the track TOC entries */ + for (i=0; i<=cdrom->numtracks; ++i) + { + if (i == cdrom->numtracks) + { + cdrom->track[i].id = CDROM_LEADOUT; + } + else + { + cdrom->track[i].id = toc.first_track+i; + } + + cdrom->track[i].type = toc.toc_entry[i].control_adr & 0x0F; + cdrom->track[i].offset = toc.toc_entry[i].addr.lba; + cdrom->track[i].length = 0; + + if (i > 0) + { + cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset; + } + } + if (i == (cdrom->numtracks+1)) + { + okay = 1; + } + } + return (okay ? 0 : -1); } /* Get CD-ROM status */ static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) { - CDstatus status; - cdrom_read_toc_t toc; - subch_current_position_t info; + CDstatus status; -#if 0 /* Sam 11/6/00 - an obsolete field? */ - info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION; - info.subch_command.track_number = 0; -#else - info.data_format = CDROM_SUBCH_CURRENT_POSITION; - info.track_number = 0; -#endif - if (devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), 0) != 0) { - if ( ERRNO_TRAYEMPTY(errno) ) { - status = CD_TRAYEMPTY; - } else { - status = CD_ERROR; - } - } else { - switch (info.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), 0)==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.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.addr.msf.minute, - info.addr.msf.second, - info.addr.msf.frame); - } else { - *position = 0; - } - } - return(status); + cdrom_read_toc_t toc; + cdrom_subch_data_t info; + cam_devinfo_t dinfo; + + int devctlret=0; + int drive=-1; + int i; + int eagaincnt=0; + + /* check media presence before read subchannel call, some cdroms can lockups */ + /* if no media, while calling read subchannel functions. */ + devctlret=devctl(cdrom->id, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL); + + if (devctlret==EOK) + { + if ((dinfo.flags & DEV_NO_MEDIA)!=0) + { + status = CD_TRAYEMPTY; + if (position) + { + *position = 0; + } + return (status); + } + } + + /* if media exists, then do other stuff */ + + memset(&info, 0x00, sizeof(info)); + info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION; + + do { + devctlret=devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), NULL); + if (devctlret==EIO) + { + /* big workaround for media change, handle is unusable after that, + that bug was found in QNX 6.2, 6.2.1 is not released yet. */ + + for (i=0; iid) + { + drive=i; + break; + } + } + if (drive==-1) + { + /* that cannot happen, but ... */ + break; + } + close(cdrom->id); + cdrom->id=open(SDL_cdlist[drive], QNX_CD_OPENMODE); + devctlret=EAGAIN; + } + 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 */ static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) { - cdrom_playmsf_t playtime; + cdrom_playmsf_t playtime; - FRAMES_TO_MSF(start, - &playtime.start_minute, &playtime.start_second, &playtime.start_frame); - FRAMES_TO_MSF(start+length, - &playtime.end_minute, &playtime.end_second, &playtime.end_frame); -#ifdef DEBUG_CDROM - fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", - playtime.start_minute, playtime.start_second, playtime.start_frame, - playtime.end_minute, playtime.end_second, playtime.end_frame); -#endif - return(devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), 0)); + FRAMES_TO_MSF(start, &playtime.start_minute, &playtime.start_second, &playtime.start_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) + { + return -1; + } + else + { + return 0; + } } /* Pause play */ 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 */ 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 */ 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 */ 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 */ static void SDL_SYS_CDClose(SDL_CD *cdrom) { - close(cdrom->id); + int i; + + for (i=0; iid) + { + SDL_cdopen[i]=0; + break; + } + } + + close(cdrom->id); } void SDL_SYS_CDQuit(void) { - int i; + int i; - if ( SDL_numcds > 0 ) { - for ( i=0; i 0) + { + for (i=0; itype == 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) { -/* PhPointerEvent_t *pointer = PhGetData( winEvent ); */ - PhRect_t *rect = PhGetRects( winEvent ); + PhRect_t *rect = PhGetRects( winEvent ); - int centre_x, centre_y; - int dx, dy; - short abs_x, abs_y; - int posted; + int centre_x, centre_y; + int dx, dy; + short abs_x, abs_y; + int posted; - centre_x = SDL_VideoSurface->w / 2; - centre_y = SDL_VideoSurface->h / 2; + centre_x = SDL_VideoSurface->w / 2; + centre_y = SDL_VideoSurface->h / 2; - dx = rect->ul.x - centre_x; - dy = rect->ul.y - centre_y; + dx = rect->ul.x - centre_x; + 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 */ - PtGetAbsPosition( window, &abs_x, &abs_y ); - PhMoveCursorAbs( PhInputGroup(NULL), - abs_x + centre_x, - abs_y + centre_y ); + /* Move mouse cursor to middle of the window */ + PtGetAbsPosition( window, &abs_x, &abs_y ); + PhMoveCursorAbs(PhInputGroup(NULL), 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 @@ -123,35 +84,34 @@ static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent) static void set_motion_sensitivity(_THIS, unsigned int flags) { - int rid, fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON; - PhRegion_t region; + int rid; + int fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON; + PhRegion_t region; - if( window ) - { - rid = PtWidgetRid( window ); - if( rid != 0 && PhRegionQuery( rid, ®ion, NULL, NULL, 0 ) == 0 ) - { - region.events_sense = ( region.events_sense & ~fields ) | - ( flags & fields ); - PhRegionChange( Ph_REGION_EV_SENSE, 0, ®ion, - NULL, NULL ); - } - } + if( window ) + { + rid = PtWidgetRid( window ); + if( rid != 0 && PhRegionQuery( rid, ®ion, NULL, NULL, 0 ) == 0 ) + { + region.events_sense=(region.events_sense & ~fields)|(flags & fields); + PhRegionChange(Ph_REGION_EV_SENSE, 0, ®ion, NULL, NULL); + } + } } /* 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 ) - mouse_button |= SDL_BUTTON_LEFT; - if( button_state & Ph_BUTTON_MENU ) - mouse_button |= SDL_BUTTON_RIGHT; - if( button_state & Ph_BUTTON_ADJUST ) - mouse_button |= SDL_BUTTON_MIDDLE; + if (button_state & Ph_BUTTON_SELECT) + mouse_button |= SDL_BUTTON_LEFT; + if (button_state & Ph_BUTTON_MENU) + mouse_button |= SDL_BUTTON_RIGHT; + if (button_state & Ph_BUTTON_ADJUST) + mouse_button |= SDL_BUTTON_MIDDLE; - return( mouse_button ); + return (mouse_button); } static int ph_DispatchEvent(_THIS) @@ -245,10 +205,6 @@ static int ph_DispatchEvent(_THIS) { set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON); posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); - - /* Queue leaving fullscreen mode */ - switch_waiting = 0x01; - switch_time = SDL_GetTicks() + 200; } /* gaining 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) /* perform a blocking read if no events available */ int ph_Pending(_THIS) { - /* Flush the display connection and look to see if events are queued */ - PgFlush(); + /* Flush the display connection and look to see if events are queued */ + PgFlush(); - while( 1 ) - { //note this is a non-blocking call - switch( PhEventPeek( event, EVENT_SIZE ) ) - { - case Ph_EVENT_MSG: - + while( 1 ) + { /* note this is a non-blocking call */ + switch( PhEventPeek( event, EVENT_SIZE ) ) + { + case Ph_EVENT_MSG: return 1; break; - case -1: - perror( "PhEventNext failed" ); + case -1: + perror("ph_Pending(): PhEventNext failed"); break; - default: - - 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= 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 - } + while (ph_Pending(this)) + { + ph_DispatchEvent(this); + } } void ph_InitKeymap(void) { - int i; + int i; - /* Odd keys used in international keyboards */ - for ( i=0; ikey_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; + /* '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. + We will assume it is valid. */ - utf8len = PhKeyToMb( utf8, key ); - if( utf8len > 0 ) - { - utf8len = mbtowc( &unicode, utf8, utf8len ); - if( utf8len > 0) - keysym->unicode = unicode; - } - } + /* FIXME: This needs to check whether the cap & scancode is valid */ - return (keysym); + 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 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) { - ph_InitKeymap(); + ph_InitKeymap(); } - diff --git a/src/video/photon/SDL_ph_events_c.h b/src/video/photon/SDL_ph_events_c.h index 89c20f44a..46f339722 100644 --- a/src/video/photon/SDL_ph_events_c.h +++ b/src/video/photon/SDL_ph_events_c.h @@ -27,7 +27,7 @@ static char rcsid = #include "SDL_ph_video.h" -#define EVENT_SIZE sizeof( PhEvent_t ) + 1000 +#define EVENT_SIZE sizeof(PhEvent_t) + 1000 /* Functions to be exported */ extern void ph_InitOSKeymap(_THIS); diff --git a/src/video/photon/SDL_ph_image.c b/src/video/photon/SDL_ph_image.c index a11f1da06..73132c372 100644 --- a/src/video/photon/SDL_ph_image.c +++ b/src/video/photon/SDL_ph_image.c @@ -29,16 +29,60 @@ static char rcsid = #include #include +#include "SDL.h" #include "SDL_error.h" #include "SDL_endian.h" +#include "SDL_video.h" +#include "SDL_pixels_c.h" #include "SDL_ph_image_c.h" -/* remove this line, if photon headers updates */ -int PgWaitHWIdle(void); +/* Mask values for SDL_ReallocFormat() */ +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) { PgColor_t* palette=NULL; + const struct ColourMasks* mask; int type=0; int bpp; @@ -68,7 +112,7 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) } break; default:{ - fprintf(stderr,"ph_SetupImage(): unsupported bbp = %d\n", bpp); + fprintf(stderr,"ph_SetupImage(): unsupported bpp=%d !\n", bpp); return -1; } break; @@ -84,7 +128,7 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) /* 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) { - fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8.\n"); + fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8 !\n"); return -1; } } @@ -93,14 +137,20 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) /* using shared memory for speed (set last param to 1) */ 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; } } - + screen->pixels = SDL_Image->image; 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; return 0; @@ -108,8 +158,12 @@ int ph_SetupImage(_THIS, SDL_Surface *screen) int ph_SetupOCImage(_THIS, SDL_Surface *screen) { + const struct ColourMasks *mask; int type = 0; int bpp; + + screen->flags &= ~SDL_DOUBLEBUF; + OCImage.flags = screen->flags; bpp=screen->format->BitsPerPixel; @@ -137,22 +191,14 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) } break; default:{ - fprintf(stderr,"ph_SetupOCImage(): unsupported bpp = %d\n", bpp); + fprintf(stderr,"ph_SetupOCImage(): unsupported bpp=%d !\n", bpp); return -1; } break; } - OCImage.FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA))); - OCImage.FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA))); - 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(); - } - + /* Currently only offscreen contexts with the same bit depth as the + * display can be created. */ OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN); if (OCImage.offscreen_context == NULL) @@ -161,13 +207,22 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) return -1; } - screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */ - - if (OCImage.flags & SDL_DOUBLEBUF) + /* 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) { - 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); if (OCImage.dc_ptr.ptr8 == NULL) @@ -176,15 +231,13 @@ int ph_SetupOCImage(_THIS, SDL_Surface *screen) return -1; } + OCImage.FrameData0 = OCImage.dc_ptr.ptr8; OCImage.CurrentFrameData = OCImage.FrameData0; - OCImage.CurrentFrameData->Y = OCImage.dc_ptr.ptr8; - OCImage.CurrentFrameData->U = NULL; - OCImage.CurrentFrameData->V = NULL; OCImage.current = 0; PhDCSetCurrent(OCImage.offscreen_context); - screen->pixels = OCImage.CurrentFrameData->Y; + screen->pixels = OCImage.CurrentFrameData; this->UpdateRects = ph_OCUpdate; @@ -198,15 +251,67 @@ int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen) 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) { if (OCImage.offscreen_context != NULL) { PhDCRelease(OCImage.offscreen_context); OCImage.offscreen_context = NULL; - free(OCImage.FrameData0); OCImage.FrameData0 = NULL; - free(OCImage.FrameData1); OCImage.FrameData1 = NULL; } @@ -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); - 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); } - else if (flags & SDL_OPENGL) + if ((flags & SDL_OPENGL)==SDL_OPENGL) { return ph_SetupOpenGLImage(this, screen); } - else - { - return ph_SetupImage(this, screen); - } + + return ph_SetupImage(this, screen); } int ph_AllocHWSurface(_THIS, SDL_Surface *surface) { @@ -265,11 +371,6 @@ int ph_FlipHWSurface(_THIS, SDL_Surface *surface) int ph_LockHWSurface(_THIS, SDL_Surface *surface) { - if ((surface == SDL_VideoSurface) && blit_queued) { - PgFlush(); - blit_queued = 0; - } - return(0); } @@ -307,7 +408,7 @@ void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) 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) PhArea_t src_rect; PhArea_t dest_rect; - if(OCImage.direct_context == NULL) - { - return; - } - PgSetRegion(PtWidgetRid(window)); PgSetClipping(0, NULL); PgWaitHWIdle(); diff --git a/src/video/photon/SDL_ph_image_c.h b/src/video/photon/SDL_ph_image_c.h index f8b5882b7..37671139d 100644 --- a/src/video/photon/SDL_ph_image_c.h +++ b/src/video/photon/SDL_ph_image_c.h @@ -29,7 +29,7 @@ static char rcsid = extern int ph_SetupImage(_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 void ph_FreeHWSurface(_THIS, SDL_Surface *surface); diff --git a/src/video/photon/SDL_ph_modes.c b/src/video/photon/SDL_ph_modes.c index 43ec07de9..8d6f75e04 100644 --- a/src/video/photon/SDL_ph_modes.c +++ b/src/video/photon/SDL_ph_modes.c @@ -31,35 +31,36 @@ static unsigned long key1, key2; static PgVideoModeInfo_t mode_info; 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_modearray[PH_MAX_VIDEOMODES]; 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) - { - 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; + key1 = mode_info.width * mode_info.height; - if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0) - { - fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n", - *(unsigned short*)mode2); - return 0; - } - key2 = mode_info.width * mode_info.height; + if (PgGetVideoModeInfo(*(unsigned short*)mode2, &mode_info) < 0) + { + fprintf(stderr,"error: In compare_modes_by_res PgGetVideoModeInfo failed on mode: 0x%x\n", + *(unsigned short*)mode2); + return 0; + } - if (key1 > key2) - return 1; - else if (key1 == key2) - return 0; - else - return -1; + key2 = mode_info.width * mode_info.height; + + if (key1 > key2) + return 1; + else if (key1 == key2) + return 0; + else + return -1; } SDL_Rect **ph_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) @@ -117,89 +118,6 @@ void ph_FreeVideoModes(_THIS) 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, ¤t_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, ¤t_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 */ /* if there is no mode then zero is returned */ int get_mode(int width, int height, int bpp) @@ -270,7 +188,7 @@ int get_mode_any_format(int width, int height, int bpp) /* get closest bpp */ closest = i++; 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); while(1) @@ -300,16 +218,12 @@ int get_mode_any_format(int width, int height, int bpp) i++; } } - return mode_list.modes[ closest ]; + return mode_list.modes[closest]; } else return 0; } -void ph_WaitMapped(_THIS); -void ph_WaitUnmapped(_THIS); -void ph_QueueEnterFullScreen(_THIS); - int ph_ToggleFullScreen(_THIS, int on) { if (currently_fullscreen) @@ -338,17 +252,18 @@ int ph_EnterFullScreen(_THIS) } } - if (OCImage.direct_context == NULL) + if (OCImage.direct_context==NULL) { OCImage.direct_context=(PdDirectContext_t*)PdCreateDirectContext(); } 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; } @@ -372,7 +287,8 @@ int ph_LeaveFullScreen(_THIS) { PdDirectStop(OCImage.direct_context); PdReleaseDirectContext(OCImage.direct_context); - + PhDCSetCurrent(OCImage.oldDC); + currently_fullscreen=0; /* Restore old video mode */ @@ -384,7 +300,8 @@ int ph_LeaveFullScreen(_THIS) if (PgSetVideoMode(&mymode_settings) < 0) { - fprintf(stderr,"error: PgSetVideoMode failed\n"); + fprintf(stderr, "Ph_LeaveFullScreen(): PgSetVideoMode failed !\n"); + return 0; } } diff --git a/src/video/photon/SDL_ph_modes_c.h b/src/video/photon/SDL_ph_modes_c.h index d1579ffdd..48b062522 100644 --- a/src/video/photon/SDL_ph_modes_c.h +++ b/src/video/photon/SDL_ph_modes_c.h @@ -36,9 +36,6 @@ static char rcsid = extern SDL_Rect **ph_ListModes(_THIS,SDL_PixelFormat *format, Uint32 flags); extern void ph_FreeVideoModes(_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_LeaveFullScreen(_THIS); extern int get_mode(int width, int height, int bpp); diff --git a/src/video/photon/SDL_ph_mouse.c b/src/video/photon/SDL_ph_mouse.c index 26a6eb1f7..e7c62decc 100644 --- a/src/video/photon/SDL_ph_mouse.c +++ b/src/video/photon/SDL_ph_mouse.c @@ -35,18 +35,18 @@ static char rcsid = #include "SDL_cursor_c.h" #include "SDL_ph_mouse_c.h" -struct WMcursor { +struct WMcursor +{ PhCursorDef_t *ph_cursor ; }; - void ph_FreeWMCursor(_THIS, WMcursor *cursor) { if (window != NULL) { 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 */ } @@ -60,64 +60,61 @@ void ph_FreeWMCursor(_THIS, WMcursor *cursor) WMcursor *ph_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) { - WMcursor* cursor; - int clen, i; - unsigned char bit, databit, maskbit; + WMcursor* cursor; + int clen, i; + unsigned char bit, databit, maskbit; - /* Allocate and initialize the cursor memory */ - if ((cursor = (WMcursor*)malloc(sizeof(WMcursor))) == NULL) - { - SDL_OutOfMemory(); - return(NULL); - } - memset(cursor,0,sizeof(WMcursor)); + /* Allocate and initialize the cursor memory */ + if ((cursor = (WMcursor*)malloc(sizeof(WMcursor))) == NULL) + { + SDL_OutOfMemory(); + return(NULL); + } + memset(cursor,0,sizeof(WMcursor)); - cursor->ph_cursor = (PhCursorDef_t *) malloc(sizeof(PhCursorDef_t) + 32*4*2); - if(cursor->ph_cursor == NULL) - printf("cursor malloc failed\n"); + cursor->ph_cursor = (PhCursorDef_t *) malloc(sizeof(PhCursorDef_t) + 32*4*2); + if (cursor->ph_cursor == NULL) + 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->size1.x = (short)w; - cursor->ph_cursor->size1.y = (short)h; - cursor->ph_cursor->offset1.x = (short)hot_x; - cursor->ph_cursor->offset1.y = (short)hot_y; - cursor->ph_cursor->bytesperline1 = (char)w/8; - cursor->ph_cursor->color1 = Pg_WHITE; - cursor->ph_cursor->size2.x = (short)w; - cursor->ph_cursor->size2.y = (short)h; - cursor->ph_cursor->offset2.x = (short)hot_x; - cursor->ph_cursor->offset2.y = (short)hot_y; - cursor->ph_cursor->bytesperline2 = (char)w/8; - cursor->ph_cursor->color2 = Pg_BLACK; + cursor->ph_cursor->hdr.type =Ph_RDATA_CURSOR; + cursor->ph_cursor->size1.x = (short)w; + cursor->ph_cursor->size1.y = (short)h; + cursor->ph_cursor->offset1.x = (short)hot_x; + cursor->ph_cursor->offset1.y = (short)hot_y; + cursor->ph_cursor->bytesperline1 = (char)w/8; + cursor->ph_cursor->color1 = Pg_WHITE; + cursor->ph_cursor->size2.x = (short)w; + cursor->ph_cursor->size2.y = (short)h; + cursor->ph_cursor->offset2.x = (short)hot_x; + cursor->ph_cursor->offset2.y = (short)hot_y; + cursor->ph_cursor->bytesperline2 = (char)w/8; + cursor->ph_cursor->color2 = Pg_BLACK; - clen = (w/8)*h; + clen = (w/8)*h; - /* Copy the mask and the data to different - bitmap planes */ - for ( i=0; iph_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; - } - } + 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); + /* #bytes following the hdr struct */ + cursor->ph_cursor->hdr.len =sizeof(PhCursorDef_t) + clen*2 - sizeof(PhRegionDataHdr_t); - return (cursor); + return (cursor); } - PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor) { return(*cursor->ph_cursor); @@ -125,47 +122,46 @@ PhCursorDef_t ph_GetWMPhCursor(WMcursor *cursor) int ph_ShowWMCursor(_THIS, WMcursor *cursor) { - PtArg_t args[3]; - int nargs = 0; - short cursor_is_defined = 0; + PtArg_t args[3]; + int nargs = 0; - /* Don't do anything if the display is gone */ - if ( window == NULL ) { - return(0); - } + /* Don't do anything if the display is gone */ + if (window == NULL) + { + return (0); + } - /* Set the photon cursor cursor, or blank if cursor is NULL */ - if ( window ) { - - if ( cursor != NULL ) { - 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 ); - PtSetArg( &args[2], Pt_ARG_BITMAP_CURSOR, cursor->ph_cursor, (cursor->ph_cursor->hdr.len + sizeof(PhRegionDataHdr_t)) ); - nargs = 3; - cursor_is_defined = 1; - } - else /* Ph_CURSOR_NONE */ - { - PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE,Ph_CURSOR_NONE, 0); - nargs = 1; - cursor_is_defined = 1; - } - if (cursor_is_defined) - { - SDL_Lock_EventThread(); - - if (PtSetResources( window, nargs, args ) < 0 ) - { - return(0); - } - - SDL_Unlock_EventThread(); - } - else - return(0); - } - return(1); + /* looks like photon can't draw mouse cursor in direct mode */ + if ((this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) + { + return (0); + } + + /* Set the photon cursor cursor, or blank if cursor is NULL */ + if (cursor!=NULL) + { + 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); + PtSetArg(&args[2], Pt_ARG_BITMAP_CURSOR, cursor->ph_cursor, (cursor->ph_cursor->hdr.len + sizeof(PhRegionDataHdr_t))); + nargs = 3; + } + else /* Ph_CURSOR_NONE */ + { + PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0); + nargs = 1; + } + + SDL_Lock_EventThread(); + + if (PtSetResources(window, nargs, args) < 0 ) + { + return (0); + } + + SDL_Unlock_EventThread(); + + return (1); } void ph_WarpWMCursor(_THIS, Uint16 x, Uint16 y) diff --git a/src/video/photon/SDL_ph_video.c b/src/video/photon/SDL_ph_video.c index 38f1e08c8..3426b80f6 100644 --- a/src/video/photon/SDL_ph_video.c +++ b/src/video/photon/SDL_ph_video.c @@ -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 void ph_VideoQuit(_THIS); static void ph_DeleteDevice(SDL_VideoDevice *device); +static void ph_UpdateMouse(_THIS); #ifdef HAVE_OPENGL int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags); @@ -90,7 +91,7 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) malloc((sizeof *device->hidden)); device->gl_data = NULL; } - if ( (device == NULL) || (device->hidden == NULL) ) { + if ((device == NULL) || (device->hidden == NULL)) { SDL_OutOfMemory(); ph_DeleteDevice(device); return(0); @@ -106,9 +107,9 @@ static SDL_VideoDevice *ph_CreateDevice(int devindex) device->ListModes = ph_ListModes; device->SetVideoMode = ph_SetVideoMode; device->ToggleFullScreen = ph_ToggleFullScreen; - device->UpdateMouse = NULL; + device->UpdateMouse = ph_UpdateMouse; device->SetColors = ph_SetColors; - device->UpdateRects = NULL; /* ph_ResizeImage */ + device->UpdateRects = NULL; /* ph_SetupUpdateFunction */ device->VideoQuit = ph_VideoQuit; device->AllocHWSurface = ph_AllocHWSurface; device->CheckHWBlit = NULL; @@ -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) { PgVideoModeInfo_t my_mode_info; @@ -184,16 +251,22 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) oglctx=NULL; #endif /* HAVE_OPENGL */ - captionflag=0; old_video_mode=-1; old_refresh_rate=-1; if (NULL == (event = malloc(EVENT_SIZE))) { - exit(EXIT_FAILURE); + SDL_OutOfMemory(); + return -1; } memset(event, 0x00, EVENT_SIZE); + window = ph_CreateWindow(this); + if (window == NULL) + { + return -1; + } + /* Create the blank cursor */ SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask, (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT, @@ -201,7 +274,7 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) 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) @@ -222,7 +295,8 @@ static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat) /* save current palette */ if (desktopbpp==8) { - PgGetPalette(ph_palette); + PgGetPalette(savedpal); + PgGetPalette(syspalph); } currently_fullscreen = 0; @@ -236,110 +310,46 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { PgDisplaySettings_t settings; + SDL_Color* colors; int mode; - PtArg_t arg[32]; - PhDim_t dim; int rtnval; int i; - unsigned long *tempptr; - int pargc; - - dim.w=width; - dim.h=height; /* Lock the event thread, in multi-threading environments */ SDL_Lock_EventThread(); current->flags = flags; - /* create window if no OpenGL support selected */ - 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(); - } + ph_SetupWindow(this, width, height, flags); #ifdef HAVE_OPENGL - if (flags & SDL_OPENGL) + if (current->flags & SDL_OPENGL) { /* ph_SetupOpenGLContext creates also window as need */ if (ph_SetupOpenGLContext(this, width, height, bpp, flags)==0) { - /* setup OGL update function ... ugly method */ - ph_ResizeImage(this, current, flags); + ph_SetupUpdateFunction(this, current, flags); } else { /* if context creation fail, report no OpenGL to high level */ - current->flags=(flags & (~SDL_OPENGL)); + current->flags &= ~SDL_OPENGL; } #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"); - current->flags=(flags & (~SDL_OPENGL)); + current->flags &= ~SDL_OPENGL; return NULL; #endif /* HAVE_OPENGL */ } else { /* 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 */ - if (flags & SDL_ANYFORMAT) + if (current->flags & SDL_ANYFORMAT) { if ((mode = get_mode_any_format(width, height, bpp)) == 0) { @@ -376,7 +386,8 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, 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 */ ph_EnterFullScreen(this); @@ -385,10 +396,10 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, else { /* Use offscreen memory iff SDL_HWSURFACE flag is set */ - if (flags & SDL_HWSURFACE) + if (current->flags & SDL_HWSURFACE) { /* no stretch blit in offscreen context */ - current->flags = (flags & (~SDL_RESIZABLE)); + current->flags &= ~SDL_RESIZABLE; } /* using palette emulation code in window mode */ @@ -402,55 +413,48 @@ static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, { desktoppal=SDLPH_PAL_SYSTEM; } + + /* fill the palette */ + PgGetPalette(savedpal); + PgGetPalette(syspalph); + + current->format->palette = calloc(1, sizeof(SDL_Palette)); + current->format->palette->ncolors = _Pg_MAX_PALETTE; + current->format->palette->colors = (SDL_Color *)calloc(_Pg_MAX_PALETTE, sizeof(SDL_Color)); + + colors = current->format->palette->colors; + + 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 { desktoppal=SDLPH_PAL_NONE; } } - - /* If we are setting video to use the palette make sure we have allocated memory for it */ - if (bpp==8) - { - current->format->palette = malloc(sizeof(SDL_Palette)); - memset(current->format->palette, 0, sizeof(SDL_Palette)); - current->format->palette->ncolors = 256; - current->format->palette->colors = (SDL_Color *)malloc(256 *sizeof(SDL_Color)); - /* fill the palette */ - rtnval = PgGetPalette(ph_palette); - - tempptr = (unsigned long *)current->format->palette->colors; - - for(i=0; i<256; i++) - { - *tempptr = (((unsigned long)ph_palette[i]) << 8); - tempptr++; - } - } - } current->w = width; current->h = height; + + /* These values can be overridden in ph_SetupUpdateFunction() */ current->format->BitsPerPixel = bpp; current->format->BytesPerPixel = (bpp+7)/8; current->pitch = SDL_CalculatePitch(current); /* 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) { - fprintf(stderr,"ph_SetVideoMode(): ph_ResizeImage failed !\n"); + fprintf(stderr,"ph_SetVideoMode(): ph_SetupUpdateFunction failed !\n"); return NULL; } - /* delayed set caption call */ - if (captionflag) - { - ph_SetCaption(this, this->wm_title, NULL); - } - /* finish window drawing */ PtFlush(); @@ -495,12 +499,6 @@ static void ph_VideoQuit(_THIS) PtDestroyWidget(window); 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 if (oglctx) @@ -510,13 +508,30 @@ static void ph_VideoQuit(_THIS) oglctx=NULL; } #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) { int i; - PhPoint_t point={0, 0}; - PgColor_t syspalph[_Pg_MAX_PALETTE]; + SDL_Rect updaterect; + + 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 */ if (desktoppal==SDLPH_PAL_EMULATE) @@ -525,14 +540,11 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { for (i=firstcolor; ipalette[i] = 0x00000000UL; - SDL_Image->palette[i] |= colors[i-firstcolor].r<<16; - SDL_Image->palette[i] |= colors[i-firstcolor].g<<8; - SDL_Image->palette[i] |= colors[i-firstcolor].b; + syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b); + SDL_Image->palette[i] = syspalph[i]; } - - /* image needs to be redrawed, very slow method */ - PgDrawPhImage(&point, SDL_Image, 0); + /* image needs to be redrawn */ + this->UpdateRects(this, 1, &updaterect); } } else @@ -541,26 +553,20 @@ static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { for (i=firstcolor; iscreen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN) { - /* window mode must use soft palette */ - PgSetPalette((PgColor_t*)&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_SOFT, 0); - /* image needs to be redrawed, very slow method */ - if (SDL_Image) - { - PgDrawPhImage(&point, SDL_Image, 0); - } + /* window mode must use soft palette */ + PgSetPalette(&syspalph[firstcolor], 1, firstcolor, ncolors, Pg_PALSET_SOFT, 0); + /* image needs to be redrawn */ + this->UpdateRects(this, 1, &updaterect); } else { /* 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 @@ -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) { - PtArg_t args[8]; PhDim_t dim; uint64_t OGLAttrib[PH_OGL_MAX_ATTRIBS]; int OGLargc; - int pargc; dim.w=width; dim.h=height; @@ -630,51 +634,6 @@ int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags) 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 */ if (flags & SDL_FULLSCREEN) { @@ -717,3 +676,30 @@ int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) } #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(); +} diff --git a/src/video/photon/SDL_ph_video.h b/src/video/photon/SDL_ph_video.h index 99bc94f75..f4d0c15bc 100644 --- a/src/video/photon/SDL_ph_video.h +++ b/src/video/photon/SDL_ph_video.h @@ -44,18 +44,16 @@ #define SDLPH_PAL_SYSTEM 0x00000002L typedef union vidptr{ - uint8_t *volatile ptr8; - uint16_t *volatile ptr16; - uint32_t *volatile ptr32; + uint8_t* volatile ptr8; + uint16_t* volatile ptr16; + uint32_t* volatile ptr32; } VidPtr_t; typedef struct { - unsigned char *Y; - unsigned char *V; - unsigned char *U; -}FRAMEDATA; - -#define EVENT_SIZE sizeof( PhEvent_t ) + 1000 + unsigned char* Y; + unsigned char* V; + unsigned char* U; +} FRAMEDATA; /* Private display data */ struct SDL_PrivateVideoData { @@ -65,15 +63,17 @@ struct SDL_PrivateVideoData { #ifdef HAVE_OPENGL PdOpenGLContext_t* OGLContext; /* OpenGL context */ #endif /* HAVE_OPENGL */ - PgColor_t ph_palette[_Pg_MAX_PALETTE]; + PgColor_t savedpal[_Pg_MAX_PALETTE]; + PgColor_t syspalph[_Pg_MAX_PALETTE]; struct { - PdDirectContext_t *direct_context; - PdOffscreenContext_t *offscreen_context; + PdDirectContext_t* direct_context; + PdOffscreenContext_t* offscreen_context; + PhDrawContext_t* oldDC; VidPtr_t dc_ptr; - FRAMEDATA *CurrentFrameData; - FRAMEDATA *FrameData0; - FRAMEDATA *FrameData1; + unsigned char* CurrentFrameData; + unsigned char* FrameData0; + unsigned char* FrameData1; int current; long flags; } ocimage; @@ -82,40 +82,15 @@ struct SDL_PrivateVideoData { int old_video_mode; /* Stored mode before 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; WMcursor* BlankCursor; int depth; /* current visual depth (not bpp) */ int desktopbpp; /* bpp of desktop at the moment of start */ int desktoppal; /* palette mode emulation or system */ - int captionflag; /* caption setting flag */ - int use_vidmode; 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; }; @@ -129,23 +104,13 @@ struct SDL_PrivateVideoData { #define graphics_card_caps (this->hidden->graphics_card_caps) #define desktopbpp (this->hidden->desktopbpp) #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 */ -#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 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 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 SDL_BlankCursor (this->hidden->BlankCursor) -#define captionflag (this->hidden->captionflag) #endif /* _SDL_x11video_h */ diff --git a/src/video/photon/SDL_ph_wm.c b/src/video/photon/SDL_ph_wm.c index 36967a6cd..b7f06d5d1 100644 --- a/src/video/photon/SDL_ph_wm.c +++ b/src/video/photon/SDL_ph_wm.c @@ -56,15 +56,11 @@ void ph_SetCaption(_THIS, const char *title, const char *icon) { SDL_Lock_EventThread(); - /* check for set caption call before window init */ + /* sanity check for set caption call before window init */ if (window!=NULL) { PtSetResource(window, Pt_ARG_WINDOW_TITLE, title, 0); } - else - { - captionflag=1; - } SDL_Unlock_EventThread(); } @@ -88,36 +84,35 @@ int ph_IconifyWindow(_THIS) 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); } SDL_GrabMode ph_GrabInput(_THIS, SDL_GrabMode mode) { - short abs_x, abs_y; + SDL_Lock_EventThread(); + mode = ph_GrabInputNoLock(this, mode); + SDL_Unlock_EventThread(); - SDL_Lock_EventThread(); -/* mode = ph_GrabInputNoLock(this, 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); + return(mode); } + int ph_GetWMInfo(_THIS, SDL_SysWMinfo *info) { if (info->version.major <= SDL_MAJOR_VERSION) diff --git a/src/video/photon/SDL_phyuv.c b/src/video/photon/SDL_phyuv.c index 7f57ec441..260869109 100644 --- a/src/video/photon/SDL_phyuv.c +++ b/src/video/photon/SDL_phyuv.c @@ -29,11 +29,6 @@ static char rcsid = #include #include -#ifndef bool -#define bool char -#define TRUE 1 -#define FALSE 0 -#endif #include #include @@ -44,606 +39,426 @@ static char rcsid = #include "SDL_phyuv_c.h" #include "SDL_yuvfuncs.h" -#if 0 //just for reference -/* 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_UNINIT 0 #define OVERLAY_STATE_ACTIVE 1 /* The functions used to manipulate software video overlays */ static struct private_yuvhwfuncs ph_yuvfuncs = { - ph_LockYUVOverlay, - ph_UnlockYUVOverlay, - ph_DisplayYUVOverlay, - ph_FreeYUVOverlay + ph_LockYUVOverlay, + ph_UnlockYUVOverlay, + ph_DisplayYUVOverlay, + 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 { - XvImage *image; - FRAMEDATA *CurrentFrameData; - FRAMEDATA *FrameData0; - FRAMEDATA *FrameData1; - PgScalerProps_t props; - PgScalerCaps_t caps; - PgVideoChannel_t *channel; - SDL_Rect CurrentWindow; - long format; - int screen_width; - int screen_height ; - int screen_bpp ; //2 - bool planar; - bool scaler_on ; - int current; - long YStride; - long VStride; - long UStride; - long chromakey; - unsigned long State; - long flags; + FRAMEDATA* CurrentFrameData; + FRAMEDATA* FrameData0; + FRAMEDATA* FrameData1; + PgScalerProps_t props; + PgScalerCaps_t caps; + PgVideoChannel_t* channel; + PhArea_t CurrentWindow; + long format; + int planar; + int scaler_on; + int current; + long YStride; + long VStride; + long UStride; + int ischromakey; + long chromakey; + unsigned long State; + long flags; + int locked; }; -extern PgVideoChannel_t * PgCreateVideoChannel(unsigned type, unsigned flags); -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 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); + /* 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++; + + if (Frame0->V) + planes++; + + return planes; } SDL_Overlay* ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) { - SDL_Overlay *overlay; - struct private_yuvhwdata *hwdata; - int xv_port; - int rtncode; -// PhRect_t rect; -// PhSysInfo_t info; -// PhRegion_t region; -// short x, y; - PtArg_t argt; - int i =0; -// bool bCont = TRUE; - int Priority[20]; - int Type[20]; - int entries, select, highest; + SDL_Overlay *overlay; + struct private_yuvhwdata *hwdata; + int xv_port; + int rtncode; + int planes; + int i=0; + PhPoint_t pos; - PhDCSetCurrent(0); //Need to set draw context to window esp. if we we in Offscreeen mode + /* Create the overlay structure */ + overlay = calloc(1, sizeof(SDL_Overlay)); - /* Create the overlay structure */ - overlay = (SDL_Overlay *)malloc(sizeof(SDL_Overlay)); - memset(overlay, 0x00, sizeof(SDL_Overlay)); - if ( overlay == NULL ) { - SDL_OutOfMemory(); - return(NULL); - } - memset(overlay, 0, (sizeof *overlay)); + if (overlay == NULL) { + SDL_OutOfMemory(); + return (NULL); + } - /* Fill in the basic members */ - overlay->format = format; - overlay->w = width; - overlay->h = height; + /* 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; + /* 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); - } - + /* 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 = PgCreateVideoChannel(Pg_VIDEO_CHANNEL_SCALER,0)) == NULL) { - SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror( errno )); - free(overlay->hwdata); - free(overlay); - return (NULL); + SDL_SetError("ph_CreateYUVOverlay(): Create channel failed: %s\n", strerror(errno)); + SDL_FreeYUVOverlay(overlay); + + return(NULL); + } } - overlay->hwdata->CurrentWindow.x = 0; - overlay->hwdata->CurrentWindow.y = 0; - overlay->hwdata->CurrentWindow.w = 320; - overlay->hwdata->CurrentWindow.h = 240; - + PtGetAbsPosition(window, &pos.x, &pos.y); + overlay->hwdata->CurrentWindow.pos.x = pos.x; + overlay->hwdata->CurrentWindow.pos.y = pos.y; + overlay->hwdata->CurrentWindow.size.w = width; + overlay->hwdata->CurrentWindow.size.h = height; overlay->hwdata->State = OVERLAY_STATE_UNINIT; - - overlay->hwdata->screen_bpp = 2; - 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 + overlay->hwdata->FrameData0 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA)); + overlay->hwdata->FrameData1 = (FRAMEDATA *) calloc(1, sizeof(FRAMEDATA)); xv_port = -1; i=0; + + overlay->hwdata->ischromakey=0; -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; - } + 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); - 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); - } + if (xv_port == -1) + { + SDL_SetError("No available video ports for requested format\n"); + SDL_FreeYUVOverlay(overlay); + 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; - } -} - - - - overlay->hwdata->caps.size = sizeof (overlay->hwdata->caps ); -PgGetScalerCapabilities(overlay->hwdata->channel, select, &(overlay->hwdata->caps)); -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->format = format; + overlay->hwdata->props.format = format; + overlay->hwdata->props.size = sizeof(PgScalerProps_t); overlay->hwdata->props.src_dim.w = width; 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. */ + overlay->hwdata->chromakey = 0; + PtSetResource(window, Pt_ARG_FILL_COLOR, overlay->hwdata->chromakey, 0); - // Set chromakey in video widget so we can see overlay data - /* I don't know where the container widget is!!!, I guess it is in hidden->window*/ - - 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); + overlay->hwdata->props.flags = Pg_SCALER_PROP_DOUBLE_BUFFER; - fflush( stderr ); + if ((overlay->hwdata->ischromakey)&&(overlay->hwdata->chromakey)) + { + overlay->hwdata->props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE; + overlay->hwdata->props.color_key = overlay->hwdata->chromakey; + overlay->hwdata->props.color_key_mask = 0x00FFFFFFUL; + } + else + { + overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_CHROMA_ENABLE; + } - overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x; - 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(NULL); + break; + case 1: + case 0: + default: + break; + } - overlay->hwdata->props.flags = - ~Pg_SCALER_PROP_SCALER_ENABLE | Pg_SCALER_PROP_DOUBLE_BUFFER ; + planes = grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); - if (overlay->hwdata->chromakey) { - 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; - } + 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); - overlay->hwdata->scaler_on = FALSE; + if(overlay->hwdata->current==0) + overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; + else + overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; + overlay->hwdata->locked = 1; + /* 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); + } - rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); - switch(rtncode) - { - case -1: - 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; - } + 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; + } + overlay->hwdata->State = OVERLAY_STATE_ACTIVE; + overlay->hwdata->scaler_on = 0; + overlay->hw_overlay = 1; - 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); - - - - if (overlay->hwdata->current == -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; - - - /* We're all done.. */ - return(overlay); + return (overlay); } int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay) { -//int rtncode; + if (overlay == NULL) + return 0; -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); + } -//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->locked = 1; - //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); + /* set current frame for double buffering */ + if (overlay->hwdata->current == 0) + overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; + else + overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; + + 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_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) { -int rtncode; + int rtncode; -if(overlay == NULL) - return ; + if(overlay == NULL) + return; - if(overlay->hwdata->scaler_on == FALSE) - { - - - overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE; + if(overlay->hwdata->scaler_on == 1) + { rtncode =PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); - switch(rtncode) - { - case -1: - SDL_SetError("PgConfigScalerChannel failed\n"); - SDL_FreeYUVOverlay(overlay); - break; - case 1: - grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); - overlay->hwdata->scaler_on = TRUE; - break; - case 0: - default: - 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 means we might see a chromakey flicker at startup - } - overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); + switch(rtncode) + { + case -1: + SDL_SetError("PgConfigScalerChannel failed\n"); + SDL_FreeYUVOverlay(overlay); + break; + case 1: + grab_ptrs2(overlay->hwdata->channel, overlay->hwdata->FrameData0, overlay->hwdata->FrameData1); + break; + case 0: + default: + break; + } + } - - if (overlay->hwdata->current == -1) { - SDL_SetError("PgNextVideoFrame failed\n"); - SDL_FreeYUVOverlay(overlay); - return; - } - - overlay->pixels = NULL; + /* 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. */ } 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; - /*SDL_Rect CurrentWindow*/ -//If CurrentWindow has change, move the viewport -if((overlay->hwdata->CurrentWindow.x != dstrect->x) || - (overlay->hwdata->CurrentWindow.y != dstrect->y) || - (overlay->hwdata->CurrentWindow.w != dstrect->w) || - (overlay->hwdata->CurrentWindow.h != dstrect->h)) -{ - if(overlay->hwdata->State == OVERLAY_STATE_UNINIT) - return -1; + overlay->hwdata->props.flags |= Pg_SCALER_PROP_SCALER_ENABLE; + overlay->hwdata->scaler_on = 1; - overlay->hwdata->CurrentWindow.x = dstrect->x; - overlay->hwdata->CurrentWindow.y = dstrect->y; - overlay->hwdata->CurrentWindow.w = dstrect->w; - overlay->hwdata->CurrentWindow.h = dstrect->h; + PtGetAbsPosition(window, &pos.x, &pos.y); + overlay->hwdata->CurrentWindow.pos.x = pos.x + dstrect->x; + overlay->hwdata->CurrentWindow.pos.y = pos.y + dstrect->y; + overlay->hwdata->CurrentWindow.size.w = dstrect->w; + overlay->hwdata->CurrentWindow.size.h = dstrect->h; - overlay->hwdata->props.viewport.ul.x = overlay->hwdata->CurrentWindow.x; - 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; + PhAreaToRect(&overlay->hwdata->CurrentWindow, &overlay->hwdata->props.viewport); - - rtncode = PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); + 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; + } + } + if (!overlay->hwdata->locked) + { + overlay->hwdata->current = PgNextVideoFrame(overlay->hwdata->channel); + if (overlay->hwdata->current == -1) + { + SDL_SetError("PgNextVideoFrame failed\n"); + SDL_FreeYUVOverlay(overlay); + return 0; + } + if (overlay->hwdata->current == 0) + overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData0; + else + overlay->hwdata->CurrentFrameData = overlay->hwdata->FrameData1; -//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! -// XvShmPutImage(GFX_Display, hwdata->port, SDL_Window, SDL_GC, -// hwdata->image, 0, 0, overlay->w, overlay->h, -// dstrect->x, dstrect->y, dstrect->w, dstrect->h, False); -/* This is what this call is -int XvShmPutImage ( - Display *dpy, - XvPortID port, - Drawable d, - GC gc, - XvImage *image, - int src_x, - int src_y, - 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) { - //struct private_yuvhwdata *hwdata; + if (overlay == NULL) + return; - if(overlay == NULL) - return; + if (overlay->hwdata == NULL) + return; + + /* it is need for some buggy drivers, that can't hide overlay before */ + /* freeing buffer, so we got trash on the srceen */ + overlay->hwdata->props.flags &= ~Pg_SCALER_PROP_SCALER_ENABLE; + PgConfigScalerChannel(overlay->hwdata->channel, &(overlay->hwdata->props)); + + overlay->hwdata->scaler_on = 0; + overlay->hwdata->State = OVERLAY_STATE_UNINIT; + + if (overlay->hwdata->channel != NULL) + { + PgDestroyVideoChannel(overlay->hwdata->channel); + overlay->hwdata->channel = NULL; + return; + } + + overlay->hwdata->CurrentFrameData = NULL; - if(overlay->hwdata == NULL) - return; - - overlay->hwdata->State = OVERLAY_STATE_UNINIT; - - if( overlay->hwdata->channel == NULL ) - { - return; - } - - PgDestroyVideoChannel(overlay->hwdata->channel); - - overlay->hwdata->channel = NULL; - overlay->hwdata->CurrentFrameData = NULL; - - free(overlay->hwdata->FrameData0); - free(overlay->hwdata->FrameData1); - overlay->hwdata->FrameData0 = NULL; - overlay->hwdata->FrameData1 = NULL; - free(overlay->hwdata); - + free(overlay->hwdata->FrameData0); + free(overlay->hwdata->FrameData1); + overlay->hwdata->FrameData0 = NULL; + overlay->hwdata->FrameData1 = NULL; + free(overlay->hwdata); } diff --git a/src/video/photon/SDL_phyuv_c.h b/src/video/photon/SDL_phyuv_c.h index fadc9f1f0..1670b19f8 100644 --- a/src/video/photon/SDL_phyuv_c.h +++ b/src/video/photon/SDL_phyuv_c.h @@ -31,11 +31,7 @@ static char rcsid = #include "SDL_ph_video.h" extern SDL_Overlay *ph_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); - extern int ph_LockYUVOverlay(_THIS, SDL_Overlay *overlay); - extern void ph_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay); - extern int ph_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); - extern void ph_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);