Initial commit

This commit is contained in:
Tomaka17 2014-07-27 10:55:37 +02:00
commit 1cc0447c5e
10 changed files with 5394 additions and 0 deletions

22
.gitattributes vendored Normal file
View file

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

8
Cargo.toml Normal file
View file

@ -0,0 +1,8 @@
[package]
name = "gl-init-rs"
version = "0.0.1"
authors = ["tomaka <pierre.krieger1708@gmail.com>"]
[dev-dependencies.gl]
path = "deps/gl"

201
LICENSE Normal file
View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# gl-init-rs
Alternative to GLFW in pure Rust.

10
deps/gl/Cargo.toml vendored Normal file
View file

@ -0,0 +1,10 @@
[project]
name = "gl"
version = "0.0.1"
authors = []
tags = []
[[lib]]
name = "gl"
path = "gl.rs"

4235
deps/gl/gl.rs vendored Normal file

File diff suppressed because it is too large Load diff

23
examples/window.rs Normal file
View file

@ -0,0 +1,23 @@
extern crate init = "gl-init-rs";
extern crate libc;
extern crate gl;
fn main() {
use std::default::Default;
let window = init::Window::new(None, "Hello world!", &Default::default()).unwrap();
window.make_current();
gl::load_with(|symbol| window.get_proc_address(symbol) as *const libc::c_void);
gl::ClearColor(0.0, 1.0, 0.0, 1.0);
while !window.should_close() {
window.wait_events();
gl::Clear(gl::COLOR_BUFFER_BIT);
window.swap_buffers();
}
}

114
src/lib.rs Normal file
View file

@ -0,0 +1,114 @@
#![feature(unsafe_destructor)]
extern crate libc;
#[cfg(windows)]
pub use win32::Window;
#[cfg(windows)]
mod win32;
#[deriving(Clone,Show)]
pub enum Event {
/// The position of the window has changed.
PositionChanged(uint, uint),
/// The size of the window has changed.
SizeChanged(uint, uint),
/// The window has been closed.
Closed,
/// The cursor has moved on the window.
///
/// The parameter are the (x,y) coords in pixels relative to the top-left corner of the window.
CursorPositionChanged(uint, uint),
/// The window gained or lost focus.
///
/// The parameter is true if the window has gained focus, and false if it has lost focus.
Focused(bool),
/// The window has been turned into an icon or restored.
///
/// The parameter is true if the window has been iconified, and false if it has been restored.
Iconified(bool),
/// The system asked that the content of this window must be redrawn.
NeedRefresh,
/// The size of the framebuffer of the window has changed.
FramebufferSizeChanged(uint, uint),
}
#[deriving(Clone,Show)]
pub struct Hints {
pub resizable: bool,
pub visible: bool,
pub decorated: bool,
pub red_bits: u8,
pub green_bits: u8,
pub blue_bits: u8,
pub alpha_bits: u8,
pub depth_bits: u8,
pub stencil_bits: u8,
pub accum_red_bits: u8,
pub accum_green_bits: u8,
pub accum_blue_bits: u8,
pub accum_alpha_bits: u8,
pub aux_buffers: u8,
pub samples: u8,
pub refresh_rate: u8,
pub stereo: bool,
pub srgb_capable: bool,
pub client_api: ClientAPI,
pub context_version: (u8, u8),
//pub robustness: ,
pub opengl_forward_compat: bool,
pub opengl_debug_context: bool,
pub opengl_profile: Profile,
}
#[deriving(Clone, Show)]
pub enum ClientAPI {
OpenGL,
OpenGLES,
}
#[deriving(Clone, Show)]
pub enum Profile {
AnyProfile,
CompatProfile,
CoreProfile,
}
impl std::default::Default for Hints {
fn default() -> Hints {
Hints {
resizable: true,
visible: true,
decorated: true,
red_bits: 8,
green_bits: 8,
blue_bits: 8,
alpha_bits: 8,
depth_bits: 24,
stencil_bits: 8,
accum_red_bits: 0,
accum_green_bits: 0,
accum_blue_bits: 0,
accum_alpha_bits: 0,
aux_buffers: 0,
samples: 0,
refresh_rate: 0,
stereo: false,
srgb_capable: false,
client_api: OpenGL,
context_version: (1, 0),
//robustness: ,
opengl_forward_compat: false,
opengl_debug_context: false,
opengl_profile: AnyProfile,
}
}
}

424
src/win32/ffi.rs Normal file
View file

@ -0,0 +1,424 @@
#![allow(dead_code)]
#![allow(non_snake_case_functions)]
#![allow(non_camel_case_types)]
use libc;
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
// we don't define the T types to ensure that A/W functions are used
pub type ATOM = WORD;
pub type BOOL = libc::c_int;
pub type BOOLEAN = BYTE;
pub type BYTE = libc::c_uchar;
pub type DWORD = libc::c_ulong;
pub type HANDLE = PVOID;
pub type HBRUSH = HANDLE;
pub type HCURSOR = HICON;
pub type HDC = HANDLE;
pub type HICON = HANDLE;
pub type HINSTANCE = HANDLE;
pub type HLOCAL = HANDLE;
pub type HMENU = HANDLE;
pub type HMODULE = HINSTANCE;
pub type HWND = HANDLE;
pub type LONG = libc::c_long;
pub type LONG_PTR = int;
pub type LPARAM = LONG_PTR;
pub type LPCSTR = *const libc::c_char;
pub type LPCWSTR = *const WCHAR;
pub type LPCVOID = *const libc::c_void;
pub type LPSTR = *mut libc::c_char;
pub type LPVOID = *mut libc::c_void;
pub type LPWSTR = *mut WCHAR;
pub type LRESULT = LONG_PTR;
pub type PVOID = *mut libc::c_void;
pub type UINT = libc::c_uint;
pub type UINT_PTR = int;
pub type WCHAR = libc::wchar_t;
pub type WORD = libc::c_ushort;
pub type WPARAM = UINT_PTR;
// macros
pub fn LOWORD(l: DWORD) -> WORD {
(l & 0xFFFF) as WORD
}
pub fn HIWORD(l: DWORD) -> WORD {
(l >> 16) as WORD
}
pub fn GET_X_LPARAM(lp: LONG_PTR) -> libc::c_int {
LOWORD(lp as DWORD) as libc::c_int
}
pub fn GET_Y_LPARAM(lp: LONG_PTR) -> libc::c_int {
HIWORD(lp as DWORD) as libc::c_int
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff485887(v=vs.85).aspx
pub static BN_CLICKED: WORD = 0;
pub static BN_DBLCLK: WORD = 5;
pub static BN_DISABLE: WORD = 4;
pub static BN_DOUBLECLICKED: WORD = 5;
pub static BN_HILITE: WORD = 2;
pub static BN_KILLFOCUS: WORD = 7;
pub static BN_PAINT: WORD = 1;
pub static BN_PUSHED: WORD = 2;
pub static BN_SETFOCUS: WORD = 6;
pub static BN_UNHILITE: WORD = 3;
pub static BN_UNPUSHED: WORD = 3;
// ?
pub static BS_3STATE: DWORD = 5;
pub static BS_AUTO3STATE: DWORD = 6;
pub static BS_AUTOCHECKBOX: DWORD = 3;
pub static BS_AUTORADIOBUTTON: DWORD = 9;
pub static BS_BITMAP: DWORD = 128;
pub static BS_BOTTOM: DWORD = 0x800;
pub static BS_CENTER: DWORD = 0x300;
pub static BS_CHECKBOX: DWORD = 2;
pub static BS_DEFPUSHBUTTON: DWORD = 1;
pub static BS_GROUPBOX: DWORD = 7;
pub static BS_ICON: DWORD = 64;
pub static BS_LEFT: DWORD = 256;
pub static BS_LEFTTEXT: DWORD = 32;
pub static BS_MULTILINE: DWORD = 0x2000;
pub static BS_NOTIFY: DWORD = 0x4000;
pub static BS_OWNERDRAW: DWORD = 0xb;
pub static BS_PUSHBUTTON: DWORD = 0;
pub static BS_PUSHLIKE: DWORD = 4096;
pub static BS_RADIOBUTTON: DWORD = 4;
pub static BS_RIGHT: DWORD = 512;
pub static BS_RIGHTBUTTON: DWORD = 32;
pub static BS_TEXT: DWORD = 0;
pub static BS_TOP: DWORD = 0x400;
pub static BS_USERBUTTON: DWORD = 8;
pub static BS_VCENTER: DWORD = 0xc00;
pub static BS_FLAT: DWORD = 0x8000;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff729176(v=vs.85).aspx
pub static CS_BYTEALIGNCLIENT: DWORD = 0x1000;
pub static CS_BYTEALIGNWINDOW: DWORD = 0x2000;
pub static CS_CLASSDC: DWORD = 0x0040;
pub static CS_DBLCLKS: DWORD = 0x0008;
pub static CS_DROPSHADOW: DWORD = 0x00020000;
pub static CS_GLOBALCLASS: DWORD = 0x4000;
pub static CS_HREDRAW: DWORD = 0x0002;
pub static CS_NOCLOSE: DWORD = 0x0200;
pub static CS_OWNDC: DWORD = 0x0020;
pub static CS_PARENTDC: DWORD = 0x0080;
pub static CS_SAVEBITS: DWORD = 0x0800;
pub static CS_VREDRAW: DWORD = 0x0001;
// ?
#[allow(type_overflow)]
pub static CW_USEDEFAULT: libc::c_int = 0x80000000;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx
pub static FORMAT_MESSAGE_ALLOCATE_BUFFER: DWORD = 0x00000100;
pub static FORMAT_MESSAGE_ARGUMENT_ARRAY: DWORD = 0x00002000;
pub static FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800;
pub static FORMAT_MESSAGE_FROM_STRING: DWORD = 0x00000400;
pub static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
pub static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
// ?
pub static PFD_TYPE_RGBA: BYTE = 0;
pub static PFD_TYPE_COLORINDEX: BYTE = 1;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
pub static SW_FORCEMINIMIZE: libc::c_int = 11;
pub static SW_HIDE: libc::c_int = 0;
pub static SW_MAXIMIZE: libc::c_int = 3;
pub static SW_MINIMIZE: libc::c_int = 6;
pub static SW_RESTORE: libc::c_int = 9;
pub static SW_SHOW: libc::c_int = 5;
pub static SW_SHOWDEFAULT: libc::c_int = 10;
pub static SW_SHOWMAXIMIZED: libc::c_int = 3;
pub static SW_SHOWMINIMIZED: libc::c_int = 2;
pub static SW_SHOWMINNOACTIVE: libc::c_int = 7;
pub static SW_SHOWNA: libc::c_int = 8;
pub static SW_SHOWNOACTIVATE: libc::c_int = 4;
pub static SW_SHOWNORMAL: libc::c_int = 1;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx
pub static SWP_ASYNCWINDOWPOS: UINT = 0x4000;
pub static SWP_DEFERERASE: UINT = 0x2000;
pub static SWP_DRAWFRAME: UINT = 0x0020;
pub static SWP_FRAMECHANGED: UINT = 0x0020;
pub static SWP_HIDEWINDOW: UINT = 0x0080;
pub static SWP_NOACTIVATE: UINT = 0x0010;
pub static SWP_NOCOPYBITS: UINT = 0x0100;
pub static SWP_NOMOVE: UINT = 0x0002;
pub static SWP_NOOWNERZORDER: UINT = 0x0200;
pub static SWP_NOREDRAW: UINT = 0x0008;
pub static SWP_NOREPOSITION: UINT = 0x0200;
pub static SWP_NOSENDCHANGING: UINT = 0x0400;
pub static SWP_NOSIZE: UINT = 0x0001;
pub static SWP_NOZORDER: UINT = 0x0004;
pub static SWP_SHOWWINDOW: UINT = 0x0040;
// messages
pub static WM_COMMAND: UINT = 0x0111;
pub static WM_DESTROY: UINT = 0x0002;
pub static WM_MOUSEMOVE: UINT = 0x0200;
pub static WM_PAINT: UINT = 0x000F;
pub static WM_SIZE: UINT = 0x0005;
pub static WM_SIZING: UINT = 0x0214;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx
pub static WS_BORDER: DWORD = 0x00800000;
pub static WS_CAPTION: DWORD = 0x00C00000;
pub static WS_CHILD: DWORD = 0x40000000;
pub static WS_CHILDWINDOW: DWORD = 0x40000000;
pub static WS_CLIPCHILDREN: DWORD = 0x02000000;
pub static WS_CLIPSIBLINGS: DWORD = 0x04000000;
pub static WS_DISABLED: DWORD = 0x08000000;
pub static WS_DLGFRAME: DWORD = 0x00400000;
pub static WS_GROUP: DWORD = 0x00020000;
pub static WS_HSCROLL: DWORD = 0x00100000;
pub static WS_ICONIC: DWORD = 0x20000000;
pub static WS_MAXIMIZE: DWORD = 0x01000000;
pub static WS_MAXIMIZEBOX: DWORD = 0x00010000;
pub static WS_MINIMIZE: DWORD = 0x20000000;
pub static WS_MINIMIZEBOX: DWORD = 0x00020000;
pub static WS_OVERLAPPED: DWORD = 0x00000000;
pub static WS_OVERLAPPEDWINDOW: DWORD = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
pub static WS_POPUP: DWORD = 0x80000000;
pub static WS_POPUPWINDOW: DWORD = (WS_POPUP | WS_BORDER | WS_SYSMENU);
pub static WS_SIZEBOX: DWORD = 0x00040000;
pub static WS_SYSMENU: DWORD = 0x00080000;
pub static WS_TABSTOP: DWORD = 0x00010000;
pub static WS_THICKFRAME: DWORD = 0x00040000;
pub static WS_TILED: DWORD = 0x00000000;
pub static WS_TILEDWINDOW: DWORD = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
pub static WS_VISIBLE: DWORD = 0x10000000;
pub static WS_VSCROLL: DWORD = 0x00200000;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx
pub static WS_EX_ACCEPTFILES: DWORD = 0x00000010;
pub static WS_EX_APPWINDOW: DWORD = 0x00040000;
pub static WS_EX_CLIENTEDGE: DWORD = 0x00000200;
pub static WS_EX_COMPOSITED: DWORD = 0x02000000;
pub static WS_EX_CONTEXTHELP: DWORD = 0x00000400;
pub static WS_EX_CONTROLPARENT: DWORD = 0x00010000;
pub static WS_EX_DLGMODALFRAME: DWORD = 0x00000001;
pub static WS_EX_LAYERED: DWORD = 0x00080000;
pub static WS_EX_LAYOUTRTL: DWORD = 0x00400000;
pub static WS_EX_LEFT: DWORD = 0x00000000;
pub static WS_EX_LEFTSCROLLBAR: DWORD = 0x00004000;
pub static WS_EX_LTRREADING: DWORD = 0x00000000;
pub static WS_EX_MDICHILD: DWORD = 0x00000040;
pub static WS_EX_NOACTIVATE: DWORD = 0x08000000;
pub static WS_EX_NOINHERITLAYOUT: DWORD = 0x00100000;
pub static WS_EX_NOPARENTNOTIFY: DWORD = 0x00000004;
pub static WS_EX_NOREDIRECTIONBITMAP: DWORD = 0x00200000;
pub static WS_EX_OVERLAPPEDWINDOW: DWORD = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
pub static WS_EX_PALETTEWINDOW: DWORD = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
pub static WS_EX_RIGHT: DWORD = 0x00001000;
pub static WS_EX_RIGHTSCROLLBAR: DWORD = 0x00000000;
pub static WS_EX_RTLREADING: DWORD = 0x00002000;
pub static WS_EX_STATICEDGE: DWORD = 0x00020000;
pub static WS_EX_TOOLWINDOW: DWORD = 0x00000080;
pub static WS_EX_TOPMOST: DWORD = 0x00000008;
pub static WS_EX_TRANSPARENT: DWORD = 0x00000020;
pub static WS_EX_WINDOWEDGE: DWORD = 0x00000100;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx
pub type WNDPROC = extern "stdcall" fn(HWND, UINT, WPARAM, LPARAM) -> LRESULT;
// ?
pub type HGLRC = HANDLE;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577(v=vs.85).aspx
#[repr(C)]
pub struct WNDCLASSEX {
pub cbSize: UINT,
pub style: UINT,
pub lpfnWndProc: WNDPROC,
pub cbClsExtra: libc::c_int,
pub cbWndExtra: libc::c_int,
pub hInstance: HINSTANCE,
pub hIcon: HICON,
pub hCursor: HCURSOR,
pub hbrBackground: HBRUSH,
pub lpszMenuName: LPCWSTR,
pub lpszClassName: LPCWSTR,
pub hIconSm: HICON,
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspxtag
#[repr(C)]
pub struct POINT {
pub x: LONG,
pub y: LONG,
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958(v=vs.85).aspx
#[repr(C)]
pub struct MSG {
pub hwnd: HWND,
pub message: UINT,
pub wParam: WPARAM,
pub lParam: LPARAM,
pub time: DWORD,
pub pt: POINT,
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162768(v=vs.85).aspx
#[repr(C)]
pub struct PAINTSTRUCT {
pub hdc: HDC,
pub fErase: BOOL,
pub rcPaint: RECT,
pub fRestore: BOOL,
pub fIncUpdate: BOOL,
pub rgbReserved: [BYTE, ..32],
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx
#[repr(C)]
pub struct RECT {
pub left: LONG,
pub top: LONG,
pub right: LONG,
pub bottom: LONG,
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd368826(v=vs.85).aspx
#[repr(C)]
pub struct PIXELFORMATDESCRIPTOR {
pub nSize: WORD,
pub nVersion: WORD,
pub dwFlags: DWORD,
pub iPixelType: BYTE,
pub cColorBits: BYTE,
pub cRedBits: BYTE,
pub cRedShift: BYTE,
pub cGreenBits: BYTE,
pub cGreenShift: BYTE,
pub cBlueBits: BYTE,
pub cBlueShift: BYTE,
pub cAlphaBits: BYTE,
pub cAlphaShift: BYTE,
pub cAccumBits: BYTE,
pub cAccumRedBits: BYTE,
pub cAccumGreenBits: BYTE,
pub cAccumBlueBits: BYTE,
pub cAccumAlphaBits: BYTE,
pub cDepthBits: BYTE,
pub cStencilBits: BYTE,
pub cAuxBuffers: BYTE,
pub iLayerType: BYTE,
pub bReserved: BYTE,
pub dwLayerMask: DWORD,
pub dwVisibleMask: DWORD,
pub dwDamageMask: DWORD,
}
pub type LPMSG = *mut MSG;
#[link(name = "advapi32")]
#[link(name = "comctl32")]
#[link(name = "comdlg32")]
#[link(name = "gdi32")]
#[link(name = "kernel32")]
#[link(name = "odbc32")]
#[link(name = "odbccp32")]
#[link(name = "ole32")]
#[link(name = "oleaut32")]
#[link(name = "Opengl32")]
#[link(name = "shell32")]
#[link(name = "user32")]
#[link(name = "uuid")]
#[link(name = "winspool")]
extern "system" {
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183362(v=vs.85).aspx
pub fn BeginPaint(hwnd: HWND, lpPaint: *mut PAINTSTRUCT) -> HDC;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
pub fn CreateWindowExW(dwExStyle: DWORD, lpClassName: LPCWSTR, lpWindowName: LPCWSTR,
dwStyle: DWORD, x: libc::c_int, y: libc::c_int, nWidth: libc::c_int, nHeight: libc::c_int,
hWndParent: HWND, hMenu: HMENU, hInstance: HINSTANCE, lpParam: LPVOID) -> HWND;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633572(v=vs.85).aspx
pub fn DefWindowProcW(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> LRESULT;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd318302(v=vs.85).aspx
pub fn DescribePixelFormat(hdc: HDC, iPixelFormat: libc::c_int, nBytes: UINT,
ppfd: *mut PIXELFORMATDESCRIPTOR) -> libc::c_int;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632682(v=vs.85).aspx
pub fn DestroyWindow(hWnd: HWND) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644934(v=vs.85).aspx
pub fn DispatchMessageW(lpmsg: *const MSG) -> LRESULT;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162598(v=vs.85).aspx
pub fn EndPaint(hWnd: HWND, lpPaint: *const PAINTSTRUCT) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162719(v=vs.85).aspx
pub fn FillRect(hDC: HDC, lprc: *const RECT, hbr: HBRUSH) -> libc::c_int;
// http://msdn.microsoft.com/en-us/library/dd144871(v=vs.85).aspx
pub fn GetDC(hWnd: HWND) -> HDC;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms679360(v=vs.85).aspx
pub fn GetLastError() -> DWORD;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx
pub fn GetMessageW(lpMsg: LPMSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683199(v=vs.85).aspx
pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx
pub fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> *const libc::c_void;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
pub fn LoadLibraryW(lpFileName: LPCWSTR) -> HMODULE;
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa366730(v=vs.85).aspx
pub fn LocalFree(hMem: HLOCAL) -> HLOCAL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644945(v=vs.85).aspx
pub fn PostQuitMessage(nExitCode: libc::c_int);
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633586(v=vs.85).aspx
pub fn RegisterClassExW(lpWndClass: *const WNDCLASSEX) -> ATOM;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd369049(v=vs.85).aspx
pub fn SetPixelFormat(hdc: HDC, iPixelFormat: libc::c_int,
ppfd: *const PIXELFORMATDESCRIPTOR) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx
pub fn SetWindowPos(hWnd: HWND, hWndInsertAfter: HWND, X: libc::c_int, Y: libc::c_int,
cx: libc::c_int, cy: libc::c_int, uFlags: UINT) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633546(v=vs.85).aspx
pub fn SetWindowTextW(hWnd: HWND, lpString: LPCWSTR) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
pub fn ShowWindow(hWnd: HWND, nCmdShow: libc::c_int) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd369060(v=vs.85).aspx
pub fn SwapBuffers(hdc: HDC) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644934(v=vs.85).aspx
pub fn TranslateMessage(lpmsg: *const MSG) -> BOOL;
// http://msdn.microsoft.com/en-us/library/dd145167(v=vs.85).aspx
pub fn UpdateWindow(hWnd: HWND) -> BOOL;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd374379(v=vs.85).aspx
pub fn wglCreateContext(hdc: HDC) -> HGLRC;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd374381(v=vs.85).aspx
pub fn wglDeleteContext(hglrc: HGLRC);
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd374386(v=vs.85).aspx
pub fn wglGetProcAddress(lpszProc: LPCSTR) -> *const libc::c_void;
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd374387(v=vs.85).aspx
pub fn wglMakeCurrent(hdc: HDC, hglrc: HGLRC);
}

354
src/win32/mod.rs Normal file
View file

@ -0,0 +1,354 @@
use std::kinds::marker::NoSend;
use std::sync::Mutex;
use std::sync::atomics::AtomicBool;
use std::ptr;
use {Event, Hints};
mod ffi;
pub struct Window {
window: ffi::HWND,
hdc: ffi::HDC,
context: ffi::HGLRC,
gl_library: ffi::HMODULE,
events_receiver: Receiver<Event>,
should_close: AtomicBool,
nosend: NoSend,
}
/// Stores the list of all the windows.
/// Only available on callback thread.
local_data_key!(pub WINDOWS_LIST: Mutex<Vec<(ffi::HWND, Sender<Event>)>>)
impl Window {
pub fn new(dimensions: Option<(uint, uint)>, title: &str, _hints: &Hints)
-> Result<Window, String>
{
use std::mem;
use std::os;
// initializing WINDOWS_LIST if needed
// this is safe because WINDOWS_LIST is task-local
if WINDOWS_LIST.get().is_none() {
WINDOWS_LIST.replace(Some(Mutex::new(Vec::new())));
}
// registering the window class
let class_name: Vec<u16> = "Window Class".utf16_units().collect::<Vec<u16>>()
.append_one(0);
let class = ffi::WNDCLASSEX {
cbSize: mem::size_of::<ffi::WNDCLASSEX>() as ffi::UINT,
style: ffi::CS_HREDRAW | ffi::CS_VREDRAW,
lpfnWndProc: callback,
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: unsafe { ffi::GetModuleHandleW(ptr::null()) },
hIcon: ptr::mut_null(),
hCursor: ptr::mut_null(),
hbrBackground: ptr::mut_null(),
lpszMenuName: ptr::null(),
lpszClassName: class_name.as_ptr(),
hIconSm: ptr::mut_null(),
};
if unsafe { ffi::RegisterClassExW(&class) } == 0 {
use std::os;
return Err(format!("RegisterClassEx function failed: {}",
os::error_string(os::errno() as uint)))
}
// creating the window
let handle = unsafe {
use libc;
let handle = ffi::CreateWindowExW(0, class_name.as_ptr(),
title.utf16_units().collect::<Vec<u16>>().append_one(0).as_ptr() as ffi::LPCWSTR,
ffi::WS_OVERLAPPEDWINDOW | ffi::WS_VISIBLE,
dimensions.map(|(x, _)| x as libc::c_int).unwrap_or(ffi::CW_USEDEFAULT),
dimensions.map(|(_, y)| y as libc::c_int).unwrap_or(ffi::CW_USEDEFAULT),
ffi::CW_USEDEFAULT, ffi::CW_USEDEFAULT,
ptr::mut_null(), ptr::mut_null(), ffi::GetModuleHandleW(ptr::null()),
ptr::mut_null());
if handle.is_null() {
use std::os;
return Err(format!("CreateWindowEx function failed: {}",
os::error_string(os::errno() as uint)))
}
handle
};
// adding it to WINDOWS_LIST
let events_receiver = {
let (tx, rx) = channel();
let list = WINDOWS_LIST.get().unwrap();
let mut list = list.lock();
list.push((handle, tx));
rx
};
// Getting the HDC of the window
let hdc = {
let hdc = unsafe { ffi::GetDC(handle) };
if hdc.is_null() {
return Err(format!("GetDC function failed: {}",
os::error_string(os::errno() as uint)))
}
hdc
};
// getting the pixel format that we will use
// TODO: use something cleaner which uses hints
let pixel_format = {
let mut output: ffi::PIXELFORMATDESCRIPTOR = unsafe { mem::uninitialized() };
if unsafe { ffi::DescribePixelFormat(hdc, 1,
mem::size_of::<ffi::PIXELFORMATDESCRIPTOR>() as ffi::UINT, &mut output) } == 0
{
return Err(format!("DescribePixelFormat function failed: {}",
os::error_string(os::errno() as uint)))
}
output
};
// calling SetPixelFormat
unsafe {
if ffi::SetPixelFormat(hdc, 1, &pixel_format) == 0 {
return Err(format!("SetPixelFormat function failed: {}",
os::error_string(os::errno() as uint)))
}
}
// creating the context
let context = {
let ctxt = unsafe { ffi::wglCreateContext(hdc) };
if ctxt.is_null() {
return Err(format!("wglCreateContext function failed: {}",
os::error_string(os::errno() as uint)))
}
ctxt
};
// loading opengl32
let gl_library = {
let name = "opengl32.dll".utf16_units().collect::<Vec<u16>>().append_one(0).as_ptr();
let lib = unsafe { ffi::LoadLibraryW(name) };
if lib.is_null() {
return Err(format!("LoadLibrary function failed: {}",
os::error_string(os::errno() as uint)))
}
lib
};
// building the struct
Ok(Window{
window: handle,
hdc: hdc,
context: context,
gl_library: gl_library,
events_receiver: events_receiver,
should_close: AtomicBool::new(false),
nosend: NoSend,
})
}
pub fn should_close(&self) -> bool {
use std::sync::atomics::Relaxed;
self.should_close.load(Relaxed)
}
/// Calls SetWindowText on the HWND.
pub fn set_title(&self, text: &str) {
unsafe {
ffi::SetWindowTextW(self.window,
text.utf16_units().collect::<Vec<u16>>().append_one(0).as_ptr() as ffi::LPCWSTR);
}
}
pub fn get_position(&self) -> (uint, uint) {
unimplemented!()
}
pub fn set_position(&self, x: uint, y: uint) {
use libc;
unsafe {
ffi::SetWindowPos(self.window, ptr::mut_null(), x as libc::c_int, y as libc::c_int,
0, 0, ffi::SWP_NOZORDER | ffi::SWP_NOSIZE);
ffi::UpdateWindow(self.window);
}
}
pub fn get_size(&self) -> (uint, uint) {
unimplemented!()
}
pub fn set_size(&self, x: uint, y: uint) {
use libc;
unsafe {
ffi::SetWindowPos(self.window, ptr::mut_null(), 0, 0, x as libc::c_int,
y as libc::c_int, ffi::SWP_NOZORDER | ffi::SWP_NOREPOSITION);
ffi::UpdateWindow(self.window);
}
}
// TODO: return iterator
pub fn poll_events(&self) -> Vec<Event> {
unimplemented!()
}
// TODO: return iterator
pub fn wait_events(&self) -> Vec<Event> {
use std::mem;
{
let mut msg = unsafe { mem::uninitialized() };
if unsafe { ffi::GetMessageW(&mut msg, ptr::mut_null(), 0, 0) } == 0 {
use std::sync::atomics::Relaxed;
use Closed;
self.should_close.store(true, Relaxed);
return vec![Closed]
}
unsafe { ffi::TranslateMessage(&msg) };
unsafe { ffi::DispatchMessageW(&msg) };
}
let mut events = Vec::new();
loop {
match self.events_receiver.try_recv() {
Ok(ev) => events.push(ev),
Err(_) => break
}
}
events
}
pub fn make_current(&self) {
unsafe { ffi::wglMakeCurrent(self.hdc, self.context) }
}
pub fn get_proc_address(&self, addr: &str) -> *const () {
use std::c_str::ToCStr;
unsafe {
addr.with_c_str(|s| {
let p = ffi::wglGetProcAddress(s) as *const ();
if !p.is_null() { return p; }
ffi::GetProcAddress(self.gl_library, s) as *const ()
})
}
}
pub fn swap_buffers(&self) {
unsafe {
ffi::SwapBuffers(self.hdc);
}
}
}
#[unsafe_destructor]
impl Drop for Window {
fn drop(&mut self) {
unsafe { ffi::DestroyWindow(self.window); }
}
}
fn send_event(window: ffi::HWND, event: Event) {
let locked = WINDOWS_LIST.get().unwrap();
let mut locked = locked.lock();
locked.retain(|&(ref val, ref sender)| {
if val != &window { return true }
sender.send_opt(event).is_ok()
});
}
extern "stdcall" fn callback(window: ffi::HWND, msg: ffi::UINT,
wparam: ffi::WPARAM, lparam: ffi::LPARAM) -> ffi::LRESULT
{
match msg {
ffi::WM_DESTROY => {
use Closed;
send_event(window, Closed);
unsafe { ffi::PostQuitMessage(0); }
0
},
ffi::WM_SIZE => {
use SizeChanged;
let w = ffi::LOWORD(lparam as ffi::DWORD) as uint;
let h = ffi::HIWORD(lparam as ffi::DWORD) as uint;
send_event(window, SizeChanged(w, h));
0
},
ffi::WM_PAINT => {
use NeedRefresh;
send_event(window, NeedRefresh);
0
},
ffi::WM_MOUSEMOVE => {
use CursorPositionChanged;
let x = ffi::GET_X_LPARAM(lparam) as uint;
let y = ffi::GET_Y_LPARAM(lparam) as uint;
send_event(window, CursorPositionChanged(x, y));
0
},
_ => unsafe {
ffi::DefWindowProcW(window, msg, wparam, lparam)
}
}
}
/*fn hints_to_pixelformat(hints: &Hints) -> ffi::PIXELFORMATDESCRIPTOR {
use std::mem;
ffi::PIXELFORMATDESCRIPTOR {
nSize: size_of::<ffi::PIXELFORMATDESCRIPTOR>(),
nVersion: 1,
dwFlags:
if hints.stereo { PFD_STEREO } else { 0 },
iPixelType: PFD_TYPE_RGBA,
cColorBits: hints.red_bits + hints.green_bits + hints.blue_bits,
cRedBits:
pub nSize: WORD,
pub nVersion: WORD,
pub dwFlags: DWORD,
pub iPixelType: BYTE,
pub cColorBits: BYTE,
pub cRedBits: BYTE,
pub cRedShift: BYTE,
pub cGreenBits: BYTE,
pub cGreenShift: BYTE,
pub cBlueBits: BYTE,
pub cBlueShift: BYTE,
pub cAlphaBits: BYTE,
pub cAlphaShift: BYTE,
pub cAccumBits: BYTE,
pub cAccumRedBits: BYTE,
pub cAccumGreenBits: BYTE,
pub cAccumBlueBits: BYTE,
pub cAccumAlphaBits: BYTE,
pub cDepthBits: BYTE,
pub cStencilBits: BYTE,
pub cAuxBuffers: BYTE,
pub iLayerType: BYTE,
pub bReserved: BYTE,
pub dwLayerMask: DWORD,
pub dwVisibleMask: DWORD,
pub dwDamageMask: DWORD,
}
}*/