diff --git a/compositor/cms-colord.c b/compositor/cms-colord.c index 0daa2a7e..f421773b 100644 --- a/compositor/cms-colord.c +++ b/compositor/cms-colord.c @@ -102,22 +102,23 @@ edid_value_valid(const char *str) static gchar * get_output_id(struct cms_colord *cms, struct weston_output *o) { + struct weston_head *head = &o->head; const gchar *tmp; GString *device_id; /* see https://github.com/hughsie/colord/blob/master/doc/device-and-profile-naming-spec.txt * for format and allowed values */ device_id = g_string_new("xrandr"); - if (edid_value_valid(o->make)) { - tmp = g_hash_table_lookup(cms->pnp_ids, o->make); + if (edid_value_valid(head->make)) { + tmp = g_hash_table_lookup(cms->pnp_ids, head->make); if (tmp == NULL) - tmp = o->make; + tmp = head->make; g_string_append_printf(device_id, "-%s", tmp); } - if (edid_value_valid(o->model)) - g_string_append_printf(device_id, "-%s", o->model); - if (edid_value_valid(o->serial_number)) - g_string_append_printf(device_id, "-%s", o->serial_number); + if (edid_value_valid(head->model)) + g_string_append_printf(device_id, "-%s", head->model); + if (edid_value_valid(head->serial_number)) + g_string_append_printf(device_id, "-%s", head->serial_number); /* no EDID data, so use fallback */ if (strcmp(device_id->str, "xrandr") == 0) @@ -230,6 +231,7 @@ colord_notifier_output_destroy(struct wl_listener *listener, void *data) static void colord_output_created(struct cms_colord *cms, struct weston_output *o) { + struct weston_head *head = &o->head; CdDevice *device; const gchar *tmp; gchar *device_id; @@ -251,25 +253,25 @@ colord_output_created(struct cms_colord *cms, struct weston_output *o) g_hash_table_insert (device_props, g_strdup(CD_DEVICE_PROPERTY_COLORSPACE), g_strdup(cd_colorspace_to_string(CD_COLORSPACE_RGB))); - if (edid_value_valid(o->make)) { - tmp = g_hash_table_lookup(cms->pnp_ids, o->make); + if (edid_value_valid(head->make)) { + tmp = g_hash_table_lookup(cms->pnp_ids, head->make); if (tmp == NULL) - tmp = o->make; + tmp = head->make; g_hash_table_insert (device_props, g_strdup(CD_DEVICE_PROPERTY_VENDOR), g_strdup(tmp)); } - if (edid_value_valid(o->model)) { + if (edid_value_valid(head->model)) { g_hash_table_insert (device_props, g_strdup(CD_DEVICE_PROPERTY_MODEL), - g_strdup(o->model)); + g_strdup(head->model)); } - if (edid_value_valid(o->serial_number)) { + if (edid_value_valid(head->serial_number)) { g_hash_table_insert (device_props, g_strdup(CD_DEVICE_PROPERTY_SERIAL), - g_strdup(o->serial_number)); + g_strdup(head->serial_number)); } - if (o->connection_internal) { + if (head->connection_internal) { g_hash_table_insert (device_props, g_strdup (CD_DEVICE_PROPERTY_EMBEDDED), NULL); diff --git a/configure.ac b/configure.ac index cde4564e..da3f7342 100644 --- a/configure.ac +++ b/configure.ac @@ -3,9 +3,9 @@ m4_define([weston_minor_version], [0]) m4_define([weston_micro_version], [90]) m4_define([weston_version], [weston_major_version.weston_minor_version.weston_micro_version]) -m4_define([libweston_major_version], [4]) +m4_define([libweston_major_version], [5]) m4_define([libweston_minor_version], [0]) -m4_define([libweston_patch_version], [90]) +m4_define([libweston_patch_version], [0]) AC_PREREQ([2.64]) AC_INIT([weston], diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index c09c49bf..4504c00c 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -4933,6 +4933,7 @@ create_output_for_connector(struct drm_backend *b, struct udev_device *drm_device) { struct drm_output *output; + struct weston_head *head; drmModeObjectPropertiesPtr props; struct drm_mode *drm_mode; char *name; @@ -4973,26 +4974,26 @@ create_output_for_connector(struct drm_backend *b, } drm_property_info_populate(b, connector_props, output->props_conn, WDRM_CONNECTOR__COUNT, props); + head = &output->base.head; find_and_parse_output_edid(b, output, props, &make, &model, &serial_number); - output->base.make = (char *)make; - output->base.model = (char *)model; - output->base.serial_number = (char *)serial_number; - output->base.subpixel = drm_subpixel_to_wayland(output->connector->subpixel); + weston_head_set_monitor_strings(head, make, model, serial_number); + weston_head_set_subpixel(head, + drm_subpixel_to_wayland(output->connector->subpixel)); drmModeFreeObjectProperties(props); if (output->connector->connector_type == DRM_MODE_CONNECTOR_LVDS || output->connector->connector_type == DRM_MODE_CONNECTOR_eDP) - output->base.connection_internal = true; + weston_head_set_internal(head); if (drm_output_init_gamma_size(output) < 0) goto err_output; - output->state_cur = drm_output_state_alloc(output, NULL); + weston_head_set_physical_size(head, output->connector->mmWidth, + output->connector->mmHeight); - output->base.mm_width = output->connector->mmWidth; - output->base.mm_height = output->connector->mmHeight; + output->state_cur = drm_output_state_alloc(output, NULL); for (i = 0; i < output->connector->count_modes; i++) { drm_mode = drm_output_add_mode(output, &output->connector->modes[i]); diff --git a/libweston/compositor-fbdev.c b/libweston/compositor-fbdev.c index c63b1fc1..7db95d21 100644 --- a/libweston/compositor-fbdev.c +++ b/libweston/compositor-fbdev.c @@ -499,6 +499,7 @@ fbdev_output_create(struct fbdev_backend *backend, const char *device) { struct fbdev_output *output; + struct weston_head *head; int fb_fd; weston_log("Creating fbdev output.\n"); @@ -532,12 +533,13 @@ fbdev_output_create(struct fbdev_backend *backend, wl_list_insert(&output->base.mode_list, &output->mode.link); output->base.current_mode = &output->mode; - output->base.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN; - output->base.make = "unknown"; - output->base.model = output->fb_info.id; - output->base.mm_width = output->fb_info.width_mm; - output->base.mm_height = output->fb_info.height_mm; + head = &output->base.head; + weston_head_set_monitor_strings(head, "unknown", output->fb_info.id, + NULL); + weston_head_set_subpixel(head, WL_OUTPUT_SUBPIXEL_UNKNOWN); + weston_head_set_physical_size(head, output->fb_info.width_mm, + output->fb_info.height_mm); close(fb_fd); diff --git a/libweston/compositor-headless.c b/libweston/compositor-headless.c index 9307a36a..d6ab9db9 100644 --- a/libweston/compositor-headless.c +++ b/libweston/compositor-headless.c @@ -185,6 +185,7 @@ headless_output_set_size(struct weston_output *base, int width, int height) { struct headless_output *output = to_headless_output(base); + struct weston_head *head = &output->base.head; int output_width, output_height; /* We can only be called once. */ @@ -204,12 +205,11 @@ headless_output_set_size(struct weston_output *base, wl_list_insert(&output->base.mode_list, &output->mode.link); output->base.current_mode = &output->mode; - output->base.make = "weston"; - output->base.model = "headless"; + + weston_head_set_monitor_strings(head, "weston", "headless", NULL); /* XXX: Calculate proper size. */ - output->base.mm_width = width; - output->base.mm_height = height; + weston_head_set_physical_size(head, width, height); output->base.start_repaint_loop = headless_output_start_repaint_loop; output->base.repaint = headless_output_repaint; diff --git a/libweston/compositor-rdp.c b/libweston/compositor-rdp.c index ee68e969..4d74d40c 100644 --- a/libweston/compositor-rdp.c +++ b/libweston/compositor-rdp.c @@ -482,6 +482,7 @@ rdp_output_set_size(struct weston_output *base, int width, int height) { struct rdp_output *output = to_rdp_output(base); + struct weston_head *head = &output->base.head; struct weston_mode *currentMode; struct weston_mode initMode; @@ -500,12 +501,11 @@ rdp_output_set_size(struct weston_output *base, return -1; output->base.current_mode = output->base.native_mode = currentMode; - output->base.make = "weston"; - output->base.model = "rdp"; + + weston_head_set_monitor_strings(head, "weston", "rdp", NULL); /* XXX: Calculate proper size. */ - output->base.mm_width = width; - output->base.mm_height = height; + weston_head_set_physical_size(head, width, height); output->base.start_repaint_loop = rdp_output_start_repaint_loop; output->base.repaint = rdp_output_repaint; diff --git a/libweston/compositor-wayland.c b/libweston/compositor-wayland.c index 111c4c09..fbb04dea 100644 --- a/libweston/compositor-wayland.c +++ b/libweston/compositor-wayland.c @@ -1313,6 +1313,7 @@ static int wayland_output_set_size(struct weston_output *base, int width, int height) { struct wayland_output *output = to_wayland_output(base); + struct weston_head *head = &output->base.head; int output_width, output_height; /* We can only be called once. */ @@ -1345,12 +1346,11 @@ wayland_output_set_size(struct weston_output *base, int width, int height) wl_list_insert(&output->base.mode_list, &output->mode.link); output->base.current_mode = &output->mode; - output->base.make = "wayland"; - output->base.model = "none"; + + weston_head_set_monitor_strings(head, "wayland", "none", NULL); /* XXX: Calculate proper size. */ - output->base.mm_width = width; - output->base.mm_height = height; + weston_head_set_physical_size(head, width, height); return 0; } @@ -1383,10 +1383,12 @@ wayland_output_create_for_parent_output(struct wayland_backend *b, output->parent.output = poutput->global; - output->base.make = poutput->physical.make; - output->base.model = poutput->physical.model; - output->base.mm_width = poutput->physical.width; - output->base.mm_height = poutput->physical.height; + weston_head_set_monitor_strings(&output->base.head, + poutput->physical.make, + poutput->physical.model, NULL); + weston_head_set_physical_size(&output->base.head, + poutput->physical.width, + poutput->physical.height); wl_list_insert_list(&output->base.mode_list, &poutput->mode_list); wl_list_init(&poutput->mode_list); diff --git a/libweston/compositor-x11.c b/libweston/compositor-x11.c index 14faeda0..de19fad8 100644 --- a/libweston/compositor-x11.c +++ b/libweston/compositor-x11.c @@ -1065,6 +1065,8 @@ x11_output_set_size(struct weston_output *base, int width, int height) { struct x11_output *output = to_x11_output(base); struct x11_backend *b = to_x11_backend(base->compositor); + struct weston_head *head = &output->base.head; + xcb_screen_t *scrn = b->screen; int output_width, output_height; /* We can only be called once. */ @@ -1099,16 +1101,13 @@ x11_output_set_size(struct weston_output *base, int width, int height) wl_list_insert(&output->base.mode_list, &output->mode.link); output->base.current_mode = &output->mode; - output->base.make = "weston-X11"; - output->base.model = "none"; - output->base.native_mode = &output->native; output->base.native_scale = output->base.scale; - output->base.mm_width = width * b->screen->width_in_millimeters / - b->screen->width_in_pixels; - output->base.mm_height = height * b->screen->height_in_millimeters / - b->screen->height_in_pixels; + weston_head_set_monitor_strings(head, "weston-X11", "none", NULL); + weston_head_set_physical_size(head, + width * scrn->width_in_millimeters / scrn->width_in_pixels, + height * scrn->height_in_millimeters / scrn->height_in_pixels); return 0; } diff --git a/libweston/compositor.c b/libweston/compositor.c index 4816f33e..3a50a33f 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -4315,6 +4315,7 @@ bind_output(struct wl_client *client, struct weston_output *output = data; struct weston_mode *mode; struct wl_resource *resource; + struct weston_head *head = &output->head; resource = wl_resource_create(client, &wl_output_interface, version, id); @@ -4329,10 +4330,10 @@ bind_output(struct wl_client *client, wl_output_send_geometry(resource, output->x, output->y, - output->mm_width, - output->mm_height, - output->subpixel, - output->make, output->model, + head->mm_width, + head->mm_height, + head->subpixel, + head->make, head->model, output->transform); if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) wl_output_send_scale(resource, @@ -4365,6 +4366,85 @@ weston_output_from_resource(struct wl_resource *resource) return wl_resource_get_user_data(resource); } +/** Store monitor make, model and serial number + * + * \param head The head to modify. + * \param make The monitor make. If EDID is available, the PNP ID. Otherwise + * any string, or NULL for none. + * \param model The monitor model or name, or a made-up string, or NULL for + * none. + * \param serialno The monitor serial number, a made-up string, or NULL for + * none. + * + * \memberof weston_head + * \internal + */ +WL_EXPORT void +weston_head_set_monitor_strings(struct weston_head *head, + const char *make, + const char *model, + const char *serialno) +{ + head->make = (char *)make; + head->model = (char *)model; + head->serial_number = (char *)serialno; +} + +/** Store physical image size + * + * \param head The head to modify. + * \param mm_width Image area width in millimeters. + * \param mm_height Image area height in millimeters. + * + * \memberof weston_head + * \internal + */ +WL_EXPORT void +weston_head_set_physical_size(struct weston_head *head, + int32_t mm_width, int32_t mm_height) +{ + head->mm_width = mm_width; + head->mm_height = mm_height; +} + +/** Store monitor sub-pixel layout + * + * \param head The head to modify. + * \param sp Sub-pixel layout. The possible values are: + * - WL_OUTPUT_SUBPIXEL_UNKNOWN, + * - WL_OUTPUT_SUBPIXEL_NONE, + * - WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB, + * - WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR, + * - WL_OUTPUT_SUBPIXEL_VERTICAL_RGB, + * - WL_OUTPUT_SUBPIXEL_VERTICAL_BGR + * + * \memberof weston_head + * \internal + */ +WL_EXPORT void +weston_head_set_subpixel(struct weston_head *head, + enum wl_output_subpixel sp) +{ + head->subpixel = sp; +} + +/** Mark the monitor as internal + * + * This is used for embedded screens, like laptop panels. + * + * \param head The head to mark as internal. + * + * By default a head is external. The type is often inferred from the physical + * connector type. + * + * \memberof weston_head + * \internal + */ +WL_EXPORT void +weston_head_set_internal(struct weston_head *head) +{ + head->connection_internal = true; +} /* Move other outputs when one is resized so the space remains contiguous. */ static void @@ -4481,6 +4561,7 @@ weston_output_init_geometry(struct weston_output *output, int x, int y) WL_EXPORT void weston_output_move(struct weston_output *output, int x, int y) { + struct weston_head *head = &output->head; struct wl_resource *resource; output->move_x = x - output->x; @@ -4501,11 +4582,11 @@ weston_output_move(struct weston_output *output, int x, int y) wl_output_send_geometry(resource, output->x, output->y, - output->mm_width, - output->mm_height, - output->subpixel, - output->make, - output->model, + head->mm_width, + head->mm_height, + head->subpixel, + head->make, + head->model, output->transform); if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION) @@ -4695,6 +4776,7 @@ weston_output_set_transform(struct weston_output *output, struct weston_seat *seat; pixman_region32_t old_region; int mid_x, mid_y; + struct weston_head *head = &output->head; if (!output->enabled && output->transform == UINT32_MAX) { output->transform = transform; @@ -4715,11 +4797,11 @@ weston_output_set_transform(struct weston_output *output, wl_output_send_geometry(resource, output->x, output->y, - output->mm_width, - output->mm_height, - output->subpixel, - output->make, - output->model, + head->mm_width, + head->mm_height, + head->subpixel, + head->make, + head->model, output->transform); if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION) @@ -4766,6 +4848,8 @@ weston_output_init(struct weston_output *output, struct weston_compositor *compositor, const char *name) { + struct weston_head *head = &output->head; + output->compositor = compositor; output->destroying = 0; output->name = strdup(name); @@ -4775,8 +4859,8 @@ weston_output_init(struct weston_output *output, /* Add some (in)sane defaults which can be used * for checking if an output was properly configured */ - output->mm_width = 0; - output->mm_height = 0; + head->mm_width = 0; + head->mm_height = 0; output->scale = 0; /* Can't use -1 on uint32_t and 0 is valid enum value */ output->transform = UINT32_MAX; diff --git a/libweston/compositor.h b/libweston/compositor.h index 010f1fa8..3af3e9ab 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -147,6 +147,21 @@ enum dpms_enum { WESTON_DPMS_OFF }; +/** Represents a monitor + * + * This object represents a monitor (hardware backends like DRM) or a window + * (windowed nested backends). + */ +struct weston_head { + int32_t mm_width; /**< physical image width in mm */ + int32_t mm_height; /**< physical image height in mm */ + char *make; /**< monitor manufacturer (PNP ID) */ + char *model; /**< monitor model */ + char *serial_number; /**< monitor serial */ + uint32_t subpixel; /**< enum wl_output_subpixel */ + bool connection_internal; /**< embedded monitor (e.g. laptop) */ +}; + struct weston_output { uint32_t id; char *name; @@ -165,7 +180,6 @@ struct weston_output { struct wl_list animation_list; int32_t x, y, width, height; - int32_t mm_width, mm_height; /** Output area in global coordinates, simple rect */ pixman_region32_t region; @@ -199,8 +213,6 @@ struct weston_output { int destroying; struct wl_list feedback_list; - char *make, *model, *serial_number; - uint32_t subpixel; uint32_t transform; int32_t native_scale; int32_t current_scale; @@ -211,6 +223,8 @@ struct weston_output { struct weston_mode *original_mode; struct wl_list mode_list; + struct weston_head head; + void (*start_repaint_loop)(struct weston_output *output); int (*repaint)(struct weston_output *output, pixman_region32_t *damage, @@ -224,7 +238,6 @@ struct weston_output { void (*set_backlight)(struct weston_output *output, uint32_t value); void (*set_dpms)(struct weston_output *output, enum dpms_enum level); - bool connection_internal; uint16_t gamma_size; void (*set_gamma)(struct weston_output *output, uint16_t size, @@ -1936,6 +1949,23 @@ weston_seat_set_keyboard_focus(struct weston_seat *seat, int weston_compositor_load_xwayland(struct weston_compositor *compositor); +void +weston_head_set_monitor_strings(struct weston_head *head, + const char *make, + const char *model, + const char *serialno); + +void +weston_head_set_physical_size(struct weston_head *head, + int32_t mm_width, int32_t mm_height); + +void +weston_head_set_subpixel(struct weston_head *head, + enum wl_output_subpixel sp); + +void +weston_head_set_internal(struct weston_head *head); + void weston_output_set_scale(struct weston_output *output, int32_t scale);