func (ic *contextInternal) initializeFromSettings(settings ContextSettings, width, height int) ThreadError { ic.deactivateSignal = make(chan bool) ic.settings = settings ic.window = createHiddenWindow(width, height) if ic.window == nil { // C.GetLastError() return NewThreadError(fmt.Errorf("could not create window (%d)", C.GetLastError()), true) } ic.ownsWindow = true ic.hdc = C.GetDC(ic.window) if ic.hdc == nil { return NewThreadError(errors.New("no device context"), true) } if sharedContext == nil { // if there is no shared context, we are it ic.isSharedContext = true pfd := C.PIXELFORMATDESCRIPTOR{ nSize: C.PIXELFORMATDESCRIPTOR_size, // size of this pfd nVersion: 1, // version number iPixelType: C.PFD_TYPE_RGBA, // RGBA type cColorBits: 24, // 24-bit color depth cDepthBits: 32, // 32-bit z-buffer iLayerType: C.PFD_MAIN_PLANE, // main layer // support window | OpenGL | double buffer dwFlags: C.PFD_DRAW_TO_WINDOW | C.PFD_SUPPORT_OPENGL | C.PFD_DOUBLEBUFFER, } // get the best available match of pixel format for the device context // make that the pixel format of the device context if iPixelFormat := C.ChoosePixelFormat(ic.hdc, &pfd); iPixelFormat == 0 { return NewThreadError(fmt.Errorf("sharedContext: ChoosePixelFormat failed (%d)", C.GetLastError()), true) } else if C.SetPixelFormat(ic.hdc, iPixelFormat, &pfd) == C.FALSE { return NewThreadError(fmt.Errorf("sharedContext: SetPixelFormat failed (%d)", C.GetLastError()), true) } ic.context = C.wglCreateContext(ic.hdc) if ic.context == nil { return NewThreadError(fmt.Errorf("sharedContext: wglCreateContext failed (%d)", C.GetLastError()), true) } } else { // otherwise we push the commands onto the shared context thread bitsPerPixel := GetDefaultMonitor().GetDesktopMode().BitsPerPixel ic.context = createContext(&sharedContext.internal.procs, sharedContext.internal.context, ic.hdc, bitsPerPixel, &ic.settings) if ic.context == nil { return NewThreadError(fmt.Errorf("could not create context (%d)", C.GetLastError()), true) } } // signal because we start out deactivated ic.signalDeactivation() return nil }
func getNativeName(DeviceInfoSet C.HDEVINFO, DeviceInfoData C.PSP_DEVINFO_DATA) (string, error) { key := C.SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, C.DICS_FLAG_GLOBAL, 0, C.DIREG_DEV, C.KEY_READ) defer C.RegCloseKey(key) if C.is_INVALID_HANDLE_VALUE(unsafe.Pointer(key)) != C.FALSE { return "", errors.New(fmt.Sprintf("Reg error: %d", int(C.GetLastError()))) } var i C.DWORD = 0 var keyType C.DWORD = 0 buffKeyName := make([]C.CHAR, 16384) buffKeyVal := make([]C.BYTE, 16384) for { var lenKeyName C.DWORD = C.DWORD(cap(buffKeyName)) var lenKeyValue C.DWORD = C.DWORD(cap(buffKeyVal)) ret := C.RegEnumValue(key, i, &buffKeyName[0], &lenKeyName, (*C.DWORD)(nil), &keyType, &buffKeyVal[0], &lenKeyValue) i++ if ret == C.ERROR_SUCCESS { if keyType == C.REG_SZ { itemName := C.GoString((*C.char)(&buffKeyName[0])) itemValue := C.GoString((*C.char)(unsafe.Pointer((&buffKeyVal[0])))) if strings.Contains(itemName, "PortName") { return itemValue, nil } } } else { break } } return "", errors.New("Empty response") }
// Deactivate, signal, wait for response, activate func (ic *contextInternal) pause(signal chan bool) ThreadError { // disable the current context if C.wglMakeCurrent(ic.hdc, nil) == C.FALSE { return NewThreadError(fmt.Errorf("wglMakeCurrent failed (%d)", C.GetLastError()), true) } // let the other thread know and then wait for them signal <- true <-signal // start up the context if C.wglMakeCurrent(ic.hdc, ic.context) == C.FALSE { return NewThreadError(fmt.Errorf("wglMakeCurrent failed (%d)", C.GetLastError()), true) } return nil }
// Temporary deactivate the context func (ic *contextInternal) release() ThreadError { // disable the current context if C.wglMakeCurrent(ic.hdc, nil) == C.FALSE { return NewThreadError(fmt.Errorf("wglMakeCurrent failed (%d)", C.GetLastError()), true) } return nil }
// Temporary activate the context func (ic *contextInternal) take() ThreadError { // start up the context if C.wglMakeCurrent(ic.hdc, ic.context) == C.FALSE { return NewThreadError(fmt.Errorf("wglMakeCurrent failed (%d)", C.GetLastError()), true) } return nil }
func (self *ProcList) Get() error { var enumSize int var pids [1024]C.DWORD // If the function succeeds, the return value is nonzero. ret, _, _ := procEnumProcesses.Call( uintptr(unsafe.Pointer(&pids[0])), uintptr(unsafe.Sizeof(pids)), uintptr(unsafe.Pointer(&enumSize)), ) if ret == 0 { return fmt.Errorf("error %d while reading processes", C.GetLastError()) } results := []int{} pids_size := enumSize / int(unsafe.Sizeof(pids[0])) for _, pid := range pids[:pids_size] { results = append(results, int(pid)) } self.List = results return nil }
// Change the window's icon func (wi *windowInternal) setIcon(icon image.Image) error { // First destroy the previous one if wi.icon != nil { C.DestroyIcon(wi.icon) } type BGRA [4]uint8 // Windows wants BGRA pixels: swap red and blue channels Rect := icon.Bounds() iconPixels := make([]BGRA, Rect.Dy()*Rect.Dx()) for i, y := 0, 0; y < Rect.Dy(); y++ { for x := 0; x < Rect.Dx(); x++ { r, g, b, a := icon.At(x, y).RGBA() iconPixels[i][0] = uint8(b) iconPixels[i][1] = uint8(g) iconPixels[i][2] = uint8(r) iconPixels[i][3] = uint8(a) } } // Create the icon from the pixel array width, height := C.int(Rect.Dx()), C.int(Rect.Dy()) wi.icon = C.CreateIcon(C.GetModuleHandle(nil), width, height, 1, 32, nil, (*C.BYTE)(&iconPixels[0][0])) if wi.icon == nil { return fmt.Errorf("could not create icon (%d)", C.GetLastError()) } C.SendMessage(wi.window.Handle, C.WM_SETICON, C.ICON_BIG, C.LPARAM(uintptr(unsafe.Pointer(wi.icon)))) C.SendMessage(wi.window.Handle, C.WM_SETICON, C.ICON_SMALL, C.LPARAM(uintptr(unsafe.Pointer(wi.icon)))) return nil }
// Set the current position of the mouse in window coordinates func (wi *windowInternal) setMousePosition(x, y int) ThreadError { if !wi.window.IsValid() { // TODO ERROR return nil } point := C.POINT{x: C.LONG(x), y: C.LONG(y)} if C.__ScreenToClient(wi.window.Handle, &point) == 0 { return NewThreadError(fmt.Errorf("ScreenToClient (%d)", C.GetLastError()), false) } if C.SetCursorPos(C.int(x), C.int(y)) == 0 { return NewThreadError(fmt.Errorf("SetCursorPos (%d)", C.GetLastError()), false) } return nil }
func SetWallPaper(file_path string) error { path := []byte(file_path) result := int(C.SystemParametersInfo(C.SPI_SETDESKWALLPAPER, 0, C.PVOID(unsafe.Pointer(&path[0])), C.SPIF_UPDATEINIFILE)) if result != C.TRUE { return fmt.Errorf("", C.GetLastError()) } return nil }
// Get the current position of the mouse in window coordinates func (wi *windowInternal) getMousePosition() (x, y int, err ThreadError) { if !wi.window.IsValid() { // TODO ERROR return } var point C.POINT if C.__GetCursorPos(&point) == 0 { err = NewThreadError(fmt.Errorf("GetCursorPos (%d)", C.GetLastError()), false) return } if C.__ScreenToClient(wi.window.Handle, &point) == 0 { err = NewThreadError(fmt.Errorf("ScreenToClient (%d)", C.GetLastError()), false) return } return int(point.x), int(point.y), nil }
// Get the current position of the mouse in desktop coordinates func getMousePosition() (x, y int) { x, y = -1, -1 var point C.POINT if C.__GetCursorPos(&point) == 0 { C.GetLastError() return } return int(point.x), int(point.y) }
// Deactivate the context as the current target for rendering func (ic *contextInternal) deactivate() ThreadError { // disable the current context if C.wglMakeCurrent(ic.hdc, nil) == C.FALSE { return NewThreadError(fmt.Errorf("wglMakeCurrent failed (%d)", C.GetLastError()), true) } // end by signaling ic.signalDeactivation() return nil }
func (self *Mem) Get() error { var statex C.MEMORYSTATUSEX statex.dwLength = C.DWORD(unsafe.Sizeof(statex)) succeeded := C.GlobalMemoryStatusEx(&statex) if succeeded == C.FALSE { lastError := C.GetLastError() return fmt.Errorf("GlobalMemoryStatusEx failed with error: %d", int(lastError)) } self.Total = uint64(statex.ullTotalPhys) return nil }
// Activate the context as the current target for rendering func (ic *contextInternal) activate() ThreadError { // start by waiting for deactivation to finish <-ic.deactivateSignal // start up the context if C.wglMakeCurrent(ic.hdc, ic.context) == C.FALSE { return NewThreadError(fmt.Errorf("wglMakeCurrent failed (%d)", C.GetLastError()), true) } // Load all the functions and such C.wglLoadProcs(&ic.procs) return nil }
func (ic *contextInternal) setVerticalSyncEnabled(enabled bool) ThreadError { var interval C.int if enabled { interval = 1 } if ic.procs.p_wglSwapIntervalEXT == nil { return NewThreadError(fmt.Errorf("wglSwapIntervalEXT == nil (%d)", ic.procs.error_wglSwapIntervalEXT), false) } if C.__wglSwapIntervalEXT(&ic.procs, interval) == C.FALSE { return NewThreadError(fmt.Errorf("wglSwapIntervalEXT failed (%d)", C.GetLastError()), false) } return nil }
func getDeviceRegistryProperty(DeviceInfoSet C.HDEVINFO, DeviceInfoData C.PSP_DEVINFO_DATA, property C.DWORD) (interface{}, error) { var dataType C.DWORD = 0 var dataSize C.DWORD = 0 C.SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, property, &dataType, (*C.BYTE)(nil), (C.DWORD)(0), &dataSize) if dataSize == 0 { return "", nil } data := make([]C.BYTE, dataSize) if C.SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, property, (*C.DWORD)(nil), &data[0], dataSize, (*C.DWORD)(nil)) == C.TRUE { switch dataType { case C.REG_EXPAND_SZ, C.REG_SZ: if dataSize > 0 { return C.GoString((*C.char)(unsafe.Pointer(&data[0]))), nil } case C.REG_MULTI_SZ: if dataSize > 0 { var res []string i := 0 for { s := C.GoString((*C.char)(unsafe.Pointer(&data[i]))) if len(s) == 0 { break } else { i += len(s) res = append(res, s) } } return res, nil } case C.REG_DWORD_BIG_ENDIAN, C.REG_DWORD: var t C.int if uintptr(dataSize) != unsafe.Sizeof(t) { panic("Reg incorrect result") } return int(*(*C.int)(unsafe.Pointer(&data[0]))), nil } } else { fmt.Printf("SetupDiGetDeviceRegistryProperty() failed (%v)\n", int(C.GetLastError())) } return nil, errors.New("Failed to get data from regestry") }
func (self *FileSystemUsage) Get(path string) error { var availableBytes C.ULARGE_INTEGER var totalBytes C.ULARGE_INTEGER var totalFreeBytes C.ULARGE_INTEGER pathChars := C.CString(path) defer C.free(unsafe.Pointer(pathChars)) succeeded := C.GetDiskFreeSpaceEx((*C.CHAR)(pathChars), &availableBytes, &totalBytes, &totalFreeBytes) if succeeded == C.FALSE { lastError := C.GetLastError() return fmt.Errorf("GetDiskFreeSpaceEx failed with error: %d", int(lastError)) } self.Total = *(*uint64)(unsafe.Pointer(&totalBytes)) return nil }
func (ic *contextInternal) initializeFromOwner(settings ContextSettings, owner *windowInternal, bitsPerPixel uint) ThreadError { ic.deactivateSignal = make(chan bool) ic.settings = settings // Get the owner window and its device context ic.window = C.HWND(owner.window.Handle) ic.ownsWindow = false // get the device context ic.hdc = C.GetDC(ic.window) if ic.hdc == nil { return NewThreadError(errors.New("no device context"), true) } ic.context = createContext(&sharedContext.internal.procs, sharedContext.internal.context, ic.hdc, bitsPerPixel, &ic.settings) if ic.context == nil { return NewThreadError(fmt.Errorf("could not create context (%d)", C.GetLastError()), true) } // signal because we start out deactivated ic.signalDeactivation() return nil }
func (self *Cpu) Get() error { var lpIdleTime, lpKernelTime, lpUserTime C.FILETIME succeeded := C.GetSystemTimes(&lpIdleTime, &lpKernelTime, &lpUserTime) if succeeded == C.FALSE { lastError := C.GetLastError() return fmt.Errorf("GetSystemTime failed with error: %d", int(lastError)) } LOT := float64(0.0000001) HIT := (LOT * 4294967296.0) idle := ((HIT * float64(lpIdleTime.dwHighDateTime)) + (LOT * float64(lpIdleTime.dwLowDateTime))) user := ((HIT * float64(lpUserTime.dwHighDateTime)) + (LOT * float64(lpUserTime.dwLowDateTime))) kernel := ((HIT * float64(lpKernelTime.dwHighDateTime)) + (LOT * float64(lpKernelTime.dwLowDateTime))) system := (kernel - idle) self.Idle = uint64(idle) self.User = uint64(user) self.Sys = uint64(system) return nil }
func GetProcName(pid int) (string, error) { handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) defer syscall.CloseHandle(handle) if err != nil { return "", fmt.Errorf("OpenProcess fails with %v", err) } var nameProc [MAX_PATH]byte ret, _, _ := procGetProcessImageFileName.Call( uintptr(handle), uintptr(unsafe.Pointer(&nameProc)), uintptr(MAX_PATH), ) if ret == 0 { return "", fmt.Errorf("error %d while getting process name", C.GetLastError()) } return filepath.Base(CarrayToString(nameProc)), nil }
func enumerate() ([]DeviceDescription, error) { //log.Print("Calling windows backend") k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\services`, registry.QUERY_VALUE) if err != nil { return nil, err } defer k.Close() var result []DeviceDescription for i := 0; i < len(guidArray); i++ { DeviceInfoSet := C.SetupDiGetClassDevs(&guidArray[i], (*C.CHAR)(nil), (*C.struct_HWND__)(nil), C.DIGCF_PRESENT) if C.is_INVALID_HANDLE_VALUE(unsafe.Pointer(DeviceInfoSet)) != 0 { return nil, errors.New(fmt.Sprintf( `Windows: SerialDeviceEnumeratorPrivate::updateInfo() SetupDiGetClassDevs() returned INVALID_HANDLE_VALUE, last error: %d`, int(C.GetLastError()))) } var DeviceIndex C.DWORD = 0 var DeviceInfoData C.SP_DEVINFO_DATA DeviceInfoData.cbSize = C.DWORD(unsafe.Sizeof(DeviceInfoData)) for { if C.SetupDiEnumDeviceInfo(DeviceInfoSet, DeviceIndex, &DeviceInfoData) != C.TRUE { break } DeviceIndex++ name, err := getNativeName(DeviceInfoSet, &DeviceInfoData) if err != nil || len(name) == 0 { continue } if strings.Contains(name, "LPT") { continue } var dev DeviceDescription dev.Name = name dev.ShortName = name if dev.Bus, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_ENUMERATOR_NAME)); err != nil { log.Printf("Error get bus of device %s: %s", name, err.Error()) } if dev.Description, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_DEVICEDESC)); err != nil { log.Printf("Error get Description of device %s: %s", name, err.Error()) } if dev.FriendlyName, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_FRIENDLYNAME)); err != nil { log.Printf("Error get FriendlyName of device %s: %s", name, err.Error()) } if dev.HardwareID, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_HARDWAREID)); err != nil { log.Printf("Error get HardwareID of device %s: %s", name, err.Error()) } if dev.LocationInfo, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_LOCATION_INFORMATION)); err != nil { log.Printf("Error get LocationInfo of device %s: %s", name, err.Error()) } if dev.Manufacturer, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_MFG)); err != nil { log.Printf("Error get Manufacturer of device %s: %s", name, err.Error()) } if dev.SubSystem, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_CLASS)); err != nil { log.Printf("Error get SubSystem of device %s: %s", name, err.Error()) } if dev.Service, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_SERVICE)); err != nil { log.Printf("Error get Service of device %s: %s", name, err.Error()) } if dev.Driver, err = getNativeDriver(dev.Service); err != nil { log.Printf("Error get Driver of device %s: %s", name, err.Error()) } if dev.SystemPath, err = result2string(getDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, C.SPDRP_PHYSICAL_DEVICE_OBJECT_NAME)); err != nil { log.Printf("Error get SystemPath of device %s: %s", name, err.Error()) } match := vidpidRegExp.FindStringSubmatch(dev.HardwareID) if len(match) > 1 { var v []byte if v, err = hex.DecodeString(match[1]); err == nil { dev.VendorID = (uint16)(v[0])<<8 + (uint16)(v[1]) } if v, err = hex.DecodeString(match[2]); err == nil { dev.ProductID = (uint16)(v[0])<<8 + (uint16)(v[1]) } } result = append(result, dev) } } return result, nil }
// Display what has been rendered to the context so far func (ic *contextInternal) swapBuffers() ThreadError { if C.SwapBuffers(ic.hdc) == C.FALSE { return NewThreadError(fmt.Errorf("SwapBuffers (%d)", C.GetLastError()), true) } return nil }
func getErr(msg string) error { return &CspError{msg: msg, Code: ErrorCode(C.GetLastError())} }