X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fx11.c;h=3440210627907698c0c4454d5c74c29bc9421a01;hb=a8b2caa1d373c84c1b3fc2f615370c2a319051ca;hp=b91c410d7abb01a6dc4471d80d2bbf1e4f561435;hpb=52189f4b3b797e08699f67880198b585320cf8bf;p=rocksndiamonds.git diff --git a/src/x11.c b/src/x11.c index b91c410d..34402106 100644 --- a/src/x11.c +++ b/src/x11.c @@ -12,6 +12,195 @@ * x11.c * ***********************************************************/ -#ifdef USE_X11_LIBRARY +#ifdef TARGET_X11 -#endif /* USE_X11_LIBRARY */ +#include "main.h" +#include "misc.h" + +struct IconFileInfo +{ + char *picture_filename; + char *picturemask_filename; +}; + +static void X11InitDisplay() +{ +#ifndef MSDOS + XVisualInfo vinfo_template, *vinfo; + int num_visuals; +#endif + unsigned int depth; + + /* connect to X server */ + if (!(display = XOpenDisplay(options.display_name))) + Error(ERR_EXIT, "cannot connect to X server %s", + XDisplayName(options.display_name)); + + screen = DefaultScreen(display); + visual = DefaultVisual(display, screen); + depth = DefaultDepth(display, screen); + cmap = DefaultColormap(display, screen); + +#ifndef MSDOS + /* look for good enough visual */ + vinfo_template.screen = screen; + vinfo_template.class = (depth == 8 ? PseudoColor : TrueColor); + vinfo_template.depth = depth; + if ((vinfo = XGetVisualInfo(display, VisualScreenMask | VisualClassMask | + VisualDepthMask, &vinfo_template, &num_visuals))) + { + visual = vinfo->visual; + XFree((void *)vinfo); + } + + /* got appropriate visual? */ + if (depth < 8) + { + printf("Sorry, displays with less than 8 bits per pixel not supported.\n"); + exit(-1); + } + else if ((depth ==8 && visual->class != PseudoColor) || + (depth > 8 && visual->class != TrueColor && + visual->class != DirectColor)) + { + printf("Sorry, cannot get appropriate visual.\n"); + exit(-1); + } +#endif /* !MSDOS */ +} + +static DrawWindow X11InitWindow() +{ + Window window; + unsigned int border_width = 4; + XGCValues gc_values; + unsigned long gc_valuemask; +#ifndef MSDOS + XTextProperty windowName, iconName; + Pixmap icon_pixmap, iconmask_pixmap; + unsigned int icon_width, icon_height; + int icon_hot_x, icon_hot_y; + char icon_filename[256]; + XSizeHints size_hints; + XWMHints wm_hints; + XClassHint class_hints; + char *window_name = WINDOW_TITLE_STRING; + char *icon_name = WINDOW_TITLE_STRING; + long window_event_mask; + Atom proto_atom = None, delete_atom = None; +#endif + int screen_width, screen_height; + int win_xpos = WIN_XPOS, win_ypos = WIN_YPOS; + unsigned long pen_fg = WhitePixel(display,screen); + unsigned long pen_bg = BlackPixel(display,screen); + const int width = WIN_XSIZE, height = WIN_YSIZE; + +#ifndef MSDOS + static struct IconFileInfo icon_pic = + { + "rocks_icon.xbm", + "rocks_iconmask.xbm" + }; +#endif + + screen_width = XDisplayWidth(display, screen); + screen_height = XDisplayHeight(display, screen); + + win_xpos = (screen_width - width) / 2; + win_ypos = (screen_height - height) / 2; + + window = XCreateSimpleWindow(display, RootWindow(display, screen), + win_xpos, win_ypos, width, height, border_width, + pen_fg, pen_bg); + +#ifndef MSDOS + proto_atom = XInternAtom(display, "WM_PROTOCOLS", FALSE); + delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", FALSE); + if ((proto_atom != None) && (delete_atom != None)) + XChangeProperty(display, window, proto_atom, XA_ATOM, 32, + PropModePrepend, (unsigned char *) &delete_atom, 1); + + sprintf(icon_filename, "%s/%s/%s", + options.ro_base_directory, GRAPHICS_DIRECTORY, + icon_pic.picture_filename); + XReadBitmapFile(display,window,icon_filename, + &icon_width,&icon_height, + &icon_pixmap,&icon_hot_x,&icon_hot_y); + if (!icon_pixmap) + Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename); + + sprintf(icon_filename, "%s/%s/%s", + options.ro_base_directory, GRAPHICS_DIRECTORY, + icon_pic.picturemask_filename); + XReadBitmapFile(display,window,icon_filename, + &icon_width,&icon_height, + &iconmask_pixmap,&icon_hot_x,&icon_hot_y); + if (!iconmask_pixmap) + Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename); + + size_hints.width = size_hints.min_width = size_hints.max_width = width; + size_hints.height = size_hints.min_height = size_hints.max_height = height; + size_hints.flags = PSize | PMinSize | PMaxSize; + + if (win_xpos || win_ypos) + { + size_hints.x = win_xpos; + size_hints.y = win_ypos; + size_hints.flags |= PPosition; + } + + if (!XStringListToTextProperty(&window_name, 1, &windowName)) + Error(ERR_EXIT, "structure allocation for windowName failed"); + + if (!XStringListToTextProperty(&icon_name, 1, &iconName)) + Error(ERR_EXIT, "structure allocation for iconName failed"); + + wm_hints.initial_state = NormalState; + wm_hints.input = True; + wm_hints.icon_pixmap = icon_pixmap; + wm_hints.icon_mask = iconmask_pixmap; + wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint; + + class_hints.res_name = program_name; + class_hints.res_class = "Rocks'n'Diamonds"; + + XSetWMProperties(display, window, &windowName, &iconName, + NULL, 0, &size_hints, &wm_hints, + &class_hints); + + XFree(windowName.value); + XFree(iconName.value); + + /* Select event types wanted */ + window_event_mask = + ExposureMask | StructureNotifyMask | FocusChangeMask | + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | + PointerMotionHintMask | KeyPressMask | KeyReleaseMask; + + XSelectInput(display, window, window_event_mask); +#endif + + /* create GC for drawing with window depth and background color (black) */ + gc_values.graphics_exposures = False; + gc_values.foreground = pen_bg; + gc_values.background = pen_bg; + gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground; + gc = XCreateGC(display, window, gc_valuemask, &gc_values); + + return window; +} + +inline void X11InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) +{ + X11InitDisplay(); + *window = X11InitWindow(); + + XMapWindow(display, *window); + FlushDisplay(); + + /* create additional buffer for double-buffering */ + *backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); + pix[PIX_DB_BACK] = *backbuffer; /* 'backbuffer' is off-screen buffer */ +} + +#endif /* TARGET_X11 */