示例#1
0
文件: view.c 项目: Hummer12007/wlc
void
wlc_view_set_class_ptr(struct wlc_view *view, const char *class_, size_t length)
{
   if (view && !chck_cstrneq(view->data._class.data, class_, length) && chck_string_set_cstr_with_length(&view->data._class, class_, length, true)) {
      WLC_INTERFACE_EMIT(view.properties_updated, convert_to_wlc_handle(view), WLC_BIT_PROPERTY_CLASS);
   }
}
示例#2
0
文件: view.c 项目: Hummer12007/wlc
void
wlc_view_set_app_id_ptr(struct wlc_view *view, const char *app_id)
{
   if (view && !chck_cstreq(view->data.app_id.data, app_id) && chck_string_set_cstr(&view->data.app_id, app_id, true)) {
      WLC_INTERFACE_EMIT(view.properties_updated, convert_to_wlc_handle(view), WLC_BIT_PROPERTY_APP_ID);
   }
}
示例#3
0
文件: view.c 项目: Hummer12007/wlc
void
wlc_view_set_title_ptr(struct wlc_view *view, const char *title, size_t length)
{
   if (view && !chck_cstrneq(view->data.title.data, title, length) && chck_string_set_cstr_with_length(&view->data.title, title, length, true)) {
      WLC_INTERFACE_EMIT(view.properties_updated, convert_to_wlc_handle(view), WLC_BIT_PROPERTY_TITLE);
   }
}
示例#4
0
文件: view.c 项目: Hummer12007/wlc
bool
wlc_view_request_geometry(struct wlc_view *view, const struct wlc_geometry *r)
{
   assert(view && r);
   wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") requested geometry %ux%u+%d,%d", convert_to_wlc_handle(view), r->size.w, r->size.h, r->origin.x, r->origin.y);

   if (view->state.created && wlc_interface()->view.request.geometry) {
      WLC_INTERFACE_EMIT(view.request.geometry, convert_to_wlc_handle(view), r);
   } else {
      memcpy(&view->pending.geometry, r, sizeof(view->pending.geometry));
   }

   configure_view(view, view->pending.edges, &view->pending.geometry);
   wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") applied geometry %ux%u+%d,%d", convert_to_wlc_handle(view), view->pending.geometry.size.w, view->pending.geometry.size.h, view->pending.geometry.origin.x, view->pending.geometry.origin.y);
   return wlc_geometry_equals(r, &view->pending.geometry);
}
示例#5
0
文件: view.c 项目: Hummer12007/wlc
void
wlc_view_set_parent_ptr(struct wlc_view *view, struct wlc_view *parent)
{
   if (!view || view == parent)
      return;

   view->parent = convert_to_wlc_handle(parent);
   wlc_view_update(view);
}
示例#6
0
文件: view.c 项目: scarabeusiv/wlc
void
wlc_view_ack_surface_attach(struct wlc_view *view, struct wlc_surface *surface)
{
   assert(view && surface);

   if (view->x11.id) {
      surface->pending.opaque.extents = (pixman_box32_t){ 0, 0, surface->size.w, surface->size.h };
      view->surface_pending.visible = (struct wlc_geometry){ wlc_origin_zero, surface->size };
   }

   const bool resizing = (view->pending.state & WLC_BIT_RESIZING || view->commit.state & WLC_BIT_RESIZING);
   if (!resizing && !wlc_geometry_equals(&view->surface_pending.visible, &view->surface_commit.visible)) {
      struct wlc_geometry g = (struct wlc_geometry){ view->pending.geometry.origin, view->surface_pending.visible.size };
      wlc_view_request_geometry(view, &g);
   }

   view->surface_commit = view->surface_pending;
   wlc_dlog(WLC_DBG_COMMIT, "=> surface view %" PRIuWLC, convert_to_wlc_handle(view));
}

static bool
should_be_transformed_by_parent(struct wlc_view *view)
{
   return !(view->type & WLC_BIT_OVERRIDE_REDIRECT) && !(view->type & WLC_BIT_UNMANAGED);
}

void
wlc_view_get_bounds(struct wlc_view *view, struct wlc_geometry *out_bounds, struct wlc_geometry *out_visible)
{
   assert(view && out_bounds && out_bounds != out_visible);
   memcpy(out_bounds, &view->commit.geometry, sizeof(struct wlc_geometry));

   struct wlc_surface *surface;
   if (!(surface = convert_from_wlc_resource(view->surface, "surface")))
      return;

   if (should_be_transformed_by_parent(view)) {
      for (struct wlc_view *parent = convert_from_wlc_handle(view->parent, "view"); parent; parent = convert_from_wlc_handle(parent->parent, "view")) {
         out_bounds->origin.x += parent->commit.geometry.origin.x;
         out_bounds->origin.y += parent->commit.geometry.origin.y;
      }
   }

   if (view->xdg_surface && view->surface_commit.visible.size.w > 0 && view->surface_commit.visible.size.h > 0) {
      // xdg-surface client that draws drop shadows or other stuff.
      out_bounds->origin.x -= view->surface_commit.visible.origin.x;
      out_bounds->origin.y -= view->surface_commit.visible.origin.y;
      out_bounds->size.w += surface->size.w - view->surface_commit.visible.size.w;
      out_bounds->size.h += surface->size.h - view->surface_commit.visible.size.h;
   }

   // Make sure bounds is never 0x0 w/h
   wlc_size_max(&out_bounds->size, &(struct wlc_size){ 1, 1 }, &out_bounds->size);
示例#7
0
文件: view.c 项目: snells/wlc
void
wlc_view_unmap(struct wlc_view *view)
{
   assert(view);

   wlc_output_unlink_view(wlc_view_get_output_ptr(view), view);

   if (!view->state.created)
      return;

   WLC_INTERFACE_EMIT(view.destroyed, convert_to_wlc_handle(view));
   view->state.created = false;
}
示例#8
0
文件: view.c 项目: Hummer12007/wlc
bool
wlc_view_request_state(struct wlc_view *view, enum wlc_view_state_bit state, bool toggle)
{
   if (!view || !view->state.created)
      return false;

   if (!!(view->pending.state & state) == toggle) {
      // refresh geometry
      if (state == WLC_BIT_FULLSCREEN || state == WLC_BIT_MAXIMIZED)
         configure_view(view, view->pending.edges, &view->pending.geometry);
      return true;
   }

   wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") requested state %d", convert_to_wlc_handle(view), state);

   if (wlc_interface()->view.request.state) {
      WLC_INTERFACE_EMIT(view.request.state, convert_to_wlc_handle(view), state, toggle);
   } else {
      wlc_view_set_state_ptr(view, state, toggle);
   }

   wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") applied states %d", convert_to_wlc_handle(view), view->pending.state);
   return (!!(view->pending.state & state) == toggle);
}
示例#9
0
文件: view.c 项目: snells/wlc
void
wlc_view_commit_state(struct wlc_view *view, struct wlc_view_state *pending, struct wlc_view_state *out)
{
   struct wlc_surface *surface;
   if (!(surface = convert_from_wlc_resource(view->surface, "surface")))
      return;

   // FIXME: handle ping
#if 0
      struct wl_resource *r;
      if (view->shell_surface && (r = wl_resource_from_wlc_resource(view->shell_surface, "shell-surface")))
         wl_shell_surface_send_ping(r, wl_display_next_serial(wlc_display()));

      wlc_dlog(WLC_DBG_COMMIT, "=> ping view %zu", convert_to_wlc_handle(view));
      return;
#endif

   if (!view->state.created) {
      // Initial size of the view
      view->pending.geometry.size = surface->size;
      view->state.created = true;

      if (WLC_INTERFACE_EMIT_EXCEPT(view.created, false, convert_to_wlc_handle(view))) {
         wlc_view_close_ptr(view);
         return;
      }
   }

   if (!memcmp(pending, out, sizeof(struct wlc_view_state)))
      return;

   if (pending->state != out->state) {
      const struct {
         uint32_t bit;
         uint32_t state;
      } map[] = {
         { WLC_BIT_MAXIMIZED, XDG_SURFACE_STATE_MAXIMIZED },
         { WLC_BIT_FULLSCREEN, XDG_SURFACE_STATE_FULLSCREEN },
         { WLC_BIT_RESIZING, XDG_SURFACE_STATE_RESIZING },
         { WLC_BIT_ACTIVATED, XDG_SURFACE_STATE_ACTIVATED },
         { 0, 0 },
      };

      chck_iter_pool_flush(&view->wl_state);

      for (uint32_t i = 0; map[i].state != 0; ++i) {
         if (pending->state & map[i].bit)
            chck_iter_pool_push_back(&view->wl_state, &map[i].state);
      }
   }

   const bool size_changed = (!wlc_size_equals(&pending->geometry.size, &out->geometry.size) || !wlc_size_equals(&pending->geometry.size, &surface->size));
   wlc_dlog(WLC_DBG_COMMIT, "=> pending commit %zu (%d) pending: %ux%u commited: %ux%u surface: %ux%u", convert_to_wlc_handle(view), size_changed, pending->geometry.size.w, pending->geometry.size.h, out->geometry.size.w, out->geometry.size.h, surface->size.w, surface->size.h);

   if (pending->state != out->state || size_changed) {
      struct wl_resource *r;
      if (view->xdg_surface && (r = wl_resource_from_wlc_resource(view->xdg_surface, "xdg-surface"))) {
         const uint32_t serial = wl_display_next_serial(wlc_display());
         struct wl_array states = { .size = view->wl_state.items.used, .alloc = view->wl_state.items.allocated, .data = view->wl_state.items.buffer };
         xdg_surface_send_configure(r, pending->geometry.size.w, pending->geometry.size.h, &states, serial);
      } else if (view->shell_surface && (r = wl_resource_from_wlc_resource(view->shell_surface, "shell-surface"))) {
         wl_shell_surface_send_configure(r, pending->edges, pending->geometry.size.w, pending->geometry.size.h);
      }
   }

   if (view->x11.id) {
      if (!wlc_origin_equals(&pending->geometry.origin, &out->geometry.origin))
         wlc_x11_window_position(&view->x11, pending->geometry.origin.x, pending->geometry.origin.y);

      if (size_changed)
         wlc_x11_window_resize(&view->x11, pending->geometry.size.w, pending->geometry.size.h);
   }

   memcpy(out, pending, sizeof(struct wlc_view_state));
   wlc_dlog(WLC_DBG_COMMIT, "=> commit %zu", convert_to_wlc_handle(view));
}
示例#10
0
文件: view.c 项目: scarabeusiv/wlc
void
wlc_view_commit_state(struct wlc_view *view, struct wlc_view_state *pending, struct wlc_view_state *out)
{
   assert(view && pending && out);

   struct wlc_surface *surface;
   if (!(surface = convert_from_wlc_resource(view->surface, "surface")))
      return;

   // FIXME: handle ping
#if 0
      struct wl_resource *r;
      if (view->shell_surface && (r = wl_resource_from_wlc_resource(view->shell_surface, "shell-surface")))
         wl_shell_surface_send_ping(r, wl_display_next_serial(wlc_display()));

      wlc_dlog(WLC_DBG_COMMIT, "=> ping view %" PRIuWLC, convert_to_wlc_handle(view));
      return;
#endif

   if (!view->state.created) {
      // Initial size of the view
      view->pending.geometry.size = surface->size;
      view->state.created = true;

      if (WLC_INTERFACE_EMIT_EXCEPT(view.created, false, convert_to_wlc_handle(view))) {
         wlc_view_close_ptr(view);
         return;
      }
   }

   if (!memcmp(pending, out, sizeof(struct wlc_view_state)))
      return;

   if (pending->state != out->state) {
      const struct {
         enum wlc_view_state_bit bit;
         uint32_t state;
      } map[] = {
         { WLC_BIT_MAXIMIZED, XDG_SURFACE_STATE_MAXIMIZED },
         { WLC_BIT_FULLSCREEN, XDG_SURFACE_STATE_FULLSCREEN },
         { WLC_BIT_RESIZING, XDG_SURFACE_STATE_RESIZING },
         { WLC_BIT_ACTIVATED, XDG_SURFACE_STATE_ACTIVATED },
      };

      chck_iter_pool_flush(&view->wl_state);

      for (uint32_t i = 0; i < LENGTH(map); ++i) {
         if (pending->state & map[i].bit)
            chck_iter_pool_push_back(&view->wl_state, &map[i].state);
      }
   }

   const bool size_changed = (!wlc_size_equals(&pending->geometry.size, &out->geometry.size) || !wlc_size_equals(&pending->geometry.size, &surface->size));
   wlc_dlog(WLC_DBG_COMMIT, "=> pending view commit %" PRIuWLC " (%d) pending: %ux%u commited: %ux%u surface: %ux%u", convert_to_wlc_handle(view), size_changed, pending->geometry.size.w, pending->geometry.size.h, out->geometry.size.w, out->geometry.size.h, surface->size.w, surface->size.h);

   if (pending->state != out->state || size_changed)
      configure_view(view, pending->edges, &pending->geometry);

   *out = *pending;
   wlc_dlog(WLC_DBG_COMMIT, "=> commit view %" PRIuWLC, convert_to_wlc_handle(view));
}
示例#11
0
文件: resources.c 项目: Azarn/wlc
int
main(void)
{
   // TEST: Basic source and handle creation
   {
      assert(wlc_resources_init());

      struct wlc_source source;
      assert(wlc_source(&source, "test", constructor, destructor, 1, sizeof(struct wlc_resource)));

      struct wlc_resource *ptr;
      assert(!constructor_called);
      assert((ptr = wlc_handle_create(&source)));
      assert(constructor_called);
      assert(source.pool.items.count == 1);

      wlc_handle handle;
#pragma GCC diagnostic ignored "-Wpointer-arith"
      assert(!convert_to_wlc_handle(NULL));
#pragma GCC diagnostic warning "-Wpointer-arith"
      assert((handle = convert_to_wlc_handle(ptr)));
      assert(!convert_from_wlc_handle(handle, "invalid"));
      assert(convert_from_wlc_handle(handle, "test") == ptr);

      const char *test = "foobar";
      wlc_handle_set_user_data(handle, test);
      assert(wlc_handle_get_user_data(handle) == test);

      assert(!destructor_called);
      wlc_handle_release(handle);
      assert(destructor_called);
      assert(!convert_from_wlc_handle(handle, "invalid"));
      assert(!convert_from_wlc_handle(handle, "test"));
      assert(!wlc_handle_get_user_data(handle));
      assert(source.pool.items.count == 0);

      wlc_source_release(&source);
      wlc_resources_terminate();
   }

   // TEST: Handle invalidation on source release
   {
      assert(wlc_resources_init());

      struct wlc_source source;
      assert(wlc_source(&source, "test", constructor, destructor, 1, sizeof(struct wlc_resource)));

      struct wlc_resource *ptr;
      assert((ptr = wlc_handle_create(&source)));
      assert(source.pool.items.count == 1);

      wlc_handle handle;
      assert((handle = convert_to_wlc_handle(ptr)));

      assert(!(destructor_called = false));
      wlc_source_release(&source);
      assert(destructor_called);

      assert(source.pool.items.count == 0);
      assert(!convert_from_wlc_handle(handle, "test"));

      wlc_resources_terminate();
   }

   // TEST: Handle invalidation on resources termination
   {
      assert(wlc_resources_init());

      struct wlc_source source;
      assert(wlc_source(&source, "test", constructor, destructor, 1, sizeof(struct wlc_resource)));

      struct wlc_resource *ptr;
      assert((ptr = wlc_handle_create(&source)));
      assert(source.pool.items.count == 1);

      wlc_handle handle;
      assert((handle = convert_to_wlc_handle(ptr)));

      assert(!(destructor_called = false));
      wlc_resources_terminate();
      assert(destructor_called);

      assert(!convert_from_wlc_handle(handle, "test"));
      wlc_source_release(&source);
   }

   // TEST: Relocation of source inside container of handle, when the handle's source changes location
   {
      assert(wlc_resources_init());

      struct wlc_source source;
      assert(wlc_source(&source, "test", constructor2, destructor2, 1, sizeof(struct contains_source)));

      struct contains_source *ptr;
      assert((ptr = wlc_handle_create(&source)));
      assert(source.pool.items.count == 1);
      void *original_source = &ptr->source;

      wlc_handle handle;
      assert((handle = convert_to_wlc_handle(ptr)));

      struct wlc_resource *ptr2;
      assert((ptr2 = wlc_handle_create(&ptr->source)));

      wlc_handle handle2;
      assert((handle2 = convert_to_wlc_handle(ptr2)));
      assert(convert_from_wlc_handle(handle2, "test2") == ptr2);

      // Play with heap until realloc does not return linear memory anymore
      {
         void *original = source.pool.items.buffer;
         do {
            void *garbage;
            assert((garbage = malloc(1024)));
            assert(wlc_handle_create(&source));
            free(garbage);
         } while (original == source.pool.items.buffer);
      }

      // So this should be true
      assert(ptr = convert_from_wlc_handle(handle, "test"));
      assert(original_source != &ptr->source);

      wlc_resources_terminate();

      assert(!convert_from_wlc_handle(handle2, "test2"));
      wlc_source_release(&source);
   }

   // TEST: Benchmark (many insertions, and removal expanding from center)
   {
      assert(wlc_resources_init());

      struct container {
         wlc_handle self;
      };

      struct wlc_source source;
      assert(wlc_source(&source, "test", constructor, destructor, 1024, sizeof(struct container)));

      wlc_handle first = 0;
      const uint32_t iters = 0xFFFFF;
      for (uint32_t i = 0; i < iters; ++i) {
         struct container *ptr = wlc_handle_create(&source);
         ptr->self = convert_to_wlc_handle(ptr);
         if (!first) first = ptr->self;
         assert(convert_from_wlc_handle(first, "test"));
      }
      assert(source.pool.items.count == iters);

      for (uint32_t i = iters / 2, d = iters / 2; i < iters; ++i, --d) {
         assert(((struct container*)convert_from_wlc_handle(i + 1, "test"))->self == i + 1);
         assert(((struct container*)convert_from_wlc_handle(d + 1, "test"))->self == d + 1);
         wlc_handle_release(i + 1);
         wlc_handle_release(d + 1);
      }
      assert(source.pool.items.count == 0);

      assert(!convert_from_wlc_handle(first, "test"));
      wlc_source_release(&source);
      wlc_resources_terminate();
   }

   // TODO: Needs test for wlc_resource.
   //       For this we need to start compositor and some clients, or dummy the wl_resource struct.
   //       (Latter probably better)

   return EXIT_SUCCESS;
}
示例#12
0
文件: view.c 项目: Hummer12007/wlc
WLC_API wlc_handle
wlc_view_get_output(wlc_handle view)
{
   return convert_to_wlc_handle(wlc_view_get_output_ptr(convert_from_wlc_handle(view, "view")));
}
示例#13
0
文件: view.c 项目: Hummer12007/wlc
void
wlc_view_set_surface(struct wlc_view *view, struct wlc_surface *surface)
{
   if (!view || view->surface == convert_to_wlc_resource(surface))
      return;

   wlc_handle old = view->surface;
   view->surface = convert_to_wlc_resource(surface);
   wlc_surface_attach_to_view(convert_from_wlc_resource(old, "surface"), NULL);
   wlc_surface_attach_to_view(surface, view);

   if (surface && surface->commit.attached) {
      wlc_view_map(view);
   } else {
      wlc_view_unmap(view);
   }

   wlc_dlog(WLC_DBG_RENDER, "-> Linked surface (%" PRIuWLC ") to view (%" PRIuWLC ")", convert_to_wlc_resource(surface), convert_to_wlc_handle(view));
}