diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-02-25 11:15:47 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-02-25 11:15:47 -0500 |
commit | 2c37aa64b50d8c76fa96f92875a20de1d500f6fc (patch) | |
tree | 5e6bc66d7ec6a8970e463445bc362e4a709cc51a | |
parent | 9607f48e1951418cc811d94ea24e360a872c9641 (diff) |
Initial setup
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | main.c | 163 | ||||
-rw-r--r-- | ocm.h | 31 | ||||
-rw-r--r-- | utils.c | 4 |
4 files changed, 195 insertions, 10 deletions
@@ -1,7 +1,10 @@ +EXTRA_CFLAGS = -g -Wall -fno-omit-frame-pointer `pkg-config --cflags x11 xrender xcomposite xdamage` +EXTRA_LDFLAGS = `pkg-config --libs x11 xrender xcomposite xdamage` + sources := main.c utils.c ocm.h %.o: %.c - $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ + $(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ ocm: utils.o main.o - $(CC) $(filter %.c %.s,$(sources)) -o $@ + $(CC) $(filter %.c %.s,$(sources)) -o $@ $(EXTRA_LDFLAGS) @@ -1,3 +1,7 @@ +/* There is code in here from metacity and from fvwm. + FIXME: add copyright statements +*/ + /* Some principles: * * - We can only deal with one screen (but know about monitors) @@ -13,26 +17,171 @@ * - There is very little configuation */ #include <stdlib.h> -#include <X11/Xlib.h> +#include <stdio.h> -typedef struct ocm_screen_t ocm_screen_t; -typedef struct ocm_app_t ocm_app_t; +#include "ocm.h" -struct ocm_app_t +static uint32_t +get_time (ocm_app_t *app) { - Display *dpy; -}; + if (app->timestamp == CurrentTime) + { + XEvent event; + + /* Using the property XA_PRIMARY because it's safe; nothing + * would use it as a property. The type doesn't matter. + */ + XChangeProperty (app->display, app->no_focus, XA_PRIMARY, XA_STRING, 8, + PropModeAppend, NULL, 0); + + XWindowEvent (app->display, app->no_focus, PropertyChangeMask, &event); + + app->timestamp = event.xproperty.time; + } + + return app->timestamp; +} static ocm_app_t * ocm_app_new (int argc, char **argv) { ocm_app_t *app = malloc (sizeof (*app)); + int render_event, render_error; + int composite_major, composite_minor; + int damage_event, damage_error; + XSetWindowAttributes attr; + Window existing; + Atom wm_s0; + XClientMessageEvent event; + bool replace; + uint32_t managed_since; + int i; + unsigned int n_children; + Window *children, r, p; + + replace = FALSE; + + for (i = 0; i < argc; ++i) + { + char *arg = argv[i]; + + if (strcmp (arg, "-r") == 0) + replace = TRUE; + } + + app->display = XOpenDisplay (NULL); + + if (!app->display) + ocm_error ("Could not open X display"); + + app->root = DefaultRootWindow (app->display); + app->timestamp = CurrentTime; + + if (!XRenderQueryExtension ( + app->display, &render_event, &render_error)) + { + ocm_error ("No Render extension"); + } + + if (!XCompositeQueryVersion ( + app->display, &composite_major, &composite_minor)) + { + ocm_error ("No Composite extension"); + } + + if (composite_major == 0 && composite_minor < 2) + ocm_error ("No NamePixmap\n"); + + if (!XDamageQueryExtension ( + app->display, &damage_event, &damage_error)) + { + ocm_error ("No Damage extensions\n"); + } + + attr.event_mask = + StructureNotifyMask | PropertyChangeMask | KeyPressMask | KeyReleaseMask; + attr.override_redirect = TRUE; + attr.background_pixmap = None; + attr.border_pixel = 0x00000000; + + app->no_focus = XCreateWindow (app->display, app->root, -10, -10, 10, 10, 0, CopyFromParent, + InputOutput, CopyFromParent, + CWEventMask | CWOverrideRedirect | CWBackPixmap | CWBorderPixel, + &attr); + wm_s0 = XInternAtom (app->display, "WM_S0", FALSE); + existing = XGetSelectionOwner (app->display, wm_s0); + if (existing) + { + if (!replace) + ocm_error ("Another window manager is already running - try -r"); + + attr.event_mask = StructureNotifyMask; + XChangeWindowAttributes (app->display, existing, CWEventMask, &attr); + } + + managed_since = get_time (app); + + XSetSelectionOwner (app->display, wm_s0, app->no_focus, managed_since); + + /* Announce ourself as the new wm */ + event.type = ClientMessage; + event.window = app->root; + event.message_type = XInternAtom (app->display, "MANAGER", FALSE); + event.format = 32; + event.data.l[0] = managed_since; + event.data.l[1] = wm_s0; + + XSendEvent (app->display, app->root, FALSE, + StructureNotifyMask, (XEvent*)&event); + + if (existing) + { + XEvent event; + + do + { + XWindowEvent (app->display, existing, StructureNotifyMask, &event); + } + while (event.type != DestroyNotify); + } + + /* Now manage all the windows */ + if (!XQueryTree (app->display, app->root, &r, &p, &children, &n_children)) + ocm_error ("XQueryTree() failed"); + + for (i = 0; i < n_children; ++i) + { + printf ("%lx\n", children[i]); + } + if (children) + XFree (children); + + return app; } +static void +ocm_app_run (ocm_app_t *app) +{ + while (1) + { + XEvent event; + + XNextEvent (app->display, &event); + + + + + + } +} int main (int argc, char **argv) { - + ocm_app_t *app = ocm_app_new (argc, argv); + + ocm_app_run (app); + + return 0; } @@ -1,7 +1,36 @@ +#include <stdint.h> #include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/extensions/Xrender.h> +#include <X11/extensions/Xcomposite.h> +#include <X11/extensions/Xdamage.h> -/* utils.c */ +/* Macros */ +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +/* Typedefs */ +typedef int bool; +typedef struct ocm_app_t ocm_app_t; +/* Data structures */ +struct ocm_app_t +{ + Display * display; + Window root; + Window no_focus; + uint32_t timestamp; +}; + +/* utils.c */ void ocm_error (const char *fmt, ...); @@ -9,7 +9,9 @@ ocm_error (const char *fmt, ...) va_list ap; va_start (ap, fmt); + fprintf (stderr, "** Fatal **: "); vfprintf (stderr, fmt, ap); + fprintf (stderr, "\n"); va_end (ap); exit (-1); @@ -22,4 +24,6 @@ ocm_malloc (size_t n) if (!mem) ocm_error ("Out of memory allocating %d bytes\n", mem); + + return 0; } |