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 }