Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright (C) 2006, 2007, 2009 Apple Computer, Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 #include "config.h"
     26 
     27 #include <windows.h>
     28 
     29 #include "QTMovieWinTimer.h"
     30 
     31 #include <wtf/Assertions.h>
     32 
     33 // This file is used by the QuickTime access DLL. It copies some WebCore code
     34 // which can't be used directly due to dependency issues.
     35 
     36 // FIXME: Find a way to do timers that can manage <10ms resolution properly too.
     37 
     38 static UINT_PTR timerID;
     39 static void (*sharedTimerFiredFunction)();
     40 
     41 static HINSTANCE instanceHandle = 0;
     42 
     43 static HWND timerWindowHandle = 0;
     44 static UINT timerFiredMessage = 0;
     45 static const LPCWSTR kTimerWindowClassName = L"TimerWindowClass";
     46 static bool processingCustomTimerMessage = false;
     47 
     48 static LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     49 {
     50     if (message == timerFiredMessage) {
     51         processingCustomTimerMessage = true;
     52         sharedTimerFiredFunction();
     53         processingCustomTimerMessage = false;
     54     } else if (message == WM_TIMER && wParam == timerID) {
     55         stopSharedTimer();
     56         sharedTimerFiredFunction();
     57     } else
     58         return DefWindowProc(hWnd, message, wParam, lParam);
     59     return 0;
     60 }
     61 
     62 static void initializeOffScreenTimerWindow()
     63 {
     64     if (timerWindowHandle)
     65         return;
     66 
     67     WNDCLASSEX wcex;
     68     memset(&wcex, 0, sizeof(WNDCLASSEX));
     69     wcex.cbSize = sizeof(WNDCLASSEX);
     70     wcex.lpfnWndProc    = TimerWindowWndProc;
     71     wcex.hInstance      = instanceHandle;
     72     wcex.lpszClassName  = kTimerWindowClassName;
     73     RegisterClassEx(&wcex);
     74 
     75     timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0,
     76        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, instanceHandle, 0);
     77     timerFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.TimerFired");
     78 }
     79 
     80 void setSharedTimerFiredFunction(void (*f)())
     81 {
     82     sharedTimerFiredFunction = f;
     83 }
     84 
     85 void setSharedTimerFireDelay(double interval)
     86 {
     87     ASSERT(sharedTimerFiredFunction);
     88 
     89     unsigned intervalInMS;
     90     if (interval < 0)
     91         intervalInMS = 0;
     92     else {
     93         interval *= 1000;
     94         if (interval > USER_TIMER_MAXIMUM)
     95             intervalInMS = USER_TIMER_MAXIMUM;
     96         else
     97             intervalInMS = (unsigned)interval;
     98     }
     99 
    100     stopSharedTimer();
    101     initializeOffScreenTimerWindow();
    102 
    103     // We don't allow nested PostMessages, since the custom messages will effectively starve
    104     // painting and user input. (Win32 has a tri-level queue with application messages >
    105     // user input > WM_PAINT/WM_TIMER.)
    106     // In addition, if the queue contains input events that have been there since the last call to
    107     // GetQueueStatus, PeekMessage or GetMessage we favor timers.
    108     if (intervalInMS < USER_TIMER_MINIMUM
    109         && !processingCustomTimerMessage
    110         && !LOWORD(::GetQueueStatus(QS_ALLINPUT))) {
    111         // Windows SetTimer does not allow timeouts smaller than 10ms (USER_TIMER_MINIMUM)
    112         PostMessage(timerWindowHandle, timerFiredMessage, 0, 0);
    113     } else
    114         timerID = SetTimer(timerWindowHandle, timerFiredMessage, intervalInMS, 0);
    115 }
    116 
    117 void stopSharedTimer()
    118 {
    119     if (timerID) {
    120         KillTimer(timerWindowHandle, timerID);
    121         timerID = 0;
    122     }
    123 }
    124 
    125 void setSharedTimerInstanceHandle(HINSTANCE handle)
    126 {
    127     instanceHandle = handle;
    128 }
    129 
    130 double systemTime()
    131 {
    132     FILETIME ft;
    133     GetSystemTimeAsFileTime(&ft);
    134     ULARGE_INTEGER t;
    135     memcpy(&t, &ft, sizeof(t));
    136     return t.QuadPart * 0.0000001 - 11644473600.0;
    137 }
    138