summaryrefslogtreecommitdiff
path: root/app/fvwm/modules/FvwmIconMan/x.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 10:53:58 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 10:53:58 +0000
commit1cb4778bcef21ea9015cfccdb99abb7a0e035d74 (patch)
treef164009397f9d3d5634c6f8a94b1542f793d9692 /app/fvwm/modules/FvwmIconMan/x.c
parent841f8331c93ff96bd798e9a74ba10fab155da5c5 (diff)
Importing from XF4, plus BSD make infrastructure
Diffstat (limited to 'app/fvwm/modules/FvwmIconMan/x.c')
-rw-r--r--app/fvwm/modules/FvwmIconMan/x.c813
1 files changed, 813 insertions, 0 deletions
diff --git a/app/fvwm/modules/FvwmIconMan/x.c b/app/fvwm/modules/FvwmIconMan/x.c
new file mode 100644
index 000000000..a62d5e87f
--- /dev/null
+++ b/app/fvwm/modules/FvwmIconMan/x.c
@@ -0,0 +1,813 @@
+#include "config.h"
+#include "FvwmIconMan.h"
+#include "readconfig.h"
+#include "x.h"
+#include "xmanager.h"
+
+static char const rcsid[] =
+ "$Id: x.c,v 1.1.1.1 2006/11/26 10:53:50 matthieu Exp $";
+
+#define GRAB_EVENTS (ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|EnterWindowMask|LeaveWindowMask)
+
+#ifdef SHAPE
+static int shapeEventBase, shapeErrorBase;
+#endif
+
+Display *theDisplay;
+Window theRoot;
+int theDepth, theScreen;
+
+static enum {
+ NOT_GRABBED = 0,
+ NEED_TO_GRAB = 1,
+ HAVE_GRABBED = 2
+} grab_state = NOT_GRABBED;
+
+static void reparentnotify_event (WinManager *man, XEvent *ev);
+
+static void grab_pointer (WinManager *man)
+{
+ /* This should only be called after we get our EXPOSE event */
+ if (grab_state == NEED_TO_GRAB) {
+ if (XGrabPointer (theDisplay, man->theWindow, True, GRAB_EVENTS,
+ GrabModeAsync, GrabModeAsync, None,
+ None, CurrentTime) != GrabSuccess) {
+ ConsoleMessage ("Couldn't grab pointer\n");
+ ShutMeDown (0);
+ }
+ grab_state = HAVE_GRABBED;
+ }
+}
+
+static int lookup_color (char *name, Pixel *ans)
+{
+ XColor color;
+ XWindowAttributes attributes;
+
+ XGetWindowAttributes(theDisplay, theRoot, &attributes);
+ color.pixel = 0;
+ if (!XParseColor (theDisplay, attributes.colormap, name, &color)) {
+ ConsoleDebug(X11, "Could not parse color '%s'\n", name);
+ return 0;
+ }
+ else if(!XAllocColor (theDisplay, attributes.colormap, &color)) {
+ ConsoleDebug(X11, "Could not allocate color '%s'\n", name);
+ return 0;
+ }
+ *ans = color.pixel;
+ return 1;
+}
+
+
+WinManager *find_windows_manager (Window win)
+{
+ int i;
+
+ for (i = 0; i < globals.num_managers; i++) {
+ if (globals.managers[i].theWindow == win)
+ return &globals.managers[i];
+ }
+
+/* ConsoleMessage ("error in find_windows_manager:\n");
+ ConsoleMessage ("Window: %x\n", win);
+ for (i = 0; i < globals.num_managers; i++) {
+ ConsoleMessage ("manager: %d %x\n", i, globals.managers[i].theWindow);
+ }
+*/
+ return NULL;
+}
+
+static void handle_buttonevent (XEvent *theEvent, WinManager *man)
+{
+ Button *b;
+ WinData *win;
+ unsigned int modifier;
+ Binding *MouseEntry;
+
+ b = xy_to_button (man, theEvent->xbutton.x, theEvent->xbutton.y);
+ if (b && theEvent->xbutton.button >= 1 && theEvent->xbutton.button <= 3) {
+ win = b->drawn_state.win;
+ if (win != NULL) {
+ ConsoleDebug (X11, "Found the window:\n");
+ ConsoleDebug (X11, "\tid: %ld\n", win->app_id);
+ ConsoleDebug (X11, "\tdesknum: %ld\n", win->desknum);
+ ConsoleDebug (X11, "\tx, y: %ld %ld\n", win->x, win->y);
+ ConsoleDebug (X11, "\ticon: %p\n", win->iconname);
+ ConsoleDebug (X11, "\ticonified: %d\n", win->iconified);
+ ConsoleDebug (X11, "\tcomplete: %d\n", win->complete);
+
+ modifier = (theEvent->xbutton.state & MODS_USED);
+ /* need to search for an appropriate mouse binding */
+ for (MouseEntry = man->bindings[MOUSE]; MouseEntry != NULL;
+ MouseEntry= MouseEntry->NextBinding) {
+ if(((MouseEntry->Button_Key == theEvent->xbutton.button)||
+ (MouseEntry->Button_Key == 0))&&
+ ((MouseEntry->Modifier == AnyModifier)||
+ (MouseEntry->Modifier == (modifier& (~LockMask)))))
+ {
+ Function *ftype = MouseEntry->Function;
+ ConsoleDebug (X11, "\tgot a mouse binding\n");
+ if (ftype && ftype->func) {
+ run_function_list (ftype);
+ draw_managers();
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+Window find_frame_window (Window win, int *off_x, int *off_y)
+{
+ Window root, parent, *junkw;
+ int junki;
+ XWindowAttributes attr;
+
+ ConsoleDebug (X11, "In find_frame_window: 0x%x\n", (unsigned int)win);
+
+ while (1) {
+ XQueryTree (theDisplay, win, &root, &parent, &junkw, &junki);
+ if (junkw)
+ XFree (junkw);
+ if (parent == root)
+ break;
+ XGetWindowAttributes (theDisplay, win, &attr);
+ ConsoleDebug (X11, "Adding (%d, %d) += (%d, %d)\n",
+ *off_x, *off_y, attr.x + attr.border_width,
+ attr.y + attr.border_width);
+ *off_x += attr.x + attr.border_width;
+ *off_y += attr.y + attr.border_width;
+ win = parent;
+ }
+
+ return win;
+}
+
+/***************************************************************************/
+/* Event handler routines */
+/* everything which has its own routine can be processed recursively */
+/***************************************************************************/
+
+static void reparentnotify_event (WinManager *man, XEvent *ev)
+{
+ ConsoleDebug (X11, "XEVENT: ReparentNotify\n");
+#if 0
+ ConsoleMessage ("seen %d expected %d\n", num_reparents_seen,
+ num_reparents_expected);
+ man->off_x = ev->xreparent.x;
+ man->off_y = ev->xreparent.y;
+ ConsoleDebug (X11, "reparent: off = (%d, %d)\n",man->off_x, man->off_y);
+ man->theFrame = find_frame_window (ev->xany.window,
+ &man->off_x, &man->off_y);
+ ConsoleMessage ("\twin = 0x%x, frame = 0x%x\n", man->theWindow,
+ man->theFrame);
+#endif
+ if (man->can_draw == 0) {
+ man->can_draw = 1;
+ force_manager_redraw (man);
+ }
+}
+
+void xevent_loop (void)
+{
+ XEvent theEvent;
+ unsigned int modifier;
+ Binding *key;
+ Button *b;
+ static int flag = 0;
+ WinManager *man;
+
+ if (flag == 0) {
+ flag = 1;
+ ConsoleDebug (X11, "A virgin event loop\n");
+ }
+ while (XPending (theDisplay)) {
+ XNextEvent (theDisplay, &theEvent);
+ if (theEvent.type == MappingNotify) {
+ ConsoleDebug (X11, "XEVENT: MappingNotify\n");
+ continue;
+ }
+
+ man = find_windows_manager (theEvent.xany.window);
+ if (!man) {
+ ConsoleDebug (X11, "Event doesn't belong to a manager\n");
+ continue;
+ }
+
+ switch (theEvent.type) {
+ case ReparentNotify:
+ reparentnotify_event (man, &theEvent);
+ break;
+
+ case KeyPress:
+ ConsoleDebug (X11, "XEVENT: KeyPress\n");
+ /* Here's a real hack - some systems have two keys with the
+ * same keysym and different keycodes. This converts all
+ * the cases to one keycode. */
+ theEvent.xkey.keycode =
+ XKeysymToKeycode (theDisplay,
+ XKeycodeToKeysym(theDisplay,
+ theEvent.xkey.keycode,0));
+ modifier = (theEvent.xkey.state & MODS_USED);
+ ConsoleDebug (X11, "\tKeyPress: %d\n", theEvent.xkey.keycode);
+
+ for (key = man->bindings[KEYPRESS]; key != NULL; key = key->NextBinding)
+ {
+ if ((key->Button_Key == theEvent.xkey.keycode) &&
+ ((key->Modifier == (modifier&(~LockMask)))||
+ (key->Modifier == AnyModifier)))
+ {
+ Function *ftype = key->Function;
+ if (ftype && ftype->func) {
+ run_function_list (ftype);
+ draw_managers();
+ }
+ break;
+ }
+ }
+ break;
+
+ case Expose:
+ ConsoleDebug (X11, "XEVENT: Expose\n");
+ if (theEvent.xexpose.count == 0) {
+ man_exposed (man, &theEvent);
+ draw_manager (man);
+ if (globals.transient) {
+ grab_pointer (man);
+ }
+ }
+ break;
+
+ case ButtonPress:
+ ConsoleDebug (X11, "XEVENT: ButtonPress\n");
+ if (!globals.transient)
+ handle_buttonevent (&theEvent, man);
+ break;
+
+ case ButtonRelease:
+ ConsoleDebug (X11, "XEVENT: ButtonRelease\n");
+ if (globals.transient) {
+ handle_buttonevent (&theEvent, man);
+ ShutMeDown (0);
+ }
+ break;
+
+ case EnterNotify:
+ ConsoleDebug (X11, "XEVENT: EnterNotify\n");
+ man->cursor_in_window = 1;
+ b = xy_to_button (man, theEvent.xcrossing.x, theEvent.xcrossing.y);
+ move_highlight (man, b);
+ run_binding (man, SELECT);
+ draw_managers();
+ break;
+
+ case LeaveNotify:
+ ConsoleDebug (X11, "XEVENT: LeaveNotify\n");
+ move_highlight (man, NULL);
+ break;
+
+ case ConfigureNotify:
+ ConsoleDebug (X11, "XEVENT: Configure Notify: %d %d %d %d\n",
+ theEvent.xconfigure.x, theEvent.xconfigure.y,
+ theEvent.xconfigure.width, theEvent.xconfigure.height);
+ ConsoleDebug (X11, "\tcurrent geometry: %d %d %d %d\n",
+ man->geometry.x, man->geometry.y,
+ man->geometry.width, man->geometry.height);
+ ConsoleDebug (X11, "\tborderwidth = %d\n",
+ theEvent.xconfigure.border_width);
+ ConsoleDebug (X11, "\tsendevent = %d\n", theEvent.xconfigure.send_event);
+#if 0
+ set_manager_width (man, theEvent.xconfigure.width);
+ ConsoleDebug (X11, "\tboxwidth = %d\n", man->geometry.boxwidth);
+ draw_manager (man);
+
+ /* pointer may not be in the same box as before */
+ if (XQueryPointer (theDisplay, man->theWindow, &root, &child, &glob_x,
+ &glob_y,
+ &x, &y, &mask)) {
+ b = xy_to_button (man, x, y);
+ if (b != man->select_button) {
+ move_highlight (man, b);
+ run_binding (man, SELECT);
+ draw_managers();
+ }
+ }
+ else {
+ if (man->select_button != NULL)
+ move_highlight (NULL, NULL);
+ }
+#endif
+ break;
+
+ case MotionNotify:
+ /* ConsoleDebug (X11, "XEVENT: MotionNotify\n"); */
+ b = xy_to_button (man, theEvent.xmotion.x, theEvent.xmotion.y);
+ if (b != man->select_button) {
+ ConsoleDebug (X11, "\tmoving select\n");
+ move_highlight (man, b);
+ run_binding (man, SELECT);
+ draw_managers();
+ }
+ break;
+
+ case MapNotify:
+ ConsoleDebug (X11, "XEVENT: MapNotify\n");
+ force_manager_redraw (man);
+ break;
+
+ case UnmapNotify:
+ ConsoleDebug (X11, "XEVENT: UnmapNotify\n");
+ break;
+
+ case DestroyNotify:
+ ConsoleDebug(X11, "XEVENT: DestroyNotify\n");
+ DeadPipe(0);
+ break;
+
+ default:
+#ifdef SHAPE
+ if (theEvent.type == shapeEventBase + ShapeNotify) {
+ XShapeEvent *xev = (XShapeEvent *)&theEvent;
+ ConsoleDebug (X11, "XEVENT: ShapeNotify\n");
+ ConsoleDebug (X11, "\tx, y, w, h = %d, %d, %d, %d\n",
+ xev->x, xev->y, xev->width, xev->height);
+ break;
+ }
+#endif
+ ConsoleDebug (X11, "XEVENT: unknown\n");
+ break;
+ }
+ }
+ check_managers_consistency();
+ XFlush (theDisplay);
+}
+
+static void set_window_properties (Window win, char *name, char *icon,
+ XSizeHints *sizehints)
+{
+ XTextProperty win_name;
+ XTextProperty win_icon;
+ XClassHint class;
+ XWMHints wmhints = {0};
+
+ wmhints.initial_state = NormalState;
+ wmhints.flags = StateHint;
+
+ if (XStringListToTextProperty (&name, 1, &win_name) == 0) {
+ ConsoleMessage ("%s: cannot allocate window name.\n",Module);
+ return;
+ }
+ if (XStringListToTextProperty (&icon, 1, &win_icon) == 0) {
+ ConsoleMessage ("%s: cannot allocate window icon.\n",Module);
+ return;
+ }
+
+ class.res_name = Module + 1;
+ class.res_class = "FvwmModule";
+
+
+ XSetWMProperties (theDisplay, win, &win_name, &win_icon, NULL, 0,
+ sizehints, &wmhints, &class);
+
+ XFree (win_name.value);
+ XFree (win_icon.value);
+}
+
+static int load_default_context_fore (WinManager *man, int i)
+{
+ int j = 0;
+
+ if (theDepth > 2)
+ j = 1;
+
+ ConsoleDebug (X11, "Loading: %s\n", contextDefaults[i].backcolor[j]);
+
+ return lookup_color (contextDefaults[i].forecolor[j], &man->forecolor[i]);
+}
+
+static int load_default_context_back (WinManager *man, int i)
+{
+ int j = 0;
+
+ if (theDepth > 2)
+ j = 1;
+
+ ConsoleDebug (X11, "Loading: %s\n", contextDefaults[i].backcolor[j]);
+
+ return lookup_color (contextDefaults[i].backcolor[j], &man->backcolor[i]);
+}
+
+void map_manager (WinManager *man)
+{
+ if (man->window_mapped == 0 && man->geometry.height > 0) {
+ XMapWindow (theDisplay, man->theWindow);
+ set_manager_window_mapping (man, 1);
+ XFlush (theDisplay);
+ if (globals.transient) {
+ /* wait for an expose event to actually do the grab */
+ grab_state = NEED_TO_GRAB;
+ }
+ }
+}
+
+void unmap_manager (WinManager *man)
+{
+ if (man->window_mapped == 1) {
+ XUnmapWindow (theDisplay, man->theWindow);
+ set_manager_window_mapping (man, 0);
+ XFlush (theDisplay);
+ }
+}
+
+#if 0
+void read_all_reparent_events (WinManager *man, int block)
+{
+ XEvent evs[2];
+ int i = 0, got_one = 0, the_event;
+
+ /* We're going to be junking ConfigureNotify events, but that's ok,
+ since this is only going to be called from resize_manager() */
+ /* This shouldn't slow things down terribly, since we'd just have to read
+ these events anyway */
+
+ assert (man->can_draw);
+
+ if (block) {
+ while (1) {
+ XWindowEvent (theDisplay, man->theWindow, StructureNotifyMask, &evs[0]);
+ if (evs[0].type == ReparentNotify) {
+ the_event = 0;
+ got_one = 1;
+ break;
+ }
+ }
+ }
+ else {
+ while (XCheckWindowEvent (theDisplay, man->theWindow, StructureNotifyMask,
+ &evs[i])) {
+ if (evs[i].type == ReparentNotify) {
+ got_one = 1;
+ the_event = i;
+ i ^= 1;
+ }
+ }
+ }
+ if (got_one) {
+ reparentnotify_event (man, &evs[the_event]);
+ }
+}
+#endif
+
+void X_init_manager (int man_id)
+{
+ WinManager *man;
+ int width, height;
+ int i, x, y, geometry_mask;
+ ConsoleDebug (X11, "In X_init_manager\n");
+
+ man = &globals.managers[man_id];
+
+ man->geometry.cols = DEFAULT_NUM_COLS;
+ man->geometry.rows = DEFAULT_NUM_ROWS;
+ man->geometry.x = 0;
+ man->geometry.y = 0;
+ man->gravity = NorthWestGravity;
+
+ man->select_button = NULL;
+ man->cursor_in_window = 0;
+ man->sizehints_flags = 0;
+
+ ConsoleDebug (X11, "boxwidth = %d\n", man->geometry.boxwidth);
+
+ if (man->fontname) {
+ man->ButtonFont = XLoadQueryFont (theDisplay, man->fontname);
+ if (!man->ButtonFont) {
+ if (!(man->ButtonFont = XLoadQueryFont (theDisplay, FONT_STRING))) {
+ ConsoleMessage ("Can't get font\n");
+ ShutMeDown (1);
+ }
+ }
+ }
+ else {
+ if (!(man->ButtonFont = XLoadQueryFont (theDisplay, FONT_STRING))) {
+ ConsoleMessage ("Can't get font\n");
+ ShutMeDown (1);
+ }
+ }
+
+ for ( i = 0; i < NUM_CONTEXTS; i++ ) {
+ if (man->backColorName[i]) {
+ if (!lookup_color (man->backColorName[i], &man->backcolor[i])) {
+ if (!load_default_context_back (man, i)) {
+ ConsoleMessage ("Can't load %s background color\n",
+ contextDefaults[i].name);
+ }
+ }
+ }
+ else if (!load_default_context_back (man, i)) {
+ ConsoleMessage ("Can't load %s background color\n",
+ contextDefaults[i].name);
+ }
+
+ if (man->foreColorName[i]) {
+ if (!lookup_color (man->foreColorName[i], &man->forecolor[i])) {
+ if (!load_default_context_fore (man, i)) {
+ ConsoleMessage ("Can't load %s foreground color\n",
+ contextDefaults[i].name);
+ }
+ }
+ }
+ else if (!load_default_context_fore (man, i)) {
+ ConsoleMessage ("Can't load %s foreground color\n",
+ contextDefaults[i].name);
+ }
+
+ if (theDepth > 2) {
+ man->shadowcolor[i] = GetShadow(man->backcolor[i]);
+ man->hicolor[i] = GetHilite(man->backcolor[i]);
+#if 0
+ /* thing about message id bg vs fg */
+ if (!lookup_shadow_color (man->backcolor[i], &man->shadowcolor[i])) {
+ ConsoleMessage ("Can't load %s shadow color\n",
+ contextDefaults[i].name);
+ }
+ if (!lookup_hilite_color (man->backcolor[i], &man->hicolor[i])) {
+ ConsoleMessage ("Can't load %s hilite color\n",
+ contextDefaults[i].name);
+ }
+#endif
+ }
+ }
+
+ man->fontheight = man->ButtonFont->ascent +
+ man->ButtonFont->descent;
+
+ /* silly hack to guess the minimum char width of the font
+ doesn't have to be perfect. */
+
+ man->fontwidth = XTextWidth (man->ButtonFont, ".", 1);
+
+ /* First: get button geometry
+ Second: get geometry from geometry string
+ Third: determine the final width and height
+ Fourth: determine final x, y coords */
+
+ man->geometry.boxwidth = DEFAULT_BUTTON_WIDTH;
+ man->geometry.boxheight = man->fontheight + 4;;
+ man->geometry.dir = 0;
+
+ geometry_mask = 0;
+
+ if (man->button_geometry_str) {
+ int val;
+ val = XParseGeometry (man->button_geometry_str, &x, &y, &width, &height);
+ ConsoleDebug (X11, "button x, y, w, h = %d %d %d %d\n", x, y, width,
+ height);
+ if (val & WidthValue)
+ man->geometry.boxwidth = width;
+ if (val & HeightValue)
+ man->geometry.boxheight = max (man->geometry.boxheight, height);
+ }
+ if (man->geometry_str) {
+ geometry_mask = XParseGeometry (man->geometry_str, &man->geometry.x,
+ &man->geometry.y, &man->geometry.cols,
+ &man->geometry.rows);
+
+ if ((geometry_mask & XValue) || (geometry_mask & YValue)) {
+ man->sizehints_flags |= USPosition;
+ if (geometry_mask & XNegative)
+ man->geometry.dir |= GROW_LEFT;
+ else
+ man->geometry.dir |= GROW_RIGHT;
+ if (geometry_mask & YNegative)
+ man->geometry.dir |= GROW_UP;
+ else
+ man->geometry.dir |= GROW_DOWN;
+ }
+ }
+
+ if (man->geometry.rows == 0) {
+ if (man->geometry.cols == 0) {
+ ConsoleMessage ("You specified a 0x0 window\n");
+ ShutMeDown (0);
+ }
+ else {
+ man->geometry.dir |= GROW_VERT;
+ }
+ man->geometry.rows = 1;
+ }
+ else {
+ if (man->geometry.cols == 0) {
+ man->geometry.dir |= GROW_HORIZ;
+ man->geometry.cols = 1;
+ }
+ else {
+ man->geometry.dir |= GROW_HORIZ | GROW_FIXED;
+ }
+ }
+
+ man->geometry.width = man->geometry.cols * man->geometry.boxwidth;
+ man->geometry.height = man->geometry.rows * man->geometry.boxheight;
+
+ if ((geometry_mask & XValue) && (geometry_mask & XNegative))
+ man->geometry.x += globals.screenx - man->geometry.width;
+ if ((geometry_mask & YValue) && (geometry_mask & YNegative))
+ man->geometry.y += globals.screeny - man->geometry.height;
+
+ if (globals.transient) {
+ Window dummyroot, dummychild;
+ int junk;
+
+ XQueryPointer(theDisplay, theRoot, &dummyroot, &dummychild,
+ &man->geometry.x,
+ &man->geometry.y, &junk, &junk, &junk);
+ man->geometry.dir |= GROW_DOWN | GROW_RIGHT;
+ man->sizehints_flags |= USPosition;
+ }
+
+ if (man->sizehints_flags & USPosition) {
+ if (man->geometry.dir & GROW_DOWN) {
+ if (man->geometry.dir & GROW_RIGHT)
+ man->gravity = NorthWestGravity;
+ else if (man->geometry.dir & GROW_LEFT)
+ man->gravity = NorthEastGravity;
+ else
+ ConsoleMessage ("Internal error in X_init_manager\n");
+ }
+ else if (man->geometry.dir & GROW_UP) {
+ if (man->geometry.dir & GROW_RIGHT)
+ man->gravity = SouthWestGravity;
+ else if (man->geometry.dir & GROW_LEFT)
+ man->gravity = SouthEastGravity;
+ else
+ ConsoleMessage ("Internal error in X_init_manager\n");
+ }
+ else {
+ ConsoleMessage ("Internal error in X_init_manager\n");
+ }
+ }
+ else {
+ man->geometry.dir |= GROW_DOWN | GROW_RIGHT;
+ man->gravity = NorthWestGravity;
+ }
+}
+
+void create_manager_window (int man_id)
+{
+ XSizeHints sizehints;
+ XGCValues gcval;
+ unsigned long gcmask = 0;
+ unsigned long winattrmask = CWBackPixel| CWBorderPixel | CWEventMask |
+ CWBackingStore | CWBitGravity;
+ XSetWindowAttributes winattr;
+ unsigned int line_width = 1;
+ int line_style = LineSolid;
+ int cap_style = CapRound;
+ int join_style = JoinRound;
+ int i;
+ WinManager *man;
+ ConsoleDebug (X11, "In create_manager_window\n");
+
+ man = &globals.managers[man_id];
+
+ if (man->window_up)
+ return;
+
+ size_manager (man);
+
+ sizehints.flags = man->sizehints_flags;
+
+
+ sizehints.base_width = sizehints.width = man->geometry.width;
+ sizehints.base_height = sizehints.height = man->geometry.height;
+ sizehints.min_width = 0;
+ sizehints.max_width = globals.screenx;
+ sizehints.min_height = man->geometry.height;
+ sizehints.max_height = man->geometry.height;
+ sizehints.win_gravity = man->gravity;
+ sizehints.flags |= PBaseSize | PMinSize | PMaxSize | PWinGravity;
+ sizehints.x = man->geometry.x;
+ sizehints.y = man->geometry.y;
+
+
+ ConsoleDebug (X11, "hints: x, y, w, h = %d %d %d %d)\n",
+ sizehints.x, sizehints.y,
+ sizehints.base_width, sizehints.base_height);
+ ConsoleDebug (X11, "gravity: %d %d\n", sizehints.win_gravity, man->gravity);
+
+
+ winattr.background_pixel = man->backcolor[PLAIN_CONTEXT];
+ winattr.border_pixel = man->forecolor[PLAIN_CONTEXT];
+ winattr.backing_store = WhenMapped;
+ winattr.bit_gravity = man->gravity;
+ winattr.event_mask = ExposureMask | PointerMotionMask | EnterWindowMask |
+ LeaveWindowMask | KeyPressMask | StructureNotifyMask;
+
+ if (globals.transient)
+ winattr.event_mask |= ButtonReleaseMask;
+ else
+ winattr.event_mask |= ButtonPressMask;
+
+ man->theWindow = XCreateWindow (theDisplay, theRoot, sizehints.x,
+ sizehints.y, man->geometry.width,
+ man->geometry.height,
+ 0, CopyFromParent, InputOutput,
+ (Visual *)CopyFromParent, winattrmask,
+ &winattr);
+#ifdef SHAPE
+ XShapeSelectInput (theDisplay, man->theWindow, ShapeNotifyMask);
+#endif
+
+ /* We really want the bit gravity to be NorthWest, so that can minimize
+ redraws. But, we had to have an appropriate bit gravity when creating
+ the window so that fvwm would place the window correctly if it has
+ a border. I don't know if I should wait until an event is received
+ before doing this. Sigh */
+ winattr.bit_gravity = NorthWestGravity;
+ XChangeWindowAttributes (theDisplay, man->theWindow,
+ CWBitGravity, &winattr);
+ set_shape (man);
+
+ man->theFrame = man->theWindow;
+ man->off_x = 0;
+ man->off_y = 0;
+
+ for (i = 0; i < NUM_CONTEXTS; i++) {
+ man->backContext[i] =
+ XCreateGC (theDisplay, man->theWindow, gcmask, &gcval);
+ XSetForeground (theDisplay, man->backContext[i], man->backcolor[i]);
+ XSetLineAttributes (theDisplay, man->backContext[i], line_width,
+ line_style, cap_style,
+ join_style);
+
+ man->hiContext[i] =
+ XCreateGC (theDisplay, man->theWindow, gcmask, &gcval);
+ XSetFont (theDisplay, man->hiContext[i], man->ButtonFont->fid);
+ XSetForeground (theDisplay, man->hiContext[i], man->forecolor[i]);
+
+ gcmask = GCForeground | GCBackground;
+ gcval.foreground = man->backcolor[i];
+ gcval.background = man->forecolor[i];
+ man->flatContext[i] = XCreateGC (theDisplay, man->theWindow,
+ gcmask, &gcval);
+ if (theDepth > 2) {
+ gcmask = GCForeground | GCBackground;
+ gcval.foreground = man->hicolor[i];
+ gcval.background = man->backcolor[i];
+ man->reliefContext[i] = XCreateGC (theDisplay, man->theWindow,
+ gcmask, &gcval);
+
+ gcmask = GCForeground | GCBackground;
+ gcval.foreground = man->shadowcolor[i];
+ gcval.background = man->backcolor[i];
+ man->shadowContext[i] = XCreateGC (theDisplay, man->theWindow,
+ gcmask, &gcval);
+ }
+ }
+
+ set_window_properties (man->theWindow, man->titlename,
+ man->iconname, &sizehints);
+ man->window_up = 1;
+ map_manager (man);
+}
+
+static int handle_error (Display *d, XErrorEvent *ev)
+{
+ ConsoleMessage ("X Error:\n");
+ ConsoleMessage (" error code: %d\n", ev->error_code);
+ ConsoleMessage (" request code: %d\n", ev->request_code);
+ ConsoleMessage (" minor code: %d\n", ev->minor_code);
+ ConsoleMessage ("Leaving a core dump now\n");
+ abort();
+ return 0;
+}
+
+void init_display (void)
+{
+ theDisplay = XOpenDisplay ("");
+ if (theDisplay == NULL) {
+ ConsoleMessage ("Can't open display: %s\n", XDisplayName (""));
+ ShutMeDown (1);
+ }
+ XSetErrorHandler (handle_error);
+ x_fd = XConnectionNumber (theDisplay);
+ theScreen = DefaultScreen (theDisplay);
+ theRoot = RootWindow (theDisplay, theScreen);
+ theDepth = DefaultDepth (theDisplay, theScreen);
+#ifdef TEST_MONO
+ theDepth = 2;
+#endif
+ globals.screenx = DisplayWidth (theDisplay, theScreen);
+ globals.screeny = DisplayHeight (theDisplay, theScreen);
+
+#ifdef SHAPE
+ globals.shapes_supported = XShapeQueryExtension (theDisplay, &shapeEventBase,
+ &shapeErrorBase);
+#endif
+
+ InitPictureCMap (theDisplay, theRoot);
+
+ ConsoleDebug (X11, "screen width: %ld\n", globals.screenx);
+ ConsoleDebug (X11, "screen height: %ld\n", globals.screeny);
+}