📄 sdl_os2fslib.c
字号:
WinTerminate(hab); /* Commented out, should not be needed anymore, because we send it from WM_CLOSE. // Notify SDL that it should really die now... SDL_PrivateQuit(); SDL_PrivateQuit(); SDL_PrivateQuit(); //... :)) */#ifdef DEBUG_BUILD printf("[PMThreadFunc] : End, status is %d!\n", pVideo->hidden->iPMThreadStatus); fflush(stdout);#endif iNumOfPMThreadInstances--; // HACK to prevent zombie and hanging SDL applications, which does not take // care of closing the window for some reason: // There are some apps which do not process messages, so do a lot of things // without noticing that the application should close. To close these, // I've thought about the following: // If the window is closed (the execution came here), I wait a bit to // give time to the app to finish its execution. If it does not, I kill it // using DosExit(). Brute force, but should work. if (pVideo->hidden->iPMThreadStatus==0) { DosSleep(5000); // Wait 5 secs // If a new PM thread has been spawned (reinitializing video mode), then all right. // Otherwise, we have a problem, the app doesn't want to stop. Kill! if (iNumOfPMThreadInstances==0) {#ifdef DEBUG_BUILD printf("[PMThreadFunc] : It seems that the application haven't terminated itself\n"); fflush(stdout); printf("[PMThreadFunc] : in the last 5 seconds, so we go berserk.\n"); fflush(stdout); printf("[PMThreadFunc] : Brute force mode. :) Killing process! Dieeeee...\n"); fflush(stdout);#endif DosExit(EXIT_PROCESS, -1); } } _endthread();}struct WMcursor{ HBITMAP hbm; HPOINTER hptr; char *pchData;};/* Free a window manager cursor */void os2fslib_FreeWMCursor(_THIS, WMcursor *cursor){ if (cursor) { GpiDeleteBitmap(cursor->hbm); WinDestroyPointer(cursor->hptr); SDL_free(cursor->pchData); SDL_free(cursor); }}/* Local functions to convert the SDL cursor mask into OS/2 format */static void memnot(Uint8 *dst, Uint8 *src, int len){ while ( len-- > 0 ) *dst++ = ~*src++;}static void memxor(Uint8 *dst, Uint8 *src1, Uint8 *src2, int len){ while ( len-- > 0 ) *dst++ = (*src1++)^(*src2++);}/* Create a black/white window manager cursor */WMcursor *os2fslib_CreateWMCursor_Win(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y){ HPOINTER hptr; HBITMAP hbm; BITMAPINFOHEADER bmih; BMPINFO bmi; HPS hps; char *pchTemp; char *xptr, *aptr; int maxx, maxy; int i, run, pad; WMcursor *pResult; maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER); maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER); // Check for max size! if ((w>maxx) || (h>maxy)) return (WMcursor *) NULL; pResult = (WMcursor *) SDL_malloc(sizeof(WMcursor)); if (!pResult) return (WMcursor *) NULL; pchTemp = (char *) SDL_malloc((maxx + 7)/8 * maxy*2); if (!pchTemp) { SDL_free(pResult); return (WMcursor *) NULL; } SDL_memset(pchTemp, 0, (maxx + 7)/8 * maxy*2); hps = WinGetPS(_this->hidden->hwndClient); bmi.cbFix = sizeof(BITMAPINFOHEADER); bmi.cx = maxx; bmi.cy = 2*maxy; bmi.cPlanes = 1; bmi.cBitCount = 1; bmi.argbColor[0].bBlue = 0x00; bmi.argbColor[0].bGreen = 0x00; bmi.argbColor[0].bRed = 0x00; bmi.argbColor[1].bBlue = 0x00; bmi.argbColor[1].bGreen = 0x00; bmi.argbColor[1].bRed = 0xff; SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); bmih.cbFix = sizeof(BITMAPINFOHEADER); bmih.cx = maxx; bmih.cy = 2*maxy; bmih.cPlanes = 1; bmih.cBitCount = 1; run = (w+7)/8; pad = (maxx+7)/8 - run; for (i=0; i<h; i++) { xptr = pchTemp + (maxx+7)/8 * (maxy-1-i); aptr = pchTemp + (maxx+7)/8 * (maxy+maxy-1-i); memxor(xptr, data, mask, run); xptr += run; data += run; memnot(aptr, mask, run); mask += run; aptr += run; SDL_memset(xptr, 0, pad); xptr += pad; SDL_memset(aptr, ~0, pad); aptr += pad; } pad += run; for (i=h ; i<maxy; i++ ) { xptr = pchTemp + (maxx+7)/8 * (maxy-1-i); aptr = pchTemp + (maxx+7)/8 * (maxy+maxy-1-i); SDL_memset(xptr, 0, (maxx+7)/8); xptr += (maxx+7)/8; SDL_memset(aptr, ~0, (maxx+7)/8); aptr += (maxx+7)/8; } hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT, (PBYTE) pchTemp, (PBITMAPINFO2)&bmi); hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, hot_x, maxy - hot_y - 1);#ifdef DEBUG_BUILD printf("HotSpot : %d ; %d\n", hot_x, hot_y); printf("HPS returned : %x\n", (ULONG)hps); printf("HBITMAP returned : %x\n", (ULONG)hbm); printf("HPOINTER returned: %x\n", (ULONG)hptr);#endif WinReleasePS(hps);#ifdef DEBUG_BUILD printf("[CreateWMCursor] : ptr = %p\n", hptr); fflush(stdout);#endif pResult->hptr = hptr; pResult->hbm = hbm; pResult->pchData = pchTemp;#ifdef DEBUG_BUILD printf("[CreateWMCursor] : ptr = %p return.\n", hptr); fflush(stdout);#endif return (WMcursor *) pResult;}WMcursor *os2fslib_CreateWMCursor_FS(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y){#ifdef DEBUG_BUILD printf("[CreateWMCursor_FS] : returning pointer NULL\n"); fflush(stdout);#endif // In FS mode we'll use software cursor return (WMcursor *) NULL;}/* Show the specified cursor, or hide if cursor is NULL */int os2fslib_ShowWMCursor(_THIS, WMcursor *cursor){#ifdef DEBUG_BUILD printf("[ShowWMCursor] : ptr = %p\n", cursor); fflush(stdout);#endif if (cursor) { WinSetPointer(HWND_DESKTOP, cursor->hptr); hptrGlobalPointer = cursor->hptr; _this->hidden->iMouseVisible = 1; } else { WinSetPointer(HWND_DESKTOP, FALSE); hptrGlobalPointer = NULL; _this->hidden->iMouseVisible = 0; }#ifdef DEBUG_BUILD printf("[ShowWMCursor] : ptr = %p, DONE\n", cursor); fflush(stdout);#endif return 1;}/* Warp the window manager cursor to (x,y) If NULL, a mouse motion event is posted internally. */void os2fslib_WarpWMCursor(_THIS, Uint16 x, Uint16 y){ LONG lx, ly; SWP swpClient; POINTL ptlPoints; WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); ptlPoints.x = swpClient.x; ptlPoints.y = swpClient.y; WinMapWindowPoints(_this->hidden->hwndFrame, HWND_DESKTOP, &ptlPoints, 1); lx = ptlPoints.x + (x*swpClient.cx) / _this->hidden->SrcBufferDesc.uiXResolution; ly = ptlPoints.y + swpClient.cy - ((y*swpClient.cy) / _this->hidden->SrcBufferDesc.uiYResolution) - 1; SDL_PrivateMouseMotion(0, // Buttons not changed 0, // Absolute position x, y); WinSetPointerPos(HWND_DESKTOP, lx, ly);}/* If not NULL, this is called when a mouse motion event occurs */void os2fslib_MoveWMCursor(_THIS, int x, int y){ /* SDL_Rect rect;#ifdef DEBUG_BUILD printf("[MoveWMCursor] : at %d ; %d\n", x, y); fflush(stdout);#endif rect.x = x; rect.y = y; rect.w = 32; rect.h = 32; os2fslib_UpdateRects(_this, 1, &rect); // TODO! */}/* Determine whether the mouse should be in relative mode or not. This function is called when the input grab state or cursor visibility state changes. If the cursor is not visible, and the input is grabbed, the driver can place the mouse in relative mode, which may result in higher accuracy sampling of the pointer motion. */void os2fslib_CheckMouseMode(_THIS){}static void os2fslib_PumpEvents(_THIS){ // Notify SDL that if window has been resized! if ( (_this->hidden->pSDLSurface) && (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) && ( (_this->hidden->SrcBufferDesc.uiXResolution!=iWindowSizeX) || (_this->hidden->SrcBufferDesc.uiYResolution!=iWindowSizeY) ) && (iWindowSizeX>0) && (iWindowSizeY>0) ) { static time_t prev_time; time_t curr_time; curr_time = time(NULL); if ((difftime(curr_time, prev_time)>=0.25) || (bWindowResized)) { // Make sure we won't flood the event queue with resize events, // only send them at 250 msecs! // (or when the window is resized)#ifdef DEBUG_BUILD printf("[os2fslib_PumpEvents] : Calling PrivateResize (%d %d).\n", iWindowSizeX, iWindowSizeY); fflush(stdout);#endif // Tell SDL the new size SDL_PrivateResize(iWindowSizeX, iWindowSizeY); prev_time = curr_time; bWindowResized = 0; } }}/* We don't actually allow hardware surfaces other than the main one */static int os2fslib_AllocHWSurface(_THIS, SDL_Surface *surface){ return(-1);}static void os2fslib_FreeHWSurface(_THIS, SDL_Surface *surface){ return;}/* We need to wait for vertical retrace on page flipped displays */static int os2fslib_LockHWSurface(_THIS, SDL_Surface *surface){ return(0);}static void os2fslib_UnlockHWSurface(_THIS, SDL_Surface *surface){ return;}static int os2fslib_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors){ printf("[os2fslib_SetColors] : TODO!\n"); fflush(stdout); // TODO: Implement paletted modes return(1);}static void os2fslib_DestroyIcon(HWND hwndFrame){ if (hptrCurrentIcon) { WinDestroyPointer(hptrCurrentIcon); hptrCurrentIcon = NULL; WinSendMsg(hwndFrame, WM_SETICON, NULL, NULL); }}/* Set the window icon image */void os2fslib_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask){ HWND hwndFrame; SDL_Surface *icon_rgb; HPOINTER hptrIcon; HBITMAP hbm; BITMAPINFOHEADER bmih; BMPINFO bmi; HPS hps; char *pchTemp; char *pptr, *mptr, *dptr, *dmptr; int maxx, maxy, w, h, x, y; SDL_Rect bounds;#ifdef DEBUG_BUILD printf("[os2fslib_SetIcon] : Creating and setting new icon\n"); fflush(stdout);#endif hwndFrame = WinQueryWindow(_this->hidden->hwndClient, QW_PARENT); // Make sure the old icon resource will be free'd! os2fslib_DestroyIcon(hwndFrame); if ((!icon) || (!mask)) return; w = icon->w; h = icon->h; maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXICON); maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYICON); // Check for max size! if ((w>maxx) || (h>maxy)) return; pchTemp = (char *) SDL_malloc(w * h*2 * 4); if (!pchTemp) return; SDL_memset(pchTemp, 0, w * h*2 * 4); // Convert surface to RGB, if it's not RGB yet! icon_rgb = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h, 32, 0, 0, 0, 0); if ( icon_rgb == NULL ) { SDL_free(pchTemp); return; } bounds.x = 0; bounds.y = 0; bounds.w = icon->w; bounds.h = icon->h; if ( SDL_LowerBlit(icon, &bounds, icon_rgb, &bounds) < 0 ) { SDL_FreeSurface(icon_rgb); SDL_free(pchTemp); return; } /* Copy pixels upside-down from RGB surface into BMP, masked with the icon mask */ // Pixels pptr = (char *) (icon_rgb->pixels); // Mask mptr = mask; for (y=0; y<h; y++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -