xclass.cpp 7.99 KB
using namespace std;

#include <cstdio>
#include <cstdlib>
#include <cstring>

#include "xclass.h"

xdisplay::xdisplay(char* name) {
    if(name) {
        display_name=new char[strlen(name)+1];
        strcpy(display_name, name);
    }
    else {
        display_name=NULL;
    }

    /* Connect to X server */
    if ((display=XOpenDisplay(display_name)) == NULL)
        throw noconnect_exception();

    wincount=0;
    screen_anz=ScreenCount(display);
    default_screen=DefaultScreen(display);
    screens=new xscreen*[screen_anz];

    for(int i=0; i<screen_anz; i++) {
        screens[i]=new xscreen(this, i);
    }

    font_info=NULL;
}

xdisplay::xdisplay(const xdisplay& xd) {
    if(xd.display_name) {
        display_name=new char[strlen(xd.display_name)+1];
        strcpy(display_name, xd.display_name);
    }
    else {
        display_name=NULL;
    }

    display=xd.display;
    wincount=xd.wincount;
    screen_anz=xd.screen_anz;
    default_screen=xd.default_screen;
    screens=new xscreen*[screen_anz];

    for(int i=0; i<screen_anz; i++) {
        screens[i]=(xd.screens)[i];
    }

    font_info=NULL;
}

xdisplay::~xdisplay() {
    if(display_name)
        delete [] display_name;

    // das ueberlass ich dem Destructor von xscreen!
//    for(int i=0; i<wincount; i++)
//        delete wins[i];
//    delete [] wins;

    //for(int i=0; i<screen_anz; i++)
    //    delete screens[i];
    //delete [] screens;

    XCloseDisplay(display);
}

xdisplay& xdisplay::operator=(const xdisplay& xd) {
    if(xd.display_name) {
        display_name=new char[strlen(xd.display_name)+1];
        strcpy(display_name, xd.display_name);
    }
    else {
        display_name=NULL;
    }

    display=xd.display;
    wincount=xd.wincount;
    screen_anz=xd.screen_anz;
    default_screen=xd.default_screen;
    screens=new xscreen*[screen_anz];

    for(int i=0; i<screen_anz; i++) {
        screens[i]=(xd.screens)[i];
    }

    font_info=NULL;

    return *this;
}

xscreen* xdisplay::defaultscreen(void) { 
    return screens[default_screen]; 
}

void xdisplay::loadfont(char* fname) {
    /* Load font and get font information structure */
    if((font_info = XLoadQueryFont(display,fname)) == NULL)
        throw nofont_exception();
}

xscreen::xscreen(xdisplay* d, int screen_num) {
    this->screen_num=screen_num;
    this->x_disp=d;

    if(screen_num!=-1) {
        XPixmapFormatValues* pixmap_formats;
        int count;

        screen=XScreenOfDisplay(d->display, screen_num);

        width=WidthOfScreen(screen);
        height=HeightOfScreen(screen);

        default_cm=DefaultColormapOfScreen(screen);
        black_pixel=XBlackPixelOfScreen(screen);
        white_pixel=XWhitePixelOfScreen(screen);

        rootwin=new xwindow(this); // Ich kann nicht this nehmen, 
                                   // da das aktuelle Object dem 
                                   // Array zugewiesen wird und
                                   // danach weg is.

        vis=DefaultVisual(d->display, 0);

        pixmap_formats=XListPixmapFormats(d->display, &count);

        depth=0;
        for(int i=0, result=0; i<count; i++) {
            if(pixmap_formats[i].depth > depth) {
                // OK, das vi existiert jetzt nur fuer TrueColor, ich muss
                // noch fuer alle anderen VisualTypes eins einbauen.
                if(XMatchVisualInfo(d->display, d->default_screen,
                                    pixmap_formats[i].depth, TrueColor, &vi)) {
                    depth=pixmap_formats[i].depth;
                    bytespp=pixmap_formats[i].bits_per_pixel/8;
                    scanline_pad=pixmap_formats[i].scanline_pad;
                }
            }
        }

        gc=DefaultGC(d->display, d->defaultscreenid());
    }
    else {
        screen=NULL;
        rootwin=NULL;
    }
}

xscreen::xscreen(const xscreen& scr) {
    x_disp=scr.x_disp;
    screen_num=scr.screen_num;
    screen=scr.screen;
    rootwin=scr.rootwin;

    width=scr.width;
    height=scr.height;
    vis=scr.vis;

    memcpy(&vi, &scr.vi, sizeof(XVisualInfo));

    depth=scr.depth;
    bytespp=scr.bytespp;
    scanline_pad=scr.scanline_pad;

    memcpy(&gc, &scr.gc, sizeof(GC));

    default_cm=scr.default_cm;
    black_pixel=scr.black_pixel;
    white_pixel=scr.white_pixel;
}

xscreen::~xscreen() {
    delete rootwin;

    XFreeGC(x_disp->display, gc);
    XFreeColormap(x_disp->display, default_cm);
}

xscreen& xscreen::operator=(const xscreen& scr) {
    x_disp=scr.x_disp;
    screen_num=scr.screen_num;
    screen=scr.screen;
    rootwin=scr.rootwin;

    width=scr.width;
    height=scr.height;
    vis=scr.vis;

    memcpy(&vi, &scr.vi, sizeof(XVisualInfo));

    depth=scr.depth;
    bytespp=scr.bytespp;
    scanline_pad=scr.scanline_pad;

    memcpy(&gc, &scr.gc, sizeof(GC));

    default_cm=scr.default_cm;
    black_pixel=scr.black_pixel;
    white_pixel=scr.white_pixel;

    return *this;
}

xwindow* xdisplay::getXwinById(Window id) {
    int i;

    for(i=0; i<wincount; i++)
        if(wins[i]->window == id)
            return wins[i];

    return NULL;
}

xwindow::xwindow(xscreen* xs) {
    screen=xs;
    window=XRootWindowOfScreen(xs->screen);

    screen->x_disp->wincount++;
    xwindow** temp=new xwindow*[screen->x_disp->wincount];

    for(int i=0; i<screen->x_disp->wincount-1; i++)
        temp[i]=screen->x_disp->wins[i];

    temp[screen->x_disp->wincount-1]=this;
    delete[] screen->x_disp->wins;
    screen->x_disp->wins=temp;
}

xwindow::xwindow(xwindow* win, int x, int y, 
                 unsigned int bwidth, unsigned int width, 
                 unsigned int height) {
    screen=win->screen;

    window=XCreateSimpleWindow(screen->x_disp->display, win->window, 
                               x, y, width, height, bwidth,
                               screen->black_pixel, screen->white_pixel);

    screen->x_disp->wincount++;
    xwindow** temp=new xwindow*[screen->x_disp->wincount];

    for(int i=0; i<screen->x_disp->wincount-1; i++)
        temp[i]=screen->x_disp->wins[i];

    temp[screen->x_disp->wincount-1]=this;
    delete[] screen->x_disp->wins;
    screen->x_disp->wins=temp;

    XSelectInput(screen->x_disp->display, window,
                 ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask);
}

xwindow::xwindow(const xwindow& xw) {
    screen=xw.screen;

    window=xw.window;
    back=xw.back;
    swapinfo=xw.swapinfo;
}

xwindow& xwindow::operator=(const xwindow& xw) {
    screen=xw.screen;

    window=xw.window;
    back=xw.back;
    swapinfo=xw.swapinfo;

    return *this;
}

// Dies sollte nochmal in mehrere kleinere Methoden zum einstellen der
// diversen Dinge fuer den WM aufgesplittet werden.
void xwindow::initWM(void) {
    XSizeHints* size_hints;     // Informationen fuer WM ueber
                                // minimale Groessen fuer App
    XWMHints* wm_hints;         // weiter Infos fuer WM z.B. Icon
                                // Input/Output initialisierung
    XClassHint* class_hints;    // noch mehr infos fuer WM

    if (!(size_hints = XAllocSizeHints())) {
        fprintf(stderr, "failure allocating memory\n");
        exit(1); //throw exception...
    }
    if (!(wm_hints = XAllocWMHints())) {
        fprintf(stderr, "failure allocating memory\n");
        exit(1); //throw exception...
    }
    if (!(class_hints = XAllocClassHint())) {
        fprintf(stderr, "failure allocating memory\n");
        exit(1); //throw exception...
    }

    size_hints->flags = PPosition | PSize | PMinSize;
    size_hints->min_width = 300;
    size_hints->min_height = 200;

    wm_hints->initial_state = NormalState;
    wm_hints->input = True;
    // wm_hints->icon_pixmap = icon_pixmap;
    wm_hints->flags = StateHint | IconPixmapHint | InputHint;

    class_hints->res_name = "jokus"; //screen->x_disp->argv[0];
    class_hints->res_class = "Basicwin";

//    XSetWMProperties(screen->x_disp->display, window, NULL, NULL, /*&iconName*/
//                     screen->x_disp->argv, screen->x_disp->argc, size_hints, 
//                     wm_hints, class_hints);
    XStoreName(screen->x_disp->display, window, "jokus");
}