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 }
func init() { // txt[KeyPress] = "KeyPress" txt[KeyRelease] = "KeyRelease" txt[ButtonPress] = "ButtonPress" txt[ButtonRelease] = "ButtonRelease" txt[MotionNotify] = "MotionNotify" txt[EnterNotify] = "EnterNotify" txt[LeaveNotify] = "LeaveNotify" txt[FocusIn] = "FocusIn" txt[FocusOut] = "FocusOut" txt[KeymapNotify] = "KeymapNotify" txt[Expose] = "Expose" txt[GraphicsExpose] = "GraphicsExpose" txt[NoExpose] = "NoExpose" txt[VisibilityNotify] = "VisibilityNotify" txt[CreateNotify] = "CreateNotify" txt[DestroyNotify] = "DestroyNotify" txt[UnmapNotify] = "UnmapNotify" txt[MapNotify] = "MapNotify" txt[MapRequest] = "MapRequest" txt[ReparentNotify] = "ReparentNotify" txt[ConfigureNotify] = "ConfigureNotify" txt[ConfigureRequest] = "ConfigureRequest" txt[GravityNotify] = "GravityNotify" txt[ResizeRequest] = "ResizeRequest" txt[CirculateNotify] = "CirculateNotify" txt[CirculateRequest] = "CirculateRequest" txt[PropertyNotify] = "PropertyNotify" txt[SelectionClear] = "SelectionClear" txt[SelectionRequest] = "SelectionRequest" txt[SelectionNotify] = "SelectionNotify" txt[ColormapNotify] = "ColormapNotify" txt[ClientMessage] = "ClientMessage" txt[MappingNotify] = "MappingNotify" txt[GenericEvent] = "GenericEvent" txt[LASTEvent] = "LASTEvent" if C.XInitThreads() == 0 { panic("XKern.XInitThreads error") } }
// GRRTHREADS is a dirty hack to prevent threads related crashs. // func GRRTHREADS() { C.XInitThreads() }
// !!! make sure XInitThreads is called before gtk_init. // http://stackoverflow.com/questions/18647475/threading-problems-with-gtk. func init() { C.XInitThreads() }