func New() *Window { xWnd := C.XCreateWindow( dpy, root, 0, 0, 500, 500, 0, C.XDefaultDepth(dpy, 0), C.InputOutput, C.XDefaultVisual(dpy, 0), C.CWBackPixel, &attributes, ) wdw := C.CString("WM_DELETE_WINDOW") wmDelete := C.XInternAtom(dpy, wdw, 1) C.free(unsafe.Pointer(wdw)) fmt.Println(wmDelete) C.XSetWMProtocols(dpy, xWnd, &wmDelete, 1) C.XSelectInput(dpy, xWnd, C.ExposureMask|C.KeyPressMask) C.XMapWindow(dpy, xWnd) wnd := &Window{ id: uintptr(xWnd), } wndMap[wnd.id] = wnd return wnd }
func XMain(callbacks Callbacks) { dpy := C.XOpenDisplay(nil) w := C.XCreateSimpleWindow(dpy, C.XDefaultRootWindow(dpy), 0, 0, 600, 400, 0, 0, 0) C.XSelectInput(dpy, w, C.StructureNotifyMask|C.SubstructureNotifyMask|C.ExposureMask) C.XMapWindow(dpy, w) win := Window{dpy: dpy, xw: w} visual := C.XDefaultVisual(dpy, 0) surf := cairo.XlibSurfaceCreate(unsafe.Pointer(dpy), uint64(win.xw), unsafe.Pointer(visual), 10, 10) for { var e C.XEvent C.XNextEvent(dpy, &e) typ := XEventType(*(*C.int)(unsafe.Pointer(&e))) // log.Printf("X event: %s", typ) switch typ { case C.ConfigureNotify: e := (*C.XConfigureEvent)(unsafe.Pointer(&e)) surf.SetSize(int(e.width), int(e.height)) case C.Expose: cr := cairo.Create(surf.Surface) callbacks.Draw(cr, surf) default: // log.Printf("unknown X event %s", typ) } } }
func CreateXWindow(width, height int) (*XWindow, error) { C.XInitThreads() W := &XWindow{} W.Display = C.XOpenDisplay(nil) if W.Display == nil { return &XWindow{}, errors.New("Can't open display") } W.Window = C.XCreateSimpleWindow(W.Display, C.XDefaultRootWindow(W.Display), 0, 0, C.uint(width), C.uint(height), 0, 0, 0xFF151515) C.XSetWindowBackgroundPixmap(W.Display, W.Window, 0) // This avoids flickering on resize C.XMapWindow(W.Display, W.Window) C.XStoreName(W.Display, W.Window, C.CString("gowitt")) C.XSelectInput(W.Display, W.Window, C.ExposureMask|C.KeyPressMask|C.ButtonPressMask) C.XFlush(W.Display) // Cairo W.Surface = C.cairo_xlib_surface_create(W.Display, C.Drawable(W.Window), C.XDefaultVisual(W.Display, 0), C.int(width), C.int(height)) C.cairo_xlib_surface_set_size(W.Surface, C.int(width), C.int(height)) W.Cairo = C.cairo_create(W.Surface) // Pango InitLayoutsCache(W.Cairo) W.PangoContext = C.pango_cairo_create_context(W.Cairo) W.FontDesc = C.pango_font_description_from_string(C.CString("Sans 10")) W.AttrList = C.pango_attr_list_new() placeholderImage = C.cairo_image_surface_create_from_png(C.CString("test.png")) W.UserImages = NewImageCache(func() { var ev C.XEvent exev := (*C.XExposeEvent)(unsafe.Pointer(&ev)) exev._type = C.Expose exev.count = 0 exev.window = W.Window exev.send_event = 1 exev.display = W.Display C.XSendEvent(W.Display, W.Window, 0, C.ExposureMask, &ev) C.XFlush(W.Display) }) return W, nil }
// Resize handles a resize of the window. func (win *Window) resize(w, h int) { if win.width == w && win.height == h { return } win.width, win.height = w, h if win.winSurface == nil { visual := C.XDefaultVisual(win.dpy.dpy, 0) win.winSurface = cairo.XlibSurfaceCreate( unsafe.Pointer(win.dpy.dpy), uint64(win.xw), unsafe.Pointer(visual), w, h) } else { win.winSurface.SetSize(w, h) } win.bufSurface = &cairo.XlibSurface{win.winSurface.CreateSimilar(cairo.ContentColor, w, h)} cr := cairo.Create(win.bufSurface.Surface) win.delegate.Draw(cr) win.repaint(0, 0, w, h) }