Esempio n. 1
0
/*
    Create a display screen, or window, large enough to accomodate a bitmap
    of the given dimensions.
    Return a osd_bitmap pointer or 0 in case of error.
*/
static struct osd_bitmap *GDI_create_display(int width, int height, int depth, int attributes)
{
    unsigned int    i;
    RECT            Rect;
    HMENU           hMenu;
    LOGPALETTE      LogPalette;
    char            TitleBuf[256];

    This.m_nDepth = depth;

    if (attributes & VIDEO_TYPE_VECTOR)
    {
        if (This.m_bVectorDouble == TRUE)
        {
            width  *= 2;
            height *= 2;
        }
        /* padding to a DWORD value */
        width  -= width  % 4;
        height -= height % 4;

        AdjustVisibleRect(0, 0, width - 1, height - 1);
    }
    else
    {
        AdjustVisibleRect(Machine->drv->visible_area.min_x,
                          Machine->drv->visible_area.min_y,
                          Machine->drv->visible_area.max_x,
                          Machine->drv->visible_area.max_y);
    }

    This.m_nClientWidth  = This.m_VisibleRect.m_Width;
    This.m_nClientHeight = This.m_VisibleRect.m_Height;

    if ((attributes & VIDEO_PIXEL_ASPECT_RATIO_MASK) == VIDEO_PIXEL_ASPECT_RATIO_1_2)
    {
        if (Machine->orientation & ORIENTATION_SWAP_XY)
            This.m_nClientWidth  *= 2;
        else
            This.m_nClientHeight *= 2;

        This.m_bDouble = FALSE;
    }

    if (This.m_bDouble == TRUE)
    {
        This.m_nClientWidth  *= 2;
        This.m_nClientHeight *= 2;
    }

    if (This.m_bUseDirty == TRUE)
    {
        if (Machine->orientation & ORIENTATION_SWAP_XY)
            InitDirty(height, width, NO_DIRTY);
        else
            InitDirty(width, height, NO_DIRTY);
    }

    /* osd_create_bitmap will swap width and height if neccesary. */
    This.m_pMAMEBitmap = osd_new_bitmap(width, height, This.m_nDepth);
    This.m_pTempBitmap = osd_new_bitmap(width, height, This.m_nDepth);

    /* Palette */
    if (This.m_nDepth == 8)
    {
        LogPalette.palVersion    = 0x0300;
        LogPalette.palNumEntries = 1;
        This.m_hPalette = CreatePalette(&LogPalette);
        ResizePalette(This.m_hPalette, OSD_NUMPENS);
    }

    /* Create BitmapInfo */
    This.m_pInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER) +
                                       sizeof(RGBQUAD) * OSD_NUMPENS);

    This.m_pInfo->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER); 
    This.m_pInfo->bmiHeader.biWidth         =  (This.m_pMAMEBitmap->line[1] - This.m_pMAMEBitmap->line[0]) / (This.m_nDepth / 8);
    This.m_pInfo->bmiHeader.biHeight        = -(int)(This.m_VisibleRect.m_Height); /* Negative means "top down" */
    This.m_pInfo->bmiHeader.biPlanes        = 1;
    This.m_pInfo->bmiHeader.biBitCount      = This.m_nDepth;
    This.m_pInfo->bmiHeader.biCompression   = BI_RGB;
    This.m_pInfo->bmiHeader.biSizeImage     = 0;
    This.m_pInfo->bmiHeader.biXPelsPerMeter = 0;
    This.m_pInfo->bmiHeader.biYPelsPerMeter = 0;
    This.m_pInfo->bmiHeader.biClrUsed       = 0;
    This.m_pInfo->bmiHeader.biClrImportant  = 0;

    if (This.m_nDepth == 8)
    {
        /* Map image values to palette index */
        for (i = 0; i < OSD_NUMPENS; i++)
            ((WORD*)(This.m_pInfo->bmiColors))[i] = i;
    }

    /*
        Modify the main window to suit our needs.
    */
    hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MAIN_MENU));
    SetMenu(MAME32App.m_hWnd, hMenu);

    SetWindowLong(MAME32App.m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME | WS_BORDER);

    sprintf(TitleBuf, "%s - %s", Machine->gamedrv->description, MAME32App.m_Name);
    SetWindowText(MAME32App.m_hWnd, TitleBuf);

    StatusCreate();

    This.m_ClientRect.left   = 0;
    This.m_ClientRect.top    = 0;
    This.m_ClientRect.right  = This.m_nClientWidth;
    This.m_ClientRect.bottom = This.m_nClientHeight;

    /* Calculate size of window based on desired client area. */
    Rect.left   = This.m_ClientRect.left;
    Rect.top    = This.m_ClientRect.top;
    Rect.right  = This.m_ClientRect.right;
    Rect.bottom = This.m_ClientRect.bottom + GetStatusHeight();
    AdjustWindowRect(&Rect, WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME | WS_BORDER, hMenu != NULL);

    This.m_nWindowWidth  = RECT_WIDTH(Rect);
    This.m_nWindowHeight = RECT_HEIGHT(Rect);

    SetWindowPos(MAME32App.m_hWnd,
                 HWND_NOTOPMOST,
                 0, 0,
                 This.m_nWindowWidth,
                 This.m_nWindowHeight,
                 SWP_NOMOVE);

    This.m_hWndAbout = CreateDialog(GetModuleHandle(NULL),
                                    MAKEINTRESOURCE(IDD_ABOUT),
                                    MAME32App.m_hWnd,
                                    AboutDialogProc);

    ShowWindow(MAME32App.m_hWnd, SW_SHOW);
    SetForegroundWindow(MAME32App.m_hWnd);

    set_ui_visarea(This.m_VisibleRect.m_Left,
                   This.m_VisibleRect.m_Top,
                   This.m_VisibleRect.m_Left + This.m_VisibleRect.m_Width  - 1,
                   This.m_VisibleRect.m_Top  + This.m_VisibleRect.m_Height - 1);

    return This.m_pMAMEBitmap;
}
Esempio n. 2
0
int GPsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {
    PIXsize_t ps;
    int color, ai;

    for (ai = 0; ai < attrn; ai++) {
        switch (attrp[ai].id) {
        case G_ATTRORIGIN:
            break;
        case G_ATTRSIZE:
            break;
        case G_ATTRNAME:
            break;
        case G_ATTRMODE:
            break;
        case G_ATTRCOLOR:
            color = attrp[ai].u.c.index;
            if (color < 0 || color > G_MAXCOLORS) {
                Gerr (POS, G_ERRBADCOLORINDEX, color);
                return -1;
            }
            WPU->colors[color].color.peRed = attrp[ai].u.c.r;
            WPU->colors[color].color.peGreen = attrp[ai].u.c.g;
            WPU->colors[color].color.peBlue = attrp[ai].u.c.b;
            WPU->colors[color].color.peFlags = 0;
            if (color >= WPU->ncolor)
                ResizePalette (WPU->cmap, color + 1), WPU->ncolor = color + 1;
            SetPaletteEntries (
                WPU->cmap, (int) color, 1, &WPU->colors[color].color
            );
            RealizePalette (GC);
            WPU->colors[color].inuse = TRUE;
            if (color == WPU->gattr.color)
                WPU->gattr.color = -1;
            break;
        case G_ATTRVIEWPORT:
            if (attrp[ai].u.s.x == 0)
                attrp[ai].u.s.x = 1;
            if (attrp[ai].u.s.y == 0)
                attrp[ai].u.s.y = 1;
            WPU->vsize.x = attrp[ai].u.s.x + 0.5;
            WPU->vsize.y = attrp[ai].u.s.y + 0.5;
            ps.x = WPU->vsize.x, ps.y = WPU->vsize.y;
            break;
        case G_ATTRWINDOW:
            if (attrp[ai].u.r.o.x == attrp[ai].u.r.c.x)
                attrp[ai].u.r.c.x = attrp[ai].u.r.o.x + 1;
            if (attrp[ai].u.r.o.y == attrp[ai].u.r.c.y)
                attrp[ai].u.r.c.y = attrp[ai].u.r.o.y + 1;
            WPU->wrect = attrp[ai].u.r;
            break;
        case G_ATTRWINDOWID:
            Gerr (POS, G_ERRCANNOTSETATTR2, "windowid");
            return -1;
        case G_ATTRUSERDATA:
            widget->udata = attrp[ai].u.u;
            break;
        default:
            Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
            return -1;
        }
    }
    return 0;
}
Esempio n. 3
0
int GPcreatewidget (
    Gwidget_t *parent, Gwidget_t *widget, int attrn, Gwattr_t *attrp
) {
    PIXpoint_t po;
    PIXsize_t ps;
    PRINTDLG pd;
    DOCINFO di;
    DEVMODE *dmp;
    /* the 2 here is to provide enough space for palPalEntry[0] and [1] */
    LOGPALETTE pal[2];

    HBRUSH brush;
    HPEN pen;
    HBITMAP bmap;
    char *s, *s1;
    int color, lflag, ai, dpix, dpiy, i;

    s = Gpscanvasname;
    lflag = FALSE;
    po.x = po.y = 0;
    ps.x = ps.y = MINPWSIZE;
    for (ai = 0; ai < attrn; ai++) {
        switch (attrp[ai].id) {
        case G_ATTRORIGIN:
            GETORIGIN (attrp[ai].u.p, po);
            break;
        case G_ATTRSIZE:
            GETSIZE (attrp[ai].u.s, ps, MINPWSIZE);
            break;
        case G_ATTRNAME:
            if (attrp[ai].u.t && attrp[ai].u.t[0])
                s = attrp[ai].u.t;
            break;
        case G_ATTRMODE:
            if (strcmp ("landscape", attrp[ai].u.t) == 0)
                lflag = TRUE;
            else if (strcmp ("portrait", attrp[ai].u.t) == 0)
                lflag = FALSE;
            else {
                Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);
                return -1;
            }
            break;
        case G_ATTRCOLOR:
            /* will do it after the widget is created */
            break;
        case G_ATTRVIEWPORT:
            /* will do it after the widget is created */
            break;
        case G_ATTRWINDOW:
            /* will do it after the widget is created */
            break;
        case G_ATTRWINDOWID:
            Gerr (POS, G_ERRCANNOTSETATTR1, "windowid");
            return -1;
        case G_ATTRUSERDATA:
            widget->udata = attrp[ai].u.u;
            break;
        default:
            Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
            return -1;
        }
    }
    s1 = s + strlen (s) - 3;
    if (s1 > s && strncmp (s1, "emf", 3) == 0) {
        WPU->mode = 1;
        ps.x *= 8.235, ps.y *= 8.235;
        if (!(GC = CreateEnhMetaFile (NULL, s, NULL, "LEFTY\\0GRAPH\\0\\0"))) {
            Gerr (POS, G_ERRCANNOTCREATEWIDGET);
            return -1;
        }
    } else { /* open the printer device */
        WPU->mode = 2;
        di.cbSize = sizeof (DOCINFO);
        di.lpszDocName = NULL;
        di.lpszOutput = NULL;
        di.lpszDatatype = "LEFTY";
        di.fwType = 0;
        pd.lStructSize = sizeof (pd);
        pd.hwndOwner = NULL;
        pd.hDevMode = NULL;
        pd.hDevNames = NULL;
        pd.hDC = NULL;
        pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
        pd.nFromPage = 0;
        pd.nToPage = 0;
        pd.nMinPage = 0;
        pd.nMaxPage = 0;
        pd.nCopies = 1;
        pd.hInstance = NULL;
        pd.lCustData = NULL;
        pd.lpfnPrintHook = NULL;
        pd.lpfnSetupHook = NULL;
        pd.lpPrintTemplateName = NULL;
        pd.lpSetupTemplateName = NULL;
        pd.hPrintTemplate = NULL;
        pd.hSetupTemplate = NULL;
        if (!PrintDlg (&pd)) {
            Gerr (POS, G_ERRCANNOTCREATEWIDGET);
            return -1;
        }
        if (lflag && pd.hDevMode) {
            dmp = (DEVMODE *) GlobalLock (pd.hDevMode);
            dmp->dmOrientation = DMORIENT_LANDSCAPE;
            GlobalUnlock (pd.hDevMode);
            pd.Flags = PD_RETURNDC;
            if (!PrintDlg (&pd)) {
                Gerr (POS, G_ERRCANNOTCREATEWIDGET);
                return -1;
            }
        }
        GC = pd.hDC;
        dpix = GetDeviceCaps (GC, LOGPIXELSX);
        if (dpix != 300)
            ps.x = ps.x * (double) dpix / 300.0;
        dpiy = GetDeviceCaps (GC, LOGPIXELSY);
        if (dpiy != 300)
            ps.y = ps.y * (double) dpiy / 300.0;
        if (StartDoc (GC, &di) <= 0 || StartPage (GC) <= 0) {
            Gerr (POS, G_ERRCANNOTCREATEWIDGET);
            return -1;
        }
    }
    WPU->wrect.o.x = 0.0, WPU->wrect.o.y = 0.0;
    WPU->wrect.c.x = 1.0, WPU->wrect.c.y = 1.0;
    WPU->vsize.x = ps.x, WPU->vsize.y = ps.y;
    WPU->ncolor = 2;
    pal[0].palVersion = 0x300; /* HA HA HA */
    pal[0].palNumEntries = 2;
    pal[0].palPalEntry[0].peRed = 255;
    pal[0].palPalEntry[0].peGreen = 255;
    pal[0].palPalEntry[0].peBlue = 255;
    pal[0].palPalEntry[0].peFlags = 0;
    pal[0].palPalEntry[1].peRed = 0;
    pal[0].palPalEntry[1].peGreen = 0;
    pal[0].palPalEntry[1].peBlue = 0;
    pal[0].palPalEntry[1].peFlags = 0;
    WPU->cmap = CreatePalette (&pal[0]);
    WPU->colors[0].color = pal[0].palPalEntry[0];
    for (i = 1; i < G_MAXCOLORS; i++)
        WPU->colors[i].color = pal[0].palPalEntry[1];
    SelectPalette (GC, WPU->cmap, FALSE);
    RealizePalette (GC);
    WPU->colors[0].inuse = TRUE;
    WPU->colors[1].inuse = TRUE;
    for (i = 2; i < G_MAXCOLORS; i++)
        WPU->colors[i].inuse = FALSE;
    WPU->gattr.color = 1;
    brush = CreateSolidBrush (PALETTEINDEX (1));
    SelectObject (GC, brush);
    pen = CreatePen (PS_SOLID, 1, PALETTEINDEX (1));
    SelectObject (GC, pen);
    SetTextColor (GC, PALETTEINDEX (1));
    SetBkMode (GC, TRANSPARENT);
    WPU->gattr.width = 0;
    WPU->gattr.mode = G_SRC;
    WPU->gattr.fill = 0;
    WPU->gattr.style = 0;
    WPU->defgattr = WPU->gattr;
    WPU->font = NULL;
    if (Gdepth == 1) {
        for (i = 0; i < 17; i++) {
            if (!(bmap = CreateBitmap (4, 4, 1, 1, &grays[i][0])))
                continue;
            WPU->grays[i] = CreatePatternBrush (bmap);
        }
    }
    for (ai = 0; ai < attrn; ai++) {
        switch (attrp[ai].id) {
        case G_ATTRCOLOR:
            color = attrp[ai].u.c.index;
            if (color < 0 || color > G_MAXCOLORS) {
                Gerr (POS, G_ERRBADCOLORINDEX, color);
                return -1;
            }
            WPU->colors[color].color.peRed = attrp[ai].u.c.r;
            WPU->colors[color].color.peGreen = attrp[ai].u.c.g;
            WPU->colors[color].color.peBlue = attrp[ai].u.c.b;
            WPU->colors[color].color.peFlags = 0;
            if (color >= WPU->ncolor)
                ResizePalette (WPU->cmap, color + 1), WPU->ncolor = color + 1;
            SetPaletteEntries (
                WPU->cmap, (int) color, 1, &WPU->colors[color].color
            );
            RealizePalette (GC);
            WPU->colors[color].inuse = TRUE;
            if (color == WPU->gattr.color)
                WPU->gattr.color = -1;
            break;
        case G_ATTRVIEWPORT:
            if (attrp[ai].u.s.x == 0)
                attrp[ai].u.s.x = 1;
            if (attrp[ai].u.s.y == 0)
                attrp[ai].u.s.y = 1;
            WPU->vsize.x = attrp[ai].u.s.x + 0.5;
            WPU->vsize.y = attrp[ai].u.s.y + 0.5;
            SetWindowPos (
                widget->w, (HWND) NULL, 0, 0, WPU->vsize.x,
                WPU->vsize.y, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE
            );
            break;
        case G_ATTRWINDOW:
            if (attrp[ai].u.r.o.x == attrp[ai].u.r.c.x)
                attrp[ai].u.r.c.x = attrp[ai].u.r.o.x + 1;
            if (attrp[ai].u.r.o.y == attrp[ai].u.r.c.y)
                attrp[ai].u.r.c.y = attrp[ai].u.r.o.y + 1;
            WPU->wrect = attrp[ai].u.r;
            break;
        }
    }
    return 0;
}
Esempio n. 4
0
static int wGLCreateContext(Ihandle* ih, IGlControlData* gldata)
{
  Ihandle* ih_shared;
  HGLRC shared_context = NULL;
  int number;
  int isIndex = 0;
  int pixelFormat;
  PIXELFORMATDESCRIPTOR test_pfd;
  PIXELFORMATDESCRIPTOR pfd = { 
    sizeof(PIXELFORMATDESCRIPTOR),  /*  size of this pfd   */
      1,                     /* version number             */
      PFD_DRAW_TO_WINDOW |   /* support window             */
      PFD_SUPPORT_OPENGL,    /* support OpenGL             */
      PFD_TYPE_RGBA,         /* RGBA type                  */
      24,                    /* 24-bit color depth         */
      0, 0, 0, 0, 0, 0,      /* color bits ignored         */
      0,                     /* no alpha buffer            */
      0,                     /* shift bit ignored          */
      0,                     /* no accumulation buffer     */
      0, 0, 0, 0,            /* accum bits ignored         */
      16,                    /* 32-bit z-buffer             */
      0,                     /* no stencil buffer          */
      0,                     /* no auxiliary buffer        */
      PFD_MAIN_PLANE,        /* main layer                 */
      0,                     /* reserved                   */
      0, 0, 0                /* layer masks ignored        */
  };

  /* the IupCanvas is already mapped, just initialize the OpenGL context */

  /* double or single buffer */
  if (iupStrEqualNoCase(iupAttribGetStr(ih,"BUFFER"), "DOUBLE"))
    pfd.dwFlags |= PFD_DOUBLEBUFFER;

  /* stereo */
  if (iupAttribGetBoolean(ih,"STEREO"))
    pfd.dwFlags |= PFD_STEREO;

  /* rgba or index */ 
  if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX"))
  {
    isIndex = 1;
    pfd.iPixelType = PFD_TYPE_COLORINDEX;
    pfd.cColorBits = 8;  /* assume 8 bits when indexed */
    number = iupAttribGetInt(ih,"BUFFER_SIZE");
    if (number > 0) pfd.cColorBits = (BYTE)number;
  }

  /* red, green, blue bits */
  number = iupAttribGetInt(ih,"RED_SIZE");
  if (number > 0) pfd.cRedBits = (BYTE)number;
  pfd.cRedShift = 0;

  number = iupAttribGetInt(ih,"GREEN_SIZE");
  if (number > 0) pfd.cGreenBits = (BYTE)number;
  pfd.cGreenShift = pfd.cRedBits;

  number = iupAttribGetInt(ih,"BLUE_SIZE");
  if (number > 0) pfd.cBlueBits = (BYTE)number;
  pfd.cBlueShift = pfd.cRedBits + pfd.cGreenBits;

  number = iupAttribGetInt(ih,"ALPHA_SIZE");
  if (number > 0) pfd.cAlphaBits = (BYTE)number;
  pfd.cAlphaShift = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits;

  /* depth and stencil size */
  number = iupAttribGetInt(ih,"DEPTH_SIZE");
  if (number > 0) pfd.cDepthBits = (BYTE)number;

  /* stencil */
  number = iupAttribGetInt(ih,"STENCIL_SIZE");
  if (number > 0) pfd.cStencilBits = (BYTE)number;

  /* red, green, blue accumulation bits */
  number = iupAttribGetInt(ih,"ACCUM_RED_SIZE");
  if (number > 0) pfd.cAccumRedBits = (BYTE)number;

  number = iupAttribGetInt(ih,"ACCUM_GREEN_SIZE");
  if (number > 0) pfd.cAccumGreenBits = (BYTE)number;

  number = iupAttribGetInt(ih,"ACCUM_BLUE_SIZE");
  if (number > 0) pfd.cAccumBlueBits = (BYTE)number;

  number = iupAttribGetInt(ih,"ACCUM_ALPHA_SIZE");
  if (number > 0) pfd.cAccumAlphaBits = (BYTE)number;

  pfd.cAccumBits = pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits;

  /* get a device context */
  {
    LONG style = GetClassLong(gldata->window, GCL_STYLE);
    gldata->is_owned_dc = (int) ((style & CS_OWNDC) || (style & CS_CLASSDC));
  }

  gldata->device = GetDC(gldata->window);
  iupAttribSetStr(ih, "VISUAL", (char*)gldata->device);

  /* choose pixel format */
  pixelFormat = ChoosePixelFormat(gldata->device, &pfd);
  if (pixelFormat == 0)
  {
    iupAttribSetStr(ih, "ERROR", "No appropriate pixel format.");
    iupAttribStoreStr(ih, "LASTERROR", IupGetGlobal("LASTERROR"));
    return IUP_NOERROR;
  } 
  SetPixelFormat(gldata->device,pixelFormat,&pfd);

  ih_shared = IupGetAttributeHandle(ih, "SHAREDCONTEXT");
  if (ih_shared && IupClassMatch(ih_shared, "glcanvas"))  /* must be an IupGLCanvas */
  {
    IGlControlData* shared_gldata = (IGlControlData*)iupAttribGet(ih_shared, "_IUP_GLCONTROLDATA");
    shared_context = shared_gldata->context;
  }

  /* create rendering context */
  if (iupAttribGetBoolean(ih, "ARBCONTEXT"))
  {
    wglCreateContextAttribsARB_PROC CreateContextAttribsARB;
    HGLRC tempContext = wglCreateContext(gldata->device);
    HGLRC oldContext = wglGetCurrentContext();
    HDC oldDC = wglGetCurrentDC();
    wglMakeCurrent(gldata->device, tempContext);   /* wglGetProcAddress only works with an active context */

    CreateContextAttribsARB = (wglCreateContextAttribsARB_PROC)wglGetProcAddress("wglCreateContextAttribsARB");
    if (CreateContextAttribsARB)
    {
      int attribs[9], a = 0;
      char* value;

      value = iupAttribGetStr(ih, "CONTEXTVERSION");
      if (value)
      {
        int major, minor;
        if (iupStrToIntInt(value, &major, &minor, '.') == 2)
        {
          attribs[a++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
          attribs[a++] = major;
          attribs[a++] = WGL_CONTEXT_MINOR_VERSION_ARB;
          attribs[a++] = minor;
        }
      }

      value = iupAttribGetStr(ih, "CONTEXTFLAGS");
      if (value)
      {
        int flags = 0;
        if (iupStrEqualNoCase(value, "DEBUG"))
          flags = WGL_CONTEXT_DEBUG_BIT_ARB;
        else if (iupStrEqualNoCase(value, "FORWARDCOMPATIBLE"))
          flags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
        else if (iupStrEqualNoCase(value, "DEBUGFORWARDCOMPATIBLE"))
          flags = WGL_CONTEXT_DEBUG_BIT_ARB|WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
        if (flags)
        {
          attribs[a++] = WGL_CONTEXT_FLAGS_ARB;
          attribs[a++] = flags;
        }
      }

      value = iupAttribGetStr(ih, "CONTEXTPROFILE");
      if (value)
      {
        int profile = 0;
        if (iupStrEqualNoCase(value, "CORE"))
          profile = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
        else if (iupStrEqualNoCase(value, "COMPATIBILITY"))
          profile = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
        else if (iupStrEqualNoCase(value, "CORECOMPATIBILITY"))
          profile = WGL_CONTEXT_CORE_PROFILE_BIT_ARB|WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
        if (profile)
        {
          attribs[a++] = WGL_CONTEXT_PROFILE_MASK_ARB;
          attribs[a++] = profile;
        }
      }

      attribs[a] = 0; /* terminator */

      gldata->context = CreateContextAttribsARB(gldata->device, shared_context, attribs);
      if (!gldata->context)
      {
        DWORD error = GetLastError();
        if (error == ERROR_INVALID_VERSION_ARB)
          iupAttribStoreStr(ih, "LASTERROR", "Invalid ARB Version");
        else if (error == ERROR_INVALID_PROFILE_ARB)
          iupAttribStoreStr(ih, "LASTERROR", "Invalid ARGB Profile");
        else
          iupAttribStoreStr(ih, "LASTERROR", IupGetGlobal("LASTERROR"));

        iupAttribSetStr(ih, "ERROR", "Could not create a rendering context.");

        wglMakeCurrent(oldDC, oldContext);
        wglDeleteContext(tempContext);

        return IUP_NOERROR;
      }
    }

    wglMakeCurrent(oldDC, oldContext);
    wglDeleteContext(tempContext);

    if (!CreateContextAttribsARB)
    {
      gldata->context = wglCreateContext(gldata->device);
      iupAttribSetStr(ih, "ARBCONTEXT", "NO");
    }
  }
  else
    gldata->context = wglCreateContext(gldata->device);

  if (!gldata->context)
  {
    iupAttribSetStr(ih, "ERROR", "Could not create a rendering context.");
    iupAttribStoreStr(ih, "LASTERROR", IupGetGlobal("LASTERROR"));
    return IUP_NOERROR;
  }

  iupAttribSetStr(ih, "CONTEXT", (char*)gldata->context);

  if (shared_context)
    wglShareLists(shared_context, gldata->context);

  DescribePixelFormat(gldata->device, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &test_pfd);
  if ((pfd.dwFlags & PFD_STEREO) && !(test_pfd.dwFlags & PFD_STEREO))
  {
    iupAttribSetStr(ih, "ERROR", "Stereo not available.");
    return IUP_NOERROR;
  }

  /* create colormap for index mode */
  if (isIndex)
  {
    if (!gldata->palette)
    {
      LOGPALETTE lp = {0x300,1,{255,255,255,PC_NOCOLLAPSE}};  /* set first color as white */
      gldata->palette = CreatePalette(&lp);
      ResizePalette(gldata->palette,1<<pfd.cColorBits);
      iupAttribSetStr(ih, "COLORMAP", (char*)gldata->palette);
    }

    SelectPalette(gldata->device,gldata->palette,FALSE);
    RealizePalette(gldata->device);
  }

  iupAttribSetStr(ih, "ERROR", NULL);
  return IUP_NOERROR;
}