view src/video/x11/SDL_x11modes.c @ 3099:82e60908fab1

Date: Mon, 23 Mar 2009 09:17:24 +0200 From: "Mike Gorchak" Subject: New QNX patches Please apply patch qnx4.diff, which is attached. What has been done: 1)Added back OpenGL ES renderer for QNX target. Added few corrections to OpenGL ES renderer to let it work under QNX. OpenGL ES renderer do not support textures under QNX, so I think some additional work must be done. 2) Added GL_OES_query_matrix extension to SDL_opengles.h header file, which required by OpenGL ES 1.1 specification. 3) Added attribute clearing at the entrance of function SDL_GL_GetAttribure(). Added error checking into the function SDL_GL_GetAttribure(), because some attributes can't be obtained in OpenGL ES 1.0. 4) Porting testdyngles to OpenGL ES 1.0 (1.1 has glColor4ub() and glColor4f() functions, but 1.0 has glColor4f() only). 5) Added error checking after obtaining attributes using SDL_GL_GetAttribute() function to the testgl2 and testgles. 6) Small correction to testmultiaudio with printing errors. 7) Added software and accelerated OpenGL ES 1.0 support into the QNX GF driver. Please remove ./src/audio/nto directory - it will not be used anymore. Please create ./src/audio/qsa directory and add content of the archive qsa.tar.gz into this directory. I rewrote some sound code, added support for multiple audio cards, enumeration, etc. Added initial support for capture. As far as I can understand SDL 1.3 is not supporting audio capture right now ? Sam, Am I right ? Or audio capture must be supported through the PlayDevice routine ? And last, please put file SDL_gf_opengles.c to the ./src/video/qnxgf directory. It is OpenGL ES 1.1 emulation layer for some functions, which are not supported by OpenGL ES 1.0.
author Sam Lantinga <slouken@libsdl.org>
date Tue, 24 Mar 2009 10:33:12 +0000
parents ee331407574f
children 4b594623401b
line wrap: on
line source

/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#include "SDL_x11video.h"

//#define X11MODES_DEBUG
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
#undef SDL_VIDEO_DRIVER_X11_XRANDR
#undef SDL_VIDEO_DRIVER_X11_VIDMODE

static int
get_visualinfo(Display * display, int screen, XVisualInfo * vinfo)
{
    const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID");
    int depth;

    /* Look for an exact visual, if requested */
    if (visual_id) {
        XVisualInfo *vi, template;
        int nvis;

        SDL_zero(template);
        template.visualid = SDL_strtol(visual_id, NULL, 0);
        vi = XGetVisualInfo(display, VisualIDMask, &template, &nvis);
        if (vi) {
            *vinfo = *vi;
            XFree(vi);
            return 0;
        }
    }

    depth = DefaultDepth(display, screen);
    if ((X11_UseDirectColorVisuals() &&
         XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) ||
        XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) ||
        XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) ||
        XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) {
        return 0;
    }
    return -1;
}

static Uint32
X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo)
{
    if (vinfo->class == DirectColor || vinfo->class == TrueColor) {
        int bpp;
        Uint32 Rmask, Gmask, Bmask, Amask;

        Rmask = vinfo->visual->red_mask;
        Gmask = vinfo->visual->green_mask;
        Bmask = vinfo->visual->blue_mask;
        if (vinfo->depth == 32) {
            Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask));
        } else {
            Amask = 0;
        }

        bpp = vinfo->depth;
        if (bpp == 24) {
            int i, n;
            XPixmapFormatValues *p = XListPixmapFormats(display, &n);
            if (p) {
                for (i = 0; i < n; ++i) {
                    if (p[i].depth == 24) {
                        bpp = p[i].bits_per_pixel;
                        break;
                    }
                }
                XFree(p);
            }
        }

        return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
    }

    if (vinfo->class == PseudoColor || vinfo->class == StaticColor) {
        switch (vinfo->depth) {
        case 8:
            return SDL_PIXELTYPE_INDEX8;
        case 4:
            if (BitmapBitOrder(display) == LSBFirst) {
                return SDL_PIXELFORMAT_INDEX4LSB;
            } else {
                return SDL_PIXELFORMAT_INDEX4MSB;
            }
            break;
        case 1:
            if (BitmapBitOrder(display) == LSBFirst) {
                return SDL_PIXELFORMAT_INDEX1LSB;
            } else {
                return SDL_PIXELFORMAT_INDEX1MSB;
            }
            break;
        }
    }

    return SDL_PIXELFORMAT_UNKNOWN;
}

void
X11_InitModes(_THIS)
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    int screen;

    for (screen = 0; screen < ScreenCount(data->display); ++screen) {
        XVisualInfo vinfo;
        SDL_VideoDisplay display;
        SDL_DisplayData *displaydata;
        SDL_DisplayMode mode;
        XPixmapFormatValues *pixmapFormats;
        int i, n;

        if (get_visualinfo(data->display, screen, &vinfo) < 0) {
            continue;
        }

        mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo);
        mode.w = DisplayWidth(data->display, screen);
        mode.h = DisplayHeight(data->display, screen);
        mode.refresh_rate = 0;
        mode.driverdata = NULL;

        displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
        if (!displaydata) {
            continue;
        }
        displaydata->screen = screen;
        displaydata->visual = vinfo.visual;
        displaydata->depth = vinfo.depth;

        displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8;
        pixmapFormats = XListPixmapFormats(data->display, &n);
        if (pixmapFormats) {
            for (i = 0; i < n; ++i) {
                if (pixmapFormats[i].depth == displaydata->depth) {
                    displaydata->scanline_pad = pixmapFormats[i].scanline_pad;
                    break;
                }
            }
            XFree(pixmapFormats);
        }

        SDL_zero(display);
        display.desktop_mode = mode;
        display.current_mode = mode;
        display.driverdata = displaydata;
        SDL_AddVideoDisplay(&display);
    }
}

/* Global for the error handler */
int vm_event, vm_error = -1;

#if SDL_VIDEO_DRIVER_X11_XINERAMA
static SDL_bool
CheckXinerama(Display * display, int *major, int *minor)
{
    const char *env;

    /* Default the extension not available */
    *major = *minor = 0;

    /* Allow environment override */
    env = getenv("SDL_VIDEO_X11_XINERAMA");
    if (env && !SDL_atoi(env)) {
        return SDL_FALSE;
    }

    /* Query the extension version */
    if (!SDL_NAME(XineramaQueryExtension) (display, major, minor) ||
        !SDL_NAME(XineramaIsActive) (display)) {
        return SDL_FALSE;
    }
    return SDL_TRUE;
}
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */

#if SDL_VIDEO_DRIVER_X11_XRANDR
static SDL_bool
CheckXRandR(Display * display, int *major, int *minor)
{
    const char *env;

    /* Default the extension not available */
    *major = *minor = 0;

    /* Allow environment override */
    env = getenv("SDL_VIDEO_X11_XRANDR");
    if (env && !SDL_atoi(env)) {
        return SDL_FALSE;
    }

    if (!SDL_X11_HAVE_XRANDR) {
        return SDL_FALSE;
    }

    /* Query the extension version */
    if (!XRRQueryVersion(display, major, minor)) {
        return SDL_FALSE;
    }
    return SDL_TRUE;
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
static SDL_bool
CheckVidMode(Display * display, int *major, int *minor)
{
    const char *env;

    /* Default the extension not available */
    *major = *minor = 0;

    /* Allow environment override */
    env = getenv("SDL_VIDEO_X11_VIDMODE");
    if (env && !SDL_atoi(env)) {
        return SDL_FALSE;
    }

    /* Query the extension version */
    vm_error = -1;
    if (!SDL_NAME(XF86VidModeQueryExtension) (display, &vm_event, &vm_error)
        || !SDL_NAME(XF86VidModeQueryVersion) (display, major, minor)) {
        return SDL_FALSE;
    }
    return SDL_TRUE;
}

Bool SDL_NAME(XF86VidModeGetModeInfo) (Display * dpy, int scr,
                                       SDL_NAME(XF86VidModeModeInfo) * info)
{
    Bool retval;
    int dotclock;
    SDL_NAME(XF86VidModeModeLine) l;
    SDL_zerop(info);
    SDL_zero(l);
    retval = SDL_NAME(XF86VidModeGetModeLine) (dpy, scr, &dotclock, &l);
    info->dotclock = dotclock;
    info->hdisplay = l.hdisplay;
    info->hsyncstart = l.hsyncstart;
    info->hsyncend = l.hsyncend;
    info->htotal = l.htotal;
    info->hskew = l.hskew;
    info->vdisplay = l.vdisplay;
    info->vsyncstart = l.vsyncstart;
    info->vsyncend = l.vsyncend;
    info->vtotal = l.vtotal;
    info->flags = l.flags;
    info->privsize = l.privsize;
    info->private = l.private;
    return retval;
}

static int
calculate_rate(SDL_NAME(XF86VidModeModeInfo) * info)
{
    return (info->htotal
            && info->vtotal) ? (1000 * info->dotclock / (info->htotal *
                                                         info->vtotal)) : 0;
}

static void
save_mode(Display * display, SDL_DisplayData * data)
{
    SDL_NAME(XF86VidModeGetModeInfo) (display, data->screen,
                                      &data->saved_mode);
    SDL_NAME(XF86VidModeGetViewPort) (display, data->screen,
                                      &data->saved_view.x,
                                      &data->saved_view.y);
}

static void
restore_mode(Display * display, SDL_DisplayData * data)
{
    SDL_NAME(XF86VidModeModeInfo) mode;

    if (SDL_NAME(XF86VidModeGetModeInfo) (display, data->screen, &mode)) {
        if (SDL_memcmp(&mode, &data->saved_mode, sizeof(mode)) != 0) {
            SDL_NAME(XF86VidModeSwitchToMode) (display, data->screen,
                                               &data->saved_mode);
        }
    }
    if ((data->saved_view.x != 0) || (data->saved_view.y != 0)) {
        SDL_NAME(XF86VidModeSetViewPort) (display, data->screen,
                                          data->saved_view.x,
                                          data->saved_view.y);
    }
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

void
X11_GetDisplayModes(_THIS)
{
    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
    SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
#if SDL_VIDEO_DRIVER_X11_XINERAMA
    int xinerama_major, xinerama_minor;
    int screens;
    SDL_NAME(XineramaScreenInfo) * xinerama;
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
    int xrandr_major, xrandr_minor;
    int nsizes, nrates;
    XRRScreenSize *sizes;
    short *rates;
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
    int vm_major, vm_minor;
    int nmodes;
    SDL_NAME(XF86VidModeModeInfo) ** modes;
#endif
    int screen_w;
    int screen_h;
    SDL_DisplayMode mode;

    /* Unfortunately X11 requires the window to be created with the correct
     * visual and depth ahead of time, but the SDL API allows you to create
     * a window before setting the fullscreen display mode.  This means that
     * we have to use the same format for all windows and all display modes.
     * (or support recreating the window with a new visual behind the scenes)
     */
    mode.format = SDL_CurrentDisplay.current_mode.format;
    mode.driverdata = NULL;

    data->use_xinerama = 0;
    data->use_xrandr = 0;
    data->use_vidmode = 0;
    screen_w = DisplayWidth(display, data->screen);
    screen_h = DisplayHeight(display, data->screen);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    /* Query Xinerama extention */
    if (CheckXinerama(display, &xinerama_major, &xinerama_minor)) {
#ifdef X11MODES_DEBUG
        printf("X11 detected Xinerama:\n");
#endif
        xinerama = SDL_NAME(XineramaQueryScreens) (display, &screens);
        if (xinerama) {
            int i;
            for (i = 0; i < screens; i++) {
#ifdef X11MODES_DEBUG
                printf("xinerama %d: %dx%d+%d+%d\n",
                       xinerama[i].screen_number,
                       xinerama[i].width, xinerama[i].height,
                       xinerama[i].x_org, xinerama[i].y_org);
#endif
                if (xinerama[i].screen_number == data->screen) {
                    data->use_xinerama =
                        xinerama_major * 100 + xinerama_minor;
                    data->xinerama_info = xinerama[i];
                }
            }
            XFree(xinerama);
        }

        if (data->use_xinerama) {
            /* Add the full xinerama mode */
            if (screen_w > data->xinerama_info.width ||
                screen_h > data->xinerama_info.height) {
                mode.w = screen_w;
                mode.h = screen_h;
                mode.refresh_rate = 0;
                SDL_AddDisplayMode(_this->current_display, &mode);
            }

            /* Add the head xinerama mode */
            mode.w = data->xinerama_info.width;
            mode.h = data->xinerama_info.height;
            mode.refresh_rate = 0;
            SDL_AddDisplayMode(_this->current_display, &mode);
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */

#if SDL_VIDEO_DRIVER_X11_XRANDR
    /* XRandR */
    /* require at least XRandR v1.0 (arbitrary) */
    if (CheckXRandR(display, &xrandr_major, &xrandr_minor)
        && xrandr_major >= 1) {
#ifdef X11MODES_DEBUG
        fprintf(stderr, "XRANDR: XRRQueryVersion: V%d.%d\n",
                xrandr_major, xrandr_minor);
#endif

        /* save the screen configuration since we must reference it
           each time we toggle modes.
         */
        data->screen_config =
            XRRGetScreenInfo(display, RootWindow(display, data->screen));

        /* retrieve the list of resolution */
        sizes = XRRConfigSizes(data->screen_config, &nsizes);
        if (nsizes > 0) {
            int i, j;
            for (i = 0; i < nsizes; i++) {
                mode.w = sizes[i].width;
                mode.h = sizes[i].height;

                rates = XRRConfigRates(data->screen_config, i, &nrates);
                for (j = 0; j < nrates; ++j) {
                    mode.refresh_rate = rates[j];
#ifdef X11MODES_DEBUG
                    fprintf(stderr,
                            "XRANDR: mode = %4d[%d], w = %4d, h = %4d, rate = %4d\n",
                            i, j, mode.w, mode.h, mode.refresh_rate);
#endif
                    SDL_AddDisplayMode(_this->current_display, &mode);
                }
            }

            data->use_xrandr = xrandr_major * 100 + xrandr_minor;
            data->saved_size =
                XRRConfigCurrentConfiguration(data->screen_config,
                                              &data->saved_rotation);
            data->saved_rate = XRRConfigCurrentRate(data->screen_config);
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
    /* XVidMode */
    if (!data->use_xrandr &&
#if SDL_VIDEO_DRIVER_X11_XINERAMA
        (!data->use_xinerama || data->xinerama_info.screen_number == 0) &&
#endif
        CheckVidMode(display, &vm_major, &vm_minor) &&
        SDL_NAME(XF86VidModeGetAllModeLines) (display, data->screen, &nmodes,
                                              &modes)) {
        int i;

#ifdef X11MODES_DEBUG
        printf("VidMode modes: (unsorted)\n");
        for (i = 0; i < nmodes; ++i) {
            printf("Mode %d: %d x %d @ %d\n", i,
                   modes[i]->hdisplay, modes[i]->vdisplay,
                   calculate_rate(modes[i]));
        }
#endif
        for (i = 0; i < nmodes; ++i) {
            mode.w = modes[i]->hdisplay;
            mode.h = modes[i]->vdisplay;
            mode.refresh_rate = calculate_rate(modes[i]);
            SDL_AddDisplayMode(_this->current_display, &mode);
        }
        XFree(modes);

        data->use_vidmode = vm_major * 100 + vm_minor;
        save_mode(display, data);
    }
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

    if (!data->use_xrandr && !data->use_vidmode) {
        mode.w = screen_w;
        mode.h = screen_h;
        mode.refresh_rate = 0;
        SDL_AddDisplayMode(_this->current_display, &mode);
    }
#ifdef X11MODES_DEBUG
    if (data->use_xinerama) {
        printf("Xinerama is enabled\n");
    }

    if (data->use_xrandr) {
        printf("XRandR is enabled\n");
    }

    if (data->use_vidmode) {
        printf("VidMode is enabled\n");
    }
#endif /* X11MODES_DEBUG */
}

static void
get_real_resolution(Display * display, SDL_DisplayData * data, int *w, int *h,
                    int *rate)
{
#if SDL_VIDEO_DRIVER_X11_XRANDR
    if (data->use_xrandr) {
        int nsizes;
        XRRScreenSize *sizes;

        sizes = XRRConfigSizes(data->screen_config, &nsizes);
        if (nsizes > 0) {
            int cur_size;
            Rotation cur_rotation;

            cur_size =
                XRRConfigCurrentConfiguration(data->screen_config,
                                              &cur_rotation);
            *w = sizes[cur_size].width;
            *h = sizes[cur_size].height;
            *rate = XRRConfigCurrentRate(data->screen_config);
#ifdef X11MODES_DEBUG
            fprintf(stderr,
                    "XRANDR: get_real_resolution: w = %d, h = %d, rate = %d\n",
                    *w, *h, *rate);
#endif
            return;
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
    if (data->use_vidmode) {
        SDL_NAME(XF86VidModeModeInfo) mode;

        if (SDL_NAME(XF86VidModeGetModeInfo) (display, data->screen, &mode)) {
            *w = mode.hdisplay;
            *h = mode.vdisplay;
            *rate = calculate_rate(&mode);
            return;
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    if (data->use_xinerama) {
        *w = data->xinerama_info.width;
        *h = data->xinerama_info.height;
        *rate = 0;
        return;
    }
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */

    *w = DisplayWidth(display, data->screen);
    *h = DisplayHeight(display, data->screen);
    *rate = 0;
}

static void
set_best_resolution(Display * display, SDL_DisplayData * data, int w, int h,
                    int rate)
{
    int real_w, real_h, real_rate;

    /* check current mode so we can avoid uneccessary mode changes */
    get_real_resolution(display, data, &real_w, &real_h, &real_rate);
    if (w == real_w && h == real_h && (!rate || rate == real_rate)) {
        return;
    }
#if SDL_VIDEO_DRIVER_X11_XRANDR
    if (data->use_xrandr) {
#ifdef X11MODES_DEBUG
        fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n",
                w, h);
#endif
        int i, nsizes, nrates;
        int best;
        int best_rate;
        XRRScreenSize *sizes;
        short *rates;

        /* find the smallest resolution that is at least as big as the user requested */
        best = -1;
        sizes = XRRConfigSizes(data->screen_config, &nsizes);
        for (i = 0; i < nsizes; ++i) {
            if (sizes[i].width < w || sizes[i].height < h) {
                continue;
            }
            if (sizes[i].width == w && sizes[i].height == h) {
                best = i;
                break;
            }
            if (best == -1 ||
                (sizes[i].width < sizes[best].width) ||
                (sizes[i].width == sizes[best].width
                 && sizes[i].height < sizes[best].height)) {
                best = i;
            }
        }

        if (best >= 0) {
            best_rate = 0;
            rates = XRRConfigRates(data->screen_config, best, &nrates);
            for (i = 0; i < nrates; ++i) {
                if (rates[i] == rate) {
                    best_rate = rate;
                    break;
                }
                if (!rate) {
                    /* Higher is better, right? */
                    if (rates[i] > best_rate) {
                        best_rate = rates[i];
                    }
                } else {
                    if (SDL_abs(rates[i] - rate) < SDL_abs(best_rate - rate)) {
                        best_rate = rates[i];
                    }
                }
            }
            XRRSetScreenConfigAndRate(display, data->screen_config,
                                      RootWindow(display, data->screen), best,
                                      data->saved_rotation, best_rate,
                                      CurrentTime);
        }
        return;
    }
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
    if (data->use_vidmode) {
        SDL_NAME(XF86VidModeModeInfo) ** modes;
        int i, nmodes;
        int best;

        if (SDL_NAME(XF86VidModeGetAllModeLines)
            (display, data->screen, &nmodes, &modes)) {
            best = -1;
            for (i = 0; i < nmodes; ++i) {
                if (modes[i]->hdisplay < w || modes[i]->vdisplay < h) {
                    continue;
                }
                if (best == -1 ||
                    (modes[i]->hdisplay < modes[best]->hdisplay) ||
                    (modes[i]->hdisplay == modes[best]->hdisplay
                     && modes[i]->vdisplay < modes[best]->vdisplay)) {
                    best = i;
                    continue;
                }
                if ((modes[i]->hdisplay == modes[best]->hdisplay) &&
                    (modes[i]->vdisplay == modes[best]->vdisplay)) {
                    if (!rate) {
                        /* Higher is better, right? */
                        if (calculate_rate(modes[i]) >
                            calculate_rate(modes[best])) {
                            best = i;
                        }
                    } else {
                        if (SDL_abs(calculate_rate(modes[i]) - rate) <
                            SDL_abs(calculate_rate(modes[best]) - rate)) {
                            best = i;
                        }
                    }
                }
            }
            if (best >= 0) {
#ifdef X11MODES_DEBUG
                printf("Best Mode %d: %d x %d @ %d\n", best,
                       modes[best]->hdisplay, modes[best]->vdisplay,
                       calculate_rate(modes[best]));
#endif
                SDL_NAME(XF86VidModeSwitchToMode) (display, data->screen,
                                                   modes[best]);
            }
            XFree(modes);
        }
        return;
    }
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
}

int
X11_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
{
    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
    SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;

    set_best_resolution(display, data, mode->w, mode->h, mode->refresh_rate);
    return 0;
}

void
X11_QuitModes(_THIS)
{
}

/* vi: set ts=4 sw=4 expandtab: */