125 lines
3.5 KiB
C
125 lines
3.5 KiB
C
#include <stdio.h>
|
|
#include <rfb/rfbclient.h>
|
|
|
|
// The world if libvncclient let you easily connect to a server without using their own retarded argv shit
|
|
// (audio and name wouldn't even have to be 2 different binaries and password could easily be specified!!!)
|
|
|
|
#define VNC_PASSWORD "D0gg0!!!"
|
|
|
|
#define VNC_ENCODING_AUDIO 0XFFFFFEFD /* -259 */
|
|
|
|
#define VNC_MSG_CLIENT_QEMU 255
|
|
#define VNC_MSG_CLIENT_QEMU_AUDIO 1
|
|
|
|
#define VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE 0
|
|
#define VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE 1
|
|
#define VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT 2
|
|
|
|
#define VNC_MSG_SERVER_QEMU_AUDIO_END 0
|
|
#define VNC_MSG_SERVER_QEMU_AUDIO_BEGIN 1
|
|
#define VNC_MSG_SERVER_QEMU_AUDIO_DATA 2
|
|
|
|
#define AUDIO_FORMAT_U8 0
|
|
#define AUDIO_FORMAT_S8 1
|
|
#define AUDIO_FORMAT_U16 2
|
|
#define AUDIO_FORMAT_S16 3
|
|
#define AUDIO_FORMAT_U32 4
|
|
#define AUDIO_FORMAT_S32 5
|
|
|
|
#define VNC_QEMU_AUDIO_RATE 48000
|
|
#define VNC_QEMU_AUDIO_CHANNELS 2
|
|
#define VNC_QEMU_AUDIO_BPS 16
|
|
|
|
char * getpassword(rfbClient *client) {
|
|
return strdup(VNC_PASSWORD);
|
|
};
|
|
|
|
static rfbBool vnc_qemu_audio_encoding(rfbClient* client, rfbFramebufferUpdateRectHeader* rect) {
|
|
struct {
|
|
uint8_t type;
|
|
uint8_t msg_id;
|
|
uint16_t audio_id;
|
|
struct {
|
|
uint8_t format;
|
|
uint8_t channels;
|
|
char frequency[sizeof(uint32_t)];
|
|
} set_format;
|
|
} audio_format_msg = {
|
|
VNC_MSG_CLIENT_QEMU,
|
|
VNC_MSG_CLIENT_QEMU_AUDIO,
|
|
rfbClientSwap16IfLE(VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT),
|
|
AUDIO_FORMAT_S16,
|
|
VNC_QEMU_AUDIO_CHANNELS
|
|
};
|
|
|
|
*(uint32_t*) audio_format_msg.set_format.frequency = rfbClientSwap32IfLE(VNC_QEMU_AUDIO_RATE);
|
|
|
|
if (!WriteToRFBServer(client, (char*)& audio_format_msg, sizeof(audio_format_msg))) return FALSE;
|
|
|
|
struct {
|
|
uint8_t type;
|
|
uint8_t msg_id;
|
|
uint16_t audio_id;
|
|
} audio_enable_msg = {
|
|
VNC_MSG_CLIENT_QEMU,
|
|
VNC_MSG_CLIENT_QEMU_AUDIO,
|
|
rfbClientSwap16IfLE(VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE)
|
|
};
|
|
|
|
if (!WriteToRFBServer(client, (char*)& audio_enable_msg, sizeof(audio_enable_msg))) return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static rfbBool vnc_qemu_audio_msg(rfbClient* client, rfbServerToClientMsg* message) {
|
|
if (message->type != VNC_MSG_CLIENT_QEMU) return FALSE;
|
|
|
|
struct {
|
|
uint8_t msg_id;
|
|
char audio_id[sizeof(uint16_t)];
|
|
} msg;
|
|
|
|
if (!ReadFromRFBServer(client, (char*)&msg, sizeof(msg))) return TRUE;
|
|
if (msg.msg_id != VNC_MSG_CLIENT_QEMU_AUDIO) return TRUE;
|
|
|
|
switch (rfbClientSwap16IfLE(*(uint16_t*)msg.audio_id)) {
|
|
case VNC_MSG_SERVER_QEMU_AUDIO_BEGIN:
|
|
break;
|
|
case VNC_MSG_SERVER_QEMU_AUDIO_DATA: {
|
|
uint32_t size;
|
|
if (!ReadFromRFBServer(client, (char*) &size, sizeof(uint32_t))) return TRUE;
|
|
size = rfbClientSwap32IfLE(size);
|
|
char* data = malloc(size);
|
|
if (ReadFromRFBServer(client, data, size)) fwrite(data, sizeof(char), size, stdout);
|
|
free(data);
|
|
break;
|
|
};
|
|
case VNC_MSG_SERVER_QEMU_AUDIO_END:
|
|
break;
|
|
};
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static int QEMU_AUDIO_ENCODING[] = {VNC_ENCODING_AUDIO, 0};
|
|
static rfbClientProtocolExtension qemu_audio_extension = {
|
|
QEMU_AUDIO_ENCODING,
|
|
vnc_qemu_audio_encoding,
|
|
vnc_qemu_audio_msg,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
int main(int argc, char **argv) {
|
|
rfbClient* client = rfbGetClient(8,3,4);
|
|
client->GetPassword = getpassword;
|
|
rfbClientRegisterExtension(&qemu_audio_extension);
|
|
if (!rfbInitClient(client,&argc,argv)) return 1;
|
|
while (1) {
|
|
if (WaitForMessage(client,50) < 0) break;
|
|
if (!HandleRFBServerMessage(client)) break;
|
|
};
|
|
rfbClientCleanup(client);
|
|
return 0;
|
|
}
|