Re: Fwd: Help with GdkWindow size



On 03/25/2014 12:12 AM, Carl Nygard wrote:
Getting resize and expose events through XWindows, but still nothing
through gdk.  The g_signal_connect still complains about invalid instance.
Based on some other docs (
http://gtk.10911.n7.nabble.com/Capture-GdkWindow-event-td8313.html) it
seems like I can't attach the configure-event to the GdkWindow.

So now I'm still left with the fact that the GdkWindow doesn't update it's
internal size, even if I use gdk_window_get_geometry to pull the info from
the X Server, the GdkWindow doesn't update it's internal cache.

So... how to get the GdkWindow to update it's internal size values?

Code and output 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>
#include <gtk/gtk.h>
#define NIL (0)

void frame_callback(GtkWindow *window,
      GdkEvent *event, gpointer data)
{
   printf("frame_callback: %d, %d\n",
          event->configure.x, event->configure.y);
}

gboolean window_expose_event (GtkWidget *widget, GdkEventExpose *event)
{
    printf("expose_event: (%d, %d) (%d,%d)\n",
           event->area.x, event->area.y,
           event->area.width, event->area.height);
    return FALSE;

}

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

      // Open the display
      Display *dpy = XOpenDisplay(NIL);
      int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
      int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
      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);
gdk_win should contain something other than null.
The fact that it is null means the xwindow handle was not properly
associated with it.  You said window isn't mapped.  Are you deliberately
not mapping it?  That doesn't feel right.  How are you going to capture
events for a NULL handled window?

In the Original X, when you call windowing functions with a NULL handle,
you would be dealing with the root window which is the desktop display
itself.

In GDK I don't know if when you pass a NULL to gdk windowing functions
that they will work, but the first hint that you did something wrong at
the gdk level is that you aren't receiving ANY gdk events.  SO revisit
the way you create/associate your gdk window with the x-window.  It's
not right.

One more suggestion.  The only way you are going to get to the bottom of
this is by UTSL(Use the source Luke).  Check out the sources for
gdk_window_foreign_new and gdk_events_pending.  Something tells me it's
not doing what you expect it is supposed to do.

Going back to what I mentioned before, I have used X in conjunction with
Motif because they were built to work together.  If I just use GTK, gtk
creates windows and gtk handles the events.  I imagine GDK is similar
that way.  I don't recall using X in conjunction with GDK as you have,
but I know its within GDK plumbing itself.  I also certainly don't
recall having two messaging handling loops one for X and one for GDK.
Within the gdk api perhaps they have a few message handling loops, but
that was to remove that complexity from gdk api user.  There should be
only one for GDK if you are just using GDK.  I know your case is
different, but if you're only interested in GDK events which I think is
what you're aiming for then perhaps you should ignore x and create a
native GDK window and get a valid gdk handle.  It should be getting
events in the gdk message loop after that.

One more thing: you may need to dispatch events to your child windows.
In normal cases, this happens transparently, but your case is not normal
which is why I am suggesting you look into gdk sources to see what it is
doing.

Cheers,
David Marceau


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

      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
      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");
                }
            }

            XNextEvent(dpy, &e);
            printf("Handling event (%d)\n", e.type);
            switch(e.type) {
            case Expose:
                printf("  Expose (%d,%d) (%d,%d)\n",
                       e.xexpose.x, e.xexpose.y,
                       e.xexpose.width, e.xexpose.height);
                // Draw the line
                XDrawLine(dpy, w, gc, e.xexpose.x, e.xexpose.y,
                          e.xexpose.width, e.xexpose.height);
                XFlush(dpy);
                break;
            case MapNotify:
                gdk_win = gdk_window_foreign_new((guint32)w);
                g_signal_connect(G_OBJECT(gdk_win), "configure-event",
                                 G_CALLBACK(frame_callback), NULL);
                g_signal_connect(G_OBJECT(gdk_win), "expose-event",
                                 G_CALLBACK(window_expose_event), NULL);
                gdk_window_get_size(gdk_win, &x, &y);
                printf("  MapNotify [%p] dims: (%d, %d)\n", gdk_win, x, y);
                break;
            case ConfigureNotify:
                printf("  ConfigureNotify dims: (%d, %d) \n",
                       e.xconfigure.width, e.xconfigure.height);
                if(gdk_win) {
                    gdk_window_get_geometry(gdk_win, NULL, NULL,
                                            &widthret,&heightret, NULL);
                    gdk_window_get_size(gdk_win, &x, &y);
                    printf("  GdkWindow[%p] geometry:(%d, %d) dims:(%d,
%d)\n",
                       gdk_win, widthret, heightret, x, y);
                }
                break;
            default:
                printf("  Unhandled event: (%d)\n", e.type);

            }
            XGetGeometry(dpy, w,
                         &root, &xret, &yret,
                         &widthret, &heightret, &borderwidthret, &depthret);
      }
}

gdk_win = (nil) (should be null since window isn't mapped
Pending event null
Handling event (21)
  Unhandled event: (21)
Handling event (22)
  ConfigureNotify dims: (200, 100)
Handling event (19)

(test:35771): GLib-GObject-WARNING **: gsignal.c:2275: signal
`configure-event' is invalid for instance `0x193e350'

(test:35771): GLib-GObject-WARNING **: gsignal.c:2275: signal
`expose-event' is invalid for instance `0x193e350'
  MapNotify [0x193e350] dims: (200, 100)
Handling event (12)
  Expose (0,0) (200,100)
Handling event (22)
  ConfigureNotify dims: (204, 104)
  GdkWindow[0x193e350] geometry:(204, 104) dims:(200, 100)
Handling event (12)
  Expose (0,0) (204,104)
Handling event (22)
  ConfigureNotify dims: (212, 111)
  GdkWindow[0x193e350] geometry:(212, 111) dims:(200, 100)
Handling event (12)
  Expose (0,0) (212,111)
Handling event (22)
  ConfigureNotify dims: (217, 117)
  GdkWindow[0x193e350] geometry:(217, 117) dims:(200, 100)
Handling event (12)
  Expose (0,0) (217,117)
Handling event (22)
  ConfigureNotify dims: (224, 124)
  GdkWindow[0x193e350] geometry:(224, 124) dims:(200, 100)
Handling event (12)
  Expose (0,0) (224,124)
Handling event (22)
  ConfigureNotify dims: (227, 128)
  GdkWindow[0x193e350] geometry:(227, 128) dims:(200, 100)
Handling event (12)
  Expose (0,0) (227,128)
Handling event (22)
  ConfigureNotify dims: (228, 130)
  GdkWindow[0x193e350] geometry:(228, 130) dims:(200, 100)
Handling event (12)
  Expose (0,0) (228,130)




On Mon, Mar 24, 2014 at 5:51 AM, David Marceau <uticdmarceau2007 yahoo ca>wrote:

On 03/23/2014 11:07 PM, Carl Nygard wrote:
Thanks for the links.  However, most of the information is geared toward
GtkWindow instead of GdkWindow. I tried adding the configure-event signal
connection but I get a message from Gtk saying:
(test:25776): GLib-GObject-WARNING **: gsignal.c:2275: signal
`configure-event' is invalid for instance `0xe45350'

two possibilities:
-bad window handle
-configure-event not flagged on at window create

Suggestions:
-you create the window with x, so set the configure-event flag, right
after the win create at the x level for starters.
-validate the x window handle before hand, right after its creation.
-Get the x callback to at least log some resize/expose events.  Don't do
anything here apart from that for the time being.

-validate the gdk window handle before hand, right after its creation.
-then again set the callback with the configure event at the gdk window
level and log the resize event and expose events.

-you will need to delete the pixmap and recreate a new one with a
different size within the window resize and set it within the window
with the respective position and size.  From what I understand you still
don't correctly capture the window resize event yet so deal with that
first with log messages.  Once that's settled you can fix this.

Cheers,
David Marceau

All I really care about is getting GdkWindow to have current size
information when the XWindow resizes.

To answer your question about the code, it does work on FC4, but we're
porting the existing code to RH5 and some of the drawing started
breaking.
Specifically, we are drawing to a backing pixmap to create animation
frames, but when the frames are copied to the windows, the area that is
rendered is limited to whatever the window size was at the time we create
the GdkWindow via gdk_window_foreign_new().  This is because the
GdkWindow
does not have accurate information regarding it's true size.

--carl




On Sun, Mar 23, 2014 at 4:09 PM, David Marceau <
uticdmarceau2007 yahoo ca>wrote:

There is a difference between resize and expose events.  You're going to
have to take care of this difference within your code and possibly force
the expose event to trigger a resize event which is not necessarily done
by default.

The urls below show how to set the configure event in X, Motif and
GTK/GDK to the appropriate window resize callback.  The gtk tutorial
mentioned a drawing area pixmap to be removed and recreated with the
correct size.

http://www.lemoda.net/c/xlib-resize/
http://zetcode.com/tutorials/gtktutorial/gtkevents/
http://www.gtk.org/tutorial1.2/gtk_tut-23.html
http://www-f9.ijs.si/~matevz/docs/007-2392-003/sgi_html/ch03.html

With all the above being said, have you succeeded in running your app on
the newer os without changing the lines of code?  I tend to believe you
don't need to change your c code if you simply recompile and run on the
newer os.  Motif Libs exist on the newer os, just to get it running.

Cheers,
David Marceau





_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list




_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list gnome org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list




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