#include <assert.h> #include <stdlib.h> #include <string.h> #include "egldisplay.h" #include "egldriver.h" #include "eglmode.h" #include "eglglobals.h" #include "eglscreen.h" #define MIN2(A, B) (((A) < (B)) ? (A) : (B)) static char * my_strdup(const char *s) { int l = strlen(s); char *s2 = malloc(l + 1); strcpy(s2, s); return s2; } /** * 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 refreshRate, const char *name) { EGLint n; _EGLMode *newModes; assert(screen); assert(width > 0); assert(height > 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].RefreshRate = refreshRate; screen->Modes[n].Stereo = EGL_FALSE; screen->Modes[n].Name = my_strdup(name); 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; } const char * _eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode) { _EGLMode *m = _eglLookupMode(dpy, mode); return m->Name; }