Atlas - SDL_DirectFB_window.c
Home / ext / SDL2 / src / video / directfb Lines: 1 | Size: 18309 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "../../SDL_internal.h" 22 23#if SDL_VIDEO_DRIVER_DIRECTFB 24 25#include "SDL_DirectFB_video.h" 26#include "SDL_DirectFB_modes.h" 27#include "SDL_DirectFB_window.h" 28#include "SDL_DirectFB_shape.h" 29 30#if SDL_DIRECTFB_OPENGL 31#include "SDL_DirectFB_opengl.h" 32#endif 33 34#include "SDL_syswm.h" 35 36#include "../SDL_pixels_c.h" 37 38int 39DirectFB_CreateWindow(_THIS, SDL_Window * window) 40{ 41 SDL_DFB_DEVICEDATA(_this); 42 SDL_DFB_DISPLAYDATA(window); 43 DFB_WindowData *windata = NULL; 44 DFBWindowOptions wopts; 45 DFBWindowDescription desc; 46 int x, y; 47 int bshaped = 0; 48 49 SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData)); 50 SDL_memset(&desc, 0, sizeof(DFBWindowDescription)); 51 windata = (DFB_WindowData *) window->driverdata; 52 53 windata->is_managed = devdata->has_own_wm; 54#if 1 55 SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb, 56 DFSCL_NORMAL)); 57 SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer, 58 DLSCL_ADMINISTRATIVE)); 59#endif 60 /* FIXME ... ughh, ugly */ 61 if (window->x == -1000 && window->y == -1000) 62 bshaped = 1; 63 64 /* Fill the window description. */ 65 x = window->x; 66 y = window->y; 67 68 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); 69 70 /* Create Window */ 71 desc.caps = 0; 72 desc.flags = 73 DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS; 74 75 if (bshaped) { 76 desc.flags |= DWDESC_CAPS; 77 desc.caps |= DWCAPS_ALPHACHANNEL; 78 } 79 else 80 { 81 desc.flags |= DWDESC_PIXELFORMAT; 82 } 83 84 if (!(window->flags & SDL_WINDOW_BORDERLESS)) 85 desc.caps |= DWCAPS_NODECORATION; 86 87 desc.posx = x; 88 desc.posy = y; 89 desc.width = windata->size.w; 90 desc.height = windata->size.h; 91 desc.pixelformat = dispdata->pixelformat; 92 desc.surface_caps = DSCAPS_PREMULTIPLIED; 93#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6 94 if (window->flags & SDL_WINDOW_OPENGL) { 95 desc.surface_caps |= DSCAPS_GL; 96 } 97#endif 98 99 /* Create the window. */ 100 SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc, 101 &windata->dfbwin)); 102 103 /* Set Options */ 104 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); 105 106 /* explicit rescaling of surface */ 107 wopts |= DWOP_SCALE; 108 if (window->flags & SDL_WINDOW_RESIZABLE) { 109 wopts &= ~DWOP_KEEP_SIZE; 110 } 111 else { 112 wopts |= DWOP_KEEP_SIZE; 113 } 114 115 if (window->flags & SDL_WINDOW_FULLSCREEN) { 116 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE; 117 SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER)); 118 } 119 120 if (bshaped) { 121 wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL; 122 wopts &= ~DWOP_OPAQUE_REGION; 123 } 124 125 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); 126 127 /* See what we got */ 128 SDL_DFB_CHECK(DirectFB_WM_GetClientSize 129 (_this, window, &window->w, &window->h)); 130 131 /* Get the window's surface. */ 132 SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin, 133 &windata->window_surface)); 134 135 /* And get a subsurface for rendering */ 136 SDL_DFB_CHECKERR(windata->window_surface-> 137 GetSubSurface(windata->window_surface, &windata->client, 138 &windata->surface)); 139 140 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF)); 141 142 /* Create Eventbuffer */ 143 144 SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin, 145 &windata-> 146 eventbuffer)); 147 SDL_DFB_CHECKERR(windata->dfbwin-> 148 EnableEvents(windata->dfbwin, DWET_ALL)); 149 150 /* Create a font */ 151 /* FIXME: once during Video_Init */ 152 windata->font = NULL; 153 154 /* Make it the top most window. */ 155 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin)); 156 157 /* remember parent */ 158 /* windata->sdlwin = window; */ 159 160 /* Add to list ... */ 161 162 windata->next = devdata->firstwin; 163 windata->opacity = 0xFF; 164 devdata->firstwin = window; 165 166 /* Draw Frame */ 167 DirectFB_WM_RedrawLayout(_this, window); 168 169 return 0; 170 error: 171 SDL_DFB_RELEASE(windata->surface); 172 SDL_DFB_RELEASE(windata->dfbwin); 173 return -1; 174} 175 176int 177DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) 178{ 179 return SDL_Unsupported(); 180} 181 182void 183DirectFB_SetWindowTitle(_THIS, SDL_Window * window) 184{ 185 SDL_DFB_WINDOWDATA(window); 186 187 if (windata->is_managed) { 188 windata->wm_needs_redraw = 1; 189 DirectFB_WM_RedrawLayout(_this, window); 190 } else { 191 SDL_Unsupported(); 192 } 193} 194 195void 196DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) 197{ 198 SDL_DFB_DEVICEDATA(_this); 199 SDL_DFB_WINDOWDATA(window); 200 SDL_Surface *surface = NULL; 201 202 if (icon) { 203 SDL_PixelFormat format; 204 DFBSurfaceDescription dsc; 205 Uint32 *dest; 206 Uint32 *p; 207 int pitch, i; 208 209 /* Convert the icon to ARGB for modern window managers */ 210 SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888); 211 surface = SDL_ConvertSurface(icon, &format, 0); 212 if (!surface) { 213 return; 214 } 215 dsc.flags = 216 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; 217 dsc.caps = DSCAPS_VIDEOONLY; 218 dsc.width = surface->w; 219 dsc.height = surface->h; 220 dsc.pixelformat = DSPF_ARGB; 221 222 SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, 223 &windata->icon)); 224 225 SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE, 226 (void *) &dest, &pitch)); 227 228 p = surface->pixels; 229 for (i = 0; i < surface->h; i++) 230 memcpy((char *) dest + i * pitch, 231 (char *) p + i * surface->pitch, 4 * surface->w); 232 233 SDL_DFB_CHECK(windata->icon->Unlock(windata->icon)); 234 SDL_FreeSurface(surface); 235 } else { 236 SDL_DFB_RELEASE(windata->icon); 237 } 238 return; 239 error: 240 SDL_FreeSurface(surface); 241 SDL_DFB_RELEASE(windata->icon); 242 return; 243} 244 245void 246DirectFB_SetWindowPosition(_THIS, SDL_Window * window) 247{ 248 SDL_DFB_WINDOWDATA(window); 249 int x, y; 250 251 x = window->x; 252 y = window->y; 253 254 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); 255 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y)); 256} 257 258void 259DirectFB_SetWindowSize(_THIS, SDL_Window * window) 260{ 261 SDL_DFB_WINDOWDATA(window); 262 263 if(SDL_IsShapedWindow(window)) 264 DirectFB_ResizeWindowShape(window); 265 266 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { 267 int cw; 268 int ch; 269 270 /* Make sure all events are disabled for this operation ! */ 271 SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin, 272 DWET_ALL)); 273 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch)); 274 275 if (cw != window->w || ch != window->h) { 276 277 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); 278 SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin, 279 windata->size.w, 280 windata->size.h)); 281 } 282 283 SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize 284 (_this, window, &window->w, &window->h)); 285 DirectFB_AdjustWindowSurface(window); 286 287 SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin, 288 DWET_ALL)); 289 290 } 291 return; 292 error: 293 SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL)); 294 return; 295} 296 297void 298DirectFB_ShowWindow(_THIS, SDL_Window * window) 299{ 300 SDL_DFB_WINDOWDATA(window); 301 302 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity)); 303 304} 305 306void 307DirectFB_HideWindow(_THIS, SDL_Window * window) 308{ 309 SDL_DFB_WINDOWDATA(window); 310 311 SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity)); 312 SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0)); 313} 314 315void 316DirectFB_RaiseWindow(_THIS, SDL_Window * window) 317{ 318 SDL_DFB_WINDOWDATA(window); 319 320 SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin)); 321 SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin)); 322} 323 324void 325DirectFB_MaximizeWindow(_THIS, SDL_Window * window) 326{ 327 SDL_DFB_WINDOWDATA(window); 328 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); 329 DFBWindowOptions wopts; 330 331 SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin, 332 &windata->restore.x, &windata->restore.y)); 333 SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w, 334 &windata->restore.h)); 335 336 DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ; 337 338 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0)); 339 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, 340 display->current_mode.w, display->current_mode.h)); 341 342 /* Set Options */ 343 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); 344 wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION; 345 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); 346} 347 348void 349DirectFB_MinimizeWindow(_THIS, SDL_Window * window) 350{ 351 /* FIXME: Size to 32x32 ? */ 352 353 SDL_Unsupported(); 354} 355 356void 357DirectFB_RestoreWindow(_THIS, SDL_Window * window) 358{ 359 SDL_DFB_WINDOWDATA(window); 360 DFBWindowOptions wopts; 361 362 /* Set Options */ 363 SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); 364 wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION); 365 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); 366 367 /* Window layout */ 368 DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED), 369 windata->restore.w, windata->restore.h); 370 SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w, 371 windata->restore.h)); 372 SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x, 373 windata->restore.y)); 374 375 if (!(window->flags & SDL_WINDOW_RESIZABLE)) 376 wopts |= DWOP_KEEP_SIZE; 377 378 if (window->flags & SDL_WINDOW_FULLSCREEN) 379 wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE; 380 SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); 381 382 383} 384 385void 386DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) 387{ 388 SDL_DFB_DEVICEDATA(_this); 389 SDL_DFB_WINDOWDATA(window); 390 DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL); 391 392 if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) { 393 if (gwindata != NULL) 394 { 395 SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin)); 396 SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin)); 397 } 398 SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin)); 399 SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin)); 400 devdata->grabbed_window = window; 401 } else { 402 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); 403 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); 404 devdata->grabbed_window = NULL; 405 } 406} 407 408void 409DirectFB_DestroyWindow(_THIS, SDL_Window * window) 410{ 411 SDL_DFB_DEVICEDATA(_this); 412 SDL_DFB_WINDOWDATA(window); 413 DFB_WindowData *p; 414 415 /* Some cleanups */ 416 SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); 417 SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); 418 419#if SDL_DIRECTFB_OPENGL 420 DirectFB_GL_DestroyWindowContexts(_this, window); 421#endif 422 423 if (window->shaper) 424 { 425 SDL_ShapeData *data = window->shaper->driverdata; 426 SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface)); 427 SDL_DFB_RELEASE(data->surface); 428 SDL_DFB_FREE(data); 429 SDL_DFB_FREE(window->shaper); 430 } 431 432 SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL)); 433 SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface)); 434 SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface)); 435 SDL_DFB_RELEASE(windata->icon); 436 SDL_DFB_RELEASE(windata->font); 437 SDL_DFB_RELEASE(windata->eventbuffer); 438 SDL_DFB_RELEASE(windata->surface); 439 SDL_DFB_RELEASE(windata->window_surface); 440 441 SDL_DFB_RELEASE(windata->dfbwin); 442 443 /* Remove from list ... */ 444 445 p = devdata->firstwin->driverdata; 446 447 while (p && p->next != window) 448 p = (p->next ? p->next->driverdata : NULL); 449 if (p) 450 p->next = windata->next; 451 else 452 devdata->firstwin = windata->next; 453 SDL_free(windata); 454 return; 455} 456 457SDL_bool 458DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, 459 struct SDL_SysWMinfo * info) 460{ 461 const Uint32 version = ((((Uint32) info->version.major) * 1000000) + 462 (((Uint32) info->version.minor) * 10000) + 463 (((Uint32) info->version.patch))); 464 465 SDL_DFB_DEVICEDATA(_this); 466 SDL_DFB_WINDOWDATA(window); 467 468 /* Before 2.0.6, it was possible to build an SDL with DirectFB support 469 (SDL_SysWMinfo will be large enough to hold DirectFB info), but build 470 your app against SDL headers that didn't have DirectFB support 471 (SDL_SysWMinfo could be smaller than DirectFB needs. This would lead 472 to an app properly using SDL_GetWindowWMInfo() but we'd accidentally 473 overflow memory on the stack or heap. To protect against this, we've 474 padded out the struct unconditionally in the headers and DirectFB will 475 just return an error for older apps using this function. Those apps 476 will need to be recompiled against newer headers or not use DirectFB, 477 maybe by forcing SDL_VIDEODRIVER=x11. */ 478 if (version < 2000006) { 479 info->subsystem = SDL_SYSWM_UNKNOWN; 480 SDL_SetError("Version must be 2.0.6 or newer"); 481 return SDL_FALSE; 482 } 483 484 if (info->version.major == SDL_MAJOR_VERSION && 485 info->version.minor == SDL_MINOR_VERSION) { 486 info->subsystem = SDL_SYSWM_DIRECTFB; 487 info->info.dfb.dfb = devdata->dfb; 488 info->info.dfb.window = windata->dfbwin; 489 info->info.dfb.surface = windata->surface; 490 return SDL_TRUE; 491 } else { 492 SDL_SetError("Application not compiled with SDL %d.%d", 493 SDL_MAJOR_VERSION, SDL_MINOR_VERSION); 494 return SDL_FALSE; 495 } 496} 497 498void 499DirectFB_AdjustWindowSurface(SDL_Window * window) 500{ 501 SDL_DFB_WINDOWDATA(window); 502 int adjust = windata->wm_needs_redraw; 503 int cw, ch; 504 505 DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); 506 507 SDL_DFB_CHECKERR(windata-> 508 window_surface->GetSize(windata->window_surface, &cw, 509 &ch)); 510 if (cw != windata->size.w || ch != windata->size.h) { 511 adjust = 1; 512 } 513 514 if (adjust) { 515#if SDL_DIRECTFB_OPENGL 516 DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window); 517#endif 518 519#if (DFB_VERSION_ATLEAST(1,2,1)) 520 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin, 521 windata->size.w, 522 windata->size.h)); 523 SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface, 524 windata-> 525 window_surface, 526 &windata->client)); 527#else 528 DFBWindowOptions opts; 529 530 SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts)); 531 /* recreate subsurface */ 532 SDL_DFB_RELEASE(windata->surface); 533 534 if (opts & DWOP_SCALE) 535 SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin, 536 windata->size.w, 537 windata->size.h)); 538 SDL_DFB_CHECKERR(windata->window_surface-> 539 GetSubSurface(windata->window_surface, 540 &windata->client, &windata->surface)); 541#endif 542 DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window); 543 544#if SDL_DIRECTFB_OPENGL 545 DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window); 546#endif 547 } 548 error: 549 return; 550} 551 552int 553DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) 554{ 555 const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f)); 556 SDL_DFB_WINDOWDATA(window); 557 SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha)); 558 windata->opacity = alpha; 559 return 0; 560 561error: 562 return -1; 563} 564 565#endif /* SDL_VIDEO_DRIVER_DIRECTFB */ 566[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.