widgetproxy_purego.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // Copyright 2025 The tk9.0-go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build (linux && (amd64 || arm64)) || (darwin && (amd64 || arm64)) || (freebsd && (amd64 || arm64))
  5. package tk9_0 // import "modernc.org/tk9.0"
  6. import (
  7. "fmt"
  8. "unsafe"
  9. "github.com/ebitengine/purego"
  10. )
  11. func (proxy *widgetProxy) eventDispatcher(clientData, in uintptr, argc int32, argv uintptr) uintptr {
  12. // Expect at least arguments for the path and the operation.
  13. if argc < 2 {
  14. setResult(fmt.Sprintf("WidgetProxy eventDispatcher internal error: argc=%v", argc))
  15. return tcl_error
  16. }
  17. argsPointers := unsafe.Slice((*uintptr)(unsafe.Pointer(argv)), argc)
  18. argsPointers = argsPointers[1:] // skip path
  19. args := make([]string, len(argsPointers))
  20. for i := 0; i < len(argsPointers); i++ {
  21. args[i] = goString(argsPointers[i])
  22. }
  23. operation := args[0]
  24. if callback, ok := proxy.operations[operation]; ok {
  25. // Dispatch to the operation's registered callback.
  26. callback(args)
  27. } else {
  28. // Process as normal.
  29. proxy.EvalWrapped(args)
  30. }
  31. return tcl_ok
  32. }
  33. // Create a new Tcl command whose name is the widget's pathname, and
  34. // whose action is to dispatch on the operation passed to the widget:
  35. func (proxy *widgetProxy) registerEventDispatcher() {
  36. runCmdProxy := purego.NewCallback(proxy.eventDispatcher)
  37. if proxy.commandName, Error = cString(proxy.window.String()); Error != nil {
  38. return
  39. }
  40. cmd, _, _ := purego.SyscallN(createCommandProc, interp, proxy.commandName, runCmdProxy, 0, 0)
  41. if cmd == 0 {
  42. fail(fmt.Errorf("registering widget proxy event dispatcher proxy failed: %v", getObjResultProc))
  43. return
  44. }
  45. }
  46. func (proxy *widgetProxy) unregisterEventDispatcher() {
  47. defer func() {
  48. allocator.UintptrFree(proxy.commandName)
  49. proxy.commandName = 0 // nil
  50. }()
  51. _, _, _ = purego.SyscallN(deleteCommandProc, interp, proxy.commandName)
  52. }