| /* |
| Simple DirectMedia Layer |
| Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> |
| |
| This software is provided 'as-is', without any express or implied |
| warranty. In no event will the authors be held liable for any damages |
| arising from the use of this software. |
| |
| Permission is granted to anyone to use this software for any purpose, |
| including commercial applications, and to alter it and redistribute it |
| freely, subject to the following restrictions: |
| |
| 1. The origin of this software must not be misrepresented; you must not |
| claim that you wrote the original software. If you use this software |
| in a product, an acknowledgment in the product documentation would be |
| appreciated but is not required. |
| 2. Altered source versions must be plainly marked as such, and must not be |
| misrepresented as being the original software. |
| 3. This notice may not be removed or altered from any source distribution. |
| */ |
| #include "../../SDL_internal.h" |
| |
| #if SDL_VIDEO_DRIVER_OS2 |
| |
| #include "SDL_video.h" |
| #include "SDL_mouse.h" |
| #include "../SDL_pixels_c.h" |
| #include "../SDL_shape_internals.h" |
| #include "../../events/SDL_events_c.h" |
| #include "SDL_os2video.h" |
| #include "SDL_syswm.h" |
| #include "SDL_os2util.h" |
| #define _MEERROR_H_ |
| #include <mmioos2.h> |
| #include <fourcc.h> |
| |
| #define WIN_CLIENT_CLASS "SDL2" |
| #define OS2DRIVER_NAME_DIVE "DIVE" |
| #define OS2DRIVER_NAME_VMAN "VMAN" |
| |
| |
| static const SDL_Scancode aSDLScancode[] = |
| { |
| /* 0 1 2 3 4 5 6 7 */ |
| /* 8 9 A B C D E F */ |
| SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */ |
| SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0, SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, /* 0 */ |
| |
| SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, /* 1 */ |
| SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, /* 1 */ |
| |
| SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, /* 2 */ |
| SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, /* 2 */ |
| |
| SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, /*55*/SDL_SCANCODE_KP_MULTIPLY, /* 3 */ |
| SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, /* 3 */ |
| |
| SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_KP_7, /* 4 */ |
| /*72*/SDL_SCANCODE_KP_8, /*73*/SDL_SCANCODE_KP_9, SDL_SCANCODE_KP_MINUS,/*75*/SDL_SCANCODE_KP_4, /*76*/SDL_SCANCODE_KP_5, /*77*/SDL_SCANCODE_KP_6, /*78*/SDL_SCANCODE_KP_PLUS, /*79*/SDL_SCANCODE_KP_1, /* 4 */ |
| |
| /*80*/SDL_SCANCODE_KP_2, /*81*/SDL_SCANCODE_KP_3, SDL_SCANCODE_KP_0, /*83*/SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_NONUSBACKSLASH,SDL_SCANCODE_F11, /* 5 */ |
| /*88*/SDL_SCANCODE_F12, /*89*/SDL_SCANCODE_PAUSE, /*90*/SDL_SCANCODE_KP_ENTER,/*91*/SDL_SCANCODE_RCTRL, /*92*/SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_APPLICATION, SDL_SCANCODE_RALT, /*95*/SDL_SCANCODE_UNKNOWN, /* 5 */ |
| |
| /*96*/SDL_SCANCODE_HOME, /*97*/SDL_SCANCODE_UP, /*98*/SDL_SCANCODE_PAGEUP, SDL_SCANCODE_LEFT, /*100*/SDL_SCANCODE_RIGHT, SDL_SCANCODE_END, /*102*/SDL_SCANCODE_DOWN, /*103*/SDL_SCANCODE_PAGEDOWN, /* 6 */ |
| /*104*/SDL_SCANCODE_F17, /*105*/SDL_SCANCODE_DELETE, SDL_SCANCODE_F19, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,/*110*/SDL_SCANCODE_UNKNOWN,/*111*/SDL_SCANCODE_UNKNOWN, /* 6 */ |
| |
| /*112*/SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1,SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */ |
| /*120*/SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4,SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5,SDL_SCANCODE_APPLICATION,SDL_SCANCODE_INTERNATIONAL3,SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI /* 7 */ |
| }; |
| |
| // Utilites. |
| // --------- |
| |
| static BOOL _getSDLPixelFormatData(SDL_PixelFormat *pSDLPixelFormat, |
| ULONG ulBPP, ULONG fccColorEncoding) |
| { |
| ULONG ulRshift, ulGshift, ulBshift; |
| ULONG ulRmask, ulGmask, ulBmask; |
| ULONG ulRloss, ulGloss, ulBloss; |
| |
| pSDLPixelFormat->BitsPerPixel = ulBPP; |
| pSDLPixelFormat->BytesPerPixel = ( pSDLPixelFormat->BitsPerPixel + 7 ) / 8; |
| |
| switch( fccColorEncoding ) |
| { |
| case FOURCC_LUT8: |
| ulRshift = 0; ulGshift = 0; ulBshift = 0; |
| ulRmask = 0; ulGmask = 0; ulBmask = 0; |
| ulRloss = 8; ulGloss = 8; ulBloss = 8; |
| break; |
| |
| case FOURCC_R555: |
| ulRshift = 10; ulGshift = 5; ulBshift = 0; |
| ulRmask = 0x7C00; ulGmask = 0x03E0; ulBmask = 0x001F; |
| ulRloss = 3; ulGloss = 3; ulBloss = 3; |
| break; |
| |
| case FOURCC_R565: |
| ulRshift = 11; ulGshift = 5; ulBshift = 0; |
| ulRmask = 0xF800; ulGmask = 0x07E0; ulBmask = 0x001F; |
| ulRloss = 3; ulGloss = 2; ulBloss = 3; |
| break; |
| |
| case FOURCC_R664: |
| ulRshift = 10; ulGshift = 4; ulBshift = 0; |
| ulRmask = 0xFC00; ulGmask = 0x03F0; ulBmask = 0x000F; |
| ulRloss = 2; ulGloss = 4; ulBloss = 3; |
| break; |
| |
| /* case FOURCC_R666: |
| ulRshift = 12; ulGshift = 6; ulBshift = 0; |
| ulRmask = 0x03F000; ulGmask = 0x000FC0; ulBmask = 0x00003F; |
| ulRloss = 2; ulGloss = 2; ulBloss = 2; |
| break;*/ |
| |
| case FOURCC_RGB3: |
| case FOURCC_RGB4: |
| ulRshift = 0; ulGshift = 8; ulBshift = 16; |
| ulRmask = 0x0000FF; ulGmask = 0x00FF00; ulBmask = 0xFF0000; |
| ulRloss = 0x00; ulGloss = 0x00; ulBloss = 0x00; |
| break; |
| |
| case FOURCC_BGR3: |
| case FOURCC_BGR4: |
| ulRshift = 16; ulGshift = 8; ulBshift = 0; |
| ulRmask = 0xFF0000; ulGmask = 0x00FF00; ulBmask = 0x0000FF; |
| ulRloss = 0; ulGloss = 0; ulBloss = 0; |
| break; |
| |
| default: |
| // printf( "Unknown color encoding: %.4s\n", fccColorEncoding ); |
| memset( pSDLPixelFormat, 0, sizeof(SDL_PixelFormat) ); |
| return FALSE; |
| } |
| |
| pSDLPixelFormat->Rshift = ulRshift; |
| pSDLPixelFormat->Gshift = ulGshift; |
| pSDLPixelFormat->Bshift = ulBshift; |
| pSDLPixelFormat->Rmask = ulRmask; |
| pSDLPixelFormat->Gmask = ulGmask; |
| pSDLPixelFormat->Bmask = ulBmask; |
| pSDLPixelFormat->Rloss = ulRloss; |
| pSDLPixelFormat->Gloss = ulGloss; |
| pSDLPixelFormat->Bloss = ulBloss; |
| |
| pSDLPixelFormat->Ashift = 0x00; |
| pSDLPixelFormat->Amask = 0x00; |
| pSDLPixelFormat->Aloss = 0x00; |
| return TRUE; |
| } |
| |
| static Uint32 _getSDLPixelFormat(ULONG ulBPP, FOURCC fccColorEncoding) |
| { |
| SDL_PixelFormat stSDLPixelFormat; |
| Uint32 uiResult = SDL_PIXELFORMAT_UNKNOWN; |
| |
| if ( _getSDLPixelFormatData( &stSDLPixelFormat, ulBPP, fccColorEncoding ) ) |
| uiResult = SDL_MasksToPixelFormatEnum( ulBPP, stSDLPixelFormat.Rmask, |
| stSDLPixelFormat.Gmask, |
| stSDLPixelFormat.Bmask, 0 ); |
| |
| return uiResult; |
| } |
| |
| static SDL_DisplayMode *_getDisplayModeForSDLWindow(SDL_Window *window) |
| { |
| SDL_VideoDisplay *pSDLDisplay = SDL_GetDisplayForWindow( window ); |
| |
| if ( pSDLDisplay == NULL ) |
| { |
| debug( "No display for the window" ); |
| return FALSE; |
| } |
| |
| return &pSDLDisplay->current_mode; |
| } |
| |
| |
| static VOID _mouseCheck(PWINDATA pWinData) |
| { |
| SDL_Mouse *pSDLMouse = SDL_GetMouse(); |
| |
| if ( ( pSDLMouse->relative_mode || |
| (pWinData->window->flags & SDL_WINDOW_INPUT_GRABBED) != 0 ) |
| && ( (pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0 ) ) |
| { |
| // We will make a real capture in _wmMouseButton(). |
| } |
| else |
| WinSetCapture( HWND_DESKTOP, NULLHANDLE ); |
| } |
| |
| |
| // PM window procedure. |
| // -------------------- |
| |
| static int OS2_ResizeWindowShape(SDL_Window *window); |
| |
| static VOID _setVisibleRegion(PWINDATA pWinData, BOOL fVisible) |
| { |
| SDL_VideoDisplay *pSDLDisplay; |
| |
| if ( pWinData->pVOData == NULL ) |
| return; |
| |
| pSDLDisplay = fVisible ? SDL_GetDisplayForWindow( pWinData->window ) : NULL; |
| pWinData->pOutput->SetVisibleRegion( pWinData->pVOData, pWinData->hwnd, |
| pSDLDisplay == NULL ? |
| NULL : &pSDLDisplay->current_mode, |
| pWinData->hrgnShape, fVisible ); |
| } |
| |
| static VOID _wmPaint(PWINDATA pWinData, HWND hwnd) |
| { |
| if ( ( pWinData->pVOData == NULL ) || |
| !pWinData->pOutput->Update( pWinData->pVOData, hwnd, NULL, 0 ) ) |
| { |
| RECTL rectl; |
| HPS hps; |
| |
| hps = WinBeginPaint( hwnd, 0, &rectl ); |
| WinFillRect( hps, &rectl, CLR_BLACK ); |
| WinEndPaint( hps ); |
| } |
| } |
| |
| static VOID _wmMouseMove(PWINDATA pWinData, SHORT lX, SHORT lY) |
| { |
| SDL_Mouse *pSDLMouse = SDL_GetMouse(); |
| POINTL pointl; |
| BOOL fWinActive = (pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) |
| != 0; |
| if ( !pSDLMouse->relative_mode || pSDLMouse->relative_mode_warp ) |
| { |
| if ( !pSDLMouse->relative_mode && fWinActive && |
| ( (pWinData->window->flags & SDL_WINDOW_INPUT_GRABBED) != 0 ) && |
| ( WinQueryCapture( HWND_DESKTOP ) == pWinData->hwnd ) ) |
| { |
| pointl.x = lX; |
| pointl.y = lY; |
| |
| if ( lX < 0 ) |
| lX = 0; |
| else if ( lX >= pWinData->window->w ) |
| lX = pWinData->window->w - 1; |
| |
| if ( lY < 0 ) |
| lY = 0; |
| else if ( lY >= pWinData->window->h ) |
| lY = pWinData->window->h - 1; |
| |
| if ( ( lX != pointl.x ) || ( lY != pointl.x ) ) |
| { |
| pointl.x = lX; |
| pointl.y = lY; |
| WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, &pointl, 1 ); |
| pWinData->lSkipWMMouseMove++; |
| WinSetPointerPos( HWND_DESKTOP, pointl.x, pointl.y ); |
| } |
| } |
| |
| SDL_SendMouseMotion( pWinData->window, 0, 0, lX, |
| pWinData->window->h - lY - 1 ); |
| return; |
| } |
| |
| if ( fWinActive ) |
| { |
| pointl.x = pWinData->window->w / 2; |
| pointl.y = pWinData->window->h / 2; |
| WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, &pointl, 1 ); |
| |
| SDL_SendMouseMotion( pWinData->window, 0, 1, |
| lX - pointl.x, pointl.y - lY ); |
| |
| pWinData->lSkipWMMouseMove++; |
| WinSetPointerPos( HWND_DESKTOP, pointl.x, pointl.y ); |
| } |
| } |
| |
| static VOID _wmMouseButton(PWINDATA pWinData, ULONG ulButton, BOOL fDown) |
| { |
| static ULONG aBtnGROP2SDL[3] = { SDL_BUTTON_LEFT, SDL_BUTTON_RIGHT, |
| SDL_BUTTON_MIDDLE }; |
| SDL_Mouse *pSDLMouse = SDL_GetMouse(); |
| |
| if ( ( pSDLMouse->relative_mode || |
| ( (pWinData->window->flags & SDL_WINDOW_INPUT_GRABBED) != 0 ) ) |
| && ( (pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0 ) |
| && ( WinQueryCapture( HWND_DESKTOP ) != pWinData->hwnd ) ) |
| { |
| // Mouse should be captured. |
| |
| if ( pSDLMouse->relative_mode && !pSDLMouse->relative_mode_warp ) |
| { |
| POINTL pointl; |
| |
| pointl.x = pWinData->window->w / 2; |
| pointl.y = pWinData->window->h / 2; |
| WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, &pointl, 1 ); |
| pWinData->lSkipWMMouseMove++; |
| WinSetPointerPos( HWND_DESKTOP, pointl.x, pointl.y ); |
| } |
| |
| WinSetCapture( HWND_DESKTOP, pWinData->hwnd ); |
| } |
| |
| SDL_SendMouseButton( pWinData->window, 0, |
| fDown ? SDL_PRESSED : SDL_RELEASED, |
| aBtnGROP2SDL[ulButton] ); |
| } |
| |
| static VOID _wmChar(PWINDATA pWinData, MPARAM mp1, MPARAM mp2) |
| { |
| ULONG ulFlags = SHORT1FROMMP(mp1); // WM_CHAR flags |
| ULONG ulVirtualKey = SHORT2FROMMP(mp2); // Virtual key code VK_* |
| ULONG ulCharCode = SHORT1FROMMP(mp2); // Character code |
| ULONG ulScanCode = CHAR4FROMMP(mp1); // Scan code |
| |
| if ( ( (ulFlags & (KC_VIRTUALKEY | KC_KEYUP | KC_ALT)) == |
| (KC_VIRTUALKEY | KC_ALT) ) && |
| ( ulVirtualKey == VK_F4 ) ) |
| SDL_SendWindowEvent( pWinData->window, SDL_WINDOWEVENT_CLOSE, 0, 0 ); |
| |
| if ( (ulFlags & KC_SCANCODE) != 0 ) |
| SDL_SendKeyboardKey( |
| (ulFlags & KC_KEYUP) == 0 ? SDL_PRESSED : SDL_RELEASED, |
| aSDLScancode[ulScanCode] ); |
| |
| if ( (ulFlags & KC_CHAR) != 0 ) |
| { |
| CHAR acUTF8[4]; |
| LONG lRC = StrUTF8( 1, &acUTF8, sizeof(acUTF8), (PSZ)&ulCharCode, 1 ); |
| |
| SDL_SendKeyboardText( lRC > 0 ? &acUTF8 : (PSZ)&ulCharCode ); |
| } |
| } |
| |
| static VOID _wmMove(PWINDATA pWinData) |
| { |
| SDL_DisplayMode *pSDLDisplayMode = |
| _getDisplayModeForSDLWindow( pWinData->window ); |
| POINTL pointl = { 0 }; |
| RECTL rectl; |
| |
| WinQueryWindowRect( pWinData->hwnd, &rectl ); |
| WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 2 ); |
| |
| WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, &pointl, 1 ); |
| SDL_SendWindowEvent( pWinData->window, SDL_WINDOWEVENT_MOVED, rectl.xLeft, |
| pSDLDisplayMode->h - rectl.yTop ); |
| } |
| |
| static MRESULT _wmDragOver(PWINDATA pWinData, PDRAGINFO pDragInfo) |
| { |
| ULONG ulIdx; |
| PDRAGITEM pDragItem; |
| USHORT usDrag = DOR_NEVERDROP; |
| USHORT usDragOp = DO_UNKNOWN; |
| |
| if ( !DrgAccessDraginfo( pDragInfo ) ) |
| return MRFROM2SHORT( DOR_NEVERDROP, DO_UNKNOWN ); |
| |
| for( ulIdx = 0; ulIdx < pDragInfo->cditem; ulIdx++ ) |
| { |
| pDragItem = DrgQueryDragitemPtr( pDragInfo, ulIdx ); |
| |
| // We accept WPS files only. |
| if ( !DrgVerifyRMF( pDragItem, "DRM_OS2FILE", NULL ) ) |
| { |
| usDrag = DOR_NEVERDROP; |
| usDragOp = DO_UNKNOWN; |
| break; |
| } |
| |
| if ( ( pDragInfo->usOperation == DO_DEFAULT ) && |
| ( (pDragItem->fsSupportedOps & DO_COPYABLE) != 0 ) ) |
| { |
| usDrag = DOR_DROP; |
| usDragOp = DO_COPY; |
| } |
| else if ( ( pDragInfo->usOperation == DO_LINK ) && |
| ( (pDragItem->fsSupportedOps & DO_LINKABLE) != 0 ) ) |
| { |
| usDrag = DOR_DROP; |
| usDragOp = DO_LINK; |
| } |
| else |
| { |
| usDrag = DOR_NODROPOP; |
| usDragOp = DO_UNKNOWN; |
| break; |
| } |
| } |
| |
| // Update window (The DIVE surface spoiled while dragging). |
| WinInvalidateRect( pWinData->hwnd, NULL, FALSE ); |
| WinUpdateWindow( pWinData->hwnd ); |
| |
| DrgFreeDraginfo( pDragInfo ); |
| return MPFROM2SHORT( usDrag, usDragOp ); |
| } |
| |
| static MRESULT _wmDrop(PWINDATA pWinData, PDRAGINFO pDragInfo) |
| { |
| ULONG ulIdx; |
| PDRAGITEM pDragItem; |
| CHAR acFName[_MAX_PATH]; |
| PCHAR pcFName; |
| |
| if ( !DrgAccessDraginfo( pDragInfo ) ) |
| return MRFROM2SHORT( DOR_NEVERDROP, 0 ); |
| |
| for( ulIdx = 0; ulIdx < pDragInfo->cditem; ulIdx++ ) |
| { |
| pDragItem = DrgQueryDragitemPtr( pDragInfo, ulIdx ); |
| |
| if ( DrgVerifyRMF( pDragItem, "DRM_OS2FILE", NULL ) && |
| ( pDragItem->hstrContainerName != NULLHANDLE ) && |
| ( pDragItem->hstrSourceName != NULLHANDLE ) ) |
| { |
| // Get file name from the item. |
| DrgQueryStrName( pDragItem->hstrContainerName, |
| sizeof(acFName), &acFName ); |
| pcFName = strchr( &acFName, '\0' ); |
| DrgQueryStrName( pDragItem->hstrSourceName, |
| sizeof(acFName) - (pcFName - &acFName), pcFName ); |
| |
| // Send to SDL full file name converted to UTF-8. |
| pcFName = OS2_SysToUTF8( &acFName ); |
| SDL_SendDropFile( pcFName ); |
| SDL_free( pcFName ); |
| |
| // Notify a source that a drag operation is complete. |
| if ( pDragItem->hwndItem ) |
| DrgSendTransferMsg( pDragItem->hwndItem, DM_ENDCONVERSATION, |
| (MPARAM)pDragItem->ulItemID, |
| (MPARAM)DMFL_TARGETSUCCESSFUL ); |
| } |
| } |
| |
| DrgDeleteDraginfoStrHandles( pDragInfo ); |
| DrgFreeDraginfo( pDragInfo ); |
| |
| return (MRESULT)FALSE; |
| } |
| |
| MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
| { |
| HWND hwndClient = WinQueryWindow( hwnd, QW_BOTTOM ); |
| PWINDATA pWinData = (PWINDATA)WinQueryWindowULong( hwndClient, 0 ); |
| |
| if ( pWinData == NULL ) |
| return WinDefWindowProc( hwnd, msg, mp1, mp2 ); |
| |
| /* Send a SDL_SYSWMEVENT if the application wants them */ |
| if ( SDL_GetEventState( SDL_SYSWMEVENT ) == SDL_ENABLE ) |
| { |
| SDL_SysWMmsg wmmsg; |
| |
| SDL_VERSION( &wmmsg.version ); |
| wmmsg.subsystem = SDL_SYSWM_OS2; |
| wmmsg.msg.os2.fFrame = TRUE; |
| wmmsg.msg.os2.hwnd = hwnd; |
| wmmsg.msg.os2.msg = msg; |
| wmmsg.msg.os2.mp1 = mp1; |
| wmmsg.msg.os2.mp2 = mp2; |
| SDL_SendSysWMEvent( &wmmsg ); |
| } |
| |
| switch( msg ) |
| { |
| case WM_MINMAXFRAME: |
| if ( (((PSWP)mp1)->fl & SWP_RESTORE) != 0 ) |
| { |
| pWinData->lSkipWMMove += 2; |
| SDL_SendWindowEvent( pWinData->window, |
| SDL_WINDOWEVENT_RESTORED, 0, 0 ); |
| } |
| |
| if ( (((PSWP)mp1)->fl & SWP_MINIMIZE) != 0 ) |
| { |
| pWinData->lSkipWMSize++; |
| pWinData->lSkipWMMove += 2; |
| SDL_SendWindowEvent( pWinData->window, |
| SDL_WINDOWEVENT_MINIMIZED, 0, 0 ); |
| } |
| |
| if ( (((PSWP)mp1)->fl & SWP_MAXIMIZE) != 0 ) |
| SDL_SendWindowEvent( pWinData->window, |
| SDL_WINDOWEVENT_MAXIMIZED, 0, 0 ); |
| break; |
| |
| case WM_ADJUSTFRAMEPOS: |
| if ( pWinData->lSkipWMAdjustFramePos > 0 ) |
| { |
| pWinData->lSkipWMAdjustFramePos++; |
| break; |
| } |
| |
| if ( (pWinData->window->flags & SDL_WINDOW_FULLSCREEN) != 0 |
| && (((PSWP)mp1)->fl & SWP_RESTORE) != 0 ) |
| { |
| // Keep fullscreen window size on restore. |
| RECTL rectl; |
| |
| rectl.xLeft = 0; |
| rectl.yBottom = 0; |
| rectl.xRight = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); |
| rectl.yTop = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); |
| WinCalcFrameRect( hwnd, &rectl, FALSE ); |
| ((PSWP)mp1)->x = rectl.xLeft; |
| ((PSWP)mp1)->y = rectl.yBottom; |
| ((PSWP)mp1)->cx = rectl.xRight - rectl.xLeft; |
| ((PSWP)mp1)->cy = rectl.yTop - rectl.yBottom; |
| } |
| |
| if ( (((PSWP)mp1)->fl & (SWP_SIZE | SWP_MINIMIZE)) == SWP_SIZE ) |
| { |
| if ( (pWinData->window->flags & SDL_WINDOW_FULLSCREEN) != 0 ) |
| { // SDL_WINDOW_FULLSCREEN_DESKTOP have flag SDL_WINDOW_FULLSCREEN... |
| if ( SDL_IsShapedWindow( pWinData->window ) ) |
| OS2_ResizeWindowShape( pWinData->window ); |
| break; |
| } |
| |
| if ( (SDL_GetWindowFlags( pWinData->window ) & SDL_WINDOW_RESIZABLE) != |
| 0 ) |
| { |
| RECTL rectl; |
| int iMinW, iMinH, iMaxW, iMaxH; |
| int iWinW; |
| int iWinH; |
| |
| rectl.xLeft = 0; |
| rectl.yBottom = 0; |
| SDL_GetWindowSize( pWinData->window, |
| (int *)&rectl.xRight, (int *)&rectl.yTop ); |
| iWinW = rectl.xRight; |
| iWinH = rectl.yTop; |
| |
| SDL_GetWindowMinimumSize( pWinData->window, &iMinW, &iMinH ); |
| SDL_GetWindowMaximumSize( pWinData->window, &iMaxW, &iMaxH ); |
| |
| if ( iWinW < iMinW ) |
| rectl.xRight = iMinW; |
| else if ( ( iMaxW != 0 ) && ( iWinW > iMaxW ) ) |
| rectl.xRight = iMaxW; |
| |
| if ( iWinH < iMinH ) |
| rectl.yTop = iMinW; |
| else if ( ( iMaxH != 0 ) && ( iWinH > iMaxH ) ) |
| rectl.yTop = iMaxH; |
| |
| if ( ( rectl.xRight == iWinW ) && ( rectl.yTop == iWinH ) ) |
| { |
| if ( SDL_IsShapedWindow( pWinData->window ) ) |
| OS2_ResizeWindowShape( pWinData->window ); |
| break; |
| } |
| |
| WinCalcFrameRect( hwnd, &rectl, FALSE ); |
| ((PSWP)mp1)->cx = rectl.xRight - rectl.xLeft; |
| ((PSWP)mp1)->cy = rectl.yTop - rectl.yBottom; |
| } |
| } |
| break; |
| } |
| |
| return pWinData->fnWndFrameProc( hwnd, msg, mp1, mp2 ); |
| } |
| |
| MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
| { |
| PWINDATA pWinData = (PWINDATA)WinQueryWindowULong( hwnd, 0 ); |
| |
| if ( pWinData == NULL ) |
| return WinDefWindowProc( hwnd, msg, mp1, mp2 ); |
| |
| /* Send a SDL_SYSWMEVENT if the application wants them */ |
| if ( SDL_GetEventState( SDL_SYSWMEVENT ) == SDL_ENABLE ) |
| { |
| SDL_SysWMmsg wmmsg; |
| |
| SDL_VERSION( &wmmsg.version ); |
| wmmsg.subsystem = SDL_SYSWM_OS2; |
| wmmsg.msg.os2.fFrame = FALSE; |
| wmmsg.msg.os2.hwnd = hwnd; |
| wmmsg.msg.os2.msg = msg; |
| wmmsg.msg.os2.mp1 = mp1; |
| wmmsg.msg.os2.mp2 = mp2; |
| SDL_SendSysWMEvent( &wmmsg ); |
| } |
| |
| switch( msg ) |
| { |
| case WM_CLOSE: |
| case WM_QUIT: |
| SDL_SendWindowEvent( pWinData->window, SDL_WINDOWEVENT_CLOSE, 0, 0 ); |
| if ( pWinData->fnUserWndProc == NULL ) |
| return (MRESULT)FALSE; |
| break; |
| |
| case WM_PAINT: |
| _wmPaint( pWinData, hwnd ); |
| break; |
| |
| case WM_SHOW: |
| SDL_SendWindowEvent( pWinData->window, |
| SHORT1FROMMP(mp1) == 0 |
| ? SDL_WINDOWEVENT_HIDDEN |
| : SDL_WINDOWEVENT_SHOWN, |
| 0, 0 ); |
| break; |
| |
| case WM_UPDATEFRAME: |
| // Return TRUE - no further action for the frame control window procedure. |
| return (MRESULT)TRUE; |
| |
| case WM_ACTIVATE: |
| if ( (BOOL)mp1 ) |
| { |
| POINTL pointl; |
| |
| if ( SDL_GetKeyboardFocus() != pWinData->window ) |
| SDL_SetKeyboardFocus( pWinData->window ); |
| |
| WinQueryPointerPos( HWND_DESKTOP, &pointl ); |
| WinMapWindowPoints( HWND_DESKTOP, pWinData->hwnd, &pointl, 1 ); |
| SDL_SendMouseMotion( pWinData->window, 0, 0, |
| pointl.x, pWinData->window->h - pointl.y - 1 ); |
| } |
| else |
| { |
| if ( SDL_GetKeyboardFocus() == pWinData->window ) |
| SDL_SetKeyboardFocus( NULL ); |
| |
| WinSetCapture( HWND_DESKTOP, NULLHANDLE ); |
| } |
| break; |
| |
| case WM_MOUSEMOVE: |
| WinSetPointer( HWND_DESKTOP, hptrCursor ); |
| |
| if ( pWinData->lSkipWMMouseMove > 0 ) |
| pWinData->lSkipWMMouseMove--; |
| else |
| _wmMouseMove( pWinData, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1) ); |
| return (MRESULT)FALSE; |
| |
| case WM_BUTTON1DOWN: |
| case WM_BUTTON1DBLCLK: |
| _wmMouseButton( pWinData, 0, TRUE ); |
| break; |
| |
| case WM_BUTTON1UP: |
| _wmMouseButton( pWinData, 0, FALSE ); |
| break; |
| |
| case WM_BUTTON2DOWN: |
| case WM_BUTTON2DBLCLK: |
| _wmMouseButton( pWinData, 1, TRUE ); |
| break; |
| |
| case WM_BUTTON2UP: |
| _wmMouseButton( pWinData, 1, FALSE ); |
| break; |
| |
| case WM_BUTTON3DOWN: |
| case WM_BUTTON3DBLCLK: |
| _wmMouseButton( pWinData, 2, TRUE ); |
| break; |
| |
| case WM_BUTTON3UP: |
| _wmMouseButton( pWinData, 2, FALSE ); |
| break; |
| |
| case WM_TRANSLATEACCEL: |
| // ALT and acceleration keys not allowed (must be processed in WM_CHAR) |
| if ( mp1 == NULL || ((PQMSG)mp1)->msg != WM_CHAR ) |
| break; |
| return (MRESULT)FALSE; |
| |
| case WM_CHAR: |
| _wmChar( pWinData, mp1, mp2 ); |
| break; |
| |
| case WM_SIZE: |
| if ( pWinData->lSkipWMSize > 0 ) |
| pWinData->lSkipWMSize--; |
| else |
| { |
| if ( (pWinData->window->flags & SDL_WINDOW_FULLSCREEN) == 0 ) |
| SDL_SendWindowEvent( pWinData->window, SDL_WINDOWEVENT_RESIZED, |
| SHORT1FROMMP(mp2), SHORT2FROMMP(mp2) ); |
| else |
| pWinData->lSkipWMVRNEnabled++; |
| } |
| break; |
| |
| case WM_MOVE: |
| if ( pWinData->lSkipWMMove > 0 ) |
| pWinData->lSkipWMMove--; |
| else if ( (pWinData->window->flags & SDL_WINDOW_FULLSCREEN) == 0 ) |
| _wmMove( pWinData ); |
| break; |
| |
| case WM_VRNENABLED: |
| if ( pWinData->lSkipWMVRNEnabled > 0 ) |
| pWinData->lSkipWMVRNEnabled--; |
| else |
| _setVisibleRegion( pWinData, TRUE ); |
| return (MRESULT)TRUE; |
| |
| case WM_VRNDISABLED: |
| _setVisibleRegion( pWinData, FALSE ); |
| return (MRESULT)TRUE; |
| |
| case DM_DRAGOVER: |
| return _wmDragOver( pWinData, (PDRAGINFO)PVOIDFROMMP(mp1) ); |
| |
| case DM_DROP: |
| return _wmDrop( pWinData, (PDRAGINFO)PVOIDFROMMP(mp1) ); |
| } |
| |
| return pWinData->fnUserWndProc != NULL |
| ? pWinData->fnUserWndProc( hwnd, msg, mp1, mp2 ) |
| : WinDefWindowProc( hwnd, msg, mp1, mp2 ); |
| } |
| |
| |
| // SDL routnes. |
| // ------------ |
| |
| static void OS2_PumpEvents(_THIS) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| QMSG qmsg; |
| |
| if( WinPeekMsg( pVData->hab, &qmsg, NULLHANDLE, 0, 0, PM_REMOVE ) ) |
| WinDispatchMsg( pVData->hab, &qmsg ); |
| } |
| |
| static PWINDATA _setupWindow(_THIS, SDL_Window *window, HWND hwndFrame, |
| HWND hwnd) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| PWINDATA pWinData = SDL_calloc( 1, sizeof(WINDATA) ); |
| |
| if ( pWinData == NULL ) |
| { |
| SDL_OutOfMemory(); |
| return NULL; |
| } |
| pWinData->hwnd = hwnd; |
| pWinData->hwndFrame = hwndFrame; |
| pWinData->window = window; |
| window->driverdata = pWinData; |
| |
| WinSetWindowULong( hwnd, 0, (ULONG)pWinData ); |
| pWinData->fnWndFrameProc = WinSubclassWindow( hwndFrame, wndFrameProc ); |
| |
| pWinData->pOutput = pVData->pOutput; |
| pWinData->pVOData = pVData->pOutput->Open(); |
| |
| WinSetVisibleRegionNotify( hwnd, TRUE ); |
| |
| return pWinData; |
| } |
| |
| static int OS2_CreateWindow(_THIS, SDL_Window *window) |
| { |
| RECTL rectl; |
| HWND hwndFrame, hwnd; |
| SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow( window ); |
| ULONG ulFrameFlags = FCF_TASKLIST | FCF_TITLEBAR | FCF_SYSMENU |
| | FCF_MINBUTTON | FCF_SHELLPOSITION; |
| ULONG ulSWPFlags = SWP_SIZE | SWP_SHOW | SWP_ZORDER | |
| SWP_ACTIVATE; |
| PWINDATA pWinData; |
| |
| if ( pSDLDisplayMode == NULL ) |
| return -1; |
| |
| // Create a PM window. |
| |
| if ( (window->flags & SDL_WINDOW_RESIZABLE) != 0 ) |
| ulFrameFlags |= FCF_SIZEBORDER | FCF_DLGBORDER | FCF_MAXBUTTON; |
| else if ( (window->flags & SDL_WINDOW_BORDERLESS) == 0 ) |
| ulFrameFlags |= FCF_DLGBORDER; |
| |
| if ( (window->flags & SDL_WINDOW_MAXIMIZED) != 0 ) |
| ulSWPFlags |= SWP_MAXIMIZE; |
| else if ( (window->flags & SDL_WINDOW_MINIMIZED) != 0 ) |
| ulSWPFlags |= SWP_MINIMIZE; |
| |
| hwndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &ulFrameFlags, |
| WIN_CLIENT_CLASS, "SDL2", 0, 0, 0, &hwnd ); |
| if ( hwndFrame == NULLHANDLE ) |
| return SDL_SetError( "Couldn't create window" ); |
| |
| // Setup window data and frame window procedure. |
| pWinData = _setupWindow( _this, window, hwndFrame, hwnd ); |
| if ( pWinData == NULL ) |
| { |
| WinDestroyWindow( hwndFrame ); |
| return -1; |
| } |
| |
| // Show window. |
| rectl.xLeft = 0; |
| rectl.yBottom = 0; |
| rectl.xRight = window->w; |
| rectl.yTop = window->h; |
| WinCalcFrameRect( hwndFrame, &rectl, FALSE ); |
| pWinData->lSkipWMSize++; |
| pWinData->lSkipWMMove++; |
| WinSetWindowPos( hwndFrame, HWND_TOP, rectl.xLeft, rectl.yBottom, |
| rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom, |
| ulSWPFlags ); |
| |
| rectl.xLeft = 0; |
| rectl.yBottom = 0; |
| WinMapWindowPoints( hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 1 ); |
| window->x = rectl.xLeft; |
| window->y = pSDLDisplayMode->h - ( rectl.yBottom + window->h ); |
| |
| window->flags |= SDL_WINDOW_SHOWN; |
| |
| return 0; |
| } |
| |
| static int OS2_CreateWindowFrom(_THIS, SDL_Window *window, const void *data) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| CHAR acBuf[256]; |
| CLASSINFO stCI; |
| HWND hwndUser = (HWND)data; |
| HWND hwndFrame, hwnd; |
| ULONG cbText; |
| PSZ pszText; |
| PWINDATA pWinData; |
| SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow( window ); |
| SWP swp; |
| POINTL pointl; |
| |
| debug( "Enter" ); |
| if ( pSDLDisplayMode == NULL ) |
| return -1; |
| |
| // User can accept client OR frame window handle. |
| // Get client and frame window handles. |
| |
| WinQueryClassName( hwndUser, sizeof(acBuf), acBuf ); |
| if ( !WinQueryClassInfo( pVData->hab, &acBuf, &stCI ) ) |
| return SDL_SetError( "Cannot get user window class information" ); |
| |
| if ( (stCI.flClassStyle & CS_FRAME) == 0 ) |
| { |
| // Client window handle is specified. |
| |
| hwndFrame = WinQueryWindow( hwndUser, QW_PARENT ); |
| if ( hwndFrame == NULLHANDLE ) |
| return SDL_SetError( "Cannot get parent window handle" ); |
| |
| if ( (ULONG)WinSendMsg( hwndFrame, WM_QUERYFRAMEINFO, 0, 0 ) == 0 ) |
| return SDL_SetError( "Parent window is not a frame window" ); |
| |
| hwnd = hwndUser; |
| } |
| else |
| { |
| // Frame window handle is specified. |
| |
| hwnd = WinWindowFromID( hwndUser, FID_CLIENT ); |
| if ( hwnd == NULLHANDLE ) |
| return SDL_SetError( "Cannot get client window handle" ); |
| |
| hwndFrame = hwndUser; |
| |
| WinQueryClassName( hwnd, sizeof(acBuf), acBuf ); |
| if ( !WinQueryClassInfo( pVData->hab, &acBuf, &stCI ) ) |
| return SDL_SetError( "Cannot get client window class information" ); |
| } |
| |
| // Check window's reserved storage. |
| if ( stCI.cbWindowData < sizeof(ULONG) ) |
| return SDL_SetError( "Reserved storage of window must be at least %u bytes", |
| sizeof(ULONG) ); |
| |
| // Set SDL-window title. |
| |
| cbText = WinQueryWindowTextLength( hwndFrame ); |
| pszText = SDL_stack_alloc( CHAR, cbText + 1 ); |
| |
| if ( pszText != NULL ) |
| cbText = pszText != NULL ? |
| WinQueryWindowText( hwndFrame, cbText, pszText ) : 0; |
| |
| if ( cbText != 0 ) |
| window->title = OS2_SysToUTF8( pszText ); |
| |
| if ( pszText != NULL ) |
| SDL_stack_free( pszText ); |
| |
| // Set SDL-window flags. |
| |
| window->flags &= ~(SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS | |
| SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED | |
| SDL_WINDOW_MINIMIZED | SDL_WINDOW_INPUT_FOCUS); |
| |
| if ( WinIsWindowVisible( hwnd ) ) |
| window->flags |= SDL_WINDOW_SHOWN; |
| |
| WinSendMsg( hwndFrame, WM_QUERYBORDERSIZE, MPFROMP(&pointl), 0 ); |
| if ( pointl.y == WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER ) ) |
| window->flags |= SDL_WINDOW_RESIZABLE; |
| else if ( pointl.y <= WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ) ) |
| window->flags |= SDL_WINDOW_BORDERLESS; |
| |
| WinQueryWindowPos( hwndFrame, &swp ); |
| |
| if ( (swp.fl & SWP_MAXIMIZE) != 0 ) |
| window->flags |= SDL_WINDOW_MAXIMIZED; |
| |
| if ( (swp.fl & SWP_MINIMIZE) != 0 ) |
| window->flags |= SDL_WINDOW_MINIMIZED; |
| |
| pointl.x = 0; |
| pointl.y = 0; |
| WinMapWindowPoints( hwnd, HWND_DESKTOP, &pointl, 1 ); |
| window->x = pointl.x; |
| window->y = pSDLDisplayMode->h - ( pointl.y + swp.cy ); |
| |
| WinQueryWindowPos( hwnd, &swp ); |
| window->w = swp.cx; |
| window->h = swp.cy; |
| |
| // Setup window data and frame window procedure. |
| pWinData = _setupWindow( _this, window, hwndFrame, hwnd ); |
| if ( pWinData == NULL ) |
| { |
| SDL_free( window->title ); |
| window->title = NULL; |
| return -1; |
| } |
| pWinData->fnUserWndProc = WinSubclassWindow( hwnd, wndProc ); |
| |
| if ( WinQueryActiveWindow( HWND_DESKTOP ) == hwndFrame ) |
| SDL_SetKeyboardFocus( window ); |
| |
| return 0; |
| } |
| |
| static void OS2_DestroyWindow(_THIS, SDL_Window * window) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter" ); |
| |
| if ( pWinData == NULL ) |
| return; |
| |
| if ( pWinData->fnUserWndProc == NULL ) |
| // Window was created by SDL ( OS2_CreateWindow() ), not by |
| // user ( OS2_CreateWindowFrom() ). |
| WinDestroyWindow( pWinData->hwndFrame ); |
| else |
| WinSetWindowULong( pWinData->hwnd, 0, 0 ); |
| |
| if ( ( pVData != NULL ) && ( pWinData->pVOData != NULL ) ) |
| { |
| pVData->pOutput->Close( pWinData->pVOData ); |
| pWinData->pVOData = NULL; |
| } |
| |
| if ( pWinData->hptrIcon != NULLHANDLE ) |
| { |
| WinDestroyPointer( pWinData->hptrIcon ); |
| pWinData->hptrIcon = NULLHANDLE; |
| } |
| |
| SDL_free( pWinData ); |
| window->driverdata = NULL; |
| } |
| |
| static void OS2_SetWindowTitle(_THIS, SDL_Window *window) |
| { |
| PSZ pszTitle = window->title == NULL ? |
| NULL : OS2_UTF8ToSys( window->title ); |
| |
| WinSetWindowText( ((PWINDATA)window->driverdata)->hwndFrame, pszTitle ); |
| SDL_free( pszTitle ); |
| } |
| |
| static void OS2_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| HPOINTER hptr = utilCreatePointer( icon, 0, 0 ); |
| |
| if ( hptr == NULLHANDLE ) |
| return; |
| |
| // Destroy old icon. |
| if ( pWinData->hptrIcon != NULLHANDLE ) |
| WinDestroyPointer( pWinData->hptrIcon ); |
| |
| // Set new window icon. |
| pWinData->hptrIcon = hptr; |
| if ( !WinSendMsg( pWinData->hwndFrame, WM_SETICON, MPFROMLONG( hptr ), 0 ) ) |
| debug( "Cannot set icon for the window" ); |
| } |
| |
| static void OS2_SetWindowPosition(_THIS, SDL_Window *window) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| RECTL rectl; |
| ULONG ulFlags; |
| SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow( window ); |
| |
| debug( "Enter" ); |
| if ( pSDLDisplayMode == NULL ) |
| return; |
| |
| rectl.xLeft = 0; |
| rectl.yBottom = 0; |
| rectl.xRight = window->w; |
| rectl.yTop = window->h; |
| WinCalcFrameRect( pWinData->hwndFrame, &rectl, FALSE ); |
| |
| if ( SDL_ShouldAllowTopmost() && |
| (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == |
| (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) ) |
| ulFlags = SWP_ZORDER | SWP_MOVE | SWP_SIZE; |
| else |
| ulFlags = SWP_MOVE | SWP_SIZE; |
| |
| pWinData->lSkipWMSize++; |
| pWinData->lSkipWMMove++; |
| WinSetWindowPos( pWinData->hwndFrame, HWND_TOP, |
| window->x + rectl.xLeft, |
| (pSDLDisplayMode->h - window->y) - window->h + rectl.yBottom, |
| rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom, |
| ulFlags ); |
| } |
| |
| static void OS2_SetWindowSize(_THIS, SDL_Window *window) |
| { |
| debug( "Enter" ); |
| OS2_SetWindowPosition( _this, window ); |
| } |
| |
| static void OS2_ShowWindow(_THIS, SDL_Window *window) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter" ); |
| WinShowWindow( pWinData->hwndFrame, TRUE ); |
| } |
| |
| static void OS2_HideWindow(_THIS, SDL_Window *window) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter" ); |
| WinShowWindow( pWinData->hwndFrame, FALSE ); |
| } |
| |
| static void OS2_RaiseWindow(_THIS, SDL_Window *window) |
| { |
| debug( "Enter" ); |
| OS2_SetWindowPosition( _this, window ); |
| } |
| |
| static void OS2_MaximizeWindow(_THIS, SDL_Window *window) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter" ); |
| WinSetWindowPos( pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MAXIMIZE ); |
| } |
| |
| static void OS2_MinimizeWindow(_THIS, SDL_Window *window) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter" ); |
| WinSetWindowPos( pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, |
| SWP_MINIMIZE | SWP_DEACTIVATE ); |
| } |
| |
| static void OS2_RestoreWindow(_THIS, SDL_Window *window) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter" ); |
| WinSetWindowPos( pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, |
| SWP_RESTORE ); |
| } |
| |
| static void OS2_SetWindowBordered(_THIS, SDL_Window * window, |
| SDL_bool bordered) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| ULONG ulStyle = WinQueryWindowULong( pWinData->hwndFrame, QWL_STYLE ); |
| RECTL rectl; |
| |
| debug( "Enter" ); |
| |
| // New frame sytle. |
| if ( bordered ) |
| ulStyle |= (window->flags & SDL_WINDOW_RESIZABLE) != 0 |
| ? FS_SIZEBORDER : FS_DLGBORDER; |
| else |
| ulStyle &= ~(FS_SIZEBORDER | FS_BORDER | FS_DLGBORDER); |
| |
| // Save client window position. |
| WinQueryWindowRect( pWinData->hwnd, &rectl ); |
| WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 2 ); |
| |
| // Change the frame. |
| WinSetWindowULong( pWinData->hwndFrame, QWL_STYLE, ulStyle ); |
| WinSendMsg( pWinData->hwndFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_BORDER), 0 ); |
| |
| // Restore client window position. |
| WinCalcFrameRect( pWinData->hwndFrame, &rectl, FALSE ); |
| pWinData->lSkipWMMove++; |
| WinSetWindowPos( pWinData->hwndFrame, HWND_TOP, rectl.xLeft, rectl.yBottom, |
| rectl.xRight - rectl.xLeft, |
| rectl.yTop - rectl.yBottom, |
| SWP_SIZE | SWP_MOVE | SWP_NOADJUST ); |
| } |
| |
| static void OS2_SetWindowFullscreen(_THIS, SDL_Window *window, |
| SDL_VideoDisplay *display, |
| SDL_bool fullscreen) |
| { |
| RECTL rectl; |
| ULONG ulFlags; |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| SDL_DisplayMode *pSDLDisplayMode = &display->current_mode; |
| |
| debug( "Enter, fullscreen: %u", fullscreen ); |
| |
| if ( pSDLDisplayMode == NULL ) |
| return; |
| |
| if ( SDL_ShouldAllowTopmost() && |
| (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == |
| (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) ) |
| ulFlags = SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_NOADJUST; |
| else |
| ulFlags = SWP_SIZE | SWP_MOVE | SWP_NOADJUST; |
| |
| if ( fullscreen ) |
| { |
| rectl.xLeft = 0; |
| rectl.yBottom = 0; |
| rectl.xRight = pSDLDisplayMode->w; |
| rectl.yTop = pSDLDisplayMode->h; |
| // We need send the restore command now to allow WinCalcFrameRect(). |
| WinSetWindowPos( pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_RESTORE ); |
| } |
| else |
| { |
| pWinData->lSkipWMMove++; |
| rectl.xLeft = window->windowed.x; |
| rectl.yTop = pSDLDisplayMode->h - window->windowed.y; |
| rectl.xRight = rectl.xLeft + window->windowed.w; |
| rectl.yBottom = rectl.yTop - window->windowed.h; |
| } |
| |
| if ( !WinCalcFrameRect( pWinData->hwndFrame, &rectl, FALSE ) ) |
| debug( "WinCalcFrameRect() failed" ); |
| else if ( !WinSetWindowPos( pWinData->hwndFrame, HWND_TOP, |
| rectl.xLeft, rectl.yBottom, |
| rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom, |
| ulFlags ) ) |
| debug( "WinSetWindowPos() failed" ); |
| } |
| |
| static SDL_bool OS2_GetWindowWMInfo(_THIS, SDL_Window * window, |
| struct SDL_SysWMinfo *info) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| if ( info->version.major <= SDL_MAJOR_VERSION ) |
| { |
| info->subsystem = SDL_SYSWM_OS2; |
| info->info.os2.hwnd = pWinData->hwnd; |
| info->info.os2.hwndFrame = pWinData->hwndFrame; |
| return SDL_TRUE; |
| } |
| |
| SDL_SetError( "Application not compiled with SDL %u.%u", |
| SDL_MAJOR_VERSION, SDL_MINOR_VERSION ); |
| return SDL_FALSE; |
| } |
| |
| static void OS2_OnWindowEnter(_THIS, SDL_Window * window) |
| { |
| } |
| |
| static int OS2_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) |
| { |
| debug( "Enter" ); |
| return 0; |
| } |
| |
| static void OS2_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter, %u", grabbed ); |
| _mouseCheck( pWinData ); |
| } |
| |
| |
| // Shaper. |
| |
| typedef struct _SHAPERECTS { |
| PRECTL pRects; |
| ULONG cRects; |
| ULONG ulWinHeight; |
| } SHAPERECTS, *PSHAPERECTS; |
| |
| static void _combineRectRegions(SDL_ShapeTree *node, void *closure) |
| { |
| PSHAPERECTS pShapeRects = (PSHAPERECTS)closure; |
| PRECTL pRect; |
| |
| // Expand rectangles list. |
| if ( (pShapeRects->cRects & 0x0F) == 0 ) |
| { |
| pRect = SDL_realloc( pShapeRects->pRects, |
| ( pShapeRects->cRects + 0x10 ) * sizeof(RECTL) ); |
| if ( pRect == NULL ) |
| return; |
| pShapeRects->pRects = pRect; |
| } |
| |
| // Add a new rectangle. |
| pRect = &pShapeRects->pRects[pShapeRects->cRects]; |
| pShapeRects->cRects++; |
| // Fill rectangle data. |
| pRect->xLeft = node->data.shape.x; |
| pRect->yTop = pShapeRects->ulWinHeight - node->data.shape.y; |
| pRect->xRight += node->data.shape.w; |
| pRect->yBottom = pRect->yTop - node->data.shape.h; |
| } |
| |
| static SDL_WindowShaper* OS2_CreateShaper(SDL_Window * window) |
| { |
| SDL_WindowShaper* pSDLShaper = SDL_malloc( sizeof(SDL_WindowShaper) ); |
| |
| debug( "Enter" ); |
| pSDLShaper->window = window; |
| pSDLShaper->mode.mode = ShapeModeDefault; |
| pSDLShaper->mode.parameters.binarizationCutoff = 1; |
| pSDLShaper->userx = 0; |
| pSDLShaper->usery = 0; |
| pSDLShaper->driverdata = (SDL_ShapeTree *)NULL; |
| window->shaper = pSDLShaper; |
| |
| if ( OS2_ResizeWindowShape( window ) != 0 ) |
| { |
| window->shaper = NULL; |
| SDL_free( pSDLShaper ); |
| return NULL; |
| } |
| |
| return pSDLShaper; |
| } |
| |
| static int OS2_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, |
| SDL_WindowShapeMode *shape_mode) |
| { |
| SDL_ShapeTree *pShapeTree; |
| PWINDATA pWinData; |
| SHAPERECTS stShapeRects = { 0 }; |
| HPS hps; |
| |
| debug( "Enter" ); |
| if ( ( shaper == NULL ) || ( shape == NULL ) || |
| ( ( shape->format->Amask == 0 ) && |
| ( shape_mode->mode != ShapeModeColorKey ) ) || |
| ( shape->w != shaper->window->w ) || ( shape->h != shaper->window->h ) ) |
| return SDL_INVALID_SHAPE_ARGUMENT; |
| |
| if ( shaper->driverdata != NULL ) |
| SDL_FreeShapeTree( (SDL_ShapeTree **)&shaper->driverdata ); |
| |
| pShapeTree = SDL_CalculateShapeTree( *shape_mode, shape ); |
| shaper->driverdata = pShapeTree; |
| |
| stShapeRects.ulWinHeight = shaper->window->h; |
| SDL_TraverseShapeTree( pShapeTree, &_combineRectRegions, &stShapeRects ); |
| |
| pWinData = (PWINDATA)shaper->window->driverdata; |
| hps = WinGetPS( pWinData->hwnd ); |
| |
| if ( pWinData->hrgnShape != NULLHANDLE ) |
| GpiDestroyRegion( hps, pWinData->hrgnShape ); |
| |
| pWinData->hrgnShape = stShapeRects.pRects == NULL |
| ? NULLHANDLE |
| : GpiCreateRegion( hps, stShapeRects.cRects, |
| stShapeRects.pRects ); |
| |
| WinReleasePS( hps ); |
| SDL_free( stShapeRects.pRects ); |
| WinSendMsg( pWinData->hwnd, WM_VRNENABLED, 0, 0 ); |
| |
| return 0; |
| } |
| |
| static int OS2_ResizeWindowShape(SDL_Window *window) |
| { |
| debug( "Enter" ); |
| |
| if ( window == NULL ) |
| return -1; |
| |
| if ( window->x != -1000 ) |
| { |
| if ( window->shaper->driverdata != NULL ) |
| SDL_FreeShapeTree( (SDL_ShapeTree **)window->shaper->driverdata ); |
| |
| if ( window->shaper->hasshape == SDL_TRUE ) |
| { |
| window->shaper->userx = window->x; |
| window->shaper->usery = window->y; |
| SDL_SetWindowPosition( window, -1000, -1000 ); |
| } |
| } |
| |
| return 0; |
| } |
| |
| |
| // Frame buffer. |
| |
| static void OS2_DestroyWindowFramebuffer(_THIS, SDL_Window *window) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| debug( "Enter" ); |
| if ( ( pWinData != NULL ) && ( pWinData->pVOData != NULL ) ) |
| pWinData->pOutput->VideoBufFree( pWinData->pVOData ); |
| } |
| |
| static int OS2_CreateWindowFramebuffer(_THIS, SDL_Window *window, |
| Uint32 *format, void **pixels, |
| int *pitch) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| SDL_VideoDisplay *pSDLDisplay = SDL_GetDisplayForWindow( window ); |
| SDL_DisplayMode *pSDLDisplayMode; |
| PMODEDATA pModeData; |
| ULONG ulWidth, ulHeight; |
| |
| debug( "Enter" ); |
| |
| if ( pSDLDisplay == NULL ) |
| { |
| debug( "No display for the window" ); |
| return -1; |
| } |
| |
| pSDLDisplayMode = &pSDLDisplay->current_mode; |
| pModeData = (PMODEDATA)pSDLDisplayMode->driverdata; |
| if ( pModeData == NULL ) |
| return SDL_SetError( "No mode data for the display" ); |
| |
| SDL_GetWindowSize( window, (int *)&ulWidth, (int *)&ulHeight ); |
| debug( "Window size: %u x %u", ulWidth, ulHeight ); |
| |
| *pixels = pWinData->pOutput->VideoBufAlloc( |
| pWinData->pVOData, ulWidth, ulHeight, pModeData->ulDepth, |
| pModeData->fccColorEncoding, (PULONG)pitch ); |
| if ( *pixels == NULL ) |
| return -1; |
| |
| *format = pSDLDisplayMode->format; |
| debug( "Pitch: %u, frame buffer: 0x%X.", *pitch, *pixels ); |
| WinSendMsg( pWinData->hwnd, WM_VRNENABLED, 0, 0 ); |
| |
| return 0; |
| } |
| |
| static int OS2_UpdateWindowFramebuffer(_THIS, SDL_Window * window, |
| const SDL_Rect *rects, int numrects) |
| { |
| PWINDATA pWinData = (PWINDATA)window->driverdata; |
| |
| return pWinData->pOutput->Update( pWinData->pVOData, pWinData->hwnd, |
| (SDL_Rect *)rects, (ULONG)numrects ) |
| ? 0 : -1; |
| } |
| |
| |
| // Clipboard. |
| |
| static int OS2_SetClipboardText(_THIS, const char *text) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| PSZ pszClipboard; |
| PSZ pszText = text == NULL ? NULL : OS2_UTF8ToSys( text ); |
| ULONG cbText; |
| ULONG ulRC; |
| BOOL fSuccess; |
| |
| debug( "Enter" ); |
| if ( pszText == NULL ) |
| return -1; |
| cbText = SDL_strlen( pszText ); |
| |
| ulRC = DosAllocSharedMem( (PPVOID)&pszClipboard, 0, cbText + 1, |
| PAG_COMMIT | PAG_READ | PAG_WRITE | |
| OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE ); |
| if ( ulRC != NO_ERROR ) |
| { |
| debug( "DosAllocSharedMem() failed, rc = %u", ulRC ); |
| SDL_free( pszText ); |
| return -1; |
| } |
| |
| strcpy( pszClipboard, pszText ); |
| SDL_free( pszText ); |
| |
| if ( !WinOpenClipbrd( pVData->hab ) ) |
| { |
| debug( "WinOpenClipbrd() failed" ); |
| fSuccess = FALSE; |
| } |
| else |
| { |
| WinEmptyClipbrd( pVData->hab ); |
| |
| fSuccess = WinSetClipbrdData( pVData->hab, (ULONG)pszClipboard, CF_TEXT, |
| CFI_POINTER ); |
| if ( !fSuccess ) |
| debug( "WinOpenClipbrd() failed" ); |
| |
| WinCloseClipbrd( pVData->hab ); |
| } |
| |
| if ( !fSuccess ) |
| { |
| DosFreeMem( pszClipboard ); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| static char *OS2_GetClipboardText(_THIS) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| PSZ pszClipboard = NULL; |
| |
| if ( !WinOpenClipbrd( pVData->hab ) ) |
| debug( "WinOpenClipbrd() failed" ); |
| else |
| { |
| pszClipboard = (PSZ)WinQueryClipbrdData( pVData->hab, CF_TEXT ); |
| if ( pszClipboard != NULL ) |
| pszClipboard = OS2_SysToUTF8( pszClipboard ); |
| WinCloseClipbrd( pVData->hab ); |
| } |
| |
| return pszClipboard == NULL ? SDL_strdup( "" ) : pszClipboard; |
| } |
| |
| static SDL_bool OS2_HasClipboardText(_THIS) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| SDL_bool fClipboard; |
| |
| if ( !WinOpenClipbrd( pVData->hab ) ) |
| { |
| debug( "WinOpenClipbrd() failed" ); |
| return SDL_FALSE; |
| } |
| |
| fClipboard = (PSZ)WinQueryClipbrdData( pVData->hab, CF_TEXT ) != NULL |
| ? SDL_TRUE : SDL_FALSE; |
| WinCloseClipbrd( pVData->hab ); |
| |
| return fClipboard; |
| } |
| |
| |
| static int OS2_VideoInit(_THIS) |
| { |
| PSDL_VideoData pVData; |
| PTIB tib; |
| PPIB pib; |
| |
| // Create SDL video driver private data. |
| |
| pVData = SDL_calloc( 1, sizeof(SDL_VideoData) ); |
| if ( pVData == NULL ) |
| return SDL_OutOfMemory(); |
| |
| // Change process type code for use Win* API from VIO session. |
| |
| DosGetInfoBlocks( &tib, &pib ); |
| if ( pib->pib_ultype == 2 || pib->pib_ultype == 0 ) |
| { |
| // VIO windowable or fullscreen protect-mode session. |
| pib->pib_ultype = 3; // Presentation Manager protect-mode session. |
| } |
| |
| // PM initialization. |
| |
| pVData->hab = WinInitialize( 0 ); |
| pVData->hmq = WinCreateMsgQueue( pVData->hab, 0 ); |
| if ( pVData->hmq == NULLHANDLE ) |
| { |
| SDL_free( pVData ); |
| return SDL_SetError( "Message queue cannot be created." ); |
| } |
| |
| if ( !WinRegisterClass( pVData->hab, WIN_CLIENT_CLASS, wndProc, |
| CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT, |
| sizeof(PSDL_VideoData) ) ) |
| { |
| SDL_free( pVData ); |
| return SDL_SetError( "Window class not successfully registered." ); |
| } |
| |
| if ( stricmp( _this->name, OS2DRIVER_NAME_VMAN ) == 0 ) |
| pVData->pOutput = &voVMan; |
| else |
| pVData->pOutput = &voDive; |
| |
| _this->driverdata = pVData; |
| |
| // Add display. |
| |
| { |
| SDL_VideoDisplay stSDLDisplay; |
| SDL_DisplayMode stSDLDisplayMode; |
| PDISPLAYDATA pDisplayData; |
| PMODEDATA pModeData; |
| VIDEOOUTPUTINFO stVOInfo; |
| |
| if ( !pVData->pOutput->QueryInfo( &stVOInfo ) ) |
| { |
| SDL_free( pVData ); |
| return SDL_SetError( "Video mode query failed." ); |
| } |
| |
| stSDLDisplayMode.format = _getSDLPixelFormat( stVOInfo.ulBPP, |
| stVOInfo.fccColorEncoding ); |
| stSDLDisplayMode.w = stVOInfo.ulHorizResolution; |
| stSDLDisplayMode.h = stVOInfo.ulVertResolution; |
| stSDLDisplayMode.refresh_rate = 0; |
| stSDLDisplayMode.driverdata = NULL; |
| |
| pModeData = SDL_malloc( sizeof(MODEDATA) ); |
| if ( pModeData != NULL ) |
| { |
| pModeData->ulDepth = stVOInfo.ulBPP; |
| pModeData->fccColorEncoding = stVOInfo.fccColorEncoding; |
| pModeData->ulScanLineBytes = stVOInfo.ulScanLineSize; |
| stSDLDisplayMode.driverdata = pModeData; |
| } |
| |
| stSDLDisplay.name = "Primary"; |
| stSDLDisplay.desktop_mode = stSDLDisplayMode; |
| stSDLDisplay.current_mode = stSDLDisplayMode; |
| stSDLDisplay.driverdata = NULL; |
| stSDLDisplay.num_display_modes = 0; |
| |
| pDisplayData = SDL_malloc( sizeof(DISPLAYDATA) ); |
| if ( pDisplayData != NULL ) |
| { |
| HPS hps = WinGetPS( HWND_DESKTOP ); |
| HDC hdc = GpiQueryDevice( hps ); |
| |
| // May be we can use CAPS_HORIZONTAL_RESOLUTION and |
| // CAPS_VERTICAL_RESOLUTION - pels per meter? |
| DevQueryCaps( hdc, CAPS_HORIZONTAL_FONT_RES, 1, |
| (PLONG)&pDisplayData->ulDPIHor ); |
| DevQueryCaps( hdc, CAPS_VERTICAL_FONT_RES, 1, |
| (PLONG)&pDisplayData->ulDPIVer ); |
| WinReleasePS( hps ); |
| |
| pDisplayData->ulDPIDiag = SDL_ComputeDiagonalDPI( |
| stVOInfo.ulHorizResolution, stVOInfo.ulVertResolution, |
| (float)stVOInfo.ulHorizResolution / pDisplayData->ulDPIHor, |
| (float)stVOInfo.ulVertResolution / pDisplayData->ulDPIVer ); |
| |
| stSDLDisplayMode.driverdata = pDisplayData; |
| } |
| |
| SDL_AddVideoDisplay( &stSDLDisplay ); |
| } |
| |
| OS2_InitMouse( _this, pVData->hab ); |
| |
| return 0; |
| } |
| |
| static void OS2_VideoQuit(_THIS) |
| { |
| PSDL_VideoData pVData = (PSDL_VideoData)_this->driverdata; |
| ULONG ulDisplayIdx, ulModeIdx; |
| SDL_VideoDisplay *pSDLDisplay; |
| |
| OS2_QuitMouse( _this ); |
| |
| WinDestroyMsgQueue( pVData->hmq ); |
| WinTerminate( pVData->hab ); |
| |
| // We support only one display. Free all listed displays data for the future. |
| for( ulDisplayIdx = 0; ulDisplayIdx < _this->num_displays; ulDisplayIdx++ ) |
| { |
| pSDLDisplay = &_this->displays[ulDisplayIdx]; |
| |
| // Free video mode data (PMODEDATA). |
| if ( pSDLDisplay->desktop_mode.driverdata != NULL ) |
| SDL_free( pSDLDisplay->desktop_mode.driverdata ); |
| |
| // We support only one mode - desktop_mode. Free all modes for the future. |
| for( ulModeIdx = 0; ulModeIdx < pSDLDisplay->num_display_modes; |
| ulModeIdx++ ) |
| if ( pSDLDisplay->display_modes[ulModeIdx].driverdata != NULL ) |
| SDL_free( pSDLDisplay->display_modes[ulModeIdx].driverdata ); |
| |
| // Free display data (PDISPLAYDATA). |
| if ( pSDLDisplay->driverdata != NULL ) |
| { |
| SDL_free( pSDLDisplay->driverdata ); |
| pSDLDisplay->driverdata = NULL; |
| } |
| } |
| } |
| |
| static int OS2_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, |
| SDL_Rect *rect) |
| { |
| debug( "Enter" ); |
| |
| rect->x = 0; |
| rect->y = 0; |
| rect->w = display->desktop_mode.w; |
| rect->h = display->desktop_mode.h; |
| |
| return 0; |
| } |
| |
| static int OS2_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, |
| float *hdpi, float *vdpi) |
| { |
| PDISPLAYDATA pDisplayData = (PDISPLAYDATA)display->driverdata; |
| |
| debug( "Enter" ); |
| |
| if ( pDisplayData == NULL ) |
| return -1; |
| |
| if ( ddpi != NULL ) |
| *hdpi = pDisplayData->ulDPIDiag; |
| |
| if ( hdpi != NULL ) |
| *hdpi = pDisplayData->ulDPIHor; |
| |
| if ( vdpi != NULL ) |
| *vdpi = pDisplayData->ulDPIVer; |
| |
| return 0; |
| } |
| |
| static void OS2_GetDisplayModes(_THIS, SDL_VideoDisplay *display) |
| { |
| debug( "Enter" ); |
| } |
| |
| static int OS2_SetDisplayMode(_THIS, SDL_VideoDisplay *display, |
| SDL_DisplayMode *mode) |
| { |
| debug( "Enter" ); |
| return -1; |
| } |
| |
| |
| static void OS2_DeleteDevice(SDL_VideoDevice *device) |
| { |
| SDL_free( device ); |
| } |
| |
| static SDL_VideoDevice *OS2_CreateDevice(int devindex) |
| { |
| SDL_VideoDevice *device; |
| |
| /* Initialize all variables that we clean on shutdown */ |
| device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); |
| if (!device) |
| { |
| SDL_OutOfMemory(); |
| return (0); |
| } |
| |
| /* Set the function pointers */ |
| device->VideoInit = OS2_VideoInit; |
| device->VideoQuit = OS2_VideoQuit; |
| device->SetDisplayMode = OS2_SetDisplayMode; |
| device->GetDisplayBounds = OS2_GetDisplayBounds; |
| device->GetDisplayDPI = OS2_GetDisplayDPI; |
| device->GetDisplayModes = OS2_GetDisplayModes; |
| device->SetDisplayMode = OS2_SetDisplayMode; |
| device->PumpEvents = OS2_PumpEvents; |
| device->CreateWindow = OS2_CreateWindow; |
| device->CreateWindowFrom = OS2_CreateWindowFrom; |
| device->DestroyWindow = OS2_DestroyWindow; |
| device->SetWindowTitle = OS2_SetWindowTitle; |
| device->SetWindowIcon = OS2_SetWindowIcon; |
| device->SetWindowPosition = OS2_SetWindowPosition; |
| device->SetWindowSize = OS2_SetWindowSize; |
| device->ShowWindow = OS2_ShowWindow; |
| device->HideWindow = OS2_HideWindow; |
| device->RaiseWindow = OS2_RaiseWindow; |
| device->MaximizeWindow = OS2_MaximizeWindow; |
| device->MinimizeWindow = OS2_MinimizeWindow; |
| device->RestoreWindow = OS2_RestoreWindow; |
| device->SetWindowBordered = OS2_SetWindowBordered; |
| device->SetWindowFullscreen = OS2_SetWindowFullscreen; |
| device->GetWindowWMInfo = OS2_GetWindowWMInfo; |
| device->OnWindowEnter = OS2_OnWindowEnter; |
| device->SetWindowHitTest = OS2_SetWindowHitTest; |
| device->SetWindowGrab = OS2_SetWindowGrab; |
| device->CreateWindowFramebuffer = OS2_CreateWindowFramebuffer; |
| device->UpdateWindowFramebuffer = OS2_UpdateWindowFramebuffer; |
| device->DestroyWindowFramebuffer = OS2_DestroyWindowFramebuffer; |
| |
| device->SetClipboardText = OS2_SetClipboardText; |
| device->GetClipboardText = OS2_GetClipboardText; |
| device->HasClipboardText = OS2_HasClipboardText; |
| |
| device->shape_driver.CreateShaper = OS2_CreateShaper; |
| device->shape_driver.SetWindowShape = OS2_SetWindowShape; |
| device->shape_driver.ResizeWindowShape = OS2_ResizeWindowShape; |
| |
| device->free = OS2_DeleteDevice; |
| |
| return device; |
| } |
| |
| |
| // Output video system availability checking. |
| |
| static int OS2DIVE_Available(void) |
| { |
| VIDEOOUTPUTINFO stVOInfo; |
| |
| return voDive.QueryInfo( &stVOInfo ); |
| } |
| |
| static int OS2VMAN_Available(void) |
| { |
| VIDEOOUTPUTINFO stVOInfo; |
| |
| return voVMan.QueryInfo( &stVOInfo ); |
| } |
| |
| |
| // Both bootstraps for DIVE and VMAN are uing same function OS2_CreateDevice(). |
| // Video output system will be selected in OS2_VideoInit() by driver name. |
| |
| VideoBootStrap OS2DIVE_bootstrap = |
| { |
| OS2DRIVER_NAME_DIVE, "OS/2 video driver", |
| OS2DIVE_Available, OS2_CreateDevice |
| }; |
| |
| VideoBootStrap OS2VMAN_bootstrap = |
| { |
| OS2DRIVER_NAME_VMAN, "OS/2 video driver", |
| OS2VMAN_Available, OS2_CreateDevice |
| }; |
| |
| #endif /* SDL_VIDEO_DRIVER_OS2 */ |