使用Go与cgo和Xlib

时间:2015-12-12 19:05:22

标签: go xlib cgo

我试图在cgo的帮助下将C代码重写为Go,但是在尝试运行go代码时,它给了我一些错误,我不知道如何解决。该代码允许在Linux桌面上获得鼠标点击的坐标。

C代码:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main () {
    int x=-1, y=-1;
    XEvent event;
    int button;
    Display *display = XOpenDisplay(NULL);
    if (display == NULL) {
    fprintf(stderr, "Cannot connect to X server!\n");
    exit (EXIT_FAILURE);
    }
    Window root= XDefaultRootWindow(display);
    XGrabPointer(display, root, False, ButtonPressMask, GrabModeAsync,
         GrabModeAsync, None, None, CurrentTime);
    while(1){
    XSelectInput(display, root, ButtonReleaseMask);
    while(1) {
      XNextEvent(display,&event);
      switch(event.type) {
    case ButtonPress:
        switch(event.xbutton.button) {
          case Button1:
          x=event.xbutton.x;
          y=event.xbutton.y;
          button=Button1;
          break;

          case Button3:
          x=event.xbutton.x;
          y=event.xbutton.y;
          button=Button3;
          break;
          default:
          break;

        }
        break;
    default:
        break;
      }
      if(x>=0 && y>=0)break;
    }

    if(button==Button1)printf("leftclick at %d %d \n",x,y);
    else printf("rightclick at %d %d \n",x,y);}
    XCloseDisplay(display);
    return 0;
}

转到代码:

package main

// #cgo LDFLAGS: -lX11
// #include <X11/Xlib.h>
// #include <X11/Xutil.h>
import "C"

import (
    "fmt"
)

func main() {
    var x = -1
    var y = -1
    var event C.XEvent
    var button int
    var display = C.XOpenDisplay(nil)
    if display == nil {
        panic("Cannot connect to X server!\n")
    }

    var root = C.XDefaultRootWindow(display);
    C.XGrabPointer(display, root, C.False, C.ButtonPressMask, C.GrabModeAsync, 
        C.GrabModeAsync, C.None, C.None, C.CurrentTime)
    for {
        C.XSelectInput(display, root, C.ButtonReleaseMask)
        for {
            C.XNextEvent(display, &event)
            switch(C.event.type) {
                case C.ButtonPress:
                    switch C.event.xbutton.button  {
                        case C.Button1:
                            x=C.event.xbutton.x
                            y=C.event.xbutton.y
                            button=C.Button1
                            break

                        case Button3:
                            x=C.event.xbutton.x
                            y=C.event.xbutton.y
                            button=C.Button3
                            break
                            default:
                                break

                    }
                    break
                default:
                    break
            }
            if(x>=0 && y>=0) {
                break
            }
        }
        if(button==Button1) {
            fmt.Printf("leftclick at %d %d \n",x,y)
        }
        else  {
            fmt.Printf("rightclick at %d %d \n",x,y)
        }
    }
    C.XCloseDisplay(display)
}

Go代码中的错误:

go run g.go
# command-line-arguments
./g.go:29:19: expected selector or type assertion, found 'type'
./g.go:58:3: expected statement, found 'else'
./g.go:63:3: expected '}', found 'EOF'

1 个答案:

答案 0 :(得分:0)

对于&#34;输入&#34;的错误,这是一个保留字,因此无法直接访问。

根据this posting,您应该将您的引用更改为:

switch C.event._type {

此外,其他人不能在自己的线上。 将其更改为

if button == Button1 {
    fmt.Printf("leftclick at %d %d \n", x, y)
} else {
    fmt.Printf("rightclick at %d %d \n", x, y)
}

切换语句不会在go中出现,所以你的break语句是不必要的。

最后,请确保在您的代码上运行go fmt,您正在使用不需要它们的parens。

这是一个格式化的版本,其中删除了一些应该适合您的内容(我没有测试此代码):

package main

// #cgo LDFLAGS: -lX11
// #include <X11/Xlib.h>
// #include <X11/Xutil.h>
import "C"

import (
    "fmt"
)

func main() {
    var x = -1
    var y = -1
    var event C.XEvent
    var button int
    var display = C.XOpenDisplay(nil)
    if display == nil {
        panic("Cannot connect to X server!\n")
    }

    var root = C.XDefaultRootWindow(display)
    C.XGrabPointer(display, root, C.False, C.ButtonPressMask, C.GrabModeAsync,
        C.GrabModeAsync, C.None, C.None, C.CurrentTime)
    for {
        C.XSelectInput(display, root, C.ButtonReleaseMask)
        for {
            C.XNextEvent(display, &event)
            switch C.event._type {
            case C.ButtonPress:
                switch C.event.xbutton.button {
                case C.Button1:
                    x = C.event.xbutton.x
                    y = C.event.xbutton.y
                    button = C.Button1

                case Button3:
                    x = C.event.xbutton.x
                    y = C.event.xbutton.y
                    button = C.Button3
                }
            }
            if x >= 0 && y >= 0 {
                break
            }
        }
        if button == Button1 {
            fmt.Printf("leftclick at %d %d \n", x, y)
        } else {
            fmt.Printf("rightclick at %d %d \n", x, y)
        }
    }
    C.XCloseDisplay(display)
}