void AddVisual(Point point) { Compositor compositor = m_visuals.Compositor(); SolidColorVisual visual = compositor.CreateSolidColorVisual(); static Color colors[] = { { 0xDC, 0x5B, 0x9B, 0xD5 }, { 0xDC, 0xED, 0x7D, 0x31 }, { 0xDC, 0x70, 0xAD, 0x47 }, { 0xDC, 0xFF, 0xC0, 0x00 } }; static unsigned last = 0; unsigned next = ++last % _countof(colors); visual.Color(colors[next]); visual.Size(Vector2 { BlockSize, BlockSize }); visual.Offset(Vector3 { point.X - BlockSize / 2.0f, point.Y - BlockSize / 2.0f, }); m_visuals.InsertAtTop(visual); }
void Compositor::setOutputGeometry(void *c, const QList<QVariant> ¶meters) { Compositor *compositor = static_cast<Compositor *>(c); compositor->m_outputGeometry = parameters.first().toRect(); wl_resource *resource; wl_list_for_each(resource, &compositor->m_outputResources, link) compositor->sendOutputGeometry(resource); }
void Parser::parseCompositor( ParserContext *context, const QDomElement &element, ComplexType &ct ) { QName name = element.tagName(); bool isChoice = name.localName() == "choice"; bool isSequence = name.localName() == "sequence"; Compositor compositor; if ( isChoice ) compositor.setType( Compositor::Choice ); else if ( isSequence ) compositor.setType( Compositor::Sequence ); if ( isChoice || isSequence ) { Element::List newElements; QDomElement childElement = element.firstChildElement(); while ( !childElement.isNull() ) { QName csName = childElement.tagName(); if ( csName.localName() == "element" ) { Element newElement; if ( isChoice ) { newElement = parseElement( context, childElement, ct.nameSpace(), element ); } else { if ( isSequence ) { // occurence attributes can be either in the // parent (sequence) to on the current element if ( childElement.hasAttribute("minOccurs") || childElement.hasAttribute("maxOccurs")) { newElement = parseElement( context, childElement, ct.nameSpace(), childElement ); } else { newElement = parseElement( context, childElement, ct.nameSpace(), element ); } } else { newElement = parseElement( context, childElement, ct.nameSpace(), childElement ); } } newElements.append( newElement ); compositor.addChild( csName ); } else if ( csName.localName() == "any" ) { addAny( context, childElement, ct ); } else if ( isChoice ) { parseCompositor( context, childElement, ct ); } else if ( isSequence ) { parseCompositor( context, childElement, ct ); } childElement = childElement.nextSiblingElement(); } foreach( Element e, newElements ) { e.setCompositor( compositor ); ct.addElement( e ); }
void Label::set_font(const char* filename, size_t pixel_size) { Compositor* compositor = get_compositor(); font_handle = compositor->get_resource_cache()->create_font(filename, pixel_size); // cache font_height size_t height; int ascender, descender; compositor->get_renderer()->font_metrics(font_handle, height, ascender, descender); font_height = static_cast<int32_t>(ascender + descender); }
void Compositor::bindOutput(wl_client *client, void *compositorData, uint32_t version, uint32_t id) { Q_UNUSED(version); wl_resource *resource = wl_client_add_object(client, &wl_output_interface, 0, id, compositorData); Compositor *compositor = static_cast<Compositor *>(compositorData); registerResource(&compositor->m_outputResources, resource); compositor->sendOutputGeometry(resource); compositor->sendOutputMode(resource); }
ClipboardManager::ClipboardManager(Shell *shell) : Interface(shell) , Global(shell->compositor(), &orbital_clipboard_manager_interface, 1) { Compositor *c = shell->compositor(); for (Seat *s: c->seats()) { connect(s, &Seat::selection, this, &ClipboardManager::selection); } connect(c, &Compositor::seatCreated, [this](Seat *s) { connect(s, &Seat::selection, this, &ClipboardManager::selection); }); }
Dashboard::Dashboard(Shell *shell) : QObject(shell) , m_shell(shell) , m_visible(true) { Compositor *c = shell->compositor(); m_toggleSurfaceBinding = c->createButtonBinding(PointerButton::Middle, KeyboardModifiers::Super); m_toggleBinding = c->createHotSpotBinding(PointerHotSpot::BottomLeftCorner); connect(m_toggleSurfaceBinding, &ButtonBinding::triggered, this, &Dashboard::toggleSurface); connect(m_toggleBinding, &HotSpotBinding::triggered, this, &Dashboard::toggle); }
void ScreenManager::draw(Compositor& compositor) { assert(!m_screen_stack.empty()); static Uint32 fps_ticks = SDL_GetTicks(); // draw the actual screen m_screen_stack.back()->draw(compositor); // draw effects and hud auto& context = compositor.make_context(true); m_menu_manager->draw(context); if (m_screen_fade) { m_screen_fade->draw(context); } Console::current()->draw(context); if (g_config->show_fps) { draw_fps(context, m_fps); } if (g_config->show_player_pos) { draw_player_pos(context); } // render everything compositor.render(); /* Calculate frames per second */ if (g_config->show_fps) { static int frame_count = 0; ++frame_count; if (SDL_GetTicks() - fps_ticks >= 500) { m_fps = static_cast<float>(frame_count) / 0.5f; frame_count = 0; fps_ticks = SDL_GetTicks(); } } }
int GLWorker::DoComposition(Compositor &compositor, Work *work) { int ret = compositor.Composite(work->layers, work->num_layers, work->framebuffer); int timeline_fd = work->timeline_fd; work->timeline_fd = -1; if (ret) { worker_ret_ = ret; glFinish(); sw_sync_timeline_inc(timeline_fd, work->num_layers); close(timeline_fd); return pthread_cond_signal(&work_done_cond_); } unsigned timeline_count = work->num_layers + 1; worker_ret_ = sw_sync_fence_create(timeline_fd, "GLComposition done fence", timeline_count); ret = pthread_cond_signal(&work_done_cond_); glFinish(); sw_sync_timeline_inc(timeline_fd, timeline_count); close(timeline_fd); return ret; }
void PostProcessSample::update(float elapsedTime) { _modelNode->rotateY(elapsedTime * MATH_DEG_TO_RAD(0.25f)); // Only the last sample will check live updating of material parameters if (_compositorIndex == _compositors.size() - 1) { Compositor* compositor = _compositors[_compositorIndex]; MaterialParameter* elapsedParam = compositor->getMaterial()->getParameter("u_elapsedTime"); if (elapsedParam) elapsedParam->setValue(elapsedTime); MaterialParameter* randomParam = compositor->getMaterial()->getParameter("u_random"); if (randomParam) randomParam->setValue(MATH_RANDOM_0_1()); } }
void TextScroller::draw(Compositor& compositor) { auto& context = compositor.make_context(); context.color().draw_filled_rect(Vector(0, 0), Vector(static_cast<float>(context.get_width()), static_cast<float>(context.get_height())), Color(0.6f, 0.7f, 0.8f, 0.5f), 0); context.color().draw_surface_part(background, Rectf(0, 0, static_cast<float>(background->get_width()), static_cast<float>(background->get_height())), Rectf(0, 0, static_cast<float>(context.get_width()), static_cast<float>(context.get_height())), 0); float y = static_cast<float>(context.get_height()) - scroll; for (auto& line : lines) { if (y + line->get_height() >= 0 && static_cast<float>(context.get_height()) - y >= 0) { line->draw(context, Rectf(LEFT_BORDER, y, static_cast<float>(context.get_width()) - 2*LEFT_BORDER, y), LAYER_GUI); } y += line->get_height(); } if(y < 0 && !fading ) { fading = true; ScreenManager::current()->pop_screen(std::unique_ptr<ScreenFade>(new FadeOut(0.5))); } }
void Parser::parseCompositor( ParserContext *context, const QDomElement &element, ComplexType &ct ) { const QName name( element.tagName() ); bool isChoice = name.localName() == QLatin1String("choice"); bool isSequence = name.localName() == QLatin1String("sequence"); Compositor compositor; if ( isChoice ) compositor.setType( Compositor::Choice ); else if ( isSequence ) compositor.setType( Compositor::Sequence ); compositor.setMaxOccurs( readMaxOccurs( element ) ); if ( isChoice || isSequence ) { Element::List newElements; QDomElement childElement = element.firstChildElement(); while ( !childElement.isNull() ) { NSManager namespaceManager( context, childElement ); const QName csName( childElement.tagName() ); if ( csName.localName() == QLatin1String("element") ) { Element newElement; if ( isChoice ) { newElement = parseElement( context, childElement, ct.nameSpace(), element ); } else { newElement = parseElement( context, childElement, ct.nameSpace(), childElement ); } newElements.append( newElement ); compositor.addChild( csName ); } else if ( csName.localName() == QLatin1String("any") ) { addAny( context, childElement, ct ); } else if ( isChoice ) { parseCompositor( context, childElement, ct ); } else if ( isSequence ) { parseCompositor( context, childElement, ct ); } childElement = childElement.nextSiblingElement(); } foreach( Element e, newElements ) { e.setCompositor( compositor ); ct.addElement( e ); }
void PaintedLayerComposite::RenderLayer(const gfx::IntRect& aClipRect) { if (!mBuffer || !mBuffer->IsAttached()) { return; } PROFILER_LABEL("PaintedLayerComposite", "RenderLayer", js::ProfileEntry::Category::GRAPHICS); Compositor* compositor = mCompositeManager->GetCompositor(); MOZ_ASSERT(mBuffer->GetCompositor() == compositor && mBuffer->GetLayer() == this, "buffer is corrupted"); const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion(); #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { RefPtr<gfx::DataSourceSurface> surf = mBuffer->GetAsSurface(); if (surf) { WriteSnapshotToDumpFile(this, surf); } } #endif RenderWithAllMasks(this, compositor, aClipRect, [&](EffectChain& effectChain, const Rect& clipRect) { mBuffer->SetPaintWillResample(MayResample()); mBuffer->Composite(this, effectChain, GetEffectiveOpacity(), GetEffectiveTransform(), GetEffectFilter(), clipRect, &visibleRegion); }); mBuffer->BumpFlashCounter(); compositor->MakeCurrent(); }
void PostProcessSample::render(float elapsedTime) { Rectangle defaultViewport = Game::getInstance()->getViewport(); // Draw into the framebuffer Game::getInstance()->setViewport(Rectangle(FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT)); FrameBuffer* previousFrameBuffer = _frameBuffer->bind(); clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0); _scene->visit(this, &PostProcessSample::drawScene); // Bind the current compositor Game::getInstance()->setViewport(defaultViewport); Compositor* compositor = _compositors[_compositorIndex]; FrameBuffer* compositorDstFrameBuffer = compositor->getDstFrameBuffer(); FrameBuffer* prevToCompositeFrameBuffer = NULL; if (compositorDstFrameBuffer) { prevToCompositeFrameBuffer = compositorDstFrameBuffer->bind(); } else { prevToCompositeFrameBuffer = previousFrameBuffer->bind(); } Game::getInstance()->clear(CLEAR_COLOR, Vector4(0, 0, 0, 1), 1.0f, 0); compositor->blit(defaultViewport); drawFrameRate(_font, Vector4(0, 0.5f, 1, 1), 5, 1, getFrameRate()); drawTechniqueId(compositor->getTechniqueId()); previousFrameBuffer->bind(); // Draw the pass through compositor at index 0 at quarter of the size and bottom right. dont clear the dest just draw last on top float quarterWidth = getWidth() / 4; float quarterHeight = getHeight() / 4; Rectangle offsetViewport = Rectangle(getWidth() - quarterWidth, 0, quarterWidth, quarterHeight); Game::getInstance()->setViewport(offsetViewport); compositor = _compositors[0]; compositor->blit(offsetViewport); Game::getInstance()->setViewport(defaultViewport); }
void SetWindow(CoreWindow const & window) { Compositor compositor; ContainerVisual root = compositor.CreateContainerVisual(); m_target = compositor.CreateTargetForCurrentView(); m_target.Root(root); m_visuals = root.Children(); window.PointerPressed([&](auto const &, PointerEventArgs const & args) { Point point = args.CurrentPoint().Position(); if (args.KeyModifiers() == VirtualKeyModifiers::Control) { AddVisual(point); } else { SelectVisual(point); } }); window.PointerMoved([&](auto const &, PointerEventArgs const & args) { if (m_selected) { Point point = args.CurrentPoint().Position(); m_selected.Offset(Vector3 { point.X + m_offset.X, point.Y + m_offset.Y }); } }); window.PointerReleased([&](auto const &, auto const &) { m_selected = nullptr; }); }
void PostProcessSample::initialize() { _font = Font::create("res/ui/arial.gpb"); // Load game scene from file _scene = Scene::load("res/common/duck.gpb"); _scene->getActiveCamera()->setAspectRatio(getAspectRatio()); // Initialize box model _modelNode = _scene->findNode("duck"); Model* model = dynamic_cast<Model*>(_modelNode->getDrawable()); Material* material = model->setMaterial("res/common/duck.material"); // Get light node Node* lightNode = _scene->findNode("directionalLight1"); Light* light = lightNode->getLight(); material->getParameter("u_directionalLightColor[0]")->setValue(light->getColor()); material->getParameter("u_directionalLightDirection[0]")->setValue(lightNode->getForwardVectorView()); // Create one frame buffer for the full screen compositerss. _frameBuffer = FrameBuffer::create("PostProcessSample", FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT); DepthStencilTarget* dst = DepthStencilTarget::create("PostProcessSample", DepthStencilTarget::DEPTH_STENCIL, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT); _frameBuffer->setDepthStencilTarget(dst); SAFE_RELEASE(dst); // Create our compositors that all output to the default framebuffer. Compositor* compositor = NULL; compositor = Compositor::create(_frameBuffer, NULL, "res/common/postprocess/postprocess.material", "Passthrough"); _compositors.push_back(compositor); compositor = Compositor::create(_frameBuffer, NULL, "res/common/postprocess/postprocess.material", "Grayscale"); _compositors.push_back(compositor); compositor = Compositor::create(_frameBuffer, NULL, "res/common/postprocess/postprocess.material", "Sepia"); _compositors.push_back(compositor); compositor = Compositor::create(_frameBuffer, NULL, "res/common/postprocess/postprocess.material", "Pixelate"); _compositors.push_back(compositor); compositor = Compositor::create(_frameBuffer, NULL, "res/common/postprocess/postprocess.material", "Sobel Edge"); _compositors.push_back(compositor); compositor->getMaterial()->getParameter("u_width")->setValue((float)FRAMEBUFFER_WIDTH / 2.0f); compositor->getMaterial()->getParameter("u_height")->setValue((float)FRAMEBUFFER_HEIGHT / 2.0f); compositor = Compositor::create(_frameBuffer, NULL, "res/common/postprocess/postprocess.material", "Gaussian Blur"); _compositors.push_back(compositor); compositor->getMaterial()->getParameter("u_length")->setValue(1.0f / ((float)FRAMEBUFFER_WIDTH / 2.0f)); compositor = Compositor::create(_frameBuffer, NULL, "res/common/postprocess/postprocess.material", "Old Film"); _compositors.push_back(compositor); compositor->getMaterial()->getParameter("u_sepiaValue")->setValue(0.8f); compositor->getMaterial()->getParameter("u_noiseValue")->setValue(0.4f); compositor->getMaterial()->getParameter("u_scratchValue")->setValue(0.4f); compositor->getMaterial()->getParameter("u_innerVignetting")->setValue(0.9f); compositor->getMaterial()->getParameter("u_outerVignetting")->setValue(0.9f); }
void GLWorker::WorkerRoutine() { int ret = 0; TRY(pthread_mutex_lock(&lock_), "lock GLThread", return ); Compositor compositor; TRY(compositor.Init(), "initialize GL", goto out_signal_done); worker_ret_ = 0; TRY(pthread_cond_signal(&work_done_cond_), "signal GLThread caller", goto out_signal_done); while (true) { while (worker_work_ == NULL && !worker_exit_) TRY(pthread_cond_wait(&work_ready_cond_, &lock_), "wait on condition", goto out_signal_done); if (worker_exit_) { ret = 0; break; } ret = DoComposition(compositor, worker_work_); worker_work_ = NULL; if (ret) { break; } } out_signal_done: worker_exit_ = true; worker_ret_ = ret; TRY(pthread_cond_signal(&work_done_cond_), "signal GLThread caller", goto out_unlock); out_unlock: TRY(pthread_mutex_unlock(&lock_), "unlock GLThread", return ); }
void Composition::Repair() { Coord* natural; Coord* stretchability; Coord* shrinkability; int componentCount; int* breaks; // prepare the arrays with the desired component sizes // ,,, // determine where the breaks are: int breakCount; breakCount = _compositor->Compose(natural, stretchability, shrinkability, componentCount, _lineWidth, breaks); // lay out components according to breaks // ... }
void TitleScreen::draw(Compositor& compositor) { auto& context = compositor.make_context(); Sector& sector = m_titlesession->get_current_sector(); sector.draw(context); context.color().draw_surface_scaled(m_frame, Rectf(0, 0, static_cast<float>(context.get_width()), static_cast<float>(context.get_height())), LAYER_FOREGROUND1); context.color().draw_text(Resources::small_font, m_copyright_text, Vector(5.0f, static_cast<float>(context.get_height()) - 50.0f), ALIGN_LEFT, LAYER_FOREGROUND1); context.color().draw_text(Resources::small_font, m_videosystem_name, Vector(static_cast<float>(context.get_width()) - 5.0f, static_cast<float>(context.get_height()) - 14.0f), ALIGN_RIGHT, LAYER_FOREGROUND1); }
//DbusHandler DBusHandler::DBusHandler(Compositor& comp) : compositor_(&comp) { DBusError err; dbus_error_init(&err); dbus_connection_set_change_sigpipe(false); //todo: error checking everywhere if(!(dbusConnection_ = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err))) { std::string errStr; checkError(err, errStr); throw std::runtime_error("DBus::DBus: cant connect to dbus. " + errStr); return; } dbus_connection_set_exit_on_disconnect(dbusConnection_, false); //use dummy event fd int fd; if((fd = eventfd(0, EFD_CLOEXEC)) < 0) { throw std::runtime_error("DBus::DBus: cant create eventfd"); return; } //event source dbusEventSource_ = wl_event_loop_add_fd(&comp.wlEventLoop(), fd, 0, Callbacks::dispatchDBus, this); close(fd); wl_event_source_check(dbusEventSource_); //watch if(!dbus_connection_set_watch_functions(dbusConnection_, Callbacks::addWatch, Callbacks::removeWatch, Callbacks::toggleWatch, this, nullptr)) { throw std::runtime_error("dbus_connection_set_watch_functions failed"); return; } //timeout if(!dbus_connection_set_timeout_functions(dbusConnection_, Callbacks::addTimeout, Callbacks::removeTimeout, Callbacks::toggleTimeout, this, nullptr)) { throw std::runtime_error("dbus_connection_set_timeout_functions failed"); return; } //filter if(!dbus_connection_add_filter(dbusConnection_, Callbacks::dbusFilter, this, nullptr)) { throw std::runtime_error("dbus add filter failed"); return; } //disconnected callback signalCallbacks_.emplace_back(MsgCallback{DBUS_INTERFACE_LOCAL, "Diconnected", nytl::memberCallback(&DBusHandler::disconnected, this)}); ny::sendLog("dbus handler succesfully set up"); }
void ContentHostIncremental::TextureCreationRequest::Execute(ContentHostIncremental* aHost) { Compositor* compositor = aHost->GetCompositor(); MOZ_ASSERT(compositor); RefPtr<DataTextureSource> temp = compositor->CreateDataTextureSource(mTextureInfo.mTextureFlags); MOZ_ASSERT(temp->AsSourceOGL() && temp->AsSourceOGL()->AsTextureImageTextureSource()); RefPtr<TextureImageTextureSourceOGL> newSource = temp->AsSourceOGL()->AsTextureImageTextureSource(); RefPtr<TextureImageTextureSourceOGL> newSourceOnWhite; if (mTextureInfo.mTextureFlags & TextureFlags::COMPONENT_ALPHA) { temp = compositor->CreateDataTextureSource(mTextureInfo.mTextureFlags); MOZ_ASSERT(temp->AsSourceOGL() && temp->AsSourceOGL()->AsTextureImageTextureSource()); newSourceOnWhite = temp->AsSourceOGL()->AsTextureImageTextureSource(); } if (mTextureInfo.mDeprecatedTextureHostFlags & DeprecatedTextureHostFlags::COPY_PREVIOUS) { MOZ_ASSERT(aHost->mSource); MOZ_ASSERT(aHost->mSource->IsValid()); nsIntRect bufferRect = aHost->mBufferRect; nsIntPoint bufferRotation = aHost->mBufferRotation; nsIntRect overlap; // The buffer looks like: // ______ // |1 |2 | Where the center point is offset by mBufferRotation from the top-left corner. // |___|__| // |3 |4 | // |___|__| // // This is drawn to the screen as: // ______ // |4 |3 | Where the center point is { width - mBufferRotation.x, height - mBufferRotation.y } from // |___|__| from the top left corner - rotationPoint. // |2 |1 | // |___|__| // // The basic idea below is to take all quadrant rectangles from the src and transform them into rectangles // in the destination. Unfortunately, it seems it is overly complex and could perhaps be simplified. nsIntRect srcBufferSpaceBottomRight(bufferRotation.x, bufferRotation.y, bufferRect.width - bufferRotation.x, bufferRect.height - bufferRotation.y); nsIntRect srcBufferSpaceTopRight(bufferRotation.x, 0, bufferRect.width - bufferRotation.x, bufferRotation.y); nsIntRect srcBufferSpaceTopLeft(0, 0, bufferRotation.x, bufferRotation.y); nsIntRect srcBufferSpaceBottomLeft(0, bufferRotation.y, bufferRotation.x, bufferRect.height - bufferRotation.y); overlap.IntersectRect(bufferRect, mBufferRect); nsIntRect srcRect(overlap), dstRect(overlap); srcRect.MoveBy(- bufferRect.TopLeft() + bufferRotation); nsIntRect srcRectDrawTopRight(srcRect); nsIntRect srcRectDrawTopLeft(srcRect); nsIntRect srcRectDrawBottomLeft(srcRect); // transform into the different quadrants srcRectDrawTopRight .MoveBy(-nsIntPoint(0, bufferRect.height)); srcRectDrawTopLeft .MoveBy(-nsIntPoint(bufferRect.width, bufferRect.height)); srcRectDrawBottomLeft.MoveBy(-nsIntPoint(bufferRect.width, 0)); // Intersect with the quadrant srcRect = srcRect .Intersect(srcBufferSpaceBottomRight); srcRectDrawTopRight = srcRectDrawTopRight .Intersect(srcBufferSpaceTopRight); srcRectDrawTopLeft = srcRectDrawTopLeft .Intersect(srcBufferSpaceTopLeft); srcRectDrawBottomLeft = srcRectDrawBottomLeft.Intersect(srcBufferSpaceBottomLeft); dstRect = srcRect; nsIntRect dstRectDrawTopRight(srcRectDrawTopRight); nsIntRect dstRectDrawTopLeft(srcRectDrawTopLeft); nsIntRect dstRectDrawBottomLeft(srcRectDrawBottomLeft); // transform back to src buffer space dstRect .MoveBy(-bufferRotation); dstRectDrawTopRight .MoveBy(-bufferRotation + nsIntPoint(0, bufferRect.height)); dstRectDrawTopLeft .MoveBy(-bufferRotation + nsIntPoint(bufferRect.width, bufferRect.height)); dstRectDrawBottomLeft.MoveBy(-bufferRotation + nsIntPoint(bufferRect.width, 0)); // transform back to draw coordinates dstRect .MoveBy(bufferRect.TopLeft()); dstRectDrawTopRight .MoveBy(bufferRect.TopLeft()); dstRectDrawTopLeft .MoveBy(bufferRect.TopLeft()); dstRectDrawBottomLeft.MoveBy(bufferRect.TopLeft()); // transform to destBuffer space dstRect .MoveBy(-mBufferRect.TopLeft()); dstRectDrawTopRight .MoveBy(-mBufferRect.TopLeft()); dstRectDrawTopLeft .MoveBy(-mBufferRect.TopLeft()); dstRectDrawBottomLeft.MoveBy(-mBufferRect.TopLeft()); newSource->EnsureBuffer(mBufferRect.Size(), ContentForFormat(aHost->mSource->GetFormat())); aHost->mSource->CopyTo(srcRect, newSource, dstRect); if (bufferRotation != nsIntPoint(0, 0)) { // Draw the remaining quadrants. We call BlitTextureImage 3 extra // times instead of doing a single draw call because supporting that // with a tiled source is quite tricky. if (!srcRectDrawTopRight.IsEmpty()) aHost->mSource->CopyTo(srcRectDrawTopRight, newSource, dstRectDrawTopRight); if (!srcRectDrawTopLeft.IsEmpty()) aHost->mSource->CopyTo(srcRectDrawTopLeft, newSource, dstRectDrawTopLeft); if (!srcRectDrawBottomLeft.IsEmpty()) aHost->mSource->CopyTo(srcRectDrawBottomLeft, newSource, dstRectDrawBottomLeft); } if (newSourceOnWhite) { newSourceOnWhite->EnsureBuffer(mBufferRect.Size(), ContentForFormat(aHost->mSourceOnWhite->GetFormat())); aHost->mSourceOnWhite->CopyTo(srcRect, newSourceOnWhite, dstRect); if (bufferRotation != nsIntPoint(0, 0)) { // draw the remaining quadrants if (!srcRectDrawTopRight.IsEmpty()) aHost->mSourceOnWhite->CopyTo(srcRectDrawTopRight, newSourceOnWhite, dstRectDrawTopRight); if (!srcRectDrawTopLeft.IsEmpty()) aHost->mSourceOnWhite->CopyTo(srcRectDrawTopLeft, newSourceOnWhite, dstRectDrawTopLeft); if (!srcRectDrawBottomLeft.IsEmpty()) aHost->mSourceOnWhite->CopyTo(srcRectDrawBottomLeft, newSourceOnWhite, dstRectDrawBottomLeft); } } } aHost->mSource = newSource; aHost->mSourceOnWhite = newSourceOnWhite; aHost->mBufferRect = mBufferRect; aHost->mBufferRotation = nsIntPoint(); }
template<class ContainerT> void ContainerRender(ContainerT* aContainer, const nsIntPoint& aOffset, LayerManagerComposite* aManager, const nsIntRect& aClipRect) { /** * Setup our temporary surface for rendering the contents of this container. */ RefPtr<CompositingRenderTarget> surface; Compositor* compositor = aManager->GetCompositor(); RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget(); nsIntPoint childOffset(aOffset); nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); aContainer->mSupportsComponentAlphaChildren = false; float opacity = aContainer->GetEffectiveOpacity(); bool needsSurface = aContainer->UseIntermediateSurface(); if (needsSurface) { SurfaceInitMode mode = INIT_MODE_CLEAR; bool surfaceCopyNeeded = false; gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); // we're about to create a framebuffer backed by textures to use as an intermediate // surface. What to do if its size (as given by framebufferRect) would exceed the // maximum texture size supported by the GL? The present code chooses the compromise // of just clamping the framebuffer's size to the max supported size. // This gives us a lower resolution rendering of the intermediate surface (children layers). // See bug 827170 for a discussion. int32_t maxTextureSize = compositor->GetMaxTextureSize(); surfaceRect.width = std::min(maxTextureSize, surfaceRect.width); surfaceRect.height = std::min(maxTextureSize, surfaceRect.height); if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff aContainer->mSupportsComponentAlphaChildren = true; mode = INIT_MODE_NONE; } else { const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); gfxMatrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. if (HasOpaqueAncestorLayer(aContainer) && transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { mode = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering() ? INIT_MODE_COPY : INIT_MODE_CLEAR; surfaceCopyNeeded = (mode == INIT_MODE_COPY); surfaceRect.x += transform.x0; surfaceRect.y += transform.y0; aContainer->mSupportsComponentAlphaChildren = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering(); } } surfaceRect -= gfx::IntPoint(aOffset.x, aOffset.y); if (surfaceCopyNeeded) { surface = compositor->CreateRenderTargetFromSource(surfaceRect, previousTarget); } else { surface = compositor->CreateRenderTarget(surfaceRect, mode); } compositor->SetRenderTarget(surface); childOffset.x = visibleRect.x; childOffset.y = visibleRect.y; } else { surface = previousTarget; aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); } nsAutoTArray<Layer*, 12> children; aContainer->SortChildrenBy3DZOrder(children); /** * Render this container's contents. */ for (uint32_t i = 0; i < children.Length(); i++) { LayerComposite* layerToRender = static_cast<LayerComposite*>(children.ElementAt(i)->ImplData()); if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty() && !layerToRender->GetLayer()->AsContainerLayer()) { continue; } nsIntRect clipRect = layerToRender->GetLayer()-> CalculateScissorRect(aClipRect, &aManager->GetWorldTransform()); if (clipRect.IsEmpty()) { continue; } layerToRender->RenderLayer(childOffset, clipRect); // invariant: our GL context should be current here, I don't think we can // assert it though } if (needsSurface) { // Unbind the current surface and rebind the previous one. #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { nsRefPtr<gfxImageSurface> surf = surface->Dump(aManager->GetCompositor()); WriteSnapshotToDumpFile(aContainer, surf); } #endif compositor->SetRenderTarget(previousTarget); EffectChain effectChain; LayerManagerComposite::AddMaskEffect(aContainer->GetMaskLayer(), effectChain, !aContainer->GetTransform().CanDraw2D()); effectChain.mPrimaryEffect = new EffectRenderTarget(surface); gfx::Matrix4x4 transform; ToMatrix4x4(aContainer->GetEffectiveTransform(), transform); gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity, transform, gfx::Point(aOffset.x, aOffset.y)); } if (aContainer->GetFrameMetrics().IsScrollable()) { gfx::Matrix4x4 transform; ToMatrix4x4(aContainer->GetEffectiveTransform(), transform); const FrameMetrics& frame = aContainer->GetFrameMetrics(); LayerRect layerViewport = frame.mViewport * frame.LayersPixelsPerCSSPixel(); gfx::Rect rect(layerViewport.x, layerViewport.y, layerViewport.width, layerViewport.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawDiagnostics(gfx::Color(1.0, 0.0, 0.0, 1.0), rect, clipRect, transform, gfx::Point(aOffset.x, aOffset.y)); } }
static void DrawVelGraph(const nsIntRect& aClipRect, LayerManagerComposite* aManager, Layer* aLayer) { static char sLayerVelocityUserDataKey; Compositor* compositor = aManager->GetCompositor(); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); TimeStamp now = TimeStamp::Now(); void* key = reinterpret_cast<void*>(&sLayerVelocityUserDataKey); if (!aLayer->HasUserData(key)) { aLayer->SetUserData(key, new LayerVelocityUserData()); } LayerVelocityUserData* velocityData = static_cast<LayerVelocityUserData*>(aLayer->GetUserData(key)); if (velocityData->mData.size() >= 1 && now > velocityData->mData[velocityData->mData.size() - 1].mFrameTime + TimeDuration::FromMilliseconds(200)) { // clear stale data velocityData->mData.clear(); } nsIntPoint scrollOffset = aLayer->GetEffectiveVisibleRegion().GetBounds().TopLeft(); velocityData->mData.push_back( LayerVelocityUserData::VelocityData(now, scrollOffset.x, scrollOffset.y)); // XXX: Uncomment these lines to enable ScrollGraph logging. This is // useful for HVGA phones or to output the data to accurate // graphing software. //printf_stderr("ScrollGraph (%p): %i, %i\n", // aLayer, scrollOffset.x, scrollOffset.y); // Keep a circular buffer of 100. size_t circularBufferSize = 100; if (velocityData->mData.size() > circularBufferSize) { velocityData->mData.erase(velocityData->mData.begin()); } if (velocityData->mData.size() == 1) { return; } // Clear and disable the graph when it's flat for (size_t i = 1; i < velocityData->mData.size(); i++) { if (velocityData->mData[i - 1].mPoint != velocityData->mData[i].mPoint) { break; } if (i == velocityData->mData.size() - 1) { velocityData->mData.clear(); return; } } if (aLayer->GetEffectiveVisibleRegion().GetBounds().width < 300 || aLayer->GetEffectiveVisibleRegion().GetBounds().height < 300) { // Don't want a graph for smaller layers return; } aManager->SetDebugOverlayWantsNextFrame(true); const gfx::Matrix4x4& transform = aLayer->GetEffectiveTransform(); nsIntRect bounds = aLayer->GetEffectiveVisibleRegion().GetBounds(); gfx::Rect graphBounds = gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height); gfx::Rect graphRect = gfx::Rect(bounds.x, bounds.y, 200, 100); float opacity = 1.0; EffectChain effects; effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0.2f,0,0,1)); compositor->DrawQuad(graphRect, clipRect, effects, opacity, transform); std::vector<gfx::Point> graph; int yScaleFactor = 3; for (int32_t i = (int32_t)velocityData->mData.size() - 2; i >= 0; i--) { const gfx::Point& p1 = velocityData->mData[i+1].mPoint; const gfx::Point& p2 = velocityData->mData[i].mPoint; int vel = sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); graph.push_back( gfx::Point(bounds.x + graphRect.width / circularBufferSize * i, graphBounds.y + graphRect.height - vel/yScaleFactor)); } compositor->DrawLines(graph, clipRect, gfx::Color(0,1,0,1), opacity, transform); }
X11Backend::X11Backend(Compositor& comp, Seat& seat) : Backend(), compositor_(&comp), seat_(&seat) { //setup x connection xDisplay_ = XOpenDisplay(nullptr); if(!xDisplay_) { throw std::runtime_error("cant connect to x11 server"); return; } xConnection_ = XGetXCBConnection(xDisplay_); if(!xConnection_) { throw std::runtime_error("cant get xcb connection"); return; } XSetEventQueueOwner(xDisplay_, XCBOwnsEventQueue); if(xcb_connection_has_error(xConnection_)) { throw std::runtime_error("xcb connection error"); return; } xScreen_ = xcb_setup_roots_iterator(xcb_get_setup(xConnection_)).data; //atoms struct atomProp { xcb_atom_t& ret; std::string str; }; atomProp vec[] = { {atoms::protocols, "WM_PROTOCOLS"}, {atoms::deleteWindow, "WM_DELETE_WINDOW"} }; xcb_intern_atom_reply_t* reply; for(auto& p : vec) { auto atom = xcb_intern_atom(xConnection_, 0, p.str.size(), p.str.c_str()); reply = xcb_intern_atom_reply(xConnection_, atom, nullptr); p.ret = (reply ? reply->atom : 0); } //xkb xkbSetup(); //event source inputEventSource_ = wl_event_loop_add_fd(&comp.wlEventLoop(), xcb_get_file_descriptor(xConnection_), WL_EVENT_READABLE, eventCallback, this); if(!inputEventSource_) throw std::runtime_error("could not create wayland event source"); //what does this? really needed? wl_event_source_check(inputEventSource_); //eglContext eglContext_ = std::make_unique<WaylandEglContext>(xDisplay_); if(!eglContext_) throw std::runtime_error("x11Backend::x11Backend: failed to create EglContext"); eglContext_->bindWlDisplay(compositor_->wlDisplay()); xcb_flush(xConnection_); }
static void compositor_create_surface(wl_client *client, wl_resource *compositorResource, uint32_t id) { Compositor *compositor = static_cast<Compositor *>(compositorResource->data); compositor->addSurface(new Surface(client, id, wl_resource_get_version(compositorResource), compositor)); }
template<class ContainerT> void ContainerRender(ContainerT* aContainer, LayerManagerComposite* aManager, const nsIntRect& aClipRect) { /** * Setup our temporary surface for rendering the contents of this container. */ RefPtr<CompositingRenderTarget> surface; Compositor* compositor = aManager->GetCompositor(); RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget(); nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); aContainer->mSupportsComponentAlphaChildren = false; float opacity = aContainer->GetEffectiveOpacity(); bool needsSurface = aContainer->UseIntermediateSurface(); if (needsSurface) { SurfaceInitMode mode = INIT_MODE_CLEAR; bool surfaceCopyNeeded = false; gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); gfx::IntPoint sourcePoint = gfx::IntPoint(visibleRect.x, visibleRect.y); // we're about to create a framebuffer backed by textures to use as an intermediate // surface. What to do if its size (as given by framebufferRect) would exceed the // maximum texture size supported by the GL? The present code chooses the compromise // of just clamping the framebuffer's size to the max supported size. // This gives us a lower resolution rendering of the intermediate surface (children layers). // See bug 827170 for a discussion. int32_t maxTextureSize = compositor->GetMaxTextureSize(); surfaceRect.width = std::min(maxTextureSize, surfaceRect.width); surfaceRect.height = std::min(maxTextureSize, surfaceRect.height); if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff aContainer->mSupportsComponentAlphaChildren = true; mode = INIT_MODE_NONE; } else { const gfx::Matrix4x4& transform3D = aContainer->GetEffectiveTransform(); gfx::Matrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. if (HasOpaqueAncestorLayer(aContainer) && transform3D.Is2D(&transform) && !ThebesMatrix(transform).HasNonIntegerTranslation()) { surfaceCopyNeeded = gfxPlatform::ComponentAlphaEnabled(); sourcePoint.x += transform._31; sourcePoint.y += transform._32; aContainer->mSupportsComponentAlphaChildren = gfxPlatform::ComponentAlphaEnabled(); } } sourcePoint -= compositor->GetCurrentRenderTarget()->GetOrigin(); if (surfaceCopyNeeded) { surface = compositor->CreateRenderTargetFromSource(surfaceRect, previousTarget, sourcePoint); } else { surface = compositor->CreateRenderTarget(surfaceRect, mode); } if (!surface) { return; } compositor->SetRenderTarget(surface); } else { surface = previousTarget; aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); } nsAutoTArray<Layer*, 12> children; aContainer->SortChildrenBy3DZOrder(children); /** * Render this container's contents. */ for (uint32_t i = 0; i < children.Length(); i++) { LayerComposite* layerToRender = static_cast<LayerComposite*>(children.ElementAt(i)->ImplData()); if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty() && !layerToRender->GetLayer()->AsContainerLayer()) { continue; } if (i + 1 < children.Length() && layerToRender->GetLayer()->GetEffectiveTransform().IsIdentity()) { LayerComposite* nextLayer = static_cast<LayerComposite*>(children.ElementAt(i + 1)->ImplData()); nsIntRect nextLayerOpaqueRect; if (nextLayer && nextLayer->GetLayer()) { nextLayerOpaqueRect = GetOpaqueRect(nextLayer->GetLayer()); } if (!nextLayerOpaqueRect.IsEmpty()) { nsIntRegion visibleRegion; visibleRegion.Sub(layerToRender->GetShadowVisibleRegion(), nextLayerOpaqueRect); layerToRender->SetShadowVisibleRegion(visibleRegion); if (visibleRegion.IsEmpty()) { continue; } } } nsIntRect clipRect = layerToRender->GetLayer()-> CalculateScissorRect(aClipRect, &aManager->GetWorldTransform()); if (clipRect.IsEmpty()) { continue; } if (layerToRender->HasLayerBeenComposited()) { // Composer2D will compose this layer so skip GPU composition // this time & reset composition flag for next composition phase layerToRender->SetLayerComposited(false); if (layerToRender->GetClearFB()) { // Clear layer's visible rect on FrameBuffer with transparent pixels gfx::Rect aRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); compositor->clearFBRect(&aRect); layerToRender->SetClearFB(false); } } else { layerToRender->RenderLayer(clipRect); } if (gfxPlatform::GetPrefLayersScrollGraph()) { DrawVelGraph(clipRect, aManager, layerToRender->GetLayer()); } // invariant: our GL context should be current here, I don't think we can // assert it though } if (needsSurface) { // Unbind the current surface and rebind the previous one. #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { RefPtr<gfx::DataSourceSurface> surf = surface->Dump(aManager->GetCompositor()); WriteSnapshotToDumpFile(aContainer, surf); } #endif compositor->SetRenderTarget(previousTarget); EffectChain effectChain; LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(aContainer->GetMaskLayer(), effectChain, !aContainer->GetTransform().CanDraw2D()); effectChain.mPrimaryEffect = new EffectRenderTarget(surface); gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity, aContainer->GetEffectiveTransform()); } if (aContainer->GetFrameMetrics().IsScrollable()) { const FrameMetrics& frame = aContainer->GetFrameMetrics(); LayerRect layerBounds = ScreenRect(frame.mCompositionBounds) * ScreenToLayerScale(1.0); gfx::Rect rect(layerBounds.x, layerBounds.y, layerBounds.width, layerBounds.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawDiagnostics(DIAGNOSTIC_CONTAINER, rect, clipRect, aContainer->GetEffectiveTransform()); } }
int main(int argc, char*argv[]) { // Parse the input if(argc < 6) { std::cerr << "Required arguments: image sourceMask.mask targetMask.mask patchRadius output" << std::endl; return EXIT_FAILURE; } std::stringstream ss; for(int i = 1; i < argc; ++i) { ss << argv[i] << " "; } std::string imageFilename; std::string sourceMaskFilename; std::string targetMaskFilename; unsigned int patchRadius; std::string outputFilename; ss >> imageFilename >> sourceMaskFilename >> targetMaskFilename >> patchRadius >> outputFilename; // Output the parsed values std::cout << "imageFilename: " << imageFilename << std::endl << "sourceMaskFilename: " << sourceMaskFilename << std::endl << "targetMaskFilename: " << targetMaskFilename << std::endl << "patchRadius: " << patchRadius << std::endl << "outputFilename: " << outputFilename << std::endl; typedef itk::Image<itk::CovariantVector<unsigned char, 3>, 2> ImageType; // Read the image and the masks typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); ImageType* image = imageReader->GetOutput(); Mask::Pointer sourceMask = Mask::New(); sourceMask->Read(sourceMaskFilename); Mask::Pointer targetMask = Mask::New(); targetMask->Read(targetMaskFilename); //std::cout << "target mask has " << targetMask->CountHolePixels() << " hole pixels." << std::endl; // Poisson fill the input image typedef PoissonEditing<typename TypeTraits<ImageType::PixelType>::ComponentType> PoissonEditingType; typename PoissonEditingType::GuidanceFieldType::Pointer zeroGuidanceField = PoissonEditingType::GuidanceFieldType::New(); zeroGuidanceField->SetRegions(image->GetLargestPossibleRegion()); zeroGuidanceField->Allocate(); typename PoissonEditingType::GuidanceFieldType::PixelType zeroPixel; zeroPixel.Fill(0); ITKHelpers::SetImageToConstant(zeroGuidanceField.GetPointer(), zeroPixel); PoissonEditingType::FillImage(image, targetMask, zeroGuidanceField.GetPointer(), image); ITKHelpers::WriteRGBImage(image, "PoissonFilled.png"); // PatchMatch requires that the target region be specified by valid pixels targetMask->InvertData(); // Setup the patch distance functor SSD<ImageType> ssdFunctor; ssdFunctor.SetImage(image); // Setup the PatchMatch functor //PatchMatch<ImageType> patchMatchFunctor; PatchMatchRings<ImageType> patchMatchFunctor; patchMatchFunctor.SetPatchRadius(patchRadius); patchMatchFunctor.SetPatchDistanceFunctor(&ssdFunctor); patchMatchFunctor.SetIterations(1); InitializerRandom<ImageType> initializer; initializer.SetImage(image); initializer.SetTargetMask(targetMask); initializer.SetSourceMask(sourceMask); initializer.SetPatchDistanceFunctor(&ssdFunctor); initializer.SetPatchRadius(patchRadius); patchMatchFunctor.SetInitializer(&initializer); // Test the result of PatchMatch here patchMatchFunctor.SetRandom(false); // Here, the source match and target match are the same, specifying the classicial // "use pixels outside the hole to fill the pixels inside the hole". // In an interactive algorith, the user could manually specify a source region, // improving the resulting inpainting. BDSInpaintingMultiRes<ImageType> bdsInpainting; bdsInpainting.SetPatchRadius(patchRadius); bdsInpainting.SetImage(image); bdsInpainting.SetSourceMask(sourceMask); bdsInpainting.SetTargetMask(targetMask); bdsInpainting.SetIterations(1); //bdsInpainting.SetIterations(4); Compositor<ImageType> compositor; compositor.SetCompositingMethod(Compositor<ImageType>::AVERAGE); bdsInpainting.SetCompositor(&compositor); bdsInpainting.SetPatchMatchFunctor(&patchMatchFunctor); bdsInpainting.Inpaint(); ITKHelpers::WriteRGBImage(bdsInpainting.GetOutput(), outputFilename); return EXIT_SUCCESS; }
//Subcompositor Subcompositor::Subcompositor(Compositor& comp) : compositor_(&comp) { wlGlobal_ = wl_global_create(&comp.wlDisplay(), &wl_subcompositor_interface, 1, this, bindSubcompositor); }
//TerminalHandler TerminalHandler::TerminalHandler(Compositor& comp) { const char* number = getenv("XDG_VTNR"); if(!number) { throw std::runtime_error("tty::tty: XDG_VTNR not set"); return; } number_ = std::stoi(number); //open tty std::string ttyString = "/dev/tty" + std::to_string(number_); tty_ = open(ttyString.c_str(), O_RDWR | O_NOCTTY | O_CLOEXEC); if(tty_ < 0) { throw std::runtime_error("TerminalHandler::TerminalHandler: couldnt open " + ttyString); return; } int fd = tty_; //save current vt_stat state; if(ioctl(fd, VT_GETSTATE, &state) == -1) { throw std::runtime_error("could not get current tty"); return; } //set it up if(ioctl(tty_, VT_ACTIVATE, number_) == -1 || ioctl(tty_, VT_WAITACTIVE, number_) == -1) { throw std::runtime_error("Could not activate tty"); return; } focus_ = 1; /* if (ioctl(fd, KDSKBMUTE, 1) == -1 && ioctl(fd, KDSKBMODE, K_OFF) == -1) { throw std::runtime_error("failed to set tty keyboard mode"); return; } if(ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) { throw std::runtime_error("Could not set tty to graphics mode"); return; } */ vt_mode mode; mode.mode = VT_PROCESS; mode.acqsig = SIGUSR1; mode.relsig = SIGUSR2; if(ioctl(fd, VT_SETMODE, &mode) == -1) { throw std::runtime_error("Could not set vt_mode"); return; } wl_event_loop_add_signal(&comp.wlEventLoop(), SIGUSR1, ttySignalhandler, this); wl_event_loop_add_signal(&comp.wlEventLoop(), SIGUSR2, ttySignalhandler, this); }
bool HomeApplication::run(const QString &shell) { // If a compositor is already running we cannot continue if (Compositor::instance()->isRunning()) { qCWarning(GREENISLAND_COMPOSITOR) << "Compositor already running, don't call run() more than once!"; return false; } // Set plugin GreenIsland::Compositor::s_fixedShell = shell; // Check whether XDG_RUNTIME_DIR is ok or not GreenIsland::verifyXdgRuntimeDir(); // If a socket is passed it means that we are nesting into // another compositor, let's do some checks if (!m_socket.isEmpty()) { // We need wayland QPA plugin if (!QGuiApplication::platformName().startsWith(QStringLiteral("wayland"))) { qCWarning(GREENISLAND_COMPOSITOR) << "By passing the \"--socket\" argument you are requesting to nest" << "this compositor into another, but you forgot to pass " << "also \"-platform wayland\"!"; #if HAVE_SYSTEMD if (m_notify) sd_notifyf(0, "STATUS=Nesting requested, but no wayland QPA"); #endif return false; } } // Screen configuration if (!m_fakeScreenFileName.isEmpty()) { // Need the native backend if (QGuiApplication::platformName().startsWith(QStringLiteral("wayland"))) { qCWarning(GREENISLAND_COMPOSITOR) << "Fake screen configuration is not allowed when Green Island" << "is nested into another compositor"; #if HAVE_SYSTEMD if (m_notify) sd_notifyf(0, "STATUS=Fake screen configuration not allowed when nested"); #endif return false; } } // Create the compositor Compositor *compositor = Compositor::instance(); if (!m_fakeScreenFileName.isEmpty()) compositor->setFakeScreenConfiguration(m_fakeScreenFileName); QObject::connect(compositor, &Compositor::screenConfigurationAcquired, [this] { #if HAVE_SYSTEMD // Notify systemd when the screen configuration is ready if (m_notify) { qCDebug(GREENISLAND_COMPOSITOR) << "Compositor ready, notify systemd on" << qgetenv("NOTIFY_SOCKET"); sd_notify(0, "READY=1"); } #endif }); compositor->run(); compositorLaunched(); return true; }