I trying to rewrite C-code to Go with help of cgo, but when trying to run the go-code it gives me some errors, which I don't know how to solve. The code allows to get coordinates of mouse clicks on a Linux-desktop.
C code:
#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!
");
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
",x,y);
else printf("rightclick at %d %d
",x,y);}
XCloseDisplay(display);
return 0;
}
Go code:
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!
")
}
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
",x,y)
}
else {
fmt.Printf("rightclick at %d %d
",x,y)
}
}
C.XCloseDisplay(display)
}
Errors in Go code:
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'
For the error about "type", that is a reserved word in go so it is not directly accessible.
According to this posting you should change your reference to:
switch C.event._type {
Also, else cannot be on a line on it's own. Change it to
if button == Button1 {
fmt.Printf("leftclick at %d %d
", x, y)
} else {
fmt.Printf("rightclick at %d %d
", x, y)
}
Switch statements don't fallthrough in go, so your break statements are unnecessary.
Lastly, make sure to run go fmt on your code, you are using parens where they are not needed.
Here's a formatted version with breaks removed that should work for you (I did not test this code):
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!
")
}
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
", x, y)
} else {
fmt.Printf("rightclick at %d %d
", x, y)
}
}
C.XCloseDisplay(display)
}