gdkinternals.h 19.1 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GDK - The GIMP Drawing Kit
2 3 4
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6 7 8 9 10
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 17 18
 */

/*
19
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20 21 22 23 24 25 26
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

/* Uninstalled header defining types and functions internal to GDK */

27 28 29
#ifndef __GDK_INTERNALS_H__
#define __GDK_INTERNALS_H__

30
#include <gio/gio.h>
31 32 33
#include "gdkwindowimpl.h"
#include "gdkdisplay.h"
#include "gdkprivate.h"
34

35 36
G_BEGIN_DECLS

37 38 39 40 41 42
/**********************
 * General Facilities * 
 **********************/

/* Debugging support */

43
typedef struct _GdkColorInfo           GdkColorInfo;
44 45
typedef struct _GdkEventFilter         GdkEventFilter;
typedef struct _GdkClientFilter        GdkClientFilter;
46 47 48 49 50 51 52 53 54 55 56

typedef enum {
  GDK_COLOR_WRITEABLE = 1 << 0
} GdkColorInfoFlags;

struct _GdkColorInfo
{
  GdkColorInfoFlags flags;
  guint ref_count;
};

57 58 59 60
typedef enum {
  GDK_EVENT_FILTER_REMOVED = 1 << 0
} GdkEventFilterFlags;

61 62 63
struct _GdkEventFilter {
  GdkFilterFunc function;
  gpointer data;
64 65
  GdkEventFilterFlags flags;
  guint ref_count;
66 67 68 69 70 71 72 73
};

struct _GdkClientFilter {
  GdkAtom       type;
  GdkFilterFunc function;
  gpointer      data;
};

74
typedef enum {
75 76 77 78 79 80 81 82 83 84
  GDK_DEBUG_MISC          = 1 <<  0,
  GDK_DEBUG_EVENTS        = 1 <<  1,
  GDK_DEBUG_DND           = 1 <<  2,
  GDK_DEBUG_XIM           = 1 <<  3,
  GDK_DEBUG_NOGRABS       = 1 <<  4,
  GDK_DEBUG_INPUT         = 1 <<  5,
  GDK_DEBUG_CURSOR        = 1 <<  6,
  GDK_DEBUG_MULTIHEAD     = 1 <<  7,
  GDK_DEBUG_XINERAMA      = 1 <<  8,
  GDK_DEBUG_DRAW          = 1 <<  9,
Owen W. Taylor's avatar
Owen W. Taylor committed
85
  GDK_DEBUG_EVENTLOOP     = 1 << 10,
86
  GDK_DEBUG_FRAMES        = 1 << 11,
87
  GDK_DEBUG_SETTINGS      = 1 << 12,
88
  GDK_DEBUG_OPENGL        = 1 << 13,
89 90
} GdkDebugFlag;

91 92 93 94 95 96
typedef enum {
  GDK_RENDERING_MODE_SIMILAR = 0,
  GDK_RENDERING_MODE_IMAGE,
  GDK_RENDERING_MODE_RECORDING
} GdkRenderingMode;

97 98 99 100 101
typedef enum {
  GDK_GL_DISABLE                = 1 << 0,
  GDK_GL_ALWAYS                 = 1 << 1,
  GDK_GL_SOFTWARE_DRAW_GL       = 1 << 2,
  GDK_GL_SOFTWARE_DRAW_SURFACE  = 1 << 3,
102
  GDK_GL_TEXTURE_RECTANGLE      = 1 << 4,
103 104
  GDK_GL_LEGACY                 = 1 << 5,
  GDK_GL_GLES                   = 1 << 6
105 106
} GdkGLFlags;

107
extern GList            *_gdk_default_filters;
108
extern GdkWindow        *_gdk_parent_root;
109 110

extern guint _gdk_debug_flags;
111
extern guint _gdk_gl_flags;
112
extern GdkRenderingMode    _gdk_rendering_mode;
113
extern gboolean _gdk_debug_updates;
114 115 116

#ifdef G_ENABLE_DEBUG

117 118 119 120
#define GDK_DEBUG_CHECK(type) G_UNLIKELY (_gdk_debug_flags & GDK_DEBUG_##type)

#define GDK_NOTE(type,action)                G_STMT_START {     \
    if (GDK_DEBUG_CHECK (type))                                 \
121
       { action; };                          } G_STMT_END
122 123 124

#else /* !G_ENABLE_DEBUG */

125
#define GDK_DEBUG_CHECK(type) 0
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
#define GDK_NOTE(type,action)

#endif /* G_ENABLE_DEBUG */

/* Arg parsing */

typedef enum 
{
  GDK_ARG_STRING,
  GDK_ARG_INT,
  GDK_ARG_BOOL,
  GDK_ARG_NOBOOL,
  GDK_ARG_CALLBACK
} GdkArgType;

typedef struct _GdkArgContext GdkArgContext;
typedef struct _GdkArgDesc GdkArgDesc;

typedef void (*GdkArgFunc) (const char *name, const char *arg, gpointer data);

struct _GdkArgContext
{
  GPtrArray *tables;
  gpointer cb_data;
};

struct _GdkArgDesc
{
  const char *name;
  GdkArgType type;
  gpointer location;
  GdkArgFunc callback;
};

/* Event handling */

162 163 164 165 166 167 168
typedef struct _GdkEventPrivate GdkEventPrivate;

typedef enum
{
  /* Following flag is set for events on the event queue during
   * translation and cleared afterwards.
   */
169 170 171 172 173 174
  GDK_EVENT_PENDING = 1 << 0,

  /* The following flag is set for:
   * 1) touch events emulating pointer events
   * 2) pointer events being emulated by a touch sequence.
   */
175 176 177 178 179 180 181
  GDK_EVENT_POINTER_EMULATED = 1 << 1,

  /* When we are ready to draw a frame, we pause event delivery,
   * mark all events in the queue with this flag, and deliver
   * only those events until we finish the frame.
   */
  GDK_EVENT_FLUSHED = 1 << 2
182 183 184 185
} GdkEventFlags;

struct _GdkEventPrivate
{
186 187 188
  GdkEvent   event;
  guint      flags;
  GdkScreen *screen;
189
  gpointer   windowing_data;
190
  GdkDevice *device;
191
  GdkDevice *source_device;
192
  GdkSeat   *seat;
193
  GdkDeviceTool *tool;
194
  guint16    key_scancode;
195 196
};

197
typedef struct _GdkWindowPaint GdkWindowPaint;
198

199
struct _GdkWindow
200
{
201
  GObject parent_instance;
202

203 204
  GdkWindowImpl *impl; /* window-system-specific delegate object */

205
  GdkWindow *parent;
206
  GdkWindow *transient_for;
207
  GdkVisual *visual;
208 209 210 211 212

  gpointer user_data;

  gint x;
  gint y;
213 214

  GdkEventMask event_mask;
Matthias Clasen's avatar
Matthias Clasen committed
215 216 217 218 219 220
  guint8 window_type;

  guint8 depth;
  guint8 resize_count;

  gint8 toplevel_window_type;
221 222 223

  GList *filters;
  GList *children;
224
  GList children_list_node;
225
  GList *native_children;
226

227

228
  cairo_pattern_t *background;
229

230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
  /* The paint logic here is a bit complex because of our intermingling of
   * cairo and GL. Let's first go over the cairo-alone case:
   *
   *  1) gdk_window_begin_paint_region() is called with an update region. If
   *     the backend wants it, we redirect drawing to a temporary surface
   *     sized the same as the update region and set `surface_needs_composite`
   *     to TRUE. Otherwise, we paint directly onto the real server-side window.
   *
   *  2) Things paint with cairo using gdk_cairo_create().
   *
   *  3) When everything is painted, the user calls gdk_window_end_paint().
   *     If there was a temporary surface, this is composited back onto the
   *     real backing surface in the appropriate places.
   *
   * This is similar to double buffering, except we only have partial surfaces
   * of undefined contents, and instead of swapping between two buffers, we
   * create a new temporary buffer every time.
   *
   * When we add GL to the mix, we have this instead:
   *
   *  1) gdk_window_begin_paint_region() is called with an update region like
   *     before. We always redirect cairo drawing to a temporary surface when
   *     GL is enabled.
   *
   *  2) Things paint with cairo using gdk_cairo_create(). Whenever
   *     something paints, it calls gdk_window_mark_paint_from_clip() to mark
   *     which regions it has painted in software. We'll learn what this does
   *     soon.
   *
   *  3) Something paints with GL and uses gdk_cairo_draw_from_gl() to
   *     composite back into the scene. We paint this onto the backing
   *     store for the window *immediately* by using GL, rather than
   *     painting to the temporary surface, and keep track of the area that
   *     we've painted in `flushed_region`.
   *
   *  4) Something paints using software again. It calls
   *     gdk_window_mark_paint_from_clip(), which subtracts the region it
   *     has painted from `flushed_region` and adds the region to
   *     `needs_blended_region`.
   *
   *  5) Something paints using GL again, using gdk_cairo_draw_from_gl().
   *     It paints directly to the backing store, removes the region it
   *     painted from `needs_blended_region`, and adds to `flushed_region`.
   *
   *  6) gdk_window_end_paint() is called. It composites the temporary surface
   *     back to the window, using GL, except it doesn't bother copying
   *     `flushed_region`, and when it paints `needs_blended_region`, it also
   *     turns on GL blending.
   *
   * That means that at any point in time, we have three regions:
   *
   *   * `region` - This is the original invalidated region and is never
   *     touched.
   *
   *   * `flushed_region` - This is the portion of `region` that has GL
   *     contents that have been painted directly to the window, and
   *     doesn't have any cairo drawing painted over it.
   *
   *   * `needs_blended_region` - This is the portion of `region` that
   *     GL contents that have part cairo drawing painted over it.
   *     gdk_window_end_paint() will draw this region using blending.
   *
   * `flushed_region` and `needs_blended_region` never intersect, and the
   * rest of `region` that isn't covered by either is the "opaque region",
   * which is any area of cairo drawing that didn't ever intersect with GL.
   * We can paint these from GL without turning on blending.
   **/

298
  struct {
299 300 301
    /* The temporary surface that we're painting to. This will be composited
     * back into the window when we call end_paint. This is our poor-man's
     * way of doing double buffering. */
302
    cairo_surface_t *surface;
303

304
    cairo_region_t *region;
305 306 307
    cairo_region_t *flushed_region;
    cairo_region_t *need_blend_region;

308
    gboolean surface_needs_composite;
309
    gboolean use_gl;
310
  } current_paint;
311
  GdkGLContext *gl_paint_context;
312

313
  cairo_region_t *update_area;
314
  guint update_freeze_count;
315 316 317 318 319 320
  /* This is the update_area that was in effect when the current expose
     started. It may be smaller than the expose area if we'e painting
     more than we have to, but it represents the "true" damage. */
  cairo_region_t *active_update_area;
  /* We store the old expose areas to support buffer-age optimizations */
  cairo_region_t *old_updated_area[2];
321

322
  GdkWindowState old_state;
Matthias Clasen's avatar
Matthias Clasen committed
323
  GdkWindowState state;
324

325
  guint8 alpha;
Matthias Clasen's avatar
Matthias Clasen committed
326
  guint8 fullscreen_mode;
327

328
  guint input_only : 1;
329
  guint pass_through : 1;
330 331
  guint modal_hint : 1;
  guint composited : 1;
332
  guint has_alpha_background : 1;
333

334 335 336 337 338
  guint destroyed : 2;

  guint accept_focus : 1;
  guint focus_on_map : 1;
  guint shaped : 1;
339
  guint support_multidevice : 1;
340 341 342 343 344 345
  guint synthesize_crossing_event_queued : 1;
  guint effective_visibility : 2;
  guint visibility : 2; /* The visibility wrt the toplevel (i.e. based on clip_region) */
  guint native_visibility : 2; /* the native visibility of a impl windows */
  guint viewable : 1; /* mapped and all parents mapped */
  guint applied_shape : 1;
346
  guint in_update : 1;
347
  guint geometry_dirty : 1;
348
  guint event_compression : 1;
349
  guint frame_clock_events_paused : 1;
350

351
  /* The GdkWindow that has the impl, ref:ed if another window.
352 353
   * This ref is required to keep the wrapper of the impl window alive
   * for as long as any GdkWindow references the impl. */
354 355 356 357 358
  GdkWindow *impl_window;

  guint update_and_descendants_freeze_count;

  gint abs_x, abs_y; /* Absolute offset in impl */
359
  gint width, height;
360 361 362 363
  gint shadow_top;
  gint shadow_left;
  gint shadow_right;
  gint shadow_bottom;
364

Matthias Clasen's avatar
Matthias Clasen committed
365 366
  guint num_offscreen_children;

367 368 369 370 371
  /* The clip region is the part of the window, in window coordinates
     that is fully or partially (i.e. semi transparently) visible in
     the window hierarchy from the toplevel and down */
  cairo_region_t *clip_region;

372
  GdkCursor *cursor;
373
  GHashTable *device_cursor;
374

375 376
  cairo_region_t *shape;
  cairo_region_t *input_shape;
377

378 379
  GList *devices_inside;
  GHashTable *device_events;
380 381 382 383

  GHashTable *source_event_masks;
  gulong device_added_handler_id;
  gulong device_changed_handler_id;
384

Owen W. Taylor's avatar
Owen W. Taylor committed
385
  GdkFrameClock *frame_clock; /* NULL to use from parent or default */
386
  GdkWindowInvalidateHandlerFunc invalidate_handler;
Emmanuele Bassi's avatar
Emmanuele Bassi committed
387 388

  GdkDrawingContext *drawing_context;
389 390

  cairo_region_t *opaque_region;
391 392
};

393 394
#define GDK_WINDOW_TYPE(d) ((((GdkWindow *)(d)))->window_type)
#define GDK_WINDOW_DESTROYED(d) (((GdkWindow *)(d))->destroyed)
395

396
extern gchar     *_gdk_display_name;
397 398
extern gint       _gdk_screen_number;
extern gchar     *_gdk_display_arg_name;
Carlos Garnacho's avatar
Carlos Garnacho committed
399
extern gboolean   _gdk_disable_multidevice;
400 401

GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
402

403 404 405
void _gdk_event_filter_unref        (GdkWindow      *window,
				     GdkEventFilter *filter);

406 407
void     gdk_event_set_pointer_emulated (GdkEvent *event,
                                         gboolean  emulated);
408

409 410
void     gdk_event_set_scancode        (GdkEvent *event,
                                        guint16 scancode);
411

412 413 414
void     gdk_event_set_seat              (GdkEvent *event,
                                          GdkSeat  *seat);

415
void   _gdk_event_emit               (GdkEvent   *event);
416 417
GList* _gdk_event_queue_find_first   (GdkDisplay *display);
void   _gdk_event_queue_remove_link  (GdkDisplay *display,
418
                                      GList      *node);
419
GList* _gdk_event_queue_append       (GdkDisplay *display,
420
                                      GdkEvent   *event);
421 422 423 424 425 426
GList* _gdk_event_queue_insert_after (GdkDisplay *display,
                                      GdkEvent   *after_event,
                                      GdkEvent   *event);
GList* _gdk_event_queue_insert_before(GdkDisplay *display,
                                      GdkEvent   *after_event,
                                      GdkEvent   *event);
427 428

void    _gdk_event_queue_handle_motion_compression (GdkDisplay *display);
429
void    _gdk_event_queue_flush                     (GdkDisplay       *display);
430

431
void   _gdk_event_button_generate    (GdkDisplay *display,
432
                                      GdkEvent   *event);
433

434 435 436
void _gdk_windowing_event_data_copy (const GdkEvent *src,
                                     GdkEvent       *dst);
void _gdk_windowing_event_data_free (GdkEvent       *event);
437

438 439 440
void _gdk_set_window_state (GdkWindow *window,
                            GdkWindowState new_state);

441 442
gboolean        _gdk_cairo_surface_extents       (cairo_surface_t *surface,
                                                  GdkRectangle    *extents);
443 444
void            gdk_gl_texture_from_surface      (cairo_surface_t *surface,
                                                  cairo_region_t  *region);
445 446 447 448 449 450

typedef struct {
  float x1, y1, x2, y2;
  float u1, v1, u2, v2;
} GdkTexturedQuad;

451 452 453
void           gdk_gl_texture_quads               (GdkGLContext *paint_context,
                                                   guint texture_target,
                                                   int n_quads,
454 455
                                                   GdkTexturedQuad *quads,
                                                   gboolean flip_colors);
456

457 458
void            gdk_cairo_surface_mark_as_direct (cairo_surface_t *surface,
                                                  GdkWindow       *window);
459 460
cairo_region_t *gdk_cairo_region_from_clip       (cairo_t         *cr);

461 462
void            gdk_cairo_set_drawing_context    (cairo_t           *cr,
                                                  GdkDrawingContext *context);
463

464 465 466 467
/*************************************
 * Interfaces used by windowing code *
 *************************************/

468 469 470
cairo_surface_t *
           _gdk_window_ref_cairo_surface (GdkWindow *window);

471 472 473 474
void       _gdk_window_destroy           (GdkWindow      *window,
                                          gboolean        foreign_destroy);
void       _gdk_window_clear_update_area (GdkWindow      *window);
void       _gdk_window_update_size       (GdkWindow      *window);
475
gboolean   _gdk_window_update_viewable   (GdkWindow      *window);
476 477
GdkGLContext * gdk_window_get_paint_gl_context (GdkWindow *window,
                                                GError   **error);
478 479 480
void gdk_window_get_unscaled_size (GdkWindow *window,
                                   int *unscaled_width,
                                   int *unscaled_height);
481

Emmanuele Bassi's avatar
Emmanuele Bassi committed
482 483
GdkDrawingContext *gdk_window_get_drawing_context (GdkWindow *window);

484 485
cairo_region_t *gdk_window_get_current_paint_region (GdkWindow *window);

486
void       _gdk_window_process_updates_recurse (GdkWindow *window,
487
                                                cairo_region_t *expose_region);
488

489 490
void       _gdk_screen_set_resolution    (GdkScreen      *screen,
                                          gdouble         dpi);
491
void       _gdk_screen_close             (GdkScreen      *screen);
492 493 494 495 496 497 498 499 500

/*****************************************
 * Interfaces provided by windowing code *
 *****************************************/

/* Font/string functions implemented in module-specific code */

void _gdk_cursor_destroy (GdkCursor *cursor);

501
extern const GOptionEntry _gdk_windowing_args[];
502

503
void _gdk_windowing_got_event                (GdkDisplay       *display,
504 505 506
                                              GList            *event_link,
                                              GdkEvent         *event,
                                              gulong            serial);
507

508
#define GDK_WINDOW_IS_MAPPED(window) (((window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0)
509

510
void _gdk_window_invalidate_for_expose (GdkWindow       *window,
511
                                        cairo_region_t       *region);
512

513
GdkWindow * _gdk_window_find_child_at (GdkWindow *window,
514
                                       double x, double y);
515
GdkWindow * _gdk_window_find_descendant_at (GdkWindow *toplevel,
516 517 518
                                            double x, double y,
                                            double *found_x,
                                            double *found_y);
519 520

GdkEvent * _gdk_make_event (GdkWindow    *window,
521 522 523
                            GdkEventType  type,
                            GdkEvent     *event_in_queue,
                            gboolean      before_event);
524 525
gboolean _gdk_window_event_parent_of (GdkWindow *parent,
                                      GdkWindow *child);
526

527
void _gdk_synthesize_crossing_events (GdkDisplay                 *display,
528 529
                                      GdkWindow                  *src,
                                      GdkWindow                  *dest,
530
                                      GdkDevice                  *device,
531
                                      GdkDevice                  *source_device,
532
				      GdkCrossingMode             mode,
533 534
				      gdouble                     toplevel_x,
				      gdouble                     toplevel_y,
535 536 537 538 539
				      GdkModifierType             mask,
				      guint32                     time_,
				      GdkEvent                   *event_in_queue,
				      gulong                      serial,
				      gboolean                    non_linear);
Alexander Larsson's avatar
Alexander Larsson committed
540
void _gdk_display_set_window_under_pointer (GdkDisplay *display,
541
                                            GdkDevice  *device,
542
                                            GdkWindow  *window);
Alexander Larsson's avatar
Alexander Larsson committed
543

544

545
void _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window);
546 547 548 549 550 551 552 553 554

gboolean    _gdk_window_has_impl (GdkWindow *window);
GdkWindow * _gdk_window_get_impl_window (GdkWindow *window);

/*****************************
 * offscreen window routines *
 *****************************/
GType gdk_offscreen_window_get_type (void);
void       _gdk_offscreen_window_new                 (GdkWindow     *window,
555 556
                                                      GdkWindowAttr *attributes,
                                                      gint           attributes_mask);
557 558 559
cairo_surface_t * _gdk_offscreen_window_create_surface (GdkWindow *window,
                                                        gint       width,
                                                        gint       height);
560

561
G_END_DECLS
562 563

#endif /* __GDK_INTERNALS_H__ */