struct wl_closure *closure;
struct wl_array *array_extra;
+ int res;
+ void *object_to_override;
+
/* Space for sender_id and opcode */
if (size < 2 * sizeof *p) {
wl_log("message too short, invalid header\n");
goto err;
}
+ /* Check if there is any object data exists with the given id */
+ object_to_override = wl_map_lookup(objects, id);
+
+ if (object_to_override)
+ {
+ res = wl_display_override_object_id(object_to_override, id, objects->side);
+
+ if (res)
+ wl_log("id (%u) has been overriden for new object, "
+ "message %s(%s)\n",
+ id, message->name, message->signature);
+ break;
+ }
+
if (wl_map_reserve_new(objects, id) < 0) {
if (errno == EINVAL) {
wl_log("not a valid new object id (%u), "
WL_PROXY_FLAG_ID_DELETED = (1 << 0),
WL_PROXY_FLAG_DESTROYED = (1 << 1),
WL_PROXY_FLAG_WRAPPER = (1 << 2),
+ WL_PROXY_FLAG_ID_OVERRIDEN = (1 << 31)
};
struct wl_zombie {
proxy->object.id,
zombie);
} else {
- wl_map_insert_at(&proxy->display->objects, 0,
- proxy->object.id, NULL);
+ /* Clear the given proxy information from the map
+ * only if it is not overriden. */
+ if (!(proxy->flags & WL_PROXY_FLAG_ID_OVERRIDEN))
+ wl_map_insert_at(&proxy->display->objects, 0,
+ proxy->object.id, NULL);
}
proxy->flags |= WL_PROXY_FLAG_DESTROYED;
closure->proxy->refcount++;
}
+int
+wl_display_override_object_id(void *object, const uint32_t id, int side)
+{
+ struct wl_proxy *proxy = (struct wl_proxy *)object;
+ struct wl_proxy *overriden_proxy;
+
+ /* Check if the given object is the pointer of wl_proxy object */
+ if (!proxy || (sizeof(*proxy) != sizeof(struct wl_proxy))) {
+ wl_log("errno:%d\n", errno);
+ wl_abort("invalid object data to override (id:%u, errno:%d)\n", id, errno = EINVAL);
+ return 0;
+ }
+ else if (id < WL_SERVER_ID_START || side != WL_MAP_CLIENT_SIDE) {
+ wl_log("errno:%d\n", errno);
+ wl_abort("invalid object id to override (id:%u, side:%d, errno:%d)\n", id, side, errno = EINVAL);
+ return 0;
+ }
+
+ overriden_proxy = wl_map_lookup(&proxy->display->objects, id);
+ if (!overriden_proxy) {
+ if (errno || proxy->display->last_error)
+ wl_log("errno:%d, last_error:%d\n", errno, proxy->display->last_error);
+ wl_abort("no proxy found with the given object id(%u), errno(%d)\n", id, errno = EINVAL);
+ return 0;
+ }
+ else if (overriden_proxy != proxy) {
+ if (errno || proxy->display->last_error)
+ wl_log("errno:%d, last_error:%d\n", errno, proxy->display->last_error);
+ wl_abort("invalid proxy objects(%p, %p) found (id:%u), errno(%d)\n", overriden_proxy, proxy, id, errno = EINVAL);
+ return 0;
+ }
+
+ /* Set overriden flag for the overriden proxy not to set data as NULL later. */
+ overriden_proxy->flags |= WL_PROXY_FLAG_ID_OVERRIDEN;
+ overriden_proxy->object.id = 0;
+
+ wl_log("proxy(%p) with id(%u) has been overriden\n", overriden_proxy, id);
+ return 1;
+}
+
static int
queue_event(struct wl_display *display, int len)
{
void *user_data;
};
+int
+wl_display_override_object_id(void *object, const uint32_t id, int side)
+{
+ /* Nothing needs to be done here in server. */
+ (void) object;
+ (void) id;
+ (void) side;
+
+ wl_log("errno:%d\n", errno);
+ wl_log("This case must not be happened. (object:%p, id:%u, side:%d, errno:%d)\n",
+ object, id, side, errno = EINVAL);
+ return 0;
+}
+
static void
log_closure(struct wl_resource *resource,
struct wl_closure *closure, int send)