1{%MainUnit gtkproc.pp}{%MainUnit gtkint.pp} 2{ $Id$ } 3{ 4 ***************************************************************************** 5 This file is part of the Lazarus Component Library (LCL) 6 7 See the file COPYING.modifiedLGPL.txt, included in this distribution, 8 for details about the license. 9 ***************************************************************************** 10} 11 12function G_OBJECT(p: Pointer): PGtkObject; 13begin 14 Result:=PGtkObject(p); 15end; 16 17function G_CALLBACK(p: Pointer): TGTKSignalFunc; 18begin 19 Result:=TGTKSignalFunc(p); 20end; 21 22function GDK_GET_CURRENT_DESKTOP(): gint; 23var 24 XDisplay: PDisplay; 25 XScreen: PScreen; 26 XWindow: TWindow; 27 AtomType: x.TAtom; 28 Format: gint; 29 nitems: gulong; 30 bytes_after: gulong; 31 current_desktop: pguint; 32begin 33 Result := -1; 34 35 xdisplay := gdk_display; 36 xscreen := XDefaultScreenOfDisplay(xdisplay); 37 xwindow := XRootWindowOfScreen(xscreen); 38 39 XGetWindowProperty (xdisplay, xwindow, 40 XInternAtom(xdisplay, '_NET_CURRENT_DESKTOP', false), 41 0, MaxInt, False, XA_CARDINAL, @atomtype, @format, @nitems, 42 @bytes_after, gpointer(@current_desktop)); 43 44 if (atomtype = XA_CARDINAL) and (format = 32) and (nitems > 0) then 45 Result := current_desktop[0]; 46 if current_desktop <> nil then 47 XFree (current_desktop); 48end; 49 50 51function GDK_WINDOW_GET_DESKTOP(Window: PGdkWindowPrivate): gint; 52var 53 xdisplay: PDisplay; 54 xwindow: TWindow; 55 56 atomtype: x.TAtom; 57 format: gint; 58 nitems: gulong; 59 bytes_after: gulong; 60 current_desktop: pguint; 61begin 62 Result := -1; 63 XWindow := GDK_WINDOW_XWINDOW (Window); 64 XDisplay := GDK_WINDOW_XDISPLAY (Window); 65 XGetWindowProperty (xdisplay, xwindow, 66 XInternAtom(xdisplay, '_NET_WM_DESKTOP', false), 67 0, MaxInt, False, XA_CARDINAL, @atomtype, @format, @nitems, 68 @bytes_after, gpointer(@current_desktop)); 69 70 if (atomtype = XA_CARDINAL) and (format = 32) and (nitems > 0) then 71 Result := current_desktop[0]; 72 if current_desktop <> nil then 73 XFree (current_desktop); 74end; 75 76function GDK_WINDOW_SET_DESKTOP(Window: PGdkWindowPrivate; Desktop: gint): gint; 77var 78 XDisplay: PDisplay; 79 XScreen: PScreen; 80 XRootWindow, 81 XWindow: TWindow; 82 XEvent: TXClientMessageEvent; 83 _NET_WM_DESKTOP: Integer; 84begin 85 86 Result := -1; 87 88 XDisplay := GDK_WINDOW_XDISPLAY (Window); 89 XScreen := XDefaultScreenOfDisplay(xdisplay); 90 XRootWindow := XRootWindowOfScreen(xscreen); 91 XWindow := GDK_WINDOW_XWINDOW (Window); 92 93 _NET_WM_DESKTOP := XInternAtom(xdisplay, '_NET_WM_DESKTOP', false); 94 95 XEvent._type := ClientMessage; 96 XEvent.window := XWindow; 97 XEvent.message_type := _NET_WM_DESKTOP; 98 XEvent.format := 32; 99 XEvent.data.l[0] := Desktop; 100 101 XSendEvent(XDisplay, XRootWindow, False, SubstructureNotifyMask, PXEvent(@XEvent)); 102end; 103 104 105procedure GDK_WINDOW_ACTIVATE(Window: PGdkWindowPrivate); 106var 107 XDisplay: PDisplay; 108 XScreen: PScreen; 109 aXRootWindow, 110 XWindow: x.TWindow; 111 XEvent: xlib.TXClientMessageEvent; 112 _NET_ACTIVE_WINDOW: Integer; 113begin 114 if (Window=nil) or (gdk.destroyed(Window^)<>0) then exit; 115 116 XDisplay := GDK_WINDOW_XDISPLAY (Window); 117 if XDisplay=nil then exit; 118 XScreen := XDefaultScreenOfDisplay(xdisplay); 119 if XScreen=nil then exit; 120 aXRootWindow := XRootWindowOfScreen(xscreen); 121 if aXRootWindow=0 then exit; 122 XWindow := GDK_WINDOW_XWINDOW (Window); 123 if XWindow=0 then exit; 124 125 _NET_ACTIVE_WINDOW := XInternAtom(xdisplay, '_NET_ACTIVE_WINDOW', false); 126 127 XEvent._type := ClientMessage; 128 XEvent.window := XWindow; 129 XEvent.message_type := _NET_ACTIVE_WINDOW; 130 XEvent.format := 32; 131 XEvent.data.l[0] := 1; //Message is from program 132 XEvent.data.l[1] := CurrentTime; 133 XEvent.data.l[2] := 0; // Applications current active window 134 135 XSendEvent(XDisplay, aXRootWindow, False, SubstructureNotifyMask, PXEvent(@XEvent)); 136end; 137 138procedure GDK_WINDOW_MAXIMIZE(Window: PGdkWindowPrivate); 139const 140 _NET_WM_STATE_REMOVE = 0; // remove/unset property 141 _NET_WM_STATE_ADD = 1; // add/set property 142 _NET_WM_STATE_TOGGLE = 2; // toggle property 143var 144 XDisplay: PDisplay; 145 XScreen: PScreen; 146 aXRootWindow, 147 XWindow: TWindow; 148 XEvent: TXClientMessageEvent; 149 _NET_WM_STATE, 150 _NET_WM_STATE_MAXIMIZED_VERT, 151 _NET_WM_STATE_MAXIMIZED_HORZ: Integer; 152 153begin 154 XDisplay := GDK_WINDOW_XDISPLAY (Window); 155 XScreen := XDefaultScreenOfDisplay(xdisplay); 156 aXRootWindow := XRootWindowOfScreen(xscreen); 157 XWindow := GDK_WINDOW_XWINDOW (Window); 158 159 _NET_WM_STATE := XInternAtom(xdisplay, '_NET_WM_STATE', false); 160 _NET_WM_STATE_MAXIMIZED_VERT := XInternAtom(xdisplay, '_NET_WM_STATE_MAXIMIZED_VERT', false); 161 _NET_WM_STATE_MAXIMIZED_HORZ := XInternAtom(xdisplay, '_NET_WM_STATE_MAXIMIZED_HORZ', false); 162 163 XEvent._type := ClientMessage; 164 XEvent.window := XWindow; 165 XEvent.message_type := _NET_WM_STATE; 166 XEvent.format := 32; 167 XEvent.data.l[0] := _NET_WM_STATE_ADD; 168 XEvent.data.l[1] := _NET_WM_STATE_MAXIMIZED_HORZ; 169 XEvent.data.l[2] := _NET_WM_STATE_MAXIMIZED_VERT; 170 171 XSendEvent(XDisplay, aXRootWindow, False, SubstructureNotifyMask, PXEvent(@XEvent)); 172end; 173 174function GDK_WINDOW_GET_MINIMIZED(Window: PGdkWindowPrivate): gboolean; 175const 176 _NET_WM_STATE_REMOVE = 0; // remove/unset property 177 _NET_WM_STATE_ADD = 1; // add/set property 178 _NET_WM_STATE_TOGGLE = 2; // toggle property 179var 180 XDisplay: PDisplay; 181 XWindow: x.TWindow; 182 _NET_WM_STATE, 183 _NET_WM_STATE_HIDDEN: Integer; 184 atomtype: x.TAtom; 185 format: gint; 186 nitems: gulong; 187 bytes_after: gulong; 188 state_array: pguint; 189 X: Integer; 190begin 191 Result := False; 192 XDisplay := GDK_WINDOW_XDISPLAY(Window); 193 XWindow := GDK_WINDOW_XWINDOW(Window); 194 195 _NET_WM_STATE := XInternAtom(XDisplay, '_NET_WM_STATE', False); 196 _NET_WM_STATE_HIDDEN := XInternAtom(XDisplay, '_NET_WM_STATE_HIDDEN', False); 197 198 XGetWindowProperty(XDisplay, XWindow, _NET_WM_STATE, 199 0, MaxInt, False, XA_ATOM, @atomtype, @format, @nitems, 200 @bytes_after, @state_array); 201 if (atomtype = XA_ATOM) and (format = 32) and (nitems > 0) then 202 begin 203 // Check to see if the window is already minimized... 204 for X := 0 to nitems - 1 do 205 begin 206 if (state_array[X] = _NET_WM_STATE_HIDDEN) then 207 begin 208 XFree(state_array); 209 Exit(True); 210 end; 211 end; 212 end; 213 if state_array <> nil then 214 XFree(state_array); 215end; 216 217procedure GDK_WINDOW_MINIMIZE(Window: PGdkWindowPrivate); 218var 219 XDisplay: PDisplay; 220 XScreen: PScreen; 221 XWindow: x.TWindow; 222begin 223 if GDK_WINDOW_GET_MINIMIZED(Window) then 224 Exit; 225 226 XDisplay := GDK_WINDOW_XDISPLAY(Window); 227 XScreen := XDefaultScreenOfDisplay(XDisplay); 228 XWindow := GDK_WINDOW_XWINDOW(Window); 229 230 XIconifyWindow(XDisplay, XWindow, XScreenNumberOfScreen(XScreen)); 231end; 232 233function GDK_WINDOW_GET_MAXIMIZED(Window: PGdkWindowPrivate): gboolean; 234var 235 xdisplay: PDisplay; 236 xwindow: TWindow; 237 238 atomtype: x.TAtom; 239 format: gint; 240 nitems: gulong; 241 bytes_after: gulong; 242 state_array: pguint; 243 _NET_WM_STATE, 244 _NET_WM_STATE_MAXIMIZED_VERT, 245 _NET_WM_STATE_MAXIMIZED_HORZ: x.TAtom; 246 X: Integer; 247 maximized_horz, maximized_vert: Boolean; 248begin 249 Result := False; 250 XWindow := GDK_WINDOW_XWINDOW(Window); 251 XDisplay := GDK_WINDOW_XDISPLAY(Window); 252 253 _NET_WM_STATE := XInternAtom(XDisplay, '_NET_WM_STATE', False); 254 _NET_WM_STATE_MAXIMIZED_VERT := XInternAtom(XDisplay, '_NET_WM_STATE_MAXIMIZED_VERT', False); 255 _NET_WM_STATE_MAXIMIZED_HORZ := XInternAtom(XDisplay, '_NET_WM_STATE_MAXIMIZED_HORZ', False); 256 257 XGetWindowProperty (xdisplay, xwindow, 258 _NET_WM_STATE, 259 0, MaxInt, False, XA_ATOM, @atomtype, @format, @nitems, 260 @bytes_after, gpointer(@state_array)); 261 262 if (atomtype = XA_ATOM) and (format = 32) and (nitems > 0) then 263 begin 264 maximized_horz := False; 265 maximized_vert := False; 266 for X := 0 to nitems - 1 do 267 begin 268 if (state_array[X] = _NET_WM_STATE_MAXIMIZED_VERT) then maximized_vert := True; 269 if (state_array[X] = _NET_WM_STATE_MAXIMIZED_HORZ) then maximized_horz := True; 270 Result := (maximized_horz and maximized_vert); 271 272 if Result then Break; 273 end; 274 end; 275 if state_array <> nil then 276 XFree(state_array); 277end; 278 279procedure GDK_WINDOW_SHOW_IN_TASKBAR(Window: PGdkWindowPrivate; Show: Boolean); 280// this is a try to hide windows from the taskbar. 281// Unpleasantly, some windowmanagers like metacity also hides from the Alt-Tab 282// cycle. 283// This feature is therefore disabled on default. 284{$IFDEF EnableHideFromTaskBar} 285var 286 XDisplay: PDisplay; 287 XScreen: PScreen; 288 XRootWindow, 289 XWindow: TWindow; 290 XEvent: TXClientMessageEvent; 291 _NET_WM_STATE, 292 _NET_WM_STATE_SKIP_TASKBAR: clong; 293{$ENDIF} 294begin 295 {$IFDEF EnableHideFromTaskBar} 296 // GTK1: reshowing does not work, so a modal form will hide the whole application 297 // GTK 298 299 XDisplay := GDK_WINDOW_XDISPLAY (Window); 300 XScreen := XDefaultScreenOfDisplay(xdisplay); 301 XRootWindow := XRootWindowOfScreen(xscreen); 302 XWindow := GDK_WINDOW_XWINDOW (Window); 303 304 _NET_WM_STATE := XInternAtom(xdisplay, '_NET_WM_STATE', false); 305 _NET_WM_STATE_SKIP_TASKBAR := XInternAtom(xdisplay, '_NET_WM_STATE_SKIP_TASKBAR', false); 306 307 XEvent._type := ClientMessage; 308 XEvent.window := XWindow; 309 XEvent.message_type := _NET_WM_STATE; 310 XEvent.format := 32; 311 if Show then 312 XEvent.data.l[0] := 1 313 else 314 XEvent.data.l[0] := 0;// 0=Remove 1=Add 2=Toggle 315 XEvent.data.l[1] := _NET_WM_STATE_SKIP_TASKBAR; 316 317 XSendEvent(XDisplay, XRootWindow, False, SubstructureNotifyMask, @XEvent); 318 {$ENDIF} 319end; 320 321function gtk_class_get_type(aclass : Pointer) : TGtkType; 322begin 323 If (aclass <> nil) then 324 result := PGtkTypeClass(aclass)^.thetype 325 else 326 result := 0; 327end; 328 329function gtk_object_get_class(anobject : Pointer) : Pointer; 330begin 331 If (anobject <> nil) then 332 result := PGtkTypeObject(anobject)^.klass 333 else 334 result := nil; 335end; 336 337function gtk_window_get_modal(window:PGtkWindow):gboolean; 338begin 339 if assigned(Window) then 340 result := (Window^.flag0 and bm_modal)<>0 341 else 342 result := False; 343end; 344 345function gtk_bin_get_child(bin : PGTKBin) : PGTKWidget; 346begin 347 if (bin <> nil) then 348 result := bin^.Child 349 else 350 result := nil; 351end; 352 353procedure gtk_menu_item_set_right_justified(menu_item : PGtkMenuItem; right_justified : gboolean); 354begin 355 if right_justified then 356 menu_item^.flag0:=menu_item^.flag0 or bm_right_justify 357 else 358 menu_item^.flag0:=menu_item^.flag0 and (not bm_right_justify); 359end; 360 361function gtk_check_menu_item_get_active(menu_item : PGtkCheckMenuItem) : gboolean; 362begin 363 Result:=(menu_item^.flag0 and bm_checkmenuitem_active <> 0); 364end; 365 366procedure gtk_menu_append(menu : PGTKWidget; Item : PGtkWidget); 367begin 368 gtk.gtk_menu_append(PGTKMenu(menu), Item); 369end; 370 371procedure gtk_menu_insert(menu : PGtkWidget; Item : PGTKWidget; Index : gint); 372begin 373 gtk.gtk_menu_insert(PGTKMenu(menu), Item, Index); 374end; 375 376procedure gtk_menu_bar_insert(menubar : PGtkWidget; Item : PGTKWidget; Index : gint); 377begin 378 gtk.gtk_menu_bar_insert(PGtkMenuBar(menubar), Item, Index); 379end; 380 381function gtk_image_new :PGTKWidget; 382begin 383 result := gtk.gtk_image_new(nil,nil); 384end; 385 386function gtk_toolbar_new : PGTKWidget; 387begin 388 result := gtk.gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,GTK_TOOLBAR_BOTH); 389end; 390 391procedure gtk_color_selection_get_current_color(colorsel : PGTKColorSelection; Color : PGDKColor); 392var 393 colorArray : array[0..2] of double; 394begin 395 gtk_color_selection_get_color(colorsel, @colorArray[0]); 396 Color^.pixel := 0; 397 Color^.red := gushort(TruncToCardinal(colorArray[0] * $FFFF)); 398 Color^.green := gushort(TruncToCardinal(colorArray[1] * $FFFF)); 399 Color^.blue := gushort(TruncToCardinal(colorArray[2] * $FFFF)); 400 {$IFDEF VerboseColorDialog} 401 DebugLn('gtk_color_selection_get_current_color ', 402 ' Red=',DbgS(Color^.Red), 403 ' Green=',DbgS(Color^.Green), 404 ' Blue=',DbgS(Color^.Blue), 405 ''); 406 {$ENDIF} 407end; 408 409procedure gtk_color_selection_set_current_color(colorsel : PGTKColorSelection; 410 Color : PGDKColor); 411var 412 SelectionColor: PGDouble; 413begin 414 {$IFDEF VerboseColorDialog} 415 DebugLn('gtk_color_selection_set_current_color ', 416 ' Red=',DbgS(Color^.Red), 417 ' Green=',DbgS(Color^.Green), 418 ' Blue=',DbgS(Color^.Blue), 419 ''); 420 {$ENDIF} 421 GetMem(SelectionColor,4*SizeOf(GDouble)); 422 try 423 SelectionColor[0]:=gdouble(Color^.Red)/65535; 424 SelectionColor[1]:=gdouble(Color^.Green)/65535; 425 SelectionColor[2]:=gdouble(Color^.Blue)/65535; 426 SelectionColor[3]:=0.0; 427 gtk_color_selection_set_color(colorSel,SelectionColor); 428 finally 429 FreeMem(SelectionColor); 430 end; 431end; 432 433procedure gdk_image_unref(Image : PGdkImage); 434begin 435 gdk_window_unref(PGdkWindow(Image)); 436end; 437 438procedure gdk_colormap_query_color(colormap : PGDKColormap; Pixel : gulong; Result : PGDKColor); 439var 440 GdkColorContext: PGdkColorContext; 441begin 442 if (Colormap = nil) or (Result = nil) then exit; 443 GdkColorContext:= gdk_color_context_new(gdk_colormap_get_visual(colormap),colormap); 444 Result^.Pixel := Pixel; 445 gdk_color_context_query_color(GdkColorContext, Result); 446 gdk_color_context_free(GdkColorContext); 447end; 448 449function gdk_region_intersect(source1:PGdkRegion; source2:PGdkRegion) : PGdkRegion; 450begin 451 result := gdk_regions_intersect(source1, source2); 452end; 453 454function gdk_region_union(source1:PGdkRegion; source2:PGdkRegion) : PGdkRegion; 455begin 456 result := gdk_regions_union(source1, source2); 457end; 458 459function gdk_region_subtract(source1:PGdkRegion; source2:PGdkRegion) : PGdkRegion; 460begin 461 result := gdk_regions_subtract(source1, source2); 462end; 463 464function gdk_region_xor(source1:PGdkRegion; source2:PGdkRegion) : PGdkRegion; 465begin 466 result := gdk_regions_xor(source1, source2); 467end; 468 469function gdk_region_copy(region: PGDKRegion): PGDKRegion; 470var 471 EmptyRegion: PGdkRegion; 472begin 473 EmptyRegion := gdk_region_new; 474 Result := gdk_regions_union(region, EmptyRegion); 475 gdk_region_destroy(EmptyRegion); 476end; 477 478function gdk_region_rectangle(rect: PGdkRectangle): PGDKRegion; 479var 480 EmptyRegion: PGdkRegion; 481begin 482 EmptyRegion := gdk_region_new; 483 Result := gdk_region_union_with_rect(EmptyRegion,Rect); 484 gdk_region_destroy(EmptyRegion); 485end; 486 487function gdk_pixmap_create_from_xpm_d (window : PGdkWindow; var mask : PGdkBitmap; transparent_color : PGdkColor; data : PPgchar) : PGdkPixmap; 488begin 489 result := gdk.gdk_pixmap_create_from_xpm_d(window, @mask, transparent_color, data) 490end; 491 492function gdk_pixmap_colormap_create_from_xpm_d (window : PGdkWindow; colormap: PGdkColormap; var mask : PGdkBitmap; transparent_color : PGdkColor; data : PPgchar) : PGdkPixmap; 493begin 494 result := gdk.gdk_pixmap_colormap_create_from_xpm_d(window, colormap, @mask, transparent_color, data) 495end; 496 497function gdk_pixmap_colormap_create_from_xpm (window : PGdkWindow; colormap: PGdkColormap; var mask : PGdkBitmap; transparent_color : PGdkColor; filename : Pgchar) : PGdkPixmap; 498begin 499 result := gdk.gdk_pixmap_colormap_create_from_xpm(window, colormap, @mask, transparent_color, filename) 500end; 501 502procedure gdk_pixbuf_render_pixmap_and_mask(pixbuf : PGdkPixbuf; var pixmap_return : PGdkPixmap; var mask_return : PGdkBitmap; alpha_threshold : gint); 503begin 504 gdkpixbuf.gdk_pixbuf_render_pixmap_and_mask(pixbuf, @pixmap_return, @mask_return, alpha_threshold); 505end; 506 507function gdk_pixbuf_new_subpixbuf(src_pixbuf: PGdkPixbuf; src_x: longint; src_y: longint; width: longint; height: longint): PGdkPixbuf; 508var 509 tmp: PGdkPixbuf; 510 buf: PChar; 511 rowstride: Integer; 512begin 513 buf := gdk_pixbuf_get_pixels(src_pixbuf); 514 515 rowstride := gdk_pixbuf_get_rowstride(src_pixbuf); 516 517 inc(buf, src_y * rowstride + src_x * gdk_pixbuf_get_n_channels(src_pixbuf)); 518 tmp := gdk_pixbuf_new_from_data(buf, gdk_pixbuf_get_colorspace(src_pixbuf), 519 gdk_pixbuf_get_has_alpha(src_pixbuf), gdk_pixbuf_get_bits_per_sample(src_pixbuf), 520 width, height, rowstride, nil, nil); 521 Result := gdk_pixbuf_copy(tmp); 522 gdk_pixbuf_unref(tmp); 523end; 524 525function gdk_drawable_get_depth(Drawable : PGDKDrawable) : gint; 526begin 527 gdk_window_get_geometry(Drawable, nil, nil, nil, nil, @result); 528end; 529 530procedure gdk_drawable_get_size(Drawable : PGDKDrawable; Width, Height : PGInt); 531begin 532 gdk_window_get_geometry(Drawable, nil, nil, Width, Height, nil); 533end; 534 535function gdk_drawable_get_image(Drawable : PGDKDrawable; x, y, width, height : gint) : PGdkImage; 536begin 537 result := gdk_image_get(Drawable, x, y, width, height); 538end; 539 540function gdk_drawable_get_colormap(Drawable : PGDKDrawable) : PGdkColormap; 541begin 542 result := gdk_window_get_colormap(Drawable); 543end; 544 545{$ifdef HasX} 546function gdk_x11_image_get_ximage(image: PGdkImage): PXImage; 547begin 548 Result := PGdkImagePrivate(Image)^.ximage; 549end; 550{$endif} 551 552