Advertisement
Guest User

Untitled

a guest
Dec 23rd, 2011
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.90 KB | None | 0 0
  1.  
  2. --[[
  3.  crashes with "luajit: bad callback" on line 198 ("while not quitting do")
  4.    when mouse is moved over window (i.e. firing events)
  5.  uncomment jit.off() here and it seems to work:
  6. --]]
  7.  
  8. --jit.off()
  9.  
  10. package.preload['extern.mswindows'] = function()
  11.  
  12.   local bit = require 'bit'
  13.   local ffi = require 'ffi'
  14.  
  15.   ffi.cdef [[
  16.  
  17.     typedef int32_t bool32;
  18.     typedef intptr_t (__stdcall *WNDPROC)(void* hwnd, unsigned int message, uintptr_t wparam, intptr_t lparam);
  19.    
  20.     enum {
  21.       CS_VREDRAW = 0x0001,
  22.       CS_HREDRAW = 0x0002,
  23.       WM_DESTROY = 0x0002,
  24.       WM_QUIT = 0x0012,
  25.       WS_OVERLAPPEDWINDOW = 0x00CF0000,
  26.       WAIT_OBJECT_0 = 0x00000000,
  27.       PM_REMOVE = 0x0001,
  28.       SW_SHOW = 5,
  29.       INFINITE =  0xFFFFFFFF,
  30.       QS_ALLEVENTS = 0x04BF
  31.     };
  32.    
  33.     typedef struct RECT { int32_t left, top, right, bottom; } RECT;
  34.     typedef struct POINT { int32_t x, y; } POINT;
  35.    
  36.     typedef struct WNDCLASSEXA {
  37.       uint32_t cbSize, style;
  38.       WNDPROC lpfnWndProc;
  39.       int32_t cbClsExtra, cbWndExtra;
  40.       void* hInstance;
  41.       void* hIcon;
  42.       void* hCursor;
  43.       void* hbrBackground;
  44.       const char* lpszMenuName;
  45.       const char* lpszClassName;
  46.       void* hIconSm;
  47.     } WNDCLASSEXA;
  48.    
  49.     typedef struct MSG {
  50.       void* hwnd;
  51.       uint32_t message;
  52.       uintptr_t wParam, lParam;
  53.       uint32_t time;
  54.       POINT pt;
  55.     } MSG;
  56.    
  57.     typedef struct SECURITY_ATTRIBUTES {
  58.       uint32_t nLength;
  59.       void* lpSecurityDescriptor;
  60.       bool32 bInheritHandle;
  61.     } SECURITY_ATTRIBUTES;
  62.    
  63.     void* GetModuleHandleA(const char* name);
  64.     uint16_t RegisterClassExA(const WNDCLASSEXA*);
  65.     intptr_t DefWindowProcA(void* hwnd, uint32_t msg, uintptr_t wparam, uintptr_t lparam);
  66.     void PostQuitMessage(int exitCode);
  67.     void* LoadIconA(void* hInstance, const char* iconName);
  68.     void* LoadCursorA(void* hInstance, const char* cursorName);
  69.     uint32_t GetLastError();
  70.     void* CreateWindowExA(uint32_t exstyle,
  71.       const char* classname,
  72.       const char* windowname,
  73.       int32_t style,
  74.       int32_t x, int32_t y, int32_t width, int32_t height,
  75.       void* parent_hwnd, void* hmenu, void* hinstance, void* param);
  76.     bool32 ShowWindow(void* hwnd, int32_t command);
  77.     bool32 UpdateWindow(void* hwnd);
  78.     bool32 PeekMessageA(MSG* out_msg, void* hwnd, uint32_t filter_min, uint32_t filter_max, uint32_t removalMode);
  79.     bool32 TranslateMessage(const MSG* msg);
  80.     intptr_t DispatchMessageA(const MSG* msg);
  81.     bool32 InvalidateRect(void* hwnd, const RECT*, bool32 erase);
  82.     void* CreateEventA(SECURITY_ATTRIBUTES*, bool32 manualReset, bool32 initialState, const char* name);
  83.     uint32_t MsgWaitForMultipleObjects(uint32_t count, void** handles, bool32 waitAll, uint32_t ms, uint32_t wakeMask);
  84.  
  85.   ]]
  86.  
  87.   return ffi.C
  88. end
  89.  
  90. package.preload['extern.mswindows.winmm'] = function()
  91.   local ffi = require 'ffi'
  92.    
  93.   ffi.cdef [[
  94.  
  95.     enum {
  96.       TIME_PERIODIC = 0x1,
  97.       TIME_CALLBACK_FUNCTION = 0x00,
  98.       TIME_CALLBACK_EVENT_SET = 0x10,
  99.       TIME_CALLBACK_EVENT_PULSE = 0x20
  100.     };
  101.     uint32_t timeSetEvent(uint32_t delayMs, uint32_t resolutionMs, void* callback_or_event, uintptr_t user, uint32_t eventType);
  102.    
  103.   ]]
  104.  
  105.   return ffi.load 'winmm'
  106. end
  107.  
  108. package.preload['extern.mswindows.idi'] = function()
  109.  
  110.   local ffi = require 'ffi'
  111.  
  112.   return {
  113.     APPLICATION = ffi.cast('const char*', 32512);
  114.   }
  115.  
  116. end
  117.  
  118. package.preload['extern.mswindows.idc'] = function()
  119.  
  120.   local ffi = require 'ffi'
  121.  
  122.   return {
  123.     ARROW = ffi.cast('const char*', 32512);
  124.   }
  125.  
  126. end
  127.  
  128. local bit = require 'bit'
  129. local ffi = require 'ffi'
  130. local mswin = require 'extern.mswindows'
  131. local winmm = require 'extern.mswindows.winmm'
  132. local idi = require 'extern.mswindows.idi'
  133. local idc = require 'extern.mswindows.idc'
  134.  
  135. local hInstance = mswin.GetModuleHandleA(nil)
  136.  
  137. local CLASS_NAME = 'TestWindowClass'
  138.  
  139. local reg = mswin.RegisterClassExA(ffi.new('WNDCLASSEXA', {
  140.   cbSize = ffi.sizeof 'WNDCLASSEXA';
  141.   style = bit.bor(mswin.CS_HREDRAW, mswin.CS_VREDRAW);
  142.   lpfnWndProc = function(hwnd, msg, wparam, lparam)
  143.     if (msg == mswin.WM_DESTROY) then
  144.       mswin.PostQuitMessage(0)
  145.       return 0
  146.     end
  147.     return mswin.DefWindowProcA(hwnd, msg, wparam, lparam)
  148.   end;
  149.   cbClsExtra = 0;
  150.   cbWndExtra = 0;
  151.   hInstance = hInstance;
  152.   hIcon = mswin.LoadIconA(nil, idi.APPLICATION);
  153.   hCursor = mswin.LoadCursorA(nil, idc.ARROW);
  154.   hbrBackground = nil;
  155.   lpszMenuName = nil;
  156.   lpszClassName = CLASS_NAME;
  157.   hIconSm = nil;
  158. }))
  159.  
  160. if (reg == 0) then
  161.   error('error #' .. mswin.GetLastError())
  162. end
  163.  
  164. local testHwnd = mswin.CreateWindowExA(
  165.   0,
  166.   CLASS_NAME,
  167.   'Test Window',
  168.   mswin.WS_OVERLAPPEDWINDOW,
  169.   320, 200,
  170.   320, 200,
  171.   nil,
  172.   nil,
  173.   hInstance,
  174.   nil)
  175.  
  176. if (testHwnd == nil) then
  177.   error 'unable to create window'
  178. end
  179.  
  180. mswin.ShowWindow(testHwnd, mswin.SW_SHOW)
  181. mswin.UpdateWindow(testHwnd)
  182.  
  183. local timerEvent = mswin.CreateEventA(nil, false, false, nil)
  184. if (timerEvent == nil) then
  185.   error('unable to create event')
  186. end
  187. local timer = winmm.timeSetEvent(25, 5, timerEvent, 0, bit.bor(winmm.TIME_PERIODIC, winmm.TIME_CALLBACK_EVENT_SET))
  188. if (timer == 0) then
  189.   error('unable to create timer')
  190. end
  191.  
  192. local handleCount = 1
  193. local handles = ffi.new('void*[1]', {timerEvent})
  194.  
  195. local msg = ffi.new 'MSG'
  196.  
  197. local quitting = false
  198. while not quitting do
  199.   local waitResult = mswin.MsgWaitForMultipleObjects(handleCount, handles, false, mswin.INFINITE, mswin.QS_ALLEVENTS)
  200.   if (waitResult == mswin.WAIT_OBJECT_0+handleCount) then
  201.     if (mswin.PeekMessageA(msg, nil, 0, 0, mswin.PM_REMOVE) ~= 0) then
  202.       mswin.TranslateMessage(msg)
  203.       mswin.DispatchMessageA(msg)
  204.       if (msg.message == mswin.WM_QUIT) then
  205.         quitting = true
  206.       end
  207.     end
  208.   elseif (waitResult == mswin.WAIT_OBJECT_0) then
  209.     mswin.InvalidateRect(testHwnd, nil, false)
  210.   else
  211.     print 'unexpected event'
  212.   end
  213. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement