Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mvaldina/weston
  • ant8me/weston
  • JaredHu/weston
  • drawat/weston
  • bnieuwenhuizen/weston
  • Robyn.marie/weston
  • dwrobel/weston
  • yjheo/weston
  • dos/weston
  • longjunyu2/weston
  • soerenmeier/weston
  • igor.torrente/weston
  • luckyziv/weston
  • qyliss/weston
  • tantan/weston
  • wengxt/weston
  • mroussin/weston
  • n3rdopolis/weston
  • xiangxuy/weston
  • RAOF/weston
  • afrantzis/weston
  • lujin/weston
  • jayjona42/weston
  • ascent/weston
  • inzamam.15/weston
  • bbara93/weston
  • adoan/weston
  • Vivalavina/weston
  • iason.paraskevopoulos/weston
  • phnaharris/weston
  • mforney/weston
  • linkmauve/weston
  • xexaxo/weston
  • rajendraprasadkj/weston
  • xeechou/weston
  • learning/weston
  • agners/weston
  • ianr/weston
  • eucan/weston
  • heemin.lee/weston
  • nniro/weston
  • PaulKocialkowski/weston
  • NaveenKumar/weston
  • msisov/weston
  • ollieparanoid/weston
  • pH5/weston
  • dbaker/weston
  • gtristan/weston
  • khosokawa/weston
  • lubosz/weston
  • Fahien/weston
  • m.tretter/weston
  • valpackett/weston
  • marimeireles/weston
  • afd/weston
  • lk1025/weston
  • marler8997/weston
  • jianglei121381/weston
  • flakylawww/weston
  • ayaka/weston
  • bbeckett/weston
  • rdp.effort/weston
  • Ganjing0224/weston
  • jcline/weston
  • bl4ckb0ne/weston
  • Bastian-Krause/weston
  • fifi899173/weston
  • jpewhacker/weston
  • yuanye100/weston
  • t-8ch/weston
  • HarshaMM/weston
  • david.turner/weston
  • wismill/weston
  • rsmith/weston
  • rohanjulka19/weston
  • shadeslayer/weston
  • sjoerd/weston
  • barry.song/weston
  • petervdperk/weston
  • renjiayuan1314/weston
  • HeYong/weston
  • bluesirhl/weston
  • macpijan/weston
  • andreinonea/weston
  • vanfanel/weston
  • mstoeckl/weston
  • chewi/weston
  • shierote/weston
  • tmaillart1/weston
  • jh-hsd/weston
  • bgjdarm/weston
  • anurup_m/weston
  • lucaweiss/weston
  • dima/weston
  • marysaka/weston
  • daissi/weston
  • vnguyentrong/weston
  • enocknyaega/weston
  • kang-sooyeon/weston
  • tpetazzoni/weston
  • mihlenfeldt/weston
  • rgallaispou/weston
  • chienpv/weston
  • kraj/weston
  • stolk/weston
  • Emantor/weston
  • kusma/weston
  • bmkimg/weston
  • 9531718244loco/weston
  • Ts/weston
  • kennylevinsen/weston
  • eyelash/weston
  • Igortorrente/weston
  • pleasurefish/weston
  • ahe/weston
  • ekurzinger/weston
  • pochu/weston
  • saavedra.pablo/weston
  • borneoa/weston
  • JimmyOhn/weston
  • ShivakumarVH/weston
  • Cwiiis/weston
  • romangg/weston
  • zubzub/weston
  • askebm/weston
  • ewtoombs/weston
  • wolf._.lael666/weston
  • dr3020187/weston
  • kxing/weston_hpd
  • filip-hejsek/weston
  • xndcn/weston
  • therealkenc/weston
  • C0rn3j/weston
  • tmaillart/weston
  • leandrohrb/weston
  • snow/weston
  • marex/weston
  • bnlrnz/weston
  • zhourunsheng2008/weston
  • zhouliang/weston
  • isinyaaa/weston
  • JeffyCN/weston
  • tzimmermann/weston
  • christian-rauch/weston
  • krh/weston
  • Rigo-V/weston
  • archiesix/weston
  • cwjo/weston
  • hedone21/weston
  • liyi42/weston
  • uniontechWu/weston
  • justdoGIT/weston
  • ajax/weston
  • pmenzel/weston
  • mominurisiamm887/weston
  • denix0/weston
  • ivyl/weston
  • fallahmahid.mahdi/weston
  • Alvarito050506/weston
  • obbardc/weston
  • joantolo/weston
  • zumbi/weston
  • doubleagent3276/weston
  • leoli/weston
  • dude/weston
  • cardenasvitealejandro/weston
  • ljia5/weston
  • Trigger.Huang/weston
  • swick/weston
  • Wladmis/weston
  • vyivel/weston
  • orbitcowboy/weston
  • AIDEA775/weston
  • maos20008/weston
  • mvicomoya/weston
  • bbrezillon/weston
  • wujiansun/weston
  • Benjamin_Loison/weston
  • rhelmot/weston
  • rgonzalez/weston
  • ekapllaj/weston
  • Shugyousha/weston
  • carbn/weston
  • derekf/weston
  • gyeyoung976/weston
  • dhobsong/weston
  • jeri.li/weston
  • mtey/weston
  • etom/weston
  • azeps/weston
  • champagneg/weston
  • makepost/weston
  • trem/weston
  • hwentland/weston
  • Ambyjkl/weston
  • YDinhVan/weston
  • pixellon/weston
  • daniels/weston
  • OctopusET/weston
  • emersion/weston
  • gilvbp/weston
  • yadneshk/weston
  • mvlad/weston
  • wayland/weston
  • phreer/weston
  • diegonieto/weston
  • vliaskov/weston
  • Vivek/weston
  • sami/weston
  • creiter/weston
  • luigi.santivetti/weston
  • aknautiyal/weston
  • martinetd/weston
  • 5HT/weston
  • yayowd/qimm
  • khangtb/weston
  • Laplac2/weston
  • pritbisw/weston
  • molinari/weston
  • vvavrychuk/weston
  • zzyiwei/weston
  • vanvugt/weston
  • pq/weston
  • qaqsw24/weston
  • gfxstrand/weston
  • alex.kanavin/weston
  • pinchyguey45/weston
  • davidre/weston
  • bigbear1385/weston
  • zzag/weston
  • benh/weston
  • harpreetbasra1313/weston
  • phomes/weston
  • rmader/weston
  • Heartyharts/weston
  • arandomhuman/weston
  • kchibisov/weston
  • hwti/weston
  • abhinavk/weston
  • vitalyp/weston
  • pedestrianlove/weston
  • sardemff7/weston
  • Ivaniku/tayland
  • JoseExposito/weston
  • zeerd/weston
  • jadahl/weston
  • sophia/weston
  • mol/weston
  • rawoul/weston
  • maxice8/weston
  • whot/weston
  • Qingwu-Li/weston
  • lfrb/weston
  • heftig/weston
  • Calandracas/weston
  • SergioGDR/weston
  • Foreal/weston
  • ghishadow/weston
  • puhui/weston
  • dmitry.batrak1/weston
  • fanbaby6/weston
  • chiragkhurana/weston
  • amaksoft/weston
  • surban/weston
  • smit-mayani/weston
  • jwillikers/weston
  • meshki022/weston
  • pritamabiswas/weston
  • antonino/weston
  • k77951586/weston
  • ChaoGuo/weston
  • ColinKinloch/weston
  • paraaz4959/weston
  • ivan.nikolaenko/weston
  • adarshgm/weston
  • ericruei/weston
  • harishkrupo/weston
  • VKadasani/weston
  • jameshilliard/weston
  • davidedmundson/weston
  • strassek/weston
  • flto/weston
  • Kishore409/weston
  • ktullavik/weston
  • Eugeniy.Paltsev/weston
  • sameer.lattannavar/weston
  • jesstindean85/weston
  • ashie/weston
  • Zamundaaa/weston
  • jlindgren90/weston
  • LARathbone/weston
  • g0hl1n/weston
  • matth/weston
  • nicolesager7/weston
  • hitong602/weston
  • Rpegusus2233/weston
  • bentiss/weston
  • hthiery/weston
  • thewayoftherob/weston
  • ofourdan/weston
  • enunes/weston
  • tomek/weston
  • bugaevc/weston
  • eero-t/weston
304 results
Show changes
Commits on Source (29)
Showing
with 869 additions and 387 deletions
......@@ -105,6 +105,7 @@ build-native-meson-default-options:
-Doptimization=0
-Db_coverage=true
-Dwerror=true
-Dtest-skip-is-failure=true
extends: .build-native-meson
after_script:
- ninja -C build-* coverage-html
......
......@@ -66,7 +66,6 @@
#define OPT_MANDELBROT (1 << 2) /* render mandelbrot */
#define OPT_DIRECT_DISPLAY (1 << 3) /* direct-display */
#define BUFFER_FORMAT DRM_FORMAT_XRGB8888
#define MAX_BUFFER_PLANES 4
struct display {
......@@ -78,6 +77,7 @@ struct display {
struct zwp_linux_dmabuf_v1 *dmabuf;
struct weston_direct_display_v1 *direct_display;
struct zwp_linux_explicit_synchronization_v1 *explicit_sync;
uint32_t format;
uint64_t *modifiers;
int modifiers_count;
int req_dmabuf_immediate;
......@@ -337,7 +337,7 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer,
buffer->display = display;
buffer->width = width;
buffer->height = height;
buffer->format = BUFFER_FORMAT;
buffer->format = display->format;
buffer->release_fence_fd = -1;
#ifdef HAVE_GBM_MODIFIERS
......@@ -998,16 +998,12 @@ dmabuf_modifiers(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
{
struct display *d = data;
switch (format) {
case BUFFER_FORMAT:
if (format == d->format) {
++d->modifiers_count;
d->modifiers = realloc(d->modifiers,
d->modifiers_count * sizeof(*d->modifiers));
d->modifiers[d->modifiers_count - 1] =
((uint64_t)modifier_hi << 32) | modifier_lo;
break;
default:
break;
}
}
......@@ -1270,7 +1266,7 @@ display_update_supported_modifiers_for_egl(struct display *d)
if (try_modifiers) {
ret = d->egl.query_dma_buf_modifiers(d->egl.display,
BUFFER_FORMAT,
d->format,
0, /* max_modifiers */
NULL, /* modifiers */
NULL, /* external_only */
......@@ -1295,7 +1291,7 @@ display_update_supported_modifiers_for_egl(struct display *d)
egl_modifiers = zalloc(num_egl_modifiers * sizeof(*egl_modifiers));
ret = d->egl.query_dma_buf_modifiers(d->egl.display,
BUFFER_FORMAT,
d->format,
num_egl_modifiers,
egl_modifiers,
NULL, /* external_only */
......@@ -1355,7 +1351,7 @@ display_set_up_gbm(struct display *display, char const* drm_render_node)
}
static struct display *
create_display(char const *drm_render_node, int opts)
create_display(char const *drm_render_node, uint32_t format, int opts)
{
struct display *display = NULL;
......@@ -1370,6 +1366,7 @@ create_display(char const *drm_render_node, int opts)
display->display = wl_display_connect(NULL);
assert(display->display);
display->format = format;
display->req_dmabuf_immediate = opts & OPT_IMMEDIATE;
display->registry = wl_display_get_registry(display->display);
......@@ -1384,7 +1381,8 @@ create_display(char const *drm_render_node, int opts)
wl_display_roundtrip(display->display);
if (!display->modifiers_count) {
fprintf(stderr, "format XRGB8888 is not available\n");
fprintf(stderr, "format 0x%"PRIX32" is not available\n",
display->format);
goto error;
}
......@@ -1450,6 +1448,8 @@ print_usage_and_exit(void)
"\t'-e,--explicit-sync=<>'"
"\n\t\t0 to disable explicit sync, "
"\n\t\t1 to enable explicit sync (default: 1)\n"
"\t'-f,--format=0x<>'"
"\n\t\tthe DRM format code to use\n"
"\t'-m,--mandelbrot'"
"\n\t\trender a mandelbrot set with multiple draw calls\n"
"\t'-g,--direct-display'"
......@@ -1479,6 +1479,7 @@ main(int argc, char **argv)
struct sigaction sigint;
struct display *display;
struct window *window;
uint32_t format = DRM_FORMAT_XRGB8888;
int opts = 0;
char const *drm_render_node = "/dev/dri/renderD128";
int c, option_index, ret = 0;
......@@ -1489,13 +1490,14 @@ main(int argc, char **argv)
{"drm-render-node", required_argument, 0, 'd' },
{"size", required_argument, 0, 's' },
{"explicit-sync", required_argument, 0, 'e' },
{"format", required_argument, 0, 'f' },
{"mandelbrot", no_argument, 0, 'm' },
{"direct-display", no_argument, 0, 'g' },
{"help", no_argument , 0, 'h' },
{0, 0, 0, 0}
};
while ((c = getopt_long(argc, argv, "hi:d:s:e:mg",
while ((c = getopt_long(argc, argv, "hi:d:s:e:f:mg",
long_options, &option_index)) != -1) {
switch (c) {
case 'i':
......@@ -1518,12 +1520,15 @@ main(int argc, char **argv)
case 'g':
opts |= OPT_DIRECT_DISPLAY;
break;
case 'f':
format = strtoul(optarg, NULL, 0);
break;
default:
print_usage_and_exit();
}
}
display = create_display(drm_render_node, opts);
display = create_display(drm_render_node, format, opts);
if (!display)
return 1;
window = create_window(display, window_size, window_size, opts);
......
......@@ -779,9 +779,13 @@ static const struct {
uint32_t bit; /* enum weston_capability */
const char *desc;
} capability_strings[] = {
{ WESTON_CAP_ROTATION_ANY, "arbitrary surface rotation:" },
{ WESTON_CAP_CAPTURE_YFLIP, "screen capture uses y-flip:" },
{ WESTON_CAP_COLOR_OPS, "color operations:" },
{ WESTON_CAP_ROTATION_ANY, "arbitrary surface rotation" },
{ WESTON_CAP_CAPTURE_YFLIP, "screen capture uses y-flip" },
{ WESTON_CAP_CURSOR_PLANE, "cursor planes" },
{ WESTON_CAP_ARBITRARY_MODES, "arbitrary resolutions" },
{ WESTON_CAP_VIEW_CLIP_MASK, "view mask clipping" },
{ WESTON_CAP_EXPLICIT_SYNC, "explicit sync" },
{ WESTON_CAP_COLOR_OPS, "color operations" },
};
static void
......@@ -794,7 +798,7 @@ weston_compositor_log_capabilities(struct weston_compositor *compositor)
weston_log("Compositor capabilities:\n");
for (i = 0; i < ARRAY_LENGTH(capability_strings); i++) {
yes = compositor->capabilities & capability_strings[i].bit;
weston_log_continue(STAMP_SPACE "%s %s\n",
weston_log_continue(STAMP_SPACE "%s: %s\n",
capability_strings[i].desc,
yes ? "yes" : "no");
}
......@@ -812,6 +816,33 @@ weston_compositor_log_capabilities(struct weston_compositor *compositor)
"presentation clock resolution: N/A\n");
}
static bool
check_compositor_capabilities(struct weston_compositor *compositor,
uint32_t mask)
{
uint32_t missing = mask & ~compositor->capabilities;
unsigned i;
if (missing == 0)
return true;
weston_log("Quirk error, missing capabilities:\n");
for (i = 0; i < ARRAY_LENGTH(capability_strings); i++) {
if (!(missing & capability_strings[i].bit))
continue;
weston_log_continue(STAMP_SPACE "- %s\n",
capability_strings[i].desc);
missing &= ~capability_strings[i].bit;
}
if (missing) {
weston_log_continue(STAMP_SPACE "- unlisted bits 0x%x\n",
missing);
}
return false;
}
static void
handle_primary_client_destroyed(struct wl_listener *listener, void *data)
{
......@@ -3351,6 +3382,12 @@ wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data)
goto out;
}
if (test_data && !check_compositor_capabilities(wet.compositor,
test_data->test_quirks.required_capabilities)) {
ret = WET_MAIN_RET_MISSING_CAPS;
goto out;
}
weston_compositor_flush_heads_changed(wet.compositor);
if (wet.init_failed)
goto out;
......
......@@ -95,6 +95,12 @@ text_backend_init(struct weston_compositor *ec);
void
text_backend_destroy(struct text_backend *text_backend);
/*
* Return value from wet_main() when
* weston_testsuite_quirks::required_capabilities are not met.
*/
#define WET_MAIN_RET_MISSING_CAPS 77
int
wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data);
......
......@@ -50,7 +50,7 @@ SERIAL=$(udevadm info "$SYSPATH" --query=property | \
[ -z "$SERIAL" ] && exit 1
# You'd have this write a file instead.
echo "ACTION==\"add|change\",SUBSYSTEM==\"input\",ENV{ID_SERIAL}==\"$SERIAL\",ENV{LIBINPUT_CALIBRATION_MATRIX}=\"$MATRIX\""
echo "ACTION!=\"remove\",SUBSYSTEM==\"input\",ENV{ID_SERIAL}==\"$SERIAL\",ENV{LIBINPUT_CALIBRATION_MATRIX}=\"$MATRIX\""
# Then you'd tell udev to reload the rules:
#udevadm control --reload
......
......@@ -198,6 +198,8 @@ struct weston_testsuite_quirks {
bool gl_force_full_upload;
/** Ensure GL shadow fb is used, and always repaint it fully. */
bool gl_force_full_redraw_of_shadow_fb;
/** Required enum weston_capability bit mask, otherwise skip run. */
uint32_t required_capabilities;
};
/** Weston test suite data that is given to compositor
......
......@@ -35,6 +35,8 @@
#include "shared/helpers.h"
#include "util.h"
#include <libweston/xwayland-api.h>
static struct kiosk_shell_surface *
get_kiosk_shell_surface(struct weston_surface *surface)
{
......@@ -63,6 +65,35 @@ get_kiosk_shell_seat(struct weston_seat *seat)
struct kiosk_shell_seat, seat_destroy_listener);
}
static void
transform_handler(struct wl_listener *listener, void *data)
{
struct weston_surface *surface = data;
struct kiosk_shell_surface *shsurf = get_kiosk_shell_surface(surface);
const struct weston_xwayland_surface_api *api;
int x, y;
if (!shsurf)
return;
api = shsurf->shell->xwayland_surface_api;
if (!api) {
api = weston_xwayland_surface_get_api(shsurf->shell->compositor);
shsurf->shell->xwayland_surface_api = api;
}
if (!api || !api->is_xwayland_surface(surface))
return;
if (!weston_view_is_mapped(shsurf->view))
return;
x = shsurf->view->geometry.x;
y = shsurf->view->geometry.y;
api->send_position(surface, x, y);
}
/*
* kiosk_shell_surface
*/
......@@ -427,6 +458,9 @@ kiosk_shell_output_recreate_background(struct kiosk_shell_output *shoutput)
{
struct kiosk_shell *shell = shoutput->shell;
struct weston_output *output = shoutput->output;
struct weston_config_section *shell_section = NULL;
uint32_t bg_color = 0x0;
float r, g, b;
if (shoutput->background_view)
weston_surface_destroy(shoutput->background_view->surface);
......@@ -434,9 +468,19 @@ kiosk_shell_output_recreate_background(struct kiosk_shell_output *shoutput)
if (!output)
return;
if (shell->config)
shell_section = weston_config_get_section(shell->config, "shell", NULL, NULL);
if (shell_section)
weston_config_section_get_color(shell_section, "background-color",
&bg_color, 0x00000000);
r = ((bg_color >> 16) & 0xff) / 255.0;
b = ((bg_color >> 8) & 0xff) / 255.0,
g = ((bg_color >> 0) & 0xff) / 255.0;
shoutput->background_view =
create_colored_surface(shoutput->shell->compositor,
0.5, 0.5, 0.5,
r, g, b,
output->x, output->y,
output->width,
output->height);
......@@ -1015,6 +1059,7 @@ kiosk_shell_destroy(struct wl_listener *listener, void *data)
wl_list_remove(&shell->output_resized_listener.link);
wl_list_remove(&shell->output_moved_listener.link);
wl_list_remove(&shell->seat_created_listener.link);
wl_list_remove(&shell->transform_listener.link);
wl_list_for_each_safe(shoutput, tmp, &shell->output_list, link) {
kiosk_shell_output_destroy(shoutput);
......@@ -1036,6 +1081,7 @@ wet_shell_init(struct weston_compositor *ec,
struct kiosk_shell *shell;
struct weston_seat *seat;
struct weston_output *output;
const char *config_file;
shell = zalloc(sizeof *shell);
if (shell == NULL)
......@@ -1050,6 +1096,12 @@ wet_shell_init(struct weston_compositor *ec,
return 0;
}
shell->transform_listener.notify = transform_handler;
wl_signal_add(&ec->transform_signal, &shell->transform_listener);
config_file = weston_config_get_name_from_env();
shell->config = weston_config_parse(config_file);
weston_layer_init(&shell->background_layer, ec);
weston_layer_init(&shell->normal_layer, ec);
......@@ -1084,6 +1136,8 @@ wet_shell_init(struct weston_compositor *ec,
shell->output_moved_listener.notify = kiosk_shell_handle_output_moved;
wl_signal_add(&ec->output_moved_signal, &shell->output_moved_listener);
screenshooter_create(ec);
kiosk_shell_add_bindings(shell);
return 0;
......
......@@ -26,6 +26,7 @@
#include <libweston-desktop/libweston-desktop.h>
#include <libweston/libweston.h>
#include <libweston/config-parser.h>
struct kiosk_shell {
struct weston_compositor *compositor;
......@@ -36,12 +37,16 @@ struct kiosk_shell {
struct wl_listener output_resized_listener;
struct wl_listener output_moved_listener;
struct wl_listener seat_created_listener;
struct wl_listener transform_listener;
struct weston_layer background_layer;
struct weston_layer normal_layer;
struct wl_list output_list;
struct wl_list seat_list;
const struct weston_xwayland_surface_api *xwayland_surface_api;
struct weston_config *config;
};
struct kiosk_shell_surface {
......
......@@ -3203,10 +3203,6 @@ err_drm_source:
err_udev_input:
udev_input_destroy(&b->input);
err_sprite:
#ifdef BUILD_DRM_GBM
if (b->gbm)
gbm_device_destroy(b->gbm);
#endif
destroy_sprites(b);
err_create_crtc_list:
drmModeFreeResources(res);
......@@ -3218,6 +3214,10 @@ err_launcher:
weston_launcher_destroy(compositor->launcher);
err_compositor:
weston_compositor_shutdown(compositor);
#ifdef BUILD_DRM_GBM
if (b->gbm)
gbm_device_destroy(b->gbm);
#endif
free(b);
return NULL;
}
......
......@@ -306,6 +306,7 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state,
struct drm_plane *plane = output->cursor_plane;
struct drm_plane_state *plane_state;
bool needs_update = false;
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
const char *p_name = drm_output_get_plane_type_name(plane);
assert(!b->cursors_are_broken);
......@@ -337,6 +338,16 @@ drm_output_prepare_cursor_view(struct drm_output_state *output_state,
goto err;
}
if (buffer->width > b->cursor_width ||
buffer->height > b->cursor_height) {
drm_debug(b, "\t\t\t\t[%s] not assigning view %p to %s plane "
"(surface buffer (%dx%d) larger than permitted"
" (%dx%d))\n", p_name, ev, p_name,
buffer->width, buffer->height,
b->cursor_width, b->cursor_height);
goto err;
}
if (plane_state->src_x != 0 || plane_state->src_y != 0 ||
plane_state->src_w > (unsigned) b->cursor_width << 16 ||
plane_state->src_h > (unsigned) b->cursor_height << 16 ||
......
......@@ -45,6 +45,7 @@ struct weston_launcher {
const struct launcher_interface *iface;
};
extern const struct launcher_interface launcher_libseat_iface;
extern const struct launcher_interface launcher_logind_iface;
extern const struct launcher_interface launcher_weston_launch_iface;
extern const struct launcher_interface launcher_direct_iface;
/*
* Copyright © 2020 Kenny Levinsen
*
* 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 the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libseat.h>
#include <libweston/libweston.h>
#include "backend.h"
#include "dbus.h"
#include "launcher-impl.h"
struct launcher_libseat_device {
struct wl_list link;
int fd;
int device_id;
dev_t fsdev;
};
struct launcher_libseat {
struct weston_launcher base;
struct weston_compositor *compositor;
struct libseat *seat;
struct wl_event_source *seat_ctx;
struct wl_list devices;
};
static struct launcher_libseat_device *
find_device_by_fd(struct launcher_libseat *wl, int fd)
{
struct launcher_libseat_device *dev;
wl_list_for_each(dev, &wl->devices, link) {
if (dev->fd == fd) {
return dev;
}
}
return NULL;
}
static void
handle_enable_seat(struct libseat *seat, void *data)
{
struct launcher_libseat *wl = data;
if (wl->compositor->session_active)
return;
wl->compositor->session_active = true;
wl_signal_emit(&wl->compositor->session_signal,
wl->compositor);
}
static void
handle_disable_seat(struct libseat *seat, void *data)
{
struct launcher_libseat *wl = data;
if (!wl->compositor->session_active)
return;
wl->compositor->session_active = false;
wl_signal_emit(&wl->compositor->session_signal,
wl->compositor);
libseat_disable_seat(wl->seat);
}
static struct libseat_seat_listener seat_listener = {
.enable_seat = handle_enable_seat,
.disable_seat = handle_disable_seat,
};
static int
seat_open_device(struct weston_launcher *launcher, const char *path, int flags)
{
struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
struct launcher_libseat_device *dev;
struct stat st;
dev = zalloc(sizeof(struct launcher_libseat_device));
if (dev == NULL) {
goto err_alloc;
}
dev->device_id = libseat_open_device(wl->seat, path, &dev->fd);
if (dev->device_id == -1) {
goto err_open;
}
if (fstat(dev->fd, &st) == -1) {
goto err_fd;
}
dev->fsdev = st.st_rdev;
wl_list_insert(&wl->devices, &dev->link);
return dev->fd;
err_fd:
libseat_close_device(wl->seat, dev->device_id);
close(dev->fd);
err_open:
free(dev);
err_alloc:
return -1;
}
static void
seat_close_device(struct weston_launcher *launcher, int fd)
{
struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
struct launcher_libseat_device *dev;
dev = find_device_by_fd(wl, fd);
if (dev == NULL) {
weston_log("libseat: No device with fd %d found\n", fd);
close(fd);
return;
}
if (libseat_close_device(wl->seat, dev->device_id) == -1) {
weston_log("libseat: Could not close device %d",
dev->device_id);
}
wl_list_remove(&dev->link);
free(dev);
close(fd);
}
static int
seat_switch_session(struct weston_launcher *launcher, int vt)
{
struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
return libseat_switch_session(wl->seat, vt);
}
static int
libseat_event(int fd, uint32_t mask, void *data)
{
struct libseat *seat = data;
if (libseat_dispatch(seat, 0) == -1) {
weston_log("libseat: dispatch failed: %s\n", strerror(errno));
exit(-1);
}
return 1;
}
static int
seat_open(struct weston_launcher **out, struct weston_compositor *compositor,
int tty, const char *seat_id, bool sync_drm)
{
struct launcher_libseat *wl;
struct wl_event_loop *event_loop;
wl = zalloc(sizeof(*wl));
if (wl == NULL) {
goto err_out;
}
wl->base.iface = &launcher_libseat_iface;
wl->compositor = compositor;
wl_list_init(&wl->devices);
wl->seat = libseat_open_seat(&seat_listener, wl);
if (wl->seat == NULL) {
weston_log("libseat: could not open seat\n");
goto err_seat;
}
event_loop = wl_display_get_event_loop(compositor->wl_display);
wl->seat_ctx = wl_event_loop_add_fd(event_loop,
libseat_get_fd(wl->seat), WL_EVENT_READABLE,
libseat_event, wl->seat);
if (wl->seat_ctx == NULL) {
weston_log("libseat: could not register connection to event loop\n");
goto err_session;
}
if (libseat_dispatch(wl->seat, 0) == -1) {
weston_log("libseat: dispatch failed\n");
goto err_session;
}
weston_log("libseat: session control granted\n");
*out = &wl->base;
return 0;
err_session:
libseat_close_seat(wl->seat);
err_seat:
free(wl);
err_out:
return -1;
}
static void
seat_close(struct weston_launcher *launcher)
{
struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
if (wl->seat != NULL) {
libseat_close_seat(wl->seat);
}
wl_event_source_remove(wl->seat_ctx);
free(wl);
}
static int
seat_get_vt(struct weston_launcher *launcher)
{
return -ENOSYS;
}
const struct launcher_interface launcher_libseat_iface = {
.name = "libseat",
.connect = seat_open,
.destroy = seat_close,
.open = seat_open_device,
.close = seat_close_device,
.activate_vt = seat_switch_session,
.get_vt = seat_get_vt,
};
......@@ -860,6 +860,9 @@ static int
launcher_logind_get_vt(struct weston_launcher *launcher)
{
struct launcher_logind *wl = wl_container_of(launcher, wl, base);
if (wl->vtnr <= 0) {
return -EINVAL;
}
return wl->vtnr;
}
......
......@@ -31,11 +31,15 @@
#include "launcher-util.h"
#include "launcher-impl.h"
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/input.h>
static const struct launcher_interface *ifaces[] = {
#ifdef HAVE_LIBSEAT
&launcher_libseat_iface,
#endif
#ifdef HAVE_SYSTEMD_LOGIN
&launcher_logind_iface,
#endif
......@@ -104,10 +108,12 @@ switch_vt_binding(struct weston_keyboard *keyboard,
WL_EXPORT void
weston_setup_vt_switch_bindings(struct weston_compositor *compositor)
{
int ret;
uint32_t key;
struct weston_launcher *launcher = compositor->launcher;
if (launcher->iface->get_vt(launcher) <= 0)
ret = launcher->iface->get_vt(launcher);
if (ret < 0 && ret != -ENOSYS)
return;
if (compositor->vt_switching == false)
......
......@@ -88,11 +88,11 @@ union cmsg_data { unsigned char b[4]; int fd; };
struct launcher_weston_launch {
struct weston_launcher base;
struct weston_compositor *compositor;
struct wl_event_loop *loop;
int fd;
struct wl_event_source *source;
int kb_mode, tty, drm_fd;
int deferred_deactivate;
};
static ssize_t
......@@ -107,12 +107,36 @@ launcher_weston_launch_send(int sockfd, void *buf, size_t buflen)
return len;
}
static void
handle_deactivate(struct launcher_weston_launch *launcher)
{
int reply;
launcher->compositor->session_active = false;
wl_signal_emit(&launcher->compositor->session_signal,
launcher->compositor);
reply = WESTON_LAUNCHER_DEACTIVATE_DONE;
launcher_weston_launch_send(launcher->fd, &reply, sizeof reply);
}
static void
idle_deactivate(void *data)
{
struct launcher_weston_launch *launcher = data;
if (launcher->deferred_deactivate) {
launcher->deferred_deactivate = 0;
handle_deactivate((struct launcher_weston_launch*)data);
}
}
static int
launcher_weston_launch_open(struct weston_launcher *launcher_base,
const char *path, int flags)
{
struct launcher_weston_launch *launcher = wl_container_of(launcher_base, launcher, base);
int n, ret;
int n;
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov;
......@@ -120,6 +144,7 @@ launcher_weston_launch_open(struct weston_launcher *launcher_base,
char control[CMSG_SPACE(sizeof data->fd)];
ssize_t len;
struct weston_launcher_open *message;
struct { int id; int ret; } event;
n = sizeof(*message) + strlen(path) + 1;
message = malloc(n);
......@@ -134,19 +159,33 @@ launcher_weston_launch_open(struct weston_launcher *launcher_base,
free(message);
memset(&msg, 0, sizeof msg);
iov.iov_base = &ret;
iov.iov_len = sizeof ret;
iov.iov_base = &event;
iov.iov_len = sizeof event;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = control;
msg.msg_controllen = sizeof control;
do {
len = recvmsg(launcher->fd, &msg, MSG_CMSG_CLOEXEC);
} while (len < 0 && errno == EINTR);
while (1) {
msg.msg_controllen = sizeof control;
do {
len = recvmsg(launcher->fd, &msg, MSG_CMSG_CLOEXEC);
} while (len < 0 && errno == EINTR);
// Only OPEN_REPLY and up to one DEACTIVATE message should be possible here
if ((len == sizeof event) && (event.id == WESTON_LAUNCHER_OPEN_REPLY))
break;
if ((len == sizeof event.id) && (event.id == WESTON_LAUNCHER_DEACTIVATE) && (launcher->deferred_deactivate == 0)) {
wl_event_loop_add_idle(wl_display_get_event_loop(launcher->compositor->wl_display), idle_deactivate, launcher);
launcher->deferred_deactivate = 1;
} else {
weston_log("unexpected event %d (len=%zd) from weston-launch\n", event.id, len);
return -1;
}
}
if (len != sizeof ret ||
ret < 0)
if (event.ret < 0)
return -1;
cmsg = CMSG_FIRSTHDR(&msg);
......@@ -201,7 +240,7 @@ static int
launcher_weston_launch_data(int fd, uint32_t mask, void *data)
{
struct launcher_weston_launch *launcher = data;
int len, ret, reply;
int len, ret;
if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) {
weston_log("launcher socket closed, exiting\n");
......@@ -212,6 +251,12 @@ launcher_weston_launch_data(int fd, uint32_t mask, void *data)
exit(-1);
}
if (launcher->deferred_deactivate) {
launcher->deferred_deactivate = 0;
handle_deactivate(launcher);
return 1;
}
do {
len = recv(launcher->fd, &ret, sizeof ret, 0);
} while (len < 0 && errno == EINTR);
......@@ -223,13 +268,7 @@ launcher_weston_launch_data(int fd, uint32_t mask, void *data)
launcher->compositor);
break;
case WESTON_LAUNCHER_DEACTIVATE:
launcher->compositor->session_active = false;
wl_signal_emit(&launcher->compositor->session_signal,
launcher->compositor);
reply = WESTON_LAUNCHER_DEACTIVATE_DONE;
launcher_weston_launch_send(launcher->fd, &reply, sizeof reply);
handle_deactivate(launcher);
break;
default:
weston_log("unexpected event from weston-launch\n");
......@@ -287,6 +326,7 @@ launcher_weston_launch_connect(struct weston_launcher **out, struct weston_compo
* (struct launcher_weston_launch **) out = launcher;
launcher->compositor = compositor;
launcher->drm_fd = -1;
launcher->deferred_deactivate = 0;
launcher->fd = launcher_weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
if (launcher->fd != -1) {
launcher->tty = launcher_weston_environment_get_fd("WESTON_TTY_FD");
......
......@@ -180,6 +180,16 @@ if get_option('launcher-logind')
systemd_dep,
]
endif
if get_option('launcher-libseat')
libseat_dep = dependency('libseat', version: '>= 0.4')
config_h.set('HAVE_LIBSEAT', '1')
srcs_session_helper += [
'launcher-libseat.c',
]
deps_session_helper += [
libseat_dep,
]
endif
lib_session_helper = static_library(
'session-helper',
......
......@@ -38,7 +38,7 @@
#include "wayland-util.h"
#include "pixel-formats.h"
#if ENABLE_EGL
#ifdef ENABLE_EGL
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
......
......@@ -74,16 +74,17 @@ static_assert(sizeof(struct gl_shader_requirements) ==
4 /* total bitfield size in bytes */,
"struct gl_shader_requirements must not contain implicit padding");
struct gl_shader {
struct gl_shader_requirements key;
GLuint program;
GLuint vertex_shader, fragment_shader;
GLint proj_uniform;
GLint tex_uniforms[3];
GLint alpha_uniform;
GLint color_uniform;
struct wl_list link; /* gl_renderer::shader_list */
struct timespec last_used;
struct gl_shader;
#define GL_SHADER_INPUT_TEX_MAX 3
struct gl_shader_config {
struct gl_shader_requirements req;
struct weston_matrix projection;
float view_alpha;
GLfloat unicolor[4];
GLint input_tex_filter; /* GL_NEAREST or GL_LINEAR */
GLuint input_tex[GL_SHADER_INPUT_TEX_MAX];
};
struct gl_renderer {
......@@ -198,16 +199,24 @@ gl_renderer_setup_egl_client_extensions(struct gl_renderer *gr);
int
gl_renderer_setup_egl_extensions(struct weston_compositor *ec);
GLenum
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v);
void
gl_shader_destroy(struct gl_renderer *gr, struct gl_shader *shader);
void
gl_renderer_shader_list_destroy(struct gl_renderer *gr);
struct gl_shader *
gl_shader_create(struct gl_renderer *gr,
const struct gl_shader_requirements *requirements);
gl_renderer_create_fallback_shader(struct gl_renderer *gr);
int
gl_shader_requirements_cmp(const struct gl_shader_requirements *a,
const struct gl_shader_requirements *b);
void
gl_renderer_garbage_collect_programs(struct gl_renderer *gr);
bool
gl_renderer_use_program(struct gl_renderer *gr,
const struct gl_shader_config *sconf);
struct weston_log_scope *
gl_shader_scope_create(struct gl_renderer *gr);
......
This diff is collapsed.
......@@ -50,6 +50,18 @@
/* static const char fragment_shader[]; fragment.glsl */
#include "fragment-shader.h"
struct gl_shader {
struct gl_shader_requirements key;
GLuint program;
GLuint vertex_shader, fragment_shader;
GLint proj_uniform;
GLint tex_uniforms[3];
GLint alpha_uniform;
GLint color_uniform;
struct wl_list link; /* gl_renderer::shader_list */
struct timespec last_used;
};
static const char *
gl_shader_texture_variant_to_string(enum gl_shader_texture_variant v)
{
......@@ -159,7 +171,7 @@ create_shader_config_string(const struct gl_shader_requirements *req)
return str;
}
struct gl_shader *
static struct gl_shader *
gl_shader_create(struct gl_renderer *gr,
const struct gl_shader_requirements *requirements)
{
......@@ -268,7 +280,16 @@ gl_shader_destroy(struct gl_renderer *gr, struct gl_shader *shader)
free(shader);
}
int
void
gl_renderer_shader_list_destroy(struct gl_renderer *gr)
{
struct gl_shader *shader, *next_shader;
wl_list_for_each_safe(shader, next_shader, &gr->shader_list, link)
gl_shader_destroy(gr, shader);
}
static int
gl_shader_requirements_cmp(const struct gl_shader_requirements *a,
const struct gl_shader_requirements *b)
{
......@@ -322,3 +343,155 @@ gl_shader_scope_create(struct gl_renderer *gr)
NULL,
gr);
}
struct gl_shader *
gl_renderer_create_fallback_shader(struct gl_renderer *gr)
{
static const struct gl_shader_requirements fallback_requirements = {
.variant = SHADER_VARIANT_SOLID,
};
struct gl_shader *shader;
shader = gl_shader_create(gr, &fallback_requirements);
if (!shader)
return NULL;
/*
* This shader must be exempt from any automatic garbage collection.
* It is destroyed explicitly.
*/
wl_list_remove(&shader->link);
wl_list_init(&shader->link);
return shader;
}
static struct gl_shader *
gl_renderer_get_program(struct gl_renderer *gr,
const struct gl_shader_requirements *requirements)
{
struct gl_shader_requirements reqs = *requirements;
struct gl_shader *shader;
assert(reqs.pad_bits_ == 0);
if (gr->fragment_shader_debug)
reqs.green_tint = true;
if (gr->current_shader &&
gl_shader_requirements_cmp(&reqs, &gr->current_shader->key) == 0)
return gr->current_shader;
wl_list_for_each(shader, &gr->shader_list, link) {
if (gl_shader_requirements_cmp(&reqs, &shader->key) == 0)
return shader;
}
shader = gl_shader_create(gr, &reqs);
if (shader)
return shader;
return NULL;
}
void
gl_renderer_garbage_collect_programs(struct gl_renderer *gr)
{
struct gl_shader *shader, *tmp;
unsigned count = 0;
wl_list_for_each_safe(shader, tmp, &gr->shader_list, link) {
/* Keep the 10 most recently used always. */
if (count++ < 10)
continue;
/* Keep everything used in the past 1 minute. */
if (timespec_sub_to_msec(&gr->compositor->last_repaint_start,
&shader->last_used) < 60000)
continue;
/* The rest throw away. */
gl_shader_destroy(gr, shader);
}
}
GLenum
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v)
{
if (v == SHADER_VARIANT_EXTERNAL)
return GL_TEXTURE_EXTERNAL_OES;
else
return GL_TEXTURE_2D;
}
static void
gl_shader_load_config(struct gl_shader *shader,
const struct gl_shader_config *sconf)
{
GLint in_filter = sconf->input_tex_filter;
GLenum in_tgt;
int i;
glUniformMatrix4fv(shader->proj_uniform,
1, GL_FALSE, sconf->projection.d);
glUniform4fv(shader->color_uniform, 1, sconf->unicolor);
glUniform1f(shader->alpha_uniform, sconf->view_alpha);
in_tgt = gl_shader_texture_variant_get_target(sconf->req.variant);
for (i = 0; i < GL_SHADER_INPUT_TEX_MAX; i++) {
if (sconf->input_tex[i] == 0)
continue;
assert(shader->tex_uniforms[i] != -1);
glUniform1i(shader->tex_uniforms[i], i);
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(in_tgt, sconf->input_tex[i]);
glTexParameteri(in_tgt, GL_TEXTURE_MIN_FILTER, in_filter);
glTexParameteri(in_tgt, GL_TEXTURE_MAG_FILTER, in_filter);
}
}
bool
gl_renderer_use_program(struct gl_renderer *gr,
const struct gl_shader_config *sconf)
{
static const GLfloat fallback_shader_color[4] = { 0.2, 0.1, 0.0, 1.0 };
struct gl_shader *shader;
shader = gl_renderer_get_program(gr, &sconf->req);
if (!shader) {
weston_log("Error: failed to generate shader program.\n");
gr->current_shader = NULL;
/*
* We only have one fallback shader, so it cannot do correct
* color on color managed outputs. Hence, what is painted
* with this one will have undefined look. Therefore the
* fallback is important to not be too bright as that might
* be shocking on a monitor in HDR mode.
*/
shader = gr->fallback_shader;
glUseProgram(shader->program);
glUniform4fv(shader->color_uniform, 1, fallback_shader_color);
glUniform1f(shader->alpha_uniform, 1.0f);
return false;
}
if (shader != gr->fallback_shader) {
/* Update list order for most recently used. */
wl_list_remove(&shader->link);
wl_list_insert(&gr->shader_list, &shader->link);
}
shader->last_used = gr->compositor->last_repaint_start;
if (gr->current_shader != shader) {
glUseProgram(shader->program);
gr->current_shader = shader;
}
gl_shader_load_config(shader, sconf);
return true;
}