Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-12-03 Thread jcupitt
Last post on this I swear, but I thought of another simple improvement.

GTK performs expose event compression, that is, when it sends an
expose to your program, the expose is the union of all the expose
events which the window system generated since your app last saw
expose. GTK computes the smallest set of non-overlapping rectangles
which are damaged (in event-region), and also the bounding box of
that set of rectangles (in event-area).

In the code I posted previously I was just using the bounding box of
the rects. If you have a large number of images moving around, this
will usually be almost the entire display. Very inefficient! Here's a
new version of the expose handler which extracts the list of the exact
damaged areas and only repaints those. This saves about 20% CPU on my
desktop machine, and would save much more if I used small images.

-
static gboolean
expose_cb (GtkDrawingArea * area, GdkEventExpose * event, App * app)
{
  GdkRectangle *rect;
  int i, j, n;

  gdk_region_get_rectangles (event-region, rect, n);
  for (j = 0; j  n; j++)
{
  for (i = 0; i  app-n; i++)
{
  GdkRectangle repaint;

  if (gdk_rectangle_intersect (rect[j], app-area[i], repaint))
gdk_pixbuf_render_to_drawable (app-image[i],
   GTK_WIDGET (area)-window,
   GTK_WIDGET (area)-style-white_gc,
   repaint.x - app-area[i].x,
   repaint.y - app-area[i].y,
   repaint.x, repaint.y,
   repaint.width, repaint.height,
   GDK_RGB_DITHER_NORMAL, 0, 0);
}

  if (app-rubber  gdk_rectangle_intersect (rect[j], app-box, NULL))
gdk_draw_line (GTK_WIDGET (area)-window,
   GTK_WIDGET (area)-style-white_gc,
   app-x1, app-y1, app-x2, app-y2);
}
  g_free (rect);

  return TRUE;
}
-

John
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


GDK_POINTER_MOTION_HINT_MASK has no effect

2007-12-02 Thread Richard Boaz
Stewart,

Yes, all philosophies must ultimately collapse to an actual workable frame
at the end of the day.  Sorry for any confusion caused.  In an attempt to
clear this up (and hopefully not make more), you will find below a
complete workable program that does nothing, really, except to
demonstrate:

  1) programmatically generated RGB buffers converted to pixmap for display
  2) bg pixmaps used as the main background layer
  3) temporary bg pixmaps used to display layers of other drawing info
  4) copying parts of bg pixmaps to another bg pixmap
  5) swapping multiple background pixmaps for display (via the expose
handler) according to a deterministic display state
  6) a pixel to user coordinate and conversion system (very handy)
  7) dragging with mouse-down and mouse-up, with effect
  8) mouse leaving and entering drawing area, with effect
  9) etc...

Copy to drawingSample.c and it will compile out of the box using:

sh  gcc `pkg-config --cflags --libs gtk+2.0` drawSample.c -o drawSample

User functions:

  1) startup - display program-generated RGB buffer
  2) drag/mouse-UP - draw dashed lines as cross hairs at mouse point
  3) drag/mouse-DOWN - draw dashed lines - display user-defined bounding box
  4) mouse-UP/post-Drag - draw solid lines - display bounding box
  5) drawing area leave/enter - display an interesting effect, before and
after bounding box definitions
  6) mouse-CLICK/no-Drag - start over
  7) resize window - start over

As Paul and John have made clear, one issue in deciding how to effectuate
all this rests very much on the size of your background pixmaps (among
other important points).  My problem entails many data points that all map
to a single displayable pixmap, i.e., my bg pixmaps are not very big, so
they're cheap.  Employing this method for large pixmaps on display could
be costly memory-wise.

As Paul also pointed out, pixmaps are server-side objects.  When they are
not large, and the distance between the client and the server is
relatively close, this is not such an issue for me.  However, one way that
the attached program could be brought more up-to-date (and work
everywhere) would be to convert all drawing commands to cairo routines,
thus using a drawing canvas that is client-side, only converting to a
pixmap at the last possible moment (or wherever it would make the most
sense).

As I said, hope this helps.  If there is anything confusing, please ask. 
Also, I program from the bottom of the file to the top, start at the
bottom and work your way backwards when reading it the first time.

cheers,

richard

=== BEGIN drawingSample.c ===

#include string.h
#include stdlib.h
#include sys/time.h
#include gtk/gtk.h

// defines and structures we need
enum {
 MOUSEIN,
 MOUSEOUT,
 TTLPMAPS
};

#define MAX_PIXEL_VALUE 255

typedef struct {
 gint startX, startY, endX, endY;
 gboolean mouseDown;
 gboolean mouseIn;
} MouseState;

typedef struct {
double user_xmin, user_xmax;
float  user_ymin, user_ymax;
float  user_xdif, user_ydif;
intpix_xmin, pix_xmax;
intpix_ymin, pix_ymax;
intpix_ydif, pix_xdif;
} graph;

typedef struct {
 guchar R, G, B;
} myColorStruct;

// some globals
GdkPixmap*DAdisplay, *pmap[TTLPMAPS];
GdkGC*gcSolid, *gcDash;
int CG[6][3] =   // color spectrum
 {{255, 0, 255},  // R = 255-0
  {0, 0, 255},  // G = 0-255
  {0, 255, 255},  // B = 255-0
  {0, 255, 0},  // R = 0-255
  {255, 255, 0},  // G = 255-0
  {240, 240, 240}}; // 0%

myColorStruct * colorP(float prob)
{   // probability to color conversion routine
//  return the color to be associated with the given input of probability:
//  each probability falls into a colour range as follows:
//  0 - 1%:   240,240,240 - 255,000,255 (grey (background) to purple)
//  1 - 6%:   255,000,255 - 000,000,255 (purple to blue)
//  6 - 12%:  000,000,255 - 000,255,255 (blue to cyan)
//  12 - 18%: 000,255,255 - 000,255,000 (cyan to green)
//  18 - 24%: 000,255,000 - 255,255,000 (green to yellow)
//  24 - 30%: 255,255,000 - 255,000,000 (yellow to red)
//
 int  probI = prob, cg;
 static myColorStruct probColor;

 if (prob  1.f)
 {
  probColor.R = 240 - prob*27.;  // R = 213 - 240, 1% - 0%
  probColor.G = 240 - prob*240.;  // G =   0 - 240, 1% - 0%
  probColor.B = 240 + prob*15.;  // B = 255 - 240, 1% - 0%
  return probColor;
 }

 cg = probI/6;
 if (cg4) // normalize all probs  30...
 {
  cg = 4;
  prob = 30.f;
 }

 probColor.R = CG[cg][0]; probColor.G = CG[cg][1]; probColor.B = CG[cg][2];

 switch(cg)
 {
  case 0:
   probColor.R = 255 - (prob*(MAX_PIXEL_VALUE/6.)); // R=255-0
  break; // 1% - 6%
  case 1:
   probColor.G = (prob-6.)*(MAX_PIXEL_VALUE/6.);  // G=0-255
  break; // 6% - 12%
  case 2:
   probColor.B = 255 - ((prob-12.)*(MAX_PIXEL_VALUE/6.)); // B=255-0
  break; // 12% - 18%
  case 3:
   probColor.R = (prob-18.)*(MAX_PIXEL_VALUE/6.);  // R=0-255
  break; // 18% - 24%
  case 4:
   probColor.G = 255 - 

Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-12-02 Thread jcupitt
Hi again Stewart,

On Dec 2, 2007 5:12 AM, Stewart Weiss [EMAIL PROTECTED] wrote:
 I do still have one question about a specific suggestion that you made in
 this thread, below:

I've just spent a while writing you a sample rubberband program and
now I come to post it I see Richard has done the same! Ah well,
perhaps you can't have too much sample code. Mine is a little
different from Richard's, so I'm going to paste it here anyway.

Richard's is a retained mode program. He keeps a complete bitmap for
his display in an offscreen buffer and does all animation there. On
expose, he just copies the relevant part to the screen.

Mine is a list-mode program. I have no backing pixmaps: I do all
drawing in the expose handler. The display only exists as a few
numbers for the positions of the images and the rubberband line.

The two styles are probably appropriate for different type of program
(as I guess our discussion showed). I suppose most programs will fall
somewhere inbetween these two.

If you try it out, run with something like:

  ./a.out ~/pics/*.jpg

(or wherever you keep some pictures). It creates a window with the
first 10 images bouncing around and lets you rubberband a white line
that floats on top. It has the following nice properties:

- the images animate smoothly, they float over each other in a clearly
defined stacking order, and the rubberband line is always on top
- the animation routine is very simple, since it does no drawing
- because drawing and animation are decoupled, the speed stays
constant even under load (the framerate just drops)
- resizing is fluid and doesn't interrupt the animation, since there's
no pixmap to rebuild
- it uses motion hints so the rubberband doesn't lag

-
/* compile with
 *  gcc -g -Wall try144.c `pkg-config gtk+-2.0 --cflags --libs`
 */

#include stdio.h
#include stdlib.h
#include gtk/gtk.h

#define MAX_IMAGES (10)

/* Application state.
 */
typedef struct _App
{
  /* Drawingarea we draw to.
   */
  GtkWidget *drawing;

  /* Loaded images.
   */
  GdkPixbuf *image[MAX_IMAGES];
  int n;

  /* Bounding box and velocity of each image.
   */
  GdkRectangle area[MAX_IMAGES];
  int u[MAX_IMAGES];
  int v[MAX_IMAGES];

  /* Rubberband state.
   */
  gboolean rubber;
  int x1, y1;
  int x2, y2;
  GdkRectangle box; /* Bounding box of rubberband line */
} App;

static void
repaint_rect (App * app, GdkRectangle * rect)
{
  gtk_widget_queue_draw_area (app-drawing,
  rect-x, rect-y, rect-width, rect-height);
}

static gboolean
event_cb (GtkWidget * widget, GdkEvent * ev, App * app)
{
  gboolean handled;

  handled = FALSE;

  switch (ev-type)
{
case GDK_BUTTON_PRESS:
  if (ev-button.button == 1)
{
  app-rubber = TRUE;
  app-x1 = app-x2 = ev-button.x;
  app-y1 = app-y2 = ev-button.y;
  handled = TRUE;
}
  break;

case GDK_BUTTON_RELEASE:
  if (ev-button.button == 1)
{
  app-rubber = FALSE;
  handled = TRUE;
}
  break;

case GDK_MOTION_NOTIFY:
  if (ev-motion.state  GDK_BUTTON1_MASK  app-rubber)
{
  /* A hint? Read the position to get the latest value.
   */
  if (ev-motion.is_hint)
{
  int x, y;

  gdk_window_get_pointer (widget-window, x, y, NULL);
  ev-motion.x = x;
  ev-motion.y = y;
}

  app-x2 = ev-motion.x;
  app-y2 = ev-motion.y;

  /* Queue a repaint at the old position to wipe out where te line
   * was.
   */
  repaint_rect (app, app-box);

  handled = TRUE;
}

  break;

default:
  break;
}

  /* If we handled the event, update the bounding box for the rubberband
   * line and queue a repaint.
   */
  if (handled)
{
  app-box.x = MIN (app-x1, app-x2);
  app-box.width = MAX (app-x1, app-x2) - app-box.x;
  app-box.y = MIN (app-y1, app-y2);
  app-box.height = MAX (app-y1, app-y2) - app-box.y;

  repaint_rect (app, app-box);
}

  return handled;
}

static gboolean
expose_cb (GtkDrawingArea * area, GdkEventExpose * event, App * app)
{
  int i;

  for (i = 0; i  app-n; i++)
{
  GdkRectangle repaint;

  if (gdk_rectangle_intersect (event-area, app-area[i], repaint))
gdk_pixbuf_render_to_drawable (app-image[i],
   GTK_WIDGET (area)-window,
   GTK_WIDGET (area)-style-white_gc,
   repaint.x - app-area[i].x,
   repaint.y - app-area[i].y,
   repaint.x, repaint.y, repaint.width,
   repaint.height,
   GDK_RGB_DITHER_NORMAL, 0, 0);
}

  if (app-rubber  gdk_rectangle_intersect (event-area, app-box, NULL))

RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-12-02 Thread Stewart Weiss
John,

Thanks. I will look at this one and try it out. So now there will be
two very different approaches to compare.  I am very grateful to all of
you for helping.

Stewart

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
 Sent: Sunday, December 02, 2007 4:58 PM
 To: [EMAIL PROTECTED]
 Cc: gtk-list
 Subject: Re: GDK_POINTER_MOTION_HINT_MASK has no effect


 Hi again Stewart,

 On Dec 2, 2007 5:12 AM, Stewart Weiss [EMAIL PROTECTED] wrote:
  I do still have one question about a specific suggestion that
 you made in
  this thread, below:

 I've just spent a while writing you a sample rubberband program and
 now I come to post it I see Richard has done the same! Ah well,
 perhaps you can't have too much sample code. Mine is a little
 different from Richard's, so I'm going to paste it here anyway.

 Richard's is a retained mode program. He keeps a complete bitmap for
 his display in an offscreen buffer and does all animation there. On
 expose, he just copies the relevant part to the screen.

 Mine is a list-mode program. I have no backing pixmaps: I do all
 drawing in the expose handler. The display only exists as a few
 numbers for the positions of the images and the rubberband line.

 The two styles are probably appropriate for different type of program
 (as I guess our discussion showed). I suppose most programs will fall
 somewhere inbetween these two.

 If you try it out, run with something like:

   ./a.out ~/pics/*.jpg

 (or wherever you keep some pictures). It creates a window with the
 first 10 images bouncing around and lets you rubberband a white line
 that floats on top. It has the following nice properties:

 - the images animate smoothly, they float over each other in a clearly
 defined stacking order, and the rubberband line is always on top
 - the animation routine is very simple, since it does no drawing
 - because drawing and animation are decoupled, the speed stays
 constant even under load (the framerate just drops)
 - resizing is fluid and doesn't interrupt the animation, since there's
 no pixmap to rebuild
 - it uses motion hints so the rubberband doesn't lag

 -
 /* compile with
  *  gcc -g -Wall try144.c `pkg-config gtk+-2.0 --cflags --libs`
  */

 #include stdio.h
 #include stdlib.h
 #include gtk/gtk.h

 #define MAX_IMAGES (10)

 /* Application state.
  */
 typedef struct _App
 {
   /* Drawingarea we draw to.
*/
   GtkWidget *drawing;

   /* Loaded images.
*/
   GdkPixbuf *image[MAX_IMAGES];
   int n;

   /* Bounding box and velocity of each image.
*/
   GdkRectangle area[MAX_IMAGES];
   int u[MAX_IMAGES];
   int v[MAX_IMAGES];

   /* Rubberband state.
*/
   gboolean rubber;
   int x1, y1;
   int x2, y2;
   GdkRectangle box;   /* Bounding box of rubberband line */
 } App;

 static void
 repaint_rect (App * app, GdkRectangle * rect)
 {
   gtk_widget_queue_draw_area (app-drawing,
 rect-x, rect-y, rect-width, rect-height);
 }

 static gboolean
 event_cb (GtkWidget * widget, GdkEvent * ev, App * app)
 {
   gboolean handled;

   handled = FALSE;

   switch (ev-type)
 {
 case GDK_BUTTON_PRESS:
   if (ev-button.button == 1)
   {
 app-rubber = TRUE;
 app-x1 = app-x2 = ev-button.x;
 app-y1 = app-y2 = ev-button.y;
 handled = TRUE;
   }
   break;

 case GDK_BUTTON_RELEASE:
   if (ev-button.button == 1)
   {
 app-rubber = FALSE;
 handled = TRUE;
   }
   break;

 case GDK_MOTION_NOTIFY:
   if (ev-motion.state  GDK_BUTTON1_MASK  app-rubber)
   {
 /* A hint? Read the position to get the latest value.
  */
 if (ev-motion.is_hint)
   {
 int x, y;

 gdk_window_get_pointer (widget-window, x, y, NULL);
 ev-motion.x = x;
 ev-motion.y = y;
   }

 app-x2 = ev-motion.x;
 app-y2 = ev-motion.y;

 /* Queue a repaint at the old position to wipe out where te line
  * was.
  */
 repaint_rect (app, app-box);

 handled = TRUE;
   }

   break;

 default:
   break;
 }

   /* If we handled the event, update the bounding box for the rubberband
* line and queue a repaint.
*/
   if (handled)
 {
   app-box.x = MIN (app-x1, app-x2);
   app-box.width = MAX (app-x1, app-x2) - app-box.x;
   app-box.y = MIN (app-y1, app-y2);
   app-box.height = MAX (app-y1, app-y2) - app-box.y;

   repaint_rect (app, app-box);
 }

   return handled;
 }

 static gboolean
 expose_cb (GtkDrawingArea * area, GdkEventExpose * event, App * app)
 {
   int i;

   for (i = 0; i  app-n; i++)
 {
   GdkRectangle repaint;

   if (gdk_rectangle_intersect (event-area, app-area[i], repaint))
   gdk_pixbuf_render_to_drawable (app-image[i],
  GTK_WIDGET (area)-window

RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-12-01 Thread Stewart Weiss
John,

For someone relatively new to GTK like myself, the thread of messages
from you, Richard Boaz, and Paul Davis was extremely eye-opening but also
confusing. I am grateful to hear the exchange of ideas, to the extent that
I understood it. The confusing part is simply trying to decide which of the
design principles makes sense for what I am trying to do now, but also
trying
to extrapolate and understand what principles to follow in general when
starting
up a new application. I am not fishing for answers here; this problem is
mine.

I do still have one question about a specific suggestion that you made in
this thread, below:

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
 Sent: Thursday, November 29, 2007 4:48 PM

-- snip --

 This is often not the case, especially in a complex application.
 Instead, you should think of your window as being composed from a
 number of separate layers (like photoshop layers), and that on an
 expose you should completely repaint that section of the window by
 drawing all layers from the back forwards.

   -- snip --

 Assuming it's raster, you should have two separate data structures.
 Keep a large image around which has the current state of your user's
 image. Only drawing operations go into this, no rubberbanding. This is
 your background layer. Rubberband operations are in another layer
 which floats on top of this.

Do you mean a second pixmap? If so, how does one draw the second one on top
of the first without replacing pixels, assuming the GC function is just
GDK_COPY?


 On an expose, use your background image to paint the exposed pixels.
 Then, if there's a rubber band active at the moment and if the
 bounding box of the rubber band intersects the expose, draw that as
 well on top of the image.

How does one draw layers on top of layers?  If I am understanding you
correctly, you are saying that I can use one bg pixmap to store one layer,
and another pixmap to store a second, higher layer. To be precise, suppose
that I have added the original scribble example, tools so that the user can
draw shapes in addition to the brush strokes. I keep the drawing the user
has created so far in a bg pixmap. Now the user wants to put a line on top
of that drawing, and I want to rubberband it. Are you saying that
(1) the rubberbanded line is drawn into a second pixmap that is drawn on
top of
the other, and if so, how does one draw on top without obscuring the
pixels
underneath using a straightforward GDK_COPY function in the gc, or
(2) do you mean that I should draw into the window, not a second pixmap,
after I have drawn the bg pixmap underneath it?

I have tried drawing directly into the window for the rubberbanded line,
and sending an invalidate_rect event for that line to force a redraw of the
rectangle that includes it as I move the mouse, to make it disappear,
but the result is that it disappears so fast that it is not visible.  Could
you clarify?

Thanks
Stewart

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread Richard Boaz
This is the paradigm I use in all my drawing apps that has served me well:

1) Do all drawing to one or more background pixmaps.
2) Do all drawing in routines separate from your configure handler or
your expose handler.
3) Call your drawing routine(s) from the configure handler.
4) Once your drawing routine has completed its task, call
gtk_widget_queue_draw_area() to force the expose event.
5) Do no drawing in your expose event except to gtk_draw_drawable(),
rendering your background pixmap to the physical display.
6) Use temporary pixmaps liberally when rendering a temporary state
to the screen.  (For example, display of cross-hairs and coordinates
when user is simply dragging the mouse (no buttons down) across the
drawing area.)

You will notice, here, that there is no actual drawing to the physical
screen except to render your pixmap.  This is the fastest possible manner
in which to draw to the screen.  As well, the expose handler is called
whenever your drawing area is exposed by the window manager, say if it has
been partially obscured by other windows and the user brings it to the
front.  By using gtk_draw_drawable(), you can use the same (x,y)
parameters passed to the callback to render only that part of the pixmap
requiring exposure, i.e., making it as fast as possible.  (Not to mention
that to use these (x,y) parameters to programmatically figure out what
should be re-drawn is practically impossible.)

By maintaining all drawing activity in separate routines, you are able to:

1) have multiple routines responsible for drawing a picture to a
single drawing area, determining programmatically which routine should
be called at any given moment.  These separate routines can draw to
separate backing store pixmaps.
2) easily call any drawing routine from anywhere else in your
application, including background threads (via g_idle_add()), thus
making it trivial to maintain a multi-threaded graphical application.
3) maintain, possibly, multiple backing store pixmaps that can be
easily referenced for redrawing without having to go through an entire
redraw.  (For example, to maintain before and after states of a
drawing action.  It is much easier to simply re-render a pixmap as
part of an Undo operation than to have to remember and redraw the
previous state.)

Basically, in de-coupling your configure and expose events from actual
drawing, you gain much more power in managing all the requirements of your
drawing area than if you use a single drawing area that is the screen. 
Not to mention that drawing directly to the screen is absolutely the
slower of the two options.

As John's post indicates, there is no single way to do all this; gtk gives
you way more than enough rope.  The trick is finding the method that works
for you and your specific requirements.

cheers,

richard

On Nov 29, 2007 4:30 AM, Stewart Weiss [EMAIL PROTECTED] wrote:

Many thanks for these posts. They are moving me closer to a better
understanding of the right way to tackle the drawing issues.
I still need a bit of clarification.

1. I am assuming that when I queue a draw for the old position of
the rubberbanded line, I am using XOR to draw it, so that it is in
effect, an erasing, right?

2. You say in the post referenced below that we should really draw
only in the expose event handler, not in the motion or button event
handlers.
Right now, my function to draw a line uses gdk_draw_line into the pixmap
and then calls gdk_window_invalidate_rect to send the expose event later.
If I actually call the gdk_draw_line in the expose event handler,
directly
into the pixmap, would I then use gdk_draw_drawable to copy the pixmap
into
the window?   I know I can't queue a drawing event in the handler or else
I have an infinite indirect recursive loop. Is this how?

Stewart



___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread Paul Davis
On Thu, 2007-11-29 at 09:51 +0100, Richard Boaz wrote:
 This is the paradigm I use in all my drawing apps that has served me well:
 
 1) Do all drawing to one or more background pixmaps.

GTK already does this for you now. All widgets are double buffered
unless you explicitly request otherwise. So you are currently drawing
into your bg pixmap, than GTK will copy it into another bg pixmap and
then finally render it to the screen.

 2) Do all drawing in routines separate from your configure handler or
 your expose handler.
 3) Call your drawing routine(s) from the configure handler.
 4) Once your drawing routine has completed its task, call
 gtk_widget_queue_draw_area() to force the expose event.
 5) Do no drawing in your expose event except to gtk_draw_drawable(),
 rendering your background pixmap to the physical display.
 6) Use temporary pixmaps liberally when rendering a temporary state
 to the screen.  (For example, display of cross-hairs and coordinates
 when user is simply dragging the mouse (no buttons down) across the
 drawing area.)

richard, i know you have a lot of experience with GTK, but i believe
this is the opposite of the design structure of GTK (and X and also
Quartz; not sure about win32). i am not saying that it doesn't work -
clearly it does. but the internal design of GTK is assuming that drawing
occurs inside expose event handlers, and is set up to make this as
efficient and smooth as possible.

 Basically, in de-coupling your configure and expose events from actual
 drawing, you gain much more power in managing all the requirements of your
 drawing area than if you use a single drawing area that is the screen. 
 Not to mention that drawing directly to the screen is absolutely the
 slower of the two options.

this is false.


___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread Richard Boaz

On Nov 29, 2007 1:36 PM, Paul Davis [EMAIL PROTECTED] wrote:

On Thu, 2007-11-29 at 09:51 +0100, Richard Boaz wrote:
 This is the paradigm I use in all my drawing apps that has served me
well:

 1) Do all drawing to one or more background pixmaps.

GTK already does this for you now. All widgets are double buffered
unless you explicitly request otherwise. So you are currently drawing
into your bg pixmap, than GTK will copy it into another bg pixmap and
then finally render it to the screen.

Well, this confuses me a bit.  Help me understand?

Given the following expose handler has been attached to a drawing area:

=== begin code sample 1 ===

gboolean exposeME(GtkWidget *da, GdkEventExpose *event, gpointer *nil)
{
  int w = da-allocation.width;
  int h = da-allocation.height;
  GdkGC *gc = da-style-fg_gc[GTK_WIDGET_STATE(widget)]

  // some lines:
  gdk_draw_line(da-window, gc, w/2, 0, w/2, h);  // vertical
  gdk_draw_line(da-window, gc, 0, h/2, w, h/2);  // horizontal
  gdk_draw_line(da-window, gc, 0, 0, w, h);  // diagonal
  gdk_draw_line(da-window, gc, 0, h, w, 0);  // diagonal

  return TRUE;
}

=== end code sample 2 ===

I assume the double-buffering occurs at least with each call to
gdk_draw_line(), but when is this double-buffer (that you the programmer
have no access to, I assume?) actually rendered to the screen?  After each
call, or only once the expose handler has exited?

If this physical event occurs only after the expose handler has exited,
then kudos to the GTK+ designers and developers, this is very good.  And
you are correct, my method employs an extra bg pixmap that is, in this
simple case, unnecessary, though in any case, not expensive.

*If* this occurs after each call, then I can do better:

=== begin code sample 2 

GdkPixmap *pmap;

void drawMe(GtkWidget *da)
{
  int w = da-allocation.width;
  int h = da-allocation.height;
  GdkGC *gc = da-style-fg_gc[GTK_WIDGET_STATE(widget)]

  gdk_draw_line(pmap, gc, w/2, 0, w/2, h);  // vertical
  gdk_draw_line(pmap, gc, 0, h/2, w, h/2);  // horizontal
  gdk_draw_line(pmap, gc, 0, 0, w, h);  // diagonal
  gdk_draw_line(pmap, gc, 0, h, w, 0);  // diagonal

  gtk_widget_queue_draw_area(da, 0, 0, w, h);
}

gboolean exposeME(GtkWidget *da, GdkEventExpose *event, GdkPixmap *pmap)
{
  int w = da-allocation.width;
  int h = da-allocation.height;
  GdkGC *gc = da-style-fg_gc[GTK_WIDGET_STATE(widget)]

  gdk_draw_drawable(da-window, gc, pmap,
event-area.x, event-area.y,
event-area.width, event-area.height);
  return TRUE;
}

=== end code sample 2 ===

Why better? For at least a couple of reasons.  First, the physical event
to render to the screen has been reduced to one instead of after each
drawing call to da-window in the previous code sample.  (Again, depending
on when the physical render actually occurs.)

Second, double-buffering aside, since (I am assuming here, please correct
me if I'm wrong) you the programmer don't have access to this double
buffer pmap, if you get an expose event from the window manager using code
sample 2, you are making a request for a physical draw that corresponds
exactly to those pixels which require being exposed.  And this particular
case is wholly not addressed in code sample 1; there, you must redraw the
entire screen even if only 4 pixels in the lower right corner require a
re-draw.  As I said before, using the GdkEvent* info to be efficient in
redrawing only what's required is impossible, and if not, a complete waste
of programming time and resources.

In both cases, this equates to a program that is more efficient.  Perhaps
a negligible increase, but an increase nonetheless.  Call me a pedantic
purist, but where graphical programming is concerned, anywhere I can find
a method that is more efficient than another and that will be the method I
choose.

For the record, I have always disagreed with the scribble example in the
demo code; it gets a simple job done, but in the real world, these things
are rarely so simple.

 2) Do all drawing in routines separate from your configure
handler or
 your expose handler.
 3) Call your drawing routine(s) from the configure handler.
 4) Once your drawing routine has completed its task, call
 gtk_widget_queue_draw_area() to force the expose event.
 5) Do no drawing in your expose event except to
gtk_draw_drawable(),
 rendering your background pixmap to the physical display.
 6) Use temporary pixmaps liberally when rendering a temporary
state
 to the screen.  (For example, display of cross-hairs and coordinates
 when user is simply dragging the mouse (no buttons down) across the
 drawing area.)

richard, i know you have a lot of experience with GTK, but i believe
this is the opposite of the design structure of GTK (and X and also
Quartz; not sure about win32). i am not saying that it doesn't work -
clearly it 

Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread Paul Davis
On Thu, 2007-11-29 at 16:24 +0100, Richard Boaz wrote:
 On Nov 29, 2007 1:36 PM, Paul Davis [EMAIL PROTECTED] wrote:
 
 On Thu, 2007-11-29 at 09:51 +0100, Richard Boaz wrote:
  This is the paradigm I use in all my drawing apps that has served me
 well:
 
  1) Do all drawing to one or more background pixmaps.
 
 GTK already does this for you now. All widgets are double buffered
 unless you explicitly request otherwise. So you are currently drawing
 into your bg pixmap, than GTK will copy it into another bg pixmap and
 then finally render it to the screen.
 
 Well, this confuses me a bit.  Help me understand?

   [ ... code  ]

 I assume the double-buffering occurs at least with each call to
 gdk_draw_line(), but when is this double-buffer (that you the programmer
 have no access to, I assume?) actually rendered to the screen?  After each
 call, or only once the expose handler has exited?
 
 If this physical event occurs only after the expose handler has exited,
 then kudos to the GTK+ designers and developers, this is very good.  And
 you are correct, my method employs an extra bg pixmap that is, in this
 simple case, unnecessary, though in any case, not expensive.

that is precisely what happens. drawing calls made during an expose
event handler are redirected into a bg pixmap; at the end of the
expose handler, the relevant parts of the bg pixmap are flushed to the
screen.

   And this particular
 case is wholly not addressed in code sample 1; there, you must redraw the
 entire screen even if only 4 pixels in the lower right corner require a
 re-draw.  As I said before, using the GdkEvent* info to be efficient in
 redrawing only what's required is impossible, and if not, a complete waste
 of programming time and resources.

no, there is never any need to do this. expose events always contain
information on the region (a collection of 1 or more non-overlapping
rectangles) to redraw. this is based either on information from the
underlying window system or whatever was passed to
gdk_window_invalidate_rect() and its cousins. the only limitation is
that GDK generally tiles a drawable with rects no smaller than a given
size, so if there were really just 4 pixels to redraw, you'd like end up
redrawing 32 or 16 or some such number.

 As I also stated, a particular method to choose comes down to
 requirements.  I now have an application that has more than 30 drawing
 areas (across several tabs/screens), each requiring different routines to
 make their picture.  Doing all my drawing in an expose handler means that
 I must define a different expose handler for each drawing area.  But this
 goes against another principle I have come to embrace, define as few
 callbacks as possible for widgets to use; I have a single configure and
 expose handler for all drawing areas, a single callback for all mouse
 events, drag events, radio button groups, etc.  Why?  This minimizes the
 number of routines that are required to exist and be defined, and for me,
 using nothing more than gedit as my editor, infinitely makes the chore of
 coding much easier to manage.

i didn't suggest unique code per expose handler. i said that all drawing
should be done in *an* expose handler. your examples look perfectly
sensible and correct to me. you're doing precisely what i was trying
to convey as far as callbacks, except that:

(a) you're using bg pixmaps that are unnecessary
(b) i believe that configure events will be followed by the necessary
expose events, so your queue_draw() calls in the configure handler are
not required (they won't hurt though)

--p





___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread Richard Boaz
Paul,

Thanks for the information, it's good to learn about how GTK+ does its
double buffering in detail.  However...

On Nov 29, 2007 5:22 PM, Paul Davis [EMAIL PROTECTED] wrote:

   And this particular
 case is wholly not addressed in code sample 1; there, you must
redraw the
 entire screen even if only 4 pixels in the lower right corner require a
 re-draw.  As I said before, using the GdkEvent* info to be efficient in
 redrawing only what's required is impossible, and if not, a complete
waste
 of programming time and resources.

no, there is never any need to do this. expose events always contain
information on the region (a collection of 1 or more non-overlapping
rectangles) to redraw. this is based either on information from the
underlying window system or whatever was passed to
gdk_window_invalidate_rect() and its cousins. the only limitation is
that GDK generally tiles a drawable with rects no smaller than a given
size, so if there were really just 4 pixels to redraw, you'd like end up
redrawing 32 or 16 or some such number.

I'm still confused as to how this case should be handled in an expose
handler if you do all your drawing there.

To illustrate: I have been called once, and GTK+ has drawn to the double
buffer pixmap as you say.  I was partially obscured and am now re-exposed,
i.e., the main loop calls me again specifying an invalidated rectangle via
the GdkEvent structure.

Do I:
  1) redraw the entire picture since I've been called, ignoring all else,
knowing this will result in a fully refreshed screen?

  2) redraw only that part which was obscured (rectangle parameters
provided), having to determine programmatically what drawing commands
actually constitute refreshing the obscured portion?

  3) know that my drawing hasn't changed its state since the last complete
draw and doesn't need to be redrawn at all since upon exiting this call,
the double buffer I had previously written to still contains my drawing
and will physically refresh only the rectangle which was passed to the
expose handler for re-exposure?

Naturally I will demand that the third option is really the only
acceptable answer since:

  1) option 1 is a complete waste of resources when I have to process 100
million data points for drawing to the screen (I exaggerate not).

  2) option 2 is simply impossible to make a one-to-one calculation as to
which pixels must be refreshed, programmatically.

If the third option is how GTK+ handles this scenario (more kudos...),
then the expose handler would look something like?:

gboolean exposeME(.)
{
   if (redrawRequired || firstTime)
   {
  // process 100,000,000 data points to draw to da-window
   }
   return TRUE;
}

If, however, the double buffer no longer exists when called the second
time, and I have to take option 1, then it is utterly inefficient to have
to redraw the entire screen each time the expose handler is called when I
have to do so much to actually redraw.  (And besides, what's the
invalidated rectangle information used for then anyway?)

(Getting a little ahead of myself since I don't know the answer to my
previous question yet, but...)

If I must do it as per option 1, consider then the two options:

Option 1:
- draw to da-window in expose handler (...of 100M data points)
- expose handler called 10 times by main loop

Option 2:
- make bg pixmap in separate routine (...of 100M data points)
- expose pixmap in expose handler via drawing of bg pixmap
- expose handler called 10 times

Would you not take option 2 and save the time required to process 900M
points of data unnecessarily?

Or am I missing something?  It just strikes me as more efficient to issue
real drawing commands as little as possible, i.e., once to a bg pixmap,
and then to draw this pixmap to the screen.  Not only is it more efficient
(simple less CPU usage), it also makes the application more responsive
and snappy since the operation of transferring a pixmap to the screen is
instantaneous, while processing 100M data points is, er, not.

And we haven't even begun to discuss animations of these drawings.  Most
definitely in this case, you would want to:
- make all your drawings making up the entire animation as bg pixmaps
- use g_timeout_add() to invalidate the entire drawing area for redraw,
being called over and over until no more drawings
- while the expose handler does nothing more than render the next pixmap
of the animation sequence to the screen.

No?  Or would you still do all your drawing in the expose handler for an
animation?

And I still don't understand why this particular paradigm which works
without fail for me is opposite to GTK+ design.  It's nothing more than an
alternative to the scribble example that, for my requirements, doesn't
work.

The way I see it, the GTK+ designers and developers have succeeded at
doing what you said: to make it as efficient and as smooth as possible,
and this they have done well.  Is that to say, 

Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread jcupitt
On 11/29/07, Stewart Weiss [EMAIL PROTECTED] wrote:
 This also explains why my solution for drawing the line worked
 reasonably well on Windows but on Linux, the old lines did not get
 erased. So I guess I have to resort to conditional compilation
 directives to make it work in both environments.

The code I pasted will work well on windows and on linux, you
shouldn't need to do any conditional compilation.

The line drawing problems are for other reasons ... you should do all
drawing in the expose handler. If I get a moment, I'll try to make a
small rubber-band example for you.

John
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread Paul Davis
On Thu, 2007-11-29 at 20:03 +0100, Richard Boaz wrote:

 
 To illustrate: I have been called once, and GTK+ has drawn to the double
 buffer pixmap as you say.  I was partially obscured and am now re-exposed,
 i.e., the main loop calls me again specifying an invalidated rectangle via
 the GdkEvent structure.
 
 Do I:
   1) redraw the entire picture since I've been called, ignoring all else,
 knowing this will result in a fully refreshed screen?
 
   2) redraw only that part which was obscured (rectangle parameters
 provided), having to determine programmatically what drawing commands
 actually constitute refreshing the obscured portion?
 
   3) know that my drawing hasn't changed its state since the last complete
 draw and doesn't need to be redrawn at all since upon exiting this call,
 the double buffer I had previously written to still contains my drawing
 and will physically refresh only the rectangle which was passed to the
 expose handler for re-exposure?
 
 Naturally I will demand that the third option is really the only
 acceptable answer since:
 
   1) option 1 is a complete waste of resources when I have to process 100
 million data points for drawing to the screen (I exaggerate not).
 
   2) option 2 is simply impossible to make a one-to-one calculation as to
 which pixels must be refreshed, programmatically.

for many (perhaps even for an overwhelming majority of applications (2)
works just fine. if you application can't do this cheaply, then your
approach is the right way. 

 If the third option is how GTK+ handles this scenario (more kudos...),
 then the expose handler would look something like?:

no, GTK discards the bg pixmaps between exposes. they exist primarily to
improve the visual appearance of the GUI (by avoid tearing and other
artifacts of the drawing process).



___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread jcupitt
On 11/29/07, Stewart Weiss [EMAIL PROTECTED] wrote:
 1. I am assuming that when I queue a draw for the old position of
 the rubberbanded line, I am using XOR to draw it, so that it is in
 effect, an erasing, right?

Actually, I'd suggest using a plain draw rather than an XOR.

XOR rubberbanding works if you can treat your display as something you
can draw incrementally, that is, you know what is on the screen and
therefore you know whether this XOR draw will set or unset a line.

This is often not the case, especially in a complex application.
Instead, you should think of your window as being composed from a
number of separate layers (like photoshop layers), and that on an
expose you should completely repaint that section of the window by
drawing all layers from the back forwards.

 Right now, my function to draw a line uses gdk_draw_line into the pixmap
 and then calls gdk_window_invalidate_rect to send the expose event later.
 If I actually call the gdk_draw_line in the expose event handler, directly
 into the pixmap, would I then use gdk_draw_drawable to copy the pixmap into
 the window?   I know I can't queue a drawing event in the handler or else
 I have an infinite indirect recursive loop. Is this how?

Is this a raster drawing program, or a vector one?

Assuming it's raster, you should have two separate data structures.
Keep a large image around which has the current state of your user's
image. Only drawing operations go into this, no rubberbanding. This is
your background layer. Rubberband operations are in another layer
which floats on top of this.

On an expose, use your background image to paint the exposed pixels.
Then, if there's a rubber band active at the moment and if the
bounding box of the rubber band intersects the expose, draw that as
well on top of the image.

If you're curious, my app is here:

  http://www.vips.ecs.soton.ac.uk

To see the rubberbanding, load an image, doubleclick the thumbnail to
get a view window, then hold down CTRL and click and drag up and left
to get a vector, down and right to get a region, just click to get a
point, or drag from a ruler to get a guide.

If you try resizing outside the edge of the window, the window will
scroll in the background. You can move objects around by dragging on
their names. Hopefully you'll see all the objects, including the
animated ones, float over each other smoothly. There's a simple
paintbox on the View menu which also does some rubberbanding with some
of the tools.

John
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-29 Thread Stewart Weiss
John,

I will study the application you sent me the link to.
My  program is not raster; it lets the user draw with a brush
or use a line tool in the window. Since the user has drawn with a
brush already, the underlying layer is in a pixmap.
First I will look at your application's  code, and if I cannot figure it
out,
I will post again.

Many thanks
Stewart

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
 Sent: Thursday, November 29, 2007 4:48 PM
 To: [EMAIL PROTECTED]
 Cc: gtk-list
 Subject: Re: GDK_POINTER_MOTION_HINT_MASK has no effect


 On 11/29/07, Stewart Weiss [EMAIL PROTECTED] wrote:
  1. I am assuming that when I queue a draw for the old position of
  the rubberbanded line, I am using XOR to draw it, so that it is in
  effect, an erasing, right?

 Actually, I'd suggest using a plain draw rather than an XOR.

 XOR rubberbanding works if you can treat your display as something you
 can draw incrementally, that is, you know what is on the screen and
 therefore you know whether this XOR draw will set or unset a line.

 This is often not the case, especially in a complex application.
 Instead, you should think of your window as being composed from a
 number of separate layers (like photoshop layers), and that on an
 expose you should completely repaint that section of the window by
 drawing all layers from the back forwards.

  Right now, my function to draw a line uses gdk_draw_line into the pixmap
  and then calls gdk_window_invalidate_rect to send the expose
 event later.
  If I actually call the gdk_draw_line in the expose event
 handler, directly
  into the pixmap, would I then use gdk_draw_drawable to copy the
 pixmap into
  the window?   I know I can't queue a drawing event in the
 handler or else
  I have an infinite indirect recursive loop. Is this how?

 Is this a raster drawing program, or a vector one?

 Assuming it's raster, you should have two separate data structures.
 Keep a large image around which has the current state of your user's
 image. Only drawing operations go into this, no rubberbanding. This is
 your background layer. Rubberband operations are in another layer
 which floats on top of this.

 On an expose, use your background image to paint the exposed pixels.
 Then, if there's a rubber band active at the moment and if the
 bounding box of the rubber band intersects the expose, draw that as
 well on top of the image.

 If you're curious, my app is here:

   http://www.vips.ecs.soton.ac.uk

 To see the rubberbanding, load an image, doubleclick the thumbnail to
 get a view window, then hold down CTRL and click and drag up and left
 to get a vector, down and right to get a region, just click to get a
 point, or drag from a ruler to get a guide.

 If you try resizing outside the edge of the window, the window will
 scroll in the background. You can move objects around by dragging on
 their names. Hopefully you'll see all the objects, including the
 animated ones, float over each other smoothly. There's a simple
 paintbox on the View menu which also does some rubberbanding with some
 of the tools.

 John

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-28 Thread jcupitt
On Nov 28, 2007 4:27 AM, Stewart Weiss [EMAIL PROTECTED] wrote:
 Aha!  I did not know that I could configure the GC to draw using
 various functions of the source and dest pixels values. Thanks !

I posted a mail about rubberbanding a couple of months ago:

http://mail.gnome.org/archives/gtk-app-devel-list/2007-October/msg7.html

Might be helpful. In my opinion, you should structure your program like this:

- appstate should have a flag for displaying rubberband line, plus
start/end points
- in your expose handler, first draw the background for the exposed
area, then draw the rubberband liine on top
- in your button-press handler, set the rubber band flag and note the
start position
- in mouse-motion, if rubberband is set and this is a button drag
event, queue a draw for the old position of the rubber band line,
update appstate with the new position, and queue a draw there too
- in button-release, unset the rubber flag and queue a draw for the
position of the line

John
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-28 Thread Stewart Weiss
Thank you. This is a very helpful explanation. I just ran the 
program you sent on my Linux box, remotely displaying on my
Windows box, and sure enough, I see the seen a hint! messages.

This also explains why my solution for drawing the line worked
reasonably well on Windows but on Linux, the old lines did not get
erased. So I guess I have to resort to conditional compilation
directives to make it work in both environments.

Are there white papers or other documents that explain the GDK
implementation on Windows? That would sure make it easier to 
understand how to build code for both platforms.

Stewart


 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
 Sent: Wednesday, November 28, 2007 3:40 AM
 To: [EMAIL PROTECTED]
 Cc: gtk-list@gnome.org
 Subject: Re: GDK_POINTER_MOTION_HINT_MASK has no effect
 
 
 On Nov 28, 2007 2:44 AM, Stewart Weiss [EMAIL PROTECTED] wrote:
  I am running this on a Windows box with gtk+ 2.12 installed.
 
 Ah, OK. I don't think the windows backend uses the is_hint field, so
 you can just ignore it.
 
 It's because X11 is asynchronous. The window server keeps on trucking
 (and sending a lot of highly detailed mouse tracking information) even
 if your program pauses for a moment. As a result, you can get a
 backlog of mouse events and this causes very annoying lag in your
 application.
 
 The idea of is_hint is that when your program comes back to check for
 mouse events it just sees an is_hint event, meaning a lot of mouse
 action has taken place, read the pointer explicitly to get the
 latest. So you get asynchronous mouse evnts and no lag.
 
 Windows is synchronous (the server can never run ahead of the
 application) so it doesn;t need this mechanism. Just ignnore is_hint
 and it'll work fine.
 
 John
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-28 Thread Stewart Weiss
Many thanks for these posts. They are moving me closer to a better
understanding of the right way to tackle the drawing issues.
I still need a bit of clarification.

1. I am assuming that when I queue a draw for the old position of
the rubberbanded line, I am using XOR to draw it, so that it is in
effect, an erasing, right?

2. You say in the post referenced below that we should really draw
only in the expose event handler, not in the motion or button event
handlers.
Right now, my function to draw a line uses gdk_draw_line into the pixmap
and then calls gdk_window_invalidate_rect to send the expose event later.
If I actually call the gdk_draw_line in the expose event handler, directly
into the pixmap, would I then use gdk_draw_drawable to copy the pixmap into
the window?   I know I can't queue a drawing event in the handler or else
I have an infinite indirect recursive loop. Is this how?

Stewart

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
 Sent: Wednesday, November 28, 2007 3:53 AM
 To: [EMAIL PROTECTED]
 Cc: gtk-list
 Subject: Re: GDK_POINTER_MOTION_HINT_MASK has no effect


 On Nov 28, 2007 4:27 AM, Stewart Weiss [EMAIL PROTECTED] wrote:
  Aha!  I did not know that I could configure the GC to draw using
  various functions of the source and dest pixels values. Thanks !

 I posted a mail about rubberbanding a couple of months ago:

 http://mail.gnome.org/archives/gtk-app-devel-list/2007-October/msg
 7.html

 Might be helpful. In my opinion, you should structure your
 program like this:

 - appstate should have a flag for displaying rubberband line, plus
 start/end points
 - in your expose handler, first draw the background for the exposed
 area, then draw the rubberband liine on top
 - in your button-press handler, set the rubber band flag and note the
 start position
 - in mouse-motion, if rubberband is set and this is a button drag
 event, queue a draw for the old position of the rubber band line,
 update appstate with the new position, and queue a draw there too
 - in button-release, unset the rubber flag and queue a draw for the
 position of the line

 John

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-27 Thread richard boaz
Hi,

I'm not really sure what *is_hint* is intended to provide, but anyway, what
you are trying to achieve is totally possible without its use (if I
understand you properly).

Going on the assumption I do understand what you are trying to achieve, I am
providing below some code to illustrate this.  Though actual code, it is not
runnable in its stand-alone form, you will need to tweak it a bit to make it
actually work.  However, it does contain all the hooks necessary to do the
following:

   1. Draw a solid line from point A to point B:
   point A = point at mouse-down
   point B = point at mouse-up
   2. Draw a dashed line from point A (same as in 1) to Drag Point B:
   Drag Point B = point at drag event callback

I have left out the configure and expose callbacks, I assume that these have
been called and produce a pixmap for display, this pixmap being held in the
global variable *DAcontents*.  (Again, this is to illustrate, not to
demonstrate proper coding, you probably shouldn't make a global variable for
this purpose.)

The mouse event callback:

   1. On mouse-down, save the starting point (point A)
   2. On mouse-up, draw a solid line from point A to the ending point
   (point B) and render to the screen.

The drag event callback:

   1. If mouse is not down, do nothing and return
   2. If mouse is down, create temporary pixmap and copy *DAcontents* to
   it
   3. draw a dashed line from point A to Drag Point B (event-x,
   event-y) on our temp pixmap
   4. Render temp pixmap to the screen
   5. unref temp pixmap
   6. call gdk_window_get_pointer() to tell the main loop we are done
   with the drag event and are ready to receive another call to the drag event
   callback

Not sure where the problem is in your implementation, but doing these sorts
of things with GTK+ is typically not problematic.

cheers,

richard

= begin code ===

GdkPixmap*DAcontents;
GdkGC*gcMain;

int main(int argc, char **argv)
{
GtkWidget*da;

gtk_init(argc, argv);

da = gtk_drawing_area_new();
g_signal_connect (da, button_press_event, G_CALLBACK (doMouse), NULL);
g_signal_connect (da, button_release_event, G_CALLBACK (doMouse),
NULL);
g_signal_connect (da, motion_notify_event, G_CALLBACK (doDrag), NULL);
gtk_widget_set_events (da, gtk_widget_get_events (da)
  | GDK_BUTTON_PRESS_MASK
  | GDK_BUTTON_RELEASE_MASK
  | GDK_POINTER_MOTION_MASK
  | GDK_POINTER_MOTION_HINT_MASK);
gtk_main();
}

intstartX, startY, endX, endY;
gboolean mouseDown;

gboolean doMouse(GtkWidget *da, GdkEventButton *event, gpointer nothing)
{
if (!gcMain)
gcMain = gdk_gc_new(da-window);

switch(event-type)
{
case GDK_BUTTON_PRESS:
startX = event-x;
startY = event-y;
mouseDown = TRUE;
break;
case GDK_BUTTON_RELEASE:
endX = event-x;
endY = event-y;
gdk_draw_line(DAcontents, gcMain, startX, startY, endX, endY);
gdk_draw_drawable(da-window,
da-style-fg_gc[GTK_STATE_NORMAL],
DAcontents, 0, 0, 0, 0, -1, -1);
mouseDown = FALSE;
break;
}
return TRUE;
}

gboolean doDrag (GtkWidget *da, GdkEventMotion *event, gpointer nothing)
{
GdkModifierType state;
gintx, y;
GdkPixmap*pixmap;
static GdkGC*gcDash=NULL;

if (!gcDash)
{// first time call setup
gcDash = gdk_gc_new(da-window);
gdk_gc_set_line_attributes(gcDash, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
}

switch(mouseDown)
{
case FALSE:
break;

case TRUE:
pixmap = gdk_pixmap_new(da-window, da-allocation.width, da-
allocation.height, -1);
gdk_draw_drawable(pixmap, da-style-fg_gc[GTK_STATE_NORMAL],
DAcontents,
0, 0, 0, 0, -1, -1);
gdk_draw_line(pixmap, gcDash, startX, startY, event-x,
event-y);
gdk_draw_drawable(da-window,
da-style-fg_gc[GTK_STATE_NORMAL],
pixmap, 0, 0, 0, 0, -1, -1);
g_object_unref(pixmap);
break;
}

gdk_window_get_pointer(event-window, x, y, state);
return TRUE;
}

= end code ===


On Nov 27, 2007 3:27 AM, Stewart Weiss [EMAIL PROTECTED] wrote:

 I have been playing around with the motion_notify_event callback in the
 Scribble example from the tutorial, and I have discovered that none of
 what the documentation states is correct.  I modified the handler to
 generate
 output on the standard outout device as follows:

 gboolean motion_notify_event( GtkWidget  *widget,
  GdkEventMotion *event,
  gpointer   *mydata )
 {
int x, y;
GdkModifierType state;

if (event-is_hint) {

Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-27 Thread Richard Boaz
Hi,

I'm not really sure what is_hint is intended to provide, but anyway, what
you are trying to achieve is totally possible without its use (if I
understand you properly).

Going on the assumption I do understand what you are trying to achieve, I
am providing below some code to illustrate this.  Though actual code, it
is not runnable in its stand-alone form, you will need to tweak it a bit
to make it actually work.  However, it does contain all the hooks
necessary to do the following:

   1. Draw a solid line from point A to point B:
  point A = point at mouse-down
  point B = point at mouse-up
   2. Draw a dashed line from point A (same as in 1) to Drag Point B:
  Drag Point B = point at drag event callback

I have left out the configure and expose callbacks, I assume that these
have been called and produce a pixmap for display, this pixmap being held
in the global variable DAcontents.  (Again, this is to illustrate, not to
demonstrate proper coding, you probably shouldn't make a global variable
for this purpose.)

The mouse event callback:

   1. On mouse-down, save the starting point (point A)
   2. On mouse-up, draw a solid line from point A to the ending point
(point B) and render to the screen.

The drag event callback:

   1. If mouse is not down, do nothing and return
   2. If mouse is down, create temporary pixmap and copy DAcontents to it
   3. draw a dashed line from point A to Drag Point B (event-x, event-y)
on our temp pixmap
   4. Render temp pixmap to the screen
   5. unref temp pixmap
   6. call gdk_window_get_pointer() to tell the main loop we are done with
the drag event and are ready to receive another call to the drag event
callback

Not sure where the problem is in your implementation, but doing these
sorts of things with GTK+ is typically not problematic.

cheers,

richard

= begin code ===

GdkPixmap*DAcontents;
GdkGC*gcMain;

int main(int argc, char **argv)
{
GtkWidget*da;

gtk_init(argc, argv);

da = gtk_drawing_area_new();
g_signal_connect (da, button_press_event, G_CALLBACK (doMouse), NULL);
g_signal_connect (da, button_release_event, G_CALLBACK (doMouse),
NULL);
g_signal_connect (da, motion_notify_event, G_CALLBACK (doDrag), NULL);
gtk_widget_set_events (da, gtk_widget_get_events (da)
  | GDK_BUTTON_PRESS_MASK
  | GDK_BUTTON_RELEASE_MASK
  | GDK_POINTER_MOTION_MASK
  | GDK_POINTER_MOTION_HINT_MASK);
gtk_main();
}

intstartX, startY, endX, endY;
gboolean mouseDown;

gboolean doMouse(GtkWidget *da, GdkEventButton *event, gpointer nothing)
{
if (!gcMain)
gcMain = gdk_gc_new(da-window);

switch(event-type)
{
case GDK_BUTTON_PRESS:
startX = event-x;
startY = event-y;
mouseDown = TRUE;
break;
case GDK_BUTTON_RELEASE:
endX = event-x;
endY = event-y;
gdk_draw_line(DAcontents, gcMain, startX, startY, endX, endY);
gdk_draw_drawable(da-window, da-style-fg_gc[GTK_STATE_NORMAL],
DAcontents, 0, 0, 0, 0, -1, -1);
mouseDown = FALSE;
break;
}
return TRUE;
}

gboolean doDrag (GtkWidget *da, GdkEventMotion *event, gpointer nothing)
{
GdkModifierType state;
gintx, y;
GdkPixmap*pixmap;
static GdkGC*gcDash=NULL;

if (!gcDash)
{// first time call setup
gcDash = gdk_gc_new(da-window);
gdk_gc_set_line_attributes(gcDash, 1, GDK_LINE_ON_OFF_DASH, 0, 0);
}

switch(mouseDown)
{
case FALSE:
break;

case TRUE:
pixmap = gdk_pixmap_new(da-window, da- allocation.width,
da-allocation.height, -1);
gdk_draw_drawable(pixmap, da-style-fg_gc[GTK_STATE_NORMAL],
DAcontents,
0, 0, 0, 0, -1, -1);
gdk_draw_line(pixmap, gcDash, startX, startY, event-x,
event-y);
gdk_draw_drawable(da-window, da-style-fg_gc[GTK_STATE_NORMAL],
pixmap, 0, 0, 0, 0, -1, -1);
g_object_unref(pixmap);
break;

}

gdk_window_get_pointer(event-window, x, y, state);
return TRUE;
}

= end code ===

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-27 Thread jcupitt
On Nov 27, 2007 2:27 AM, Stewart Weiss [EMAIL PROTECTED] wrote:
 Does anyone know what the real semantics are, and when is_hint is true?

Here's a complete small program that shows mouse events (with hints)
for a drawing area.

--
/* compile with
 *  gcc -g -Wall try32.c `pkg-config gtk+-2.0 --cflags --libs`
 */

#include stdio.h
#include gtk/gtk.h

static gboolean
event_cb (GtkWidget * widget, GdkEvent * ev)
{
  gboolean handled;

  handled = FALSE;

  switch (ev-type)
{
case GDK_BUTTON_PRESS:
  printf (button %d press\n, ev-button.button);
  handled = TRUE;
  break;

case GDK_BUTTON_RELEASE:
  printf (button %d release\n, ev-button.button);
  handled = TRUE;
  break;

case GDK_MOTION_NOTIFY:
  /* A hint? Read the position to get the latest value.
   */
  if (ev-motion.is_hint)
{
  GdkDisplay *display = gtk_widget_get_display (widget);
  GdkScreen *screen;
  int x_root, y_root;

  printf (seen a hint!\n);

  gdk_display_get_pointer (display, screen, x_root, y_root, NULL);
  ev-motion.x_root = x_root;
  ev-motion.y_root = y_root;
}

  printf (motion at %g x %g\n, ev-motion.x_root, ev-motion.y_root);

  if (ev-motion.state  GDK_BUTTON1_MASK)
printf ((and btn1 held down)\n);
  if (ev-motion.state  GDK_BUTTON2_MASK)
printf ((and btn2 held down)\n);

  handled = TRUE;

  break;

default:
  break;
}

  return (handled);
}

int
main (int argc, char **argv)
{
  GtkWidget *win;
  GtkWidget *area;

  gtk_init (argc, argv);
  win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (win, destroy, G_CALLBACK (gtk_main_quit), NULL);

  area = gtk_drawing_area_new ();
  gtk_widget_add_events (GTK_WIDGET (area),
 GDK_POINTER_MOTION_MASK |
 GDK_POINTER_MOTION_HINT_MASK |
 GDK_BUTTON_PRESS_MASK |
 GDK_BUTTON_RELEASE_MASK);

  gtk_signal_connect_after (GTK_OBJECT (area), event,
GTK_SIGNAL_FUNC (event_cb), NULL);

  gtk_container_add (GTK_CONTAINER (win), area);

  gtk_window_set_default_size (GTK_WINDOW (win), 250, 250);
  gtk_widget_show_all (win);

  gtk_main ();

  return (0);
}


You get output like:

seen a hint!
motion at 1367 x 446
seen a hint!
motion at 1368 x 446
button 1 press
seen a hint!
motion at 1368 x 447
(and btn1 held down)
button 2 press
seen a hint!
motion at 1368 x 448
(and btn1 held down)
(and btn2 held down)

John
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-27 Thread Stewart Weiss
Thanks for the code, BUT... when I run it exactly as you
typed it below, I get NO output lines that say
seen a hint!
no matter how I move the mouse and press the buttons.
I get all other outputs: all button down and release and
motion at r x c type messages. No hints.

I am running this on a Windows box with gtk+ 2.12 installed.


Stewart


 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 27, 2007 9:30 AM
 To: [EMAIL PROTECTED]
 Cc: gtk-list@gnome.org
 Subject: Re: GDK_POINTER_MOTION_HINT_MASK has no effect
 
 
 On Nov 27, 2007 2:27 AM, Stewart Weiss [EMAIL PROTECTED] wrote:
  Does anyone know what the real semantics are, and when is_hint is true?
 
 Here's a complete small program that shows mouse events (with hints)
 for a drawing area.
 
 --
 /* compile with
  *  gcc -g -Wall try32.c `pkg-config gtk+-2.0 --cflags --libs`
  */
 
 #include stdio.h
 #include gtk/gtk.h
 
 static gboolean
 event_cb (GtkWidget * widget, GdkEvent * ev)
 {
   gboolean handled;
 
   handled = FALSE;
 
   switch (ev-type)
 {
 case GDK_BUTTON_PRESS:
   printf (button %d press\n, ev-button.button);
   handled = TRUE;
   break;
 
 case GDK_BUTTON_RELEASE:
   printf (button %d release\n, ev-button.button);
   handled = TRUE;
   break;
 
 case GDK_MOTION_NOTIFY:
   /* A hint? Read the position to get the latest value.
*/
   if (ev-motion.is_hint)
 {
   GdkDisplay *display = gtk_widget_get_display (widget);
   GdkScreen *screen;
   int x_root, y_root;
 
   printf (seen a hint!\n);
 
   gdk_display_get_pointer (display, screen, x_root, 
 y_root, NULL);
   ev-motion.x_root = x_root;
   ev-motion.y_root = y_root;
 }
 
   printf (motion at %g x %g\n, ev-motion.x_root, 
 ev-motion.y_root);
 
   if (ev-motion.state  GDK_BUTTON1_MASK)
 printf ((and btn1 held down)\n);
   if (ev-motion.state  GDK_BUTTON2_MASK)
 printf ((and btn2 held down)\n);
 
   handled = TRUE;
 
   break;
 
 default:
   break;
 }
 
   return (handled);
 }
 
 int
 main (int argc, char **argv)
 {
   GtkWidget *win;
   GtkWidget *area;
 
   gtk_init (argc, argv);
   win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   g_signal_connect (win, destroy, G_CALLBACK (gtk_main_quit), NULL);
 
   area = gtk_drawing_area_new ();
   gtk_widget_add_events (GTK_WIDGET (area),
  GDK_POINTER_MOTION_MASK |
  GDK_POINTER_MOTION_HINT_MASK |
  GDK_BUTTON_PRESS_MASK |
  GDK_BUTTON_RELEASE_MASK);
 
   gtk_signal_connect_after (GTK_OBJECT (area), event,
 GTK_SIGNAL_FUNC (event_cb), NULL);
 
   gtk_container_add (GTK_CONTAINER (win), area);
 
   gtk_window_set_default_size (GTK_WINDOW (win), 250, 250);
   gtk_widget_show_all (win);
 
   gtk_main ();
 
   return (0);
 }
 
 
 You get output like:
 
 seen a hint!
 motion at 1367 x 446
 seen a hint!
 motion at 1368 x 446
 button 1 press
 seen a hint!
 motion at 1368 x 447
 (and btn1 held down)
 button 2 press
 seen a hint!
 motion at 1368 x 448
 (and btn1 held down)
 (and btn2 held down)
 
 John
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-27 Thread Stewart Weiss
Richard:

Thanks for this suggestion.  Last night after sending the message, I did, in
fact, resort to
doing pretty much what you suggested below, by getting the mouse-down, then
tracking it
with button-motion-notify, and then getting the mouse-up event. But I am not
using a temporary
pixmap, and I have to erase each previously drawn line.

What I want to achieve is a typical Line Tool, like the one in Windows
Paint, one that will
continuously redraw the line as I drag the mouse.   In order to solve this,
in my motion-notify-event
handler I erase the previous line by drawing it on the window (not the
pixmap) using the background
color of my pixmap, then draw a new one in the window (not in the pixmap).
When I get the mouse up event,
I draw the last line into the pixmap and render it to the screen. But I
still have some problems.
When I erase the previous line, I also erase pixels that might have been
drawn as part of something
else in the window, so my solution is that when I get the button-up event I
invalidate the entire
window to redraw it. But until I release the mouse button, the erase pixels
remain erased. I was thinking
of invalidating the rectangle containing the line each time to se if that
would work, but I have not tried it
yet (busy day). But any other ideas would be appreciated.

The motion event handler is basically this (with stuff removed because I use
the same handler
to draw free-form lines with a brush):

gboolean motion_notify_event( GtkWidget *widget,
  GdkEventMotion *event,
  ApplicationState *appState )
{
int x, y;
GdkModifierType state;

if (event-is_hint) {
gdk_window_get_pointer (event-window, x, y, state);
}
else
{
state = event-state;
if (state  GDK_BUTTON1_MASK  appState-pixmap != NULL 
appState-isLineToolOn )
erase_line ( widget, appState,
line_start_x,
line_start_y,
line_end_x, line_end_y );
x = event-x;
y = event-y;
}

if (state  GDK_BUTTON1_MASK  appState-pixmap != NULL
   appState-isLineToolOn  ) {
line_end_x = x;
line_end_y = y;
draw_line ( widget, appState,
line_start_x,
line_start_y,
line_end_x, line_end_y, FALSE );

}

return TRUE;
}

The appState is just a struct that has all the application data in it. The
button press
event callback handles both down and up events:

gboolean button_press_event( GtkWidget  *widget,
GdkEventButton *event,
ApplicationState *appState )
{
const gboolean  finalize = TRUE;

if ( event-button == 1  appState-pixmap != NULL 
appState-isLineToolOn) {
if ( event-type == GDK_BUTTON_PRESS ) {
line_start_x = event-x;
line_start_y = event-y;
}
else if ( event-type == GDK_BUTTON_RELEASE 
appState-isLineToolOn) {
draw_line ( widget, appState,
line_start_x,
line_start_y,
line_end_x, line_end_y, finalize);
}
}
return TRUE;
}

 Thanks for the help
Stewart
  -Original Message-
  From: richard boaz [mailto:[EMAIL PROTECTED]
  Sent: Tuesday, November 27, 2007 6:19 AM
  To: [EMAIL PROTECTED]
  Cc: gtk-list@gnome.org
  Subject: Re: GDK_POINTER_MOTION_HINT_MASK has no effect


  Hi,

  I'm not really sure what is_hint is intended to provide, but anyway, what
you are trying to achieve is totally possible without its use (if I
understand you properly).

  Going on the assumption I do understand what you are trying to achieve, I
am providing below some code to illustrate this.  Though actual code, it is
not runnable in its stand-alone form, you will need to tweak it a bit to
make it actually work.  However, it does contain all the hooks necessary to
do the following:

1.. Draw a solid line from point A to point B:
point A = point at mouse-down
point B = point at mouse-up
2.. Draw a dashed line from point A (same as in 1) to Drag Point B:
Drag Point B = point at drag event callback
  I have left out the configure and expose callbacks, I assume that these
have been called and produce a pixmap for display, this pixmap being held in
the global variable DAcontents.  (Again, this is to illustrate, not to
demonstrate proper coding, you probably shouldn't make a global variable for
this purpose.)

  The mouse event callback:

1.. On mouse-down, save the starting point (point A)

2.. On mouse-up, draw a solid line from point A to the ending point
(point B) and render to the screen.
  The drag event callback:

1.. If mouse is not down, do nothing and return

2.. If mouse is down, create temporary pixmap and copy DAcontents to it
3.. draw a dashed line

RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-27 Thread Stewart Weiss
Aha!  I did not know that I could configure the GC to draw using
various functions of the source and dest pixels values. Thanks !

Stewart

 -Original Message-
 From: Paul Davis [mailto:[EMAIL PROTECTED]
 Sent: Tuesday, November 27, 2007 11:13 PM
 To: [EMAIL PROTECTED]
 Cc: richard boaz; gtk-list@gnome.org
 Subject: RE: GDK_POINTER_MOTION_HINT_MASK has no effect
 
 
 On Tue, 2007-11-27 at 22:17 -0500, Stewart Weiss wrote:
  Richard:
   
  Thanks for this suggestion.  Last night after sending the message, I
  did, in fact, resort to
  doing pretty much what you suggested below, by getting the mouse-down,
  then tracking it 
  with button-motion-notify, and then getting the mouse-up event. But I
  am not using a temporary
  pixmap, and I have to erase each previously drawn line.
   
  What I want to achieve is a typical Line Tool, like the one in Windows
  Paint, one that will
  continuously redraw the line as I drag the mouse.   In order to solve
  this, in my motion-notify-event
  handler I erase the previous line by drawing it on the window (not the
  pixmap) using the background 
  color of my pixmap, then draw a new one in the window (not in the
  pixmap). When I get the mouse up event,
  I draw the last line into the pixmap and render it to the screen. But
  I still have some problems.
  When I erase the previous line, I also erase pixels that might have
  been drawn as part of something
  else in the window, so my solution is that when I get the button-up
  event I invalidate the entire
  window to redraw it. But until I release the mouse button, the erase
  pixels remain erased. I was thinking
  of invalidating the rectangle containing the line each time to se if
  that would work, but I have not tried it
  yet (busy day). But any other ideas would be appreciated.
 
 google for draw xor gtk and read on ...
 
 
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


RE: GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-27 Thread Paul Davis
On Tue, 2007-11-27 at 22:17 -0500, Stewart Weiss wrote:
 Richard:
  
 Thanks for this suggestion.  Last night after sending the message, I
 did, in fact, resort to
 doing pretty much what you suggested below, by getting the mouse-down,
 then tracking it 
 with button-motion-notify, and then getting the mouse-up event. But I
 am not using a temporary
 pixmap, and I have to erase each previously drawn line.
  
 What I want to achieve is a typical Line Tool, like the one in Windows
 Paint, one that will
 continuously redraw the line as I drag the mouse.   In order to solve
 this, in my motion-notify-event
 handler I erase the previous line by drawing it on the window (not the
 pixmap) using the background 
 color of my pixmap, then draw a new one in the window (not in the
 pixmap). When I get the mouse up event,
 I draw the last line into the pixmap and render it to the screen. But
 I still have some problems.
 When I erase the previous line, I also erase pixels that might have
 been drawn as part of something
 else in the window, so my solution is that when I get the button-up
 event I invalidate the entire
 window to redraw it. But until I release the mouse button, the erase
 pixels remain erased. I was thinking
 of invalidating the rectangle containing the line each time to se if
 that would work, but I have not tried it
 yet (busy day). But any other ideas would be appreciated.

google for draw xor gtk and read on ...



___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


GDK_POINTER_MOTION_HINT_MASK has no effect

2007-11-26 Thread Stewart Weiss
I have been playing around with the motion_notify_event callback in the
Scribble example from the tutorial, and I have discovered that none of
what the documentation states is correct.  I modified the handler to
generate
output on the standard outout device as follows:

gboolean motion_notify_event( GtkWidget  *widget,
  GdkEventMotion *event,
  gpointer   *mydata )
{
int x, y;
GdkModifierType state;

if (event-is_hint) {
gdk_window_get_pointer (event-window, x, y, state);
g_print ( is hint at %d, %d\n, x, y );
}
else {
x = event-x;
y = event-y;
state = event-state;
g_print ( is not hint at %d, %d\n, x, y );
}

I have set events on the widget using all 8 possible combinations of the
three
masks:
   GDK_POINTER_MOTION_MASK
   GDK_BUTTON_MOTION_MASK
   GDK_POINTER_MOTION_HINT_MASK

What I have found is that the event-is_hint IS NEVER true, regardless of
the
masks I set on the widget.  What IS TRUE is that when the
GDK_BUTTON_MOTION_MASK
is set on the widget, with or without the GDK_POINTER_MOTION_HINT_MASK, the
only
signals emitted by the widget are when the mouse button is down while the
pointer
is in motion. This is contrary to what is written in the GDK Reference
Manual.

Because the is hint at ... is never displayed, it also implies that
gdk_window_get_pointer() is never called.

I was trying to implement a straight-line tool and I had hoped that I could
detect
the starting and ending points using the fact that the is_hint member would
be true
only when the window was entered, or a button press or release event (as it
says in
the tutorial.)   I figured I could get the point when the mouse button was
first
pressed and then wait until the mouse button was released to write the line
into
my pixmap.

Does anyone know what the real semantics are, and when is_hint is true?

Stewart

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list