/* %Z%%M% %I% %E% */

/*
 * Copyright (c) 1994-2005 by Wayne C. Gramlich.
 * All rights reserved.
 */

/*
 * This file provide a bunch of interface routines for accessing objects
 * of type Display from Xlib from STIPPLE code.
 */

#ifndef XLIB_H
#include "xlib.h"
#endif

extern Vector vector__allocate(void);
extern void vector__append(Vector, void *);

/* The initial object: */
Xlib_screen_struct xlib_screen___initial_object = {
    0,
    &xlib_display___initial_object,
    &xlib_window___initial_object,
    0
};
Xlib_screen xlib_screen___initial = &xlib_screen___initial_object;

/*
 * xlib_screen__address_get(screen)
 *	This routine will return the address of {screen}.
 */
unsigned
xlib_screen__address_get(
    Xlib_screen screen)
{
    return (unsigned)screen;
}

/*
 * xlib_screen__black_pixel_get(screen)
 *	This routine will return the "black" pixel associated with {screen}.
 */
Xlib_pixel
xlib_screen__black_pixel_get(
    Xlib_screen screen)
{
    Xlib_display display;
    Xlib_pixel pixel;

    display = screen->display;
    if (display->closed) {
	xlib_display___closed(display);
	pixel = (Xlib_pixel)0;
    } else {
	pixel = (Xlib_pixel)BlackPixel(display->display, screen->number);
    }
    return pixel;
}

/*
 * xlib_screen__close(screen)
 *	This routine will close make {screen} no longer useful.
 */
void
xlib_screen__close(
    Xlib_screen screen)
{
    screen->depth = 0;
    screen->display = xlib_display___initial;
    screen->root_window = xlib_window___initial;
    screen->number = 0;
}

/*
 * xlib_screen__closed_get(screen)
 *	This routine will return 1 if the connection to the X server
 *	is closed and 0 otherwise.
 */
int
xlib_screen__closed_get(
    Xlib_screen screen)
{
    return screen->display->closed;
}

/*
 * xlib_screen__default_open(display)
 *	This routine will return the default screen associated with {display}.
 */
Xlib_screen
xlib_screen__default_open(
    Xlib_display display)
{
    Xlib_screen screen;

    screen = xlib_screen___initial;
    if (display->closed) {
	xlib_display___closed(display);
    } else {
	Display *disp;
	unsigned number;
	Xlib_window root_window;

	screen = (Xlib_screen)malloc(sizeof(*screen));
	disp = display->display;
	number = DefaultScreen(disp);
	root_window = xlib_window___create(screen,
	  RootWindow(disp, number), (Xlib_window)0);

	screen->depth = XDisplayPlanes(disp, number);
	screen->display = display;
	screen->number = number;
	screen->root_window = root_window;
    }
    return screen;
}

/*
 * xlib_screen__display_get(screen)
 *	This routine will return the {Xlib_display} object associated with
 *	{screen}.
 */
Xlib_display
xlib_screen__display_get(
    Xlib_screen screen)
{
    return screen->display;
}

/*
 * xlib_screen__depth_get(screen)
 *	This returns the depth of {screen}.
 */
unsigned
xlib_screen__depth_get(
    Xlib_screen screen)
{
    return screen->depth;
}

/*
 * xlib_screen__depths_get(screen)
 *	This routine will return a vector of pixel depths associated
 *	with {screen}.
 */
Vector
xlib_screen__depths_get(
    Xlib_screen screen)
{
    int count;
    Vector depths;
    int *depths_ptr;
    Xlib_display display;
    int index;

    depths = vector__allocate();
    display = screen->display;
    if (display->closed) {
	xlib_display___closed(display);
    } else {
	depths_ptr = XListDepths(display->display, screen->number, &count);
	for (index = 0; index < count; index++) {
	    vector__append(depths, (void *)depths_ptr[index]);
	}
	XFree(depths_ptr);
    }
    return depths;
}

/*
 * xlib_screen__height_get(screen)
 *	This routine will return the height of {screen} in pixels.
 */
unsigned
xlib_screen__height_get(
    Xlib_screen screen)
{
    Xlib_display display;
    unsigned height;

    display = screen->display;
    if  (display->closed) {
	xlib_display___closed(display);
	height = 0;
    } else {
	height = DisplayHeight(display->display, screen->number);
    }
    return height;
}

/*
 * xlib_screen__external__initialize()
 *	This routine will "initialize" the {xlib_screen} external
 *	code.
 */
void
xlib_screen__external__initialize(void)
{
    assert(xlib_screen___initial == &xlib_screen___initial_object);
}

/*
 * xlib_screen__icon_sizes(_screen)
 *	This routine will return the vector of {Xlib_icon_size} objects
 *	associated with {screen}.
 */
Vector
xlib_screen__icon_sizes(
    Xlib_screen screen)
{
    Vector icon_sizes;
    Xlib_display display;

    icon_sizes = vector__allocate();
    display = screen->display;
    if (display->closed) {
	xlib_display___closed(display);
    } else {
	Display *disp;
	int size;
	XIconSize *icon_size_list;

	disp = display->display;
	if (XGetIconSizes(disp, screen->root_window->window,
	  &icon_size_list, &size) == 0) {
	    /* KDE does not have icons! */
	    /* xlib_errors___add(display->errors, "Get icon sizes failed"); */
	} else {
	    unsigned index;
	    XIconSize *icon_size;
	    Xlib_icon_size xlib_icon_size;

	    for (index = 0; index < size; index++) {
		icon_size = &icon_size_list[index];
		xlib_icon_size = xlib_icon_size__create(icon_size->max_height,
		  icon_size->min_height, icon_size->height_inc,
		  icon_size->max_width, icon_size->min_width,
		  icon_size->width_inc);
	    }
	    vector__append(icon_sizes, (void *)xlib_icon_size);
	    XFree((void *)icon_size_list);
	}
    }
    return icon_sizes;
}

/*
 * xlib_screen__number_get(screen)
 *	This routine will return the screen number associated with {screen).
 */
unsigned
xlib_screen__number_get(
    Xlib_screen screen)
{
    return screen->number;
}

/*
 * xlib_screen__root_window_get(screen)
 *	This routine will return the root window associated with {screen}.
 */
Xlib_window
xlib_screen__root_window_get(
    Xlib_screen screen)
{
    return screen->root_window;
}

/*
 * xlib_screen__white_pixel_get(screen)
 *	This routine will return the "white" pixel associated with {screen}.
 */
Xlib_pixel
xlib_screen__white_pixel_get(
    Xlib_screen screen)
{
    Xlib_display display;
    Xlib_pixel pixel;

    display = screen->display;
    if (display->closed) {
	xlib_display___closed(display);
	pixel = (Xlib_pixel)0;
    } else {
	pixel = (Xlib_pixel)WhitePixel(display->display, screen->number);
    }
    return pixel;
}

/*
 * xlib_screen__width_get(screen)
 *	This routine will return the width of {display} is pixels.
 */
unsigned
xlib_screen__width_get(
    Xlib_screen screen)
{
    unsigned width;
    Xlib_display display;

    display = screen->display;
    if (display->closed) {
	xlib_display___closed(display);
	width = 0;
    } else {
	width = DisplayWidth(display->display, screen->number);
    }
    return width;
}

/*
 * xlib_screen__xlib_display_get(screen)
 *	This routine will return the {xlib_display} associated with
 *	{screen}.
 */
Xlib_display
xlib_screen__xlib_display_get(
    Xlib_screen screen)
{
    return screen->display;
}



