rm some cruft that got imported accidently
[lcore.git] / httpserver_20080306 / lmessages.pas
diff --git a/httpserver_20080306/lmessages.pas b/httpserver_20080306/lmessages.pas
deleted file mode 100755 (executable)
index 7bb73fd..0000000
+++ /dev/null
@@ -1,656 +0,0 @@
-unit lmessages;\r
-//windows messages like system based on lcore tasks\r
-interface\r
-\r
-uses pgtypes,sysutils,bsearchtree,strings,syncobjs;\r
-\r
-type\r
-  lparam=taddrint;\r
-  wparam=taddrint;\r
-  thinstance=pointer;\r
-  hicon=pointer;\r
-  hcursor=pointer;\r
-  hbrush=pointer;\r
-  hwnd=qword; //window handles are monotonically increasing 64 bit integers,\r
-              //this should allow for a million windows per second for over half\r
-              //a million years!\r
-\r
-  twndproc=function(ahWnd:HWND; auMsg:Integer; awParam:WPARAM; alParam:LPARAM):Integer; stdcall;\r
-\r
-\r
-  twndclass=record\r
-    style : dword;\r
-    lpfnwndproc : twndproc;\r
-    cbclsextra : integer;\r
-    cbwndextra : integer;\r
-    hinstance : thinstance;\r
-    hicon : hicon;\r
-    hcursor : hcursor;\r
-    hbrbackground : hbrush;\r
-    lpszmenuname : pchar;\r
-    lpszclassname : pchar;\r
-  end;\r
-  PWNDCLASS=^twndclass;\r
-  \r
-  UINT=dword;\r
-  WINBOOL = longbool;\r
-  tTIMERPROC = procedure (ahwnd:HWND; umsg:integer; idevent:taddrint;dwtime:taddrint);stdcall;\r
-  ATOM = pointer;\r
-  LPCSTR = pchar;\r
-  LPVOID = pointer;\r
-  HMENU = pointer;\r
-  HINST = pointer;\r
-\r
-  TPOINT = record \r
-    x : LONGint; \r
-    y : LONGint; \r
-  end; \r
-  \r
-  TMSG = record \r
-    hwnd : HWND; \r
-    message : UINT; \r
-    wParam : WPARAM; \r
-    lParam : LPARAM; \r
-    time : DWORD; \r
-    pt : TPOINT;\r
-  end; \r
-  THevent=TEventObject;\r
-const\r
-  WS_EX_TOOLWINDOW = $80;\r
-  WS_POPUP = longint($80000000);\r
-  hinstance=nil;\r
-  PM_REMOVE = 1;\r
-  WM_USER = 1024;\r
-  WM_TIMER = 275;\r
-  INFINITE = syncobjs.infinite;\r
-function getwindowlongptr(ahwnd:hwnd;nindex:integer) : taddrint;\r
-function setwindowlongptr(ahwnd:hwnd;nindex:integer;dwNewLong : taddrint) : taddrint;\r
-function DefWindowProc(ahWnd:HWND; auMsg:Integer; awParam:WPARAM; alParam:LPARAM):Integer; stdcall;\r
-function RegisterClass(const lpWndClass:TWNDCLASS):ATOM;\r
-function CreateWindowEx(dwExStyle:DWORD; lpClassName:LPCSTR; lpWindowName:LPCSTR; dwStyle:DWORD; X:longint;Y:longint; nWidth:longint; nHeight:longint; hWndParent:HWND; hMenu:HMENU;hInstance:HINST; lpParam:LPVOID):HWND;\r
-function DestroyWindow(ahWnd:HWND):WINBOOL;\r
-function PostMessage(hWnd:HWND; Msg:UINT; wParam:WPARAM; lParam:LPARAM):WINBOOL;\r
-function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): WINBOOL;\r
-function DispatchMessage(const lpMsg: TMsg): Longint;\r
-function GetMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax: UINT): WINBOOL;\r
-function SetEvent(hEvent:THevent):WINBOOL;\r
-function CreateEvent(lpEventAttributes:PSECURITYATTRIBUTES; bManualReset:WINBOOL; bInitialState:WINBOOL; lpName:pchar):tHevent;\r
-function terminatethread(threadhandle : tthreadid;dummy:integer) : boolean;\r
-function waitforsingleevent(event:thevent;timeout:cardinal) : twaitresult;\r
-function SetTimer(ahWnd:HWND; nIDEvent:taddrint; uElapse:UINT; lpTimerFunc:tTIMERPROC):UINT;\r
-function KillTimer(ahWnd:HWND; uIDEvent:taddrint):WINBOOL;\r
-\r
-procedure init;\r
-\r
-implementation\r
-uses\r
-  baseunix,unix,lcore;//,safewriteln;\r
-{$i unixstuff.inc}\r
-\r
-type\r
-  tmessageintransit = class\r
-    msg : tmsg;\r
-    next : tmessageintransit;\r
-  end;\r
-\r
-  tthreaddata = class\r
-    messagequeue : tmessageintransit;\r
-    messageevent : teventobject;\r
-    waiting : boolean;\r
-    lcorethread : boolean;\r
-    nexttimer : ttimeval;\r
-    threadid : integer;\r
-  end;\r
-  twindow=class\r
-    hwnd : hwnd;\r
-    extrawindowmemory : pointer;\r
-    threadid : tthreadid;\r
-    windowproc : twndproc;\r
-  end;\r
-\r
-var\r
-  structurelock : tcriticalsection;\r
-  threaddata : thashtable;\r
-  windowclasses : thashtable;\r
-  lcorelinkpipesend : integer;\r
-  lcorelinkpiperecv : tlasio;\r
-  windows : thashtable;\r
-  //I would rather things crash immediately\r
-  //if they use an insufficiant size type\r
-  //than crash after over four billion\r
-  //windows have been made ;)\r
-  nextwindowhandle : qword = $100000000;\r
-{$i ltimevalstuff.inc}\r
-\r
-//findthreaddata should only be called while holding the structurelock\r
-function findthreaddata(threadid : integer) : tthreaddata;\r
-begin\r
-  result := tthreaddata(findtree(@threaddata,inttostr(threadid)));\r
-  if result = nil then begin\r
-    result := tthreaddata.create;\r
-    result.messageevent := teventobject.create(nil,false,false,inttostr(taddrint(result)));\r
-    result.nexttimer := tv_invalidtimebig;\r
-    result.threadid := threadid;\r
-    addtree(@threaddata,inttostr(threadid),result);\r
-  end;\r
-end;\r
-\r
-//deletethreaddataifunused should only be called while holding the structurelock\r
-procedure deletethreaddataifunused(athreaddata : tthreaddata);\r
-begin\r
-  //writeln('in deletethreaddataifunused');\r
-  if (athreaddata <> nil) then if (athreaddata.waiting=false) and (athreaddata.messagequeue=nil) and (athreaddata.lcorethread=false) and (athreaddata.nexttimer.tv_sec=tv_invalidtimebig.tv_sec) and (athreaddata.nexttimer.tv_usec=tv_invalidtimebig.tv_usec) then begin\r
-    //writeln('threaddata is unused, freeing messageevent');\r
-    athreaddata.messageevent.free;\r
-    //writeln('freeing thread data object');\r
-    athreaddata.free;\r
-    //writeln('deleting thread data object from hashtable');\r
-    deltree(@threaddata,inttostr(athreaddata.threadid));\r
-    //writeln('finished deleting thread data');\r
-  end else begin\r
-    //writeln('thread data is not unused');\r
-  end;\r
-end;\r
-\r
-function getwindowlongptr(ahwnd:hwnd;nindex:integer) : taddrint;\r
-var\r
-  window : twindow;\r
-begin\r
-  structurelock.acquire;\r
-  try\r
-    window := findtree(@windows,inttostr(ahwnd));\r
-    if window <> nil then begin\r
-      result := paddrint(taddrint(window.extrawindowmemory)+nindex)^;\r
-    end else begin\r
-      result := 0;\r
-    end;\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-end;\r
-\r
-function setwindowlongptr(ahwnd:hwnd;nindex:integer;dwNewLong : taddrint) : taddrint;\r
-var\r
-  window : twindow;\r
-begin\r
-  structurelock.acquire;\r
-  try\r
-    window := findtree(@windows,inttostr(ahwnd));\r
-    if window <> nil then begin\r
-      result := paddrint(taddrint(window.extrawindowmemory)+nindex)^;\r
-      paddrint(taddrint(window.extrawindowmemory)+nindex)^ := dwnewlong;\r
-    end else begin\r
-      result := 0;\r
-    end;\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-\r
-end;\r
-\r
-\r
-function DefWindowProc(ahWnd:HWND; auMsg:Integer; awParam:WPARAM; alParam:LPARAM):Integer; stdcall;\r
-begin\r
-  result := 0;\r
-end;\r
-\r
-function strdup(s:pchar) : pchar;\r
-begin\r
-  //swriteln('in strdup, about to allocate memory');\r
-  result := getmem(strlen(s)+1);\r
-  //swriteln('about to copy string');\r
-  strcopy(s,result);\r
-  //swriteln('leaving strdup');\r
-end;\r
-\r
-function RegisterClass(const lpWndClass:TWNDCLASS):ATOM;\r
-var\r
-  storedwindowclass:pwndclass;\r
-begin\r
-  structurelock.acquire;\r
-  try\r
-    //swriteln('in registerclass, about to check for duplicate window class');\r
-    storedwindowclass := findtree(@windowclasses, lpwndclass.lpszclassname);\r
-    if storedwindowclass <> nil then begin\r
-\r
-      if comparebyte(storedwindowclass^,lpwndclass,sizeof(twndclass)-sizeof(pchar)-sizeof(pchar)) <> 0 then begin\r
-        //swriteln('duplicate window class registered with different settings');\r
-        raise exception.create('duplicate window class registered with different settings');\r
-      end else begin\r
-        //swriteln('duplicate window class registered with same settings, tollerated');\r
-      end;\r
-    end else begin\r
-      //swriteln('about to allocate memory for new windowclass');\r
-      storedwindowclass := getmem(sizeof(twndclass));\r
-      //swriteln('about to copy windowclass from parameter');\r
-      move(lpwndclass,storedwindowclass^,sizeof(twndclass));\r
-      //swriteln('about to copy strings');\r
-      if lpwndclass.lpszmenuname <> nil then storedwindowclass.lpszmenuname := strdup(lpwndclass.lpszmenuname);\r
-      if lpwndclass.lpszclassname <> nil then storedwindowclass.lpszclassname := strdup(lpwndclass.lpszclassname);\r
-      //swriteln('about to add result to list of windowclasses');\r
-      addtree(@windowclasses,lpwndclass.lpszclassname,storedwindowclass);\r
-    end;\r
-    //swriteln('about to return result');\r
-    result := storedwindowclass;\r
-    //swriteln('leaving registerclass');\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-end;\r
-\r
-function CreateWindowEx(dwExStyle:DWORD; lpClassName:LPCSTR; lpWindowName:LPCSTR; dwStyle:DWORD; X:longint;Y:longint; nWidth:longint; nHeight:longint; hWndParent:HWND; hMenu:HMENU;hInstance:HINST; lpParam:LPVOID):HWND;\r
-var\r
-  wndclass : pwndclass;\r
-  tm : tthreadmanager;\r
-  window : twindow;\r
-begin\r
-  structurelock.acquire;\r
-  try\r
-    window := twindow.create;\r
-    window.hwnd := nextwindowhandle;\r
-    result := window.hwnd;\r
-    nextwindowhandle := nextwindowhandle + 1;\r
-    addtree(@windows,inttostr(window.hwnd),window);\r
-    wndclass := findtree(@windowclasses,lpclassname);\r
-    window.extrawindowmemory := getmem(wndclass.cbwndextra);\r
-\r
-    getthreadmanager(tm);\r
-    window.threadid := tm.GetCurrentThreadId;\r
-    window.windowproc := wndclass.lpfnwndproc;\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-end;\r
-function DestroyWindow(ahWnd:HWND):WINBOOL;\r
-var\r
-  window : twindow;\r
-  windowthreaddata : tthreaddata;\r
-  currentmessage : tmessageintransit;\r
-  prevmessage : tmessageintransit;\r
-begin\r
-  //writeln('started to destroy window');\r
-  structurelock.acquire;\r
-  try\r
-    window := twindow(findtree(@windows,inttostr(ahwnd)));\r
-    if window <> nil then begin\r
-      freemem(window.extrawindowmemory);\r
-      //writeln('aboute to delete window from windows structure');\r
-      deltree(@windows,inttostr(ahwnd));\r
-      //writeln('deleted window from windows structure');\r
-      windowthreaddata := tthreaddata(findtree(@threaddata,inttostr(window.threadid)));\r
-\r
-      if windowthreaddata <> nil then begin\r
-        //writeln('found thread data scanning for messages to clean up');\r
-        currentmessage := windowthreaddata.messagequeue;\r
-        prevmessage := nil;\r
-        while currentmessage <> nil do begin\r
-          while (currentmessage <> nil) and (currentmessage.msg.hwnd = ahwnd) do begin\r
-            if prevmessage = nil then begin\r
-              windowthreaddata.messagequeue := currentmessage.next;\r
-            end else begin\r
-              prevmessage.next := currentmessage.next;\r
-            end;\r
-            currentmessage.free;\r
-            if prevmessage = nil then begin\r
-              currentmessage := windowthreaddata.messagequeue;\r
-            end else begin\r
-              currentmessage := prevmessage.next;\r
-            end;\r
-          end;\r
-          if currentmessage <> nil then begin\r
-            prevmessage := currentmessage;\r
-            currentmessage := currentmessage.next;\r
-          end;\r
-        end;\r
-        //writeln('deleting thread data structure if it is unused');\r
-        deletethreaddataifunused(windowthreaddata);\r
-      end else begin\r
-        //writeln('there is no thread data to search for messages to cleanup');\r
-      end;\r
-      //writeln('freeing window');\r
-      window.free;\r
-      result := true;\r
-    end else begin\r
-      result := false;\r
-    end;\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-  //writeln('window destroyed');\r
-end;\r
-\r
-\r
-\r
-function PostMessage(hWnd:HWND; Msg:UINT; wParam:WPARAM; lParam:LPARAM):WINBOOL;\r
-var\r
-  threaddata : tthreaddata;\r
-  message : tmessageintransit;\r
-  messagequeueend : tmessageintransit;\r
-  window : twindow;\r
-begin\r
-  structurelock.acquire;\r
-  try\r
-    window := findtree(@windows,inttostr(hwnd));\r
-    if window <> nil then begin\r
-      threaddata := findthreaddata(window.threadid);\r
-      message := tmessageintransit.create;\r
-      message.msg.hwnd := hwnd;\r
-      message.msg.message := msg;\r
-      message.msg.wparam := wparam;\r
-      message.msg.lparam := lparam;\r
-      if threaddata.lcorethread then begin\r
-        //swriteln('posting message to lcore thread');\r
-        fdwrite(lcorelinkpipesend,message,sizeof(message));\r
-      end else begin\r
-        //writeln('posting message to non lcore thread');\r
-        if threaddata.messagequeue = nil then begin\r
-          threaddata.messagequeue := message;\r
-        end else begin\r
-          messagequeueend := threaddata.messagequeue;\r
-          while messagequeueend.next <> nil do begin\r
-            messagequeueend := messagequeueend.next;\r
-          end;\r
-          messagequeueend.next := message;\r
-        end;\r
-\r
-        //writeln('message added to queue');\r
-        if threaddata.waiting then threaddata.messageevent.setevent;\r
-      end;\r
-      result := true;\r
-    end else begin\r
-      result := false;\r
-    end;\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-\r
-end;\r
-\r
-function gettickcount : dword;\r
-var\r
-  result64: integer;\r
-  tv : ttimeval;\r
-begin\r
-  gettimeofday(tv);\r
-  result64 := (tv.tv_sec*1000)+(tv.tv_usec div 1000);\r
-  result := result64;\r
-end;\r
-\r
-function DispatchMessage(const lpMsg: TMsg): Longint;\r
-var\r
-  timerproc : ttimerproc;\r
-  window : twindow;\r
-  windowproc : twndproc;\r
-begin\r
-  ////swriteln('in dispatchmessage, msg.hwnd='+inttohex(taddrint(lpmsg.hwnd),16));\r
-  if (lpmsg.lparam <> 0) and (lpmsg.message = WM_TIMER) then begin\r
-    timerproc := ttimerproc(lpmsg.lparam);\r
-    timerproc(lpmsg.hwnd,lpmsg.message,lpmsg.wparam,gettickcount);\r
-    result := 0;\r
-  end else begin\r
-    structurelock.acquire;\r
-    try\r
-      window := findtree(@windows,inttostr(lpmsg.hwnd));\r
-      //we have to get the window procedure while the structurelock\r
-      //is still held as the window could be destroyed from another thread\r
-      //otherwise.\r
-      windowproc := window.windowproc;\r
-    finally\r
-      structurelock.release;\r
-    end;\r
-    if window <> nil then begin\r
-      result := windowproc(lpmsg.hwnd,lpmsg.message,lpmsg.wparam,lpmsg.lparam);\r
-    end else begin\r
-      result := -1;\r
-    end;\r
-  end;\r
-end;\r
-\r
-procedure processtimers;\r
-begin\r
-end;\r
-\r
-function GetMessageinternal(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax: UINT; wremovemsg : UINT;peek:boolean): WINBOOL;\r
-var\r
-  tm : tthreadmanager;\r
-  threaddata : tthreaddata;\r
-  message : tmessageintransit;\r
-  nowtv : ttimeval;\r
-  timeouttv : ttimeval;\r
-  timeoutms : int64;\r
-\r
-begin\r
-  if hwnd <> 0 then raise exception.create('getting messages for an individual window is not supported');\r
-  if (wmsgfiltermin <> 0) or (wmsgfiltermax <> 0) then raise exception.create('message filtering is not supported');\r
-  structurelock.acquire;\r
-  result := true;\r
-  try\r
-    getthreadmanager(tm);\r
-    threaddata := findthreaddata(tm.GetCurrentThreadId);\r
-    if threaddata.lcorethread then raise exception.create('get/peek message cannot be used in the lcore thread');\r
-    message := threaddata.messagequeue;\r
-    gettimeofday(nowtv);\r
-    while (not peek) and (message=nil) and (not tv_compare(nowtv,threaddata.nexttimer)) do begin\r
-      threaddata.waiting := true;\r
-      structurelock.release;\r
-      if (threaddata.nexttimer.tv_sec = TV_invalidtimebig.tv_sec) and (threaddata.nexttimer.tv_usec = TV_invalidtimebig.tv_usec) then begin\r
-        threaddata.messageevent.waitfor(INFINITE);\r
-      end else begin\r
-\r
-        timeouttv := threaddata.nexttimer;\r
-        timeoutms := (timeouttv.tv_sec * 1000)+(timeouttv.tv_usec div 1000);\r
-        //i'm assuming the timeout is in milliseconds\r
-        if (timeoutms > maxlongint) then timeoutms := maxlongint;\r
-        threaddata.messageevent.waitfor(timeoutms);\r
-\r
-      end;\r
-      structurelock.acquire;\r
-      threaddata.waiting := false;\r
-      message := threaddata.messagequeue;\r
-      gettimeofday(nowtv);\r
-    end;\r
-    if (message=nil) and tv_compare(nowtv,threaddata.nexttimer) then begin\r
-      processtimers;\r
-    end;\r
-    message := threaddata.messagequeue;\r
-    if message <> nil then begin\r
-      lpmsg := message.msg;\r
-      if wremovemsg=PM_REMOVE then begin\r
-        threaddata.messagequeue := message.next;\r
-        message.free;\r
-      end;\r
-    end else begin\r
-      result :=false;\r
-    end;\r
-    deletethreaddataifunused(threaddata);\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-end;\r
-\r
-function GetMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax: UINT): WINBOOL;\r
-begin\r
-  result := getmessageinternal(lpmsg,hwnd,wmsgfiltermin,wmsgfiltermax,PM_REMOVE,false);\r
-end;\r
-\r
-function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): WINBOOL;\r
-begin\r
-  result := getmessageinternal(lpmsg,hwnd,wmsgfiltermin,wmsgfiltermax,PM_REMOVE,true);\r
-end;\r
-\r
-function SetEvent(hEvent:THevent):WINBOOL;\r
-begin\r
-  hevent.setevent;\r
-  result := true;\r
-end;\r
-\r
-function CreateEvent(lpEventAttributes:PSECURITYATTRIBUTES; bManualReset:WINBOOL; bInitialState:WINBOOL; lpName:pchar):tHevent;\r
-begin\r
-  result := teventobject.create(lpeventattributes,bmanualreset,binitialstate,lpname);\r
-end;\r
-\r
-function terminatethread(threadhandle:tthreadid;dummy : integer) : boolean;\r
-var\r
-  tm : tthreadmanager;\r
-begin\r
-  getthreadmanager(tm);\r
-  tm.killthread(threadhandle);\r
-  result := true;\r
-end;\r
-\r
-function waitforsingleevent(event:thevent;timeout:cardinal) : twaitresult;\r
-begin\r
-  result := event.waitfor(timeout);\r
-end;\r
-\r
-procedure removefrombuffer(n : integer; var buffer:string);\r
-begin\r
-  if n=length(buffer) then begin\r
-    buffer := '';\r
-  end else begin\r
-    uniquestring(buffer);\r
-    move(buffer[n+1],buffer[1],length(buffer)-n);\r
-    setlength(buffer,length(buffer)-n);\r
-  end;\r
-end;\r
-\r
-type\r
-  tsc=class\r
-    procedure available(sender:tobject;error:word);\r
-  end;\r
-\r
-var\r
-  recvbuf : string;\r
-\r
-procedure tsc.available(sender:tobject;error:word);\r
-var\r
-  message : tmessageintransit;\r
-  messagebytes : array[1..sizeof(tmessageintransit)] of char absolute  message;\r
-  i : integer;\r
-begin\r
-  //swriteln('received data on lcorelinkpipe');\r
-  recvbuf := recvbuf + lcorelinkpiperecv.receivestr;\r
-  while length(recvbuf) >= sizeof(tmessageintransit) do begin\r
-    for i := 1 to sizeof(tmessageintransit) do begin\r
-      messagebytes[i] := recvbuf[i];\r
-    end;\r
-    dispatchmessage(message.msg);\r
-    message.free;\r
-    removefrombuffer(sizeof(tmessageintransit),recvbuf);\r
-  end;\r
-end;\r
-\r
-procedure init;\r
-var\r
-  tm : tthreadmanager;\r
-  threaddata : tthreaddata;\r
-  pipeends : tfildes;\r
-  sc : tsc;\r
-begin\r
-  structurelock := tcriticalsection.create;\r
-  getthreadmanager(tm);\r
-  threaddata := findthreaddata(tm.GetCurrentThreadId);\r
-  threaddata.lcorethread := true;\r
-  fppipe(pipeends);\r
-  lcorelinkpipesend := pipeends[1];\r
-  lcorelinkpiperecv := tlasio.create(nil);\r
-  lcorelinkpiperecv.dup(pipeends[0]);\r
-  lcorelinkpiperecv.ondataavailable := sc.available;\r
-  recvbuf := '';\r
-end;\r
-\r
-var\r
-  lcorethreadtimers : thashtable;\r
-type\r
-  tltimerformsg = class(tltimer)\r
-  public\r
-    hwnd : hwnd;\r
-    id : taddrint;\r
-    procedure timer(sender : tobject);\r
-  end;\r
-\r
-procedure tltimerformsg.timer(sender : tobject);\r
-var\r
-  msg : tmsg;\r
-begin\r
-  ////swriteln('in tltimerformsg.timer');\r
-  fillchar(msg,sizeof(msg),0);\r
-  msg.message := WM_TIMER;\r
-  msg.hwnd := hwnd;\r
-  msg.wparam := ID;\r
-  msg.lparam := 0;\r
-  dispatchmessage(msg);\r
-end;\r
-\r
-function SetTimer(ahWnd:HWND; nIDEvent:taddrint; uElapse:UINT; lpTimerFunc:tTIMERPROC):UINT;\r
-var\r
-  threaddata : tthreaddata;\r
-  ltimer : tltimerformsg;\r
-  tm : tthreadmanager;\r
-  window : twindow;\r
-begin\r
-  structurelock.acquire;\r
-  try\r
-    window := findtree(@windows,inttostr(ahwnd));\r
-    if window= nil then raise exception.create('invalid window');\r
-    threaddata := findthreaddata(window.threadid);\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-  if threaddata.lcorethread then begin\r
-    getthreadmanager(tm);\r
-    if tm.GetCurrentThreadId <> window.threadid then raise exception.create('timers on the lcore thread may only be added and removed from the lcore thread');\r
-    if ahwnd = 0 then raise exception.create('timers on the lcore thread must be associated with a window handle');\r
-    if @lptimerfunc <> nil then raise exception.create('seperate timer functions are not supported');\r
-\r
-    //remove preexisting timer with same ID\r
-    killtimer(ahwnd,nIDEvent);\r
-\r
-    ltimer := tltimerformsg.create(nil);\r
-    ltimer.interval := uelapse;\r
-    ltimer.id := nidevent;\r
-    ltimer.hwnd := ahwnd;\r
-    ltimer.enabled := true;\r
-    ltimer.ontimer := ltimer.timer;\r
-\r
-    addtree(@lcorethreadtimers,inttostr(taddrint(ahwnd))+' '+inttostr(nIDEvent),ltimer);\r
-\r
-    result := nidevent;\r
-  end else begin\r
-    raise exception.create('settimer not implemented for threads other than the lcore thread');\r
-  end;\r
-end;\r
-\r
-function KillTimer(ahWnd:HWND; uIDEvent:taddrint):WINBOOL;\r
-var\r
-  threaddata : tthreaddata;\r
-  ltimer : tltimerformsg;\r
-  tm : tthreadmanager;\r
-  window : twindow;\r
-begin\r
-  structurelock.acquire;\r
-  try\r
-    window := findtree(@windows,inttostr(ahwnd));\r
-    if window= nil then raise exception.create('invalid window');\r
-    threaddata := findthreaddata(window.threadid);\r
-  finally\r
-    structurelock.release;\r
-  end;\r
-  if threaddata.lcorethread then begin\r
-    getthreadmanager(tm);\r
-    if tm.GetCurrentThreadId <> window.threadid then raise exception.create('timers on the lcore thread may only be added and remove from the lcore thread');\r
-    if ahwnd = 0 then raise exception.create('timers on the lcore thread must be associated with a window handle');\r
-    ltimer := tltimerformsg(findtree(@lcorethreadtimers,inttostr(taddrint(ahwnd))+' '+inttostr(uIDEvent)));\r
-    if ltimer <> nil then begin\r
-      deltree(@lcorethreadtimers,inttostr(taddrint(ahwnd))+' '+inttostr(uIDEvent));\r
-      ltimer.free;\r
-      result := true;\r
-    end else begin\r
-      result := false;\r
-    end;\r
-  end else begin\r
-    raise exception.create('settimer not implemented for threads other than the lcore thread');\r
-  end;\r
-end;\r
-\r
-end.
\ No newline at end of file