Workspace::Workspace() : mDamage( None ), mWaitForClients( false ), mInitialRepaint( true ) { Extensions::initialize(); XGrabServer( dpy ); // Redirect all toplevel window contents to offscreen storage XCompositeRedirectSubwindows( dpy, rootId(), CompositeRedirectManual ); initClientList(); // Request notification about toplevel window state changes XSelectInput( dpy, rootId(), SubstructureNotifyMask | ExposureMask | StructureNotifyMask | PropertyChangeMask ); XUngrabServer( dpy ); // Get the picture format for the root window mFormat = XRenderFindVisualFormat( dpy, visual() ); // Create an unclipped picture for drawing on the root window XRenderPictureAttributes pa; pa.subwindow_mode = IncludeInferiors; mFrontbuffer = XRenderCreatePicture( dpy, rootId(), format(), CPSubwindowMode, &pa ); createBackbuffer(); XSync( dpy, false ); }
/*! Tries to ask the X Composite extension (if supported) to redirect all windows on all screens to backing storage. This does not have any effect if another application already requested the same thing (typically the window manager does this). */ void WindowImageProvider::activateComposite() { int event_base; int error_base; Display *display = QX11Info::display(); bool compositeSupport = false; if (XCompositeQueryExtension(display, &event_base, &error_base)) { int major = 0; int minor = 2; XCompositeQueryVersion(display, &major, &minor); if (major > 0 || minor >= 2) { compositeSupport = true; (UQ_DEBUG).nospace() << "Server supports the Composite extension (ver " << major << "." << minor << ")"; } else { (UQ_DEBUG).nospace() << "Server supports the Composite extension, but " "version is < 0.2 (ver " << major << "." << minor << ")"; } } else { UQ_DEBUG << "Server doesn't support the Composite extension."; } if (compositeSupport) { int screens = ScreenCount(display); for (int i = 0; i < screens; ++i) { XCompositeRedirectSubwindows(display, RootWindow(display, i), CompositeRedirectAutomatic); } } }
void setup_x(void) { screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); XSetErrorHandler(on_xerror); XSelectInput (dpy, root, SubstructureNotifyMask|KeyPressMask|VisibilityChangeMask|ExposureMask); XCompositeRedirectSubwindows(dpy, root, CompositeRedirectAutomatic); overlay = create_overlay(); canvas = create_canvas(); debug("Root 0x%x, Overlay 0x%x, Canvas 0x%x\n", root, overlay, canvas); stop = 0; }
void MCompositeScene::prepareRoot() { Display *dpy = QX11Info::display(); Window root = QX11Info::appRootWindow(); XSetWindowAttributes sattr; sattr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask | PropertyChangeMask; // All newly mapped windows should be redirected to avoid double Expose XCompositeRedirectSubwindows(dpy, root, CompositeRedirectManual); XChangeWindowAttributes(dpy, root, CWEventMask, &sattr); XSelectInput(dpy, root, SubstructureNotifyMask | SubstructureRedirectMask | StructureNotifyMask | PropertyChangeMask | FocusChangeMask); XSetErrorHandler(error_handler); }
static void redirect_windows (MetaScreen *screen) { MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); Window xroot = meta_screen_get_xroot (screen); int screen_number = meta_screen_get_screen_number (screen); guint n_retries; guint max_retries; if (meta_get_replace_current_wm ()) max_retries = 5; else max_retries = 1; n_retries = 0; /* Some compositors (like old versions of Mutter) might not properly unredirect * subwindows before destroying the WM selection window; so we wait a while * for such a compositor to exit before giving up. */ while (TRUE) { meta_error_trap_push (display); XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual); XSync (xdisplay, FALSE); if (!meta_error_trap_pop_with_return (display)) break; if (n_retries == max_retries) { /* This probably means that a non-WM compositor like xcompmgr is running; * we have no way to get it to exit */ meta_fatal (_("Another compositing manager is already running on screen %i on display \"%s\"."), screen_number, display->name); } n_retries++; g_usleep (G_USEC_PER_SEC); } }
gboolean init_composite (void) { Display *display; display = gdk_x11_get_default_xdisplay (); // First, check the Composite extension, then the Render extension. int error_base; int event_base; int version_major; int version_minor; if (!XCompositeQueryExtension (display, &event_base, &error_base)) { return FALSE; } // We need at least version 0.2, for XCompositeNameWindowPixmap. XCompositeQueryVersion (display, &version_major, &version_minor); if (version_major <= 0 && version_minor < 2) { return FALSE; } if (!XRenderQueryExtension (display, &event_base, &error_base)) { return FALSE; } // We need at least version 0.6, for XRenderSetPictureTransform. XRenderQueryVersion (display, &version_major, &version_minor); if (version_major <= 0 && version_minor < 6) { return FALSE; } XCompositeRedirectSubwindows (display, GDK_WINDOW_XWINDOW (gdk_get_default_root_window ()), CompositeRedirectAutomatic); return TRUE; }
KWD::Decorator::Decorator () : KApplication (), mConfig (0), mCompositeWindow (0), mSwitcher (0) { XSetWindowAttributes attr; int i, j; mSelf = this; mRootInfo = new NETRootInfo (QX11Info::display (), 0); mActiveId = 0; KConfigGroup cfg (KSharedConfig::openConfig ("plasmarc"), QString ("Theme")); Plasma::Theme::defaultTheme ()->setThemeName (cfg.readEntry ("name")); Atoms::init (); new KWinAdaptor (this); mConfig = new KConfig ("kwinrc"); mOptions = new KWD::Options (mConfig); mPlugins = new PluginManager (KSharedConfig::openConfig ("kwinrc")); mActiveShadowOptions.shadow_radius = SHADOW_RADIUS; mActiveShadowOptions.shadow_opacity = SHADOW_OPACITY; mActiveShadowOptions.shadow_offset_x = SHADOW_OFFSET_X; mActiveShadowOptions.shadow_offset_y = SHADOW_OFFSET_Y; mActiveShadowOptions.shadow_color[0] = SHADOW_COLOR_RED; mActiveShadowOptions.shadow_color[1] = SHADOW_COLOR_GREEN; mActiveShadowOptions.shadow_color[2] = SHADOW_COLOR_BLUE; mInactiveShadowOptions.shadow_radius = SHADOW_RADIUS; mInactiveShadowOptions.shadow_opacity = SHADOW_OPACITY; mInactiveShadowOptions.shadow_offset_x = SHADOW_OFFSET_X; mInactiveShadowOptions.shadow_offset_y = SHADOW_OFFSET_Y; mInactiveShadowOptions.shadow_color[0] = SHADOW_COLOR_RED; mInactiveShadowOptions.shadow_color[1] = SHADOW_COLOR_GREEN; mInactiveShadowOptions.shadow_color[2] = SHADOW_COLOR_BLUE; updateShadowProperties (QX11Info::appRootWindow ()); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { if (cursors[i][j].shape != XC_left_ptr) cursors[i][j].cursor = XCreateFontCursor (QX11Info::display (), cursors[i][j].shape); } } attr.override_redirect = True; mCompositeWindow = XCreateWindow (QX11Info::display (), QX11Info::appRootWindow (), -ROOT_OFF_X, -ROOT_OFF_Y, 1, 1, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr); long data = 1; XChangeProperty (QX11Info::display(), mCompositeWindow, Atoms::enlightmentDesktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &data, 1); XCompositeRedirectSubwindows (QX11Info::display (), mCompositeWindow, CompositeRedirectManual); XMapWindow (QX11Info::display (), mCompositeWindow); QDBusConnection dbus = QDBusConnection::sessionBus (); dbus.connect (KDED_SERVICE, KDED_APPMENU_PATH, KDED_INTERFACE, "showRequest", this, SIGNAL (showRequest (qulonglong))); dbus.connect (KDED_SERVICE, KDED_APPMENU_PATH, KDED_INTERFACE, "menuAvailable", this, SLOT (menuAvailable (qulonglong))); dbus.connect (KDED_SERVICE, KDED_APPMENU_PATH, KDED_INTERFACE, "clearMenus", this, SLOT (clearMenus ())); dbus.connect (KDED_SERVICE, KDED_APPMENU_PATH, KDED_INTERFACE, "menuHidden", this, SIGNAL (menuHidden ())); }
int main (int argc, char *argv[]) { GstPipeline *pipeline; GstBus *bus; GstElement *srcbin; GstElement *tee; GstElement *queue[N_ACTORS], *sink[N_ACTORS]; GstElement *upload[N_ACTORS]; /* GstElement *effect[N_ACTORS]; */ ClutterActor *stage; GstGLClutterActor *actor[N_ACTORS]; Display *disp; Window stage_win; const gchar *desc; gint i; gint ok = FALSE; ClutterInitError clutter_err = CLUTTER_INIT_ERROR_UNKNOWN; clutter_err = clutter_init (&argc, &argv); if (clutter_err != CLUTTER_INIT_SUCCESS) g_warning ("Failed to initalize clutter: %d\n", clutter_err); gst_init (&argc, &argv); disp = clutter_x11_get_default_display (); if (!clutter_x11_has_composite_extension ()) { g_error ("XComposite extension missing"); } stage = clutter_stage_get_default (); clutter_actor_set_size (CLUTTER_ACTOR (stage), W * COLS + (COLS - 1), H * ROWS + (ROWS - 1)); stage_win = clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); XCompositeRedirectSubwindows (disp, stage_win, CompositeRedirectManual); for (i = 0; i < N_ACTORS; i++) { actor[i] = g_new0 (GstGLClutterActor, 1); actor[i]->stage = stage; actor[i]->win = XCreateSimpleWindow (disp, stage_win, 0, 0, W, H, 0, 0, 0); XMapRaised (disp, actor[i]->win); XSync (disp, FALSE); } /* desc = g_strdup_printf ("v4l2src ! " "video/x-raw, width=640, height=480, framerate=30/1 ! " "videoscale !" "video/x-raw, width=%d, height=%d ! " "identity", W, H); */ desc = g_strdup_printf ("videotestsrc ! " "video/x-raw, format=RGB, width=%d, height=%d !" "identity", W, H); pipeline = GST_PIPELINE (gst_pipeline_new (NULL)); srcbin = gst_parse_bin_from_description (desc, TRUE, NULL); if (!srcbin) g_error ("Source bin creation failed"); tee = gst_element_factory_make ("tee", NULL); gst_bin_add_many (GST_BIN (pipeline), srcbin, tee, NULL); for (i = 0; i < N_ACTORS; i++) { queue[i] = gst_element_factory_make ("queue", NULL); upload[i] = gst_element_factory_make ("glupload", NULL); /* effect[i] = gst_element_factory_make ("gleffects", NULL); */ sink[i] = gst_element_factory_make ("glimagesink", NULL); /* gst_bin_add_many (GST_BIN (pipeline), queue[i], upload[i], effect[i], sink[i], NULL); */ gst_bin_add_many (GST_BIN (pipeline), queue[i], upload[i], sink[i], NULL); } gst_element_link_many (srcbin, tee, NULL); for (i = 0; i < N_ACTORS; i++) { ok |= // gst_element_link_many (tee, queue[i], upload[i], effect[i], sink[i], gst_element_link_many (tee, queue[i], upload[i], sink[i], NULL); } if (!ok) g_error ("Failed to link one or more elements"); /* for (i = 0; i < N_ACTORS; i++) { g_message ("setting effect %d on %s", i + 1, gst_element_get_name (effect[i])); g_object_set (G_OBJECT (effect[i]), "effect", i + 1, NULL); } */ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, actor, NULL); gst_object_unref (bus); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); clutter_actor_show_all (stage); clutter_main (); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); gst_object_unref (pipeline); return 0; }
void X11EmbedContainer::embedSystemTrayClient(WId clientId) { Display *display = QX11Info::display(); if (!XGetWindowAttributes(display, clientId, &d->attr)) { emit error(QX11EmbedContainer::Unknown); return; } XSetWindowAttributes sAttr; sAttr.background_pixel = BlackPixel(display, DefaultScreen(display)); sAttr.border_pixel = BlackPixel(display, DefaultScreen(display)); sAttr.colormap = d->attr.colormap; WId parentId = parentWidget() ? parentWidget()->winId() : DefaultRootWindow(display); Window winId = XCreateWindow(display, parentId, 0, 0, d->attr.width, d->attr.height, 0, d->attr.depth, InputOutput, d->attr.visual, CWBackPixel | CWBorderPixel | CWColormap, &sAttr); XWindowAttributes attr; if (!XGetWindowAttributes(display, winId, &attr)) { emit error(QX11EmbedContainer::Unknown); return; } create(winId); XRenderPictFormat *format = XRenderFindVisualFormat(display, d->attr.visual); if (format && format->type == PictTypeDirect && format->direct.alphaMask && FdoSelectionManager::manager()->haveComposite()) { // Redirect ARGB windows to offscreen storage so we can composite them ourselves XRenderPictureAttributes attr; attr.subwindow_mode = IncludeInferiors; d->picture = XRenderCreatePicture(display, clientId, format, CPSubwindowMode, &attr); XCompositeRedirectSubwindows(display, winId, CompositeRedirectManual); FdoSelectionManager::manager()->addDamageWatch(this, clientId); //kDebug() << "Embedded client uses an ARGB visual -> compositing."; } else { //kDebug() << "Embedded client is not using an ARGB visual."; } // repeat everything from QX11EmbedContainer's ctor that might be relevant setFocusPolicy(Qt::StrongFocus); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setAcceptDrops(true); setEnabled(false); XSelectInput(display, winId, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | KeymapStateMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | ExposureMask | StructureNotifyMask | SubstructureNotifyMask); XFlush(display); embedClient(clientId); // FIXME: This checks that the client is still valid. Qt won't pick it up // if the client closes before embedding completes. However, what happens // if the close happens after this point? Should checks happen on a timer // until embedding completes perhaps? if (!XGetWindowAttributes(QX11Info::display(), clientId, &d->attr)) { emit error(QX11EmbedContainer::Unknown); return; } }
Bool addDisplay (char *name, char **plugin, int nPlugin) { CompDisplay *d; Display *dpy; int i; d = &compDisplay; if (displayPrivateLen) { d->privates = malloc (displayPrivateLen * sizeof (CompPrivate)); if (!d->privates) return FALSE; } else d->privates = 0; d->screenPrivateIndices = 0; d->screenPrivateLen = 0; for (i = 0; i < CompModNum; i++) d->modMask[i] = CompNoMask; d->plugin.list.type = CompOptionTypeString; d->plugin.list.nValue = 0; d->plugin.list.value = 0; compDisplayInitOptions (d, plugin, nPlugin); d->textureFilter = GL_LINEAR; d->display = dpy = XOpenDisplay (name); if (!d->display) { fprintf (stderr, "%s: Couldn't open display %s\n", programName, XDisplayName (name)); return FALSE; } #ifdef DEBUG XSynchronize (dpy, TRUE); #endif XSetErrorHandler (errorHandler); updateModifierMappings (d); d->setDisplayOption = setDisplayOption; d->setDisplayOptionForPlugin = setDisplayOptionForPlugin; d->initPluginForDisplay = initPluginForDisplay; d->finiPluginForDisplay = finiPluginForDisplay; d->handleEvent = handleEvent; d->winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", 0); d->winDesktopAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", 0); d->winDockAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DOCK", 0); d->winToolbarAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", 0); d->winMenuAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_MENU", 0); d->winUtilAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_UTILITY", 0); d->winSplashAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_SPLASH", 0); d->winDialogAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DIALOG", 0); d->winNormalAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_NORMAL", 0); d->winOpacityAtom = XInternAtom (dpy, "_NET_WM_WINDOW_OPACITY", 0); d->winActiveAtom = XInternAtom (dpy, "_NET_ACTIVE_WINDOW", 0); d->wmStateAtom = XInternAtom (dpy, "WM_STATE", 0); d->wmDeleteWindowAtom = XInternAtom (dpy, "WM_DELETE_WINDOW", 0); d->xBackgroundAtom[0] = XInternAtom (dpy, "_XSETROOT_ID", 0); d->xBackgroundAtom[1] = XInternAtom (dpy, "_XROOTPMAP_ID", 0); if (testMode) { d->compositeOpcode = MAXSHORT; d->compositeEvent = MAXSHORT; d->compositeError = MAXSHORT; d->damageEvent = MAXSHORT; d->damageError = MAXSHORT; } else { int compositeMajor, compositeMinor; if (!XQueryExtension (dpy, COMPOSITE_NAME, &d->compositeOpcode, &d->compositeEvent, &d->compositeError)) { fprintf (stderr, "%s: No composite extension\n", programName); return FALSE; } XCompositeQueryVersion (dpy, &compositeMajor, &compositeMinor); if (compositeMajor == 0 && compositeMinor < 2) { fprintf (stderr, "%s: Old composite extension\n", programName); return FALSE; } if (!XDamageQueryExtension (dpy, &d->damageEvent, &d->damageError)) { fprintf (stderr, "%s: No damage extension\n", programName); return FALSE; } } d->shapeExtension = XShapeQueryExtension (dpy, &d->shapeEvent, &d->shapeError); compDisplays = d; if (testMode) { addScreen (d, 0); } else { XGrabServer (dpy); for (i = 0; i < ScreenCount (dpy); i++) { redirectFailed = 0; XCompositeRedirectSubwindows (dpy, XRootWindow (dpy, i), CompositeRedirectManual); XSync (dpy, FALSE); if (redirectFailed) { fprintf (stderr, "%s: Another composite manager is already " "running on screen: %d\n", programName, i); } else { if (!addScreen (d, i)) { fprintf (stderr, "%s: Failed to manage screen: %d\n", programName, i); } } } XUngrabServer (dpy); } if (!d->screens) { fprintf (stderr, "%s: No managable screens found on display %s\n", programName, XDisplayName (name)); return FALSE; } return TRUE; }
void meta_compositor_manage_screen (MetaCompositor *compositor, MetaScreen *screen) { MetaCompScreen *info; MetaDisplay *display = meta_screen_get_display (screen); Display *xdisplay = meta_display_get_xdisplay (display); int screen_number = meta_screen_get_screen_number (screen); Window xroot = meta_screen_get_xroot (screen); Window xwin; gint width, height; XWindowAttributes attr; long event_mask; guint n_retries; guint max_retries; /* Check if the screen is already managed */ if (meta_screen_get_compositor_data (screen)) return; if (meta_get_replace_current_wm ()) max_retries = 5; else max_retries = 1; n_retries = 0; /* Some compositors (like old versions of Muffin) might not properly unredirect * subwindows before destroying the WM selection window; so we wait a while * for such a compositor to exit before giving up. */ while (TRUE) { meta_error_trap_push_with_return (display); XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual); XSync (xdisplay, FALSE); if (!meta_error_trap_pop_with_return (display)) break; if (n_retries == max_retries) { /* This probably means that a non-WM compositor like xcompmgr is running; * we have no way to get it to exit */ meta_fatal (_("Another compositing manager is already running on screen %i on display \"%s\"."), screen_number, display->name); } n_retries++; g_usleep (G_USEC_PER_SEC); } info = g_new0 (MetaCompScreen, 1); /* * We use an empty input region for Clutter as a default because that allows * the user to interact with all the windows displayed on the screen. * We have to initialize info->pending_input_region to an empty region explicitly, * because None value is used to mean that the whole screen is an input region. */ info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0); info->screen = screen; meta_screen_set_compositor_data (screen, info); info->output = None; info->windows = NULL; meta_screen_set_cm_selection (screen); info->stage = clutter_stage_new (); meta_screen_get_size (screen, &width, &height); clutter_actor_realize (info->stage); xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage)); XResizeWindow (xdisplay, xwin, width, height); event_mask = FocusChangeMask | ExposureMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | PropertyChangeMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask; if (XGetWindowAttributes (xdisplay, xwin, &attr)) { event_mask |= attr.your_event_mask; } XSelectInput (xdisplay, xwin, event_mask); info->window_group = meta_window_group_new (screen); info->background_actor = meta_background_actor_new_for_screen (screen); info->bottom_window_group = clutter_group_new(); info->overlay_group = clutter_group_new (); info->top_window_group = meta_window_group_new (screen); info->hidden_group = clutter_group_new (); clutter_container_add (CLUTTER_CONTAINER (info->window_group), info->background_actor, NULL); clutter_container_add (CLUTTER_CONTAINER (info->stage), info->window_group, info->overlay_group, info->hidden_group, NULL); clutter_actor_hide (info->hidden_group); info->plugin_mgr = meta_plugin_manager_get (screen); meta_plugin_manager_initialize (info->plugin_mgr); /* * Delay the creation of the overlay window as long as we can, to avoid * blanking out the screen. This means that during the plugin loading, the * overlay window is not accessible; if the plugin needs to access it * directly, it should hook into the "show" signal on stage, and do * its stuff there. */ info->output = get_output_window (screen); XReparentWindow (xdisplay, xwin, info->output, 0, 0); /* Make sure there isn't any left-over output shape on the * overlay window by setting the whole screen to be an * output region. * * Note: there doesn't seem to be any real chance of that * because the X server will destroy the overlay window * when the last client using it exits. */ XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None); do_set_stage_input_region (screen, info->pending_input_region); if (info->pending_input_region != None) { XFixesDestroyRegion (xdisplay, info->pending_input_region); info->pending_input_region = None; } clutter_actor_show (info->overlay_group); clutter_actor_show (info->stage); }