Help with GdkWindow size



Hoping to get some help on an older version of Gtk.  I'm actually using
Gtkmm, but I've boiled the issue down to straight X/Gtk code.  I'm
supporting some legacy code and as we migrate to newer versions of OS,
we're running into issues with some drawing functionality.

To boil it down, we are creating a GdkWindow via gdk_window_foreign_new()
from a drawable X window.  The app is a Motif application (yes, old) and we
use the GdkWindow to render images and drawing.

The issue is that everything works fine the first time through.  But if we
resize the window, the gdk_window_get_size()  always returns whatever size
the window was when the drawable was initialized.

I've tried a bunch of different ideas to try to get this to work:

- gdk_window_foreign_new_for_display(dpy, win) has no effect on behavior
- re-creating GdkWindow via new call to gdk_window_foreign_new()
- XGetGeometry(dpy, win, ...) followed by gdk_window_resize(win,...)

Nothing seems to work.  gdk_window_resize() has no effect on the
GdkWindow.  Freeing the drawable and then calling gdk_window_foreign_new()
actually returns the same value for the GdkWindow* every time, so I don't
think internal GdkWindow state is updated.

I'm hoping someone has some clues as to what I'm doing wrong.  I'd be happy
with any kind of workaround just to get this functional.  Suggestions to
just upgrade to latest are not helpful, as this is legacy code.  I've
included the code I'm testing with below.

My best guess at a solution is to somehow get Gtk to process the resize
internally so that the GdkWindow internal cache of window size is up to
date.  I think that means that Gtk needs to process the GdkEventConfigure
when the XWindow is resized.  But I haven't been able to figure out the
hooks to make that happen.

Any help would be much appreciated.  Code example below:

// Written by Ch. Tronche (http://tronche.lri.fr:8000/)
// Modified by C. Nygard to illustrate gdk_window resize issue
// Copyright by the author. This is unmaintained, no-warranty free
software.
// Please use freely. It is appreciated (but by no means mandatory) to
// acknowledge the author's contribution. Thank you.
// Started on Thu Jun 26 23:29:03 1997

// gcc -o test test.c `pkg-config --libs --cflags gtk+-2.0 gtk+-x11-2.0`


#include <X11/Xlib.h>
#include <assert.h>
#include <unistd.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>

#define NIL (0)

main(int argc, char **argv)
{
      GdkWindow *gdk_win;

      gdk_init(&argc, &argv);

      // Open the display
      Display *dpy = XOpenDisplay(NIL);

      // Get some colors
      int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
      int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

      // Create the window
      Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
                                     200, 100, 0, blackColor, blackColor);
      gdk_win = gdk_window_foreign_new((guint32)w);
      printf("gdk_win = %p (should be null since window isn't mapped\n",
             gdk_win);

      // We want to get MapNotify events
      XSelectInput(dpy, w, StructureNotifyMask);

      // "Map" the window (that is, make it appear on the screen)
      XMapWindow(dpy, w);

      // Create a "Graphics Context"
      GC gc = XCreateGC(dpy, w, 0, NIL);

      // Tell the GC we draw using the white color
      XSetForeground(dpy, gc, whiteColor);

      // Wait for the MapNotify event
      for(;;) {
            XEvent e;
            XNextEvent(dpy, &e);
            if (e.type == MapNotify)
                  break;
      }

      gdk_win = gdk_window_foreign_new((guint32)w);
      printf("gdk_win = %p\n", gdk_win);
      {
          int x, y;
          gdk_window_get_size(gdk_win, &x, &y);
          printf("GdkWindow initial dims: (%d, %d)\n", x, y);

          // Draw the line
          XDrawLine(dpy, w, gc, 10, 60, x-20, y-20);

          // Send the "DrawLine" request to the server
          XFlush(dpy);
      }

      // Wait for the MapNotify event
      int done = 0;
      while(!done) {
            XEvent e;
            Window root;
            int x, y, xret, yret;
            unsigned int widthret,heightret,borderwidthret,depthret;

            // process gdk event loop
            while(gdk_events_pending()) {
                GdkEvent *ev = gdk_event_get();
                if(ev) {
                    printf("Processing event [%d]\n", ev->type);
                    switch(ev->type) {
                    case GDK_DELETE:
                        done = 1;
                        break;
                    default:
                        printf("GDK Event: [%d]", ev->type);
                        break;
                    }
                    gdk_event_free(ev);
                }else{
                    printf("Pending event null\n");
                }
            }
            // Re-initializing gdk_win doesn't even help
            g_object_unref(gdk_win);
            gdk_win = gdk_window_foreign_new((guint32)w);
            gdk_window_get_size(gdk_win, &x, &y);
            printf("GdkWindow [%p] dims: (%d, %d)\n", gdk_win, x, y);

            XNextEvent(dpy, &e);
            XGetGeometry(dpy, w,
                         &root, &xret, &yret,
                         &widthret, &heightret, &borderwidthret, &depthret);
            printf("Window dims: (%d, %d) pos: (%d, %d)\n",
                   widthret, heightret, xret, yret);

            // Draw the line
            XDrawLine(dpy, w, gc, 10, 60, widthret-20, heightret-20);

            // Send the "DrawLine" request to the server
            XFlush(dpy);
      }

}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]