| #include <assert.h> |
| #include <stdlib.h> |
| #include "egldisplay.h" |
| #include "egldriver.h" |
| #include "eglmode.h" |
| #include "eglglobals.h" |
| #include "eglscreen.h" |
| |
| |
| #define MIN2(A, B) (((A) < (B)) ? (A) : (B)) |
| |
| |
| /** |
| * Given an EGLModeMESA handle, return the corresponding _EGLMode object |
| * or null if non-existant. |
| */ |
| _EGLMode * |
| _eglLookupMode(EGLDisplay dpy, EGLModeMESA mode) |
| { |
| const _EGLDisplay *disp = _eglLookupDisplay(dpy); |
| EGLint scrnum; |
| |
| /* loop over all screens on the display */ |
| for (scrnum = 0; scrnum < disp->NumScreens; scrnum++) { |
| const _EGLScreen *scrn = disp->Screens[scrnum]; |
| EGLint i; |
| /* search list of modes for handle */ |
| for (i = 0; i < scrn->NumModes; i++) { |
| if (scrn->Modes[i].Handle == mode) { |
| return scrn->Modes + i; |
| } |
| } |
| } |
| |
| return NULL; |
| } |
| |
| |
| /** |
| * Add a new mode with the given attributes (width, height, depth, refreshRate) |
| * to the given screen. |
| * Assign a new mode ID/handle to the mode as well. |
| * \return pointer to the new _EGLMode |
| */ |
| _EGLMode * |
| _eglAddMode(_EGLScreen *screen, EGLint width, EGLint height, |
| EGLint depth, EGLint refreshRate) |
| { |
| EGLint n; |
| _EGLMode *newModes; |
| |
| assert(screen); |
| assert(width > 0); |
| assert(height > 0); |
| assert(depth > 0); |
| assert(refreshRate > 0); |
| |
| n = screen->NumModes; |
| newModes = (_EGLMode *) realloc(screen->Modes, (n+1) * sizeof(_EGLMode)); |
| if (newModes) { |
| screen->Modes = newModes; |
| screen->Modes[n].Handle = n + 1; |
| screen->Modes[n].Width = width; |
| screen->Modes[n].Height = height; |
| screen->Modes[n].Depth = depth; |
| screen->Modes[n].RefreshRate = refreshRate; |
| screen->Modes[n].Stereo = EGL_FALSE; |
| screen->NumModes++; |
| return screen->Modes + n; |
| } |
| else { |
| return NULL; |
| } |
| } |
| |
| |
| |
| /** |
| * Search for the EGLMode that best matches the given attribute list. |
| */ |
| EGLBoolean |
| _eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, |
| const EGLint *attrib_list, EGLModeMESA *modes, |
| EGLint modes_size, EGLint *num_modes) |
| { |
| EGLint i; |
| |
| /* XXX incomplete */ |
| |
| for (i = 0; attrib_list[i] != EGL_NONE; i++) { |
| switch (attrib_list[i]) { |
| case EGL_WIDTH: |
| i++; |
| break; |
| case EGL_HEIGHT: |
| i++; |
| break; |
| case EGL_REFRESH_RATE_MESA: |
| i++; |
| break; |
| #if 0 |
| case EGL_STEREO_MESA: |
| i++; |
| break; |
| #endif |
| default: |
| _eglError(EGL_BAD_ATTRIBUTE, "eglChooseMode"); |
| return EGL_FALSE; |
| } |
| } |
| |
| return EGL_TRUE; |
| } |
| |
| |
| |
| /** |
| * Return all possible modes for the given screen |
| */ |
| EGLBoolean |
| _eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, |
| EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes) |
| { |
| _EGLScreen *scrn = _eglLookupScreen(dpy, screen); |
| EGLint i; |
| |
| if (!scrn) { |
| _eglError(EGL_BAD_SCREEN_MESA, "eglGetModes"); |
| return EGL_FALSE; |
| } |
| |
| *num_modes = MIN2(modes_size, scrn->NumModes); |
| for (i = 0; i < *num_modes; i++) { |
| modes[i] = scrn->Modes[i].Handle; |
| } |
| |
| return EGL_TRUE; |
| } |
| |
| |
| /** |
| * Query an attribute of a mode. |
| */ |
| EGLBoolean |
| _eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, |
| EGLModeMESA mode, EGLint attribute, EGLint *value) |
| { |
| _EGLMode *m = _eglLookupMode(dpy, mode); |
| |
| switch (attribute) { |
| case EGL_MODE_ID_MESA: |
| *value = m->Handle; |
| break; |
| case EGL_WIDTH: |
| *value = m->Width; |
| break; |
| case EGL_HEIGHT: |
| *value = m->Height; |
| break; |
| #if 0 |
| case EGL_DEPTH_MESA: |
| *value = m->Depth; |
| break; |
| #endif |
| case EGL_REFRESH_RATE_MESA: |
| *value = m->RefreshRate; |
| break; |
| #if 0 |
| case EGL_STEREO_MESA: |
| *value = m->Stereo; |
| break; |
| #endif |
| default: |
| _eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttrib"); |
| return EGL_FALSE; |
| } |
| return EGL_TRUE; |
| } |