Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b6a2277
begin with instrospection: Add GIRepository, GIBaseInfo
bfredl Dec 30, 2013
d69cdc5
add GINamespace, access methdods
bfredl Dec 30, 2013
295315c
subclass on different GIInfo types
bfredl Dec 30, 2013
8527baa
Fix indexing + add some accessors
bfredl Dec 30, 2013
8dc4933
some fixes + simple testing
bfredl Dec 30, 2013
64b58dd
extract types of arguments (+ cleanup)
bfredl Dec 31, 2013
be28474
Call methods (with one argument :)
bfredl Dec 31, 2013
34a2e44
Merge branch 'master' of https://github.com/JuliaLang/Gtk.jl into girepo
bfredl Dec 31, 2013
5cf04bc
load correct shared libraries + Clutter test
bfredl Jan 1, 2014
1034c29
work on Namespace generation
bfredl Jan 1, 2014
077620f
fix Gtk test
bfredl Jan 1, 2014
6290375
String passing
bfredl Jan 1, 2014
789e5d4
gimport interface (proof of concept)
bfredl Jan 1, 2014
5791fdf
subtyping support
bfredl Jan 1, 2014
77aa401
julia 0.3 compat & simpler const generation ( JuliaLang/julia#5276 )
bfredl Jan 2, 2014
a095c2c
joining together GI.Gtk and Gtk (ugly, but mostly works)
bfredl Jan 2, 2014
7c55395
forgot const
bfredl Jan 2, 2014
f67406e
demonstration of using autogenerated wrappers
bfredl Jan 2, 2014
22421df
fix ambigous constructors and restore show(GObject)
bfredl Jan 2, 2014
c262f50
some gtype and debug cleanup
bfredl Jan 2, 2014
fd413b4
clean up quot
bfredl Jan 3, 2014
ef2dd55
GType generation w/o using introspection
bfredl Jan 3, 2014
9305818
factor out signal code for GObject module
bfredl Jan 3, 2014
cebe8e8
Merge branch 'master' of https://github.com/JuliaLang/Gtk.jl into girepo
bfredl Jan 3, 2014
7d7f7ab
stab at splitting out Glib.jl (still many missing exports)
bfredl Jan 3, 2014
4e271f1
revert GdkPixbuf change + remove trailing whitespace
bfredl Jan 4, 2014
4cd86b4
make @gimport work again
bfredl Jan 4, 2014
3e7ae33
split the modules
bfredl Jan 4, 2014
189003e
namespace functions
bfredl Jan 4, 2014
2a94ccc
work on constants
bfredl Jan 4, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions deps/ext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ if OS_NAME == :Windows
const libgobject = "libgobject-2.0-0"
const libglib = "libglib-2.0-0"
const libgdk_pixbuf = "libgdk_pixbuf-2.0-0"
const libgi = "libgirepository-1.0-0" # unverifie
else
const libgobject = "libgobject-2.0"
const libglib = "libglib-2.0"
const libgdk_pixbuf = "libgdk_pixbuf-2.0"
const libgi = "libgirepository-1.0"
end
14 changes: 14 additions & 0 deletions src/GI.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module GI
using GLib
using GLib.MutableTypes
import Base: convert, show, showcompact, length, getindex, setindex!

# gimport interface (not final in any way)
export @gimport

export extract_type, ensure_name, ensure_method

include(joinpath("..","deps","ext.jl"))
include("girepo.jl")
include("giimport.jl")
end
37 changes: 37 additions & 0 deletions src/GLib.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module GLib
import Base: convert, show, showall, showcompact, run, size, length, getindex, setindex!,
insert!, push!, unshift!, shift!, pop!, splice!, delete!,
start, next, done, parent, isempty, empty!, first, last, in,
eltype, copy
import Base.Graphics: width, height, getgc
export GObject, GObjectI, GType, @GType, make_gvalue
export Enum, GError, GValue, gvalue
export GSList, gslist,gslist2, gc_ref, gc_ref_closure
export signal_connect, signal_emit
export bytestring, GConnectFlags
include(joinpath("..","deps","ext.jl"))
bytestring(s) = Base.bytestring(s)
bytestring(s::Symbol) = s
bytestring(s::Ptr{Uint8},own::Bool) = UTF8String(pointer_to_array(s,int(ccall(:strlen,Csize_t,(Ptr{Uint8},),s)),own))

ccall((:g_type_init,libgobject),Void,())
include("MutableTypes.jl")
using MutableTypes
include("gslist.jl")
include("gobject.jl")
include("gvalues.jl")
include("gerror.jl")
include("signals.jl")
sizeof_gclosure = 0
function init()
global sizeof_gclosure = WORD_SIZE
closure = C_NULL
while closure == C_NULL
sizeof_gclosure += WORD_SIZE
closure = ccall((:g_closure_new_simple,libgobject),Ptr{Void},(Int,Ptr{Void}),sizeof_gclosure,C_NULL)
end
ccall((:g_closure_sink,libgobject),Void,(Ptr{Void},),closure)
end
init()
end

17 changes: 6 additions & 11 deletions src/Gtk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

module Gtk
using Cairo
include("MutableTypes.jl")
using .MutableTypes
using GLib
using GLib.MutableTypes

import Base: convert, show, showall, run, size, length, getindex, setindex!,
import Base: convert, show, showall, showcompact, run, size, length, getindex, setindex!,
insert!, push!, unshift!, shift!, pop!, splice!, delete!,
start, next, done, parent, isempty, empty!, first, last, in,
eltype, copy
Expand Down Expand Up @@ -71,18 +71,11 @@ export GdkKeySyms, GdkScrollDirection, GtkJustification
# set_position

# local function, handles Symbol and makes UTF8-strings easier
bytestring(s) = Base.bytestring(s)
bytestring(s::Symbol) = s
bytestring(s::Ptr{Uint8},own::Bool) = UTF8String(pointer_to_array(s,int(ccall(:strlen,Csize_t,(Ptr{Uint8},),s)),own))

typealias Index Union(Integer,AbstractVector{TypeVar(:I,Integer)})

include(joinpath("..","deps","ext.jl"))
ccall((:g_type_init,libgobject),Void,())
include("gslist.jl")

include("gtktypes.jl")
include("gvalues.jl")
include("gerror.jl")
include("gdk.jl")
include("events.jl")
include("container.jl")
Expand Down Expand Up @@ -124,6 +117,7 @@ for container in subtypes(GtkContainerI,true)
@eval $(symbol(string(container)))(child::GtkWidgetI,vargs...) = push!($container(vargs...),child)
end
for orientable in tuple(:GtkPaned, :GtkScale, [sym.name.name for sym in subtypes(GtkBoxI)]...)
if endswith(string(orientable),"I") continue end # Sorry :(
@eval $orientable(orientation::Symbol,vargs...) = $orientable(
(orientation==:v ? true :
(orientation==:h ? false :
Expand Down Expand Up @@ -252,3 +246,4 @@ export Canvas, Window

init()
end

14 changes: 7 additions & 7 deletions src/buttons.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,26 @@
#GtkSwitch — A "light switch" style toggle
#GtkLockButton — A widget to unlock or lock privileged operations

@GType GtkButton <: GtkBin
@GType GtkButton
GtkButton() = GtkButton(ccall((:gtk_button_new,libgtk),Ptr{GObject},()))
GtkButton(title::String) =
GtkButton(ccall((:gtk_button_new_with_mnemonic,libgtk),Ptr{GObject},
(Ptr{Uint8},), bytestring(title)))

@GType GtkCheckButton <: GtkBin
@GType GtkCheckButton
GtkCheckButton() = GtkCheckButton(ccall((:gtk_check_button_new,libgtk),Ptr{GObject},()))
GtkCheckButton(title::String) =
GtkCheckButton(ccall((:gtk_check_button_new_with_mnemonic,libgtk),Ptr{GObject},
(Ptr{Uint8},), bytestring(title)))

@GType GtkToggleButton <: GtkBin
@GType GtkToggleButton
GtkToggleButton() = GtkToggleButton(ccall((:gtk_toggle_button_new,libgtk),Ptr{GObject},()))
GtkToggleButton(title::String) =
GtkToggleButton(ccall((:gtk_toggle_button_new_with_mnemonic,libgtk),Ptr{GObject},
(Ptr{Uint8},), bytestring(title)))

if gtk_version >= 3
@GType GtkSwitch <: GtkWidget
@GType GtkSwitch
GtkSwitch() = GtkSwitch(ccall((:gtk_switch_new,libgtk),Ptr{GObject},()))
function GtkSwitch(active::Bool)
b = GtkSwitch()
Expand All @@ -43,7 +43,7 @@ else
const GtkSwitch = GtkToggleButton
end

@GType GtkRadioButton <: GtkBin
@GType GtkRadioButton
GtkRadioButton(group::Ptr{Void}=C_NULL) =
GtkRadioButton(ccall((:gtk_radio_button_new,libgtk),Ptr{GObject},
(Ptr{Void},),group))
Expand Down Expand Up @@ -157,7 +157,7 @@ for btn in (:GtkCheckButton, :GtkToggleButton, :GtkRadioButton)
end


@GType GtkLinkButton <: GtkBin
@GType GtkLinkButton
GtkLinkButton(uri::String) =
GtkLinkButton(ccall((:gtk_link_button_new,libgtk),Ptr{GObject},
(Ptr{Uint8},),bytestring(uri)))
Expand All @@ -177,7 +177,7 @@ end

#TODO: @GType GtkScaleButton

@GType GtkVolumeButton <: GtkBin
@GType GtkVolumeButton
GtkVolumeButton() = GtkVolumeButton(ccall((:gtk_volume_button_new,libgtk),Ptr{GObject},()))
function GtkVolumeButton(value::Real) # 0<=value<=1
b = GtkVolumeButton()
Expand Down
9 changes: 5 additions & 4 deletions src/displays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ baremodule GtkIconSize
end
end

@GType GtkImage <: GtkWidget
@GType GtkImage
GtkImage(pixbuf::GdkPixbuf) = GtkImage(ccall((:gtk_image_new_from_pixbuf,libgtk),Ptr{GObject},(Ptr{GObject},),pixbuf))
GtkImage(filename::String) = GtkImage(ccall((:gtk_image_new_from_file,libgtk),Ptr{GObject},(Ptr{Uint8},),bytestring(filename)))

Expand All @@ -310,14 +310,14 @@ end
empty!(img::GtkImage) = ccall((:gtk_image_clear,libgtk),Void,(Ptr{GObject},),img)
GdkPixbuf(img::GtkImage) = GdkPixbuf(ccall((:gtk_image_get_pixbuf,libgtk),Ptr{GObject},(Ptr{GObject},),img))

@GType GtkProgressBar <: GtkWidget
@GType GtkProgressBar
GtkProgressBar() = GtkProgressBar(ccall((:gtk_progress_bar_new,libgtk),Ptr{GObject},()))
pulse(progress::GtkProgressBar) = ccall((:gtk_progress_bar_pulse,libgtk),Void,(Ptr{GObject},),progress)

@GType GtkSpinner <: GtkWidget
@GType GtkSpinner
GtkSpinner() = GtkSpinner(ccall((:gtk_spinner_new,libgtk),Ptr{GObject},()))

@GType GtkStatusbar <: GtkBox
@GType GtkStatusbar
GtkStatusbar() = GtkStatusbar(ccall((:gtk_statusbar_new,libgtk),Ptr{GObject},()))
context_id(status::GtkStatusbar,source) =
ccall((:gtk_statusbar_get_context_id,libgtk),Cuint,(Ptr{GObject},Ptr{Uint8}),
Expand All @@ -342,3 +342,4 @@ empty!(status::GtkStatusbar,context) =
@GType GtkStatusIcon
GtkStatusIcon() = GtkStatusIcon(ccall((:gtk_status_icon_new,libgtk),Ptr{GObject},()))


124 changes: 0 additions & 124 deletions src/events.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,119 +16,17 @@ function gtk_doevent()
end
end

sizeof_gclosure = 0
function init()
GError() do error_check
ccall((:gtk_init_with_args,libgtk), Bool,
(Ptr{Void}, Ptr{Void}, Ptr{Uint8}, Ptr{Void}, Ptr{Uint8}, Ptr{GError}),
C_NULL, C_NULL, "Julia Gtk Bindings", C_NULL, C_NULL, error_check)
end
global sizeof_gclosure = WORD_SIZE
closure = C_NULL
while closure == C_NULL
sizeof_gclosure += WORD_SIZE
closure = ccall((:g_closure_new_simple,libgobject),Ptr{Void},(Int,Ptr{Void}),sizeof_gclosure,C_NULL)
end
ccall((:g_closure_sink,libgobject),Void,(Ptr{Void},),closure)
global timeout
timeout = Base.TimeoutAsyncWork(gtk_doevent)
Base.start_timer(timeout,.1,.005)
end

# id = signal_connect(widget, :event, Void, (ArgsT...)) do ptr, evt_args..., closure
# stuff
# end
function signal_connect(cb::Function,w::GObject,sig::Union(String,Symbol),
RT::Type,param_types::Tuple,after::Bool=false,closure=w) #TODO: assert that length(param_types) is correct
if isgeneric(cb)
callback = cfunction(cb,RT,tuple(Ptr{GObject},param_types...,typeof(closure)))
return ccall((:g_signal_connect_data,libgobject), Culong,
(Ptr{GObject}, Ptr{Uint8}, Ptr{Void}, Any, Ptr{Void}, Enum),
w,
bytestring(sig),
callback,
closure,
gc_ref_closure(closure),
after*GConnectFlags.AFTER)
end
# oops, Julia doesn't support this natively yet -- fake it instead
return _signal_connect(cb, w, sig, after, true,param_types,closure)
end

# id = signal_connect(widget, :event) do obj, evt_args...
# stuff
# end
function signal_connect(cb::Function,w::GObject,sig::Union(String,Symbol),after::Bool=false)
_signal_connect(cb, w, sig, after, false,nothing,nothing)
end
function _signal_connect(cb::Function,w::GObject,sig::Union(String,Symbol),after::Bool,gtk_call_conv::Bool,param_types,closure)
closuref = ccall((:g_closure_new_object,libgobject), Ptr{Void}, (Cuint, Ptr{GObject}), sizeof_gclosure::Int+WORD_SIZE*2, w)
closure_env = convert(Ptr{Any},closuref+sizeof_gclosure)
unsafe_store!(closure_env, cb, 1)
if gtk_call_conv
env = Any[param_types,closure]
unsafe_store!(closure_env, env, 2)
ccall((:g_closure_add_invalidate_notifier,libgobject), Void,
(Ptr{Void}, Any, Ptr{Void}), closuref, env, gc_ref_closure(env))
else
unsafe_store!(convert(Ptr{Int},closure_env), 0, 2)
end
ccall((:g_closure_add_invalidate_notifier,libgobject), Void,
(Ptr{Void}, Any, Ptr{Void}), closuref, cb, gc_ref_closure(cb))
ccall((:g_closure_set_marshal,libgobject), Void,
(Ptr{Void}, Ptr{Void}), closuref, JuliaClosureMarshal)
return ccall((:g_signal_connect_closure,libgobject), Culong,
(Ptr{GObject}, Ptr{Uint8}, Ptr{Void}, Cint), w, bytestring(sig), closuref, after)
end
function GClosureMarshal(closuref, return_value, n_param_values,
param_values, invocation_hint, marshal_data)
try
closure_env = convert(Ptr{Any},closuref+sizeof_gclosure)
cb = unsafe_load(closure_env, 1)
gtk_calling_convention = (0 != unsafe_load(convert(Ptr{Int},closure_env), 2))
params = Array(Any, n_param_values)
if gtk_calling_convention
# compatibility mode, if we must
param_types,closure = unsafe_load(closure_env, 2)::Array{Any,1}
length(param_types)+1 == n_param_values || error("GCallback called with the wrong number of parameters")
for i = 1:n_param_values
gv = mutable(param_values,i)
g_type = unsafe_load(gv).g_type
# avoid auto-unboxing for some builtin types in gtk_calling_convention mode
if bool(ccall((:g_type_is_a,libgobject),Cint,(Int,Int),g_type,gobject_id))
params[i] = ccall((:g_value_get_object,libgobject), Ptr{GObject}, (Ptr{GValue},), gv)
elseif bool(ccall((:g_type_is_a,libgobject),Cint,(Int,Int),g_type,gboxed_id))
params[i] = ccall((:g_value_get_boxed,libgobject), Ptr{Void}, (Ptr{GValue},), gv)
elseif bool(ccall((:g_type_is_a,libgobject),Cint,(Int,Int),g_type,gstring_id))
params[i] = ccall((:g_value_get_string,libgobject), Ptr{Void}, (Ptr{GValue},), gv)
else
params[i] = gv[]
end
if i > 1
params[i] = convert(param_types[i-1], params[i])
end
end
push!(params, closure)
else
for i = 1:n_param_values
params[i] = mutable(param_values,i)[]
end
end
retval = cb(params...) # widget, args...
if return_value != C_NULL && retval !== nothing
g_type = unsafe_load(return_value).g_type
if g_type != gvoid_id && g_type != 0
return_value[] = gvalue(retval)
end
end
catch e
Base.display_error(e,catch_backtrace())
end
return nothing
end
JuliaClosureMarshal = cfunction(GClosureMarshal, Void,
(Ptr{Void}, Ptr{GValue}, Cuint, Ptr{GValue}, Ptr{Void}, Ptr{Void}))


add_events(widget::GtkWidgetI, mask::Integer) = ccall((:gtk_widget_add_events,libgtk),Void,(Ptr{GObject},Enum),widget,mask)

Expand All @@ -147,28 +45,6 @@ add_events(widget::GtkWidgetI, mask::Integer) = ccall((:gtk_widget_add_events,li
# https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget-accel-closures-changed


signal_handler_disconnect(w::GObject, handler_id::Culong) =
ccall(:g_signal_handler_disconnect, Void, (Ptr{GObject}, Culong), w, handler_id)

signal_handler_block(w::GObject, handler_id::Culong) =
ccall(:g_signal_handler_block, Void, (Ptr{GObject}, Culong), w, handler_id)

signal_handler_unblock(w::GObject, handler_id::Culong) =
ccall(:g_signal_handler_unblock, Void, (Ptr{GObject}, Culong), w, handler_id)

function signal_emit(w::GObject, sig::Union(String,Symbol), RT::Type, args...)
i = isa(sig, String) ? search(sig, "::") : (0:-1)
if !isempty(i)
detail = @quark_str sig[last(i)+1:end]
sig = sig[1:first(i)-1]
else
detail = uint32(0)
end
signal_id = ccall((:g_signal_lookup,libgobject),Cuint,(Ptr{Uint8},Csize_t), sig, G_OBJECT_CLASS_TYPE(w))
return_value = RT===Void ? C_NULL : gvalue(RT)
ccall((:g_signal_emitv,libgobject),Void,(Ptr{GValue},Cuint,Uint32,Ptr{GValue}),gvalues(w, args...),signal_id,detail,return_value)
return_value[RT]
end

function on_signal_resize(resize_cb::Function, widget::GtkWidgetI, vargs...)
signal_connect(resize_cb, widget, "size-allocate", Void, (Ptr{GdkRectangle},), vargs...)
Expand Down
Loading