-
Notifications
You must be signed in to change notification settings - Fork 75
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
Using shm.GetImage().Reply() #28
Comments
Honestly, I don't know (but I'd like to). I've never used |
Indeed, that was the first place I went looking. It seems I need to brush up on tmpfs/shm, especially as it relates to X11 in general. I'll continue looking into it and reply with any findings. |
@Jsewill yes, please do! I'm personally quite carious. Even if you're findings are, "I found this good C example but I can't translate it to Go. Can you help?" :-) |
Well, I was able to use shm.NewSegId(), shm.CreateSegment().Reply(), and shm.GetImage().Reply() without error. This gets me a segment ID and file descriptor (I think), and has X create the image in that segment. I'm not really sure how to read it. In my research earlier in the week, I came across an example in C from the VLC project: https://github.com/videolan/vlc/blob/master/modules/access/screen/xcb.c . This is the best example I have found yet. Perhaps I need to attach and detach the segment to and from X and my program, though I was hoping this was happening automatically. As far as I know, SHM related stuff was explicitly left out of Golang's builtin, "syscall". Short of using a Go wrapper for the C shm related functions, do you have any insight regarding all this? |
I've made some progress, but now I'm hitting a wall. The X server comes back with "BadIDChoice" when attempting to attach an SHM segment, whether I create the segment using shm.CreateSegment() or wrapped C functions. Any ideas? |
After revisiting this, I figured out the proper arguements and their order, and with that X stops complaining. The current process is as such:
I still have a problem accessing the data from the segment yet, but I'll work through that when I have more time to work on it. |
@Jsewill Can you post the code for this? |
Here is working version, figured it out. package main
/*
#include <sys/ipc.h>
#include <sys/shm.h>
*/
import "C"
import (
"github.com/BurntSushi/xgb"
"github.com/BurntSushi/xgb/shm"
"github.com/BurntSushi/xgb/xproto"
"fmt"
"image"
"time"
"unsafe"
)
func main() {
scr := newXgbShmScreen()
for i := 0; i < 100; i++ {
start := time.Now()
scr.capture()
elapsed := time.Since(start)
fmt.Printf("%d\n", elapsed.Nanoseconds())
}
scr.Close()
}
type xgbShmScreen struct {
conn *xgb.Conn
screen *xproto.ScreenInfo
shmId int
data unsafe.Pointer
shmSize int
seg shm.Seg
}
func newXgbShmScreen() *xgbShmScreen {
var scr xgbShmScreen
var err error
scr.conn, err = xgb.NewConn()
if err != nil || shm.Init(scr.conn) != nil {
return nil
}
scr.screen = xproto.Setup(scr.conn).DefaultScreen(scr.conn)
scr.shmSize = int(scr.screen.WidthInPixels) * int(scr.screen.HeightInPixels) * 4
scr.shmId = int(C.shmget(C.IPC_PRIVATE, C.size_t(scr.shmSize), C.IPC_CREAT|0777))
if scr.shmId == -1 {
return nil
}
scr.data = C.shmat(C.int(scr.shmId), nil, 0)
scr.seg, err = shm.NewSegId(scr.conn)
if err != nil {
return nil
}
shm.AttachChecked(scr.conn, scr.seg, uint32(scr.shmId), false)
return &scr
}
func (scr *xgbShmScreen) capture() (imgData []byte, err error) {
_, err = shm.GetImage(scr.conn, xproto.Drawable(scr.screen.Root), 0, 0, scr.screen.WidthInPixels, scr.screen.HeightInPixels, 0xffffffff, byte(xproto.ImageFormatZPixmap), scr.seg, 0).Reply()
if err != nil {
return nil, err
}
imgData = (*[1 << 30]byte)(scr.data)[:scr.shmSize:scr.shmSize]
return imgData, nil
}
func (scr *xgbShmScreen) Close() {
shm.Detach(scr.conn, scr.seg)
C.shmctl(C.int(scr.shmId), C.IPC_RMID, nil)
C.shmdt(scr.data)
scr.conn.Close()
}
|
This is not a bug, just a lack of understanding on my part. I have put xproto.GetImage() to good use in a project I'm working on, but I'd like to use shm.GetImage() to get an image from the X server via SHM, where should I start? I apologize if it is inappropriate for me to post this as an issue, and I'd be glad to delete it if needed.
The text was updated successfully, but these errors were encountered: