1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdk.Surface;
26 
27 private import cairo.Region;
28 private import cairo.Surface : CairoSurface = Surface;
29 private import gdk.CairoContext;
30 private import gdk.Cursor;
31 private import gdk.Device;
32 private import gdk.Display;
33 private import gdk.Event;
34 private import gdk.FrameClock;
35 private import gdk.GLContext;
36 private import gdk.MonitorGdk;
37 private import gdk.VulkanContext;
38 private import gdk.c.functions;
39 public  import gdk.c.types;
40 private import glib.ConstructionException;
41 private import glib.ErrorG;
42 private import glib.GException;
43 private import gobject.ObjectG;
44 private import gobject.Signals;
45 private import std.algorithm;
46 
47 
48 /**
49  * A `GdkSurface` is a rectangular region on the screen.
50  * 
51  * It’s a low-level object, used to implement high-level objects
52  * such as [class@Gtk.Window] or [class@Gtk.Dialog] in GTK.
53  * 
54  * The surfaces you see in practice are either [class@Gdk.Toplevel] or
55  * [class@Gdk.Popup], and those interfaces provide much of the required
56  * API to interact with these surfaces. Other, more specialized surface
57  * types exist, but you will rarely interact with them directly.
58  */
59 public class Surface : ObjectG
60 {
61 	/** the main Gtk struct */
62 	protected GdkSurface* gdkSurface;
63 
64 	/** Get the main Gtk struct */
65 	public GdkSurface* getSurfaceStruct(bool transferOwnership = false)
66 	{
67 		if (transferOwnership)
68 			ownedRef = false;
69 		return gdkSurface;
70 	}
71 
72 	/** the main Gtk struct as a void* */
73 	protected override void* getStruct()
74 	{
75 		return cast(void*)gdkSurface;
76 	}
77 
78 	/**
79 	 * Sets our main struct and passes it to the parent class.
80 	 */
81 	public this (GdkSurface* gdkSurface, bool ownedRef = false)
82 	{
83 		this.gdkSurface = gdkSurface;
84 		super(cast(GObject*)gdkSurface, ownedRef);
85 	}
86 
87 
88 	/** */
89 	public static GType getType()
90 	{
91 		return gdk_surface_get_type();
92 	}
93 
94 	/**
95 	 * Create a new popup surface.
96 	 *
97 	 * The surface will be attached to @parent and can be positioned
98 	 * relative to it using [method@Gdk.Popup.present].
99 	 *
100 	 * Params:
101 	 *     parent = the parent surface to attach the surface to
102 	 *     autohide = whether to hide the surface on outside clicks
103 	 *
104 	 * Returns: a new `GdkSurface`
105 	 *
106 	 * Throws: ConstructionException GTK+ fails to create the object.
107 	 */
108 	public this(Surface parent, bool autohide)
109 	{
110 		auto __p = gdk_surface_new_popup((parent is null) ? null : parent.getSurfaceStruct(), autohide);
111 
112 		if(__p is null)
113 		{
114 			throw new ConstructionException("null returned by new_popup");
115 		}
116 
117 		this(cast(GdkSurface*) __p, true);
118 	}
119 
120 	/**
121 	 * Creates a new toplevel surface.
122 	 *
123 	 * Params:
124 	 *     display = the display to create the surface on
125 	 *
126 	 * Returns: the new `GdkSurface`
127 	 *
128 	 * Throws: ConstructionException GTK+ fails to create the object.
129 	 */
130 	public this(Display display)
131 	{
132 		auto __p = gdk_surface_new_toplevel((display is null) ? null : display.getDisplayStruct());
133 
134 		if(__p is null)
135 		{
136 			throw new ConstructionException("null returned by new_toplevel");
137 		}
138 
139 		this(cast(GdkSurface*) __p, true);
140 	}
141 
142 	/**
143 	 * Emits a short beep associated to @surface.
144 	 *
145 	 * If the display of @surface does not support per-surface beeps,
146 	 * emits a short beep on the display just as [method@Gdk.Display.beep].
147 	 */
148 	public void beep()
149 	{
150 		gdk_surface_beep(gdkSurface);
151 	}
152 
153 	/**
154 	 * Creates a new `GdkCairoContext` for rendering on @surface.
155 	 *
156 	 * Returns: the newly created `GdkCairoContext`
157 	 */
158 	public CairoContext createCairoContext()
159 	{
160 		auto __p = gdk_surface_create_cairo_context(gdkSurface);
161 
162 		if(__p is null)
163 		{
164 			return null;
165 		}
166 
167 		return ObjectG.getDObject!(CairoContext)(cast(GdkCairoContext*) __p, true);
168 	}
169 
170 	/**
171 	 * Creates a new `GdkGLContext` for the `GdkSurface`.
172 	 *
173 	 * The context is disconnected from any particular surface or surface.
174 	 * If the creation of the `GdkGLContext` failed, @error will be set.
175 	 * Before using the returned `GdkGLContext`, you will need to
176 	 * call [method@Gdk.GLContext.make_current] or [method@Gdk.GLContext.realize].
177 	 *
178 	 * Returns: the newly created `GdkGLContext`,
179 	 *     or %NULL on error
180 	 *
181 	 * Throws: GException on failure.
182 	 */
183 	public GLContext createGlContext()
184 	{
185 		GError* err = null;
186 
187 		auto __p = gdk_surface_create_gl_context(gdkSurface, &err);
188 
189 		if (err !is null)
190 		{
191 			throw new GException( new ErrorG(err) );
192 		}
193 
194 		if(__p is null)
195 		{
196 			return null;
197 		}
198 
199 		return ObjectG.getDObject!(GLContext)(cast(GdkGLContext*) __p, true);
200 	}
201 
202 	/**
203 	 * Create a new Cairo surface that is as compatible as possible with the
204 	 * given @surface.
205 	 *
206 	 * For example the new surface will have the same fallback resolution
207 	 * and font options as @surface. Generally, the new surface will also
208 	 * use the same backend as @surface, unless that is not possible for
209 	 * some reason. The type of the returned surface may be examined with
210 	 * cairo_surface_get_type().
211 	 *
212 	 * Initially the surface contents are all 0 (transparent if contents
213 	 * have transparency, black otherwise.)
214 	 *
215 	 * This function always returns a valid pointer, but it will return a
216 	 * pointer to a “nil” surface if @other is already in an error state
217 	 * or any other error occurs.
218 	 *
219 	 * Params:
220 	 *     content = the content for the new surface
221 	 *     width = width of the new surface
222 	 *     height = height of the new surface
223 	 *
224 	 * Returns: a pointer to the newly allocated surface. The caller
225 	 *     owns the surface and should call cairo_surface_destroy() when done
226 	 *     with it.
227 	 */
228 	public CairoSurface createSimilarSurface(cairo_content_t content, int width, int height)
229 	{
230 		auto __p = gdk_surface_create_similar_surface(gdkSurface, content, width, height);
231 
232 		if(__p is null)
233 		{
234 			return null;
235 		}
236 
237 		return new CairoSurface(cast(cairo_surface_t*) __p);
238 	}
239 
240 	/**
241 	 * Creates a new `GdkVulkanContext` for rendering on @surface.
242 	 *
243 	 * If the creation of the `GdkVulkanContext` failed, @error will be set.
244 	 *
245 	 * Returns: the newly created `GdkVulkanContext`, or
246 	 *     %NULL on error
247 	 *
248 	 * Throws: GException on failure.
249 	 */
250 	public VulkanContext createVulkanContext()
251 	{
252 		GError* err = null;
253 
254 		auto __p = gdk_surface_create_vulkan_context(gdkSurface, &err);
255 
256 		if (err !is null)
257 		{
258 			throw new GException( new ErrorG(err) );
259 		}
260 
261 		if(__p is null)
262 		{
263 			return null;
264 		}
265 
266 		return ObjectG.getDObject!(VulkanContext)(cast(GdkVulkanContext*) __p, true);
267 	}
268 
269 	/**
270 	 * Destroys the window system resources associated with @surface and
271 	 * decrements @surface's reference count.
272 	 *
273 	 * The window system resources for all children of @surface are also
274 	 * destroyed, but the children’s reference counts are not decremented.
275 	 *
276 	 * Note that a surface will not be destroyed automatically when its
277 	 * reference count reaches zero. You must call this function yourself
278 	 * before that happens.
279 	 */
280 	public void destroy()
281 	{
282 		gdk_surface_destroy(gdkSurface);
283 	}
284 
285 	/**
286 	 * Retrieves a `GdkCursor` pointer for the cursor currently set on the
287 	 * `GdkSurface`.
288 	 *
289 	 * If the return value is %NULL then there is no custom cursor set on
290 	 * the surface, and it is using the cursor for its parent surface.
291 	 *
292 	 * Returns: a `GdkCursor`, or %NULL. The
293 	 *     returned object is owned by the `GdkSurface` and should not be
294 	 *     unreferenced directly. Use [method@Gdk.Surface.set_cursor] to
295 	 *     unset the cursor of the surface
296 	 */
297 	public Cursor getCursor()
298 	{
299 		auto __p = gdk_surface_get_cursor(gdkSurface);
300 
301 		if(__p is null)
302 		{
303 			return null;
304 		}
305 
306 		return ObjectG.getDObject!(Cursor)(cast(GdkCursor*) __p);
307 	}
308 
309 	/**
310 	 * Retrieves a `GdkCursor` pointer for the @device currently set on the
311 	 * specified `GdkSurface`.
312 	 *
313 	 * If the return value is %NULL then there is no custom cursor set on the
314 	 * specified surface, and it is using the cursor for its parent surface.
315 	 *
316 	 * Params:
317 	 *     device = a pointer `GdkDevice`
318 	 *
319 	 * Returns: a `GdkCursor`, or %NULL. The
320 	 *     returned object is owned by the `GdkSurface` and should not be
321 	 *     unreferenced directly. Use [method@Gdk.Surface.set_cursor] to unset
322 	 *     the cursor of the surface
323 	 */
324 	public Cursor getDeviceCursor(Device device)
325 	{
326 		auto __p = gdk_surface_get_device_cursor(gdkSurface, (device is null) ? null : device.getDeviceStruct());
327 
328 		if(__p is null)
329 		{
330 			return null;
331 		}
332 
333 		return ObjectG.getDObject!(Cursor)(cast(GdkCursor*) __p);
334 	}
335 
336 	/**
337 	 * Obtains the current device position and modifier state.
338 	 *
339 	 * The position is given in coordinates relative to the upper
340 	 * left corner of @surface.
341 	 *
342 	 * Params:
343 	 *     device = pointer `GdkDevice` to query to
344 	 *     x = return locatio for the X coordinate of @device, or %NULL
345 	 *     y = return location for the Y coordinate of @device, or %NULL
346 	 *     mask = return location for the modifier mask, or %NULL
347 	 *
348 	 * Returns: %TRUE if the device is over the surface
349 	 */
350 	public bool getDevicePosition(Device device, out double x, out double y, out GdkModifierType mask)
351 	{
352 		return gdk_surface_get_device_position(gdkSurface, (device is null) ? null : device.getDeviceStruct(), &x, &y, &mask) != 0;
353 	}
354 
355 	/**
356 	 * Gets the `GdkDisplay` associated with a `GdkSurface`.
357 	 *
358 	 * Returns: the `GdkDisplay` associated with @surface
359 	 */
360 	public Display getDisplay()
361 	{
362 		auto __p = gdk_surface_get_display(gdkSurface);
363 
364 		if(__p is null)
365 		{
366 			return null;
367 		}
368 
369 		return ObjectG.getDObject!(Display)(cast(GdkDisplay*) __p);
370 	}
371 
372 	/**
373 	 * Gets the frame clock for the surface.
374 	 *
375 	 * The frame clock for a surface never changes unless the surface is
376 	 * reparented to a new toplevel surface.
377 	 *
378 	 * Returns: the frame clock
379 	 */
380 	public FrameClock getFrameClock()
381 	{
382 		auto __p = gdk_surface_get_frame_clock(gdkSurface);
383 
384 		if(__p is null)
385 		{
386 			return null;
387 		}
388 
389 		return ObjectG.getDObject!(FrameClock)(cast(GdkFrameClock*) __p);
390 	}
391 
392 	/**
393 	 * Returns the height of the given @surface.
394 	 *
395 	 * Surface size is reported in ”application pixels”, not
396 	 * ”device pixels” (see [method@Gdk.Surface.get_scale_factor]).
397 	 *
398 	 * Returns: The height of @surface
399 	 */
400 	public int getHeight()
401 	{
402 		return gdk_surface_get_height(gdkSurface);
403 	}
404 
405 	/**
406 	 * Checks whether the surface has been mapped.
407 	 *
408 	 * A surface is mapped with [method@Gdk.Toplevel.present]
409 	 * or [method@Gdk.Popup.present].
410 	 *
411 	 * Returns: %TRUE if the surface is mapped
412 	 */
413 	public bool getMapped()
414 	{
415 		return gdk_surface_get_mapped(gdkSurface) != 0;
416 	}
417 
418 	/**
419 	 * Returns the internal scale factor that maps from surface coordinates
420 	 * to the actual device pixels.
421 	 *
422 	 * On traditional systems this is 1, but on very high density outputs
423 	 * this can be a higher value (often 2). A higher value means that drawing
424 	 * is automatically scaled up to a higher resolution, so any code doing
425 	 * drawing will automatically look nicer. However, if you are supplying
426 	 * pixel-based data the scale value can be used to determine whether to
427 	 * use a pixel resource with higher resolution data.
428 	 *
429 	 * The scale of a surface may change during runtime.
430 	 *
431 	 * Returns: the scale factor
432 	 */
433 	public int getScaleFactor()
434 	{
435 		return gdk_surface_get_scale_factor(gdkSurface);
436 	}
437 
438 	/**
439 	 * Returns the width of the given @surface.
440 	 *
441 	 * Surface size is reported in ”application pixels”, not
442 	 * ”device pixels” (see [method@Gdk.Surface.get_scale_factor]).
443 	 *
444 	 * Returns: The width of @surface
445 	 */
446 	public int getWidth()
447 	{
448 		return gdk_surface_get_width(gdkSurface);
449 	}
450 
451 	/**
452 	 * Hide the surface.
453 	 *
454 	 * For toplevel surfaces, withdraws them, so they will no longer be
455 	 * known to the window manager; for all surfaces, unmaps them, so
456 	 * they won’t be displayed. Normally done automatically as
457 	 * part of [method@Gtk.Widget.hide].
458 	 */
459 	public void hide()
460 	{
461 		gdk_surface_hide(gdkSurface);
462 	}
463 
464 	/**
465 	 * Check to see if a surface is destroyed.
466 	 *
467 	 * Returns: %TRUE if the surface is destroyed
468 	 */
469 	public bool isDestroyed()
470 	{
471 		return gdk_surface_is_destroyed(gdkSurface) != 0;
472 	}
473 
474 	/**
475 	 * Forces a [signal@Gdk.Surface::render] signal emission for @surface
476 	 * to be scheduled.
477 	 *
478 	 * This function is useful for implementations that track invalid
479 	 * regions on their own.
480 	 */
481 	public void queueRender()
482 	{
483 		gdk_surface_queue_render(gdkSurface);
484 	}
485 
486 	/**
487 	 * Request a layout phase from the surface's frame clock.
488 	 *
489 	 * See [method@Gdk.FrameClock.request_phase].
490 	 */
491 	public void requestLayout()
492 	{
493 		gdk_surface_request_layout(gdkSurface);
494 	}
495 
496 	/**
497 	 * Sets the default mouse pointer for a `GdkSurface`.
498 	 *
499 	 * Passing %NULL for the @cursor argument means that @surface will use
500 	 * the cursor of its parent surface. Most surfaces should use this default.
501 	 * Note that @cursor must be for the same display as @surface.
502 	 *
503 	 * Use [ctor@Gdk.Cursor.new_from_name] or [ctor@Gdk.Cursor.new_from_texture]
504 	 * to create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR.
505 	 *
506 	 * Params:
507 	 *     cursor = a `GdkCursor`
508 	 */
509 	public void setCursor(Cursor cursor)
510 	{
511 		gdk_surface_set_cursor(gdkSurface, (cursor is null) ? null : cursor.getCursorStruct());
512 	}
513 
514 	/**
515 	 * Sets a specific `GdkCursor` for a given device when it gets inside @surface.
516 	 *
517 	 * Passing %NULL for the @cursor argument means that @surface will use the
518 	 * cursor of its parent surface. Most surfaces should use this default.
519 	 *
520 	 * Use [ctor@Gdk.Cursor.new_from_name] or [ctor@Gdk.Cursor.new_from_texture]
521 	 * to create the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR.
522 	 *
523 	 * Params:
524 	 *     device = a pointer `GdkDevice`
525 	 *     cursor = a `GdkCursor`
526 	 */
527 	public void setDeviceCursor(Device device, Cursor cursor)
528 	{
529 		gdk_surface_set_device_cursor(gdkSurface, (device is null) ? null : device.getDeviceStruct(), (cursor is null) ? null : cursor.getCursorStruct());
530 	}
531 
532 	/**
533 	 * Apply the region to the surface for the purpose of event
534 	 * handling.
535 	 *
536 	 * Mouse events which happen while the pointer position corresponds
537 	 * to an unset bit in the mask will be passed on the surface below
538 	 * @surface.
539 	 *
540 	 * An input region is typically used with RGBA surfaces. The alpha
541 	 * channel of the surface defines which pixels are invisible and
542 	 * allows for nicely antialiased borders, and the input region
543 	 * controls where the surface is “clickable”.
544 	 *
545 	 * Use [method@Gdk.Display.supports_input_shapes] to find out if
546 	 * a particular backend supports input regions.
547 	 *
548 	 * Params:
549 	 *     region = region of surface to be reactive
550 	 */
551 	public void setInputRegion(Region region)
552 	{
553 		gdk_surface_set_input_region(gdkSurface, (region is null) ? null : region.getRegionStruct());
554 	}
555 
556 	/**
557 	 * Marks a region of the `GdkSurface` as opaque.
558 	 *
559 	 * For optimisation purposes, compositing window managers may
560 	 * like to not draw obscured regions of surfaces, or turn off blending
561 	 * during for these regions. With RGB windows with no transparency,
562 	 * this is just the shape of the window, but with ARGB32 windows, the
563 	 * compositor does not know what regions of the window are transparent
564 	 * or not.
565 	 *
566 	 * This function only works for toplevel surfaces.
567 	 *
568 	 * GTK will update this property automatically if the @surface background
569 	 * is opaque, as we know where the opaque regions are. If your surface
570 	 * background is not opaque, please update this property in your
571 	 * #GtkWidgetClass.css_changed() handler.
572 	 *
573 	 * Params:
574 	 *     region = a region, or %NULL
575 	 */
576 	public void setOpaqueRegion(Region region)
577 	{
578 		gdk_surface_set_opaque_region(gdkSurface, (region is null) ? null : region.getRegionStruct());
579 	}
580 
581 	/**
582 	 * Translates coordinates between two surfaces.
583 	 *
584 	 * Note that this only works if @to and @from are popups or
585 	 * transient-for to the same toplevel (directly or indirectly).
586 	 *
587 	 * Params:
588 	 *     to = the target surface
589 	 *     x = coordinates to translate
590 	 *     y = coordinates to translate
591 	 *
592 	 * Returns: %TRUE if the coordinates were successfully translated
593 	 */
594 	public bool translateCoordinates(Surface to, ref double x, ref double y)
595 	{
596 		return gdk_surface_translate_coordinates(gdkSurface, (to is null) ? null : to.getSurfaceStruct(), &x, &y) != 0;
597 	}
598 
599 	/**
600 	 * Emitted when @surface starts being present on the monitor.
601 	 *
602 	 * Params:
603 	 *     monitor = the monitor
604 	 */
605 	gulong addOnEnterMonitor(void delegate(MonitorGdk, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
606 	{
607 		return Signals.connect(this, "enter-monitor", dlg, connectFlags ^ ConnectFlags.SWAPPED);
608 	}
609 
610 	/**
611 	 * Emitted when GDK receives an input event for @surface.
612 	 *
613 	 * Params:
614 	 *     event = an input event
615 	 *
616 	 * Returns: %TRUE to indicate that the event has been handled
617 	 */
618 	gulong addOnEvent(bool delegate(Event, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
619 	{
620 		return Signals.connect(this, "event", dlg, connectFlags ^ ConnectFlags.SWAPPED);
621 	}
622 
623 	/**
624 	 * Emitted when the size of @surface is changed, or when relayout should
625 	 * be performed.
626 	 *
627 	 * Surface size is reported in ”application pixels”, not
628 	 * ”device pixels” (see gdk_surface_get_scale_factor()).
629 	 *
630 	 * Params:
631 	 *     width = the current width
632 	 *     height = the current height
633 	 */
634 	gulong addOnLayout(void delegate(int, int, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
635 	{
636 		return Signals.connect(this, "layout", dlg, connectFlags ^ ConnectFlags.SWAPPED);
637 	}
638 
639 	/**
640 	 * Emitted when @surface stops being present on the monitor.
641 	 *
642 	 * Params:
643 	 *     monitor = the monitor
644 	 */
645 	gulong addOnLeaveMonitor(void delegate(MonitorGdk, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
646 	{
647 		return Signals.connect(this, "leave-monitor", dlg, connectFlags ^ ConnectFlags.SWAPPED);
648 	}
649 
650 	/**
651 	 * Emitted when part of the surface needs to be redrawn.
652 	 *
653 	 * Params:
654 	 *     region = the region that needs to be redrawn
655 	 *
656 	 * Returns: %TRUE to indicate that the signal has been handled
657 	 */
658 	gulong addOnRender(bool delegate(Region, Surface) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
659 	{
660 		return Signals.connect(this, "render", dlg, connectFlags ^ ConnectFlags.SWAPPED);
661 	}
662 }