/* channel common events: mode1 and 2 */
static int
chn_common_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
{
	if (q->l.chn >= 32)
		return -EINVAL;
	switch (q->l.cmd) {
	case MIDI_PGM_CHANGE:
		return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_PGMCHANGE,
					  q->l.chn, 0, q->l.p1, ev);

	case MIDI_CTL_CHANGE:
		return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_CONTROLLER,
					  q->l.chn, q->l.p1, q->l.val, ev);

	case MIDI_PITCH_BEND:
		/* conversion: 0:0x3fff -> -0x2000:0x1fff */
		return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_PITCHBEND,
					  q->l.chn, 0, q->l.val - 8192, ev);
		
	case MIDI_CHN_PRESSURE:
		return set_control_event(dp, q->l.dev, SNDRV_SEQ_EVENT_CHANPRESS,
					  q->l.chn, 0, q->l.val, ev);
	}
	return -EINVAL;
}
void VDAgent::dispatch_message(VDAgentMessage* msg, uint32_t port)
{
    bool res = true;

    switch (msg->type) {
    case VD_AGENT_MOUSE_STATE:
        res = handle_mouse_event((VDAgentMouseState*)msg->data);
        break;
    case VD_AGENT_MONITORS_CONFIG:
        res = handle_mon_config((VDAgentMonitorsConfig*)msg->data, port);
        break;
    case VD_AGENT_CLIPBOARD:
        handle_clipboard((VDAgentClipboard*)msg->data, msg->size - sizeof(VDAgentClipboard));
        break;
    case VD_AGENT_CLIPBOARD_GRAB:
        handle_clipboard_grab((VDAgentClipboardGrab*)msg->data, msg->size);        
        break;
    case VD_AGENT_CLIPBOARD_REQUEST:
        res = handle_clipboard_request((VDAgentClipboardRequest*)msg->data);
        if (!res) {
            VDAgentClipboard clipboard = {VD_AGENT_CLIPBOARD_NONE};
            res = write_message(VD_AGENT_CLIPBOARD, sizeof(clipboard), &clipboard);
        }
        break;
    case VD_AGENT_CLIPBOARD_RELEASE:
        handle_clipboard_release();
        break;
    case VD_AGENT_DISPLAY_CONFIG:
        res = handle_display_config((VDAgentDisplayConfig*)msg->data, port);
        break;
    case VD_AGENT_ANNOUNCE_CAPABILITIES:
        res = handle_announce_capabilities((VDAgentAnnounceCapabilities*)msg->data, msg->size);
        break;
    case VD_AGENT_FILE_XFER_START:
    case VD_AGENT_FILE_XFER_STATUS:
    case VD_AGENT_FILE_XFER_DATA: {
        VDAgentFileXferStatusMessage status;
        if (_file_xfer.dispatch(msg, &status)) {
            write_message(VD_AGENT_FILE_XFER_STATUS, sizeof(status), &status);
        }
        break;
    }
    case VD_AGENT_CLIENT_DISCONNECTED:
        vd_printf("Client disconnected, agent to be restarted");
        set_control_event(CONTROL_STOP);
        break;
    case VD_AGENT_MAX_CLIPBOARD:
        res = handle_max_clipboard((VDAgentMaxClipboard*)msg->data, msg->size);
        break;
    default:
        vd_printf("Unsupported message type %u size %u", msg->type, msg->size);
    }
    if (!res) {
        vd_printf("handling message type %u failed: %lu", msg->type, GetLastError());
        _running = false;
    }
}
void VDAgent::handle_clipboard_release()
{
    if (_clipboard_owner != owner_client) {
        vd_printf("Received clipboard release from client while clipboard is not owned by client");
        return;
    }
    set_control_event(CONTROL_CLIPBOARD);
    set_clipboard_owner(owner_none);
}
bool VDAgent::handle_clipboard(VDAgentClipboard* clipboard, uint32_t size)
{
    HANDLE clip_data;
    UINT format;
    bool ret = false;

    if (_clipboard_owner != owner_client) {
        vd_printf("Received clipboard data from client while clipboard is not owned by client");
        goto fin;
    }
    if (clipboard->type == VD_AGENT_CLIPBOARD_NONE) {
        goto fin;
    }
    switch (clipboard->type) {
    case VD_AGENT_CLIPBOARD_UTF8_TEXT:
        clip_data = utf8_alloc((LPCSTR)clipboard->data, size);
        break;
    case VD_AGENT_CLIPBOARD_IMAGE_PNG:
    case VD_AGENT_CLIPBOARD_IMAGE_BMP: {
        DWORD cximage_format = get_cximage_format(clipboard->type);
        ASSERT(cximage_format);
        CxImage image(clipboard->data, size, cximage_format);
        clip_data = image.CopyToHandle();
        break;
    }
    default:
        vd_printf("Unsupported clipboard type %u", clipboard->type);
        goto fin;
    }
    format = get_clipboard_format(clipboard->type);
    if (format == 0) {
        vd_printf("Unknown clipboard format, type %u", clipboard->type);
        goto fin;
    }
    ret = !!SetClipboardData(format, clip_data);
    if (!ret) {
        DWORD err = GetLastError();
        if (err == ERROR_NOT_ENOUGH_MEMORY) {
            vd_printf("Not enough memory to set clipboard data, size %u bytes", size);
        } else {
            vd_printf("SetClipboardData failed: %lu", err);
        }
    }
fin:
    set_control_event(CONTROL_CLIPBOARD);
    return ret;
}
/* 8bytes extended event: mode1 only */
static int
extended_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
{
	int val;

	switch (q->e.cmd) {
	case SEQ_NOTEOFF:
		return note_off_event(dp, q->e.dev, q->e.chn, q->e.p1, q->e.p2, ev);

	case SEQ_NOTEON:
		return note_on_event(dp, q->e.dev, q->e.chn, q->e.p1, q->e.p2, ev);

	case SEQ_PGMCHANGE:
		return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_PGMCHANGE,
					 q->e.chn, 0, q->e.p1, ev);

	case SEQ_AFTERTOUCH:
		return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_CHANPRESS,
					 q->e.chn, 0, q->e.p1, ev);

	case SEQ_BALANCE:
		/* convert -128:127 to 0:127 */
		val = (char)q->e.p1;
		val = (val + 128) / 2;
		return set_control_event(dp, q->e.dev, SNDRV_SEQ_EVENT_CONTROLLER,
					 q->e.chn, CTL_PAN, val, ev);

	case SEQ_CONTROLLER:
		val = ((short)q->e.p3 << 8) | (short)q->e.p2;
		switch (q->e.p1) {
		case CTRL_PITCH_BENDER: /* SEQ1 V2 control */
			/* -0x2000:0x1fff */
			return set_control_event(dp, q->e.dev,
						 SNDRV_SEQ_EVENT_PITCHBEND,
						 q->e.chn, 0, val, ev);
		case CTRL_PITCH_BENDER_RANGE:
			/* conversion: 100/semitone -> 128/semitone */
			return set_control_event(dp, q->e.dev,
						 SNDRV_SEQ_EVENT_REGPARAM,
						 q->e.chn, 0, val*128/100, ev);
		default:
			return set_control_event(dp, q->e.dev,
						  SNDRV_SEQ_EVENT_CONTROL14,
						  q->e.chn, q->e.p1, val, ev);
		}

	case SEQ_VOLMODE:
		return snd_seq_oss_synth_raw_event(dp, q->e.dev, q->c, ev);

	}
	return -EINVAL;
}
/* old type events: mode1 only */
static int
old_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
{
	switch (q->s.code) {
	case SEQ_NOTEOFF:
		return note_off_event(dp, 0, q->n.chn, q->n.note, q->n.vel, ev);

	case SEQ_NOTEON:
		return note_on_event(dp, 0, q->n.chn, q->n.note, q->n.vel, ev);

	case SEQ_WAIT:
		/* skip */
		break;

	case SEQ_PGMCHANGE:
		return set_control_event(dp, 0, SNDRV_SEQ_EVENT_PGMCHANGE,
					 q->n.chn, 0, q->n.note, ev);

	case SEQ_SYNCTIMER:
		return snd_seq_oss_timer_reset(dp->timer);
	}

	return -EINVAL;
}
Beispiel #7
0
void VDService::stop()
{
    vd_printf("Service stopped");
    set_control_event(VD_CONTROL_STOP);
}