Add wayvncctl get-outputs command
Signed-off-by: Jim Ramsay <i.am@jimramsay.com>pull/195/head
parent
ac5e207321
commit
80fd6b074e
|
@ -27,6 +27,14 @@ struct ctl_server_vnc_client {
|
||||||
char username[256];
|
char username[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ctl_server_output {
|
||||||
|
char name[65];
|
||||||
|
char description[128];
|
||||||
|
unsigned height;
|
||||||
|
unsigned width;
|
||||||
|
bool captured;
|
||||||
|
};
|
||||||
|
|
||||||
struct ctl_server_actions {
|
struct ctl_server_actions {
|
||||||
void* userdata;
|
void* userdata;
|
||||||
struct cmd_response* (*on_output_cycle)(struct ctl*,
|
struct cmd_response* (*on_output_cycle)(struct ctl*,
|
||||||
|
@ -39,6 +47,12 @@ struct ctl_server_actions {
|
||||||
// Receiver will free(clients) when done.
|
// Receiver will free(clients) when done.
|
||||||
int (*get_client_list)(struct ctl*,
|
int (*get_client_list)(struct ctl*,
|
||||||
struct ctl_server_vnc_client** clients);
|
struct ctl_server_vnc_client** clients);
|
||||||
|
|
||||||
|
// Return number of elements created
|
||||||
|
// Allocate 'outputs' array or set to NULL if none
|
||||||
|
// Receiver will free(outputs) when done.
|
||||||
|
int (*get_output_list)(struct ctl*,
|
||||||
|
struct ctl_server_output** outputs);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ctl* ctl_server_new(const char* socket_path,
|
struct ctl* ctl_server_new(const char* socket_path,
|
||||||
|
|
|
@ -412,6 +412,29 @@ static void pretty_client_list(json_t* data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pretty_output_list(json_t* data)
|
||||||
|
{
|
||||||
|
int n = json_array_size(data);
|
||||||
|
printf("There %s %d output%s%s\n", (n == 1) ? "is" : "are",
|
||||||
|
n, (n == 1) ? "" : "s", (n > 0) ? ":" : ".");
|
||||||
|
int i;
|
||||||
|
json_t* value;
|
||||||
|
json_array_foreach(data, i, value) {
|
||||||
|
char* name = NULL;
|
||||||
|
char* description = NULL;
|
||||||
|
int height = -1;
|
||||||
|
int width = -1;
|
||||||
|
int captured = false;
|
||||||
|
json_unpack(value, "{s:s, s:s, s:i, s:i, s:b}", "name", &name,
|
||||||
|
"description", &description,
|
||||||
|
"height", &height,
|
||||||
|
"width", &width,
|
||||||
|
"captured", &captured);
|
||||||
|
printf("%s output[%s]: %s (%dx%d)\n",
|
||||||
|
captured ? "*" : " ", name, description, width,
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
}
|
||||||
static void pretty_print(json_t* data,
|
static void pretty_print(json_t* data,
|
||||||
struct jsonipc_request* request)
|
struct jsonipc_request* request)
|
||||||
{
|
{
|
||||||
|
@ -422,6 +445,8 @@ static void pretty_print(json_t* data,
|
||||||
pretty_version(data);
|
pretty_version(data);
|
||||||
else if (strcmp(method, "get-clients") == 0)
|
else if (strcmp(method, "get-clients") == 0)
|
||||||
pretty_client_list(data);
|
pretty_client_list(data);
|
||||||
|
else if (strcmp(method, "get-outputs") == 0)
|
||||||
|
pretty_output_list(data);
|
||||||
else
|
else
|
||||||
json_dumpf(data, stdout, JSON_INDENT(2));
|
json_dumpf(data, stdout, JSON_INDENT(2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ enum cmd_type {
|
||||||
CMD_EVENT_RECEIVE,
|
CMD_EVENT_RECEIVE,
|
||||||
CMD_SET_OUTPUT,
|
CMD_SET_OUTPUT,
|
||||||
CMD_GET_CLIENTS,
|
CMD_GET_CLIENTS,
|
||||||
|
CMD_GET_OUTPUTS,
|
||||||
CMD_UNKNOWN,
|
CMD_UNKNOWN,
|
||||||
};
|
};
|
||||||
#define CMD_LIST_LEN CMD_UNKNOWN
|
#define CMD_LIST_LEN CMD_UNKNOWN
|
||||||
|
@ -99,7 +100,10 @@ static struct cmd_info cmd_list[] = {
|
||||||
"Return a list of all currently connected VNC sessions",
|
"Return a list of all currently connected VNC sessions",
|
||||||
{{NULL, NULL}}
|
{{NULL, NULL}}
|
||||||
},
|
},
|
||||||
|
[CMD_GET_OUTPUTS] = { "get-outputs",
|
||||||
|
"Return a list of all currently detected Wayland outputs",
|
||||||
|
{{NULL, NULL}}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CLIENT_EVENT_PARAMS(including) \
|
#define CLIENT_EVENT_PARAMS(including) \
|
||||||
|
@ -290,6 +294,7 @@ static struct cmd* parse_command(struct jsonipc_request* ipc,
|
||||||
case CMD_VERSION:
|
case CMD_VERSION:
|
||||||
case CMD_EVENT_RECEIVE:
|
case CMD_EVENT_RECEIVE:
|
||||||
case CMD_GET_CLIENTS:
|
case CMD_GET_CLIENTS:
|
||||||
|
case CMD_GET_OUTPUTS:
|
||||||
cmd = calloc(1, sizeof(*cmd));
|
cmd = calloc(1, sizeof(*cmd));
|
||||||
cmd->type = cmd_type;
|
cmd->type = cmd_type;
|
||||||
break;
|
break;
|
||||||
|
@ -448,6 +453,25 @@ static struct cmd_response* generate_vnc_client_list(struct ctl* self)
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct cmd_response* generate_output_list(struct ctl* self)
|
||||||
|
{
|
||||||
|
struct ctl_server_output* outputs;
|
||||||
|
size_t num_outputs = self->actions.get_output_list(self, &outputs);
|
||||||
|
struct cmd_response* response = cmd_ok();
|
||||||
|
|
||||||
|
response->data = json_array();
|
||||||
|
for (int i = 0; i < num_outputs; ++i)
|
||||||
|
json_array_append_new(response->data, json_pack(
|
||||||
|
"{s:s, s:s, s:i, s:i, s:b}",
|
||||||
|
"name", outputs[i].name,
|
||||||
|
"description", outputs[i].description,
|
||||||
|
"height", outputs[i].height,
|
||||||
|
"width", outputs[i].width,
|
||||||
|
"captured", outputs[i].captured));
|
||||||
|
free(outputs);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
static struct cmd_response* ctl_server_dispatch_cmd(struct ctl* self,
|
static struct cmd_response* ctl_server_dispatch_cmd(struct ctl* self,
|
||||||
struct ctl_client* client, struct cmd* cmd)
|
struct ctl_client* client, struct cmd* cmd)
|
||||||
{
|
{
|
||||||
|
@ -479,6 +503,9 @@ static struct cmd_response* ctl_server_dispatch_cmd(struct ctl* self,
|
||||||
case CMD_GET_CLIENTS:
|
case CMD_GET_CLIENTS:
|
||||||
response = generate_vnc_client_list(self);
|
response = generate_vnc_client_list(self);
|
||||||
break;
|
break;
|
||||||
|
case CMD_GET_OUTPUTS:
|
||||||
|
response = generate_output_list(self);
|
||||||
|
break;
|
||||||
case CMD_UNKNOWN:
|
case CMD_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
25
src/main.c
25
src/main.c
|
@ -493,6 +493,30 @@ static int get_client_list(struct ctl* ctl,
|
||||||
return self->nr_clients;
|
return self->nr_clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_output_list(struct ctl* ctl,
|
||||||
|
struct ctl_server_output** outputs)
|
||||||
|
{
|
||||||
|
struct wayvnc* self = ctl_server_userdata(ctl);
|
||||||
|
int n = wl_list_length(&self->outputs);
|
||||||
|
if (n == 0) {
|
||||||
|
*outputs = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*outputs = calloc(n, sizeof(**outputs));
|
||||||
|
struct output* output;
|
||||||
|
struct ctl_server_output* item = *outputs;
|
||||||
|
wl_list_for_each(output, &self->outputs, link) {
|
||||||
|
strlcpy(item->name, output->name, sizeof(item->name));
|
||||||
|
strlcpy(item->description, output->description,
|
||||||
|
sizeof(item->description));
|
||||||
|
item->height = output->height;
|
||||||
|
item->width = output->width;
|
||||||
|
item->captured = (output->id == self->selected_output->id);
|
||||||
|
item++;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
int init_main_loop(struct wayvnc* self)
|
int init_main_loop(struct wayvnc* self)
|
||||||
{
|
{
|
||||||
struct aml* loop = aml_get_default();
|
struct aml* loop = aml_get_default();
|
||||||
|
@ -1335,6 +1359,7 @@ int main(int argc, char* argv[])
|
||||||
.on_output_cycle = on_output_cycle,
|
.on_output_cycle = on_output_cycle,
|
||||||
.on_output_switch = on_output_switch,
|
.on_output_switch = on_output_switch,
|
||||||
.get_client_list = get_client_list,
|
.get_client_list = get_client_list,
|
||||||
|
.get_output_list = get_output_list,
|
||||||
};
|
};
|
||||||
self.ctl = ctl_server_new(socket_path, &ctl_actions);
|
self.ctl = ctl_server_new(socket_path, &ctl_actions);
|
||||||
if (!self.ctl)
|
if (!self.ctl)
|
||||||
|
|
13
wayvnc.scd
13
wayvnc.scd
|
@ -68,11 +68,15 @@ is also possible to run wayvnc without a physical display attached.
|
||||||
|
|
||||||
## MULTIPLE OUTPUTS
|
## MULTIPLE OUTPUTS
|
||||||
|
|
||||||
If the Wayland session consists of multiple outputs, only one will be captured.
|
If the Wayland session consists of multiple outputs, only one will be captured.
|
||||||
By default this will be the first one, but can be specified by the _-o_ command
|
By default this will be the first one, but can be specified by the _-o_ command
|
||||||
line argument. The argument accepts the short name such as _eDP-1_ or _DP-4_.
|
line argument. The argument accepts the short name such as _eDP-1_ or _DP-4_.
|
||||||
Running wayvnc in verbose mode (_-v_) will display the names of all outputs on
|
Running wayvnc in verbose mode (_-v_) will display the names of all outputs on
|
||||||
startup.
|
startup, or you can query them at runtime via the *wayvncctl get-outputs*
|
||||||
|
command.
|
||||||
|
|
||||||
|
You can also change which output is being captured on the fly via the *wayvncctl
|
||||||
|
set-output* command.
|
||||||
|
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|
||||||
|
@ -204,6 +208,11 @@ _GET-CLIENTS_
|
||||||
The *get-clients* command retrieves a list of all VNC clients currently
|
The *get-clients* command retrieves a list of all VNC clients currently
|
||||||
connected to wayvnc.
|
connected to wayvnc.
|
||||||
|
|
||||||
|
_GET-OUTPUTS_
|
||||||
|
|
||||||
|
The *get-outputs* command retrieves a list of all outputs known to wayvnc and
|
||||||
|
whether or not each one is currently being captured.
|
||||||
|
|
||||||
## IPC EVENTS
|
## IPC EVENTS
|
||||||
|
|
||||||
_CLIENT-CONNECTED_
|
_CLIENT-CONNECTED_
|
||||||
|
|
Loading…
Reference in New Issue