diff --git a/shiny/driver/gldriver/cocoa.go b/shiny/driver/gldriver/cocoa.go index e13ac8027..edd8d101e 100644 --- a/shiny/driver/gldriver/cocoa.go +++ b/shiny/driver/gldriver/cocoa.go @@ -22,6 +22,7 @@ void stopDriver(); void makeCurrentContext(uintptr_t ctx); void flushContext(uintptr_t ctx); uintptr_t doNewWindow(int width, int height, char* title); +void doSetTitle(uintptr_t id, char* title); void doShowWindow(uintptr_t id); void doCloseWindow(uintptr_t id); uint64_t threadID(); @@ -81,6 +82,13 @@ func showWindow(w *windowImpl) { C.doShowWindow(C.uintptr_t(w.id)) } +func setTitle(id uintptr, title string) { + ctitle := C.CString(title) + defer C.free(unsafe.Pointer(ctitle)) + + C.doSetTitle(C.uintptr_t(id), ctitle) +} + //export preparedOpenGL func preparedOpenGL(id, ctx, vba uintptr) { theScreen.mu.Lock() diff --git a/shiny/driver/gldriver/cocoa.m b/shiny/driver/gldriver/cocoa.m index 2c8fd8376..89855246d 100644 --- a/shiny/driver/gldriver/cocoa.m +++ b/shiny/driver/gldriver/cocoa.m @@ -302,6 +302,14 @@ uintptr_t doNewWindow(int width, int height, char* title) { return (uintptr_t)view; } +void doSetTitle(uintptr_t viewID, char* title) { + ScreenGLView* view = (ScreenGLView*)viewID; + NSString* name = [[NSString alloc] initWithUTF8String:title]; + dispatch_async(dispatch_get_main_queue(), ^{ + [view.window setTitle:name]; + }); +} + void doShowWindow(uintptr_t viewID) { ScreenGLView* view = (ScreenGLView*)viewID; dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/shiny/driver/gldriver/other.go b/shiny/driver/gldriver/other.go index 0a0442545..49132814f 100644 --- a/shiny/driver/gldriver/other.go +++ b/shiny/driver/gldriver/other.go @@ -24,10 +24,11 @@ var errUnsupported = fmt.Errorf("gldriver: unsupported GOOS/GOARCH %s/%s or cgo func newWindow(opts *screen.NewWindowOptions) (uintptr, error) { return 0, errUnsupported } -func initWindow(id *windowImpl) {} -func showWindow(id *windowImpl) {} -func closeWindow(id uintptr) {} -func drawLoop(w *windowImpl) {} +func initWindow(id *windowImpl) {} +func showWindow(id *windowImpl) {} +func closeWindow(id uintptr) {} +func drawLoop(w *windowImpl) {} +func setTitle(id uintptr, title string) {} func surfaceCreate() error { return errUnsupported } func main(f func(screen.Screen)) error { return errUnsupported } diff --git a/shiny/driver/gldriver/win32.go b/shiny/driver/gldriver/win32.go index 8ece242f5..d019ac847 100755 --- a/shiny/driver/gldriver/win32.go +++ b/shiny/driver/gldriver/win32.go @@ -89,6 +89,10 @@ func showWindow(w *windowImpl) { func closeWindow(id uintptr) {} // TODO +func setTitle(id uintptr, title string) { + _ = win32.SetWindowTitle(syscall.Handle(id), title) +} + func drawLoop(w *windowImpl) { runtime.LockOSThread() diff --git a/shiny/driver/gldriver/window.go b/shiny/driver/gldriver/window.go index 82baf2c2c..08b3f6507 100644 --- a/shiny/driver/gldriver/window.go +++ b/shiny/driver/gldriver/window.go @@ -387,3 +387,7 @@ func (w *windowImpl) Publish() screen.PublishResult { return res } + +func (w *windowImpl) SetTitle(title string) { + setTitle(w.id, title) +} diff --git a/shiny/driver/gldriver/x11.c b/shiny/driver/gldriver/x11.c index dff6d2d64..9909ba30d 100644 --- a/shiny/driver/gldriver/x11.c +++ b/shiny/driver/gldriver/x11.c @@ -231,6 +231,12 @@ doCloseWindow(uintptr_t id) { XDestroyWindow(x_dpy, win); } +void +doSetTitle(uintptr_t id, char* title, int title_len) { + Window win = (Window)(id); + XChangeProperty(x_dpy, win, net_wm_name, utf8_string, 8, PropModeReplace, title, title_len); +} + uintptr_t doNewWindow(int width, int height, char* title, int title_len) { XSetWindowAttributes attr; diff --git a/shiny/driver/gldriver/x11.go b/shiny/driver/gldriver/x11.go index 4847e85b2..74f922803 100644 --- a/shiny/driver/gldriver/x11.go +++ b/shiny/driver/gldriver/x11.go @@ -23,6 +23,7 @@ void processEvents(); void makeCurrent(uintptr_t ctx); void swapBuffers(uintptr_t ctx); void doCloseWindow(uintptr_t id); +void doSetTitle(uintptr_t id, char* title, int title_len); uintptr_t doNewWindow(int width, int height, char* title, int title_len); uintptr_t doShowWindow(uintptr_t id); uintptr_t surfaceCreate(); @@ -98,6 +99,21 @@ func closeWindow(id uintptr) { } } +func setTitle(id uintptr, title string) { + ctitle := C.CString(title) + defer C.free(unsafe.Pointer(ctitle)) + + retc := make(chan uintptr) + uic <- uiClosure{ + f: func() uintptr { + C.doSetTitle(C.uintptr_t(id), ctitle, C.int(len(title))) + return 0 + }, + retc: retc, + } + <-retc +} + func drawLoop(w *windowImpl) { glcontextc <- w.ctx.(uintptr) go func() { diff --git a/shiny/driver/internal/win32/syscall_windows.go b/shiny/driver/internal/win32/syscall_windows.go index d71536d6b..82e3e88d7 100644 --- a/shiny/driver/internal/win32/syscall_windows.go +++ b/shiny/driver/internal/win32/syscall_windows.go @@ -169,17 +169,18 @@ func _HIWORD(l uintptr) uint16 { //sys _DispatchMessage(msg *_MSG) (ret int32) = user32.DispatchMessageW //sys _GetClientRect(hwnd syscall.Handle, rect *_RECT) (err error) = user32.GetClientRect //sys _GetWindowRect(hwnd syscall.Handle, rect *_RECT) (err error) = user32.GetWindowRect -//sys _GetKeyboardLayout(threadID uint32) (locale syscall.Handle) = user32.GetKeyboardLayout -//sys _GetKeyboardState(lpKeyState *byte) (err error) = user32.GetKeyboardState +//sys _GetKeyboardLayout(threadID uint32) (locale syscall.Handle) = user32.GetKeyboardLayout +//sys _GetKeyboardState(lpKeyState *byte) (err error) = user32.GetKeyboardState //sys _GetKeyState(virtkey int32) (keystatus int16) = user32.GetKeyState //sys _GetMessage(msg *_MSG, hwnd syscall.Handle, msgfiltermin uint32, msgfiltermax uint32) (ret int32, err error) [failretval==-1] = user32.GetMessageW //sys _LoadCursor(hInstance syscall.Handle, cursorName uintptr) (cursor syscall.Handle, err error) = user32.LoadCursorW //sys _LoadIcon(hInstance syscall.Handle, iconName uintptr) (icon syscall.Handle, err error) = user32.LoadIconW //sys _MoveWindow(hwnd syscall.Handle, x int32, y int32, w int32, h int32, repaint bool) (err error) = user32.MoveWindow //sys _PostMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult bool) = user32.PostMessageW -//sys _PostQuitMessage(exitCode int32) = user32.PostQuitMessage +//sys _PostQuitMessage(exitCode int32) = user32.PostQuitMessage //sys _RegisterClass(wc *_WNDCLASS) (atom uint16, err error) = user32.RegisterClassW //sys _ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) = user32.ShowWindow +//sys _SetWindowTextW(hwnd syscall.Handle, lpString *uint16) (err error) = user32.SetWindowTextW //sys _ScreenToClient(hwnd syscall.Handle, lpPoint *_POINT) (ok bool) = user32.ScreenToClient //sys _ToUnicodeEx(wVirtKey uint32, wScanCode uint32, lpKeyState *byte, pwszBuff *uint16, cchBuff int32, wFlags uint32, dwhkl syscall.Handle) (ret int32) = user32.ToUnicodeEx //sys _TranslateMessage(msg *_MSG) (done bool) = user32.TranslateMessage diff --git a/shiny/driver/internal/win32/win32.go b/shiny/driver/internal/win32/win32.go index 22a601395..359235ec5 100644 --- a/shiny/driver/internal/win32/win32.go +++ b/shiny/driver/internal/win32/win32.go @@ -175,6 +175,15 @@ func sendClose(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResul return _DefWindowProc(hwnd, uMsg, wParam, lParam) } +func SetWindowTitle(hwnd syscall.Handle, title string) error { + ctitle, err := syscall.UTF16PtrFromString(title) + if err != nil { + return err + } + + return _SetWindowTextW(hwnd, ctitle) +} + func sendMouseEvent(hwnd syscall.Handle, uMsg uint32, wParam, lParam uintptr) (lResult uintptr) { e := mouse.Event{ X: float32(_GET_X_LPARAM(lParam)), diff --git a/shiny/driver/internal/win32/zsyscall_windows.go b/shiny/driver/internal/win32/zsyscall_windows.go index 26999f652..424259910 100644 --- a/shiny/driver/internal/win32/zsyscall_windows.go +++ b/shiny/driver/internal/win32/zsyscall_windows.go @@ -1,4 +1,4 @@ -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT +// Code generated by 'go generate'; DO NOT EDIT. package win32 @@ -19,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -26,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -39,72 +40,38 @@ func errnoErr(e syscall.Errno) error { var ( moduser32 = windows.NewLazySystemDLL("user32.dll") - procGetDC = moduser32.NewProc("GetDC") - procReleaseDC = moduser32.NewProc("ReleaseDC") - procSendMessageW = moduser32.NewProc("SendMessageW") procCreateWindowExW = moduser32.NewProc("CreateWindowExW") procDefWindowProcW = moduser32.NewProc("DefWindowProcW") procDestroyWindow = moduser32.NewProc("DestroyWindow") procDispatchMessageW = moduser32.NewProc("DispatchMessageW") procGetClientRect = moduser32.NewProc("GetClientRect") - procGetWindowRect = moduser32.NewProc("GetWindowRect") + procGetDC = moduser32.NewProc("GetDC") + procGetKeyState = moduser32.NewProc("GetKeyState") procGetKeyboardLayout = moduser32.NewProc("GetKeyboardLayout") procGetKeyboardState = moduser32.NewProc("GetKeyboardState") - procGetKeyState = moduser32.NewProc("GetKeyState") procGetMessageW = moduser32.NewProc("GetMessageW") + procGetWindowRect = moduser32.NewProc("GetWindowRect") procLoadCursorW = moduser32.NewProc("LoadCursorW") procLoadIconW = moduser32.NewProc("LoadIconW") procMoveWindow = moduser32.NewProc("MoveWindow") procPostMessageW = moduser32.NewProc("PostMessageW") procPostQuitMessage = moduser32.NewProc("PostQuitMessage") procRegisterClassW = moduser32.NewProc("RegisterClassW") - procShowWindow = moduser32.NewProc("ShowWindow") + procReleaseDC = moduser32.NewProc("ReleaseDC") procScreenToClient = moduser32.NewProc("ScreenToClient") + procSendMessageW = moduser32.NewProc("SendMessageW") + procSetWindowTextW = moduser32.NewProc("SetWindowTextW") + procShowWindow = moduser32.NewProc("ShowWindow") procToUnicodeEx = moduser32.NewProc("ToUnicodeEx") procTranslateMessage = moduser32.NewProc("TranslateMessage") procUnregisterClassW = moduser32.NewProc("UnregisterClassW") ) -func GetDC(hwnd syscall.Handle) (dc syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall(procGetDC.Addr(), 1, uintptr(hwnd), 0, 0) - dc = syscall.Handle(r0) - if dc == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func ReleaseDC(hwnd syscall.Handle, dc syscall.Handle) (err error) { - r1, _, e1 := syscall.Syscall(procReleaseDC.Addr(), 2, uintptr(hwnd), uintptr(dc), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func sendMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) { - r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(uMsg), uintptr(wParam), uintptr(lParam), 0, 0) - lResult = uintptr(r0) - return -} - func _CreateWindowEx(exstyle uint32, className *uint16, windowText *uint16, style uint32, x int32, y int32, width int32, height int32, parent syscall.Handle, menu syscall.Handle, hInstance syscall.Handle, lpParam uintptr) (hwnd syscall.Handle, err error) { r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(windowText)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(parent), uintptr(menu), uintptr(hInstance), uintptr(lpParam)) hwnd = syscall.Handle(r0) if hwnd == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -118,11 +85,7 @@ func _DefWindowProc(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uin func _DestroyWindow(hwnd syscall.Handle) (err error) { r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -136,27 +99,26 @@ func _DispatchMessage(msg *_MSG) (ret int32) { func _GetClientRect(hwnd syscall.Handle, rect *_RECT) (err error) { r1, _, e1 := syscall.Syscall(procGetClientRect.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(rect)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _GetWindowRect(hwnd syscall.Handle, rect *_RECT) (err error) { - r1, _, e1 := syscall.Syscall(procGetWindowRect.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(rect)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func GetDC(hwnd syscall.Handle) (dc syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetDC.Addr(), 1, uintptr(hwnd), 0, 0) + dc = syscall.Handle(r0) + if dc == 0 { + err = errnoErr(e1) } return } +func _GetKeyState(virtkey int32) (keystatus int16) { + r0, _, _ := syscall.Syscall(procGetKeyState.Addr(), 1, uintptr(virtkey), 0, 0) + keystatus = int16(r0) + return +} + func _GetKeyboardLayout(threadID uint32) (locale syscall.Handle) { r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(threadID), 0, 0) locale = syscall.Handle(r0) @@ -166,30 +128,24 @@ func _GetKeyboardLayout(threadID uint32) (locale syscall.Handle) { func _GetKeyboardState(lpKeyState *byte) (err error) { r1, _, e1 := syscall.Syscall(procGetKeyboardState.Addr(), 1, uintptr(unsafe.Pointer(lpKeyState)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _GetKeyState(virtkey int32) (keystatus int16) { - r0, _, _ := syscall.Syscall(procGetKeyState.Addr(), 1, uintptr(virtkey), 0, 0) - keystatus = int16(r0) - return -} - func _GetMessage(msg *_MSG, hwnd syscall.Handle, msgfiltermin uint32, msgfiltermax uint32) (ret int32, err error) { r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(msgfiltermin), uintptr(msgfiltermax), 0, 0) ret = int32(r0) if ret == -1 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) + } + return +} + +func _GetWindowRect(hwnd syscall.Handle, rect *_RECT) (err error) { + r1, _, e1 := syscall.Syscall(procGetWindowRect.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(rect)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } @@ -198,11 +154,7 @@ func _LoadCursor(hInstance syscall.Handle, cursorName uintptr) (cursor syscall.H r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(hInstance), uintptr(cursorName), 0) cursor = syscall.Handle(r0) if cursor == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -211,11 +163,7 @@ func _LoadIcon(hInstance syscall.Handle, iconName uintptr) (icon syscall.Handle, r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(hInstance), uintptr(iconName), 0) icon = syscall.Handle(r0) if icon == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -224,16 +172,10 @@ func _MoveWindow(hwnd syscall.Handle, x int32, y int32, w int32, h int32, repain var _p0 uint32 if repaint { _p0 = 1 - } else { - _p0 = 0 } r1, _, e1 := syscall.Syscall6(procMoveWindow.Addr(), 6, uintptr(hwnd), uintptr(x), uintptr(y), uintptr(w), uintptr(h), uintptr(_p0)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -253,18 +195,16 @@ func _RegisterClass(wc *_WNDCLASS) (atom uint16, err error) { r0, _, e1 := syscall.Syscall(procRegisterClassW.Addr(), 1, uintptr(unsafe.Pointer(wc)), 0, 0) atom = uint16(r0) if atom == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) { - r0, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hwnd), uintptr(cmdshow), 0) - wasvisible = r0 != 0 +func ReleaseDC(hwnd syscall.Handle, dc syscall.Handle) (err error) { + r1, _, e1 := syscall.Syscall(procReleaseDC.Addr(), 2, uintptr(hwnd), uintptr(dc), 0) + if r1 == 0 { + err = errnoErr(e1) + } return } @@ -274,6 +214,26 @@ func _ScreenToClient(hwnd syscall.Handle, lpPoint *_POINT) (ok bool) { return } +func sendMessage(hwnd syscall.Handle, uMsg uint32, wParam uintptr, lParam uintptr) (lResult uintptr) { + r0, _, _ := syscall.Syscall6(procSendMessageW.Addr(), 4, uintptr(hwnd), uintptr(uMsg), uintptr(wParam), uintptr(lParam), 0, 0) + lResult = uintptr(r0) + return +} + +func _SetWindowTextW(hwnd syscall.Handle, lpString *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procSetWindowTextW.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(lpString)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func _ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) { + r0, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hwnd), uintptr(cmdshow), 0) + wasvisible = r0 != 0 + return +} + func _ToUnicodeEx(wVirtKey uint32, wScanCode uint32, lpKeyState *byte, pwszBuff *uint16, cchBuff int32, wFlags uint32, dwhkl syscall.Handle) (ret int32) { r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(wVirtKey), uintptr(wScanCode), uintptr(unsafe.Pointer(lpKeyState)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(wFlags), uintptr(dwhkl), 0, 0) ret = int32(r0) diff --git a/shiny/driver/mtldriver/window.go b/shiny/driver/mtldriver/window.go index 7bbb837ca..99b34052a 100644 --- a/shiny/driver/mtldriver/window.go +++ b/shiny/driver/mtldriver/window.go @@ -95,6 +95,10 @@ func (w *windowImpl) Publish() screen.PublishResult { return screen.PublishResult{} } +func (w *windowImpl) SetTitle(title string) { + w.window.SetTitle(title) +} + func (w *windowImpl) Upload(dp image.Point, src screen.Buffer, sr image.Rectangle) { draw.Draw(w.rgba, sr.Sub(sr.Min).Add(dp), src.RGBA(), sr.Min, draw.Src) } diff --git a/shiny/driver/windriver/syscall.go b/shiny/driver/windriver/syscall.go index e4790328d..265c67695 100644 --- a/shiny/driver/windriver/syscall.go +++ b/shiny/driver/windriver/syscall.go @@ -2,6 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall_windows.go package windriver diff --git a/shiny/driver/windriver/window.go b/shiny/driver/windriver/window.go index 9577f2c69..f987704a0 100644 --- a/shiny/driver/windriver/window.go +++ b/shiny/driver/windriver/window.go @@ -171,6 +171,10 @@ func (w *windowImpl) Publish() screen.PublishResult { return screen.PublishResult{} } +func (w *windowImpl) SetTitle(title string) { + _ = win32.SetWindowTitle(w.hwnd, title) +} + func init() { send := func(hwnd syscall.Handle, e interface{}) { theScreen.mu.Lock() diff --git a/shiny/driver/windriver/zsyscall_windows.go b/shiny/driver/windriver/zsyscall_windows.go index 18047b1cd..f78270146 100644 --- a/shiny/driver/windriver/zsyscall_windows.go +++ b/shiny/driver/windriver/zsyscall_windows.go @@ -1,4 +1,4 @@ -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT +// Code generated by 'go generate'; DO NOT EDIT. package windriver @@ -11,12 +11,37 @@ import ( var _ unsafe.Pointer +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return errERROR_EINVAL + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + var ( - modmsimg32 = windows.NewLazySystemDLL("msimg32.dll") modgdi32 = windows.NewLazySystemDLL("gdi32.dll") + modmsimg32 = windows.NewLazySystemDLL("msimg32.dll") moduser32 = windows.NewLazySystemDLL("user32.dll") - procAlphaBlend = modmsimg32.NewProc("AlphaBlend") procBitBlt = modgdi32.NewProc("BitBlt") procCreateCompatibleBitmap = modgdi32.NewProc("CreateCompatibleBitmap") procCreateCompatibleDC = modgdi32.NewProc("CreateCompatibleDC") @@ -24,35 +49,20 @@ var ( procCreateSolidBrush = modgdi32.NewProc("CreateSolidBrush") procDeleteDC = modgdi32.NewProc("DeleteDC") procDeleteObject = modgdi32.NewProc("DeleteObject") - procFillRect = moduser32.NewProc("FillRect") + procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps") procModifyWorldTransform = modgdi32.NewProc("ModifyWorldTransform") procSelectObject = modgdi32.NewProc("SelectObject") procSetGraphicsMode = modgdi32.NewProc("SetGraphicsMode") procSetWorldTransform = modgdi32.NewProc("SetWorldTransform") procStretchBlt = modgdi32.NewProc("StretchBlt") - procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps") + procAlphaBlend = modmsimg32.NewProc("AlphaBlend") + procFillRect = moduser32.NewProc("FillRect") ) -func _AlphaBlend(dcdest syscall.Handle, xoriginDest int32, yoriginDest int32, wDest int32, hDest int32, dcsrc syscall.Handle, xoriginSrc int32, yoriginSrc int32, wsrc int32, hsrc int32, ftn uintptr) (err error) { - r1, _, e1 := syscall.Syscall12(procAlphaBlend.Addr(), 11, uintptr(dcdest), uintptr(xoriginDest), uintptr(yoriginDest), uintptr(wDest), uintptr(hDest), uintptr(dcsrc), uintptr(xoriginSrc), uintptr(yoriginSrc), uintptr(wsrc), uintptr(hsrc), uintptr(ftn), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - func _BitBlt(dcdest syscall.Handle, xdest int32, ydest int32, width int32, height int32, dcsrc syscall.Handle, xsrc int32, ysrc int32, rop uint32) (err error) { r1, _, e1 := syscall.Syscall9(procBitBlt.Addr(), 9, uintptr(dcdest), uintptr(xdest), uintptr(ydest), uintptr(width), uintptr(height), uintptr(dcsrc), uintptr(xsrc), uintptr(ysrc), uintptr(rop)) if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -61,11 +71,7 @@ func _CreateCompatibleBitmap(dc syscall.Handle, width int32, height int32) (bitm r0, _, e1 := syscall.Syscall(procCreateCompatibleBitmap.Addr(), 3, uintptr(dc), uintptr(width), uintptr(height)) bitmap = syscall.Handle(r0) if bitmap == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -74,11 +80,7 @@ func _CreateCompatibleDC(dc syscall.Handle) (newdc syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procCreateCompatibleDC.Addr(), 1, uintptr(dc), 0, 0) newdc = syscall.Handle(r0) if newdc == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -87,11 +89,7 @@ func _CreateDIBSection(dc syscall.Handle, bmi *_BITMAPINFO, usage uint32, bits * r0, _, e1 := syscall.Syscall6(procCreateDIBSection.Addr(), 6, uintptr(dc), uintptr(unsafe.Pointer(bmi)), uintptr(usage), uintptr(unsafe.Pointer(bits)), uintptr(section), uintptr(offset)) bitmap = syscall.Handle(r0) if bitmap == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -100,11 +98,7 @@ func _CreateSolidBrush(color _COLORREF) (brush syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procCreateSolidBrush.Addr(), 1, uintptr(color), 0, 0) brush = syscall.Handle(r0) if brush == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -112,11 +106,7 @@ func _CreateSolidBrush(color _COLORREF) (brush syscall.Handle, err error) { func _DeleteDC(dc syscall.Handle) (err error) { r1, _, e1 := syscall.Syscall(procDeleteDC.Addr(), 1, uintptr(dc), 0, 0) if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -124,35 +114,21 @@ func _DeleteDC(dc syscall.Handle) (err error) { func _DeleteObject(object syscall.Handle) (err error) { r1, _, e1 := syscall.Syscall(procDeleteObject.Addr(), 1, uintptr(object), 0, 0) if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _FillRect(dc syscall.Handle, rc *_RECT, brush syscall.Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFillRect.Addr(), 3, uintptr(dc), uintptr(unsafe.Pointer(rc)), uintptr(brush)) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } +func _GetDeviceCaps(dc syscall.Handle, index int32) (ret int32) { + r0, _, _ := syscall.Syscall(procGetDeviceCaps.Addr(), 2, uintptr(dc), uintptr(index), 0) + ret = int32(r0) return } func _ModifyWorldTransform(dc syscall.Handle, x *_XFORM, mode uint32) (err error) { r1, _, e1 := syscall.Syscall(procModifyWorldTransform.Addr(), 3, uintptr(dc), uintptr(unsafe.Pointer(x)), uintptr(mode)) if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -161,11 +137,7 @@ func _SelectObject(dc syscall.Handle, gdiobj syscall.Handle) (newobj syscall.Han r0, _, e1 := syscall.Syscall(procSelectObject.Addr(), 2, uintptr(dc), uintptr(gdiobj), 0) newobj = syscall.Handle(r0) if newobj == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -174,11 +146,7 @@ func _SetGraphicsMode(dc syscall.Handle, mode int32) (oldmode int32, err error) r0, _, e1 := syscall.Syscall(procSetGraphicsMode.Addr(), 2, uintptr(dc), uintptr(mode), 0) oldmode = int32(r0) if oldmode == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -186,11 +154,7 @@ func _SetGraphicsMode(dc syscall.Handle, mode int32) (oldmode int32, err error) func _SetWorldTransform(dc syscall.Handle, x *_XFORM) (err error) { r1, _, e1 := syscall.Syscall(procSetWorldTransform.Addr(), 2, uintptr(dc), uintptr(unsafe.Pointer(x)), 0) if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -198,17 +162,23 @@ func _SetWorldTransform(dc syscall.Handle, x *_XFORM) (err error) { func _StretchBlt(dcdest syscall.Handle, xdest int32, ydest int32, wdest int32, hdest int32, dcsrc syscall.Handle, xsrc int32, ysrc int32, wsrc int32, hsrc int32, rop uint32) (err error) { r1, _, e1 := syscall.Syscall12(procStretchBlt.Addr(), 11, uintptr(dcdest), uintptr(xdest), uintptr(ydest), uintptr(wdest), uintptr(hdest), uintptr(dcsrc), uintptr(xsrc), uintptr(ysrc), uintptr(wsrc), uintptr(hsrc), uintptr(rop), 0) if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _GetDeviceCaps(dc syscall.Handle, index int32) (ret int32) { - r0, _, _ := syscall.Syscall(procGetDeviceCaps.Addr(), 2, uintptr(dc), uintptr(index), 0) - ret = int32(r0) +func _AlphaBlend(dcdest syscall.Handle, xoriginDest int32, yoriginDest int32, wDest int32, hDest int32, dcsrc syscall.Handle, xoriginSrc int32, yoriginSrc int32, wsrc int32, hsrc int32, ftn uintptr) (err error) { + r1, _, e1 := syscall.Syscall12(procAlphaBlend.Addr(), 11, uintptr(dcdest), uintptr(xoriginDest), uintptr(yoriginDest), uintptr(wDest), uintptr(hDest), uintptr(dcsrc), uintptr(xoriginSrc), uintptr(yoriginSrc), uintptr(wsrc), uintptr(hsrc), uintptr(ftn), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func _FillRect(dc syscall.Handle, rc *_RECT, brush syscall.Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFillRect.Addr(), 3, uintptr(dc), uintptr(unsafe.Pointer(rc)), uintptr(brush)) + if r1 == 0 { + err = errnoErr(e1) + } return } diff --git a/shiny/driver/x11driver/window.go b/shiny/driver/x11driver/window.go index f77b876e5..0e05d82b9 100644 --- a/shiny/driver/x11driver/window.go +++ b/shiny/driver/x11driver/window.go @@ -106,6 +106,10 @@ func (w *windowImpl) Publish() screen.PublishResult { return screen.PublishResult{} } +func (w *windowImpl) SetTitle(title string) { + xproto.ChangeProperty(w.s.xc, xproto.PropModeReplace, w.xw, w.s.atomNETWMName, w.s.atomUTF8String, 8, uint32(len(title)), []byte(title)) +} + func (w *windowImpl) handleConfigureNotify(ev xproto.ConfigureNotifyEvent) { // TODO: does the order of these lifecycle and size events matter? Should // they really be a single, atomic event? diff --git a/shiny/screen/screen.go b/shiny/screen/screen.go index 5d89fe8c2..1dbcd9041 100644 --- a/shiny/screen/screen.go +++ b/shiny/screen/screen.go @@ -217,6 +217,9 @@ type Window interface { // Publish flushes any pending Upload and Draw calls to the window, and // swaps the back buffer to the front. Publish() PublishResult + + // SetTitle changes the window's title. + SetTitle(title string) } // PublishResult is the result of an Window.Publish call.