Пример #1
0
static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	int                  status;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;
	snd_pcm_format_t     format;
	snd_pcm_uframes_t    frames;
	Uint16               test_format;

	/* Open the audio device */
	/* Name of device should depend on # channels in spec */
	status = SDL_NAME(snd_pcm_open)(&pcm_handle, get_audio_device(spec->channels), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);

	if ( status < 0 ) {
		SDL_SetError("Couldn't open audio device: %s", SDL_NAME(snd_strerror)(status));
		return(-1);
	}

	/* Figure out what the hardware is capable of */
	snd_pcm_hw_params_alloca(&hwparams);
	status = SDL_NAME(snd_pcm_hw_params_any)(pcm_handle, hwparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't get hardware config: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* SDL only uses interleaved sample output */
	status = SDL_NAME(snd_pcm_hw_params_set_access)(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set interleaved access: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* Try for a closest match on audio format */
	status = -1;
	for ( test_format = SDL_FirstAudioFormat(spec->format);
	      test_format && (status < 0); ) {
		switch ( test_format ) {
			case AUDIO_U8:
				format = SND_PCM_FORMAT_U8;
				break;
			case AUDIO_S8:
				format = SND_PCM_FORMAT_S8;
				break;
			case AUDIO_S16LSB:
				format = SND_PCM_FORMAT_S16_LE;
				break;
			case AUDIO_S16MSB:
				format = SND_PCM_FORMAT_S16_BE;
				break;
			case AUDIO_U16LSB:
				format = SND_PCM_FORMAT_U16_LE;
				break;
			case AUDIO_U16MSB:
				format = SND_PCM_FORMAT_U16_BE;
				break;
			default:
				format = 0;
				break;
		}
		if ( format != 0 ) {
			status = SDL_NAME(snd_pcm_hw_params_set_format)(pcm_handle, hwparams, format);
		}
		if ( status < 0 ) {
			test_format = SDL_NextAudioFormat();
		}
	}
	if ( status < 0 ) {
		SDL_SetError("Couldn't find any hardware audio formats");
		ALSA_CloseAudio(this);
		return(-1);
	}
	spec->format = test_format;

	/* Set the number of channels */
	status = SDL_NAME(snd_pcm_hw_params_set_channels)(pcm_handle, hwparams, spec->channels);
	if ( status < 0 ) {
		status = SDL_NAME(snd_pcm_hw_params_get_channels)(hwparams);
		if ( (status <= 0) || (status > 2) ) {
			SDL_SetError("Couldn't set audio channels");
			ALSA_CloseAudio(this);
			return(-1);
		}
		spec->channels = status;
	}

	/* Set the audio rate */
	status = SDL_NAME(snd_pcm_hw_params_set_rate_near)(pcm_handle, hwparams, spec->freq, NULL);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	spec->freq = status;

	/* Set the buffer size, in samples */
	frames = spec->samples;
	frames = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, frames, NULL);
	spec->samples = frames;
	SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, 2, NULL);

	/* "set" the hardware with the desired parameters */
	status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set hardware audio parameters: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

/* This is useful for debugging... */
/*
{ snd_pcm_sframes_t bufsize; int fragments;
   bufsize = SDL_NAME(snd_pcm_hw_params_get_period_size)(hwparams);
   fragments = SDL_NAME(snd_pcm_hw_params_get_periods)(hwparams);

   fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize, fragments);
}
*/

	/* Set the software parameters */
	snd_pcm_sw_params_alloca(&swparams);
	status = SDL_NAME(snd_pcm_sw_params_current)(pcm_handle, swparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't get software config: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	status = SDL_NAME(snd_pcm_sw_params_set_start_threshold)(pcm_handle, swparams, 0);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set start threshold: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	status = SDL_NAME(snd_pcm_sw_params_set_avail_min)(pcm_handle, swparams, frames);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set avail min: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}
	status = SDL_NAME(snd_pcm_sw_params)(pcm_handle, swparams);
	if ( status < 0 ) {
		SDL_SetError("Couldn't set software audio parameters: %s", SDL_NAME(snd_strerror)(status));
		ALSA_CloseAudio(this);
		return(-1);
	}

	/* Calculate the final parameters for this audio specification */
	SDL_CalculateAudioSpec(spec);

	/* Allocate mixing buffer */
	mixlen = spec->size;
	mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
	if ( mixbuf == NULL ) {
		ALSA_CloseAudio(this);
		return(-1);
	}
	SDL_memset(mixbuf, spec->silence, spec->size);

	/* Get the parent process id (we're the parent of the audio thread) */
	parent = getpid();

	/* Switch to blocking mode for playback */
	SDL_NAME(snd_pcm_nonblock)(pcm_handle, 0);

	/* We're ready to rock and roll. :-) */
	return(0);
}
Пример #2
0
/*
 * Opens the haptic device from the file descriptor.
 */
static int
SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service)
{
    HRESULT ret;
    int ret2;

    /* Allocate the hwdata */
    haptic->hwdata = (struct haptic_hwdata *)
        SDL_malloc(sizeof(*haptic->hwdata));
    if (haptic->hwdata == NULL) {
        SDL_OutOfMemory();
        goto creat_err;
    }
    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));

    /* Open the device */
    ret = FFCreateDevice(service, &haptic->hwdata->device);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to create device from service: %s.",
                     FFStrError(ret));
        goto creat_err;
    }

    /* Get supported features. */
    ret2 = GetSupportedFeatures(haptic);
    if (haptic->supported < 0) {
        goto open_err;
    }


    /* Reset and then enable actuators. */
    ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
                                           FFSFFC_RESET);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to reset device: %s.", FFStrError(ret));
        goto open_err;
    }
    ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
                                           FFSFFC_SETACTUATORSON);
    if (ret != FF_OK) {
        SDL_SetError("Haptic: Unable to enable actuators: %s.",
                     FFStrError(ret));
        goto open_err;
    }


    /* Allocate effects memory. */
    haptic->effects = (struct haptic_effect *)
        SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
    if (haptic->effects == NULL) {
        SDL_OutOfMemory();
        goto open_err;
    }
    /* Clear the memory */
    SDL_memset(haptic->effects, 0,
               sizeof(struct haptic_effect) * haptic->neffects);

    return 0;

    /* Error handling */
  open_err:
    FFReleaseDevice(haptic->hwdata->device);
  creat_err:
    if (haptic->hwdata != NULL) {
        free(haptic->hwdata);
        haptic->hwdata = NULL;
    }
    return -1;

}
Пример #3
0
static int
ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    esd_format_t format = (ESD_STREAM | ESD_PLAY);
    SDL_AudioFormat test_format = 0;
    int found = 0;

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_zerop(this->hidden);
    this->hidden->audio_fd = -1;

    /* Convert audio spec to the ESD audio format */
    /* Try for a closest match on audio format */
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
         !found && test_format; test_format = SDL_NextAudioFormat()) {
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
        found = 1;
        switch (test_format) {
        case AUDIO_U8:
            format |= ESD_BITS8;
            break;
        case AUDIO_S16SYS:
            format |= ESD_BITS16;
            break;
        default:
            found = 0;
            break;
        }
    }

    if (!found) {
        return SDL_SetError("Couldn't find any hardware audio formats");
    }

    if (this->spec.channels == 1) {
        format |= ESD_MONO;
    } else {
        format |= ESD_STEREO;
    }
#if 0
    this->spec.samples = ESD_BUF_SIZE;  /* Darn, no way to change this yet */
#endif

    /* Open a connection to the ESD audio server */
    this->hidden->audio_fd =
        SDL_NAME(esd_play_stream) (format, this->spec.freq, NULL,
                                   get_progname());

    if (this->hidden->audio_fd < 0) {
        return SDL_SetError("Couldn't open ESD connection");
    }

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);
    this->hidden->frame_ticks =
        (float) (this->spec.samples * 1000) / this->spec.freq;
    this->hidden->next_frame = SDL_GetTicks() + this->hidden->frame_ticks;

    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);

    /* Get the parent process id (we're the parent of the audio thread) */
    this->hidden->parent = getpid();

    /* We're ready to rock and roll. :-) */
    return 0;
}
Пример #4
0
/* Function to open a joystick for use.
   The joystick to open is specified by the index field of the joystick.
   This should fill the nbuttons and naxes fields of the joystick structure.
   It returns 0, or -1 if there is an error.
 */
int
SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
{
    HRESULT result;
    LPDIRECTINPUTDEVICE device;
    DIPROPDWORD dipdw;

    SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD));
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);


    /* allocate memory for system specific hardware data */
    joystick->hwdata =
        (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
    if (joystick->hwdata == NULL) {
        SDL_OutOfMemory();
        return (-1);
    }
    SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata));
    joystick->hwdata->buffered = 1;
    joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);

    result =
        IDirectInput_CreateDevice(dinput,
                                  &SYS_Joystick[joystick->index].
                                  guidInstance, &device, NULL);
    if (FAILED(result)) {
        SetDIerror("IDirectInput::CreateDevice", result);
        return (-1);
    }

    /* Now get the IDirectInputDevice2 interface, instead. */
    result = IDirectInputDevice_QueryInterface(device,
                                               &IID_IDirectInputDevice2,
                                               (LPVOID *) & joystick->
                                               hwdata->InputDevice);
    /* We are done with this object.  Use the stored one from now on. */
    IDirectInputDevice_Release(device);

    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice::QueryInterface", result);
        return (-1);
    }

    /* Aquire shared access. Exclusive access is required for forces,
     * though. */
    result =
        IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata->
                                                InputDevice, SDL_HelperWindow,
                                                DISCL_EXCLUSIVE |
                                                DISCL_BACKGROUND);
    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::SetCooperativeLevel", result);
        return (-1);
    }

    /* Use the extended data structure: DIJOYSTATE2. */
    result =
        IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice,
                                          &c_dfDIJoystick2);
    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::SetDataFormat", result);
        return (-1);
    }

    /* Get device capabilities */
    result =
        IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice,
                                            &joystick->hwdata->Capabilities);

    if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::GetCapabilities", result);
        return (-1);
    }

    /* Force capable? */
    if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {

        result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);

        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::Acquire", result);
            return (-1);
        }

        /* reset all accuators. */
        result =
            IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata->
                                                         InputDevice,
                                                         DISFFC_RESET);

        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand",
                       result);
            return (-1);
        }

        result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice);

        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::Unacquire", result);
            return (-1);
        }

        /* Turn on auto-centering for a ForceFeedback device (until told
         * otherwise). */
        dipdw.diph.dwObj = 0;
        dipdw.diph.dwHow = DIPH_DEVICE;
        dipdw.dwData = DIPROPAUTOCENTER_ON;

        result =
            IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
                                            DIPROP_AUTOCENTER, &dipdw.diph);

        if (FAILED(result)) {
            SetDIerror("IDirectInputDevice2::SetProperty", result);
            return (-1);
        }
    }

    /* What buttons and axes does it have? */
    IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice,
                                    EnumDevObjectsCallback, joystick,
                                    DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);

    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = INPUT_QSIZE;

    /* Set the buffer size */
    result =
        IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
                                        DIPROP_BUFFERSIZE, &dipdw.diph);

    if (result == DI_POLLEDDEVICE) {
        /* This device doesn't support buffering, so we're forced
         * to use less reliable polling. */
        joystick->hwdata->buffered = 0;
    } else if (FAILED(result)) {
        SetDIerror("IDirectInputDevice2::SetProperty", result);
        return (-1);
    }

    return (0);
}
Пример #5
0
/* helper function for direct input, gets called for each connected joystick */
static BOOL CALLBACK
EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
{
    const Uint16 BUS_USB = 0x03;
    const Uint16 BUS_BLUETOOTH = 0x05;
    JoyStick_DeviceData *pNewJoystick;
    JoyStick_DeviceData *pPrevJoystick = NULL;
    const DWORD devtype = (pdidInstance->dwDevType & 0xFF);
    Uint16 *guid16;

    if (devtype == DI8DEVTYPE_SUPPLEMENTAL) {
        return DIENUM_CONTINUE;  /* Ignore touchpads, etc. */
    }

    if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) {
        return DIENUM_CONTINUE;  /* ignore XInput devices here, keep going. */
    }

    pNewJoystick = *(JoyStick_DeviceData **)pContext;
    while (pNewJoystick) {
        if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) {
            /* if we are replacing the front of the list then update it */
            if (pNewJoystick == *(JoyStick_DeviceData **)pContext) {
                *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
            } else if (pPrevJoystick) {
                pPrevJoystick->pNext = pNewJoystick->pNext;
            }

            pNewJoystick->pNext = SYS_Joystick;
            SYS_Joystick = pNewJoystick;

            return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
        }

        pPrevJoystick = pNewJoystick;
        pNewJoystick = pNewJoystick->pNext;
    }

    pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData));
    if (!pNewJoystick) {
        return DIENUM_CONTINUE; /* better luck next time? */
    }

    SDL_zerop(pNewJoystick);
    pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
    if (!pNewJoystick->joystickname) {
        SDL_free(pNewJoystick);
        return DIENUM_CONTINUE; /* better luck next time? */
    }

    SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
        sizeof(DIDEVICEINSTANCE));

    SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));

    guid16 = (Uint16 *)pNewJoystick->guid.data;
    if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
        *guid16++ = SDL_SwapLE16(BUS_USB);
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16((Uint16)LOWORD(pdidInstance->guidProduct.Data1)); /* vendor */
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16((Uint16)HIWORD(pdidInstance->guidProduct.Data1)); /* product */
        *guid16++ = 0;
        *guid16++ = 0; /* version */
        *guid16++ = 0;
    } else {
        *guid16++ = SDL_SwapLE16(BUS_BLUETOOTH);
        *guid16++ = 0;
        SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
    }

    SDL_SYS_AddJoystickDevice(pNewJoystick);

    return DIENUM_CONTINUE; /* get next device, please */
}
Пример #6
0
int ReadTOCData (FSVolumeRefNum theVolume, SDL_CD *theCD)
{
    HFSUniStr255      dataForkName;
    OSStatus          theErr;
    FSIORefNum        forkRefNum;
    SInt64            forkSize;
    Ptr               forkData = 0;
    ByteCount         actualRead;
    CFDataRef         dataRef = 0;
    CFPropertyListRef propertyListRef = 0;
    FSRefParam      fsRefPB;
    FSRef           tocPlistFSRef;
    FSRef           rootRef;
    const char* error = "Unspecified Error";
    const UniChar uniName[] = { '.','T','O','C','.','p','l','i','s','t' };

    theErr = FSGetVolumeInfo(theVolume, 0, 0, kFSVolInfoNone, 0, 0, &rootRef);
    if(theErr != noErr) {
        error = "FSGetVolumeInfo";
        goto bail;
    }

    SDL_memset(&fsRefPB, '\0', sizeof (fsRefPB));

    
    fsRefPB.ref = &rootRef;
    fsRefPB.newRef = &tocPlistFSRef;
    fsRefPB.nameLength = sizeof (uniName) / sizeof (uniName[0]);
    fsRefPB.name = uniName;
    fsRefPB.textEncodingHint = kTextEncodingUnknown;

    theErr = PBMakeFSRefUnicodeSync (&fsRefPB);
    if(theErr != noErr) {
        error = "PBMakeFSRefUnicodeSync";
        goto bail;
    }
    
    

    theErr = FSGetDataForkName (&dataForkName);
    if (theErr != noErr) {
        error = "FSGetDataForkName";
        goto bail;
    }
    
    theErr = FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, fsRdPerm, &forkRefNum);
    if (theErr != noErr) {
        error = "FSOpenFork";
        goto bail;
    }
    
    theErr = FSGetForkSize (forkRefNum, &forkSize);
    if (theErr != noErr) {
        error = "FSGetForkSize";
        goto bail;
    }
    
    
    forkData = NewPtr (forkSize);
    if(forkData == NULL) {
        error = "NewPtr";
        goto bail;
    }
    
    theErr = FSReadFork (forkRefNum, fsFromStart, 0 , forkSize, forkData, &actualRead);
    if(theErr != noErr) {
        error = "FSReadFork";
        goto bail;
    }
    
    dataRef = CFDataCreate (kCFAllocatorDefault, (UInt8 *)forkData, forkSize);
    if(dataRef == 0) {
        error = "CFDataCreate";
        goto bail;
    }

    propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault,
                                                       dataRef,
                                                       kCFPropertyListImmutable,
                                                       NULL);
    if (propertyListRef == NULL) {
        error = "CFPropertyListCreateFromXMLData";
        goto bail;
    }

    
    
    
    if(CFGetTypeID(propertyListRef)== CFDictionaryGetTypeID())
    {
        CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef;
        
        CFDataRef   theRawTOCDataRef;
        CFArrayRef  theSessionArrayRef;
        CFIndex     numSessions;
        CFIndex     index;
        
        
        theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString));
        
        
        theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString));
        
        
        numSessions = CFArrayGetCount (theSessionArrayRef);
        
        
        theCD->numtracks = 0;
        
        
        for(index = 0; index < numSessions; index++)
        {
            CFDictionaryRef theSessionDict;
            CFNumberRef     leadoutBlock;
            CFArrayRef      trackArray;
            CFIndex         numTracks;
            CFIndex         trackIndex;
            UInt32          value = 0;
            
            theSessionDict      = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index);
            leadoutBlock        = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString));
            
            trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString));
            
            numTracks = CFArrayGetCount (trackArray);

            for(trackIndex = 0; trackIndex < numTracks; trackIndex++) {
                    
                CFDictionaryRef theTrackDict;
                CFNumberRef     trackNumber;
                CFNumberRef     sessionNumber;
                CFNumberRef     startBlock;
                CFBooleanRef    isDataTrack;
                UInt32          value;
                
                theTrackDict  = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex);
                
                trackNumber   = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString));
                sessionNumber = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString));
                startBlock    = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString));
                isDataTrack   = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString));
                                                        
                
                int idx = theCD->numtracks++;

                CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value);
                theCD->track[idx].id = value;
                
                CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value);
                theCD->track[idx].offset = value;

                theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK;

                
                if (trackIndex > 0) {
                    theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset;
                }
            }
            
            
            CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value);
            
            theCD->track[theCD->numtracks-1].length = 
                value - theCD->track[theCD->numtracks-1].offset;

            
            theCD->track[theCD->numtracks].offset = value;
        }
    
    }

    theErr = 0;
    goto cleanup;
bail:
    SDL_SetError ("ReadTOCData: %s returned %d", error, theErr);
    theErr = -1;
cleanup:

    if (propertyListRef != NULL)
        CFRelease(propertyListRef);
    if (dataRef != NULL)
        CFRelease(dataRef);
    if (forkData != NULL)
        DisposePtr(forkData);
        
    FSCloseFork (forkRefNum);

    return theErr;
}
Пример #7
0
static int
SNDIO_OpenDevice(_THIS, const char *devname, int iscapture)
{
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    struct sio_par par;
    int status;

    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc(sizeof(*this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, sizeof(*this->hidden));

    this->hidden->mixlen = this->spec.size;

    /* !!! FIXME: SIO_DEVANY can be a specific device... */
    if ((this->hidden->dev = SNDIO_sio_open(NULL, SIO_PLAY, 0)) == NULL) {
        SNDIO_CloseDevice(this);
        return SDL_SetError("sio_open() failed");
    }

    SNDIO_sio_initpar(&par);

    par.rate = this->spec.freq;
    par.pchan = this->spec.channels;
    par.round = this->spec.samples;
    par.appbufsz = par.round * 2;

    /* Try for a closest match on audio format */
    status = -1;
    while (test_format && (status < 0)) {
        if (!SDL_AUDIO_ISFLOAT(test_format)) {
            par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0;
            par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0;
            par.bits = SDL_AUDIO_BITSIZE(test_format);

            if (SNDIO_sio_setpar(this->hidden->dev, &par) == 1) {
                status = 0;
                break;
            }
        }
        test_format = SDL_NextAudioFormat();
    }

    if (status < 0) {
        SNDIO_CloseDevice(this);
        return SDL_SetError("sndio: Couldn't find any hardware audio formats");
    }

    if (SNDIO_sio_getpar(this->hidden->dev, &par) == 0) {
        SNDIO_CloseDevice(this);
        return SDL_SetError("sio_getpar() failed");
    }

    if ((par.bits == 32) && (par.sig) && (par.le))
        this->spec.format = AUDIO_S32LSB;
    else if ((par.bits == 32) && (par.sig) && (!par.le))
        this->spec.format = AUDIO_S32MSB;
    else if ((par.bits == 16) && (par.sig) && (par.le))
        this->spec.format = AUDIO_S16LSB;
    else if ((par.bits == 16) && (par.sig) && (!par.le))
        this->spec.format = AUDIO_S16MSB;
    else if ((par.bits == 16) && (!par.sig) && (par.le))
        this->spec.format = AUDIO_U16LSB;
    else if ((par.bits == 16) && (!par.sig) && (!par.le))
        this->spec.format = AUDIO_U16MSB;
    else if ((par.bits == 8) && (par.sig))
        this->spec.format = AUDIO_S8;
    else if ((par.bits == 8) && (!par.sig))
        this->spec.format = AUDIO_U8;
    else {
        SNDIO_CloseDevice(this);
        return SDL_SetError("sndio: Got unsupported hardware audio format.");
    }

    this->spec.freq = par.rate;
    this->spec.channels = par.pchan;
    this->spec.samples = par.round;

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        SNDIO_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);

    if (!SNDIO_sio_start(this->hidden->dev)) {
        return SDL_SetError("sio_start() failed");
    }

    /* We're ready to rock and roll. :-) */
    return 0;
}
Пример #8
0
/**
 * \brief Start, open, close and stop audio
 *
 * \sa https://wiki.libsdl.org/SDL_InitAudio
 * \sa https://wiki.libsdl.org/SDL_OpenAudio
 * \sa https://wiki.libsdl.org/SDL_CloseAudio
 * \sa https://wiki.libsdl.org/SDL_QuitAudio
 */
int audio_initOpenCloseQuitAudio()
{
    int result, expectedResult;
    int i, iMax, j, k;
    const char* audioDriver;
    SDL_AudioSpec desired;

    /* Stop SDL audio subsystem */
    SDL_QuitSubSystem( SDL_INIT_AUDIO );
        SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");

        /* Loop over all available audio drivers */
        iMax = SDL_GetNumAudioDrivers();
        SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
        SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
        for (i = 0; i < iMax; i++) {
            audioDriver = SDL_GetAudioDriver(i);
            SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
            SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL");
            SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver);

            /* Change specs */
            for (j = 0; j < 2; j++) {

                /* Call Init */
                result = SDL_AudioInit(audioDriver);
                SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
                SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);

                /* Set spec */
                SDL_memset(&desired, 0, sizeof(desired));
                switch (j) {
                    case 0:
                    /* Set standard desired spec */
                    desired.freq = 22050;
                    desired.format = AUDIO_S16SYS;
                    desired.channels = 2;
                    desired.samples = 4096;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;

                    case 1:
                    /* Set custom desired spec */
                    desired.freq = 48000;
                    desired.format = AUDIO_F32SYS;
                    desired.channels = 2;
                    desired.samples = 2048;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;
                    break;
            }

            /* Call Open (maybe multiple times) */
            for (k=0; k <= j; k++) {
                result = SDL_OpenAudio(&desired, NULL);
                SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL), call %d", j, k+1);
                expectedResult = (k==0) ? 0 : -1;
                SDLTest_AssertCheck(result == expectedResult, "Verify return value; expected: %d, got: %d", expectedResult, result);
            }

            /* Call Close (maybe multiple times) */
            for (k=0; k <= j; k++) {
                SDL_CloseAudio();
                SDLTest_AssertPass("Call to SDL_CloseAudio(), call %d", k+1);
            }

            /* Call Quit (maybe multiple times) */
            for (k=0; k <= j; k++) {
                SDL_AudioQuit();
                SDLTest_AssertPass("Call to SDL_AudioQuit(), call %d", k+1);
            }

        } /* spec loop */
    } /* driver loop */

        /* Restart audio again */
        _audioSetUp(NULL);

    return TEST_COMPLETED;
}
Пример #9
0
/**
 * \brief Pause and unpause audio
 *
 * \sa https://wiki.libsdl.org/SDL_PauseAudio
 */
int audio_pauseUnpauseAudio()
{
    int result;
    int i, iMax, j, k, l;
    int totalDelay;
    int pause_on;
    int originalCounter;
    const char* audioDriver;
    SDL_AudioSpec desired;

    /* Stop SDL audio subsystem */
    SDL_QuitSubSystem( SDL_INIT_AUDIO );
        SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");

        /* Loop over all available audio drivers */
        iMax = SDL_GetNumAudioDrivers();
        SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
        SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
        for (i = 0; i < iMax; i++) {
            audioDriver = SDL_GetAudioDriver(i);
            SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
            SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL");
            SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver);

            /* Change specs */
            for (j = 0; j < 2; j++) {

                /* Call Init */
                result = SDL_AudioInit(audioDriver);
                SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
                SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);

                /* Set spec */
                SDL_memset(&desired, 0, sizeof(desired));
                switch (j) {
                    case 0:
                    /* Set standard desired spec */
                    desired.freq = 22050;
                    desired.format = AUDIO_S16SYS;
                    desired.channels = 2;
                    desired.samples = 4096;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;

                    case 1:
                    /* Set custom desired spec */
                    desired.freq = 48000;
                    desired.format = AUDIO_F32SYS;
                    desired.channels = 2;
                    desired.samples = 2048;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;
                    break;
            }

            /* Call Open */
            result = SDL_OpenAudio(&desired, NULL);
            SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL)", j);
            SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0 got: %d", result);

            /* Start and stop audio multiple times */
            for (l=0; l<3; l++) {
                SDLTest_Log("Pause/Unpause iteration: %d", l+1);
            
                /* Reset callback counters */
                _audio_testCallbackCounter = 0;
                _audio_testCallbackLength = 0;

                /* Un-pause audio to start playing (maybe multiple times) */
                pause_on = 0;
                for (k=0; k <= j; k++) {
                    SDL_PauseAudio(pause_on);
                    SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1);
                }
            
                /* Wait for callback */
                totalDelay = 0;
                do {
                    SDL_Delay(10);
                    totalDelay += 10;
                } 
                while (_audio_testCallbackCounter == 0 && totalDelay < 1000);
                SDLTest_AssertCheck(_audio_testCallbackCounter > 0, "Verify callback counter; expected: >0 got: %d", _audio_testCallbackCounter);
                SDLTest_AssertCheck(_audio_testCallbackLength > 0, "Verify callback length; expected: >0 got: %d", _audio_testCallbackLength);

                /* Pause audio to stop playing (maybe multiple times) */
                for (k=0; k <= j; k++) {
                    pause_on = (k==0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999);
                    SDL_PauseAudio(pause_on);
                    SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1);
                }
            
                /* Ensure callback is not called again */
                originalCounter = _audio_testCallbackCounter;
                SDL_Delay(totalDelay + 10);
                SDLTest_AssertCheck(originalCounter == _audio_testCallbackCounter, "Verify callback counter; expected: %d, got: %d", originalCounter, _audio_testCallbackCounter);
            }

            /* Call Close */
            SDL_CloseAudio();
            SDLTest_AssertPass("Call to SDL_CloseAudio()");

            /* Call Quit */
            SDL_AudioQuit();
            SDLTest_AssertPass("Call to SDL_AudioQuit()");

        } /* spec loop */
    } /* driver loop */

    /* Restart audio again */
    _audioSetUp(NULL);

    return TEST_COMPLETED;
}
Пример #10
0
static int
DCAUD_OpenDevice(_THIS, SDL_AudioSpec * spec)
{
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
    int valid_datatype = 0;

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    spu_init();

    while ((!valid_datatype) && (test_format)) {
        spec->format = test_format;
        switch (test_format) {
            /* only formats Dreamcast accepts... */
        case AUDIO_S8:
        case AUDIO_S16LSB:
            valid_datatype = 1;
            break;

        default:
            test_format = SDL_NextAudioFormat();
            break;
        }
    }

    if (!valid_datatype) {      /* shouldn't happen, but just in case... */
        DCAUD_CloseDevice(this);
        SDL_SetError("Unsupported audio format");
        return 0;
    }

    if (spec->channels > 2)
        spec->channels = 2;     /* no more than stereo on the Dreamcast. */

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(spec);

    /* Allocate mixing buffer */
    this->hidden->mixlen = spec->size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        DCAUD_CloseDevice(this);
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
    this->hidden->leftpos = 0x11000;
    this->hidden->rightpos = 0x11000 + spec->size;
    this->hidden->playing = 0;
    this->hidden->nextbuf = 0;

    /* We're ready to rock and roll. :-) */
    return 1;
}
Пример #11
0
/*
 * Create an empty RGB surface of the appropriate depth
 */
SDL_Surface * SDL_CreateRGBSurface (Uint32 flags,
			int width, int height, int depth,
			Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
	SDL_Surface *surface;

	/* Make sure the size requested doesn't overflow our datatypes */
	/* Next time I write a library like SDL, I'll use int for size. :) */
	if ( width >= 16384 || height >= 65536 ) {
		SDL_SetError("Width or height is too large");
		return(NULL);
	}

	flags &= ~SDL_HWSURFACE;

	/* Allocate the surface */
	surface = (SDL_Surface *)SDL_malloc(sizeof(*surface));
	if (!surface)
   {
		SDL_OutOfMemory();
		return(NULL);
	}
	surface->flags = SDL_SWSURFACE;

	surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
	if (!surface->format)
   {
		SDL_free(surface);
		return(NULL);
	}

	if (Amask)
		surface->flags |= SDL_SRCALPHA;
	surface->w = width;
	surface->h = height;
	surface->pitch = SDL_CalculatePitch(surface);
	surface->pixels = NULL;
	surface->offset = 0;
	surface->hwdata = NULL;
	surface->locked = 0;
	surface->map = NULL;
	surface->unused1 = 0;
	SDL_SetClipRect(surface, NULL);
	SDL_FormatChanged(surface);

	/* Get the pixels */
	if ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE))
   {
      if ( surface->w && surface->h )
      {
         surface->pixels = SDL_malloc(surface->h*surface->pitch);
         if (!surface->pixels)
         {
            SDL_FreeSurface(surface);
            SDL_OutOfMemory();
            return(NULL);
         }
         /* This is important for bitmaps */
         SDL_memset(surface->pixels, 0, surface->h*surface->pitch);
      }
   }

	/* Allocate an empty mapping */
	surface->map = SDL_AllocBlitMap();
	if (!surface->map)
   {
      SDL_FreeSurface(surface);
      return(NULL);
   }

	/* The surface is ready to go */
	surface->refcount = 1;
	return(surface);
}
Пример #12
0
static int
PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture)
{
    int format, mixlen, i;
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc(sizeof(*this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
    switch (this->spec.format & 0xff) {
        case 8:
        case 16:
            this->spec.format = AUDIO_S16LSB;
            break;
        default:
            return SDL_SetError("Unsupported audio format");
    }

    /* The sample count must be a multiple of 64. */
    this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples);
    this->spec.freq = 44100;

    /* Update the fragment size as size in bytes. */
/*  SDL_CalculateAudioSpec(this->spec); MOD */
    switch (this->spec.format) {
    case AUDIO_U8:
        this->spec.silence = 0x80;
        break;
    default:
        this->spec.silence = 0x00;
        break;
    }
    this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
    this->spec.size *= this->spec.channels;
    this->spec.size *= this->spec.samples;

/* ========================================== */

    /* Allocate the mixing buffer.  Its size and starting address must
       be a multiple of 64 bytes.  Our sample count is already a multiple of
       64, so spec->size should be a multiple of 64 as well. */
    mixlen = this->spec.size * NUM_BUFFERS;
    this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
    if (this->hidden->rawbuf == NULL) {
        return SDL_SetError("Couldn't allocate mixing buffer");
    }

    /* Setup the hardware channel. */
    if (this->spec.channels == 1) {
        format = PSP_AUDIO_FORMAT_MONO;
    } else {
        format = PSP_AUDIO_FORMAT_STEREO;
    }
    this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format);
    if (this->hidden->channel < 0) {
        free(this->hidden->rawbuf);
        this->hidden->rawbuf = NULL;
        return SDL_SetError("Couldn't reserve hardware channel");
    }

    memset(this->hidden->rawbuf, 0, mixlen);
    for (i = 0; i < NUM_BUFFERS; i++) {
        this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
    }

    this->hidden->next_buffer = 0;
    return 0;
}
static int
BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
    SDL_AudioFormat format = 0;
    audio_info_t info;

    /* We don't care what the devname is...we'll try to open anything. */
    /*  ...but default to first name in the list... */
    if (devname == NULL) {
        devname = SDL_GetAudioDeviceName(0, iscapture);
        if (devname == NULL) {
            return SDL_SetError("No such audio device");
        }
    }

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    /* Open the audio device */
    this->hidden->audio_fd = open(devname, flags, 0);
    if (this->hidden->audio_fd < 0) {
        return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
    }

    AUDIO_INITINFO(&info);

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    /* Set to play mode */
    info.mode = AUMODE_PLAY;
    if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
        BSDAUDIO_CloseDevice(this);
        return SDL_SetError("Couldn't put device into play mode");
    }

    AUDIO_INITINFO(&info);
    for (format = SDL_FirstAudioFormat(this->spec.format);
         format; format = SDL_NextAudioFormat()) {
        switch (format) {
        case AUDIO_U8:
            info.play.encoding = AUDIO_ENCODING_ULINEAR;
            info.play.precision = 8;
            break;
        case AUDIO_S8:
            info.play.encoding = AUDIO_ENCODING_SLINEAR;
            info.play.precision = 8;
            break;
        case AUDIO_S16LSB:
            info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
            info.play.precision = 16;
            break;
        case AUDIO_S16MSB:
            info.play.encoding = AUDIO_ENCODING_SLINEAR_BE;
            info.play.precision = 16;
            break;
        case AUDIO_U16LSB:
            info.play.encoding = AUDIO_ENCODING_ULINEAR_LE;
            info.play.precision = 16;
            break;
        case AUDIO_U16MSB:
            info.play.encoding = AUDIO_ENCODING_ULINEAR_BE;
            info.play.precision = 16;
            break;
        default:
            continue;
        }

        if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
            break;
        }
    }

    if (!format) {
        BSDAUDIO_CloseDevice(this);
        return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
    }

    this->spec.format = format;

    AUDIO_INITINFO(&info);
    info.play.channels = this->spec.channels;
    if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) {
        this->spec.channels = 1;
    }
    AUDIO_INITINFO(&info);
    info.play.sample_rate = this->spec.freq;
    info.blocksize = this->spec.size;
    info.hiwat = 5;
    info.lowat = 3;
    (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info);
    (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info);
    this->spec.freq = info.play.sample_rate;
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        BSDAUDIO_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);

    BSDAUDIO_Status(this);

    /* We're ready to rock and roll. :-) */
    return 0;
}
Пример #14
0
static int
WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
{
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    int valid_datatype = 0;
    MMRESULT result;
    WAVEFORMATEX waveformat;
    UINT_PTR devId = WAVE_MAPPER;  /* WAVE_MAPPER == choose system's default */
    char *utf8 = NULL;
    int i;

    if (devname != NULL) {  /* specific device requested? */
        if (iscapture) {
            const int devcount = (int) waveInGetNumDevs();
            WAVEINCAPS caps;
            for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
                result = waveInGetDevCaps(i, &caps, sizeof (caps));
                if (result != MMSYSERR_NOERROR)
                    continue;
                else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
                    continue;
                else if (SDL_strcmp(devname, utf8) == 0)
                    devId = (UINT_PTR) i;
                SDL_free(utf8);
            }
        } else {
            const int devcount = (int) waveOutGetNumDevs();
            WAVEOUTCAPS caps;
            for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
                result = waveOutGetDevCaps(i, &caps, sizeof (caps));
                if (result != MMSYSERR_NOERROR)
                    continue;
                else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
                    continue;
                else if (SDL_strcmp(devname, utf8) == 0)
                    devId = (UINT_PTR) i;
                SDL_free(utf8);
            }
        }

        if (devId == WAVE_MAPPER) {
            return SDL_SetError("Requested device not found");
        }
    }

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    /* Initialize the wavebuf structures for closing */
    for (i = 0; i < NUM_BUFFERS; ++i)
        this->hidden->wavebuf[i].dwUser = 0xFFFF;

    if (this->spec.channels > 2)
        this->spec.channels = 2;        /* !!! FIXME: is this right? */

    /* Check the buffer size -- minimum of 1/4 second (word aligned) */
    if (this->spec.samples < (this->spec.freq / 4))
        this->spec.samples = ((this->spec.freq / 4) + 3) & ~3;

    while ((!valid_datatype) && (test_format)) {
        switch (test_format) {
        case AUDIO_U8:
        case AUDIO_S16:
        case AUDIO_S32:
        case AUDIO_F32:
            this->spec.format = test_format;
            if (PrepWaveFormat(this, devId, &waveformat, iscapture)) {
                valid_datatype = 1;
            } else {
                test_format = SDL_NextAudioFormat();
            }
            break;

        default:
            test_format = SDL_NextAudioFormat();
            break;
        }
    }

    if (!valid_datatype) {
        WINMM_CloseDevice(this);
        return SDL_SetError("Unsupported audio format");
    }

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&this->spec);

    /* Open the audio device */
    if (iscapture) {
        result = waveInOpen(&this->hidden->hin, devId, &waveformat,
                             (DWORD_PTR) CaptureSound, (DWORD_PTR) this,
                             CALLBACK_FUNCTION);
    } else {
        result = waveOutOpen(&this->hidden->hout, devId, &waveformat,
                             (DWORD_PTR) FillSound, (DWORD_PTR) this,
                             CALLBACK_FUNCTION);
    }

    if (result != MMSYSERR_NOERROR) {
        WINMM_CloseDevice(this);
        return SetMMerror("waveOutOpen()", result);
    }
#ifdef SOUND_DEBUG
    /* Check the sound device we retrieved */
    {
        WAVEOUTCAPS caps;

        result = waveOutGetDevCaps((UINT) this->hidden->hout,
                                   &caps, sizeof(caps));
        if (result != MMSYSERR_NOERROR) {
            WINMM_CloseDevice(this);
            return SetMMerror("waveOutGetDevCaps()", result);
        }
        printf("Audio device: %s\n", caps.szPname);
    }
#endif

    /* Create the audio buffer semaphore */
    this->hidden->audio_sem =
        CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
    if (this->hidden->audio_sem == NULL) {
        WINMM_CloseDevice(this);
        return SDL_SetError("Couldn't create semaphore");
    }

    /* Create the sound buffers */
    this->hidden->mixbuf =
        (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
    if (this->hidden->mixbuf == NULL) {
        WINMM_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    for (i = 0; i < NUM_BUFFERS; ++i) {
        SDL_memset(&this->hidden->wavebuf[i], 0,
                   sizeof(this->hidden->wavebuf[i]));
        this->hidden->wavebuf[i].dwBufferLength = this->spec.size;
        this->hidden->wavebuf[i].dwFlags = WHDR_DONE;
        this->hidden->wavebuf[i].lpData =
            (LPSTR) & this->hidden->mixbuf[i * this->spec.size];
        result = waveOutPrepareHeader(this->hidden->hout,
                                      &this->hidden->wavebuf[i],
                                      sizeof(this->hidden->wavebuf[i]));
        if (result != MMSYSERR_NOERROR) {
            WINMM_CloseDevice(this);
            return SetMMerror("waveOutPrepareHeader()", result);
        }
    }

    return 0;                   /* Ready to go! */
}
Пример #15
0
/* This function tries to create a secondary audio buffer, and returns the
   number of audio chunks available in the created buffer.
*/
static int
CreateSecondary(_THIS, HWND focus)
{
    LPDIRECTSOUND sndObj = this->hidden->sound;
    LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
    Uint32 chunksize = this->spec.size;
    const int numchunks = 8;
    HRESULT result = DS_OK;
    DSBUFFERDESC format;
    LPVOID pvAudioPtr1, pvAudioPtr2;
    DWORD dwAudioBytes1, dwAudioBytes2;
    WAVEFORMATEX wfmt;

    SDL_zero(wfmt);

    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
        wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    } else {
        wfmt.wFormatTag = WAVE_FORMAT_PCM;
    }

    wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
    wfmt.nChannels = this->spec.channels;
    wfmt.nSamplesPerSec = this->spec.freq;
    wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
    wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&this->spec);

    /* Try to set primary mixing privileges */
    if (focus) {
        result = IDirectSound_SetCooperativeLevel(sndObj,
                                                  focus, DSSCL_PRIORITY);
    } else {
        result = IDirectSound_SetCooperativeLevel(sndObj,
                                                  GetDesktopWindow(),
                                                  DSSCL_NORMAL);
    }
    if (result != DS_OK) {
        return SetDSerror("DirectSound SetCooperativeLevel", result);
    }

    /* Try to create the secondary buffer */
    SDL_zero(format);
    format.dwSize = sizeof(format);
    format.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
    if (!focus) {
        format.dwFlags |= DSBCAPS_GLOBALFOCUS;
    } else {
        format.dwFlags |= DSBCAPS_STICKYFOCUS;
    }
    format.dwBufferBytes = numchunks * chunksize;
    if ((format.dwBufferBytes < DSBSIZE_MIN) ||
        (format.dwBufferBytes > DSBSIZE_MAX)) {
        return SDL_SetError("Sound buffer size must be between %d and %d",
                            DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks);
    }
    format.dwReserved = 0;
    format.lpwfxFormat = &wfmt;
    result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL);
    if (result != DS_OK) {
        return SetDSerror("DirectSound CreateSoundBuffer", result);
    }
    IDirectSoundBuffer_SetFormat(*sndbuf, &wfmt);

    /* Silence the initial audio buffer */
    result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
                                     (LPVOID *) & pvAudioPtr1, &dwAudioBytes1,
                                     (LPVOID *) & pvAudioPtr2, &dwAudioBytes2,
                                     DSBLOCK_ENTIREBUFFER);
    if (result == DS_OK) {
        SDL_memset(pvAudioPtr1, this->spec.silence, dwAudioBytes1);
        IDirectSoundBuffer_Unlock(*sndbuf,
                                  (LPVOID) pvAudioPtr1, dwAudioBytes1,
                                  (LPVOID) pvAudioPtr2, dwAudioBytes2);
    }

    /* We're ready to go */
    return (numchunks);
}
Пример #16
0
/* These are global for SDL_eventloop.c */
int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y)
{
 int posted;
 Uint16 X, Y;
 Sint16 Xrel;
 Sint16 Yrel;

 /* Default buttonstate is the current one */
 if ( ! buttonstate ) {
   buttonstate = SDL_ButtonState;
 }

 Xrel = x;
 Yrel = y;
 if ( relative ) {
   /* Push the cursor around */
   x = (SDL_MouseX+x);
   y = (SDL_MouseY+y);
 } else {
   /* Do we need to clip {x,y} ? */
   ClipOffset(&x, &y);
 }

 /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
 if ( x < 0 )
   X = 0;
 else
 if ( x >= SDL_MouseMaxX )
   X = SDL_MouseMaxX-1;
 else
   X = (Uint16)x;

 if ( y < 0 )
   Y = 0;
 else
 if ( y >= SDL_MouseMaxY )
   Y = SDL_MouseMaxY-1;
 else
   Y = (Uint16)y;

 /* If not relative mode, generate relative motion from clamped X/Y.
    This prevents lots of extraneous large delta relative motion when
    the screen is windowed mode and the mouse is outside the window.
 */
 if ( ! relative ) {
   Xrel = X-SDL_MouseX;
   Yrel = Y-SDL_MouseY;
 }

 /* Drop events that don't change state */
 if ( ! Xrel && ! Yrel ) {
#if 0
printf("Mouse event didn't change state - dropped!\n");
#endif
   return(0);
 }

 /* Update internal mouse state */
 SDL_ButtonState = buttonstate;
 SDL_MouseX = X;
 SDL_MouseY = Y;
 SDL_DeltaX += Xrel;
 SDL_DeltaY += Yrel;
        SDL_MoveCursor(SDL_MouseX, SDL_MouseY);

 /* Post the event, if desired */
 posted = 0;
 if ( SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE ) {
   SDL_Event event;
   SDL_memset(&event, 0, sizeof(event));
   event.type = SDL_MOUSEMOTION;
   event.motion.state = buttonstate;
   event.motion.x = X;
   event.motion.y = Y;
   event.motion.xrel = Xrel;
   event.motion.yrel = Yrel;
   if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
     posted = 1;
     SDL_PushEvent(&event);
   }
 }
 return(posted);
}
Пример #17
0
static int
DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
{
    HRESULT result;
    SDL_bool valid_format = SDL_FALSE;
    SDL_bool tried_format = SDL_FALSE;
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    FindDevGUIDData devguid;
    LPGUID guid = NULL;

    if (devname != NULL) {
        devguid.found = 0;
        devguid.devname = devname;
        if (iscapture)
            pDirectSoundCaptureEnumerateW(FindDevGUID, &devguid);
        else
            pDirectSoundEnumerateW(FindDevGUID, &devguid);

        if (!devguid.found) {
            return SDL_SetError("DirectSound: Requested device not found");
        }
        guid = &devguid.guid;
    }

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    /* Open the audio device */
    result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
    if (result != DS_OK) {
        DSOUND_CloseDevice(this);
        return SetDSerror("DirectSoundCreate", result);
    }

    while ((!valid_format) && (test_format)) {
        switch (test_format) {
        case AUDIO_U8:
        case AUDIO_S16:
        case AUDIO_S32:
        case AUDIO_F32:
            tried_format = SDL_TRUE;
            this->spec.format = test_format;
            this->hidden->num_buffers = CreateSecondary(this, NULL);
            if (this->hidden->num_buffers > 0) {
                valid_format = SDL_TRUE;
            }
            break;
        }
        test_format = SDL_NextAudioFormat();
    }

    if (!valid_format) {
        DSOUND_CloseDevice(this);
        if (tried_format) {
            return -1;  /* CreateSecondary() should have called SDL_SetError(). */
        }
        return SDL_SetError("DirectSound: Unsupported audio format");
    }

    /* The buffer will auto-start playing in DSOUND_WaitDevice() */
    this->hidden->mixlen = this->spec.size;

    return 0;                   /* good to go. */
}
Пример #18
0
int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y)
{
 SDL_Event event;
 int posted;
 int move_mouse;
 Uint8 buttonstate;

 SDL_memset(&event, 0, sizeof(event));

 /* Check parameters */
 if ( x || y ) {
   ClipOffset(&x, &y);
   move_mouse = 1;
   /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */
   if ( x < 0 )
     x = 0;
   else
   if ( x >= SDL_MouseMaxX )
     x = SDL_MouseMaxX-1;

   if ( y < 0 )
     y = 0;
   else
   if ( y >= SDL_MouseMaxY )
     y = SDL_MouseMaxY-1;
 } else {
   move_mouse = 0;
 }
 if ( ! x )
   x = SDL_MouseX;
 if ( ! y )
   y = SDL_MouseY;

 /* Figure out which event to perform */
 buttonstate = SDL_ButtonState;
 switch ( state ) {
   case SDL_PRESSED:
     event.type = SDL_MOUSEBUTTONDOWN;
     buttonstate |= SDL_BUTTON(button);
     break;
   case SDL_RELEASED:
     event.type = SDL_MOUSEBUTTONUP;
     buttonstate &= ~SDL_BUTTON(button);
     break;
   default:
     /* Invalid state -- bail */
     return(0);
 }

 /* Update internal mouse state */
 SDL_ButtonState = buttonstate;
 if ( move_mouse ) {
   SDL_MouseX = x;
   SDL_MouseY = y;
   SDL_MoveCursor(SDL_MouseX, SDL_MouseY);
 }

 /* Post the event, if desired */
 posted = 0;
 if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) {
   event.button.state = state;
   event.button.button = button;
   event.button.x = x;
   event.button.y = y;
   if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
     posted = 1;
     SDL_PushEvent(&event);
   }
 }
 return(posted);
}
Пример #19
0
static char *
IBus_GetDBusAddressFilename(void)
{
    SDL_DBusContext *dbus;
    const char *disp_env;
    char config_dir[PATH_MAX];
    char *display = NULL;
    const char *addr;
    const char *conf_env;
    char *key;
    char file_path[PATH_MAX];
    const char *host;
    char *disp_num, *screen_num;

    if (ibus_addr_file) {
        return SDL_strdup(ibus_addr_file);
    }
    
    dbus = SDL_DBus_GetContext();
    if (!dbus) {
        return NULL;
    }
    
    /* Use this environment variable if it exists. */
    addr = SDL_getenv("IBUS_ADDRESS");
    if (addr && *addr) {
        return SDL_strdup(addr);
    }
    
    /* Otherwise, we have to get the hostname, display, machine id, config dir
       and look up the address from a filepath using all those bits, eek. */
    disp_env = SDL_getenv("DISPLAY");

    if (!disp_env || !*disp_env) {
        display = SDL_strdup(":0.0");
    } else {
        display = SDL_strdup(disp_env);
    }
    
    host = display;
    disp_num   = SDL_strrchr(display, ':');
    screen_num = SDL_strrchr(display, '.');
    
    if (!disp_num) {
        SDL_free(display);
        return NULL;
    }
    
    *disp_num = 0;
    disp_num++;
    
    if (screen_num) {
        *screen_num = 0;
    }
    
    if (!*host) {
        host = "unix";
    }
        
    SDL_memset(config_dir, 0, sizeof(config_dir));
    
    conf_env = SDL_getenv("XDG_CONFIG_HOME");
    if (conf_env && *conf_env) {
        SDL_strlcpy(config_dir, conf_env, sizeof(config_dir));
    } else {
        const char *home_env = SDL_getenv("HOME");
        if (!home_env || !*home_env) {
            SDL_free(display);
            return NULL;
        }
        SDL_snprintf(config_dir, sizeof(config_dir), "%s/.config", home_env);
    }
    
    key = dbus->get_local_machine_id();

    SDL_memset(file_path, 0, sizeof(file_path));
    SDL_snprintf(file_path, sizeof(file_path), "%s/ibus/bus/%s-%s-%s", 
                                               config_dir, key, host, disp_num);
    dbus->free(key);
    SDL_free(display);
    
    return SDL_strdup(file_path);
}
Пример #20
0
static int
SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid)
{
    char threadName[32];
    XINPUT_VIBRATION vibration = { 0, 0 };  /* stop any current vibration */
    XINPUTSETSTATE(userid, &vibration);

    haptic->supported = SDL_HAPTIC_LEFTRIGHT;

    haptic->neffects = 1;
    haptic->nplaying = 1;

    /* Prepare effects memory. */
    haptic->effects = (struct haptic_effect *)
        SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
    if (haptic->effects == NULL) {
        return SDL_OutOfMemory();
    }
    /* Clear the memory */
    SDL_memset(haptic->effects, 0,
        sizeof(struct haptic_effect) * haptic->neffects);

    haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata));
    if (haptic->hwdata == NULL) {
        SDL_free(haptic->effects);
        haptic->effects = NULL;
        return SDL_OutOfMemory();
    }
    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));

    haptic->hwdata->bXInputHaptic = 1;
    haptic->hwdata->userid = userid;

    haptic->hwdata->mutex = SDL_CreateMutex();
    if (haptic->hwdata->mutex == NULL) {
        SDL_free(haptic->effects);
        SDL_free(haptic->hwdata);
        haptic->effects = NULL;
        return SDL_SetError("Couldn't create XInput haptic mutex");
    }

    SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", (int)userid);

#if defined(__WIN32__) && !defined(HAVE_LIBC)  /* !!! FIXME: this is nasty. */
#undef SDL_CreateThread
#if SDL_DYNAMIC_API
    haptic->hwdata->thread = SDL_CreateThread_REAL(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
#else
    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
#endif
#else
    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata);
#endif
    if (haptic->hwdata->thread == NULL) {
        SDL_DestroyMutex(haptic->hwdata->mutex);
        SDL_free(haptic->effects);
        SDL_free(haptic->hwdata);
        haptic->effects = NULL;
        return SDL_SetError("Couldn't create XInput haptic thread");
    }

    return 0;
}
Пример #21
0
static int
XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
{
    HRESULT result = S_OK;
    WAVEFORMATEX waveformat;
    int valid_format = 0;
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    IXAudio2 *ixa2 = NULL;
    IXAudio2SourceVoice *source = NULL;
    UINT32 devId = 0;  /* 0 == system default device. */

	static IXAudio2VoiceCallbackVtbl callbacks_vtable = {
	    VoiceCBOnVoiceProcessPassStart,
        VoiceCBOnVoiceProcessPassEnd,
        VoiceCBOnStreamEnd,
        VoiceCBOnBufferStart,
        VoiceCBOnBufferEnd,
        VoiceCBOnLoopEnd,
        VoiceCBOnVoiceError
	};

	static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };

    if (iscapture) {
        return SDL_SetError("XAudio2: capture devices unsupported.");
    } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
        return SDL_SetError("XAudio2: XAudio2Create() failed.");
    }

    if (devname != NULL) {
        UINT32 devcount = 0;
        UINT32 i = 0;

        if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
            IXAudio2_Release(ixa2);
            return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
        }
        for (i = 0; i < devcount; i++) {
            XAUDIO2_DEVICE_DETAILS details;
            if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
                char *str = utf16_to_utf8(details.DisplayName);
                if (str != NULL) {
                    const int match = (SDL_strcmp(str, devname) == 0);
                    SDL_free(str);
                    if (match) {
                        devId = i;
                        break;
                    }
                }
            }
        }

        if (i == devcount) {
            IXAudio2_Release(ixa2);
            return SDL_SetError("XAudio2: Requested device not found.");
        }
    }

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        IXAudio2_Release(ixa2);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

    this->hidden->ixa2 = ixa2;
    this->hidden->semaphore = CreateSemaphore(NULL, 1, 2, NULL);
    if (this->hidden->semaphore == NULL) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: CreateSemaphore() failed!");
    }

    while ((!valid_format) && (test_format)) {
        switch (test_format) {
        case AUDIO_U8:
        case AUDIO_S16:
        case AUDIO_S32:
        case AUDIO_F32:
            this->spec.format = test_format;
            valid_format = 1;
            break;
        }
        test_format = SDL_NextAudioFormat();
    }

    if (!valid_format) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Unsupported audio format");
    }

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&this->spec);

    /* We feed a Source, it feeds the Mastering, which feeds the device. */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        XAUDIO2_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    this->hidden->nextbuf = this->hidden->mixbuf;
    SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);

    /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
       Xbox360, this means 5.1 output, but on Windows, it means "figure out
       what the system has." It might be preferable to let XAudio2 blast
       stereo output to appropriate surround sound configurations
       instead of clamping to 2 channels, even though we'll configure the
       Source Voice for whatever number of channels you supply. */
    result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering,
                                           XAUDIO2_DEFAULT_CHANNELS,
                                           this->spec.freq, 0, devId, NULL);
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't create mastering voice");
    }

    SDL_zero(waveformat);
    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
        waveformat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    } else {
        waveformat.wFormatTag = WAVE_FORMAT_PCM;
    }
    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
    waveformat.nChannels = this->spec.channels;
    waveformat.nSamplesPerSec = this->spec.freq;
    waveformat.nBlockAlign =
        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
    waveformat.nAvgBytesPerSec =
        waveformat.nSamplesPerSec * waveformat.nBlockAlign;

    result = IXAudio2_CreateSourceVoice(ixa2, &source, &waveformat,
                                        XAUDIO2_VOICE_NOSRC |
                                        XAUDIO2_VOICE_NOPITCH,
                                        1.0f, &callbacks, NULL, NULL);
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't create source voice");
    }
    this->hidden->source = source;

    /* Start everything playing! */
    result = IXAudio2_StartEngine(ixa2);
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't start engine");
    }

    result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't start source voice");
    }

    return 0; /* good to go. */
}
Пример #22
0
static SDL_VideoDevice *DIB_CreateDevice(int devindex)
{
	SDL_VideoDevice *device;

	/* Initialize all variables that we clean on shutdown */
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
	if ( device ) {
		SDL_memset(device, 0, (sizeof *device));
		device->hidden = (struct SDL_PrivateVideoData *)
				SDL_malloc((sizeof *device->hidden));
		device->gl_data = (struct SDL_PrivateGLData *)
				SDL_malloc((sizeof *device->gl_data));
	}
	if ( (device == NULL) || (device->hidden == NULL) ||
		                 (device->gl_data == NULL) ) {
		SDL_OutOfMemory();
		DIB_DeleteDevice(device);
		return(NULL);
	}
	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
	SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));

	/* Set the function pointers */
	device->VideoInit = DIB_VideoInit;
	device->ListModes = DIB_ListModes;
	device->SetVideoMode = DIB_SetVideoMode;
	device->UpdateMouse = WIN_UpdateMouse;
	device->SetColors = DIB_SetColors;
	device->UpdateRects = NULL;
	device->VideoQuit = DIB_VideoQuit;
	device->AllocHWSurface = DIB_AllocHWSurface;
	device->CheckHWBlit = NULL;
	device->FillHWRect = NULL;
	device->SetHWColorKey = NULL;
	device->SetHWAlpha = NULL;
	device->LockHWSurface = DIB_LockHWSurface;
	device->UnlockHWSurface = DIB_UnlockHWSurface;
	device->FlipHWSurface = NULL;
	device->FreeHWSurface = DIB_FreeHWSurface;
	device->SetGammaRamp = DIB_SetGammaRamp;
	device->GetGammaRamp = DIB_GetGammaRamp;
#if SDL_VIDEO_OPENGL
	device->GL_LoadLibrary = WIN_GL_LoadLibrary;
	device->GL_GetProcAddress = WIN_GL_GetProcAddress;
	device->GL_GetAttribute = WIN_GL_GetAttribute;
	device->GL_MakeCurrent = WIN_GL_MakeCurrent;
	device->GL_SwapBuffers = WIN_GL_SwapBuffers;
#endif
	device->SetCaption = WIN_SetWMCaption;
	device->SetIcon = WIN_SetWMIcon;
	device->IconifyWindow = WIN_IconifyWindow;
	device->GrabInput = WIN_GrabInput;
	device->GetWMInfo = WIN_GetWMInfo;
	device->FreeWMCursor = WIN_FreeWMCursor;
	device->CreateWMCursor = WIN_CreateWMCursor;
	device->ShowWMCursor = WIN_ShowWMCursor;
	device->WarpWMCursor = WIN_WarpWMCursor;
	device->CheckMouseMode = WIN_CheckMouseMode;
	device->InitOSKeymap = DIB_InitOSKeymap;
	device->PumpEvents = DIB_PumpEvents;

    device->GetWindowPos = DIB_GetWinPos;
    device->SetWindowPos = DIB_SetWinPos;
    device->IsWindowVisible = DIB_IsWinVisible;
    device->GetMonitorDPI = DIB_GetMonitorDPI;
    device->GetMonitorRect = DIB_GetMonitorRect;

	/* Set up the windows message handling functions */
	WIN_Activate = DIB_Activate;
	WIN_RealizePalette = DIB_RealizePalette;
	WIN_PaletteChanged = DIB_PaletteChanged;
	WIN_WinPAINT = DIB_WinPAINT;
	HandleMessage = DIB_HandleMessage;

	device->free = DIB_DeleteDevice;

	/* We're finally ready */
	return device;
}
Пример #23
0
static int DX5_DInputInit(_THIS)
{
	int         i;
	LPDIRECTINPUTDEVICE device;
	HRESULT     result;
	DIPROPDWORD dipdw;
	HWND        topwnd;

	/* Create the DirectInput object */
	result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
							&dinput, NULL);
	if ( result != DI_OK ) {
		SetDIerror("DirectInputCreate", result);
		return(-1);
	}

	/* Create all of our registered input devices */
	SDL_DIndev = 0;
	for ( i=0; inputs[i].name; ++i ) {
		/* Create the DirectInput device */
		result = IDirectInput_CreateDevice(dinput, inputs[i].guid,
								&device, NULL);
		if ( result != DI_OK ) {
			SetDIerror("DirectInput::CreateDevice", result);
			return(-1);
		}
		result = IDirectInputDevice_QueryInterface(device,
			&IID_IDirectInputDevice2, (LPVOID *)&SDL_DIdev[i]);
		IDirectInputDevice_Release(device);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::QueryInterface", result);
			return(-1);
		}
		topwnd =  GetTopLevelParent(SDL_Window);
		result = IDirectInputDevice2_SetCooperativeLevel(SDL_DIdev[i],
					topwnd, inputs[i].win_level);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetCooperativeLevel",
									result);
			return(-1);
		}
		result = IDirectInputDevice2_SetDataFormat(SDL_DIdev[i],
							inputs[i].format);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetDataFormat", result);
			return(-1);
		}

		/* Set buffered input -- we aren't polling */
		SDL_memset(&dipdw, 0, sizeof(dipdw));
		dipdw.diph.dwSize = sizeof(dipdw);
		dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
		dipdw.diph.dwObj = 0;
		dipdw.diph.dwHow = DIPH_DEVICE;
		dipdw.dwData = INPUT_QSIZE;
		result = IDirectInputDevice2_SetProperty(SDL_DIdev[i],
						DIPROP_BUFFERSIZE, &dipdw.diph);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetProperty", result);
			return(-1);
		}

		/* Create an event to be signaled when input is ready */
		SDL_DIevt[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
		if ( SDL_DIevt[i] == NULL ) {
			SDL_SetError("Couldn't create DirectInput event");
			return(-1);
		}
		result = IDirectInputDevice2_SetEventNotification(SDL_DIdev[i],
								SDL_DIevt[i]);
		if ( result != DI_OK ) {
			SetDIerror("DirectInputDevice::SetEventNotification",
									result);
			return(-1);
		}
		SDL_DIfun[i] = inputs[i].fun;

		/* Acquire the device for input */
		IDirectInputDevice2_Acquire(SDL_DIdev[i]);

		/* Increment the number of devices we have */
		++SDL_DIndev;
	}
	mouse_pressed = 0;
	mouse_buttons_swapped = GetSystemMetrics(SM_SWAPBUTTON);

	/* DirectInput is ready! */
	return(0);
}
Пример #24
0
SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
				int width, int height, int bpp, Uint32 flags)
{
	SDL_Surface *video;
	int prev_w, prev_h;
	Uint32 prev_flags;
	DWORD style;
	const DWORD directstyle =
			(WS_POPUP);
	const DWORD windowstyle =
			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
	const DWORD resizestyle =
			(WS_THICKFRAME|WS_MAXIMIZEBOX);
	int binfo_size;
	BITMAPINFO *binfo;
	HDC hdc;
	RECT bounds;
	int x, y;
	Uint32 Rmask, Gmask, Bmask;

	/* Clean up any GL context that may be hanging around */
	if ( current->flags & SDL_OPENGL ) {
		WIN_GL_ShutDown(this);
	}
	SDL_resizing = 1;

	/* Recalculate the bitmasks if necessary */
	if ( bpp == current->format->BitsPerPixel ) {
		video = current;
	} else {
		switch (bpp) {
			case 15:
			case 16:
				if ( DIB_SussScreenDepth() == 15 ) {
					/* 5-5-5 */
					Rmask = 0x00007c00;
					Gmask = 0x000003e0;
					Bmask = 0x0000001f;
				} else {
					/* 5-6-5 */
					Rmask = 0x0000f800;
					Gmask = 0x000007e0;
					Bmask = 0x0000001f;
				}
				break;
			case 24:
			case 32:
				/* GDI defined as 8-8-8 */
				Rmask = 0x00ff0000;
				Gmask = 0x0000ff00;
				Bmask = 0x000000ff;
				break;
			default:
				Rmask = 0x00000000;
				Gmask = 0x00000000;
				Bmask = 0x00000000;
				break;
		}
		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
					0, 0, bpp, Rmask, Gmask, Bmask, 0);
		if ( video == NULL ) {
			SDL_OutOfMemory();
			return(NULL);
		}
	}

	/* Fill in part of the video surface */
	prev_flags = video->flags;
	prev_w = video->w;
	prev_h = video->h;
	video->flags = 0;	/* Clear flags */
	video->w = width;
	video->h = height;
	video->pitch = SDL_CalculatePitch(video);

	/* Small fix for WinCE/Win32 - when activating window
	   SDL_VideoSurface is equal to zero, so activating code
	   is not called properly for fullscreen windows because
	   macros WINDIB_FULLSCREEN uses SDL_VideoSurface
	*/
	SDL_VideoSurface = video;

#if defined(_WIN32_WCE)
	if ( flags & SDL_FULLSCREEN )
		video->flags |= SDL_FULLSCREEN;
#endif

#ifndef NO_CHANGEDISPLAYSETTINGS
	/* Set fullscreen mode if appropriate */
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
		DEVMODE settings;
		BOOL changed;

		SDL_memset(&settings, 0, sizeof(DEVMODE));
		settings.dmSize = sizeof(DEVMODE);

#ifdef _WIN32_WCE
		// try to rotate screen to fit requested resolution
		if( this->hidden->supportRotation )
		{
			DWORD rotation;

			// ask current mode
			settings.dmFields = DM_DISPLAYORIENTATION;
			ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
			rotation = settings.dmDisplayOrientation;

			if( (width > GetDeviceCaps(GetDC(NULL), HORZRES))
				&& (height < GetDeviceCaps(GetDC(NULL), VERTRES)))
			{
				switch( rotation )
				{
				case DMDO_0:
					settings.dmDisplayOrientation = DMDO_90;
					break;
				case DMDO_270:
					settings.dmDisplayOrientation = DMDO_180;
					break;
				}
				if( settings.dmDisplayOrientation != rotation )
				{
					// go to landscape
					this->hidden->origRotation = rotation;
					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
				}
			}
			if( (width < GetDeviceCaps(GetDC(NULL), HORZRES))
				&& (height > GetDeviceCaps(GetDC(NULL), VERTRES)))
			{
				switch( rotation )
				{
				case DMDO_90:
					settings.dmDisplayOrientation = DMDO_0;
					break;
				case DMDO_180:
					settings.dmDisplayOrientation = DMDO_270;
					break;
				}
				if( settings.dmDisplayOrientation != rotation )
				{
					// go to portrait
					this->hidden->origRotation = rotation;
					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
				}
			}

		}
#endif

#ifndef _WIN32_WCE
		settings.dmBitsPerPel = video->format->BitsPerPixel;
		settings.dmPelsWidth = width;
		settings.dmPelsHeight = height;
		settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
		if ( width <= (int)SDL_desktop_mode.dmPelsWidth &&
		     height <= (int)SDL_desktop_mode.dmPelsHeight ) {
			settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
			settings.dmFields |= DM_DISPLAYFREQUENCY;
		}
		changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
		if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) {
			settings.dmFields &= ~DM_DISPLAYFREQUENCY;
			changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
		}
#else
		changed = 1;
#endif
		if ( changed ) {
			video->flags |= SDL_FULLSCREEN;
			SDL_fullscreen_mode = settings;
		}

	}
#endif /* !NO_CHANGEDISPLAYSETTINGS */

	/* Reset the palette and create a new one if necessary */
	if ( grab_palette ) {
		DIB_ReleaseStaticColors(SDL_Window);
		grab_palette = FALSE;
	}
	if ( screen_pal != NULL ) {
	/*	RJR: March 28, 2000
		delete identity palette if switching from a palettized mode */
		DeleteObject(screen_pal);
		screen_pal = NULL;
	}
	if ( screen_logpal != NULL ) {
		SDL_free(screen_logpal);
		screen_logpal = NULL;
	}

	if ( bpp <= 8 )
	{
	/*	RJR: March 28, 2000
		create identity palette switching to a palettized mode */
		DIB_CreatePalette(this, bpp);
	}

	style = GetWindowLong(SDL_Window, GWL_STYLE);
	style &= ~(resizestyle|WS_MAXIMIZE);
	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
		style &= ~windowstyle;
		style |= directstyle;
	} else {
#ifndef NO_CHANGEDISPLAYSETTINGS
		if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
			ChangeDisplaySettings(NULL, 0);
		}
#endif
		if ( flags & SDL_NOFRAME ) {
			style &= ~windowstyle;
			style |= directstyle;
			video->flags |= SDL_NOFRAME;
		} else {
			style &= ~directstyle;
			style |= windowstyle;
			if ( flags & SDL_RESIZABLE ) {
				style |= resizestyle;
				video->flags |= SDL_RESIZABLE;
			}
		}
#if WS_MAXIMIZE
		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
#endif
	}

	/* DJM: Don't piss of anyone who has setup his own window */
	if ( !SDL_windowid )
		SetWindowLong(SDL_Window, GWL_STYLE, style);

	/* Delete the old bitmap if necessary */
	if ( screen_bmp != NULL ) {
		DeleteObject(screen_bmp);
	}
	if ( ! (flags & SDL_OPENGL) ) {
		BOOL is16bitmode = (video->format->BytesPerPixel == 2);

		/* Suss out the bitmap info header */
		binfo_size = sizeof(*binfo);
		if( is16bitmode ) {
			/* 16bit modes, palette area used for rgb bitmasks */
			binfo_size += 3*sizeof(DWORD);
		} else if ( video->format->palette ) {
			binfo_size += video->format->palette->ncolors *
							sizeof(RGBQUAD);
		}
		binfo = (BITMAPINFO *)SDL_malloc(binfo_size);
		if ( ! binfo ) {
			if ( video != current ) {
				SDL_FreeSurface(video);
			}
			SDL_OutOfMemory();
			return(NULL);
		}

		binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		binfo->bmiHeader.biWidth = video->w;
		binfo->bmiHeader.biHeight = -video->h;	/* -ve for topdown bitmap */
		binfo->bmiHeader.biPlanes = 1;
		binfo->bmiHeader.biSizeImage = video->h * video->pitch;
		binfo->bmiHeader.biXPelsPerMeter = 0;
		binfo->bmiHeader.biYPelsPerMeter = 0;
		binfo->bmiHeader.biClrUsed = 0;
		binfo->bmiHeader.biClrImportant = 0;
		binfo->bmiHeader.biBitCount = video->format->BitsPerPixel;

		if ( is16bitmode ) {
			/* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */
			binfo->bmiHeader.biCompression = BI_BITFIELDS;
			((Uint32*)binfo->bmiColors)[0] = video->format->Rmask;
			((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
			((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
		} else {
			binfo->bmiHeader.biCompression = BI_RGB;	/* BI_BITFIELDS for 565 vs 555 */
			if ( video->format->palette ) {
				SDL_memset(binfo->bmiColors, 0,
					video->format->palette->ncolors*sizeof(RGBQUAD));
			}
		}

		/* Create the offscreen bitmap buffer */
		hdc = GetDC(SDL_Window);
		screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
					(void **)(&video->pixels), NULL, 0);
		ReleaseDC(SDL_Window, hdc);
		SDL_free(binfo);
		if ( screen_bmp == NULL ) {
			if ( video != current ) {
				SDL_FreeSurface(video);
			}
			SDL_SetError("Couldn't create DIB section");
			return(NULL);
		}
		this->UpdateRects = DIB_NormalUpdate;

		/* Set video surface flags */
		if ( screen_pal && (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) ) {
			grab_palette = TRUE;
		}
		/* BitBlt() maps colors for us */
		video->flags |= SDL_HWPALETTE;
	}
#ifndef _WIN32_WCE
	/* Resize the window */
	if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
#else
	if ( !SDL_windowid ) {
#endif
		HWND top;
		UINT swp_flags;
		const char *window = NULL;
		const char *center = NULL;

		if ( video->w != prev_w || video->h != prev_h ) {
			window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
			center = SDL_getenv("SDL_VIDEO_CENTERED");
			if ( window ) {
				if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
					SDL_windowX = x;
					SDL_windowY = y;
				}
				if ( SDL_strcmp(window, "center") == 0 ) {
					center = window;
				}
			}
		}
		swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);

		bounds.left = SDL_windowX;
		bounds.top = SDL_windowY;
		bounds.right = SDL_windowX+video->w;
		bounds.bottom = SDL_windowY+video->h;
#ifndef _WIN32_WCE
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
#else
		// The bMenu parameter must be FALSE; menu bars are not supported
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), 0, 0);
#endif
		width = bounds.right-bounds.left;
		height = bounds.bottom-bounds.top;
		if ( (flags & SDL_FULLSCREEN) ) {
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
		} else if ( center ) {
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
		} else if ( SDL_windowX || SDL_windowY || window ) {
			x = bounds.left;
			y = bounds.top;
		} else {
			x = y = -1;
			swp_flags |= SWP_NOMOVE;
		}
		if ( flags & SDL_FULLSCREEN ) {
			top = HWND_TOPMOST;
		} else {
			top = HWND_NOTOPMOST;
		}
		SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
		if ( !(flags & SDL_FULLSCREEN) ) {
			SDL_windowX = SDL_bounds.left;
			SDL_windowY = SDL_bounds.top;
		}
		SetForegroundWindow(SDL_Window);
	}
	SDL_resizing = 0;

	/* Set up for OpenGL */
	if ( flags & SDL_OPENGL ) {
		if ( WIN_GL_SetupWindow(this) < 0 ) {
			return(NULL);
		}
		video->flags |= SDL_OPENGL;
	}

	/* JC 14 Mar 2006
		Flush the message loop or this can cause big problems later
		Especially if the user decides to use dialog boxes or assert()!
	*/
	WIN_FlushMessageQueue();

	/* We're live! */
	return(video);
}

/* We don't actually allow hardware surfaces in the DIB driver */
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface)
{
	return(-1);
}
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
{
	return(0);
}
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
{
	HDC hdc, mdc;
	int i;

	hdc = GetDC(SDL_Window);
	if ( screen_pal ) {
		SelectPalette(hdc, screen_pal, FALSE);
	}
	mdc = CreateCompatibleDC(hdc);
	SelectObject(mdc, screen_bmp);
	for ( i=0; i<numrects; ++i ) {
		BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
					mdc, rects[i].x, rects[i].y, SRCCOPY);
	}
	DeleteDC(mdc);
	ReleaseDC(SDL_Window, hdc);
}
Пример #25
0
/*
 * Initializes the haptic subsystem.
 */
int
SDL_SYS_HapticInit(void)
{
    int numhaptics;
    IOReturn result;
    io_iterator_t iter;
    CFDictionaryRef match;
    io_service_t device;
    CFMutableDictionaryRef hidProperties;
    CFTypeRef refCF;

    /* Clear all the memory. */
    SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist));

    /* Get HID devices. */
    match = IOServiceMatching(kIOHIDDeviceKey);
    if (match == NULL) {
        SDL_SetError("Haptic: Failed to get IOServiceMatching.");
        return -1;
    }

    /* Now search I/O Registry for matching devices. */
    result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter);
    if (result != kIOReturnSuccess) {
        SDL_SetError("Haptic: Couldn't create a HID object iterator.");
        return -1;
    }
    /* IOServiceGetMatchingServices consumes dictionary. */

    if (!IOIteratorIsValid(iter)) {     /* No iterator. */
        numhaptics = 0;
        return 0;
    }

    numhaptics = 0;
    while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) {

        /* Check for force feedback. */
        if (FFIsForceFeedback(device) == FF_OK) {

            /* Set basic device data. */
            HIDGetDeviceProduct(device, SDL_hapticlist[numhaptics].name);
            SDL_hapticlist[numhaptics].dev = device;
            SDL_hapticlist[numhaptics].haptic = NULL;

            /* Set usage pages. */
            hidProperties = 0;
            refCF = 0;
            result = IORegistryEntryCreateCFProperties(device,
                                                       &hidProperties,
                                                       kCFAllocatorDefault,
                                                       kNilOptions);
            if ((result == KERN_SUCCESS) && hidProperties) {
                refCF =
                    CFDictionaryGetValue(hidProperties,
                                         CFSTR(kIOHIDPrimaryUsagePageKey));
                if (refCF) {
                    if (!CFNumberGetValue(refCF, kCFNumberLongType,
                                          &SDL_hapticlist[numhaptics].
                                          usagePage))
                        SDL_SetError
                            ("Haptic: Recieving device's usage page.");
                    refCF =
                        CFDictionaryGetValue(hidProperties,
                                             CFSTR(kIOHIDPrimaryUsageKey));
                    if (refCF) {
                        if (!CFNumberGetValue(refCF, kCFNumberLongType,
                                              &SDL_hapticlist[numhaptics].
                                              usage))
                            SDL_SetError("Haptic: Recieving device's usage.");
                    }
                }
                CFRelease(hidProperties);
            }

            /* Device has been added. */
            numhaptics++;
        } else {                /* Free the unused device. */
            IOObjectRelease(device);
        }

        /* Reached haptic limit. */
        if (numhaptics >= MAX_HAPTICS)
            break;
    }
    IOObjectRelease(iter);

    return numhaptics;
}
Пример #26
0
static SDL_VideoDevice *X11_CreateDevice(int devindex)
{
	SDL_VideoDevice *device = NULL;

	if ( SDL_X11_LoadSymbols() ) {
		/* Initialize all variables that we clean on shutdown */
		device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
		if ( device ) {
			SDL_memset(device, 0, (sizeof *device));
			device->hidden = (struct SDL_PrivateVideoData *)
					SDL_malloc((sizeof *device->hidden));
			SDL_memset(device->hidden, 0, (sizeof *device->hidden));
			device->gl_data = (struct SDL_PrivateGLData *)
					SDL_malloc((sizeof *device->gl_data));
			SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
		}
		if ( (device == NULL) || (device->hidden == NULL) ||
		                         (device->gl_data == NULL) ) {
			SDL_OutOfMemory();
			X11_DeleteDevice(device); /* calls SDL_X11_UnloadSymbols(). */
			return(0);
		}
		SDL_memset(device->hidden, 0, (sizeof *device->hidden));
		SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));

		/* Set the driver flags */
		device->handles_any_size = 1;

		/* Set the function pointers */
		device->VideoInit = X11_VideoInit;
		device->ListModes = X11_ListModes;
		device->SetVideoMode = X11_SetVideoMode;
		device->ToggleFullScreen = X11_ToggleFullScreen;
		device->UpdateMouse = X11_UpdateMouse;
#if SDL_VIDEO_DRIVER_X11_XV
		device->CreateYUVOverlay = X11_CreateYUVOverlay;
#endif
		device->SetColors = X11_SetColors;
		device->UpdateRects = NULL;
		device->VideoQuit = X11_VideoQuit;
		device->AllocHWSurface = X11_AllocHWSurface;
		device->CheckHWBlit = NULL;
		device->FillHWRect = NULL;
		device->SetHWColorKey = NULL;
		device->SetHWAlpha = NULL;
		device->LockHWSurface = X11_LockHWSurface;
		device->UnlockHWSurface = X11_UnlockHWSurface;
		device->FlipHWSurface = X11_FlipHWSurface;
		device->FreeHWSurface = X11_FreeHWSurface;
		device->SetGamma = X11_SetVidModeGamma;
		device->GetGamma = X11_GetVidModeGamma;
		device->SetGammaRamp = X11_SetGammaRamp;
		device->GetGammaRamp = NULL;
#if SDL_VIDEO_OPENGL_GLX
		device->GL_LoadLibrary = X11_GL_LoadLibrary;
		device->GL_GetProcAddress = X11_GL_GetProcAddress;
		device->GL_GetAttribute = X11_GL_GetAttribute;
		device->GL_MakeCurrent = X11_GL_MakeCurrent;
		device->GL_SwapBuffers = X11_GL_SwapBuffers;
#endif
		device->SetCaption = X11_SetCaption;
		device->SetIcon = X11_SetIcon;
		device->IconifyWindow = X11_IconifyWindow;
		device->GrabInput = X11_GrabInput;
		device->GetWMInfo = X11_GetWMInfo;
		device->FreeWMCursor = X11_FreeWMCursor;
		device->CreateWMCursor = X11_CreateWMCursor;
		device->ShowWMCursor = X11_ShowWMCursor;
		device->WarpWMCursor = X11_WarpWMCursor;
		device->CheckMouseMode = X11_CheckMouseMode;
		device->InitOSKeymap = X11_InitOSKeymap;
		device->PumpEvents = X11_PumpEvents;

		device->free = X11_DeleteDevice;
	}

	return device;
}
Пример #27
0
/*
 * Creates the FFEFFECT from a SDL_HapticEffect.
 */
static int
SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest,
                   SDL_HapticEffect * src)
{
    int i;
    FFCONSTANTFORCE *constant;
    FFPERIODIC *periodic;
    FFCONDITION *condition;     /* Actually an array of conditions - one per axis. */
    FFRAMPFORCE *ramp;
    FFCUSTOMFORCE *custom;
    FFENVELOPE *envelope;
    SDL_HapticConstant *hap_constant;
    SDL_HapticPeriodic *hap_periodic;
    SDL_HapticCondition *hap_condition;
    SDL_HapticRamp *hap_ramp;
    SDL_HapticCustom *hap_custom;
    DWORD *axes;

    /* Set global stuff. */
    SDL_memset(dest, 0, sizeof(FFEFFECT));
    dest->dwSize = sizeof(FFEFFECT);    /* Set the structure size. */
    dest->dwSamplePeriod = 0;   /* Not used by us. */
    dest->dwGain = 10000;       /* Gain is set globally, not locally. */
    dest->dwFlags = FFEFF_OBJECTOFFSETS;        /* Seems obligatory. */

    /* Envelope. */
    envelope = SDL_malloc(sizeof(FFENVELOPE));
    if (envelope == NULL) {
        SDL_OutOfMemory();
        return -1;
    }
    SDL_memset(envelope, 0, sizeof(FFENVELOPE));
    dest->lpEnvelope = envelope;
    envelope->dwSize = sizeof(FFENVELOPE);      /* Always should be this. */

    /* Axes. */
    dest->cAxes = haptic->naxes;
    if (dest->cAxes > 0) {
        axes = SDL_malloc(sizeof(DWORD) * dest->cAxes);
        if (axes == NULL) {
            SDL_OutOfMemory();
            return -1;
        }
        axes[0] = haptic->hwdata->axes[0];      /* Always at least one axis. */
        if (dest->cAxes > 1) {
            axes[1] = haptic->hwdata->axes[1];
        }
        if (dest->cAxes > 2) {
            axes[2] = haptic->hwdata->axes[2];
        }
        dest->rgdwAxes = axes;
    }


    /* The big type handling switch, even bigger then linux's version. */
    switch (src->type) {
    case SDL_HAPTIC_CONSTANT:
        hap_constant = &src->constant;
        constant = SDL_malloc(sizeof(FFCONSTANTFORCE));
        if (constant == NULL) {
            SDL_OutOfMemory();
            return -1;
        }
        SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE));

        /* Specifics */
        constant->lMagnitude = CONVERT(hap_constant->level);
        dest->cbTypeSpecificParams = sizeof(FFCONSTANTFORCE);
        dest->lpvTypeSpecificParams = constant;

        /* Generics */
        dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_constant->button);
        dest->dwTriggerRepeatInterval = hap_constant->interval;
        dest->dwStartDelay = hap_constant->delay * 1000;        /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_constant->attack_length == 0)
            && (hap_constant->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_constant->attack_level);
            envelope->dwAttackTime = hap_constant->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_constant->fade_level);
            envelope->dwFadeTime = hap_constant->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_SINE:
    case SDL_HAPTIC_SQUARE:
    case SDL_HAPTIC_TRIANGLE:
    case SDL_HAPTIC_SAWTOOTHUP:
    case SDL_HAPTIC_SAWTOOTHDOWN:
        hap_periodic = &src->periodic;
        periodic = SDL_malloc(sizeof(FFPERIODIC));
        if (periodic == NULL) {
            SDL_OutOfMemory();
            return -1;
        }
        SDL_memset(periodic, 0, sizeof(FFPERIODIC));

        /* Specifics */
        periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
        periodic->lOffset = CONVERT(hap_periodic->offset);
        periodic->dwPhase = hap_periodic->phase;
        periodic->dwPeriod = hap_periodic->period * 1000;
        dest->cbTypeSpecificParams = sizeof(FFPERIODIC);
        dest->lpvTypeSpecificParams = periodic;

        /* Generics */
        dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_periodic->button);
        dest->dwTriggerRepeatInterval = hap_periodic->interval;
        dest->dwStartDelay = hap_periodic->delay * 1000;        /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_periodic->attack_length == 0)
            && (hap_periodic->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_periodic->attack_level);
            envelope->dwAttackTime = hap_periodic->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_periodic->fade_level);
            envelope->dwFadeTime = hap_periodic->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_SPRING:
    case SDL_HAPTIC_DAMPER:
    case SDL_HAPTIC_INERTIA:
    case SDL_HAPTIC_FRICTION:
        hap_condition = &src->condition;
        condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes);
        if (condition == NULL) {
            SDL_OutOfMemory();
            return -1;
        }
        SDL_memset(condition, 0, sizeof(FFCONDITION));

        /* Specifics */
        for (i = 0; i < dest->cAxes; i++) {
            condition[i].lOffset = CONVERT(hap_condition->center[i]);
            condition[i].lPositiveCoefficient =
                CONVERT(hap_condition->right_coeff[i]);
            condition[i].lNegativeCoefficient =
                CONVERT(hap_condition->left_coeff[i]);
            condition[i].dwPositiveSaturation =
                CCONVERT(hap_condition->right_sat[i]);
            condition[i].dwNegativeSaturation =
                CCONVERT(hap_condition->left_sat[i]);
            condition[i].lDeadBand = CCONVERT(hap_condition->deadband[i]);
        }
        dest->cbTypeSpecificParams = sizeof(FFCONDITION) * dest->cAxes;
        dest->lpvTypeSpecificParams = condition;

        /* Generics */
        dest->dwDuration = hap_condition->length * 1000;        /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_condition->button);
        dest->dwTriggerRepeatInterval = hap_condition->interval;
        dest->dwStartDelay = hap_condition->delay * 1000;       /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes)
            < 0) {
            return -1;
        }

        /* Envelope - Not actually supported by most CONDITION implementations. */
        SDL_free(dest->lpEnvelope);
        dest->lpEnvelope = NULL;

        break;

    case SDL_HAPTIC_RAMP:
        hap_ramp = &src->ramp;
        ramp = SDL_malloc(sizeof(FFRAMPFORCE));
        if (ramp == NULL) {
            SDL_OutOfMemory();
            return -1;
        }
        SDL_memset(ramp, 0, sizeof(FFRAMPFORCE));

        /* Specifics */
        ramp->lStart = CONVERT(hap_ramp->start);
        ramp->lEnd = CONVERT(hap_ramp->end);
        dest->cbTypeSpecificParams = sizeof(FFRAMPFORCE);
        dest->lpvTypeSpecificParams = ramp;

        /* Generics */
        dest->dwDuration = hap_ramp->length * 1000;     /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_ramp->button);
        dest->dwTriggerRepeatInterval = hap_ramp->interval;
        dest->dwStartDelay = hap_ramp->delay * 1000;    /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) {
            return -1;
        }

        /* Envelope */
        if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_ramp->attack_level);
            envelope->dwAttackTime = hap_ramp->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_ramp->fade_level);
            envelope->dwFadeTime = hap_ramp->fade_length * 1000;
        }

        break;

    case SDL_HAPTIC_CUSTOM:
        hap_custom = &src->custom;
        custom = SDL_malloc(sizeof(FFCUSTOMFORCE));
        if (custom == NULL) {
            SDL_OutOfMemory();
            return -1;
        }
        SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE));

        /* Specifics */
        custom->cChannels = hap_custom->channels;
        custom->dwSamplePeriod = hap_custom->period * 1000;
        custom->cSamples = hap_custom->samples;
        custom->rglForceData =
            SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels);
        for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) {      /* Copy data. */
            custom->rglForceData[i] = CCONVERT(hap_custom->data[i]);
        }
        dest->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE);
        dest->lpvTypeSpecificParams = custom;

        /* Generics */
        dest->dwDuration = hap_custom->length * 1000;   /* In microseconds. */
        dest->dwTriggerButton = FFGetTriggerButton(hap_custom->button);
        dest->dwTriggerRepeatInterval = hap_custom->interval;
        dest->dwStartDelay = hap_custom->delay * 1000;  /* In microseconds. */

        /* Direction. */
        if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) <
            0) {
            return -1;
        }

        /* Envelope */
        if ((hap_custom->attack_length == 0)
            && (hap_custom->fade_length == 0)) {
            SDL_free(envelope);
            dest->lpEnvelope = NULL;
        } else {
            envelope->dwAttackLevel = CCONVERT(hap_custom->attack_level);
            envelope->dwAttackTime = hap_custom->attack_length * 1000;
            envelope->dwFadeLevel = CCONVERT(hap_custom->fade_level);
            envelope->dwFadeTime = hap_custom->fade_length * 1000;
        }

        break;


    default:
        SDL_SetError("Haptic: Unknown effect type.");
        return -1;
    }

    return 0;
}
Пример #28
0
/* Create auxiliary (toplevel) windows with the current visual */
static void create_aux_windows(_THIS)
{
    int x = 0, y = 0;
    char classname[1024];
    XSetWindowAttributes xattr;
    XWMHints *hints;
    unsigned long app_event_mask;
    int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));

    /* Look up some useful Atoms */
    WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);

    /* Don't create any extra windows if we are being managed */
    if ( SDL_windowid ) {
	FSwindow = 0;
	WMwindow = SDL_strtol(SDL_windowid, NULL, 0);
        return;
    }

    if(FSwindow)
	XDestroyWindow(SDL_Display, FSwindow);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    if ( use_xinerama ) {
        x = xinerama_info.x_org;
        y = xinerama_info.y_org;
    }
#endif
    xattr.override_redirect = True;
    xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
    xattr.border_pixel = 0;
    xattr.colormap = SDL_XColorMap;

    FSwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x, y, 32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWOverrideRedirect | CWBackPixel | CWBorderPixel
			     | CWColormap,
			     &xattr);

    XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);

    /* Tell KDE to keep the fullscreen window on top */
    {
	XEvent ev;
	long mask;

	SDL_memset(&ev, 0, sizeof(ev));
	ev.xclient.type = ClientMessage;
	ev.xclient.window = SDL_Root;
	ev.xclient.message_type = XInternAtom(SDL_Display,
					      "KWM_KEEP_ON_TOP", False);
	ev.xclient.format = 32;
	ev.xclient.data.l[0] = FSwindow;
	ev.xclient.data.l[1] = CurrentTime;
	mask = SubstructureRedirectMask;
	XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
    }

    hints = NULL;
    if(WMwindow) {
	/* All window attributes must survive the recreation */
	hints = XGetWMHints(SDL_Display, WMwindow);
	XDestroyWindow(SDL_Display, WMwindow);
    }

    /* Create the window for windowed management */
    /* (reusing the xattr structure above) */
    WMwindow = XCreateWindow(SDL_Display, SDL_Root,
                             x, y, 32, 32, 0,
			     this->hidden->depth, InputOutput, SDL_Visual,
			     CWBackPixel | CWBorderPixel | CWColormap,
			     &xattr);

    /* Set the input hints so we get keyboard input */
    if(!hints) {
	hints = XAllocWMHints();
	hints->input = True;
	hints->flags = InputHint;
    }
    XSetWMHints(SDL_Display, WMwindow, hints);
    XFree(hints);
    X11_SetCaptionNoLock(this, this->wm_title, this->wm_icon);

    app_event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask
	| PropertyChangeMask | StructureNotifyMask | KeymapStateMask;
    XSelectInput(SDL_Display, WMwindow, app_event_mask);

    /* Set the class hints so we can get an icon (AfterStep) */
    get_classname(classname, sizeof(classname));
    {
	XClassHint *classhints;
	classhints = XAllocClassHint();
	if(classhints != NULL) {
	    classhints->res_name = classname;
	    classhints->res_class = classname;
	    XSetClassHint(SDL_Display, WMwindow, classhints);
	    XFree(classhints);
	}
    }

	/* Setup the communication with the IM server */
	/* create_aux_windows may be called several times against the same
	   Display.  We should reuse the SDL_IM if one has been opened for
	   the Display, so we should not simply reset SDL_IM here.  */

	#ifdef X_HAVE_UTF8_STRING
	if (SDL_X11_HAVE_UTF8) {
		/* Discard obsolete resources if any.  */
		if (SDL_IM != NULL && SDL_Display != XDisplayOfIM(SDL_IM)) {
			/* Just a double check. I don't think this
		           code is ever executed. */
			SDL_SetError("display has changed while an IM is kept");
			if (SDL_IC) {
				XUnsetICFocus(SDL_IC);
				XDestroyIC(SDL_IC);
				SDL_IC = NULL;
			}
			XCloseIM(SDL_IM);
			SDL_IM = NULL;
		}

		/* Open an input method.  */
		if (SDL_IM == NULL) {
			char *old_locale = NULL, *old_modifiers = NULL;
			const char *p;
			size_t n;
			/* I'm not comfortable to do locale setup
			   here.  However, we need C library locale
			   (and xlib modifiers) to be set based on the
			   user's preference to use XIM, and many
			   existing game programs doesn't take care of
			   users' locale preferences, so someone other
			   than the game program should do it.
			   Moreover, ones say that some game programs
			   heavily rely on the C locale behaviour,
			   e.g., strcol()'s, and we can't change the C
			   library locale.  Given the situation, I
			   couldn't find better place to do the
			   job... */

			/* Save the current (application program's)
			   locale settings.  */
			p = setlocale(LC_ALL, NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_locale = SDL_stack_alloc(char, n);
				if ( old_locale ) {
					SDL_strlcpy(old_locale, p, n);
				}
			}
			p = XSetLocaleModifiers(NULL);
			if ( p ) {
				n = SDL_strlen(p)+1;
				old_modifiers = SDL_stack_alloc(char, n);
				if ( old_modifiers ) {
					SDL_strlcpy(old_modifiers, p, n);
				}
			}

			/* Fetch the user's preferences and open the
			   input method with them.  */
			setlocale(LC_ALL, "");
			XSetLocaleModifiers("");
			SDL_IM = XOpenIM(SDL_Display, NULL, classname, classname);

			/* Restore the application's locale settings
			   so that we don't break the application's
			   expected behaviour.  */
			if ( old_locale ) {
				/* We need to restore the C library
				   locale first, since the
				   interpretation of the X modifier
				   may depend on it.  */
				setlocale(LC_ALL, old_locale);
				SDL_stack_free(old_locale);
			}
			if ( old_modifiers ) {
				XSetLocaleModifiers(old_modifiers);
				SDL_stack_free(old_modifiers);
			}
		}

		/* Create a new input context for the new window just created.  */
		if (SDL_IM == NULL) {
			SDL_SetError("no input method could be opened");
		} else {
			if (SDL_IC != NULL) {
				/* Discard the old IC before creating new one.  */
			    XUnsetICFocus(SDL_IC);
			    XDestroyIC(SDL_IC);
			}
			/* Theoretically we should check the current IM supports
			   PreeditNothing+StatusNothing style (i.e., root window method)
			   before creating the IC.  However, it is the bottom line method,
			   and we supports any other options.  If the IM didn't support
			   root window method, the following call fails, and SDL falls
			   back to pre-XIM keyboard handling.  */
			SDL_IC = pXCreateIC(SDL_IM,
					XNClientWindow, WMwindow,
					XNFocusWindow, WMwindow,
					XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
					XNResourceName, classname,
					XNResourceClass, classname,
					NULL);

			if (SDL_IC == NULL) {
				SDL_SetError("no input context could be created");
				XCloseIM(SDL_IM);
				SDL_IM = NULL;
			} else {
				/* We need to receive X events that an IM wants and to pass
				   them to the IM through XFilterEvent. The set of events may
				   vary depending on the IM implementation and the options
				   specified through various routes. Although unlikely, the
				   xlib specification allows IM to change the event requirement
				   with its own circumstances, it is safe to call SelectInput
				   whenever we re-create an IC.  */
				unsigned long mask = 0;
				char *ret = pXGetICValues(SDL_IC, XNFilterEvents, &mask, NULL);
				if (ret != NULL) {
					XUnsetICFocus(SDL_IC);
					XDestroyIC(SDL_IC);
					SDL_IC = NULL;
					SDL_SetError("no input context could be created");
					XCloseIM(SDL_IM);
					SDL_IM = NULL;
				} else {
					XSelectInput(SDL_Display, WMwindow, app_event_mask | mask);
					XSetICFocus(SDL_IC);
				}
			}
		}
	}
Пример #29
0
static void NTO_PlayAudio(_THIS)
{
    int written, rval;
    int towrite;
    void* pcmbuffer;

    if (!this->enabled)
    {
        return;
    }
    
    towrite = this->spec.size;
    pcmbuffer = pcm_buf;

    /* Write the audio data, checking for EAGAIN (buffer full) and underrun */
    do {
        written = snd_pcm_plugin_write(audio_handle, pcm_buf, towrite);
        if (written != towrite)
        {
            if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
            {
                /* Let a little CPU time go by and try to write again */
                SDL_Delay(1);
                /* if we wrote some data */
                towrite -= written;
                pcmbuffer += written * this->spec.channels;
                continue;
            }		
            else
            {
                if ((errno == EINVAL) || (errno == EIO))
                {
                    SDL_memset(&cstatus, 0, sizeof(cstatus));
                    cstatus.channel = SND_PCM_CHANNEL_PLAYBACK;
                    if ((rval = snd_pcm_plugin_status(audio_handle, &cstatus)) < 0)
                    {
                        SDL_SetError("NTO_PlayAudio(): snd_pcm_plugin_status failed: %s\n", snd_strerror(rval));
                        return;
                    }	
                    if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || (cstatus.status == SND_PCM_STATUS_READY))
                    {
                        if ((rval = snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0)
                        {
                            SDL_SetError("NTO_PlayAudio(): snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rval));
                            return;
                        }
                    }		        		
                    continue;
                }
                else
                {
                    return;
                }
            }
        }
        else
        {
            /* we wrote all remaining data */
            towrite -= written;
            pcmbuffer += written * this->spec.channels;
        }
    } while ((towrite > 0)  && (this->enabled));

    /* If we couldn't write, assume fatal error for now */
    if (towrite != 0)
    {
        this->enabled = 0;
    }

    return;
}
Пример #30
0
/*
 * Open a joystick for use - the index passed as an argument refers to
 * the N'th joystick on the system.  This index is the value which will
 * identify this joystick in future joystick events.
 *
 * This function returns a joystick identifier, or NULL if an error occurred.
 */
SDL_Joystick *
SDL_JoystickOpen(int device_index)
{
    SDL_Joystick *joystick;
    SDL_Joystick *joysticklist;
    const char *joystickname = NULL;

    if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
        SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
        return (NULL);
    }

    joysticklist = SDL_joysticks;
    /* If the joystick is already open, return it
    * it is important that we have a single joystick * for each instance id
    */
    while (joysticklist) {
        if (SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == joysticklist->instance_id) {
                joystick = joysticklist;
                ++joystick->ref_count;
                return (joystick);
        }
        joysticklist = joysticklist->next;
    }

    /* Create and initialize the joystick */
    joystick = (SDL_Joystick *) SDL_malloc((sizeof *joystick));
    if (joystick == NULL) {
        SDL_OutOfMemory();
        return NULL;
    }

    SDL_memset(joystick, 0, (sizeof *joystick));
    if (SDL_SYS_JoystickOpen(joystick, device_index) < 0) {
        SDL_free(joystick);
        return NULL;
    }

    joystickname = SDL_SYS_JoystickNameForDeviceIndex(device_index);
    if (joystickname)
        joystick->name = SDL_strdup(joystickname);
    else
        joystick->name = NULL;

    if (joystick->naxes > 0) {
        joystick->axes = (Sint16 *) SDL_malloc
            (joystick->naxes * sizeof(Sint16));
    }
    if (joystick->nhats > 0) {
        joystick->hats = (Uint8 *) SDL_malloc
            (joystick->nhats * sizeof(Uint8));
    }
    if (joystick->nballs > 0) {
        joystick->balls = (struct balldelta *) SDL_malloc
            (joystick->nballs * sizeof(*joystick->balls));
    }
    if (joystick->nbuttons > 0) {
        joystick->buttons = (Uint8 *) SDL_malloc
            (joystick->nbuttons * sizeof(Uint8));
    }
    if (((joystick->naxes > 0) && !joystick->axes)
        || ((joystick->nhats > 0) && !joystick->hats)
        || ((joystick->nballs > 0) && !joystick->balls)
        || ((joystick->nbuttons > 0) && !joystick->buttons)) {
        SDL_OutOfMemory();
        SDL_JoystickClose(joystick);
        return NULL;
    }
    if (joystick->axes) {
        SDL_memset(joystick->axes, 0, joystick->naxes * sizeof(Sint16));
    }
    if (joystick->hats) {
        SDL_memset(joystick->hats, 0, joystick->nhats * sizeof(Uint8));
    }
    if (joystick->balls) {
        SDL_memset(joystick->balls, 0,
            joystick->nballs * sizeof(*joystick->balls));
    }
    if (joystick->buttons) {
        SDL_memset(joystick->buttons, 0, joystick->nbuttons * sizeof(Uint8));
    }
    joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;

    /* Add joystick to list */
    ++joystick->ref_count;
    /* Link the joystick in the list */
    joystick->next = SDL_joysticks;
    SDL_joysticks = joystick;

    SDL_SYS_JoystickUpdate(joystick);

    return (joystick);
}