Fixed errors with Area on Windows. Woo!
This commit is contained in:
parent
57df87f11d
commit
96c81996ba
|
@ -258,7 +258,7 @@ static void scrollArea(HWND hwnd, void *data, WPARAM wParam, int which)
|
||||||
|
|
||||||
// NOW redraw it
|
// NOW redraw it
|
||||||
if (UpdateWindow(hwnd) == 0)
|
if (UpdateWindow(hwnd) == 0)
|
||||||
panic("error updating Area after scrolling", GetLastError());
|
xpanic("error updating Area after scrolling", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustAreaScrollbars(HWND hwnd, void *data)
|
static void adjustAreaScrollbars(HWND hwnd, void *data)
|
||||||
|
@ -305,7 +305,7 @@ void repaintArea(HWND hwnd)
|
||||||
xpanic("error repainting Area after event", GetLastError());
|
xpanic("error repainting Area after event", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
void areaMouseEvent(HWND hwnd, void *data, DWORD button, BOOL up, LPARAM lParam)
|
void areaMouseEvent(HWND hwnd, void *data, DWORD button, BOOL up, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ void areaMouseEvent(HWND hwnd, void *data, DWORD button, BOOL up, LPARAM lParam)
|
||||||
getScrollPos(hwnd, &xpos, &ypos);
|
getScrollPos(hwnd, &xpos, &ypos);
|
||||||
xpos += GET_X_LPARAM(lParam);
|
xpos += GET_X_LPARAM(lParam);
|
||||||
ypos += GET_Y_LPARAM(lParam);
|
ypos += GET_Y_LPARAM(lParam);
|
||||||
finishAreaMouseEvent(data, button, up, xpos, ypos);
|
finishAreaMouseEvent(data, button, up, wParam, xpos, ypos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
@ -363,34 +363,34 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
|
||||||
// and don't eat the click, as we want to handle clicks that switch into Windows with Areas from other windows
|
// and don't eat the click, as we want to handle clicks that switch into Windows with Areas from other windows
|
||||||
return MA_ACTIVATE;
|
return MA_ACTIVATE;
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
areaMouseEvent(hwnd, data, 0, FALSE, lParam);
|
areaMouseEvent(hwnd, data, 0, FALSE, wParam, lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
areaMouseEvent(hwnd, data, 1, FALSE, lParam);
|
areaMouseEvent(hwnd, data, 1, FALSE, wParam, lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
areaMouseEvent(hwnd, data, 1, TRUE, lParam);
|
areaMouseEvent(hwnd, data, 1, TRUE, wParam, lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_MBUTTONDOWN:
|
case WM_MBUTTONDOWN:
|
||||||
areaMouseEvent(hwnd, data, 2, FALSE, lParam);
|
areaMouseEvent(hwnd, data, 2, FALSE, wParam, lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_MBUTTONUP:
|
case WM_MBUTTONUP:
|
||||||
areaMouseEvent(hwnd, data, 2, TRUE, lParam);
|
areaMouseEvent(hwnd, data, 2, TRUE, wParam, lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
areaMouseEvent(hwnd, data, 3, FALSE, lParam);
|
areaMouseEvent(hwnd, data, 3, FALSE, wParam, lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_RBUTTONUP:
|
case WM_RBUTTONUP:
|
||||||
areaMouseEvent(hwnd, data, 3, TRUE, lParam);
|
areaMouseEvent(hwnd, data, 3, TRUE, wParam, lParam);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_XBUTTONDOWN:
|
case WM_XBUTTONDOWN:
|
||||||
// values start at 1; we want them to start at 4
|
// values start at 1; we want them to start at 4
|
||||||
which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3;
|
which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3;
|
||||||
areaMouseEvent(hwnd, data, which, FALSE, lParam);
|
areaMouseEvent(hwnd, data, which, FALSE, wParam, lParam);
|
||||||
return TRUE; // XBUTTON messages are different!
|
return TRUE; // XBUTTON messages are different!
|
||||||
case WM_XBUTTONUP:
|
case WM_XBUTTONUP:
|
||||||
which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3;
|
which = (DWORD) GET_XBUTTON_WPARAM(wParam) + 3;
|
||||||
areaMouseEvent(hwnd, data, which, TRUE, lParam);
|
areaMouseEvent(hwnd, data, which, TRUE, wParam, lParam);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
areaKeyEvent(data, FALSE, wParam, lParam);
|
areaKeyEvent(data, FALSE, wParam, lParam);
|
||||||
|
|
|
@ -20,10 +20,10 @@ type area struct {
|
||||||
clickCounter *clickCounter
|
clickCounter *clickCounter
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerAreaWndClass() (err error) {
|
func makeAreaWindowClass() error {
|
||||||
var errmsg *C.char
|
var errmsg *C.char
|
||||||
|
|
||||||
err := C.makeWindowWindowClass(&errmsg)
|
err := C.makeAreaWindowClass(&errmsg)
|
||||||
if err != 0 || errmsg != nil {
|
if err != 0 || errmsg != nil {
|
||||||
return fmt.Errorf("%s: %v", C.GoString(errmsg), syscall.Errno(err))
|
return fmt.Errorf("%s: %v", C.GoString(errmsg), syscall.Errno(err))
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ func newArea(ab *areabase) Area {
|
||||||
clickCounter: new(clickCounter),
|
clickCounter: new(clickCounter),
|
||||||
}
|
}
|
||||||
a._hwnd = C.newArea(unsafe.Pointer(a))
|
a._hwnd = C.newArea(unsafe.Pointer(a))
|
||||||
a.SetSize(width, height)
|
a.SetSize(a.width, a.height)
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func doPaint(xrect *C.RECT, hscroll C.int, vscroll C.int, data unsafe.Pointer, d
|
||||||
cliprect := image.Rect(int(xrect.left), int(xrect.top), int(xrect.right), int(xrect.bottom))
|
cliprect := image.Rect(int(xrect.left), int(xrect.top), int(xrect.right), int(xrect.bottom))
|
||||||
cliprect = cliprect.Add(image.Pt(int(hscroll), int(vscroll))) // adjust by scroll position
|
cliprect = cliprect.Add(image.Pt(int(hscroll), int(vscroll))) // adjust by scroll position
|
||||||
// make sure the cliprect doesn't fall outside the size of the Area
|
// make sure the cliprect doesn't fall outside the size of the Area
|
||||||
cliprect = cliprect.Intersect(image.Rect(0, 0, a.areawidth, a.areaheight))
|
cliprect = cliprect.Intersect(image.Rect(0, 0, a.width, a.height))
|
||||||
if !cliprect.Empty() { // we have an update rect
|
if !cliprect.Empty() { // we have an update rect
|
||||||
i := a.handler.Paint(cliprect)
|
i := a.handler.Paint(cliprect)
|
||||||
*dx = C.intptr_t(i.Rect.Dx())
|
*dx = C.intptr_t(i.Rect.Dx())
|
||||||
|
@ -68,10 +68,10 @@ func doPaint(xrect *C.RECT, hscroll C.int, vscroll C.int, data unsafe.Pointer, d
|
||||||
}
|
}
|
||||||
|
|
||||||
//export dotoARGB
|
//export dotoARGB
|
||||||
func dotoARGB(img unsafe.Pointer, ppvBIts unsafe.Pointer) {
|
func dotoARGB(img unsafe.Pointer, ppvBits unsafe.Pointer) {
|
||||||
i := (*image.RGBA)(unsafe.Pointer(img))
|
i := (*image.RGBA)(unsafe.Pointer(img))
|
||||||
// the bitmap Windows gives us has a stride == width
|
// the bitmap Windows gives us has a stride == width
|
||||||
toARGB(i, unsafe.Pointer(ppvBits), i.Rect.Dx() * 4)
|
toARGB(i, uintptr(ppvBits), i.Rect.Dx() * 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export areaWidthLONG
|
//export areaWidthLONG
|
||||||
|
@ -108,13 +108,13 @@ func getModifiers() (m Modifiers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//export finishAreaMouseEvent
|
//export finishAreaMouseEvent
|
||||||
func finishAreaMouseEvent(data unsafe.Pointer, cbutton C.DWORD, up C.BOOL, xpos C.int, ypos C.int) {
|
func finishAreaMouseEvent(data unsafe.Pointer, cbutton C.DWORD, up C.BOOL, wParam C.WPARAM, xpos C.int, ypos C.int) {
|
||||||
var me MouseEvent
|
var me MouseEvent
|
||||||
|
|
||||||
a := (*area)(data)
|
a := (*area)(data)
|
||||||
button := uint(cbutton)
|
button := uint(cbutton)
|
||||||
me.Pos = image.Pt(int(xpos), int(ypos))
|
me.Pos = image.Pt(int(xpos), int(ypos))
|
||||||
if !me.Pos.In(image.Rect(0, 0, s.areawidth, s.areaheight)) { // outside the actual Area; no event
|
if !me.Pos.In(image.Rect(0, 0, a.width, a.height)) { // outside the actual Area; no event
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if up != C.FALSE {
|
if up != C.FALSE {
|
||||||
|
@ -127,30 +127,32 @@ func finishAreaMouseEvent(data unsafe.Pointer, cbutton C.DWORD, up C.BOOL, xpos
|
||||||
maxTime := C.GetDoubleClickTime()
|
maxTime := C.GetDoubleClickTime()
|
||||||
// ignore zero returns and errors; MSDN says zero will be returned on error but that GetLastError() is meaningless
|
// ignore zero returns and errors; MSDN says zero will be returned on error but that GetLastError() is meaningless
|
||||||
xdist := C.GetSystemMetrics(C.SM_CXDOUBLECLK)
|
xdist := C.GetSystemMetrics(C.SM_CXDOUBLECLK)
|
||||||
ydist, _, _ := C.GetSystemMetrics(C.SM_CYDOUBLECLK)
|
ydist := C.GetSystemMetrics(C.SM_CYDOUBLECLK)
|
||||||
me.Count = s.clickCounter.click(button, me.Pos.X, me.Pos.Y,
|
me.Count = a.clickCounter.click(button, me.Pos.X, me.Pos.Y,
|
||||||
time, maxTime, int(xdist/2), int(ydist/2))
|
uintptr(time), uintptr(maxTime), int(xdist/2), int(ydist/2))
|
||||||
}
|
}
|
||||||
// though wparam will contain control and shift state, let's use just one function to get modifiers for both keyboard and mouse events; it'll work the same anyway since we have to do this for alt and windows key (super)
|
// though wparam will contain control and shift state, let's use just one function to get modifiers for both keyboard and mouse events; it'll work the same anyway since we have to do this for alt and windows key (super)
|
||||||
me.Modifiers = getModifiers()
|
me.Modifiers = getModifiers()
|
||||||
if button != 1 && (wparam&_MK_LBUTTON) != 0 {
|
// TODO make wParam unsigned
|
||||||
|
// TODO XBUTTONs use something different
|
||||||
|
if button != 1 && (wParam & C.MK_LBUTTON) != 0 {
|
||||||
me.Held = append(me.Held, 1)
|
me.Held = append(me.Held, 1)
|
||||||
}
|
}
|
||||||
if button != 2 && (wparam&_MK_MBUTTON) != 0 {
|
if button != 2 && (wParam & C.MK_MBUTTON) != 0 {
|
||||||
me.Held = append(me.Held, 2)
|
me.Held = append(me.Held, 2)
|
||||||
}
|
}
|
||||||
if button != 3 && (wparam&_MK_RBUTTON) != 0 {
|
if button != 3 && (wParam & C.MK_RBUTTON) != 0 {
|
||||||
me.Held = append(me.Held, 3)
|
me.Held = append(me.Held, 3)
|
||||||
}
|
}
|
||||||
if button != 4 && (wparam&_MK_XBUTTON1) != 0 {
|
if button != 4 && (wParam & C.MK_XBUTTON1) != 0 {
|
||||||
me.Held = append(me.Held, 4)
|
me.Held = append(me.Held, 4)
|
||||||
}
|
}
|
||||||
if button != 5 && (wparam&_MK_XBUTTON2) != 0 {
|
if button != 5 && (wParam & C.MK_XBUTTON2) != 0 {
|
||||||
me.Held = append(me.Held, 5)
|
me.Held = append(me.Held, 5)
|
||||||
}
|
}
|
||||||
repaint := a.handler.Mouse(me)
|
repaint := a.handler.Mouse(me)
|
||||||
if repaint {
|
if repaint {
|
||||||
C.repaintArea(a.hwnd)
|
a.RepaintAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,10 +187,11 @@ func areaKeyEvent(data unsafe.Pointer, up C.BOOL, wParam C.WPARAM, lParam C.LPAR
|
||||||
// no key, extkey, or modifiers; do nothing
|
// no key, extkey, or modifiers; do nothing
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ke.Up = up
|
ke.Up = up != C.FALSE
|
||||||
|
// TODO repaint may no longer be needed
|
||||||
repaint := a.handler.Key(ke)
|
repaint := a.handler.Key(ke)
|
||||||
if repaint {
|
if repaint {
|
||||||
C.repaintArea(a)
|
a.RepaintAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,8 +306,8 @@ func (a *area) preferredSize(d *sizing) (width, height int) {
|
||||||
return a.width, a.height
|
return a.width, a.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *area) commitResize(a *allocation, d *sizing) {
|
func (a *area) commitResize(c *allocation, d *sizing) {
|
||||||
basecommitResize(a, a, d)
|
basecommitResize(a, c, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *area) getAuxResizeInfo(d *sizing) {
|
func (a *area) getAuxResizeInfo(d *sizing) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// #cgo LDFLAGS: -luser32 -lkernel32 -lgdi32 -luxtheme
|
// #cgo LDFLAGS: -luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32
|
||||||
// #include "winapi_windows.h"
|
// #include "winapi_windows.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <uxtheme.h>
|
#include <uxtheme.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
|
||||||
/* global messages unique to everything */
|
/* global messages unique to everything */
|
||||||
enum {
|
enum {
|
||||||
|
|
Loading…
Reference in New Issue