예제 #1
0
파일: shell.cpp 프로젝트: nyorain/iro
void MyShellModule::render(Output& outp, ny::DrawContext& dc)
{
	if(!myTexture.glTexture())
	{
		ny::Image myImage;
		ny::sendLog("loading wallpaper... ", myImage.load("wallpaper.png"));

		myTexture.create(myImage);
	}
	
	glViewport(0, 0, outp.size().x, outp.size().y);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	dc.clear(ny::Color::red);

	ny::TextureBrush texBrush;
	texBrush.extents.position = {0.f, 0.f};
	texBrush.extents.size = outp.size();
	texBrush.texture = &myTexture;

	ny::Rectangle bg = texBrush.extents;
	dc.mask(bg);
	dc.fill(texBrush);

	SurfaceRes* cursorSurface = nullptr;
	ny::sendLog("Shell: Drawing ", outp.mappedSurfaces().size(), " mapped surfaces");
	for(auto& surf : outp.mappedSurfaces())
	{
		if(surf->roleType() == surfaceRoleType::cursor)
			cursorSurface = surf;

		/*
		ny::Rectangle surfaceRect(surf->extents());
		surfaceRect.position(surfaceRect.position() - outp.extents().position);
		dc.mask(surfaceRect);

		ny::TextureBrush surfaceBrush;
		surfaceBrush.extents = surfaceRect;
		surfaceBrush.texture = surf->surfaceContext().content();

		dc.fill(surfaceBrush);
		*/

		surf->sendFrameDone();
	}

	//windows are sorted by z order
	for(auto& window : windows_)
	{
		auto* surf = window->surfaceRes();	
		if(!surf) continue;

		if(window == focus_)
		{
			ny::Rectangle surfaceRect(surf->extents());
			surfaceRect.position(surfaceRect.position() + nytl::Vec2ui{20,20});
			surfaceRect.size(surfaceRect.size() - nytl::Vec2ui{40,40});
			dc.mask(surfaceRect);
			dc.fill(ny::Color::green);
		}

		ny::Rectangle surfaceRect(surf->extents());
		surfaceRect.position(surfaceRect.position() - outp.extents().position);
		dc.mask(surfaceRect);

		ny::TextureBrush surfaceBrush;
		surfaceBrush.extents = surfaceRect;
		surfaceBrush.texture = surf->surfaceContext().content();

		dc.fill(surfaceBrush);
	}
	
	if(cursorSurface)
	{
		SurfaceRes* surf = cursorSurface;
		ny::Rectangle surfaceRect(surf->extents());
		surfaceRect.position(surfaceRect.position() - outp.extents().position);
		dc.mask(surfaceRect);

		ny::TextureBrush surfaceBrush;
		surfaceBrush.extents = surfaceRect;
		surfaceBrush.texture = surf->surfaceContext().content();

		dc.fill(surfaceBrush);

		surf->sendFrameDone();
	}
	
	else
	{
		if(!cursorTexture.glTexture())
		{
			ny::Image cursorImage;
			ny::sendLog("loading cursor image: ", cursorImage.load("cursor.png"));
			cursorTexture.create(cursorImage);
		}

		ny::TextureBrush cursorBrush;
		cursorBrush.extents.position = seat_->pointer()->position() - outp.extents().position;
		cursorBrush.extents.size = nytl::Vec2f(30, 30);
		cursorBrush.texture = &cursorTexture;

		dc.mask(ny::Rectangle(cursorBrush.extents.position, nytl::Vec2f(30, 30)));
		dc.fill(cursorBrush);
	}
}
예제 #2
0
void Screenshooter::shootSurface(wl_client *client, wl_resource *resource, uint32_t id)
{
    wl_resource *res = wl_resource_create(client, &orbital_surface_screenshot_interface, 1, id);
    class SurfaceScreenshot : public PointerGrab
    {
    public:
        SurfaceScreenshot(Compositor *c, wl_resource *res)
            : m_compositor(c)
            , m_resource(res)
            , m_surface(nullptr)
        {
            static const struct orbital_surface_screenshot_interface implementation = {
                wrapInterface(shoot),
            };
            wl_resource_set_implementation(m_resource, &implementation, this, nullptr);
        }

        void failed()
        {
            orbital_surface_screenshot_send_failed(m_resource);
            wl_resource_destroy(m_resource);
            delete this;
        }

        void shoot(wl_resource *resource)
        {
            if (!wl_shm_buffer_get(resource)) {
                failed();
                return;
            }

            wl_shm_buffer *shm = wl_shm_buffer_get(resource);
            int width = wl_shm_buffer_get_width(shm);
            int height = wl_shm_buffer_get_height(shm);
            int stride = wl_shm_buffer_get_stride(shm);
            QSize size = m_surface->contentSize();

            if (stride != size.width() * 4 || height != size.height()) {
                failed();
                return;
            }

            wl_shm_buffer_begin_access(shm);

            void *data = wl_shm_buffer_get_data(shm);
            m_surface->copyContent(data, stride * height, QRect(0, 0, width, height));

            wl_shm_buffer_end_access(shm);

            orbital_surface_screenshot_send_done(m_resource);
            wl_resource_destroy(m_resource);
            delete this;
        }

        void motion(uint32_t time, Pointer::MotionEvent evt) override
        {
            pointer()->move(evt);
        }
        void button(uint32_t time, PointerButton button, Pointer::ButtonState state) override
        {
            if (pointer()->buttonCount() == 0 && state == Pointer::ButtonState::Released) {
                View *view = m_compositor->pickView(pointer()->x(), pointer()->y());
                if (view) {
                    m_surface = view->surface();

                    QSize size = m_surface->contentSize();
                    orbital_surface_screenshot_send_setup(m_resource, size.width(), size.height(), size.width() * 4, 0);
                }

                end();
            }
        }

        Compositor *m_compositor;
        wl_resource *m_resource;
        Surface *m_surface;
    };

    auto *grab = new SurfaceScreenshot(m_compositor, res);
    Seat *seat = m_compositor->seats().front();
    seat->pointer()->setFocus(nullptr);
    grab->start(seat, PointerCursor::Kill);
}