add new-output handler
This commit is contained in:
1
Makefile
1
Makefile
@@ -20,6 +20,7 @@ OBJ=src/riverguile.o $\
|
||||
src/call-user-command-handler.o $\
|
||||
src/call-idle-handler.o $\
|
||||
src/call-exit-handler.o $\
|
||||
src/call-new-output-handler.o $\
|
||||
src/load-script.o $\
|
||||
protocol/river-layout-v3.o $\
|
||||
protocol/ext-idle-notify-v1.o $\
|
||||
|
||||
@@ -201,10 +201,35 @@ As of now, river only supports a single seat anyway.
|
||||
.RE
|
||||
.
|
||||
.P
|
||||
\fBnew-output\fR
|
||||
.RE
|
||||
.RS
|
||||
A handler installed under this key will be called everytime a new output appears.
|
||||
On binding, it is also called for all outputs that already exist at that time.
|
||||
.P
|
||||
Installing a new-output handler will cause riverguile to run continously.
|
||||
.P
|
||||
The handler procderure must accept a single argument, the global name of the
|
||||
output (integer).
|
||||
.P
|
||||
Here is an example of a simple new-output handler which merely logs new outputs:
|
||||
.P
|
||||
.RS
|
||||
.EX
|
||||
(\fBinstall-handler\fR 'new-output
|
||||
(\fBlambda\fR (output)
|
||||
(\fBdisplay\fR "New output: ")
|
||||
(\fBdisplay\fR output)
|
||||
(\fBnewline\fR)))
|
||||
.EE
|
||||
.RE
|
||||
.RE
|
||||
.
|
||||
.P
|
||||
\fBexit\fR
|
||||
.RE
|
||||
.RS
|
||||
This key allows you to installs a handler which is called when riverguile exits.
|
||||
This key allows you to install a handler which is called when riverguile exits.
|
||||
.P
|
||||
The procedure takes no arguments.
|
||||
.P
|
||||
|
||||
36
src/call-new-output-handler.c
Normal file
36
src/call-new-output-handler.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <assert.h>
|
||||
#include <libguile.h>
|
||||
|
||||
#include "output.h"
|
||||
#include "riverguile.h"
|
||||
#include "call-new-output-handler.h"
|
||||
|
||||
static void *call_new_output_handler_inner (void *data)
|
||||
{
|
||||
struct Call_new_output_handler_parameters *params = (struct Call_new_output_handler_parameters *)data;
|
||||
return scm_call_1(
|
||||
context.new_output_handler,
|
||||
scm_from_uint32(params->output->name)
|
||||
);
|
||||
}
|
||||
|
||||
void *call_new_output_handler (void *data)
|
||||
{
|
||||
assert(context.new_output_handler != NULL);
|
||||
assert(scm_is_true(scm_procedure_p(context.new_output_handler)) == 1);
|
||||
|
||||
/* Continuation barrier causes stack unwind on exceptions (i.e. errors
|
||||
* in the user defined new-output handler) to stop here. Otherwise
|
||||
* the entire stack created by scm_with_guile() would be unwound. This
|
||||
* makes responding to exceptions nicer.
|
||||
*/
|
||||
SCM call_result = scm_c_with_continuation_barrier(
|
||||
call_new_output_handler_inner, data
|
||||
);
|
||||
|
||||
|
||||
if ( call_result == NULL )
|
||||
return (void *)"ERROR: An exception occured while calling the user-command handler.\n";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
11
src/call-new-output-handler.h
Normal file
11
src/call-new-output-handler.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef RIVERGUILE_CALL_NEW_OUTPUT_HANDLER_H
|
||||
#define RIVERGUILE_CALL_NEW_OUTPUT_HANDLER_H
|
||||
|
||||
struct Call_new_output_handler_parameters
|
||||
{
|
||||
struct Output *output;
|
||||
};
|
||||
|
||||
void *call_new_output_handler (void *data);
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "seat.h"
|
||||
|
||||
#include "river-control-unstable-v1.h"
|
||||
#include "call-new-output-handler.h"
|
||||
|
||||
/**
|
||||
* ISO C forbids casting a function pointer to a void pointer because on some
|
||||
@@ -77,7 +78,29 @@ static SCM install_handler (SCM key, SCM proc)
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if ( scm_is_eq(scm_from_utf8_symbol("layout-demand"), key) == 1 )
|
||||
if ( scm_is_eq(scm_from_utf8_symbol("new-output"), key) == 1 )
|
||||
{
|
||||
context.mode = CONTINOUS;
|
||||
context.new_output_handler = proc;
|
||||
|
||||
/* Call handler for all already existing outputs. */
|
||||
struct Output *output;
|
||||
wl_list_for_each(output, &context.outputs, link)
|
||||
{
|
||||
struct Call_new_output_handler_parameters params = {
|
||||
.output = output,
|
||||
};
|
||||
|
||||
void *res = scm_with_guile(call_new_output_handler, (void *)¶ms);
|
||||
if ( res != NULL )
|
||||
{
|
||||
fputs(res, stderr);
|
||||
fputs("INFO: This error is not fatal.\n", stderr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( scm_is_eq(scm_from_utf8_symbol("layout-demand"), key) == 1 )
|
||||
{
|
||||
if ( context.layout_manager == NULL )
|
||||
{
|
||||
|
||||
16
src/output.c
16
src/output.c
@@ -11,6 +11,7 @@
|
||||
#include "output.h"
|
||||
#include "call-layout-demand-handler.h"
|
||||
#include "call-user-command-handler.h"
|
||||
#include "call-new-output-handler.h"
|
||||
|
||||
static void layout_handle_layout_demand (void *data, struct river_layout_v3 *river_layout_v3,
|
||||
uint32_t view_count, uint32_t width, uint32_t height, uint32_t tags, uint32_t serial)
|
||||
@@ -106,6 +107,21 @@ struct Output *output_create (struct wl_output *wl_output, uint32_t name)
|
||||
output->name = name;
|
||||
output->wl_output = wl_output;
|
||||
|
||||
/* If we have a new-output handler installed, send it. */
|
||||
if ( context.new_output_handler != NULL )
|
||||
{
|
||||
struct Call_new_output_handler_parameters params = {
|
||||
.output = output,
|
||||
};
|
||||
|
||||
void *res = scm_with_guile(call_new_output_handler, (void *)¶ms);
|
||||
if ( res != NULL )
|
||||
{
|
||||
fputs(res, stderr);
|
||||
fputs("INFO: This error is not fatal.\n", stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only bind layout if we need it. Outputs advertised in the initial
|
||||
* registry burst, before the script is loaded, will always skip this,
|
||||
* however it is necessary for outputs added later.
|
||||
|
||||
@@ -34,6 +34,7 @@ struct Context context = {
|
||||
* that is intended or will disappear in the future. Special care must be taken
|
||||
* to never call any scm_* function on these while they are NULL.
|
||||
*/
|
||||
.new_output_handler = NULL,
|
||||
.layout_demand_handler = NULL,
|
||||
.user_command_handler = NULL,
|
||||
.exit_handler = NULL,
|
||||
|
||||
@@ -22,6 +22,7 @@ enum Riverguile_mode
|
||||
|
||||
struct Context
|
||||
{
|
||||
SCM new_output_handler;
|
||||
SCM layout_demand_handler;
|
||||
SCM user_command_handler;
|
||||
SCM exit_handler;
|
||||
|
||||
Reference in New Issue
Block a user