Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface for "g_signal_emitv" #8

Open
lscrd opened this issue Sep 14, 2017 · 7 comments

Comments

Projects
None yet
2 participants
@lscrd
Copy link

commented Sep 14, 2017

I have a doubt regarding the interface of "g_signal_emitv". I think that the first parameter should be a pointer to an array of "Value", i.e. a "ptr Value", rather than a "ValueArray" which is a pointer to an object. This is the way it is defined in the documentation and, furthermore, "ValueArray" is now deprecated (not that I find this to be a logical change though, as a pure array is less secure).

Still adapting my program written for gtk2, I have emitted a signal with the modified interface (with a "ptr Value") and it is correctly processed by the connected callback, so I think this is the right interface.

@StefanSalewski

This comment has been minimized.

Copy link
Owner

commented Sep 15, 2017

Yes, you are right. All the functions which takes array or glist parameters or return these needs manually work unfortunately. And it may be necessary to manually convert carrays and glist to Nim's seq data structure. Doing that is some work, testing that may be even more work because one needs working example code.

I have used GTK from Ruby language in the past, but never needed/used array or list parameters for GTK functions. And I have never used something like g_emit_signal myself. Unfortunately I don't even know a C example for use of functions like g_signal_emit in applications, I have only seen these signal emission in the library itself. So testing is not easy without complete C examples.

Of course we should try to provide all this. Concrete Nim glue code with test examples would be helpful. When we have these, then we can see if we maybe can generate some similar procs even with automatically generated code.

I will investigate this issue, but it may take some time...

@lscrd

This comment has been minimized.

Copy link
Author

commented Sep 15, 2017

If it may be of some help, here is the code I have written to emit a signal with "emitv". I accept here only "int" parameters for the signal.

# The modified interface to "g_signal_emitv".
proc g_signal_emitv(instanceAndParams: ptr Value; signalId: uint32;
                    detail: uint32; returnValue: var Value) {.
                    importc: "g_signal_emitv", libprag.}

const
  TYPE_INT = GType(6 shl TYPE_FUNDAMENTAL_SHIFT)
  TYPE_OBJECT = GType(20 shl TYPE_FUNDAMENTAL_SHIFT)

proc emitSignal*(obj: Object, signalName: string, params: varargs[int]) =
  var values = newSeq[Value](len(params) + 1)
  # Set sender value.
  discard values[0].g_value_init(TYPE_OBJECT)
  values[0].g_value_set_object(obj.impl)
  # Set parameters.
  for idx in 1..values.high:
    discard values[idx].g_value_init(TYPE_INT)
    values[idx].g_value_set_int(int32(params[idx - 1]))
  # Find identifier and detail.
  let signame = cstring(signalName)
  let id = signalLookup(signame, TYPE_OBJECT)
  let detail = quarkTryString(signame)
  # Emit the signal.
  var retval: Value
  g_signal_emitv(addr(values[0]), id, detail, retval)

The signal may be caught using "connect", but only for predefined signals, as, in its current state, "gintro" doesn’t provide a way to create custom signals.

@StefanSalewski

This comment has been minimized.

Copy link
Owner

commented Sep 15, 2017

Thanks. Would it be possible for you to provide a complete example including the receiving object so that I can compile and test the code?

I have never emitted signals myself, and I was unable to find a small but complete example for its use. I guess programs like gedit may have examples in its code, but extracting the relevant code and putting it in a self contained small C example will be much work.

@lscrd

This comment has been minimized.

Copy link
Author

commented Sep 15, 2017

Here is an example, but I’m not sure it will help a lot for two reasons:

  1. It seems that it is not possible to emit predefined signals, so I had to create a custom signal. As there is yet no wrapper for this in "gintro", I have done one quick and dirty.

  2. After that, the template "connect" from "gimpl.nim" doesn’t work with this signal: a procedure whose name starts with "sc" is missing. So, I have added another wrapper for the connection.

The final program is composed of three parts. The needed interfaces, the wrappers and the test.

test_signal.nim.txt

@StefanSalewski

This comment has been minimized.

Copy link
Owner

commented Sep 16, 2017

Thanks, that is a good starting point for my investigations.

But it may take some time...

@StefanSalewski

This comment has been minimized.

Copy link
Owner

commented Sep 17, 2017

I have not touched this issue yet, so you have still to use your own patches. Your example is nice, but creating a real high level Nim interface is some work and will need some time...

@lscrd

This comment has been minimized.

Copy link
Author

commented Sep 17, 2017

I agree. The wrapping is not easy, in general, and especially for signals. I think that a great work has already been done to provide a nice interface which hides the low level details (the interface for "gtk2" was just a thin wrapper compared to this one). Thanks for your work !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.