text:
#include "SDL_config.h"

/* Utilities for getting and setting the X display mode */

#include <stdio.h>

#include "SDL_timer.h"
#include "SDL_events.h"
#include "../../events/SDL_events_c.h"
#include "SDL_x11video.h"
#include "SDL_x11wm_c.h"
#include "SDL_x11modes_c.h"
#include "SDL_x11image_c.h"

/*#define X11MODES_DEBUG*/

#define MAX(a, b)        (a > b ? a : b)

#if SDL_VIDEO_DRIVER_X11_XRANDR
static int cmpmodelist(const void *va, const void *vb)
{
    const SDL_Rect *a = *(const SDL_Rect **)va;
    const SDL_Rect *b = *(const SDL_Rect **)vb;
    if ( a->w == b->w )
        return b->h - a->h;
    else
        return b->w - a->w;
}
#endif

#if SDL_VIDEO_DRIVER_X11_VIDMODE
Bool SDL_NAME(XF86VidModeGetModeInfo)(Display *dpy, int scr, SDL_NAME(XF86VidModeModeInfo) *info)
{
    SDL_NAME(XF86VidModeModeLine) *l = (SDL_NAME(XF86VidModeModeLine)*)((char*)info + sizeof info->dotclock);
    return SDL_NAME(XF86VidModeGetModeLine)(dpy, scr, (int*)&info->dotclock, l);
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
static void save_mode(_THIS)
{
    SDL_memset(&saved_mode, 0, sizeof(saved_mode));
    SDL_NAME(XF86VidModeGetModeInfo)(SDL_Display,SDL_Screen,&saved_mode);
    SDL_NAME(XF86VidModeGetViewPort)(SDL_Display,SDL_Screen,&saved_view.x,&saved_view.y);
}
#endif

#if SDL_VIDEO_DRIVER_X11_VIDMODE
static void restore_mode(_THIS)
{
    SDL_NAME(XF86VidModeModeLine) mode;
    int unused;

    if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) {
        if ( (saved_mode.hdisplay != mode.hdisplay) ||
             (saved_mode.vdisplay != mode.vdisplay) ) {
            SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, &saved_mode);
        }
    }
    if ( (saved_view.x != 0) || (saved_view.y != 0) ) {
        SDL_NAME(XF86VidModeSetViewPort)(SDL_Display, SDL_Screen, saved_view.x, saved_view.y);
    }
}
#endif

#if SDL_VIDEO_DRIVER_X11_VIDMODE
static int cmpmodes(const void *va, const void *vb)
{
    const SDL_NAME(XF86VidModeModeInfo) *a = *(const SDL_NAME(XF86VidModeModeInfo)**)va;
    const SDL_NAME(XF86VidModeModeInfo) *b = *(const SDL_NAME(XF86VidModeModeInfo)**)vb;
    if ( a->hdisplay == b->hdisplay )
        return b->vdisplay - a->vdisplay;
    else
        return b->hdisplay - a->hdisplay;
}
#endif

static void get_real_resolution(_THIS, int* w, int* h);

static void set_best_resolution(_THIS, int width, int height)
{
#if SDL_VIDEO_DRIVER_X11_VIDMODE
    if ( use_vidmode ) {
        SDL_NAME(XF86VidModeModeLine) mode;
        SDL_NAME(XF86VidModeModeInfo) **modes;
        int i;
        int nmodes;
        int best = -1;

        if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &i, &mode) &&
             SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display,SDL_Screen,&nmodes,&modes) ) {
            for ( i = 0; i < nmodes ; i++ ) {
                if ( (modes[i]->hdisplay == width) &&
                     (modes[i]->vdisplay == height) ) {
                    best = i;
                    break;
                }
                if ( modes[i]->hdisplay >= width &&
                     modes[i]->vdisplay >= height ) {
                    if ( best < 0 ||
                         (modes[i]->hdisplay < modes[best]->hdisplay &&
                          modes[i]->vdisplay <= modes[best]->vdisplay) ||
                         (modes[i]->vdisplay < modes[best]->vdisplay &&
                          modes[i]->hdisplay <= modes[best]->hdisplay) ) {
                        best = i;
                    }
                }
            }
            if ( best >= 0 &&
                 ((modes[best]->hdisplay != mode.hdisplay) ||
                  (modes[best]->vdisplay != mode.vdisplay)) ) {
#ifdef X11MODES_DEBUG
                printf("Best Mode %d: %d x %d @ %d\n", best,
                        modes[best]->hdisplay, modes[best]->vdisplay,
                        (modes[best]->htotal && modes[best]->vtotal) ? (1000 * modes[best]->dotclock / (modes[best]->htotal * modes[best]->vtotal)) : 0 );
#endif
                SDL_NAME(XF86VidModeSwitchToMode)(SDL_Display, SDL_Screen, modes[best]);
            }
            XFree(modes);
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

                                /* XiG */
#if SDL_VIDEO_DRIVER_X11_XME
    if ( use_xme && SDL_modelist ) {
        int i;

#ifdef X11MODES_DEBUG
        fprintf(stderr, "XME: set_best_resolution(): w = %d, h = %d\n",
                width, height);
#endif
        for ( i=0; SDL_modelist[i]; ++i ) {
            if ( (SDL_modelist[i]->w >= width) &&
                 (SDL_modelist[i]->h >= height) ) {
                break;
            }
        }

        if ( SDL_modelist[i] ) { /* found one, lets try it */
            int w, h;

            /* check current mode so we can avoid uneccessary mode changes */
            get_real_resolution(this, &w, &h);

            if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
#ifdef X11MODES_DEBUG
                fprintf(stderr, "XME: set_best_resolution: "
                        "XiGMiscChangeResolution: %d %d\n",
                        SDL_modelist[i]->w, SDL_modelist[i]->h);
#endif
                XiGMiscChangeResolution(SDL_Display,
                                        SDL_Screen,
                                        0, /* view */
                                        SDL_modelist[i]->w,
                                        SDL_modelist[i]->h,
                                        0);
                XSync(SDL_Display, False);
            }
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XME */

#if SDL_VIDEO_DRIVER_X11_XRANDR
    if ( use_xrandr && SDL_modelist ) {
#ifdef X11MODES_DEBUG
        fprintf(stderr, "XRANDR: set_best_resolution(): w = %d, h = %d\n",
                width, height);
#endif
        int i, nsizes;
        XRRScreenSize *sizes;

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

        if ( i >= 0 && SDL_modelist[i] ) { /* found one, lets try it */
            int w, h;

            /* check current mode so we can avoid uneccessary mode changes */
            get_real_resolution(this, &w, &h);

            if ( (SDL_modelist[i]->w != w) || (SDL_modelist[i]->h != h) ) {
                int size_id;

#ifdef X11MODES_DEBUG
                fprintf(stderr, "XRANDR: set_best_resolution: "
                        "XXRSetScreenConfig: %d %d\n",
                        SDL_modelist[i]->w, SDL_modelist[i]->h);
#endif

                /* find the matching size entry index */
                for ( size_id = 0; size_id < nsizes; ++size_id ) {
                    if ( (sizes[size_id].width == SDL_modelist[i]->w) &&
                         (sizes[size_id].height == SDL_modelist[i]->h) )
                        break;
                }

                XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
                                   size_id, saved_rotation, CurrentTime);
            }
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
}

static void get_real_resolution(_THIS, int* w, int* h)
{
#if SDL_VIDEO_DRIVER_X11_XME
    if ( use_xme ) {
        int ractive;
        XiGMiscResolutionInfo *modelist;

        XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
                                0, /* view */
                                &ractive, &modelist);
        *w = modelist[ractive].width;
        *h = modelist[ractive].height;
#ifdef X11MODES_DEBUG
        fprintf(stderr, "XME: get_real_resolution: w = %d h = %d\n", *w, *h);
#endif
        XFree(modelist);
        return;
    }
#endif /* SDL_VIDEO_DRIVER_X11_XME */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
    if ( use_vidmode ) {
        SDL_NAME(XF86VidModeModeLine) mode;
        int unused;

        if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) {
            *w = mode.hdisplay;
            *h = mode.vdisplay;
            return;
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

#if SDL_VIDEO_DRIVER_X11_XRANDR
    if ( use_xrandr ) {
        int nsizes;
        XRRScreenSize* sizes;

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

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

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

    *w = DisplayWidth(SDL_Display, SDL_Screen);
    *h = DisplayHeight(SDL_Display, SDL_Screen);
}

/* Called after mapping a window - waits until the window is mapped */
void X11_WaitMapped(_THIS, Window win)
{
    XEvent event;
    do {
        XMaskEvent(SDL_Display, StructureNotifyMask, &event);
    } while ( (event.type != MapNotify) || (event.xmap.event != win) );
}

/* Called after unmapping a window - waits until the window is unmapped */
void X11_WaitUnmapped(_THIS, Window win)
{
    XEvent event;
    do {
        XMaskEvent(SDL_Display, StructureNotifyMask, &event);
    } while ( (event.type != UnmapNotify) || (event.xunmap.event != win) );
}

static void move_cursor_to(_THIS, int x, int y)
{
    XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y);
}

static int add_visual(_THIS, int depth, int class)
{
    XVisualInfo vi;
    if(XMatchVisualInfo(SDL_Display, SDL_Screen, depth, class, &vi)) {
        int n = this->hidden->nvisuals;
        this->hidden->visuals[n].depth = vi.depth;
        this->hidden->visuals[n].visual = vi.visual;
        this->hidden->nvisuals++;
    }
    return(this->hidden->nvisuals);
}
static int add_visual_byid(_THIS, const char *visual_id)
{
    XVisualInfo *vi, template;
    int nvis;

    if ( visual_id ) {
        SDL_memset(&template, 0, (sizeof template));
        template.visualid = SDL_strtol(visual_id, NULL, 0);
        vi = XGetVisualInfo(SDL_Display, VisualIDMask, &template, &nvis);
        if ( vi ) {
            int n = this->hidden->nvisuals;
            this->hidden->visuals[n].depth = vi->depth;
            this->hidden->visuals[n].visual = vi->visual;
            this->hidden->nvisuals++;
            XFree(vi);
        }
    }
    return(this->hidden->nvisuals);
}

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

#if SDL_VIDEO_DRIVER_X11_XINERAMA
static int CheckXinerama(_THIS, 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 0;
    }

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

#if SDL_VIDEO_DRIVER_X11_XRANDR
static int CheckXRandR(_THIS, 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 0;
    }

    /* This defaults off now, due to KDE window maximize problems */
    if ( !env ) {
        return 0;
    }

    if ( !SDL_X11_HAVE_XRANDR ) {
        return 0;
    }

    /* Query the extension version */
    if ( !XRRQueryVersion(SDL_Display, major, minor) ) {
        return 0;
    }
    return 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
static int CheckVidMode(_THIS, 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 0;
    }

    /* Metro-X 4.3.0 and earlier has a broken implementation of
       XF86VidModeGetAllModeLines() - it hangs the client.
     */
    if ( SDL_strcmp(ServerVendor(SDL_Display), "Metro Link Incorporated") == 0 ) {
        FILE *metro_fp;

        metro_fp = fopen("/usr/X11R6/lib/X11/Metro/.version", "r");
        if ( metro_fp != NULL ) {
            int major, minor, patch, version;
            major = 0; minor = 0; patch = 0;
            fscanf(metro_fp, "%d.%d.%d", &major, &minor, &patch);
            fclose(metro_fp);
            version = major*100+minor*10+patch;
            if ( version < 431 ) {
                return 0;
            }
        }
    }

    /* Query the extension version */
    vm_error = -1;
    if ( !SDL_NAME(XF86VidModeQueryExtension)(SDL_Display, &vm_event, &vm_error) ||
         !SDL_NAME(XF86VidModeQueryVersion)(SDL_Display, major, minor) ) {
        return 0;
    }
    return 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

#if SDL_VIDEO_DRIVER_X11_XME
static int CheckXME(_THIS, 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 0;
    }

    /* Query the extension version */
    if ( !XiGMiscQueryVersion(SDL_Display, major, minor) ) {
        return 0;
    }
    return 1;
}
#endif /* SDL_VIDEO_DRIVER_X11_XME */

int X11_GetVideoModes(_THIS)
{
#if SDL_VIDEO_DRIVER_X11_XINERAMA
    int xinerama_major, xinerama_minor;
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
    int xrandr_major, xrandr_minor;
    int nsizes;
    XRRScreenSize *sizes;
#endif
#if SDL_VIDEO_DRIVER_X11_VIDMODE
    int vm_major, vm_minor;
    int nmodes;
    SDL_NAME(XF86VidModeModeInfo) **modes;
#endif
#if SDL_VIDEO_DRIVER_X11_XME
    int xme_major, xme_minor;
    int ractive, nummodes;
    XiGMiscResolutionInfo *modelist;
#endif
    int i, n;
    int screen_w;
    int screen_h;

    use_xinerama = 0;
    use_xrandr = 0;
    use_vidmode = 0;
    use_xme = 0;
    screen_w = DisplayWidth(SDL_Display, SDL_Screen);
    screen_h = DisplayHeight(SDL_Display, SDL_Screen);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    /* Query Xinerama extention */
    if ( CheckXinerama(this, &xinerama_major, &xinerama_minor) ) {
        /* Find out which screen is the desired one */
        int desired = 0;
        int screens;
        int w, h;
        SDL_NAME(XineramaScreenInfo) *xinerama;

        const char *variable = SDL_getenv("SDL_VIDEO_FULLSCREEN_HEAD");
        if ( variable ) {
                desired = SDL_atoi(variable);
        }
#ifdef X11MODES_DEBUG
        printf("X11 detected Xinerama:\n");
#endif
        xinerama = SDL_NAME(XineramaQueryScreens)(SDL_Display, &screens);
        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 == desired ) {
                use_xinerama = 1;
                xinerama_info = xinerama[i];
            }
        }
        XFree(xinerama);

        if ( use_xinerama ) {
            SDL_modelist = (SDL_Rect **)SDL_malloc(3*sizeof(SDL_Rect *));
            if ( !SDL_modelist ) {
                SDL_OutOfMemory();
                return -1;
            }

            /* Add the full xinerama mode */
            n = 0;
            w = xinerama_info.width;
            h = xinerama_info.height;
            if ( screen_w > w || screen_h > h) {
                SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
                if ( SDL_modelist[n] ) {
                    SDL_modelist[n]->x = 0;
                    SDL_modelist[n]->y = 0;
                    SDL_modelist[n]->w = screen_w;
                    SDL_modelist[n]->h = screen_h;
                    ++n;
                }
            }

            /* Add the head xinerama mode */
            SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
            if ( SDL_modelist[n] ) {
                SDL_modelist[n]->x = 0;
                SDL_modelist[n]->y = 0;
                SDL_modelist[n]->w = w;
                SDL_modelist[n]->h = h;
                ++n;
            }
            SDL_modelist[n] = NULL;
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */

#if SDL_VIDEO_DRIVER_X11_XRANDR
    /* XRandR */
    /* require at least XRandR v1.0 (arbitrary) */
    if ( CheckXRandR(this, &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.
        */
        screen_config = XRRGetScreenInfo(SDL_Display, SDL_Root);

        /* retrieve the list of resolution */
        sizes = XRRConfigSizes(screen_config, &nsizes);
        if (nsizes > 0) {
            if ( SDL_modelist ) {
                for ( i = 0; SDL_modelist[i]; ++i ) {
                    SDL_free(SDL_modelist[i]);
                }
                SDL_free(SDL_modelist);
            }
            SDL_modelist = (SDL_Rect **)malloc((nsizes+1)*sizeof(SDL_Rect *));
            if ( !SDL_modelist ) {
                SDL_OutOfMemory();
                return -1;
            }
            for ( i=0; i < nsizes; i++ ) {
                if ((SDL_modelist[i] =
                     (SDL_Rect *)malloc(sizeof(SDL_Rect))) == NULL)
                    break;
#ifdef X11MODES_DEBUG
                fprintf(stderr, "XRANDR: mode = %4d, w = %4d, h = %4d\n",
                        i, sizes[i].width, sizes[i].height);
#endif

                SDL_modelist[i]->x = 0;
                SDL_modelist[i]->y = 0;
                SDL_modelist[i]->w = sizes[i].width;
                SDL_modelist[i]->h = sizes[i].height;

            }
            /* sort the mode list descending as SDL expects */
            SDL_qsort(SDL_modelist, nsizes, sizeof *SDL_modelist, cmpmodelist);
            SDL_modelist[i] = NULL; /* terminator */

            use_xrandr = xrandr_major * 100 + xrandr_minor;
            saved_size_id = XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

#if SDL_VIDEO_DRIVER_X11_VIDMODE
    /* XVidMode */
    if ( !use_xrandr &&
#if SDL_VIDEO_DRIVER_X11_XINERAMA
         (!use_xinerama || xinerama_info.screen_number == 0) &&
#endif
         CheckVidMode(this, &vm_major, &vm_minor) &&
         SDL_NAME(XF86VidModeGetAllModeLines)(SDL_Display, SDL_Screen,&nmodes,&modes) )
    {
#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,
                    (modes[i]->htotal && modes[i]->vtotal) ? (1000 * modes[i]->dotclock / (modes[i]->htotal * modes[i]->vtotal)) : 0 );
        }
#endif
        if ( SDL_modelist ) {
            for ( i = 0; SDL_modelist[i]; ++i ) {
                SDL_free(SDL_modelist[i]);
            }
            SDL_free(SDL_modelist);
        }
        SDL_modelist = (SDL_Rect **)SDL_malloc((nmodes+2)*sizeof(SDL_Rect *));
        if ( !SDL_modelist ) {
            SDL_OutOfMemory();
            return -1;
        }
        SDL_qsort(modes, nmodes, sizeof *modes, cmpmodes);
        n = 0;
        for ( i=0; i<nmodes; ++i ) {
            int w, h;

            /* Eliminate duplicate modes with different refresh rates */
            if ( i > 0 &&
                 modes[i]->hdisplay == modes[i-1]->hdisplay &&
                 modes[i]->vdisplay == modes[i-1]->vdisplay ) {
                    continue;
            }

            /* Check to see if we should add the screen size (Xinerama) */
            w = modes[i]->hdisplay;
            h = modes[i]->vdisplay;
            if ( (screen_w * screen_h) >= (w * h) ) {
                if ( (screen_w != w) || (screen_h != h) ) {
                    SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
                    if ( SDL_modelist[n] ) {
                        SDL_modelist[n]->x = 0;
                        SDL_modelist[n]->y = 0;
                        SDL_modelist[n]->w = screen_w;
                        SDL_modelist[n]->h = screen_h;
                        ++n;
                    }
                }
                screen_w = 0;
                screen_h = 0;
            }

            /* Add the size from the video mode list */
            SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
            if ( SDL_modelist[n] == NULL ) {
                break;
            }
            SDL_modelist[n]->x = 0;
            SDL_modelist[n]->y = 0;
            SDL_modelist[n]->w = w;
            SDL_modelist[n]->h = h;
            ++n;
        }
        SDL_modelist[n] = NULL;
        XFree(modes);

        use_vidmode = vm_major * 100 + vm_minor;
        save_mode(this);
    }
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

#if SDL_VIDEO_DRIVER_X11_XME
    /* XiG */
    modelist = NULL;
    /* first lets make sure we have the extension, and it's at least v2.0 */
    if ( CheckXME(this, &xme_major, &xme_minor) && xme_major >= 2 &&
         (nummodes = XiGMiscQueryResolutions(SDL_Display, SDL_Screen,
                                             0, /* view */
                                             &ractive, &modelist)) > 1 )
    {                                /* then we actually have some */
        int j;

        /* We get the list already sorted in descending order.
           We'll copy it in reverse order so SDL is happy */
#ifdef X11MODES_DEBUG
        fprintf(stderr, "XME: nummodes = %d, active mode = %d\n",
                nummodes, ractive);
#endif
        if ( SDL_modelist ) {
            for ( i = 0; SDL_modelist[i]; ++i ) {
                SDL_free(SDL_modelist[i]);
            }
            SDL_free(SDL_modelist);
        }
        SDL_modelist = (SDL_Rect **)SDL_malloc((nummodes+1)*sizeof(SDL_Rect *));
        if ( !SDL_modelist ) {
            SDL_OutOfMemory();
            return -1;
        }
        for ( i=0, j=nummodes-1; j>=0; i++, j-- ) {
            if ((SDL_modelist[i] =
                 (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect))) == NULL)
              break;
#ifdef X11MODES_DEBUG
            fprintf(stderr, "XME: mode = %4d, w = %4d, h = %4d\n",
                   i, modelist[i].width, modelist[i].height);
#endif

            SDL_modelist[i]->x = 0;
            SDL_modelist[i]->y = 0;
            SDL_modelist[i]->w = modelist[j].width;
            SDL_modelist[i]->h = modelist[j].height;

        }
        SDL_modelist[i] = NULL; /* terminator */

        use_xme = xme_major * 100 + xme_minor;
        saved_res = modelist[ractive]; /* save the current resolution */
    }
    if ( modelist ) {
        XFree(modelist);
    }
#endif /* SDL_VIDEO_DRIVER_X11_XME */

    {
	/* It's interesting to note that if we allow 32 bit depths,
	   we get a visual with an alpha mask on composite servers.
        static int depth_list[] = { 32, 24, 16, 15, 8 };
	*/
        static int depth_list[] = { 24, 16, 15, 8 };
        int j, np;
        int use_directcolor = 1;
        XPixmapFormatValues *pf;

        /* Search for the visuals in deepest-first order, so that the first
           will be the richest one */
        if ( SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) {
                use_directcolor = 0;
        }
        this->hidden->nvisuals = 0;
        if ( ! add_visual_byid(this, SDL_getenv("SDL_VIDEO_X11_VISUALID")) ) {
                for ( i=0; i<SDL_arraysize(depth_list); ++i ) {
                        if ( depth_list[i] > 8 ) {
                                if ( use_directcolor ) {
                                        add_visual(this, depth_list[i], DirectColor);
                                }
                                add_visual(this, depth_list[i], TrueColor);
                        } else {
                                add_visual(this, depth_list[i], PseudoColor);
                                add_visual(this, depth_list[i], StaticColor);
                        }
                }
        }
        if ( this->hidden->nvisuals == 0 ) {
            SDL_SetError("Found no sufficiently capable X11 visuals");
            return -1;
        }

        /* look up the pixel quantum for each depth */
        pf = XListPixmapFormats(SDL_Display, &np);
        for(i = 0; i < this->hidden->nvisuals; i++) {
            int d = this->hidden->visuals[i].depth;
            for(j = 0; j < np; j++)
                if(pf[j].depth == d)
                    break;
            this->hidden->visuals[i].bpp = j < np ? pf[j].bits_per_pixel : d;
        }

        XFree(pf);
    }

    if ( SDL_modelist == NULL ) {
        SDL_modelist = (SDL_Rect **)SDL_malloc((1+1)*sizeof(SDL_Rect *));
        if ( !SDL_modelist ) {
            SDL_OutOfMemory();
            return -1;
        }
        n = 0;
        SDL_modelist[n] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
        if ( SDL_modelist[n] ) {
            SDL_modelist[n]->x = 0;
            SDL_modelist[n]->y = 0;
            SDL_modelist[n]->w = screen_w;
            SDL_modelist[n]->h = screen_h;
            ++n;
        }
        SDL_modelist[n] = NULL;
    }

#ifdef X11MODES_DEBUG
    if ( use_xinerama ) {
        printf("Xinerama is enabled\n");
    }

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

    if ( use_vidmode ) {
        printf("VidMode is enabled\n");
    }

    if ( use_xme ) {
        printf("Xi Graphics XME fullscreen is enabled\n");
    }

    if ( SDL_modelist ) {
        printf("X11 video mode list:\n");
        for ( i=0; SDL_modelist[i]; ++i ) {
            printf("\t%dx%d\n", SDL_modelist[i]->w, SDL_modelist[i]->h);
        }
    }
#endif /* X11MODES_DEBUG */

    return 0;
}

int X11_SupportedVisual(_THIS, SDL_PixelFormat *format)
{
    int i;
    for(i = 0; i < this->hidden->nvisuals; i++)
        if(this->hidden->visuals[i].bpp == format->BitsPerPixel)
            return 1;
    return 0;
}

SDL_Rect **X11_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
    if ( X11_SupportedVisual(this, format) ) {
        if ( flags & SDL_FULLSCREEN ) {
            return(SDL_modelist);
        } else {
            return((SDL_Rect **)-1);
        }
    } else {
        return((SDL_Rect **)0);
    }
}

void X11_FreeVideoModes(_THIS)
{
    int i;

    if ( SDL_modelist ) {
        for ( i=0; SDL_modelist[i]; ++i ) {
            SDL_free(SDL_modelist[i]);
        }
        SDL_free(SDL_modelist);
        SDL_modelist = NULL;
    }

#if SDL_VIDEO_DRIVER_X11_XRANDR
    /* Free the Xrandr screen configuration */
    if ( screen_config ) {
        XRRFreeScreenConfigInfo(screen_config);
        screen_config = NULL;
    }
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
}

int X11_ResizeFullScreen(_THIS)
{
    int x = 0, y = 0;
    int real_w, real_h;
    int screen_w;
    int screen_h;

    screen_w = DisplayWidth(SDL_Display, SDL_Screen);
    screen_h = DisplayHeight(SDL_Display, SDL_Screen);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    if ( use_xinerama &&
         window_w <= xinerama_info.width &&
         window_h <= xinerama_info.height ) {
        x = xinerama_info.x_org;
        y = xinerama_info.y_org;
    }
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */

    if ( currently_fullscreen ) {
        /* Switch resolution and cover it with the FSwindow */
        move_cursor_to(this, x, y);
        set_best_resolution(this, window_w, window_h);
        move_cursor_to(this, x, y);
        get_real_resolution(this, &real_w, &real_h);
        if ( window_w > real_w ) {
            real_w = MAX(real_w, screen_w);
        }
        if ( window_h > real_h ) {
            real_h = MAX(real_h, screen_h);
        }
        XMoveResizeWindow(SDL_Display, FSwindow, x, y, real_w, real_h);
        move_cursor_to(this, real_w/2, real_h/2);

        /* Center and reparent the drawing window */
        x = (real_w - window_w)/2;
        y = (real_h - window_h)/2;
        XReparentWindow(SDL_Display, SDL_Window, FSwindow, x, y);
        /* FIXME: move the mouse to the old relative location */
        XSync(SDL_Display, True);   /* Flush spurious mode change events */
    }
    return(1);
}

void X11_QueueEnterFullScreen(_THIS)
{
    switch_waiting = 0x01 | SDL_FULLSCREEN;
    switch_time = SDL_GetTicks() + 1500;
#if 0 /* This causes a BadMatch error if the window is iconified (not needed) */
    XSetInputFocus(SDL_Display, WMwindow, RevertToNone, CurrentTime);
#endif
}

int X11_EnterFullScreen(_THIS)
{
    int okay;
#if 0
    Window tmpwin, *windows;
    int i, nwindows;
#endif
    int x = 0, y = 0;
    int real_w, real_h;
    int screen_w;
    int screen_h;

    okay = 1;
    if ( currently_fullscreen ) {
        return(okay);
    }

    /* Ungrab the input so that we can move the mouse around */
    X11_GrabInputNoLock(this, SDL_GRAB_OFF);

#if SDL_VIDEO_DRIVER_X11_XINERAMA
    if ( use_xinerama &&
         window_w <= xinerama_info.width &&
         window_h <= xinerama_info.height ) {
        x = xinerama_info.x_org;
        y = xinerama_info.y_org;
    }
#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */

    /* Map the fullscreen window to blank the screen */
    screen_w = DisplayWidth(SDL_Display, SDL_Screen);
    screen_h = DisplayHeight(SDL_Display, SDL_Screen);
    get_real_resolution(this, &real_w, &real_h);
    if ( window_w > real_w ) {
        real_w = MAX(real_w, screen_w);
    }
    if ( window_h > real_h ) {
        real_h = MAX(real_h, screen_h);
    }
    XMoveResizeWindow(SDL_Display, FSwindow,
                      x, y, real_w, real_h);
    XMapRaised(SDL_Display, FSwindow);
    X11_WaitMapped(this, FSwindow);

#if 0 /* This seems to break WindowMaker in focus-follows-mouse mode */
    /* Make sure we got to the top of the window stack */
    if ( XQueryTree(SDL_Display, SDL_Root, &tmpwin, &tmpwin,
                            &windows, &nwindows) && windows ) {
        /* If not, try to put us there - if fail... oh well */
        if ( windows[nwindows-1] != FSwindow ) {
            tmpwin = windows[nwindows-1];
            for ( i=0; i<nwindows; ++i ) {
                if ( windows[i] == FSwindow ) {
                    SDL_memcpy(&windows[i], &windows[i+1],
                           (nwindows-i-1)*sizeof(windows[i]));
                    break;
                }
            }
            windows[nwindows-1] = FSwindow;
            XRestackWindows(SDL_Display, windows, nwindows);
            XSync(SDL_Display, False);
        }
        XFree(windows);
    }
#else
    XRaiseWindow(SDL_Display, FSwindow);
#endif

#if SDL_VIDEO_DRIVER_X11_VIDMODE
    /* Save the current video mode */
    if ( use_vidmode ) {
        SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, True);
    }
#endif
    currently_fullscreen = 1;

    /* Set the new resolution */
    okay = X11_ResizeFullScreen(this);
    if ( ! okay ) {
        X11_LeaveFullScreen(this);
    }
    /* Set the colormap */
    if ( SDL_XColorMap ) {
        XInstallColormap(SDL_Display, SDL_XColorMap);
    }
    if ( okay ) {
        X11_GrabInputNoLock(this, this->input_grab | SDL_GRAB_FULLSCREEN);
    }

    /* We may need to refresh the screen at this point (no backing store)
       We also don't get an event, which is why we explicitly refresh. */
    if ( this->screen ) {
        if ( this->screen->flags & SDL_OPENGL ) {
            SDL_PrivateExpose();
        } else {
            X11_RefreshDisplay(this);
        }
    }

    return(okay);
}

int X11_LeaveFullScreen(_THIS)
{
    if ( currently_fullscreen ) {
        XReparentWindow(SDL_Display, SDL_Window, WMwindow, 0, 0);
#if SDL_VIDEO_DRIVER_X11_VIDMODE
        if ( use_vidmode ) {
            restore_mode(this);
            SDL_NAME(XF86VidModeLockModeSwitch)(SDL_Display, SDL_Screen, False);
        }
#endif

#if SDL_VIDEO_DRIVER_X11_XME
        if ( use_xme ) {
            int rw, rh;

            /* check current mode so we can avoid uneccessary mode changes */
            get_real_resolution(this, &rw, &rh);

            if (rw != saved_res.width || rh != saved_res.height) {
                XiGMiscChangeResolution(SDL_Display,
                                        SDL_Screen,
                                        0, /* view */
                                        saved_res.width,
                                        saved_res.height,
                                        0);
                XSync(SDL_Display, False);
            }
        }
#endif

#if SDL_VIDEO_DRIVER_X11_XRANDR
        if ( use_xrandr ) {
            XRRSetScreenConfig(SDL_Display, screen_config, SDL_Root,
                               saved_size_id, saved_rotation, CurrentTime);
        }
#endif

        XUnmapWindow(SDL_Display, FSwindow);
        X11_WaitUnmapped(this, FSwindow);
        XSync(SDL_Display, True);   /* Flush spurious mode change events */
        currently_fullscreen = 0;
    }
    /* If we get popped out of fullscreen mode for some reason, input_grab
       will still have the SDL_GRAB_FULLSCREEN flag set, since this is only
       temporary.  In this case, release the grab unless the input has been
       explicitly grabbed.
     */
    X11_GrabInputNoLock(this, this->input_grab & ~SDL_GRAB_FULLSCREEN);

    /* We may need to refresh the screen at this point (no backing store)
       We also don't get an event, which is why we explicitly refresh. */
    if ( this->screen ) {
        if ( this->screen->flags & SDL_OPENGL ) {
            SDL_PrivateExpose();
        } else {
            X11_RefreshDisplay(this);
        }
    }

    return(0);
}

redpajama_set_name: RedPajamaGithub


innovation, work, organisations, culture, communication, theory, qualitative methods, critical data studies, science and technology studies.
Benjamin Franklin used to keep charts of his time spent and virtues lived up to. Today, we use technology to self-track: our hours slept, ... Read More Exploring the world of self-tracking: who wants our data and why?
NEFF, G., Tanweer,, A., Fiore-Gartland,, B. and Osburn, L. (2017) "Critique and Contribute: A Practice-based Framework for Improving Critical Data Studies and Data Science", Big Data. 5 (2) 85-97.
Neff, G. and Nafus, D. (2016) Self-Tracking. MIT Press.
Barta, K. and Neff, G. (2016) "Technologies for Sharing: lessons from Quantified Self about the political economy of platforms", Information, Communication & Society. 19 (4) 518-531.
Nagy, P. and Neff, G. (2015) "Imagined Affordance: Reconstructing a Keyword for Communication Theory", Social Media + Society. 1 (2) 205630511560338.
Neff, G. and Fiore-Gartland, B. (2015) "Communication, Mediation, and the Expectations of Data: Data Valences Across Health and Wellness Communities", International Journal of Communication. 9 (1) 1466-1484.
Neff, G. (2013) "Why Big Data Won't Cure Us", Big Data. 1 (3) 117-123.
Neff, G. (2012) Venture Labor. Cambridge, MA: MIT Press.
Dossick, C.S. and Neff, G. (2011) "Messy talk and clean technology: communication, problem-solving and collaboration using Building Information Modelling", Engineering Project Organization Journal. 1 (2) 83-93.
Dossick, C.S. and Neff, G. (2010) "Organizational Divisions in BIM-Enabled Commercial Construction", Journal of Construction Engineering and Management. 136 (4) 459-467.
Amman, J., Carpenter, T. and Neff, G. (2015) Surviving the New Economy. Routledge.
NEFF, G. (2018) "The Potential of Networked Solidarity: Communication at the End of the Long Twentieth Century" In: Trump and the Media Boczkowski, P.J. and Papacharissi, Z. (eds.). MIT Press.
Fiore-Gartland,, B. and Neff, G. (2016) "Disruption and the Political Economy of Biosensor Data" In: Quantified: Biosensing Technologies in Everyday Life Nafus, D. (eds.). Cambridge, MA: MIT Press. 101-122.
Neff, G. and Stark, D. (2004) "Permanently Beta: Responsive Organization in the Internet Era" In: Society Online The Internet in Context Howard, P.N. and Jones, S. (eds.). SAGE.
NEFF, G. and Nagy, P. "Agency in the digital age: Using symbiotic agency to explain human-technology interaction" In: A Networked Self: Human Augmentics, Artificial Intelligence, Sentience Papacharissi, Z. (eds.). Routledge.
NEFF, G. "The Potential of Networked Solidarity: Communication at the End of the Long Twentieth Century" In: Trump and the Media Boczkowski, P.J. and Papacharissi, Z. (eds.). Cambridge, Massachusetts: MIT Press.
Kuksenok, K., Aragon, C., Fogerty, J., Lee, C.P. and NEFF, G. (2017) "Deliberate Individual Change Framework for Understanding Programming Practices in Four Oceanography Groups", Computer Supported Cooperative Work: the journal of collaborative computing. Springer Verlag (Germany). 26 (4-6) 663-691.
Dossick, C.S., NEFF, G., Osburn, L., Monson, C. and Burpee, H. (2016) "Technical Boundary Spanners and Translation:A Study of Energy Modeling for High Performance Hospitals", Engineering Project Organization Conference.
Monson, C., NEFF, G., Dossick, C., Osburn, L. and Burpee, H. (2016) "Finding Connections Between Design Processes and Institutional Forces on Integrated AEC Teams for High Performing Energy Design", Engineering Project Organization Conference. Taylor & Francis: STM, Behavioural Science and Public Health Titles.
Dossick, C.S., Osburn, L. and NEFF, G. (2019) "Innovation Through Practice: The Messy Work of Making Technology Useful for Architecture, Engineering and Construction Teams", Engineering, Construction and Architectural Management 2019.
Neff, G. (2017) "Conclusion: Agendas for Studying Communicative Capitalism", INTERNATIONAL JOURNAL OF COMMUNICATION. 11 2046-2049.
NEFF, G. (2016) "Talking to Bots: Symbiotic Agency and the Case of Tay", International Journal of Communication. 10 4915-4931.
Neff, G. (2015) "Learning from documents: Applying new theories of materiality to journalism", Journalism: Theory, Practice & Criticism. 16 (1) 74-78.
Dossick, C.S., Anderson, A., Azari, R., Iorio, J., Neff, G. and Taylor, J.E. (2014) "Messy Talk in Virtual Teams: Achieving Knowledge Synthesis through Shared Visualizations", Journal of Management in Engineering. 31 (1) A4014003.
Neff, G., Fiore-Silfvast, B. and Dossick, C.S. (2014) Materiality: Challenges and Opportunities for Communication Theory.
Bird, S.E., Couldry, N., Hepp, A., Livingstone, S., Losh, E., Mittell, J., Neff, G., Slater, D. and Watkins, S.C. (2014) "Participations: Dialogues on the Participatory Promise of Contemporary Culture and Politics PART 4: KNOWLEDGE AND EDUCATION", INTERNATIONAL JOURNAL OF COMMUNICATION. 8 1216-1242.
Bird, S.E., Couldry, N., Hepp, A., Livingstone, S., Losh, E., Mittell, J., Neff, G., Slater, D. and Watkins, S.C. (2014) "Participations: Dialogues on the participatory promise of contemporary culture and politics", International Journal of Communication. 8 (1) 1216-1242.
FIORE-SILFVAST, B.R.I.T.T.A.N.Y. and NEFF, G.I.N.A. (2013) "What we talk about when we talk data: Valences and the social performance of multiple metrics in digital health", Ethnographic Praxis in Industry Conference Proceedings. 2013 (1) 74-87.
Neff, G., Jordan, T., McVeigh-Schultz, J. and Gillespie, T. (2012) "Affordances, Technical Agency, and the Politics of Technologies of Cultural Production", Journal of Broadcasting & Electronic Media. 56 (2) 299-313.
Neff, G. and Robinson, L. (2012) "THE SOCIAL MATRIX OF THE EMERGENT WEB: GOVERNANCE, EXCHANGE, PARTICIPATION, & ENGAGEMENT", Information, Communication & Society. 15 (4) 449-454.
Dossick, C.S. and Neff, G. (2010) Messy Talk and Clean Technology: Requirements for Inter-Organizational Collaboration and BIM Implementation within the AEC Industry.
Neff, G., Fiore-Silfvast, B. and Dossick, C.S. (2010) "A CASE STUDY OF THE FAILURE OF DIGITAL COMMUNICATION TO CROSS KNOWLEDGE BOUNDARIES IN VIRTUAL CONSTRUCTION", Information, Communication & Society. 13 (4) 556-573.
Amman, J., Carpenter, T. and Neff, G. (2006) Surviving in the New Economy: Sharecroppers in the Ownership Society.
Neff, G., Wissinger, E. and Zukin, S. (2005) "Entrepreneurial Labor among Cultural Producers: "Cool" Jobs in "Hot" Industries", Social Semiotics. 15 (3) 307-334.
FISHER, D.A.N.A.R., STANLEY, K.E.V.I.N., BERMAN, D.A.V.I.D. and NEFF, G.I.N.A. (2005) "How Do Organizations Matter? Mobilization and Support for Participants at Five Globalization Protests", Social Problems. 52 (1) 102-121.
Neff, G. (2004) "Risk Relations: The New Uncertainties of Work", WorkingUSA. 5 (2) 59-68.
Neff, G. (2004) "Sous la culture des fondations", Agone. (31-32) 124-131.
An overview of the major findings to date regarding the social implications of the Internet, drawing material from several social science disciplines, including communication studies, sociology, and political science.
Speakers like Alexa, Google and Siri are excluding people who do not identify as male or female, the creators of a new gender-neutral voice assistant have claimed.
To avoid the risk of your leisure time feeling like work when it is tracked, Gina Neff, co-author of "Self-Tracking," suggests using "non-quantitative" tracking.


text:
TikTok Announces New Policy Updates to Better Protect Young Users
TikTok has announced a raft of changes to its default privacy settings for younger users as part of its ongoing effort to implement better systems to protect vulnerable members of its audience. Which, given the younger skew of its user base, is a particularly important focus for the short-form video app.
The biggest change will see all accounts created by users aged 13-15 now set to 'Private' by default. People under 13 are technically not allowed to sign-up for a regular TikTok account.
As explained by TikTok:
"Starting today, we're changing the default privacy setting for all registered accounts ages 13-15 to private. With a private TikTok account, only someone who the user approves as a follower can view their videos. We want our younger users to be able to make informed choices about what and with whom they choose to share, which includes whether they want to open their account to public views. By engaging them early in their privacy journey, we can enable them to make more deliberate decisions about their online privacy."
Which is a good approach - by restricting the audience for videos by default, TikTok is also educating younger users as to how these systems work, which could provide them with a better understanding of their privacy options moving forward.
In addition to this, TikTok is also implementing new restrictions on comments, engagement and the downloading of videos created by younger users.
We're tightening the options for commenting on videos created by those ages 13-15. These users can now choose between 'Friends' or 'No One' for their account; the 'Everyone' comment setting is being removed.
We're changing Duet and Stitch settings to now make these features available on content created by users age 16 and over only. For users ages 16-17, the default setting for Duet and Stitch will now be set to Friends.
We'll only allow downloads of videos that have been created by users 16 and over. Other users can decide whether they want to allow downloads of their videos, though for users ages 16-17 the default setting will now be changed to Off unless they decide to enable it.
The "Suggest your account to others" setting will be switched off by default for users ages 13-15.
These are good updates, which should offer additional protection for younger users. Of course, there are still ways to subvert the sign-in process, and to get around the initial, sign-in age gate. But in terms what TikTok is able to do itself, these extra limitations should offer more protection, and reduce unwanted exposure in the app.
In addition to this, TikTok's also partnering with Common Sense Networks to improve the safety of its TikTok for Younger Users offering.
"Through our partnership, Common Sense Networks will provide additional guidance on the appropriateness of content for children under 13 as we work to create an enjoyable and safe viewing experience."
Amid the app's massive growth over the past two years, TikTok has also had to rapidly update its processes in order to better protect younger users, while also ensuring that their data is not being harvested and used in unethical, even illegal ways.
The platform has faced a range of legal challenges on this - in July 2019, the UK Information Commissioner launched an investigation into how TikTok handles the personal data of its young users, and whether it prioritizes the safety of children on its network. In February 2019, the FTC fined TikTok a record $5.7 million for illegally collecting the names, email addresses, pictures and locations of kids under age 13. And in August last year, French officials announced a new investigation into TikTok's data-gathering practices, primarily due to concerns around its measures to protect younger users.
TikTok has also been banned in some regions over its failure to protect children from exposure to offensive content, while just recently, a damages claim was made on behalf of a 12-year-old girl from London over "loss of control of personal data".
It's a key element of concern, and with reports suggesting that more than a third of the app's users are under 14 years of age, it's of particular significance that TikTok takes additional steps to address such issues.
Which is why these new measures are important. As noted, they won't address every concern, but it's good to see TikTok taking proactive measures to better protect its younger, more impressionable audience.
Filed Under: Social Media Updates
Get social media news like this in your inbox daily. Subscribe to Social Media Today:
Latest in Social Media Updates
Facebook Blocks Creation of Events Near Capitol, Halts Ads for Weapons in Lead-Up to Inauguration Day
WhatsApp Delays Privacy Policy Update in Order to Further Address User Concerns
Instagram's Testing an Option to Unhide Total Like Counts on Posts

redpajama_set_name: RedPajamaCommonCrawl


text:
For Writers & Illustrators
A blog on race, diversity, education, and children's books.
Tag Archives: Sally Derby
Diversity, Race, and Representation, Interviews with Authors and Illustrators, Lee & Low Likes
Shadra Strickland and Sally Derby Discuss Their New Book, Diversity in Publishing, and More
October 7, 2015 leeandlowbooks 3 Comments
Released this past May, Sunday Shopping tells a whimsical story of a girl and her grandma who go "shopping" through the newspaper ads every Sunday. We interviewed author Sally Derby and illustrator Shadra Strickland about their creative processes, the children's book publishing industry, and encouraging children to write more. Continue reading →
book publishingchildren's booksSally Derbyshadra stricklandsunday shopping
Common Core State Standards, Educator Resources
Close Reading in the Lower Elementary Classroom: compelling or counterproductive?
November 19, 2012 leeandlowbooks 1 Comment
Jaclyn DeForge, our Resident Literacy Expert, began her career teaching first and second grade in the South Bronx, and went on to become a literacy coach and earn her Masters of Science in Teaching. In her column she offers teaching and literacy tips for educators.
Last Monday, my post on close reading in the second grade classroom inspired some great discussion in the comments section from Lee & Low authors Sally (Derby) Miller (author of My Steps) and Edith Hope Fine (author of our mentor text for the post, Under the Lemon Moon). Click here to read both my post and their thoughts in full.
Something Sally Miller brought up in her comment really stuck with me. On what she imagines a close reading experience to be in a lower elementary classroom:
"We are talking about very young children–say ages five to eight–who have just heard or read a short, illustrated text. Some of them liked it, some of them loved it, and some of them waited patiently for a change in activity so that they could move around the classroom instead of being required to sit and absorb the story. Very well, it has ever been thus in public schools. But now…now they are expected to stay focused on the story, to decide why the author wrote it the way he did, why he used certain words, why he chose to set the story in, say, another country instead of this one. It's not a story any more, it's a lesson."
The adoption of the new Common Core Standards has certainly not come without controversy. One of the purposes of the new standards, from what I understand, is to begin to address large gaps in reading comprehension and performance that we're seeing in high schools across the country. SAT scores for the high school class of 2012 indicated that a whopping 57% (!!!) of test takers "did not score high enough to indicate likely success in college, according to the College Board." (Layton, Lyndsey and Brown, Emma; Washington Post; Sept. 24, 2012).
close readingEdith Hope FineEducatorsMy StepsReading Aloudreading comprehensionSally DerbySally Millerslow readingUnder the Lemon Moon
Don't miss a post! Subscribe via email for regular updates.
Posts | Comments
All content copyright of Lee & Low Books unless otherwise noted. Contact us for permission to reprint
Requesting Review Copies
Lee & Low Books
Fairs/Conventions
Art and Book Design
New Voices/New Visions Award
Book Lists by Topic
Diversity 102
How We Did It
Diversity, Race, and Representation
Diversity Baseline Survey
Diversity in YA
Diversity Videos
Gender/LGBTQ Diversity
The Diversity Gap
ELL/ESL and Bilingual Books
Giveaways and Contests
Guest Blogger Post
Interviews with Authors and Illustrators
Lee & Low Likes
Musings & Ponderings
recap post
Tu Books
Archives Select Month January 2023 December 2022 November 2022 October 2022 September 2022 August 2022 July 2022 June 2022 May 2022 April 2022 March 2022 February 2022 January 2022 December 2021 November 2021 October 2021 September 2021 August 2021 July 2021 June 2021 May 2021 April 2021 March 2021 February 2021 January 2021 December 2020 November 2020 October 2020 September 2020 August 2020 July 2020 June 2020 May 2020 April 2020 March 2020 February 2020 January 2020 December 2019 November 2019 October 2019 September 2019 August 2019 July 2019 June 2019 May 2019 April 2019 March 2019 February 2019 January 2019 December 2018 November 2018 October 2018 September 2018 August 2018 July 2018 June 2018 May 2018 April 2018 March 2018 February 2018 January 2018 December 2017 November 2017 October 2017 September 2017 August 2017 July 2017 June 2017 May 2017 April 2017 March 2017 February 2017 January 2017 December 2016 November 2016 October 2016 September 2016 August 2016 July 2016 June 2016 May 2016 April 2016 March 2016 February 2016 January 2016 December 2015 November 2015 October 2015 September 2015 August 2015 July 2015 June 2015 May 2015 April 2015 March 2015 February 2015 January 2015 December 2014 November 2014 October 2014 September 2014 August 2014 July 2014 June 2014 May 2014 April 2014 March 2014 February 2014 January 2014 December 2013 November 2013 October 2013 September 2013 August 2013 July 2013 June 2013 May 2013 April 2013 March 2013 February 2013 January 2013 December 2012 November 2012 October 2012 September 2012 August 2012 July 2012 June 2012 May 2012 April 2012 March 2012 February 2012 January 2012 December 2011 November 2011 October 2011 September 2011 August 2011 June 2011 May 2011 April 2011 March 2011 February 2011 January 2011 December 2010 November 2010 October 2010 September 2010 August 2010 July 2010 June 2010 May 2010 April 2010 March 2010 February 2010 January 2010 December 2009 November 2009 October 2009 September 2009 August 2009 July 2009 June 2009
Resources on LeeandLow.com
Bebop Books
Children's Book Press
Dive Into Reading
Shen's Books
Lee & Low Games
Teacher Guides and Lesson Plans
Books by Theme
Diverse Leveled Bookrooms
For Writers and Illustrators
Submission Guidelines for Writers
New Voices Award
Submission Guidelines for Illustrators
About Lee & Low
New Visions Award
Art Submission Guidelines
Join Lee & Low
© 2023 Lee & Low Books


text:
Dudu is het zesde muziekalbum van de Turkse zanger Tarkan. Het album, dat vijf nieuwe nummers en vijf remixes bevat, werd in 2003 voor het eerst uitgebracht door Tarkans eigen platenlabel, HITT Müzik & Prodüksiyon.

Van Dudu, Sorma Kalbim, Gülümse Kaderine en een remix van het liedje Uzun İnce Bir Yoldayım (deze remix is niet op de cd te vinden) zijn videoclips gemaakt. De clip Dudu speelt zich af tijdens een geacteerd concert van Tarkan, op straat in Istanboel en in een bus. De clip Uzun İnce Bir Yoldayım [Remix] bevat beelden van meerdere concerten van Tarken inclusief taferelen om de concerten heen.

Nummers
De tien nummers van Dudu met daarachter de duur van het nummer en de Nederlandse vertaling van de titel:
"Dudu" – 4:38; Mevrouw
"Bu Şarkılar Da Olmasa" – 4:29; Als deze liedjes er ook niet waren
"Gülümse Kaderine" – 3:49; Lach je lot toe
"Sorma Kalbim" – 4:37; Vraag het niet, mijn hart
"Uzun İnce Bir Yoldayım" – 4:59; Ik bevind me op een lange, smalle weg
"Dudu (Ozan Çolakoğlu Remix)" – 4:53
"Gülümse Kaderine (Devrim Remix)" – 5:20
"Bu Şarkılar Da Olmasa (Devrim Remix)" – 5:54
"Dudu (Özgür Buldum Remix)" – 3:56
"Gülümse Kaderine (Murat Matthew Erdem Remix)" – 4:57

Credits

Personeel
 Productie: HITT Müzik & Prodüksiyon
 Producent: Tarkan
 Distributeur: İstanbul Plak
 Mixer: Murat Matthew Erdem
 Mastering: Tim Young, Metropolist Studios London
 Opgenomen te: Sari Ev (Kayıt ve Mix), Imaj, ASM (Uzun Ince Bir Yoldayim Mix)
 Uitvoerend producent: Egemen Öncel
 Fotografie: Hasan Hüseyin
 Haar: Mete Türkmen
 Make-up: Neriman Eröz
 Kostuums: Gülümser Gürtunca

Gastmuzikanten
 Instrumenten:
 Klassieke gitaar - Erdem Sökmen, Ayhan Gunyil
 Elektrische gitaar en basgitaar - Nurkan Renda
 Oed - Ilyas Tetik
 Snaarinstrumenten - Gündem Yayli Grubu
 Voor het nummer Uzun İnce Bir Yoldayım:
 Achtergrondzanger, Bağlama - Arif Sağ
 Bağlama - Erdal Erzincan
 Balaban - Ertan Tekin
 Slaginstrumenten - Mehmet Akatay, Cengiz Ercumer, Arif Sağ
 Eerdere uitvoerenden - o.a. Aşik Veysel, Neşet Ertaş

Externe links
 Dudu op allmusic.com
 tarkan.com
Muziekalbum van Tarkan
Popalbum
Extended play uit 2003

redpajama_set_name: RedPajamaWikipedia


The lionfish (Pterois volitans) is an invasive species in the Caribbean. It was introduced through the inadvertent release of aquarium fish into the surrounding waters. Scientists believe that only 8 females and a small number of males, released in a few separate incidents over the past decade, account for the explosive proliferation of this animal in Caribbean ecosystem. Consequently, the populations of naturally occurring reef fish have been greatly depleted throughout the Caribbean in favor of this invading species.
Like its terrestrial namesake, the king of the jungle, this fish had become the king of the reef! It eats voraciously (commonly eating fish that are 60% its own size), is protected by an array of venomous spines, and until recently, had no known reef predators that recognized it as a source of food.
It is now known that large groupers and occasionally large snappers will gulp down this intruder and keep its population in check. Scientists have found that reefs with large groupers present have lionfish population approximately 10 times lower than reefs without big groupers. Unfortunately, both grouper and snapper are prized food fish and are notoriously overfished in the Caribbean to help feed the bulging tourist population that has come to expect a delicious grouper meal on the dinner menu.
Curaçao (where this photo was taken) is known to be an island that has been particularly hard on its native grouper. Past studies have shown that poorly enforced spearfishing laws and severe overfishing in general has badly depleted the population of reef carnivores, including those species that would prey on lionfish. Divers have long criticized Curaçao reefs for the lack of large fish. This may be the reason why the number of lionfish on Curaçao reefs has been particularly excessive. On my last trip to the island in 2010, I found lionfish to be both common and abundant. I really feared that the ecosystem was damaged beyond hope.
But there is hope. Though I'm not a scientist and I did not perform a rigorous, controlled investigation, I believe that the population of lionfish is now either flat or even lower in Curaçao than it was two years ago! Expecting to find the lionfish all over the reef, I was surprised to find the opposite to be true. Oh, they are still there, but were scarcer than in 2010 and much more wary when approached. The reason may be the presence of large, predatory groupers!
I've been diving Curaçao for over a decade now and have never seen a really large grouper... never... until this trip, that is. On two separate reefs (Playa Forti and Playa Kalki), I encountered Tiger Grouper about 4 feet in length. Again, this is not based on any scientific study, only my own personal experiences, but I found this to be an encouraging sign. The Tiger Grouper is a native species known to grow to large size. (Paul Humann's identification guide puts the upper size of these fish at 3 1/2 feet but I challenge this based on what I saw).
I remain optimistic about the future of the reefs surrounding Curaçao. I don't know the entire story as to why large grouper are making a comeback, but I hope that it has something to do with a change in human behavior or recognition of the effects of previous overfishing. I don't know the reason.
Anyway, the next time you are in the Caribbean, do me a favor. When you are trying to decide what to order from the menu... try the chicken!


text:
Sustainability >
With unparalleled choice, great taste, high quality standards and strict traceability, we believe our product range is the best in the industry. Our buyers work closely with our suppliers and other stakeholders to ensure environmental stewardship, ethical business practices and economic sustainability.
Sustainable and Responsible Sourcing
The term "responsible sourcing" refers to practices that help us to make sure our products are produced in a sustainable way without any negative environmental, social or ethical impacts, while preserving the excellent quality we demand. This is something which features increasingly highly on our customers' and consumers' priorities; as a large business we have a duty to manage our impact on the planet's ecosystems and support responsible animal welfare practices.
We're particularly proud of our work on sustainable fish and seafood; through working with the Marine Stewardship Council (MSC), the Marine Conservation Society (MCS), the Aquaculture Stewardship Council (ASC) and Sustain's Sustainable Fish Cities initiative, we're helping to protect and preserve seafood stocks.
Find out more about our work in sustainable fish & seafood
We were the first UK foodservice company to bring an MSC-certified product to market – the Fishwich, still in our range today! Over 150 products within our fish & seafood range are MSC-certified; we do not stock any fish or seafood rated 4 (eat very occasionally) or 5 (avoid) by the MCS.
We were the first UK foodservice company to ban many species (e.g. bluefin tuna, wild Atlantic salmon) and we continue to monitor fish stocks to make decisions about others should they come under threat. We don't support commercial whaling activities and expect the same of our suppliers
All palm oil in Brakes' own brand products is from certified sustainable sources
We only support meat and poultry products from suppliers who abide by the five freedoms for animal welfare
We pledge to be cage free on all whole egg and egg products by 2025 (Brakes own brand range only), subject to available supply, affordability and customer demand.
We work closely with our customers and our suppliers to ensure responsible sourcing practices are in place throughout our supply chain
We are certified with the British Retail Consortium's (BRC) "Global Standard for Food Storage and Distribution", and apply the principles of HACCP Food Safety Management throughout our operation (Hazard Analysis Critical Control Points)
Everything we deliver is fully traceable back to the supplier – strict policies on labelling and batch coding allow us to isolate any issues to particular suppliers and batches
British Lion eggs – all shell eggs in our range are certified
Red Tractor – over 300 products in our range are certified (meat, poultry, dairy and produce), some of which also carry the LEAF Marque
MSC (Marine Stewardship Council)'s Foodservice Supplier of the Year – Brakes has won this award every year since 2014, and counting!
LEAF Marque (Linking Environment and Farming) – LEAF works closely with member farmers to develop and implement farming techniques that help to produce affordable food in harmony with the environment. We source LEAF-accredited products wherever possible and in season for our fresh produce
GlobalG.A.P. (Good Agricultural Practices) – a set of voluntary standards and certification which assesses all agricultural and aquacultural practices. Products that carry this standard have been produced in a way that minimises the environmental impact of farming operations and ensures the responsible use of chemicals
Regional Sourcing/Provenance
Our customers want to make the most of their regions; using local products also provides them with great farm-to-fork stories to tell. Across the communities we serve, we offer local products to each where possible and when in season, without compromising on taste – but we also make the most of our national network and international partnerships to bring the best specialist regional goods to every customer.
What does this really mean?
A British-first sourcing approach; this includes supporting local manufacturing as well as products and ingredients. We aim to offer local/regional options in each product category – a British choice where British is available and in season. Our buyers ensure we have the best available options for our customers – now and in the future
Offering products local to each region. For example, we work with a number of suppliers in Scotland to offer more than 550 Scottish-manufactured products to our customers above the border
For Brakes' own brand range we take a local-first approach where relevant and cost-effective, creating ranges with local provenance where appropriate. Over 65% of our own brand range is produced and packed in the UK
Working with our network of European partners (Constellation) to source the best of speciality European products, like authentic Italian meats and French cheeses
A smart supply chain that makes the most of opportunities to reduce our "food miles" – for example, trucks picking up from suppliers when they are on their way back to depots, rather than returning empty
Working with our customers to be their partner of choice in the UK, delivering British products to big-ticket events (Wimbledon, Royal Ascot and the 2012 Olympics to name just a few!)
Woodall's Charcuterie
Three Oceans
Yew Tree Dairy
Outstanding British charcuterie from a leader in animal welfare, subscribing to a higher welfare standard for sows and pigs.
The first company, and so far only UK fish producer, to sign the Sustainable Fish Cities Pledge; over 75% of all their products are MSC-certified
An independent, family-run supplier with excellent farmer relationships – so much so that they have a list of dairy farmers waiting to work with them
Ethical Standards & Human Rights
Brakes is proud to be a responsible, ethical business with a moral compass – not only to meet legal obligations, but also because our customers, colleagues and suppliers (and we ourselves) expect nothing less. We protect and uphold human rights, ethical standards and labour rights throughout our supply chain.
Our Modern Day Slavery policy sets out our zero-tolerance approach to modern day slavery in our complete supply chain and the steps we take to ensure this – including in our own business – such as right-to-work checks and a preferred partner list of verified temporary worker agencies. Read the full policy here.
Supplier Partnerships
Every supplier to Brakes signs, and must adhere to, a strict Ethical Code of Conduct. This policy covers topics like anti-bribery and corruption, competition laws, health & safety and protecting whistleblowers, as well as modern slavery.
"Brakes will not tolerate the practice by any supplier of using forced, bonded, indentured, or slave labour nor will Brakes tolerate the use of physical or mental coercion or corporal punishment." (Supplier Code of Conduct)
Our Sedex membership (a global membership organisation for sharing information and best practice around responsible, ethical sourcing) helps us to work collaboratively with others to achieve high standards of ethical practice in our supply chains.
Case study: Sourcing sustainable meat with ABP
Working together since 2003, ABP Food Group supply Brakes with beef and lamb joints and cuts. Over the years they have evolved their practices to help improve animal welfare and reduce their impact on the environment, while continuing to produce high-quality, safe and assured products.
Since 2015 ABP's Ellesmere site uses an energy-efficient CHP (combined heat and power) engine, using biodiesel from sister company Olleco and recycled refined tallow from its own operations to power the engine.
ABP's "Doing more with less" programme sets out its targets for reducing carbon, water, energy and electricity usage by 2020, increasing recycling rates and investing in research to continue driving down utility usage.
The group's Blade Farming business focuses on producing consistently high quality beef through a controlled supply chain operation, ensuring the right environment to allow cattle to thrive and partnering with farmers to offer a guaranteed income from calf rearing.


text:
Home » blog » 2023 » 01 » 14
Bet365 Expands Presence in Pennsylvania via New Partnership with CDI
Lou De Aguila
14. January 2023 | UPDATED ON: 14. January 2023
Following the completion of an agreement with CDI, leading operator bet365 has been granted entry to the iGaming and online sports betting markets in the state of Pennsylvania.
Churchill Downs Incorporated (CDI) announced that it had reached a deal with bet365 that would last for many years. After receiving the requisite regulatory permits, the UK-based operator will use CDI's wholly-owned subsidiary Presque Isle Downs & Casino, to launch in Pennsylvania.
CDI will be able to concentrate on the principal horseracing mobile wagering business thanks to this advantageous agreement for both parties.
Top 3 Sports Betting Sites For Players From Pennsylvania in 2023
Min. Deposit: $10
Payout speed: 15 minutes
50% first deposit bonus up to $250Play NowOur score:
Payout speed: 1-3 business days
Welcome Bonus: 100% Up to $500Play NowOur score:
Payout speed: 48 hours
$20 free betPlay NowOur score:
Bet365 Continues Its Expansion Efforts in the United States
Bet365 had a difficult year in 2022, as the operator reported a disastrous 95% decline in profits despite a marginal increase in revenue. This was despite the fact that revenue had increased slightly.
The company's rising administrative costs are mostly attributed to the increased emphasis it places on globalization, which is the fundamental cause for the dismal performance of these indicators.
bet365 added more than 500 new staff to its payroll, which had the effect of significantly cutting into the company's operational profitability.
In spite of the adverse metrics, it is absolutely necessary to incur the additional expense in order to ensure a long-term presence in the American sports betting market.
The operator has been making consistent headway, most recently establishing operations in Colorado, Ontario, and Argentina. The price of acquiring new customers in the United States has been unusually high. Despite this, bet365's efforts are continuing unabated, as evidenced by the most recent agreement they've reached with CDI.
Significant Gains Await Both Businesses as Result of this Agreement
The establishment of a contract that spans multiple years is advantageous to both parties involved. The transaction paves the way for a relatively painless expansion of bet365's operations in Pennsylvania.
At the same time, it enables CDI to monetize its sports betting and iGaming assets while maintaining its focus on its own goals. A spokeswoman for bet365 praised the acquisition and promised to bring the company's most compelling products and services to this emerging market.
Concentrating on Expanding the Horse Racing Wagering
In the official news release that CDI issued on the arrangement, the firm states that it would continue to concentrate on expanding the TwinSpires online horse racing wagering area.
Because of the agreement with bet365, Presque Isle Downs & Casino will continue to make a profit from its iGaming and online sports betting operations, but it will do so with the least amount of expense and effort feasible. The Chief Executive Officer of CDI, Bill Carstanjen, lauded bet365 for its achievements on a global scale and expressed optimism over the cooperation.
The Industry Continuous to be Competitive in the Market
A successful debut in Pennsylvania would be a big advantage to bet365's aspirations to expand its presence in the United States. By securing a market share in the Keystone State, the operator will gain access to a flourishing gambling market that is able to support large earnings.
Despite this, the industry continues to be extremely competitive, which indicates that bet365 will need to exert significantly more effort in order to lure customers away from established operators.
BoVegas Casino - the Sin City Experience in One Click!
200% Welcome Bonus of Up to $2,000. Promo code: COOLBV200
Accepts Players From the US
Support Bitcoin For Deposits And Withdrawals
Play 800+ Casino Slot Games
Claim Your Bonus Now
About Lou De Aguila
Lou Aguila is a news and feature writer for Golden Casino News. For over a decade, Lou has published news and featured articles for some of the most reputable sports betting and online casino sites in the world, including BetNow.UK, VegasOdds, and BWin. Apart from being a hardcore live casino punter, he also covers sports stories in North American leagues from time to time.
View all posts by Lou De Aguila →
Categories News Tags bet365, Pennsylvania Online Casino, Pennsylvania sports betting Post navigation
North Dakota is considering legalizing sports betting
Slotmill's Slot Hits, iGaming Titles Now on SoftGamings Network
Top-Rated Real Money Online Casino
Claim $5,000 Welcome Bonus *Terms and Conditions apply


text:
Kamal Shah's Blog
On Dialysis in India for 23 years, Daily Nocturnal Home Hemodialysis, Atypical HUS, Co-Founder of NephroPlus, India's largest Dialysis Provider
Battle at Poorna Tiffins
Thrinath, a former colleague and a dear friend challenged me to a competition a few days back."Who can eat more idlis?" Wow, I thought. Who could eat more idlis than me? This was going to be easy. I agreed. The bet was that the loser would pay the bill. Simple enough. The date and time were fixed. Saturday, 25th July, 8:30 a.m. at Poorna Tiffins (where you get arguably the best idlis in town).
I added a caveat. The idlis had to be with ghee. Thrinath preferred idlis with ghee too.
So, the stage was set. Saturday it was.
To be honest, I was pretty confident of winning. I'm going to let you into a little secret. But promise me you won't tell anyone. I eat a minimum of 16 every Sunday morning when I go to Poorna Tiffins. On occasion I have also touched 24. 20 is the average. Who could eat that many? People who have accompanied me have rarely eaten more than half of what I usually do.
Thrinath also roped in Santosh Ramakrishnan, another former colleague into the bet. It was going to be a threesome. The bet was modified so that the person in 3rd place would pay two-thirds of the bill while the first runner up would pay a third.
I was all charged up. Saturday morning came. When I got up, I actually debated whether I should have my daily cup of Darjeeling Tea. If I did not have it, I could probably eat a couple of Idlis more. But I told you I was quite cocky about this whole thing. There was no way I could lose. I went ahead and had the tea.
I then left for Poorna. Thrinath and a few other former colleagues were already there by then. Santosh arrived a while later. We started the competition.
Each of us took 8 idlis to start with. They were heavenly as usual. Soaked in ghee with the spicy chutney. Thrinath was slow. Santosh and I gobbled them up quickly. The only person I was scared of was Santosh. There was a lot of real estate there that could be put to good use in competitions such as this!
All of us took another eight. Thrinath was still quite slow. Santosh had also slowed down by then. I thought both were struggling. I comfortably finished them. I took another four. I had finished 20 and was totally full. I waited while my other two competitors took another 4 each. I was quite surprised and disappointed too. At the end of this round, all of us would be at 20. A three way tie, I thought?
To my utter shock and horror, Thrinath asked for four more and Santosh asked for two. The waiter, by then had figured out we were in a bet and he put two in my plate too. I struggled to finish them. Thrinath and Santosh slowly finished their four and two respectively. There was no way I could have had any more. I got up and went to wash my hands. Just then I heard Thrinath ask for two more! I could hardly believe my ears! Santosh ordered a Poori bhaji. I almost fainted. It was too much for me to take.
The prime consumer of idlis had just been defeated fair and square. The king tuned out to be a mere pretender to the throne. Thrinath was the new king. Santosh and I split the bill because we came a joint second. The poori bhaji did not entitle him a sole second place. This competition was about idlis after all!
At the end of the day, I was lesser by about Rs. Three hundred and thirty and a lot of ego.
Thrinath, finishing his 26th idli
Santosh, enjoying the poori bhaji - after 22 idlis
at July 25, 2009 5 comments:
Phosphorus continues to baffle
Day before yesterday I started adding a phosphate solution to my dialysate so that too much Phosphorus is not removed from my blood during dialysis. The normal range for Phosphorus is 2.5 to 4.5 mg/dl. Mine has been between 1 and 2 mg/dl post dialysis.
I have been taking a phosphorus supplement called Neutraphos but it has not been helping too much because the removal of Phosphorus during dialysis was a lot.
Yesterday, post dialysis, my Phosphorus was only 1.1 mg/dl. This, after adding the phosphate solution to the dialysate. Yesterday, I had two packets of Neutraphos before dialysis. This morning it was 1.7 mg/dl.
I'm wondering if it is safe to increase the amount of phosphate solution further in the dialysate.
Way to go, Justices!
The Andhra Pradesh High Court directed the state government to stop funding religious pilgrimages. This was the judgement in two Public Interest Litigations filed against the Andhra Pradesh government's decision to fund pilgrimages of Christians to Bethlehem and other religious places. This judgement apparently also covers the subsidy to Haj pilgrimages.
This judgement must be welcomed by all.
What business does the government have funding religious pilgrimages? Isn't this a blatant example of minority appeasement by the politicians of the country? Why are only Muslim and Christian pilgrimages subsidized? Now, I am not, for a moment, suggesting funding Hindu pilgrimages at all. No religious pilgrimages must be funded by the state. Period.
Clearly, the government has got its priorities all wrong. Every year around Rs. 400 crore is spent on the Haj subsidy. Add to this the amount proposed to be spent on the Christian pilgrimage subsidy. Just imagine how much can be done with this money!
I did a quick calculation and realized that a shocking 28,000 people can be given free dialysis for a year at a corporate hospital in India with that money!!!
This is just one example. But it goes to show how wasteful that expenditure is. What has the government got to do with religion? Especially when we claim that we are a secular nation.
The judiciary has once again proved that it is capable of rational thinking. The judges must be complimented for this. I suspect, however, that the government will find a way to wriggle out of the embarrassing situation it finds itself in. But these kinds of judgements are welcome. Hats off, Justices!
An enterprise of honorable, dangerous consequence
I can't get over Shakespeare, can I?
Well, the title is only partly true. It is more an enterprise of healthy or dangerous consequence! Only one of the two really. Let me explain.
As you probably know, I undergo daily nocturnal dialysis. Which means that I get considerably more dialysis than your average Joe who usually gets about 12 hours a week. I get around 42. There is a downside to this.
For most dialyzors, Phosphorus is not adequately removed during dialysis due to the infrequent and relatively short sessions they get. They need to take Phosphate binders that remove the excess Phosphorus from their blood.
I get so much dialysis that excess Phosphorus is actually removed from my blood. So much that my Phosphorus is - hold your breath - below normal!
I have been taking Neutraphos, a Phosphorus supplement. This is one of the ways to treat this but not ideal. My Phosphorus probably goes below normal towards the last 2-3 hours of my dialysis. Then I take the supplement after a couple of hours of this. So, for a long time, my Phosphorus is below normal.
The amazing Dr. John Agar suggested in a webinar on Home Dialysis Central that a phosphate additive be added to the dialysate so that too much phosphorus is not removed in the first place. They add a phosphate solution (I am leaving out more details on purpose. You don't want to know. Trust me) to the dialysate for most nocturnal dialysis patients in Australia.
A similar solution is available in India too but the composition is slightly different. So, though the dosage is standardized in Australia, I am going to have to do a little bit of trial and error to arrive at what will work for me.
The consequences can't be too bad however, given that I am going to start with a low dose, measure my post-dialysis Phosphorus and then keep tweaking it till I get a good post-dialysis Phosphorus.
My Class 12 Chemistry has really helped me in this endeavor!
I start trials today. Wish me luck!
What's happening in the Afzal Guru case?
So today Ajmal Kasab finally confessed. Let us see how the trial now proceeds. Hopefully, it should be brought to an early end.
This brings me to Afzal Guru. The Supreme Court pronounced him guilty in the attack on Parliament and upheld the death sentence that was announced earlier. He filed a mercy petition before the President who forwarded it to the Central Government. The last I heard about this was that the Central Government had sent it to the Delhi Government headed by Sheila Dixit for advice. This was several months back.
The Delhi Government was apparently too busy with elections to take a decision on the matter. That is a ridiculous excuse. But let us accept that reasoning for a moment. The elections are now completed. It should be business as usual by now. What is stopping the Government from taking a decision on the matter?
No less an authority than the Supreme Court found enough evidence of his involvement in the attack on the seat of democracy in this country - symbol of national pride and honor. What is there to decide?
Why did the petition have to be sent to the Delhi Government in the first place? Why is the Delhi Government taking so long to decide on what should be an open and shut issue?
Why is nobody raising these questions?
Why the BIG project failed - Earthy Mistakes
(This is a work of fiction. Resemblance to any company, project or people is unintentional.)
Grey Matter was sold to the NEW company. The BIG project was supposed to be a major reason for this sale. The NEW company believed it had the ability to bring the project back on track and they had good reason to do so. They were expecting "many more similar sized projects" if this went well. Ah, the lure of more work! This has done so many people in.
The NEW company did what it could do best. Throw highly qualified and experienced people at the project. And expect it to be done. Unfortunately, that did not work.
Introducing Mr. Smart Alec. He thought he could solve all the world's software problems. This should be a piece of cake. Accompanied by Mr. Jack-of-all-trades who was the NEW company's handy boy. He looked after everything from database design to uncomfortable chairs. Ouch!
Together they brought on chaos. The developers were already fatigued with all the hullabaloo over the acquisition and the concomitant unkept promises. The dynamic duo had to instill enthusiasm into the team. They threatened them instead. Tch tch. Didn't work.
To add to the confusion, the NEW company added more heavyweights to the team thinking that they could solve all the problems. What was needed was more hands-on people. What they added was a bunch of managers. What are managers? Managers, as an old saying goes, is a bunch of people who cannot do anything, but they keep meeting and decide that nothing can be done! So it was with the BIG project.
Where do I fit in in all this?
Well, I was involved with the BIG project for a few months too. This was just before the company was sold. So, I am also equally responsible for the failure of the project. I should have done more. Used more common sense. There was this sense however to not go against the tide. This is a major problem with me as a person. I don't always go against the tide. I am more comfortable agreeing with everyone - supposedly more knowledgeable and experienced than me. I must learn not to do this. I must ask myself - what I think should really be done. And then listen to the answer.
Why the BIG project failed - Efficient and Intelligent Mistakes
The BIG project (BIGP) was the promise of liberation for Grey Matter. It was supposed to be a two year, multi-million dollar project. With "many more similar sized projects" if this went well.
An entire army of big guns were poached from software majors. Folks who had executed similar projects and come out with flying colors. Or so they said.
Today, about three years since the project was started, the curtains have come down - officially.
Many things.
To start with, the project was highly over-architected. When I first saw the architecture diagram, I thought it was a huge club sandwich. There were about ten layers. Ten layers? That's a lot. When you have ten layers in your architecture, you know you have a problem. Mr. Architect-in-Chief just loved complicated architectures. "Come on guys, this is a huge project. How can it have a simple architecture? Three layers is for wimps. The more (layers) the merrier. How about 10?"
"Makes sense", all his cronies nodded in agreement.
In any software project, there is one cardinal rule that must be followed: Keep it simple. When you have a project with such complicated functionality, you have to keep the design simple.
This brings me to the next problem with the BIGP. Multiple locations with no single anchor. The project was executed from three locations. There was no single person responsible for the project. People in all three locations had heavyweights who took no personal responsibility for the overall delivery of the project. They had a fancily named Project Management Office (PMO) which was supposed to be jointly responsible for the project. Joint responsibility - another red flag. There is no such thing as joint responsibility. There has to be one person responsible for a project. Nobody could be held accountable. Not Mr. Bald Eagle, not Mr. Bong Babu. Certainly not Mr. Spineless in San Jose.
In going with the fancy sounding names, the Agile methodology was adopted. Apart from sounding sexy - "We're using Agile" - it looked good on a resume. Well, there is nothing wrong with the Agile methodology. The only caveat is you have to follow it completely. Here, Agile was used in parts. For example, requirements freezing for a sprint, the foundation of an Agile sprint was never done. As a result, features kept getting added on the last day of a sprint! A sure recipe for disaster.
A major problem with the project was nobody from the PMO had their ears to the ground. The developers on the project, the foot soldiers, had predicted this outcome six months into the project. Nobody listened. They raised red flags again and again. Still nobody listened. The number of bugs kept getting bigger and bigger. Stability plummeted. Still nobody listened. If the customer was happy, why bother.
That was a huge problem in itself. Mr. Chief Architect knew how to please customers. Unfortunately he did not realize that you can fool some people some times, but you can definitely not fool all people all the time. Sooner or later the customer would wake up. When he did, all hell broke loose. But by then it was too late.
Inhuman doctors
I was recently contacted by a fellow dialyzor from India. He has been on dialysis for more than 15 years now. He has had some tough times. I was appalled however to read about the attitude of his doctors. He has got no support from them.
Doctors have a special responsibility. They are not dealing with machines. They are not even dealing with human beings who have had a normal life. People with chronic conditions go through a huge amount of mental stress and depression. They deserve a lot of compassion. Who knows this better than a doctor?
Doctors know exactly what a patient goes through. They know the symptoms, the pain and suffering. They know the side effects and all the co-morbidities that people on dialysis have to deal with. How can some of them then be so indifferent to the plight of their patients?
Again, all doctors are not like that. I have, for the most part, had doctors that were extremely considerate. They would happily engage in a discussion about my condition. They would answer all my questions very satisfactorily. Sadly, all of them are not like that.
The person in question has been threatened with discontinuation of his dialysis if a particular wish of his doctor was not fulfilled. (I am intentionally leaving out the details because I don't want to compromise his position.) This kind of blackmail is downright evil. It is against the basic tenets of humanity, let alone the medical profession.
The techs in his unit are hardly qualified. He is not answered properly when he asks questions regarding his dialysis. I can tell that he wants to know. Which is a very good thing. He browses the internet looking for answers his doctor should be giving him.
This is really bad. We really need a support system for people on dialysis in India. Where people can go to when they are faced with problems like this. Some doctors can be quite vindictive if they realize you are taking action against them. We need a system by which patients can be educated on their options and how to get the answers they want without compromising their treatment due to the offended sensibilities of their doctors.
Merely blogging about this is not enough.
at July 17, 2009 1 comment:
To start or not to start - that is the question
This incident really brought back all the questions I have always had about my home hemodialysis and more importantly, whether I should start the treatment myself or not.
Whatever you say, there is an element of risk involved. But then, you can argue, isn't life itself full of risks? There are tons of people doing home hemo all over the world. Many people do it alone at home without anyone to call out to for help in case of an emergency.
There is one important difference between their situation and mine. Training. Everyone I know on home hemo has undergone four to six weeks of formal training. They are taught what to do in case of an emergency. What to do when something goes wrong. How to recover quickly from an error.
We are humans, after all. We are bound to make a mistake once in a way. The important thing is to recover from the mistake, take corrective action and get on with the treatment. That is one thing that I sorely lack. The ability to get out of a mess caused by a mistake.
Even techs or nurses in a hospital or dialysis center setting make mistakes. I have lost a circuit of blood once many years back. But since they have the infrastructure and the training to deal with them, it is is usually not a problem.
Also, since I am undergoing dialysis daily, the process is in itself, much gentler compared to conventional in-center hemodialysis. So, the chances of anything wrong happening during the treatment itself is much lower. The risk is of human error while starting and closing dialysis.
Yes, a checklist will help. I must try this. The only thing is, once you use the checklist for a few days, you tend to get complacent and not go through the list. Anyway, for a few days atleast, I am not going to start treatment on my own. Or at best, will start only when the tech is present.
at July 16, 2009 No comments:
A really scary incident
Yesterday, my dialysis tech was going to be late. He's going through some pretty tough times professionally. He came early, primed the dialyser and tubes and got everything ready and left. I was to cannulate and start the treatment myself.
By the time I got back from work, he had already left. He was to return a few hours later and did not want to delay my dialysis session. I had dinner and then started the process.
I first cannulated myself. No problems. I was anyway doing this even when he was there. Then came the part where I connect the needles to the tubes. I connected the arterial tube and then realized that that the dialysate flow was off. This is usually done when there was a long gap between the time you primed and the time you started the session.
I quickly started the flow. But the conductivity takes time to come to the normal level once you start the flow. By the time the blood had reached the end of the line, the conductivity had not yet reached the normal level and gave an alarm. I connected the venous line and thought I would have to "reset" a few times for it to settle down.
For some reason the Trans Membrane Pressure (TMP) shot up to its maximum level and so did the venous pressure. I was surprised. This had never happened before. I tried resetting a few times. No change. Then suddenly, blood started coming out from the dialyser's two ends. I started to panic. I noticed that the tubes were not screwed tightly enough. I tightened both ends. The blood stopped leaking. The alarm however did not stop. The TMP and venous pressure continued to be at their maximum levels. Dialysis was not happening.
Blood had also gone through the venous line into the protector. The venous chamber was also full.
I shouted out to my mother and asked her to call the tech and put the phone to my ear. I got him on the line and explained the situation. By then the blood in the tube had become quite dark and was almost black. He asked me to check if the clamps on the tube and the needles were open. That was it. The venous clamp was closed on the tube at the point of connecting to the needles. I opened it immediately.
The alarms still did not stop. The TMP and venous pressure were still at their maximum levels. I removed the venous chamber from the Air Bubble Detector and also removed the venous line from the protector. To no avail.
The tech then said he was on his way. He sent his brother, also a dialysis tech who arrived in about 10 minutes. All this while, I had the venous chamber in my right hand and was resetting the machine with the left. The blood was regaining its natural color. But the alarms were not letting up.
He asked me to lie on my bed. I did. He then put the venous chamber back. With a syringe he cleared the protector of the blood and reduced the level of blood in the venous chamber. The alarms finally abated.
The brother of the tech wanted to leave as they were all having dinner out. My mother would have none of it. She said there had to be one person during my dialysis session. The tech came about an hour later and his brother then left.
The one mistake of not opening the clamp caused all this. I was quite shaken.
I love you Prateeka!
Prateeka who?
The host (RJ) of Full2Bindaas.
What Full2Bindaas?
A show on 93.5 SFM.
What 93.5 SFM?
A radio station in Hyderabad.
When does it air?
Every evening 6 to 7 in the evening.
Why all the luv-shuv?
Well, she is really funny. In a different way. Very silly. Despite that, can make you laugh uncontrollably! She speaks in a mixture of Telugu, Hindi and English, plays Hindi and Telugu songs. Is famous for "cutting" people. Totally insulting them (in a funny way). Some people find it "faltu". It is meant to be. I like "faltu" stuff sometimes!
Every day, she chooses some question. People have to call in to a number and tell her the answer to the question. You can also SMS your answer to the question. She reads a few of the SMSes on the show too. Simple questions. For example, how would you spend Rs 10? Or on a rainy day, what would you really like to eat or drink and where? Who would you take with you to the moon? For the last question, she added, "Now don't say boyfriend/girlfriend!"
It is usually on on my way back from work. It is the perfect way to relax after a tiring day.
Keep going Prateeka!
Mayawati's monument mania
Aren't statues of only dead people erected? Not any longer.
Mayawati has taken Indian politics to a new low by spending around Rs. 1,000 crores on building mammoth monuments that has statues of Ambedkar, Kanshi Ram and herself apart from hundreds of huge elephants, her party's symbol. This is really ridiculous. Never before in the country's history have we heard people erecting their own statues. When she got to know that the Supreme Court was going to hear a PIL regarding this, she advanced the inauguration of these monuments.
The court has given her four weeks to respond on this.
Mayawati's actions have been the most blatant example of self-aggrandizement we have seen in recent times. The levels of corruption in Uttar Pradesh, one of the poorest states in the country have risen dramatically. There are fixed rates for government contracts. Everyone knows about this. Nobody can do anything about it.
The self-proclaimed messiah of the dalits could have spent this money for their upliftment instead of pandering to her own ego. Imagine how much can be done with this money! Yet, despite all this, she continues to be regarded as the hope of the dalits by many.
These are instances where I feel the judiciary needs to act more strongly and proactively. There should be more stringent action and punishment. People like Mayawati need to be taught a lesson they will not forget. They need to told, in no uncertain terms, that they cannot take the country for a ride.
Dear Nicky
First of all, thanks for awarding me on your blog! I am so excited! Wow, the "Most Thoughtful Posts which also make the reader think award". Sounds quite good. I never realized my posts were thoughtful. I consider my blog to be very mundane, about the simple things in life. Swimming, idlis, dialysis etc.
Anyway, I am writing this to you to let you (and through the blog others) know how much I appreciate you and your blog. Girls like you are very hard to come across. Fearless, frank, WYSIWYG.
I have for the longest time appreciated girls who are of the traditional kind. Home makers, shy, not too ambitious. Well, yes, I know you are going to hate me for this. But, hang on, I have changed over time. No, seriously!
One complaint I have though - some readers of my blog have followed the links to your blog on your comments to my posts and have become fans of your blog. So much so, they are now more regular readers of your blog than mine!!
Thanks again Nicky for the award. It means a lot to me!
(P.S. Those who haven't read Nicky's blog, please do so. It is freakin' awesome. It is called BitchSena. Need I say more?)
Co-founder of NephroPlus
Founder of Dialysis in India
Founder of The Atypical HUS India Foundation
Trustee Director of The aHUS Alliance Action
Books I am reading now
The Almanack of Naval Ravikant: A Guide to Wealth and Happiness by Eric Jorgenson, Jack Butcher, Tim Ferriss
Man's Eternal Quest: Collected Talks & Essays on Realizing God in Daily Life, Volume I by Paramahansa Yogananda
Why the BIG project failed - Efficient and Intelli...
aarogyasri
artificial kidney
Atypical HUS India
dialysis academy
dialysis policy
dialysis.org.in
Effigent
global HHD experts forum
hello kidney
hkf
home hemo
home hemo training
know your dialysis
Nephroplus
Sunday Me Blog
US trip
WebObjects
'Wish you the same'
Know your dialysis: Conductivity
Two little Elevator button rules to use in life