Skip to content

Commit

Permalink
winepulse.drv: Implement pulse_get_loopback_capture_device().
Browse files Browse the repository at this point in the history
CW-Bug-Id: #23934
  • Loading branch information
Paul Gofman authored and ivyl committed Jun 20, 2024
1 parent e6497c8 commit 089de15
Showing 1 changed file with 110 additions and 2 deletions.
112 changes: 110 additions & 2 deletions dlls/winepulse.drv/pulse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2227,6 +2227,89 @@ static NTSTATUS pulse_is_format_supported(void *args)
return STATUS_SUCCESS;
}

static void sink_name_info_cb(pa_context *c, const pa_sink_info *i, int eol, void *userdata)
{
uint32_t *current_device_index = userdata;
pulse_broadcast();

if (!i || !i->name || !i->name[0])
return;
*current_device_index = i->index;
}

struct find_monitor_of_sink_cb_param
{
struct get_loopback_capture_device_params *params;
uint32_t current_device_index;
};

static void find_monitor_of_sink_cb(pa_context *c, const pa_source_info *i, int eol, void *userdata)
{
struct find_monitor_of_sink_cb_param *p = userdata;
unsigned int len;

pulse_broadcast();

if (!i || !i->name || !i->name[0])
return;
if (i->monitor_of_sink != p->current_device_index)
return;

len = strlen(i->name) + 1;
if (len <= p->params->ret_device_len)
{
memcpy(p->params->ret_device, i->name, len);
p->params->result = STATUS_SUCCESS;
return;
}
p->params->ret_device_len = len;
p->params->result = STATUS_BUFFER_TOO_SMALL;
}

static NTSTATUS pulse_get_loopback_capture_device(void *args)
{
struct get_loopback_capture_device_params *params = args;
uint32_t current_device_index = PA_INVALID_INDEX;
struct find_monitor_of_sink_cb_param p;
const char *device_name;
char *name;

pulse_lock();

if (!pulse_ml)
{
pulse_unlock();
ERR("Called without main loop running.\n");
params->result = E_INVALIDARG;
return STATUS_SUCCESS;
}

name = wstr_to_str(params->name);
params->result = pulse_connect(name);
free(name);

if (FAILED(params->result))
{
pulse_unlock();
return STATUS_SUCCESS;
}

device_name = params->device;
if (device_name && !device_name[0]) device_name = NULL;

params->result = E_FAIL;
wait_pa_operation_complete(pa_context_get_sink_info_by_name(pulse_ctx, device_name, &sink_name_info_cb, &current_device_index));
if (current_device_index != PA_INVALID_INDEX)
{
p.current_device_index = current_device_index;
p.params = params;
wait_pa_operation_complete(pa_context_get_source_info_list(pulse_ctx, &find_monitor_of_sink_cb, &p));
}

pulse_unlock();
return STATUS_SUCCESS;
}

static NTSTATUS pulse_get_mix_format(void *args)
{
struct get_mix_format_params *params = args;
Expand Down Expand Up @@ -2580,7 +2663,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
pulse_get_capture_buffer,
pulse_release_capture_buffer,
pulse_is_format_supported,
pulse_not_implemented,
pulse_get_loopback_capture_device,
pulse_get_mix_format,
pulse_get_device_period,
pulse_get_buffer_size,
Expand Down Expand Up @@ -2773,6 +2856,31 @@ static NTSTATUS pulse_wow64_is_format_supported(void *args)
return STATUS_SUCCESS;
}

static NTSTATUS pulse_wow64_get_loopback_capture_device(void *args)
{
struct
{
PTR32 name;
PTR32 device;
PTR32 ret_device;
UINT32 ret_device_len;
HRESULT result;
} *params32 = args;

struct get_loopback_capture_device_params params =
{
.name = ULongToPtr(params32->name),
.device = ULongToPtr(params32->device),
.ret_device = ULongToPtr(params32->device),
.ret_device_len = params32->ret_device_len,
};

pulse_get_loopback_capture_device(&params);
params32->result = params.result;
params32->ret_device_len = params.ret_device_len;
return STATUS_SUCCESS;
}

static NTSTATUS pulse_wow64_get_mix_format(void *args)
{
struct
Expand Down Expand Up @@ -3053,7 +3161,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
pulse_wow64_get_capture_buffer,
pulse_release_capture_buffer,
pulse_wow64_is_format_supported,
pulse_not_implemented,
pulse_wow64_get_loopback_capture_device,
pulse_wow64_get_mix_format,
pulse_wow64_get_device_period,
pulse_wow64_get_buffer_size,
Expand Down

0 comments on commit 089de15

Please sign in to comment.