13464ebd5Sriastradh/**************************************************************************
23464ebd5Sriastradh *
33464ebd5Sriastradh * Copyright 2010 VMware, Inc.
43464ebd5Sriastradh * All Rights Reserved.
53464ebd5Sriastradh *
63464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
73464ebd5Sriastradh * copy of this software and associated documentation files (the
83464ebd5Sriastradh * "Software"), to deal in the Software without restriction, including
93464ebd5Sriastradh * without limitation the rights to use, copy, modify, merge, publish,
103464ebd5Sriastradh * distribute, sub license, and/or sell copies of the Software, and to
113464ebd5Sriastradh * permit persons to whom the Software is furnished to do so, subject to
123464ebd5Sriastradh * the following conditions:
133464ebd5Sriastradh *
143464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
153464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
163464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
173464ebd5Sriastradh * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
183464ebd5Sriastradh * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
193464ebd5Sriastradh * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
203464ebd5Sriastradh * USE OR OTHER DEALINGS IN THE SOFTWARE.
213464ebd5Sriastradh *
223464ebd5Sriastradh * The above copyright notice and this permission notice (including the
233464ebd5Sriastradh * next paragraph) shall be included in all copies or substantial portions
243464ebd5Sriastradh * of the Software.
253464ebd5Sriastradh *
263464ebd5Sriastradh *
273464ebd5Sriastradh **************************************************************************/
283464ebd5Sriastradh
293464ebd5Sriastradh#include "gdi/gdi_sw_winsys.h"
303464ebd5Sriastradh#include "pipe/p_screen.h"
317ec681f3Smrg#include "frontend/graw.h"
323464ebd5Sriastradh#include "target-helpers/inline_debug_helper.h"
333464ebd5Sriastradh#include "target-helpers/inline_sw_helper.h"
343464ebd5Sriastradh#include <windows.h>
353464ebd5Sriastradh
363464ebd5Sriastradh
373464ebd5Sriastradhstatic LRESULT CALLBACK
383464ebd5Sriastradhwindow_proc(HWND hWnd,
393464ebd5Sriastradh            UINT uMsg,
403464ebd5Sriastradh            WPARAM wParam,
413464ebd5Sriastradh            LPARAM lParam)
423464ebd5Sriastradh{
433464ebd5Sriastradh   switch (uMsg) {
443464ebd5Sriastradh   case WM_DESTROY:
453464ebd5Sriastradh      PostQuitMessage(0);
463464ebd5Sriastradh      break;
473464ebd5Sriastradh
483464ebd5Sriastradh   default:
493464ebd5Sriastradh      return DefWindowProc(hWnd, uMsg, wParam, lParam);
503464ebd5Sriastradh   }
513464ebd5Sriastradh
523464ebd5Sriastradh   return 0;
533464ebd5Sriastradh}
543464ebd5Sriastradh
553464ebd5Sriastradhstatic struct {
563464ebd5Sriastradh   void (* draw)(void);
573464ebd5Sriastradh} graw;
583464ebd5Sriastradh
593464ebd5Sriastradhstruct pipe_screen *
603464ebd5Sriastradhgraw_create_window_and_screen(int x,
613464ebd5Sriastradh                              int y,
623464ebd5Sriastradh                              unsigned width,
633464ebd5Sriastradh                              unsigned height,
643464ebd5Sriastradh                              enum pipe_format format,
653464ebd5Sriastradh                              void **handle)
663464ebd5Sriastradh{
673464ebd5Sriastradh   struct sw_winsys *winsys = NULL;
683464ebd5Sriastradh   struct pipe_screen *screen = NULL;
693464ebd5Sriastradh   WNDCLASSEX wc;
703464ebd5Sriastradh   UINT style = WS_VISIBLE | WS_TILEDWINDOW;
713464ebd5Sriastradh   RECT rect;
723464ebd5Sriastradh   HWND hWnd = NULL;
733464ebd5Sriastradh   HDC hDC = NULL;
743464ebd5Sriastradh
753464ebd5Sriastradh   if (format != PIPE_FORMAT_R8G8B8A8_UNORM)
763464ebd5Sriastradh      goto fail;
773464ebd5Sriastradh
783464ebd5Sriastradh   winsys = gdi_create_sw_winsys();
793464ebd5Sriastradh   if (winsys == NULL)
803464ebd5Sriastradh      goto fail;
813464ebd5Sriastradh
823464ebd5Sriastradh   screen = sw_screen_create(winsys);
833464ebd5Sriastradh   if (screen == NULL)
843464ebd5Sriastradh      goto fail;
853464ebd5Sriastradh
863464ebd5Sriastradh   memset(&wc, 0, sizeof wc);
873464ebd5Sriastradh   wc.cbSize = sizeof wc;
883464ebd5Sriastradh   wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
893464ebd5Sriastradh   wc.lpfnWndProc = window_proc;
907ec681f3Smrg   wc.lpszClassName = TEXT("graw-gdi");
913464ebd5Sriastradh   wc.hInstance = GetModuleHandle(NULL);
923464ebd5Sriastradh   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
933464ebd5Sriastradh   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
943464ebd5Sriastradh   wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
953464ebd5Sriastradh   RegisterClassEx(&wc);
963464ebd5Sriastradh
973464ebd5Sriastradh   SetRect(&rect, 0, 0, width, height);
983464ebd5Sriastradh   AdjustWindowRectEx(&rect, style, FALSE, 0);
993464ebd5Sriastradh
1003464ebd5Sriastradh   hWnd = CreateWindowEx(0,
1013464ebd5Sriastradh                         wc.lpszClassName,
1023464ebd5Sriastradh                         wc.lpszClassName,
1033464ebd5Sriastradh                         style,
1043464ebd5Sriastradh                         x,
1053464ebd5Sriastradh                         y,
1063464ebd5Sriastradh                         rect.right - rect.left,
1073464ebd5Sriastradh                         rect.bottom - rect.top,
1083464ebd5Sriastradh                         NULL,
1093464ebd5Sriastradh                         NULL,
1103464ebd5Sriastradh                         wc.hInstance,
1113464ebd5Sriastradh                         0);
1123464ebd5Sriastradh   if (hWnd == NULL)
1133464ebd5Sriastradh      goto fail;
1143464ebd5Sriastradh
1153464ebd5Sriastradh   hDC = GetDC(hWnd);
1163464ebd5Sriastradh   if (hDC == NULL)
1173464ebd5Sriastradh      goto fail;
1183464ebd5Sriastradh
1193464ebd5Sriastradh   *handle = (void *)hDC;
1203464ebd5Sriastradh
1213464ebd5Sriastradh   return debug_screen_wrap(screen);
1223464ebd5Sriastradh
1233464ebd5Sriastradhfail:
1243464ebd5Sriastradh   if (hWnd)
1253464ebd5Sriastradh      DestroyWindow(hWnd);
1263464ebd5Sriastradh
1273464ebd5Sriastradh   if (screen)
1283464ebd5Sriastradh      screen->destroy(screen);
1293464ebd5Sriastradh
1303464ebd5Sriastradh   return NULL;
1313464ebd5Sriastradh}
1323464ebd5Sriastradh
1333464ebd5Sriastradhvoid
1343464ebd5Sriastradhgraw_set_display_func(void (* draw)(void))
1353464ebd5Sriastradh{
1363464ebd5Sriastradh   graw.draw = draw;
1373464ebd5Sriastradh}
1383464ebd5Sriastradh
1393464ebd5Sriastradhvoid
1403464ebd5Sriastradhgraw_main_loop(void)
1413464ebd5Sriastradh{
1423464ebd5Sriastradh   for (;;) {
1433464ebd5Sriastradh      MSG msg;
1443464ebd5Sriastradh
1453464ebd5Sriastradh      while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
1463464ebd5Sriastradh         if (msg.message == WM_QUIT) {
1473464ebd5Sriastradh            return;
1483464ebd5Sriastradh         }
1493464ebd5Sriastradh         TranslateMessage(&msg);
1503464ebd5Sriastradh         DispatchMessage(&msg);
1513464ebd5Sriastradh      }
1523464ebd5Sriastradh
1533464ebd5Sriastradh      if (graw.draw) {
1543464ebd5Sriastradh         graw.draw();
1553464ebd5Sriastradh      }
1563464ebd5Sriastradh
1573464ebd5Sriastradh      Sleep(0);
1583464ebd5Sriastradh   }
1593464ebd5Sriastradh}
160