Skip to content

Commit

Permalink
Support signals introduced in later version than record.
Browse files Browse the repository at this point in the history
Generate Connect... and Disconnect... functions for signals
that are only supported in a library version later than that
in which their record or class is first supported.
  • Loading branch information
pekim committed Dec 28, 2018
1 parent 5e7ea92 commit 8e2172c
Show file tree
Hide file tree
Showing 15 changed files with 1,339 additions and 1 deletion.
3 changes: 2 additions & 1 deletion internal/generate/signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ func (s *Signal) supported() (bool, string) {

func (s *Signal) generate(g *jen.Group, version *Version, parentVersion string) {
if !((parentVersion == "" && s.Version == version.value) ||
(parentVersion != "" && (s.Version == "" && parentVersion == version.value))) {
(parentVersion != "" && (s.Version == "" && parentVersion == version.value)) ||
(s.Version == version.value)) {
return
}

Expand Down
142 changes: 142 additions & 0 deletions lib/gdk/class-3.22.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ import (
return g_signal_connect(instance, "invalidate", G_CALLBACK(monitor_invalidateHandler), data);
}
*/
/*
void seat_toolAddedHandler(GObject *, GdkDeviceTool *, gpointer);
static gulong Seat_signal_connect_tool_added(gpointer instance, gpointer data) {
return g_signal_connect(instance, "tool-added", G_CALLBACK(seat_toolAddedHandler), data);
}
*/
/*
void seat_toolRemovedHandler(GObject *, GdkDeviceTool *, gpointer);
static gulong Seat_signal_connect_tool_removed(gpointer instance, gpointer data) {
return g_signal_connect(instance, "tool-removed", G_CALLBACK(seat_toolRemovedHandler), data);
}
*/
/*
Expand Down Expand Up @@ -739,6 +757,130 @@ func CastToSeat(object *gobject.Object) *Seat {
return SeatNewFromC(object.ToC())
}

type signalSeatToolAddedDetail struct {
callback SeatSignalToolAddedCallback
handlerID C.gulong
}

var signalSeatToolAddedId int
var signalSeatToolAddedMap = make(map[int]signalSeatToolAddedDetail)
var signalSeatToolAddedLock sync.RWMutex

// SeatSignalToolAddedCallback is a callback function for a 'tool-added' signal emitted from a Seat.
type SeatSignalToolAddedCallback func(tool *DeviceTool)

/*
ConnectToolAdded connects the callback to the 'tool-added' signal for the Seat.
The returned value represents the connection, and may be passed to DisconnectToolAdded to remove it.
*/
func (recv *Seat) ConnectToolAdded(callback SeatSignalToolAddedCallback) int {
signalSeatToolAddedLock.Lock()
defer signalSeatToolAddedLock.Unlock()

signalSeatToolAddedId++
instance := C.gpointer(recv.native)
handlerID := C.Seat_signal_connect_tool_added(instance, C.gpointer(uintptr(signalSeatToolAddedId)))

detail := signalSeatToolAddedDetail{callback, handlerID}
signalSeatToolAddedMap[signalSeatToolAddedId] = detail

return signalSeatToolAddedId
}

/*
DisconnectToolAdded disconnects a callback from the 'tool-added' signal for the Seat.
The connectionID should be a value returned from a call to ConnectToolAdded.
*/
func (recv *Seat) DisconnectToolAdded(connectionID int) {
signalSeatToolAddedLock.Lock()
defer signalSeatToolAddedLock.Unlock()

detail, exists := signalSeatToolAddedMap[connectionID]
if !exists {
return
}

instance := C.gpointer(recv.native)
C.g_signal_handler_disconnect(instance, detail.handlerID)
delete(signalSeatToolAddedMap, connectionID)
}

//export seat_toolAddedHandler
func seat_toolAddedHandler(_ *C.GObject, c_tool *C.GdkDeviceTool, data C.gpointer) {
signalSeatToolAddedLock.RLock()
defer signalSeatToolAddedLock.RUnlock()

tool := DeviceToolNewFromC(unsafe.Pointer(c_tool))

index := int(uintptr(data))
callback := signalSeatToolAddedMap[index].callback
callback(tool)
}

type signalSeatToolRemovedDetail struct {
callback SeatSignalToolRemovedCallback
handlerID C.gulong
}

var signalSeatToolRemovedId int
var signalSeatToolRemovedMap = make(map[int]signalSeatToolRemovedDetail)
var signalSeatToolRemovedLock sync.RWMutex

// SeatSignalToolRemovedCallback is a callback function for a 'tool-removed' signal emitted from a Seat.
type SeatSignalToolRemovedCallback func(tool *DeviceTool)

/*
ConnectToolRemoved connects the callback to the 'tool-removed' signal for the Seat.
The returned value represents the connection, and may be passed to DisconnectToolRemoved to remove it.
*/
func (recv *Seat) ConnectToolRemoved(callback SeatSignalToolRemovedCallback) int {
signalSeatToolRemovedLock.Lock()
defer signalSeatToolRemovedLock.Unlock()

signalSeatToolRemovedId++
instance := C.gpointer(recv.native)
handlerID := C.Seat_signal_connect_tool_removed(instance, C.gpointer(uintptr(signalSeatToolRemovedId)))

detail := signalSeatToolRemovedDetail{callback, handlerID}
signalSeatToolRemovedMap[signalSeatToolRemovedId] = detail

return signalSeatToolRemovedId
}

/*
DisconnectToolRemoved disconnects a callback from the 'tool-removed' signal for the Seat.
The connectionID should be a value returned from a call to ConnectToolRemoved.
*/
func (recv *Seat) DisconnectToolRemoved(connectionID int) {
signalSeatToolRemovedLock.Lock()
defer signalSeatToolRemovedLock.Unlock()

detail, exists := signalSeatToolRemovedMap[connectionID]
if !exists {
return
}

instance := C.gpointer(recv.native)
C.g_signal_handler_disconnect(instance, detail.handlerID)
delete(signalSeatToolRemovedMap, connectionID)
}

//export seat_toolRemovedHandler
func seat_toolRemovedHandler(_ *C.GObject, c_tool *C.GdkDeviceTool, data C.gpointer) {
signalSeatToolRemovedLock.RLock()
defer signalSeatToolRemovedLock.RUnlock()

tool := DeviceToolNewFromC(unsafe.Pointer(c_tool))

index := int(uintptr(data))
callback := signalSeatToolRemovedMap[index].callback
callback(tool)
}

// GetDisplay is a wrapper around the C function gdk_seat_get_display.
func (recv *Seat) GetDisplay() *Display {
retC := C.gdk_seat_get_display((*C.GdkSeat)(recv.native))
Expand Down
76 changes: 76 additions & 0 deletions lib/gio/class-2.22.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ import (
// #include <gio/gunixoutputstream.h>
// #include <gio/gunixsocketaddress.h>
// #include <stdlib.h>
/*
gboolean socketservice_incomingHandler(GObject *, GSocketConnection *, GObject *, gpointer);
static gulong SocketService_signal_connect_incoming(gpointer instance, gpointer data) {
return g_signal_connect(instance, "incoming", G_CALLBACK(socketservice_incomingHandler), data);
}
*/
/*
gboolean threadedsocketservice_runHandler(GObject *, GSocketConnection *, GObject *, gpointer);
Expand Down Expand Up @@ -2169,6 +2178,73 @@ func CastToSocketService(object *gobject.Object) *SocketService {
return SocketServiceNewFromC(object.ToC())
}

type signalSocketServiceIncomingDetail struct {
callback SocketServiceSignalIncomingCallback
handlerID C.gulong
}

var signalSocketServiceIncomingId int
var signalSocketServiceIncomingMap = make(map[int]signalSocketServiceIncomingDetail)
var signalSocketServiceIncomingLock sync.RWMutex

// SocketServiceSignalIncomingCallback is a callback function for a 'incoming' signal emitted from a SocketService.
type SocketServiceSignalIncomingCallback func(connection *SocketConnection, sourceObject *gobject.Object) bool

/*
ConnectIncoming connects the callback to the 'incoming' signal for the SocketService.
The returned value represents the connection, and may be passed to DisconnectIncoming to remove it.
*/
func (recv *SocketService) ConnectIncoming(callback SocketServiceSignalIncomingCallback) int {
signalSocketServiceIncomingLock.Lock()
defer signalSocketServiceIncomingLock.Unlock()

signalSocketServiceIncomingId++
instance := C.gpointer(recv.native)
handlerID := C.SocketService_signal_connect_incoming(instance, C.gpointer(uintptr(signalSocketServiceIncomingId)))

detail := signalSocketServiceIncomingDetail{callback, handlerID}
signalSocketServiceIncomingMap[signalSocketServiceIncomingId] = detail

return signalSocketServiceIncomingId
}

/*
DisconnectIncoming disconnects a callback from the 'incoming' signal for the SocketService.
The connectionID should be a value returned from a call to ConnectIncoming.
*/
func (recv *SocketService) DisconnectIncoming(connectionID int) {
signalSocketServiceIncomingLock.Lock()
defer signalSocketServiceIncomingLock.Unlock()

detail, exists := signalSocketServiceIncomingMap[connectionID]
if !exists {
return
}

instance := C.gpointer(recv.native)
C.g_signal_handler_disconnect(instance, detail.handlerID)
delete(signalSocketServiceIncomingMap, connectionID)
}

//export socketservice_incomingHandler
func socketservice_incomingHandler(_ *C.GObject, c_connection *C.GSocketConnection, c_source_object *C.GObject, data C.gpointer) C.gboolean {
signalSocketServiceIncomingLock.RLock()
defer signalSocketServiceIncomingLock.RUnlock()

connection := SocketConnectionNewFromC(unsafe.Pointer(c_connection))

sourceObject := gobject.ObjectNewFromC(unsafe.Pointer(c_source_object))

index := int(uintptr(data))
callback := signalSocketServiceIncomingMap[index].callback
retGo := callback(connection, sourceObject)
retC :=
boolToGboolean(retGo)
return retC
}

// SocketServiceNew is a wrapper around the C function g_socket_service_new.
func SocketServiceNew() *SocketService {
retC := C.g_socket_service_new()
Expand Down
Loading

0 comments on commit 8e2172c

Please sign in to comment.