Merge branch 'master' of https://github.com/SirCmpwn/sway
| 
						 | 
				
			
			@ -71,7 +71,7 @@ message as well.
 | 
			
		|||
## Coding Style
 | 
			
		||||
 | 
			
		||||
Sway is written in C. The style guidelines is [kernel
 | 
			
		||||
style](https://www.kernel.org/doc/Documentation/CodingStyle), but all braces go
 | 
			
		||||
style](https://www.kernel.org/doc/Documentation/process/coding-style.rst), but all braces go
 | 
			
		||||
on the same line (*"but K&R says so!" is a silly way of justifying something*).
 | 
			
		||||
Some points to note:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								LICENSE
									
										
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
Copyright (c) 2016 Drew DeVault
 | 
			
		||||
Copyright (c) 2016-2017 Drew DeVault
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
		 Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 31 KiB  | 
| 
		 Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 53 KiB  | 
| 
		 Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 11 KiB  | 
| 
		 Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 50 KiB  | 
| 
		 Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 5.6 KiB  | 
| 
		 Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 32 KiB  | 
| 
		 Before Width: | Height: | Size: 639 KiB After Width: | Height: | Size: 318 KiB  | 
| 
		 Before Width: | Height: | Size: 650 KiB After Width: | Height: | Size: 344 KiB  | 
| 
		 Before Width: | Height: | Size: 932 KiB After Width: | Height: | Size: 520 KiB  | 
| 
		 Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 838 KiB  | 
| 
		 Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 1.1 MiB  | 
| 
		 Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 1 MiB  | 
| 
		 Before Width: | Height: | Size: 712 KiB After Width: | Height: | Size: 403 KiB  | 
| 
		 Before Width: | Height: | Size: 692 KiB After Width: | Height: | Size: 339 KiB  | 
| 
						 | 
				
			
			@ -22,12 +22,18 @@ WAYLAND_ADD_PROTOCOL_SERVER(proto-server-swaylock
 | 
			
		|||
	swaylock
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
WAYLAND_ADD_PROTOCOL_SERVER(proto-server-gamma-control
 | 
			
		||||
	gamma-control.xml
 | 
			
		||||
	gamma-control
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_library(sway-protocols STATIC
 | 
			
		||||
	${proto-client-xdg-shell}
 | 
			
		||||
	${proto-client-desktop-shell}
 | 
			
		||||
	${proto-server-desktop-shell}
 | 
			
		||||
	${proto-client-swaylock}
 | 
			
		||||
	${proto-server-swaylock}
 | 
			
		||||
	${proto-server-gamma-control}
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
set(PROTOCOLS_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/protocols PARENT_SCOPE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										57
									
								
								protocols/gamma-control.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<protocol name="gamma_control">
 | 
			
		||||
 | 
			
		||||
    <copyright>
 | 
			
		||||
        Copyright © 2015 Giulio camuffo
 | 
			
		||||
 | 
			
		||||
        Permission to use, copy, modify, distribute, and sell this
 | 
			
		||||
        software and its documentation for any purpose is hereby granted
 | 
			
		||||
        without fee, provided that the above copyright notice appear in
 | 
			
		||||
        all copies and that both that copyright notice and this permission
 | 
			
		||||
        notice appear in supporting documentation, and that the name of
 | 
			
		||||
        the copyright holders not be used in advertising or publicity
 | 
			
		||||
        pertaining to distribution of the software without specific,
 | 
			
		||||
        written prior permission.  The copyright holders make no
 | 
			
		||||
        representations about the suitability of this software for any
 | 
			
		||||
        purpose.  It is provided "as is" without express or implied
 | 
			
		||||
        warranty.
 | 
			
		||||
 | 
			
		||||
        THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 | 
			
		||||
        SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
        FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
        SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
        WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 | 
			
		||||
        AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 | 
			
		||||
        ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 | 
			
		||||
        THIS SOFTWARE.
 | 
			
		||||
    </copyright>
 | 
			
		||||
 | 
			
		||||
    <interface name="gamma_control_manager" version="1">
 | 
			
		||||
        <request name="destroy" type="destructor"/>
 | 
			
		||||
 | 
			
		||||
        <request name="get_gamma_control">
 | 
			
		||||
            <arg name="id" type="new_id" interface="gamma_control"/>
 | 
			
		||||
            <arg name="output" type="object" interface="wl_output"/>
 | 
			
		||||
        </request>
 | 
			
		||||
    </interface>
 | 
			
		||||
 | 
			
		||||
    <interface name="gamma_control" version="1">
 | 
			
		||||
        <enum name="error">
 | 
			
		||||
            <entry name="invalid_gamma" value="0"/>
 | 
			
		||||
        </enum>
 | 
			
		||||
 | 
			
		||||
        <request name="destroy" type="destructor"/>
 | 
			
		||||
 | 
			
		||||
        <request name="set_gamma">
 | 
			
		||||
            <arg name="red" type="array"/>
 | 
			
		||||
            <arg name="green" type="array"/>
 | 
			
		||||
            <arg name="blue" type="array"/>
 | 
			
		||||
        </request>
 | 
			
		||||
 | 
			
		||||
        <request name="reset_gamma"/>
 | 
			
		||||
 | 
			
		||||
        <event name="gamma_size">
 | 
			
		||||
            <arg name="size" type="uint"/>
 | 
			
		||||
        </event>
 | 
			
		||||
    </interface>
 | 
			
		||||
</protocol>
 | 
			
		||||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
#include <wlc/wlc-render.h>
 | 
			
		||||
#include "wayland-desktop-shell-server-protocol.h"
 | 
			
		||||
#include "wayland-swaylock-server-protocol.h"
 | 
			
		||||
#include "wayland-gamma-control-server-protocol.h"
 | 
			
		||||
#include "sway/layout.h"
 | 
			
		||||
#include "sway/input_state.h"
 | 
			
		||||
#include "sway/extensions.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +141,52 @@ static void desktop_unlock(struct wl_client *client, struct wl_resource *resourc
 | 
			
		|||
	sway_log(L_ERROR, "desktop_unlock is not currently supported");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_grab_surface(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface) {
 | 
			
		||||
	sway_log(L_ERROR, "desktop_set_grab_surface is not currently supported");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void desktop_ready(struct wl_client *client, struct wl_resource *resource) {
 | 
			
		||||
	// nop
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_panel_position(struct wl_client *client, struct wl_resource *resource, uint32_t position) {
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
	wl_client_get_credentials(client, &pid, NULL, NULL);
 | 
			
		||||
	if (!(get_feature_policy(pid) & FEATURE_PANEL)) {
 | 
			
		||||
		sway_log(L_INFO, "Denying panel feature to %d", pid);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct panel_config *config = find_or_create_panel_config(resource);
 | 
			
		||||
	sway_log(L_DEBUG, "Panel position for wl_resource %p changed %d => %d", resource, config->panel_position, position);
 | 
			
		||||
	config->panel_position = position;
 | 
			
		||||
	arrange_windows(&root_container, -1, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct desktop_shell_interface desktop_shell_implementation = {
 | 
			
		||||
	.set_background = set_background,
 | 
			
		||||
	.set_panel = set_panel,
 | 
			
		||||
	.set_lock_surface = desktop_set_lock_surface,
 | 
			
		||||
	.unlock = desktop_unlock,
 | 
			
		||||
	.set_grab_surface = set_grab_surface,
 | 
			
		||||
	.desktop_ready = desktop_ready,
 | 
			
		||||
	.set_panel_position = set_panel_position
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void desktop_shell_bind(struct wl_client *client, void *data,
 | 
			
		||||
		unsigned int version, unsigned int id) {
 | 
			
		||||
	if (version > 3) {
 | 
			
		||||
		// Unsupported version
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wl_resource *resource = wl_resource_create(client, &desktop_shell_interface, version, id);
 | 
			
		||||
	if (!resource) {
 | 
			
		||||
		wl_client_post_no_memory(client);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_resource_set_implementation(resource, &desktop_shell_implementation, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_lock_surface(struct wl_client *client, struct wl_resource *resource,
 | 
			
		||||
		struct wl_resource *_output, struct wl_resource *surface) {
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
| 
						 | 
				
			
			@ -179,57 +226,11 @@ static void unlock(struct wl_client *client, struct wl_resource *resource) {
 | 
			
		|||
	// This isn't really necessary, we just unlock when the client exits.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_grab_surface(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface) {
 | 
			
		||||
	sway_log(L_ERROR, "desktop_set_grab_surface is not currently supported");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void desktop_ready(struct wl_client *client, struct wl_resource *resource) {
 | 
			
		||||
	// nop
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_panel_position(struct wl_client *client, struct wl_resource *resource, uint32_t position) {
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
	wl_client_get_credentials(client, &pid, NULL, NULL);
 | 
			
		||||
	if (!(get_feature_policy(pid) & FEATURE_PANEL)) {
 | 
			
		||||
		sway_log(L_INFO, "Denying panel feature to %d", pid);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct panel_config *config = find_or_create_panel_config(resource);
 | 
			
		||||
	sway_log(L_DEBUG, "Panel position for wl_resource %p changed %d => %d", resource, config->panel_position, position);
 | 
			
		||||
	config->panel_position = position;
 | 
			
		||||
	arrange_windows(&root_container, -1, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct desktop_shell_interface desktop_shell_implementation = {
 | 
			
		||||
	.set_background = set_background,
 | 
			
		||||
	.set_panel = set_panel,
 | 
			
		||||
	.set_lock_surface = desktop_set_lock_surface,
 | 
			
		||||
	.unlock = desktop_unlock,
 | 
			
		||||
	.set_grab_surface = set_grab_surface,
 | 
			
		||||
	.desktop_ready = desktop_ready,
 | 
			
		||||
	.set_panel_position = set_panel_position
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct lock_interface swaylock_implementation = {
 | 
			
		||||
	.set_lock_surface = set_lock_surface,
 | 
			
		||||
	.unlock = unlock
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void desktop_shell_bind(struct wl_client *client, void *data,
 | 
			
		||||
		unsigned int version, unsigned int id) {
 | 
			
		||||
	if (version > 3) {
 | 
			
		||||
		// Unsupported version
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wl_resource *resource = wl_resource_create(client, &desktop_shell_interface, version, id);
 | 
			
		||||
	if (!resource) {
 | 
			
		||||
		wl_client_post_no_memory(client);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_resource_set_implementation(resource, &desktop_shell_implementation, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void swaylock_bind(struct wl_client *client, void *data,
 | 
			
		||||
		unsigned int version, unsigned int id) {
 | 
			
		||||
	if (version > 1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +246,80 @@ static void swaylock_bind(struct wl_client *client, void *data,
 | 
			
		|||
	wl_resource_set_implementation(resource, &swaylock_implementation, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gamma_control_destroy(struct wl_client *client, struct wl_resource *res) {
 | 
			
		||||
	wl_resource_destroy(res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gamma_control_set_gamma(struct wl_client *client,
 | 
			
		||||
		struct wl_resource *res, struct wl_array *red,
 | 
			
		||||
		struct wl_array *green, struct wl_array *blue) {
 | 
			
		||||
	if (red->size != green->size || red->size != blue->size) {
 | 
			
		||||
		wl_resource_post_error(res, GAMMA_CONTROL_ERROR_INVALID_GAMMA,
 | 
			
		||||
				"The gamma ramps don't have the same size");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	uint16_t *r = (uint16_t *)red->data;
 | 
			
		||||
	uint16_t *g = (uint16_t *)green->data;
 | 
			
		||||
	uint16_t *b = (uint16_t *)blue->data;
 | 
			
		||||
	wlc_handle output = wlc_handle_from_wl_output_resource(
 | 
			
		||||
			wl_resource_get_user_data(res));
 | 
			
		||||
	if (!output) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	sway_log(L_DEBUG, "Setting gamma for output");
 | 
			
		||||
	wlc_output_set_gamma(output, red->size / sizeof(uint16_t), r, g, b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gamma_control_reset_gamma(struct wl_client *client,
 | 
			
		||||
		struct wl_resource *resource) {
 | 
			
		||||
	// This space intentionally left blank
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct gamma_control_interface gamma_control_implementation = {
 | 
			
		||||
	.destroy = gamma_control_destroy,
 | 
			
		||||
	.set_gamma = gamma_control_set_gamma,
 | 
			
		||||
	.reset_gamma = gamma_control_reset_gamma
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void gamma_control_manager_destroy(struct wl_client *client,
 | 
			
		||||
		struct wl_resource *res) {
 | 
			
		||||
	wl_resource_destroy(res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gamma_control_manager_get(struct wl_client *client,
 | 
			
		||||
		struct wl_resource *res, uint32_t id, struct wl_resource *_output) {
 | 
			
		||||
	struct wl_resource *manager_res = wl_resource_create(client,
 | 
			
		||||
			&gamma_control_interface, wl_resource_get_version(res), id);
 | 
			
		||||
	wlc_handle output = wlc_handle_from_wl_output_resource(_output);
 | 
			
		||||
	if (!output) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	wl_resource_set_implementation(manager_res, &gamma_control_implementation,
 | 
			
		||||
			_output, NULL);
 | 
			
		||||
	gamma_control_send_gamma_size(manager_res, wlc_output_get_gamma_size(output));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct gamma_control_manager_interface gamma_manager_implementation = {
 | 
			
		||||
	.destroy = gamma_control_manager_destroy,
 | 
			
		||||
	.get_gamma_control = gamma_control_manager_get
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void gamma_control_manager_bind(struct wl_client *client, void *data,
 | 
			
		||||
		unsigned int version, unsigned int fd) {
 | 
			
		||||
	if (version > 1) {
 | 
			
		||||
		// Unsupported version
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wl_resource *resource = wl_resource_create(client,
 | 
			
		||||
			&gamma_control_manager_interface, version, fd);
 | 
			
		||||
	if (!resource) {
 | 
			
		||||
		wl_client_post_no_memory(client);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_resource_set_implementation(resource, &gamma_manager_implementation, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void register_extensions(void) {
 | 
			
		||||
	wl_global_create(wlc_get_wl_display(), &desktop_shell_interface, 3, NULL, desktop_shell_bind);
 | 
			
		||||
	desktop_shell.backgrounds = create_list();
 | 
			
		||||
| 
						 | 
				
			
			@ -252,4 +327,6 @@ void register_extensions(void) {
 | 
			
		|||
	desktop_shell.lock_surfaces = create_list();
 | 
			
		||||
	desktop_shell.is_locked = false;
 | 
			
		||||
	wl_global_create(wlc_get_wl_display(), &lock_interface, 1, NULL, swaylock_bind);
 | 
			
		||||
	wl_global_create(wlc_get_wl_display(), &gamma_control_manager_interface, 1,
 | 
			
		||||
			NULL, gamma_control_manager_bind);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ static void ipc_json_describe_output(swayc_t *output, json_object *object) {
 | 
			
		|||
 | 
			
		||||
static void ipc_json_describe_workspace(swayc_t *workspace, json_object *object) {
 | 
			
		||||
	int num = (isdigit(workspace->name[0])) ? atoi(workspace->name) : -1;
 | 
			
		||||
	const char *layout = ipc_json_layout_description(workspace->layout);
 | 
			
		||||
	const char *layout = ipc_json_layout_description(workspace->workspace_layout);
 | 
			
		||||
 | 
			
		||||
	json_object_object_add(object, "num", json_object_new_int(num));
 | 
			
		||||
	json_object_object_add(object, "output", (workspace->parent) ? json_object_new_string(workspace->parent->name) : NULL);
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +173,7 @@ static void ipc_json_describe_view(swayc_t *c, json_object *object) {
 | 
			
		|||
	json_object_object_add(object, "last_split_layout",
 | 
			
		||||
		(strcmp(last_layout, "null") == 0) ? NULL : json_object_new_string(last_layout));
 | 
			
		||||
	json_object_object_add(object, "workspace_layout",
 | 
			
		||||
		json_object_new_string(ipc_json_layout_description(swayc_parent_by_type(c, C_WORKSPACE)->layout)));
 | 
			
		||||
		json_object_new_string(ipc_json_layout_description(swayc_parent_by_type(c, C_WORKSPACE)->workspace_layout)));
 | 
			
		||||
 | 
			
		||||
	json_object_object_add(object, "border", json_object_new_string(ipc_json_border_description(c)));
 | 
			
		||||
	json_object_object_add(object, "current_border_width", json_object_new_int(c->border_thickness));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||