Exemple #1
0
void App::setBackground(const string& themedir) {
    string filename;
    filename = themedir + "/background.png";
    Image *image = new Image;
    bool loaded = image->Read(filename.c_str());
    if (!loaded){ // try jpeg if png failed
        filename = "";
        filename = themedir + "/background.jpg";
        loaded = image->Read(filename.c_str());
    }
    if (loaded) {
        string bgstyle = cfg.getOption("background_style");
        if (bgstyle == "stretch") {
            image->Resize(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
        } else if (bgstyle == "tile") {
            image->Tile(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
        } else if (bgstyle == "center") {
    	    string hexvalue = cfg.getOption("background_color");
            hexvalue = hexvalue.substr(1,6);
    	    image->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
        			    hexvalue.c_str());
        } else { // plain color or error
    	    string hexvalue = cfg.getOption("background_color");
            hexvalue = hexvalue.substr(1,6);
    	    image->Center(XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)), XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)),
        			    hexvalue.c_str());
        }
        Pixmap p = image->createPixmap(Dpy, Scr, Root);
        XSetWindowBackgroundPixmap(Dpy, Root, p);
    }
    XClearWindow(Dpy, Root);

    XFlush(Dpy);
}
Exemple #2
0
/**
@brief    This function places a popup menu either above or below a particular widget.
          It is placed above the widget to prevent it going off the bottom of the screen.
          The x,y needs to be supplied because the x,y of the calling widget will be relative to its parent, not the screen.
@return   void
**/
void 
place_popup_menu(Display *display, Window calling_widget, Window popup_menu, int x, int y) {
  Screen* screen = DefaultScreenOfDisplay(display);
  XWindowAttributes details;
  XWindowAttributes popup_details;

  XGetWindowAttributes(display, calling_widget, &details);
  XGetWindowAttributes(display, popup_menu, &popup_details);  
  
  int width  = popup_details.width;
  int height = popup_details.height;

  y += details.height;

  if(y + height > XHeightOfScreen(screen)) y = y - (details.height + height); //either side of the widget
  if(y < 0) y = XHeightOfScreen(screen) - height;  
  if(x + width > XWidthOfScreen(screen)) x = XWidthOfScreen(screen) - width;
  //printf("width is %d\n", width);
  XMoveWindow(display, popup_menu, x, y);
  XRaiseWindow(display, popup_menu);
//  xcheck_raisewin(display, popup_menu);
  XMapWindow(display, popup_menu);
  XFlush(display);
  //printf("placed popup\n");
}
Exemple #3
0
/**
@pre      display is valid, themes is valid, cursors is valid.
@pre      all widgets are zero'd.
@pre      themes is valid and has loaded at least a background for the popup_menu_parent. 
@post     Menu with borders and background but no items is created but not mapped.
@brief    This function is used to create a blank and generic menu.  Items must be added by caller.
@return   void
**/
void 
create_popup_menu(Display *display, struct Popup_menu *menu, struct Themes *themes, struct Cursors *cursors) {

  XSetWindowAttributes set_attributes;
  Window root = DefaultRootWindow(display);
  Screen* screen = DefaultScreenOfDisplay(display);
  int black = BlackPixelOfScreen(screen);
  
  const int width = menu->inner_width + themes->popup_menu[popup_l_edge].w + themes->popup_menu[popup_r_edge].w;
  const int height = menu->inner_height + themes->popup_menu[popup_t_edge].h + themes->popup_menu[popup_b_edge].h;
  
  menu->widgets[popup_menu_parent].widget = XCreateSimpleWindow(display, root
  , 0, 0
  , width, height, 0, black, black);

  XDefineCursor(display, menu->widgets[popup_menu_parent].widget, cursors->normal);
  XSetWindowBackgroundPixmap(display, menu->widgets[popup_menu_parent].widget
  , themes->popup_menu[popup_menu_parent].state_p[normal]);
   
  //Currently, this is the "base" of the popup menu.
  //A similar loop will be needed for the actual menu items but not in this function
  for(int i = popup_t_edge; i < popup_menu_parent; i++) { //popup_menu_parent already done

    int x = themes->popup_menu[i].x;
    int y = themes->popup_menu[i].y;
    int w = themes->popup_menu[i].w;
    int h = themes->popup_menu[i].h;
    
    if(x < 0)  x += width;
    if(y < 0)  y += height; 
    if(w <= 0) w += width;
    if(h <= 0) h += height;
  
    menu->widgets[i].widget = XCreateSimpleWindow(display
    , menu->widgets[popup_menu_parent].widget
    , x, y, w, h, 0, black, black);
    
    if(themes->popup_menu[i].w <= 0) w = XWidthOfScreen(screen);
    if(themes->popup_menu[i].h <= 0) h = XWidthOfScreen(screen);    
    for(int j = 0; j <= inactive; j++) {
      if(themes->popup_menu[i].state_p[j]) {
        menu->widgets[i].state[j] = XCreateSimpleWindow(display, menu->widgets[i].widget
        , 0, 0, w, h, 0, black, black);
        XSetWindowBackgroundPixmap(display, menu->widgets[i].state[j]
        , themes->popup_menu[i].state_p[j]);
        if(j == normal) XMapWindow(display, menu->widgets[i].state[j]);
      }
    }

    XMapWindow(display, menu->widgets[i].widget);
  } 

  set_attributes.override_redirect = True; 
  XChangeWindowAttributes(display, menu->widgets[popup_menu_parent].widget, CWOverrideRedirect, &set_attributes);

//  XMapWindow(display, menu->widgets[popup_menu_parent].widget);
  XFlush(display);


}
Exemple #4
0
static void SplashCenter(Splash * splash) {
    Atom type, atom, actual_type;
    int status, actual_format;
    unsigned long nitems, bytes_after;
    CARD16 *prop = NULL;

    /*  try centering using Xinerama hint
        if there's no hint, use the center of the screen */
    atom = XInternAtom(splash->display, "XINERAMA_CENTER_HINT", True);
    if (atom != None) {
        status = XGetWindowProperty(splash->display,
            XRootWindowOfScreen(splash->screen), atom, 0, 1, False, XA_INTEGER,
            &actual_type, &actual_format, &nitems,
            &bytes_after, (unsigned char**)(&prop));
        if (status == Success && actual_type != None && prop != NULL) {
            splash->x = prop[0] - splash->width/2;
            splash->y = prop[1] - splash->height/2;
            XFree(prop);
            return;
        }
        if (prop != NULL) {
            XFree(prop);
        }
    }
    splash->x = (XWidthOfScreen(splash->screen) - splash->width) / 2;
    splash->y = (XHeightOfScreen(splash->screen) - splash->height) / 2;
}
Exemple #5
0
int main(void)
{
	Display *display;
	Window window;
	XEvent event;

	display = XOpenDisplay(NULL);
	if (display == NULL) {
		fprintf(stderr, "Error: Cannot open display!\n");
		return 1;
	}

	int width = XWidthOfScreen(ScreenOfDisplay(display, DefaultScreen(display)));
	int height = XHeightOfScreen(ScreenOfDisplay(display, DefaultScreen(display)));
	int blackColor = BlackPixel(display, DefaultScreen(display));
	window = XCreateSimpleWindow(display, DefaultRootWindow(display), 
				0, 0, width, height, 0, blackColor, blackColor);

	Atom delwindow = XInternAtom(display, "WM_DELETE_WINDOW", 0);
	XSetWMProtocols(display, window, &delwindow, 1);

	XMapWindow(display, window);

	for(;;) {
		XNextEvent(display, &event);
		if (event.type == ClientMessage)
			break;
	}

	XDestroyWindow(display, window);
	XCloseDisplay(display);

	return 0;
}
HelloWorld::HelloWorld(Display* display) :
    _game() {

    _display = display;
    _screen = XDefaultScreenOfDisplay(display);

    _blackColor = BlackPixelOfScreen(_screen);
    _whiteColor = WhitePixelOfScreen(_screen);
    _font = XLoadFont(_display, WINDOW_FONT);

    int screenWidth = XWidthOfScreen(_screen);
    int screenHeight = XHeightOfScreen(_screen);

    int windowWidth = MIN_CELL_SIZE * 3;
    int windowHeight = MIN_CELL_SIZE * 3 + STRING_HEIGHT * 3;
    int windowX = (screenWidth + windowWidth) / 2;
    int windowY = (screenHeight + windowHeight) / 2;
    _window = XCreateSimpleWindow(_display, XRootWindowOfScreen(_screen),
            windowX, windowY, windowWidth, windowHeight, 1, _blackColor,
            _whiteColor);

    long eventMask = ButtonPressMask | ExposureMask | KeyPressMask;
    XSelectInput(_display, _window, eventMask);

    draw();
}
Exemple #7
0
int main(int argc, char *argv[])
{
	struct sigaction act;

	if(!(display = XOpenDisplay(DISPLAY))){
		LOG("BARE: cannot open display! Ending session.\n");
		return -1;
	}
	if((root = DefaultRootWindow(display)))
	{
		XSetWindowBackground(display, root, BlackPixel(display, XDefaultScreen(display)));
		XClearWindow(display, root);
	} else {
		LOG("BARE: cannot get root window! Ending session.\n");
		return -1;
	}
	if((screen = DefaultScreenOfDisplay(display)))
	{
		SCREEN_WIDTH 	= XWidthOfScreen(screen);
		SCREEN_HEIGHT 	= XHeightOfScreen(screen);
		LOG("Screen: %d x %d\n", SCREEN_WIDTH, SCREEN_HEIGHT);
	} else {
		LOG("BARE: cannot get screen! Ending session.\n");
		return -1;	
	}
	selected = root;
	fontstruct = XLoadQueryFont(display, FONT);
	if (!fontstruct) {
		LOG("Couldn't find font \"%s\", loading default\n", FONT);
		fontstruct = XLoadQueryFont(display, "-*-fixed-medium-r-*-*-12-*-*-*-*-*-iso8859-1");
		if (!fontstruct) {
			LOG("Couldn't load default fixed font. Something is seriouslly wrong. Ending session.\n");
			return -1;		
		}

	}
	XDefineCursor(display, selected, (XCreateFontCursor(display, CURSOR)));
	grab_keyboard();	
	XSelectInput(display, root, SubstructureNotifyMask | SubstructureRedirectMask | KeyPressMask); 

	BARE_colormap = DefaultColormap(display, 0);
	init_gc();
	message("Welcome to Bare WM v%s", VERSION);
	
	act.sa_handler = sighandler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = SA_NOCLDSTOP | SA_RESTART ;
	sigaction(SIGCHLD, &act, NULL);

	
	main_loop();

	XFree(BARE_GC);
	XFree(BARE_SELECTEDFG_GC);
	XCloseDisplay(display);
	return 0;
}
Exemple #8
0
void App::blankScreen()
{
    GC gc = XCreateGC(Dpy, Root, 0, 0);
    XSetForeground(Dpy, gc, BlackPixel(Dpy, Scr));
    XFillRectangle(Dpy, Root, gc, 0, 0,
                   XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)),
                   XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)));
    XFlush(Dpy);
    XFreeGC(Dpy, gc);

}
Exemple #9
0
int main() {
    // Open $DISPLAY
    Display *display = XOpenDisplay(NULL);
    // Get screen 0
    Screen *screen = XScreenOfDisplay(display, 0);
    int screen_w = XWidthOfScreen(screen);
    int screen_h = XHeightOfScreen(screen);

    printf("width\t: %i\n", screen_w);
    printf("height\t: %i\n", screen_h);

    return 0;
}
Exemple #10
0
void App::Console() {
    int posx = 40;
    int posy = 40;
    int fontx = 9;
    int fonty = 15;
    int width = (XWidthOfScreen(ScreenOfDisplay(Dpy, Scr)) - (posx * 2)) / fontx;
    int height = (XHeightOfScreen(ScreenOfDisplay(Dpy, Scr)) - (posy * 2)) / fonty;

    // Execute console
    const char* cmd = cfg.getOption("console_cmd").c_str();
    char *tmp = new char[strlen(cmd) + 60];
    sprintf(tmp, cmd, width, height, posx, posy, fontx, fonty);
    system(tmp);
    delete [] tmp;
}
Exemple #11
0
int *
get_screen_dims ()
{
	int		* ret;
	Display	* display;
	Screen	* screen;

	ret = (int *) malloc (2 * sizeof (int));
	ret[0] = ret[1] = 0;

	display = XOpenDisplay (NULL);
	screen = XDefaultScreenOfDisplay (display);
	ret[0] = XWidthOfScreen (screen);
	ret[1] = XHeightOfScreen (screen);

	return ret;
}
Exemple #12
0
/*ARGSUSED*/
void 
PrintThisManpage(Widget w, XEvent * event, String * params, Cardinal * num_params)
{
  ManpageGlobals *mg = GetGlobals(w);
  Dimension       width, height;
  Position        x, y;
  Widget          parent    = mg->This_Manpage;
  Widget          topwindow = mg->This_Manpage;
  Log(("print!\n"));
  
  if (!mg->printdialog) {
    int n;
    Arg args[20];

    n = 0;
    XtSetArg(args[n], XtNallowShellResize, True); n++;
    mg->printdialog_shell = XtCreatePopupShell("printdialogshell",
                                               transientShellWidgetClass,
                                               topwindow, args, n);
    n = 0;
    mg->printdialog = XtCreateManagedWidget("printdialog", printDialogWidgetClass,
                                            mg->printdialog_shell, args, n);
    XtAddCallback(mg->printdialog, XawNOkCallback,     printOKXtProc,     NULL);
    XtAddCallback(mg->printdialog, XawNCancelCallback, printCancelXtProc, NULL);

    XtRealizeWidget(mg->printdialog_shell);
  }

  /* Center dialog */
  XtVaGetValues(mg->printdialog_shell,
      XtNwidth,  &width,
      XtNheight, &height,
      NULL);

  x = (Position)(XWidthOfScreen( XtScreen(parent)) - width)  / 2;
  y = (Position)(XHeightOfScreen(XtScreen(parent)) - height) / 3;

  XtVaSetValues(mg->printdialog_shell,
      XtNx, x,
      XtNy, y,
      NULL);
        
  XtPopup(mg->printdialog_shell, XtGrabNonexclusive);
}
Exemple #13
0
int_fast32_t x11_screen_geo(Display *dpy, const int_fast32_t screen,
	int_fast32_t *w, int_fast32_t *h)
{
	Screen *scr;

	if (!dpy || screen < 0 || screen >= XScreenCount(dpy))
		goto fail;

	scr = XScreenOfDisplay(dpy, screen);
	if (!scr)
		goto fail;

	*w = XWidthOfScreen(scr);
	*h = XHeightOfScreen(scr);

	return 0;
fail:
	*w = *h = 0;
	return -1;
}
Exemple #14
0
/* ------------------------------------------------------------------ */ 
int initGraphics() 
{
  theDisplay = XOpenDisplay(XDisplayName(NULL));
  if (theDisplay == NULL) {
    printf("You need to run the program under X-window.\n\n");
    exit(1);
  }
  theScreen  = XDefaultScreen(theDisplay);
  rootW      =  RootWindow(theDisplay, theScreen);
  theGC      = XDefaultGC(theDisplay, theScreen);
  theCmap    = XDefaultColormap(theDisplay, theScreen);
  theVisual  =  DefaultVisual(theDisplay, theScreen);
  theDepth   = XDefaultDepth(theDisplay, theScreen);
  // fprintf(stderr, "Visual %x Depth %d\n",  theVisual, theDepth);

  pScreen    = XDefaultScreenOfDisplay(theDisplay);
  sW         = XWidthOfScreen(pScreen);
  sH         = XHeightOfScreen(pScreen);
  theFont    = XLoadFont(theDisplay, FONT10 );
  XSetFont(theDisplay, theGC, theFont);

  return 0;
}
Exemple #15
0
void
AutoInvokePerformMonitor()
{
  enum WHICH_TIME get_which_time;
  extern void AutoGetTime();
  Widget PB;
  Arg args[MAX_ARGS];
  int n;


  if (MonitorOn == True)  {
    Command_In_Progress = True;
    /* Use SyncWidget to synchronize the timing of the performance
       monitor wrt the events in the queue.
     */
    if (SyncWidgetCreated != True)  {
      n = 0;
      XtSetArg(args[n], XtNwidth, SYNCWIDTH);                                n++;
      XtSetArg(args[n], XtNheight, SYNCHEIGHT);                              n++;
      XtSetArg(args[n], XtNy, (XHeightOfScreen(screen) - (SYNCHEIGHT+5)));   n++;
      XtSetArg(args[n], XtNx, (XWidthOfScreen(screen) - (SYNCWIDTH+5)));     n++;
      XtSetArg(args[n], XmNpopdownCallback, PopdownCR);                      n++;
      SyncWidget = XtCreatePopupShell ("SyncWidget", topLevelShellWidgetClass,
				       Shell1, args, n);
      XtRealizeWidget(SyncWidget);
      XtPopup(SyncWidget, XtGrabNone);
      SyncWidgetCreated = True;
    }
    else if (SyncWidgetPoppedup == False)  {
      XtPopup(SyncWidget, XtGrabNone);
    }
    SyncWidgetPoppedup = True;
    get_which_time = START_TIME;
    AutoGetTime(get_which_time);
  }
}
Exemple #16
0
int main(int argc, char *argv[])
{
    int i,j,k,ysize,xsize,header,winY,winX,bysize,bxsize,ret;
    int border,menubar,xmin,ymin,nrow,ncol,nwin;
    char cmdbuf[100],PR[80];

    Display *myDisplay;
    Screen  *myScreen;

    myDisplay= XOpenDisplay("");
    myScreen = DefaultScreenOfDisplay(myDisplay);
    winX = XWidthOfScreen(myScreen);
    winY = XHeightOfScreen(myScreen);
    ret = XCloseDisplay(myDisplay);

    sprintf(PR,"%s","tilesg");

    /* platform parameters (these are for MacOSX): */
    menubar=20;
    /* generic parameters: */
    header=20;
    border=2;

    /* handles args; determine which Vio object to create (file/unix/inet) */
    if (argc == 4) {
        nrow = atoi(argv[1]);
        ncol = atoi(argv[2]);
        nwin = atoi(argv[3]);
    } else {
        fprintf(stderr,"\n");
        fprintf(stderr, "Usage: %s rows cols nwin\n",PR);
        fprintf(stderr,"\n");
        fprintf(stderr,"   Parameter interpretation:\n\n");
        fprintf(stderr,"    rows = number of rows\n");
        fprintf(stderr,"    cols = number of columns\n");
        fprintf(stderr,"    nwin = number of windows\n");
        fprintf(stderr,"\n");
        return 0;
    }

    /* ratio=5/7 */
    ysize = (winY-menubar)/nrow - header - 2*border;
    xsize = winX/ncol - 2*border;
    if (5*xsize > 7*ysize) {
        xsize = (ysize*7)/5;
    } else {
        ysize = (xsize*5)/7;
    }
    fprintf(stderr,"xsize=<%d> ysize=<%d>\n",xsize,ysize);
    bysize = ysize + header + 2*border;
    bxsize = xsize + 2*border;
    for (i=0; i<ncol; i++) {
        for (j=0; j<nrow; j++) {
            k = j + i*nrow;
            if (k < nwin) {
                xmin = winX - (i+1)*bxsize;
                ymin = winY - (j+1)*bysize;
                fprintf(stderr,"k=<%d> xmin=<%d> ymin=<%d>\n",k,xmin,ymin);
                sprintf(cmdbuf, "sg -Mci %d -wpos %d,%d@%d,%d &",
                        k,xsize,ysize,xmin,ymin);
                system(cmdbuf);
            }
        }
    }

    return 0;
}
Exemple #17
0
int main(int argc, char** argv)
{
    int attrib[] = {
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
        GLX_DOUBLEBUFFER, True,
        GLX_RED_SIZE, 8,
        GLX_GREEN_SIZE, 8,
        GLX_BLUE_SIZE, 8,
        GLX_ALPHA_SIZE, 8,
        GLX_DEPTH_SIZE, 24,
        None
    };
    
    PlatformContext context;

    context.MainDisplay = XOpenDisplay(NULL);
    int screenIndex = DefaultScreen(context.MainDisplay);
    Window root = RootWindow(context.MainDisplay, screenIndex);

    int fbcount;
    PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress((GLubyte*)"glXChooseFBConfig");
    GLXFBConfig *fbc = glXChooseFBConfig(context.MainDisplay, screenIndex, attrib, &fbcount);
    if (!fbc)
        pezFatal("Failed to retrieve a framebuffer config\n");

    PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) glXGetProcAddress((GLubyte*)"glXGetVisualFromFBConfig");
    if (!glXGetVisualFromFBConfig)
        pezFatal("Failed to get a GLX function pointer\n");

    PFNGLXGETFBCONFIGATTRIBPROC glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) glXGetProcAddress((GLubyte*)"glXGetFBConfigAttrib");
    if (!glXGetFBConfigAttrib)
        pezFatal("Failed to get a GLX function pointer\n");

    if (PezGetConfig().Multisampling) {
        int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
        for ( int i = 0; i < fbcount; i++ ) {
            XVisualInfo *vi = glXGetVisualFromFBConfig( context.MainDisplay, fbc[i] );
            if (!vi) {
                continue;
            }
            int samp_buf, samples;
            glXGetFBConfigAttrib( context.MainDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
            glXGetFBConfigAttrib( context.MainDisplay, fbc[i], GLX_SAMPLES       , &samples  );
            //printf( "  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
            //        " SAMPLES = %d\n", 
            //        i, (unsigned int) vi->visualid, samp_buf, samples );
            if ( best_fbc < 0 || (samp_buf && samples > best_num_samp) )
                best_fbc = i, best_num_samp = samples;
            if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
                worst_fbc = i, worst_num_samp = samples;
            XFree( vi );
        }
        fbc[0] = fbc[ best_fbc ];
    }

    XVisualInfo *visinfo = glXGetVisualFromFBConfig(context.MainDisplay, fbc[0]);
    if (!visinfo)
        pezFatal("Error: couldn't create OpenGL window with this pixel format.\n");

    XSetWindowAttributes attr;
    attr.background_pixel = 0;
    attr.border_pixel = 0;
    attr.colormap = XCreateColormap(context.MainDisplay, root, visinfo->visual, AllocNone);
    attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask |
                      PointerMotionMask | ButtonPressMask | ButtonReleaseMask;

    context.MainWindow = XCreateWindow(
        context.MainDisplay,
        root,
        0, 0,
        PezGetConfig().Width, PezGetConfig().Height, 0,
        visinfo->depth,
        InputOutput,
        visinfo->visual,
        CWBackPixel | /*CWBorderPixel |*/ CWColormap | CWEventMask,
        &attr
    );

    int borderless = 1;
    if (borderless) {
        Atom mwmHintsProperty = XInternAtom(context.MainDisplay, "_MOTIF_WM_HINTS", 0);
        MwmHints hints = {0};
        hints.flags = MWM_HINTS_DECORATIONS;
        hints.decorations = 0;
        XChangeProperty(context.MainDisplay, context.MainWindow, mwmHintsProperty, mwmHintsProperty, 32,
                        PropModeReplace, (unsigned char *)&hints, PROP_MWM_HINTS_ELEMENTS);
    }

    XMapWindow(context.MainDisplay, context.MainWindow);

    int centerWindow = 1;
    if (centerWindow) {
        Screen* pScreen = XScreenOfDisplay(context.MainDisplay, screenIndex);
        int left = XWidthOfScreen(pScreen)/2 - PezGetConfig().Width/2;
        int top = XHeightOfScreen(pScreen)/2 - PezGetConfig().Height/2;
        XMoveWindow(context.MainDisplay, context.MainWindow, left, top);
    }

    GLXContext glcontext = 0;
    if (PEZ_FORWARD_COMPATIBLE_GL) {
        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((GLubyte*)"glXCreateContextAttribsARB");
        if (!glXCreateContextAttribs) {
            pezFatal("Your platform does not support OpenGL 4.0.\n"
                     "Try changing PEZ_FORWARD_COMPATIBLE_GL to 0.\n");
        }
        int attribs[] = {
            GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
            GLX_CONTEXT_MINOR_VERSION_ARB, 0,
            GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
            GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
            0
        };
        glcontext = glXCreateContextAttribs(context.MainDisplay, fbc[0], NULL, True, attribs);
    } else {
        glcontext = glXCreateContext(context.MainDisplay, visinfo, NULL, True);
    }

    glXMakeCurrent(context.MainDisplay, context.MainWindow, glcontext);
    PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddress((GLubyte*)"glXSwapIntervalSGI");
    if (glXSwapIntervalSGI) {
        glXSwapIntervalSGI(PezGetConfig().VerticalSync ? 1 : 0);
    }
/*
    GLenum err = glewInit();
    if (GLEW_OK != err)
        pezFatal("GLEW Error: %s\n", glewGetErrorString(err));

    // Work around some GLEW issues:    
    #define glewGetProcAddress(name) (*glXGetProcAddressARB)(name)
    glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPatchParameteri");
    glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray");
    glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays");
    glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays");
    glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray");
*/
    // Reset OpenGL error state:
    glGetError();

    // Lop off the trailing .c
    bstring name = bfromcstr(PezGetConfig().Title);
    bstring shaderPrefix = bmidstr(name, 0, blength(name) - 1);
    pezSwInit(bdata(shaderPrefix));
    bdestroy(shaderPrefix);

    // Set up the Shader Wrangler
    pezSwAddPath("./", ".glsl");
    pezSwAddPath("../", ".glsl");
    char qualifiedPath[128];
    strcpy(qualifiedPath, pezResourcePath());
    strcat(qualifiedPath, "/");
    pezSwAddPath(qualifiedPath, ".glsl");
    pezSwAddDirective("*", "#version 420");

    // Perform user-specified intialization
    pezPrintString("OpenGL Version: %s\n", glGetString(GL_VERSION));
    PezInitialize();
    bstring windowTitle = bmidstr(name, 5, blength(name) - 7);
    XStoreName(context.MainDisplay, context.MainWindow, bdata(windowTitle));
    bdestroy(windowTitle);
    bdestroy(name);
    
    // -------------------
    // Start the Game Loop
    // -------------------

    unsigned int previousTime = GetMicroseconds();
    int done = 0;
    while (!done) {
        
        if (glGetError() != GL_NO_ERROR)
            pezFatal("OpenGL error.\n");

        if (XPending(context.MainDisplay)) {
            XEvent event;
    
            XNextEvent(context.MainDisplay, &event);
            switch (event.type)
            {
                case Expose:
                    //redraw(display, event.xany.window);
                    break;
                
                case ConfigureNotify:
                    //resize(event.xconfigure.width, event.xconfigure.height);
                    break;
                
#ifdef PEZ_MOUSE_HANDLER
                case ButtonPress:
                    PezHandleMouse(event.xbutton.x, event.xbutton.y, PEZ_DOWN);
                    break;

                case ButtonRelease:
                    PezHandleMouse(event.xbutton.x, event.xbutton.y, PEZ_UP);
                    break;

                case MotionNotify:
                    PezHandleMouse(event.xmotion.x, event.xmotion.y, PEZ_MOVE);
                    break;
#endif

                case KeyRelease:
                case KeyPress: {
                    XComposeStatus composeStatus;
                    char asciiCode[32];
                    KeySym keySym;
                    int len;
                    
                    len = XLookupString(&event.xkey, asciiCode, sizeof(asciiCode), &keySym, &composeStatus);
                    switch (asciiCode[0]) {
                        case 'x': case 'X': case 'q': case 'Q':
                        case 0x1b:
                            done = 1;
                            break;
                    }
                }
            }
        }

        unsigned int currentTime = GetMicroseconds();
        unsigned int deltaTime = currentTime - previousTime;
        previousTime = currentTime;
        
        PezUpdate((float) deltaTime / 1000000.0f);

        PezRender(0);
        glXSwapBuffers(context.MainDisplay, context.MainWindow);
    }

    pezSwShutdown();

    return 0;
}
/*--------------------------------------------------------*/
void open_gwindow_( )
{
/*
 * create new graphics window on first entry....
 */
  int                          font,black,white;
  int                          scr_width,scr_height;
  int                          j;
  unsigned long                valuemask;
  static int                   depth;    /* number of planes  */
  static Visual               *visual;   /*VISUAL TYPE       */
  static XSizeHints            win_position;   /*position and size for
                                            window manager.*/

/*
 * initialize display id and screen id....
 */
      disp_id = XOpenDisplay(0);
      if (!disp_id) {
         printf("Display not opened!\n");
         exit(-1);
      }
/*
 * next instruction for debugging only....
 */
/*      XSynchronize(disp_id, 1); */
  
  screen_id  =  XDefaultScreenOfDisplay(disp_id);
  root_win_id = XRootWindowOfScreen(screen_id);
  black =       XBlackPixelOfScreen(screen_id);
  white =       XWhitePixelOfScreen(screen_id);
  scr_width =   XWidthOfScreen(screen_id);
  scr_height =  XHeightOfScreen(screen_id);
  depth  =      XDefaultDepthOfScreen(screen_id);
  visual =      XDefaultVisualOfScreen(screen_id);


/*
 * set up backing store....
 */
      valuemask = CWBitGravity | CWBackingStore | CWBackPixel;
      setwinattr.bit_gravity = SouthWestGravity;
      setwinattr.backing_store = Always;
      setwinattr.background_pixel = white;
/*
 * create the window....
 */
      win_id  = XCreateWindow(disp_id,
			      root_win_id,
			      scr_width - win_width - 15,
			      scr_height - win_height - 35,
			      win_width, 
			      win_height, 
			      10,
			      depth,
			      InputOutput,
			      visual,
			      valuemask,
			      &setwinattr);
/* WMHints structure */
  win_position.x = scr_width - win_width - 15;
  win_position.y = scr_height - win_height - 35;
  win_position.width = win_width;
  win_position.height = win_height;
  win_position.flags=USPosition|USSize;
  
  XSetWMNormalHints(disp_id, win_id, &win_position); 

      XStoreName(disp_id, win_id, WINDNAME);
/*
 * get named color values....
 */

      color[1]   = define_color_("BLUE");
      color[2]   = define_color_("DEEP SKY BLUE");
      color[3]   = define_color_("LIGHT SKY BLUE");

      color[4]   = define_color_("SEA GREEN");
      color[5]  = define_color_("MEDIUM SEA GREEN");
      color[6]  = define_color_("GREEN");

      color[7]  = define_color_("BROWN");
      color[8]  = define_color_("CHOCOLATE");
      color[9]  = define_color_("SANDY BROWN");

      color[10]   = define_color_("RED");
      color[11]   = define_color_("CORAL");
      color[12]   = define_color_("ORANGE");

      color[13]  = define_color_("YELLOW3");
      color[14]  = define_color_("YELLOW2");
      color[15]  = define_color_("YELLOW");

      color[16]  = define_color_("PEACH PUFF");
      color[17]  = define_color_("PAPAYA WHIP");
      color[18]  = define_color_("OLD LACE");

      color[19]   = white;
      color[20]   = black;
      color[21]   = black;


/*
 * create graphics context....
 */
      xgcvl.background = color[19];
      xgcvl.foreground = color[20];
      gc_id = XCreateGC(disp_id, win_id, GCForeground | GCBackground, &xgcvl);
      xgcvl.function = GXinvert;
      gc_comp_id = XCreateGC(disp_id, win_id, GCFunction, &xgcvl);
/*
 * load the font for text writing....
 */
      font = XLoadFont(disp_id, FONTNAME);
      XSetFont(disp_id, gc_id, font);

  /* Map the window.... */
  XSelectInput(disp_id,win_id,ExposureMask|VisibilityChangeMask);
  XMapRaised(disp_id,win_id);

  /*
   * Wait for the window to be raised. Some X servers do not 
   * generate an initial expose event, so also check the visibility
   * event.
   */
  XMaskEvent(disp_id,ExposureMask|VisibilityChangeMask,&event);
  XSelectInput(disp_id,win_id,0);
  XSync(disp_id,1);
}
Exemple #19
0
/* ARGSUSED */
static void Initialize (
    Widget greq,
    Widget gnew,
    ArgList args,
    Cardinal *num_args)
{
    LoginWidget w = (LoginWidget)gnew;
    XtGCMask	valuemask, xvaluemask;
    XGCValues	myXGCV;
    Arg		position[2];
    Position	x, y;
#ifdef USE_XINERAMA
    XineramaScreenInfo *screens;
    int                 s_num;
#endif

#ifdef XPM
    myXGCV.foreground = w->login.hipixel;
    myXGCV.background = w->core.background_pixel;
    valuemask = GCForeground | GCBackground;
    w->login.hiGC = XtGetGC(gnew, valuemask, &myXGCV);

    myXGCV.foreground = w->login.shdpixel;
    myXGCV.background = w->core.background_pixel;
    valuemask = GCForeground | GCBackground;
    w->login.shdGC = XtGetGC(gnew, valuemask, &myXGCV);
#endif /* XPM */

    myXGCV.foreground = w->login.textpixel;
    myXGCV.background = w->core.background_pixel;
    valuemask = GCForeground | GCBackground;
    if (w->login.font) {
	myXGCV.font = w->login.font->fid;
	valuemask |= GCFont;
    }
    w->login.textGC = XtGetGC(gnew, valuemask, &myXGCV);
    myXGCV.foreground = w->core.background_pixel;
    w->login.bgGC = XtGetGC(gnew, valuemask, &myXGCV);

    myXGCV.foreground = w->login.textpixel ^ w->core.background_pixel;
    myXGCV.function = GXxor;
    xvaluemask = valuemask | GCFunction;
    w->login.xorGC = XtGetGC (gnew, xvaluemask, &myXGCV);

    /*
     * Note that the second argument is a GCid -- QueryFont accepts a GCid and
     * returns the curently contained font.
     */

    if (w->login.font == NULL)
	w->login.font = XQueryFont (XtDisplay (w),
		XGContextFromGC (XDefaultGCOfScreen (XtScreen (w))));

    xvaluemask = valuemask;
    if (w->login.promptFont == NULL)
        w->login.promptFont = w->login.font;
    else
	xvaluemask |= GCFont;

    myXGCV.foreground = w->login.promptpixel;
    myXGCV.font = w->login.promptFont->fid;
    w->login.promptGC = XtGetGC (gnew, xvaluemask, &myXGCV);

    xvaluemask = valuemask;
    if (w->login.greetFont == NULL)
    	w->login.greetFont = w->login.font;
    else
	xvaluemask |= GCFont;

    myXGCV.foreground = w->login.greetpixel;
    myXGCV.font = w->login.greetFont->fid;
    w->login.greetGC = XtGetGC (gnew, xvaluemask, &myXGCV);

    xvaluemask = valuemask;
    if (w->login.failFont == NULL)
	w->login.failFont = w->login.font;
    else
	xvaluemask |= GCFont;

    myXGCV.foreground = w->login.failpixel;
    myXGCV.font = w->login.failFont->fid;
    w->login.failGC = XtGetGC (gnew, xvaluemask, &myXGCV);

#ifdef XPM
    w->login.logoValid = False;

    if (NULL != w->login.logoFileName)
    {
        XpmAttributes myAttributes = { 0 };
        Window tmpWindow = { 0 };
        struct stat myBuffer = { 0 };
        unsigned int myPixmapDepth = 0;

        if (0 != stat(w->login.logoFileName, &myBuffer))
        {
            LogError("Unable to stat() pixmap file %s\n",
                w->login.logoFileName);
            w->login.logoValid = False;
            goto SkipXpmLoad;
        }
        else

        myAttributes.valuemask |= XpmReturnPixels;
        myAttributes.valuemask |= XpmReturnExtensions;

        XpmReadFileToPixmap(XtDisplay(w),            /* display */
            RootWindowOfScreen(XtScreen(w)),         /* window */
            w->login.logoFileName,                   /* XPM filename */
            &(w->login.logoPixmap),                  /* pixmap */
            &(w->login.logoMask),                    /* pixmap mask */
            &myAttributes);                          /* XPM attributes */
        w->login.logoValid = True;

        XGetGeometry(XtDisplay(w), w->login.logoPixmap,
            &tmpWindow,
            &(w->login.logoX),
            &(w->login.logoY),
            &(w->login.logoWidth),
            &(w->login.logoHeight),
            &(w->login.logoBorderWidth),
            &myPixmapDepth);
    } else {
	w->login.logoX = 0;
	w->login.logoY = 0;
	w->login.logoWidth = 0;
	w->login.logoHeight = 0;
	w->login.logoBorderWidth = 0;
    }


SkipXpmLoad:
#endif /* XPM */
    w->login.data.name[0] = '\0';
    w->login.data.passwd[0] = '\0';
    w->login.state = GET_NAME;
    w->login.cursor = 0;
    w->login.failUp = 0;
    if (w->core.width == 0)
	w->core.width = max (GREET_W(w), FAIL_W(w)) + PAD_X(w);
    if (w->core.height == 0) {
	int fy = FAIL_Y(w);
	int pady = PAD_Y(w);

#ifndef XPM
	w->core.height = fy + pady;	/* for stupid compilers */
#else
/*	w->core.height = fy + pady;	* for stupid compilers */

        w->core.height = max(fy + pady,
            (w->login.logoHeight + (2*w->login.logoPadding)) + pady);
        
#endif /* XPM */
    }
#ifdef USE_XINERAMA
    if (
	XineramaIsActive(XtDisplay(w)) &&
	(screens = XineramaQueryScreens(XtDisplay(w), &s_num)) != NULL
       )
    {
	if ((x = w->core.x) == -1)
	    x = screens[0].x_org + (int)(screens[0].width - w->core.width) / 2;
	if ((y = w->core.y) == -1)
	    y = screens[0].y_org + (int)(screens[0].height - w->core.height) / 3;
	
	XFree(screens);
    }
    else
#endif
    {
	if ((x = w->core.x) == -1)
	    x = (int)(XWidthOfScreen (XtScreen (w)) - w->core.width) / 2;
	if ((y = w->core.y) == -1)
	    y = (int)(XHeightOfScreen (XtScreen (w)) - w->core.height) / 3;
    }
    XtSetArg (position[0], XtNx, x);
    XtSetArg (position[1], XtNy, y);
    XtSetValues (XtParent (w), position, (Cardinal) 2);
}
Exemple #20
0
/**
@brief    Creates a new workspace, including separators used for stacking windows in different modes and the workspace menu item for the program menu.
@return   the index of the created workspace
**/
int
create_workspace(Display *display, struct Workspace_list* workspaces, char *workspace_name, struct Themes *themes) {
//  Window root = DefaultRootWindow(display);
  Screen* screen =  DefaultScreenOfDisplay(display);
  int black = BlackPixelOfScreen(screen);
//  XSetWindowAttributes attributes;
  struct Workspace *frames;

  if(workspaces->list == NULL) {
    workspaces->used_workspaces = 0;
    workspaces->max_workspaces = 16;
    workspaces->list = malloc(sizeof(struct Workspace) * workspaces->max_workspaces);
    if(workspaces->list == NULL) return -1;
  }
  else if(workspaces->used_workspaces == workspaces->max_workspaces) {
    //printf("reallocating, used_workspaces %d, max%d\n", workspaces->used_workspaces, workspaces->max);
    struct Workspace* temp = NULL;
    temp = realloc(workspaces->list, sizeof(struct Workspace) * workspaces->max_workspaces * 2);
    if(temp != NULL) workspaces->list = temp;
    else {
      perror("\nError: Not enough available memory\n");
      return -1;
    }
    workspaces->max_workspaces *= 2;
  }

  //the frame list frames is the new workspace
  frames = &workspaces->list[workspaces->used_workspaces];
  frames->workspace_name = workspace_name;

  frames->states = calloc(sizeof(struct Saved_frame_state), workspaces->max_frames);
  if(!frames->states) { perror("Error: not enough memory to allocate frame save states in a new workspace"); return -1; }

  //TODO when a workspace is added to the list, it must also be resized to the width of that list.
  unsigned int width = workspaces->workspace_menu.inner_width;

  frames->workspace_menu.item = XCreateSimpleWindow(display
  , workspaces->workspace_menu.widgets[popup_menu_parent].widget
  , themes->popup_menu[popup_l_edge].w, themes->popup_menu[popup_t_edge].h
  , width, themes->popup_menu[menu_item_mid].h
  , 0, black, black);

  XSelectInput(display, frames->workspace_menu.item,  ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);

  for(int i = 0; i <= inactive; i++) { //if(themes->popup_menu[menu_item].state_p[i])
    frames->workspace_menu.state[i] = XCreateSimpleWindow(display
    , frames->workspace_menu.item
    , 0, 0
    , XWidthOfScreen(screen), themes->popup_menu[menu_item_mid].h
    , 0, black, black);

    create_text_background(display, frames->workspace_menu.state[i], frames->workspace_name
    , &themes->font_theme[i], themes->popup_menu[menu_item_mid].state_p[i]
    , themes->popup_menu[menu_item_mid].w, themes->popup_menu[menu_item_mid].h);

    XMapWindow(display, frames->workspace_menu.state[i]);
  }

  XMapWindow(display, frames->workspace_menu.item);

  frames->workspace_menu.width = get_text_width(display, frames->workspace_name, &themes->font_theme[active]);

  //Create the frame_list
  frames->used = 0;
  frames->max  = DEFAULT_STARTING_FRAMES;
  frames->list = NULL; //this is allocated when we change to this workspace.

  frames->focus.used = 0;
  frames->focus.max  = 8; //must be divisible by 2
  frames->focus.list = malloc(sizeof(struct Focus_list) * frames->focus.max); //ok if it fails.
  #ifdef SHOW_WORKSPACE
  printf("Created workspace %d\n", workspaces->used_workspaces);
  #endif

  //need to make the existing neutral windows available to new workspaces
  for(int i = 0; i < workspaces->used_frames; i++) {
    if(suitable_for_foreign_workspaces(&workspaces->frame_list[i])) {
      load_initial_states(&frames->states[i], &workspaces->frame_list[i]);
    }
  }

  workspaces->used_workspaces++;
  XSync(display, False);

  return workspaces->used_workspaces - 1;
}
Exemple #21
0
/**
@brief   create pixmaps with the specified name if it is available, otherwise use a default name
@return  void
**/
void
create_frame_name(Display* display, struct Popup_menu *window_menu, struct Frame *temp
, struct Themes *themes, struct Atoms *atoms) {
  char untitled[] = "noname";

  //struct Frame temp = *frame;

  Screen* screen = DefaultScreenOfDisplay(display);
  int black = BlackPixelOfScreen(screen);

  /* Destroy/Free old title if it had one */
  free_frame_name(temp);

  {
    /* Recover EWMH UTF8 name first. If none exists, get the ICCCM ASCII name */
    /* If this succeeds, previous names will be freed if they exists later on */
    Atom ret_type;
    int  ret_format;
    unsigned long ret_nitems;
    unsigned long ret_trailing_bytes;
    temp->window_name = NULL;
    if((XGetWindowProperty (display, temp->framed_window, atoms->name, (long)0, (long)MAX_WM_NAME_LENGTH
    , False, atoms->utf8
    , &ret_type, &ret_format, &ret_nitems, &ret_trailing_bytes
    , (unsigned char **)&temp->window_name ) != Success) || temp->window_name == NULL) {

      //Try and get the non EWMH name
      if(!XFetchName(display, temp->framed_window, &temp->window_name)) {

        //Generate a blank name.
        printf("Warning: unnamed window\n");
        XStoreName(display, temp->framed_window, untitled);
        XFlush(display);
        XFetchName(display, temp->framed_window, &temp->window_name);
        XFlush(display);
      }
    }
  }
  /*
  if(temp->window_name == NULL
  && frame->window_name != NULL
  && strcmp(frame->window_name, untitled) == 0) {
    //it was null and already has the name from untitled above.
    return;
  }
  else
  if( (temp->window_name != NULL
  && frame->window_name != NULL )
  && (strcmp(temp->window_name, frame->window_name) == 0)) {
    XFree(temp->window_name);
    //skip this if the name hasn't changed
    return;
  }
  */

  if(!temp->menu.item) {
    temp->menu.item = XCreateSimpleWindow(display
    , window_menu->widgets[popup_menu_parent].widget
    , themes->popup_menu[l_edge].w, 0
    , XWidthOfScreen(screen), themes->popup_menu[menu_item_mid].h
    , 0, black, black);
    for(int i = 0; i <= inactive; i++) {
      temp->menu.state[i] = XCreateSimpleWindow(display
      , temp->menu.item
      , 0, 0
      , XWidthOfScreen(screen), themes->popup_menu[menu_item_mid].h
      , 0, black, black);
    }
    XSelectInput(display, temp->menu.item, ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);
  }

  temp->menu.width = get_text_width(display, temp->window_name, &themes->font_theme[active]);

  //create corresponding title menu item for this frame
  for(int i = 0; i <= inactive; i++) {
    XUnmapWindow(display, temp->menu.state[i]);
    XUnmapWindow(display, temp->widgets[title_menu_text].state[i]);
    XFlush(display);
    //create the title menu item with the windows title
    create_text_background(display, temp->menu.state[i], temp->window_name
    , &themes->font_theme[i], themes->popup_menu[menu_item_mid].state_p[i]
    , XWidthOfScreen(screen), themes->popup_menu[menu_item_mid].h);

    //TODO make the title for unfocussed windows not bold?
    create_text_background(display, temp->widgets[title_menu_text].state[i], temp->window_name
    , &themes->font_theme[active], themes->window_type[temp->theme_type][title_menu_text].state_p[i]
    , XWidthOfScreen(screen), themes->window_type[temp->theme_type][title_menu_text].h);

    //If this is mapped here, it might be shown in the wrong workspace, //XMapWindow(display, temp->menu.item);
    /* Show changes to background pixmaps */
    XMapWindow(display, temp->menu.state[i]);
    XMapWindow(display, temp->widgets[title_menu_text].state[i]);
  }
  xcheck_raisewin(display, temp->menu.state[active]);
  //these are the items for inside the menu
  //need to create all these windows.

  {
    XWindowAttributes attr;
    XGetWindowAttributes(display, temp->menu.item, &attr);

    if(attr.map_state != IsUnmapped) { //remap all the state pixmaps
      XSelectInput(display, temp->menu.item, 0);
      XSync(display, False);
      XUnmapWindow(display, temp->menu.item);
      XSelectInput(display, temp->menu.item, ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);
      XFlush(display);
      XMapWindow(display, temp->menu.item);
    }
  }
  XFlush(display);

  //*frame = temp;
}
Exemple #22
0
/**
@brief    Reparents the specified framed_window to a newly created frame.
@return   returns 1 if successful or 0 if no window was created.
@todo     A the moment each pointer is totally valid, in the future it will merely be an alias from another datastructure.
**/
int
create_frame(Display *display, struct Frame* frame
, Window framed_window, struct Popup_menu *window_menu, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes
, struct Cursors *cursors, struct Atoms *atoms) {
  XWindowAttributes get_attributes;

  //printf("Creating frames->list[%d] with window %lu, connection %lu\n"
  //, frames->used, (unsigned long)framed_window, (unsigned long)display);
  //add this window to the save set as soon as possible so that if an error occurs it is still available

  XAddToSaveSet(display, framed_window);
  XSync(display, False);
  XGetWindowAttributes(display, framed_window, &get_attributes);

  /*** Set up defaults ***/
  frame->focussed = False;
  frame->sticky = False;
  frame->window_name = NULL;
  frame->framed_window = framed_window;
  frame->type = unknown;
  frame->theme_type = unknown;
  frame->mode = unset;
  frame->state = none;
  frame->wants_attention = False;
  frame->transient = 0;
  frame->width_inc = 1;
  frame->height_inc = 1;
  frame->menu.item = 0;

  frame->w_inc_offset = 0;
  frame->h_inc_offset = 0;

  frame->w = get_attributes.width;
  frame->h = get_attributes.height;

  get_frame_type_and_mode (display, frame, atoms, themes);

  frame->x = get_attributes.x - themes->window_type[frame->theme_type][window].x;
  frame->y = get_attributes.y - themes->window_type[frame->theme_type][window].y;
  frame->hspace = 0 - themes->window_type[frame->theme_type][window].w;
  frame->vspace = 0 - themes->window_type[frame->theme_type][window].h;


  // This is not set to the something sensive, like the size of the workarea
  // as it may change and we can't tell if it's a default value or a real
  // one set by the client.
  // Instead, always use the MIN of the workarea dimension and these values
  frame->max_width  = INT_MAX;
  frame->max_height = INT_MAX;

  //prevent overly small windows with these sensible defaults
  frame->min_width  = MINWIDTH + frame->hspace;
  frame->min_height = MINHEIGHT + frame->vspace;

  #ifdef ALLOW_OVERSIZE_WINDOWS_WITHOUT_MINIMUM_HINTS
  Screen* screen = DefaultScreenOfDisplay(display);
  /* Ugh Horrible.  */
  /* Many apps that are resizeable ask to be the size of the screen and since windows
     often don't specifiy their minimum size, we have no other way of knowing if they
     really need to be that size or not.  In case they do, this specifies that their
     current width is their minimum size, in the hope that it is overridden by the
     size hints. This kind of behaviour causes problems on small screens like the
     eee pc. */
  if(frame->w > XWidthOfScreen(screen))  frame->min_width = frame->w;
  if(frame->h > XHeightOfScreen(screen)) frame->min_height = frame->h;
  #endif

  /* This requires hspace and vspace to be set as well as the incremental hints */
  get_frame_hints(display, frame);

  frame_type_settings(display, frame, workarea);

  //Don't manage splash screens, they just cause the workspace to be created and instantly destroyed
  if(frame->type == splash) {
    XMapWindow(display, framed_window);
    XFlush(display);
    return 0;
  }


  get_frame_state(display, frame, atoms);
  create_frame_subwindows(display, frame, workarea, themes, cursors);
  create_frame_name(display, window_menu, frame, themes, atoms);

  get_frame_wm_hints(display, frame);  //this might need to change the focus, it's mode (to hidden) and so on
  get_frame_strut_hints_as_normal_hints(display, frame, atoms);

  //_NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
  int32_t ewmh_frame_extents[4] = { themes->window_type[frame->theme_type][window].x
  , themes->window_type[frame->theme_type][window].y
  , - themes->window_type[frame->theme_type][window].x - themes->window_type[frame->theme_type][window].w
  , - themes->window_type[frame->theme_type][window].y - themes->window_type[frame->theme_type][window].h
  };

  XChangeProperty(display, framed_window, atoms->frame_extents, XA_CARDINAL
  , 32, PropModeReplace, (unsigned char *)ewmh_frame_extents, 4);

  XSetWindowBorderWidth(display, framed_window, 0);

  change_frame_mode(display, frame, unset, workarea, themes);

  #ifdef CRASH_ON_BUG
  XGrabServer(display);
  XSetErrorHandler(supress_xerror);
  #endif

  XSelectInput(display, framed_window,  0);

  //reparent the framed_window to frame->widgets[window].widget
  XReparentWindow(display, framed_window, frame->widgets[window].widget, 0, 0);
  //for some odd reason the reparent only reports an extra unmap event if the window was already unmapped
  XRaiseWindow(display, framed_window);
  XMapWindow(display, frame->widgets[window].widget);

  #ifdef CRASH_ON_BUG
  XSetErrorHandler(NULL);
  XUngrabServer(display);
  #endif

  XSelectInput(display, framed_window,  PropertyChangeMask); //Property notify is used to update titles
  XSelectInput(display, frame->widgets[window].widget
  , SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);

  //Some windows only send the destroy event (e.g., gimp splash screen)
  XSync(display, False);

  //Intercept clicks so we can set the focus and possibly raise floating windows
  XGrabButton(display, Button1, 0, frame->widgets[window].widget
  , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);

  //do it for numlock as well
  XGrabButton(display, Button1, Mod2Mask, frame->widgets[window].widget
  , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);

  frame->w += frame->hspace;
  frame->h += frame->vspace;

  check_frame_limits(frame, workarea, themes);

  resize_frame(display, frame, workarea, themes);
  stack_frame(display, frame, seps);
  change_frame_state(display, frame, frame->state, seps, workarea, themes, atoms);
  XMoveResizeWindow(display, framed_window, 0, 0, frame->w - frame->hspace, frame->h - frame->vspace);
  XMoveWindow(display, framed_window, 0, 0);
  XMapWindow(display, framed_window);

  XFlush(display);
  save_frame_initial_state(frame);
  return 1;
}
Exemple #23
0
/**
@pre      display is valid, menubar is not null but not initialized, seps is valid, themes is valid, cursors is valid.
@post     Menubar created and mapped.
@brief    This function uses the menubar member of the themes pointer to generate all the windows 
          that comprise the menubar with appropriate pixmap backgrounds.
@todo     Possibly have an extra parameter that determines whether the menubar is a popup menu and use the shape
          extention.
@return   void
**/
void 
create_menubar(Display *display, struct Menubar *menubar, struct Separators *seps, struct Themes *themes, struct Cursors *cursors) {
  /* create new window structure, using theme pixmaps */
  XSetWindowAttributes set_attributes;
  Window root = DefaultRootWindow(display);
  Screen* screen = DefaultScreenOfDisplay(display);
  int black = BlackPixelOfScreen(screen);
  unsigned int spacing;

  spacing = (XWidthOfScreen(screen) - themes->menubar[program_menu].w )/4;
  
  menubar->widgets[menubar_parent].widget = XCreateSimpleWindow(display, root
  , 0, XHeightOfScreen(screen) - themes->menubar[menubar_parent].h, XWidthOfScreen(screen)
  , themes->menubar[menubar_parent].h, 0, black, black);
  
  xcheck_setpixmap(display, menubar->widgets[menubar_parent].widget
  , themes->menubar[menubar_parent].state_p[normal]);
  
  for(int i = 0; i < menubar_parent; i++) {
        
    menubar->widgets[i].widget = XCreateSimpleWindow(display, menubar->widgets[menubar_parent].widget
    , spacing*i, 0, themes->menubar[i].w, themes->menubar[i].h, 0, black, black);
    XSelectInput(display, menubar->widgets[i].widget,  Button1MotionMask | ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, menubar->widgets[i].widget, cursors->pressable);
    for(int j = 0; j <= inactive; j++) {
      if(themes->menubar[i].state_p[j]) {
        menubar->widgets[i].state[j] = XCreateSimpleWindow(display, menubar->widgets[i].widget
        , 0, 0, themes->menubar[i].w, themes->menubar[i].h, 0, black, black);

        char *label = NULL;
        char Program[] = "Program";
        char Window[] = "Window";
        char Options[] = "Options";
        char Links[] = "Links";
        char Tool[] = "Tool";
        
        switch(i) {
          case program_menu: label = Program;
          break;
          case window_menu: label = Window;
          break;
          case options_menu: label = Options;
          break;
          case links_menu: label = Links;
          break;
          case tool_menu: label = Tool;
          break;
        }

        
        if(label) {
          create_text_background(display, menubar->widgets[i].state[j], label
          , &themes->font_theme[j], themes->menubar[i].state_p[j]
          , themes->menubar[i].w,  themes->menubar[i].h);
        }
        else {
          xcheck_setpixmap(display, menubar->widgets[i].state[j], themes->menubar[i].state_p[j]);
        }
       
        xcheck_map(display, menubar->widgets[i].state[j]);
      }
      //else printf("Warning:  Skipping state pixmap\n");
    }
    xcheck_map(display, menubar->widgets[i].widget);
  }

  set_attributes.override_redirect = True; 
  
  XChangeWindowAttributes(display, menubar->widgets[menubar_parent].widget
  , CWOverrideRedirect, &set_attributes);

  {
    XWindowChanges changes;  
    unsigned int mask = CWSibling | CWStackMode;  
    changes.stack_mode = Below;
    changes.sibling = seps->panel_separator;
    XConfigureWindow(display, menubar->widgets[menubar_parent].widget, mask, &changes);
  }
  /* Show initial state. */
  xcheck_raisewin(display, menubar->widgets[program_menu].state[normal]);
  xcheck_raisewin(display, menubar->widgets[window_menu].state[normal]);
  XFlush(display);
  
  /* Show everything */
  XMapWindow(display, menubar->widgets[menubar_parent].widget);
  XFlush(display);
}
Exemple #24
0
 int screen::IMPL::width() const
 {
   return XWidthOfScreen( _xscrn );
 }
Exemple #25
0
/*
 * Setup X11 wnd System
 */
void
X11_SetupWindow (GF_VideoOutput * vout)
{
	X11VID ();
	const char *sOpt;
        Bool autorepeat, supported;

	xWindow->display = XOpenDisplay (NULL);
	xWindow->screennum = DefaultScreen (xWindow->display);
	xWindow->screenptr = DefaultScreenOfDisplay (xWindow->display);
	xWindow->visual = DefaultVisualOfScreen (xWindow->screenptr);
	xWindow->depth = DefaultDepth (xWindow->display, xWindow->screennum);

	{
		Float screenWidth = (Float)XWidthOfScreen(xWindow->screenptr);
		Float screenWidthIn = (Float)XWidthMMOfScreen(xWindow->screenptr) / 25.4f;
		Float screenHeight = (Float)XHeightOfScreen(xWindow->screenptr);
		Float screenHeightIn = (Float)XHeightMMOfScreen(xWindow->screenptr) / 25.4f;
		vout->dpi_x = (u32)(screenWidth / screenWidthIn);
		vout->dpi_y = (u32)(screenHeight / screenHeightIn);	
	}

	switch (xWindow->depth) {
	case 8:
		xWindow->pixel_format = GF_PIXEL_GREYSCALE;
		break;
	case 16:
		xWindow->pixel_format = GF_PIXEL_RGB_565;
		break;
	case 24:
		xWindow->pixel_format = GF_PIXEL_RGB_32;
		break;
	default:
		xWindow->pixel_format = GF_PIXEL_GREYSCALE;
		break;
	}
	xWindow->bpp = xWindow->depth / 8;
	xWindow->bpp = xWindow->bpp == 3 ? 4 : xWindow->bpp;

xWindow->screennum=0;
	vout->max_screen_width = DisplayWidth(xWindow->display, xWindow->screennum);
	vout->max_screen_height = DisplayHeight(xWindow->display, xWindow->screennum);
	/*
	 * Full screen wnd
	 */
	xWindow->full_wnd = XCreateWindow (xWindow->display,
								   RootWindowOfScreen (xWindow->screenptr),
								   0, 0,
								   vout->max_screen_width,
								   vout->max_screen_height, 0,
								   xWindow->depth, InputOutput,
								   xWindow->visual, 0, NULL);

	XSelectInput(xWindow->display, xWindow->full_wnd,
					FocusChangeMask | ExposureMask | PointerMotionMask | ButtonReleaseMask | ButtonPressMask | KeyPressMask | KeyReleaseMask);

	if (!xWindow->par_wnd) {
		xWindow->w_width = 320;
		xWindow->w_height = 240;
		xWindow->wnd = XCreateWindow (xWindow->display,
					   RootWindowOfScreen(xWindow->screenptr), 0, 0,
					   xWindow->w_width, xWindow->w_height, 0,
					   xWindow->depth, InputOutput,
					   xWindow->visual, 0, NULL);
		XMapWindow (xWindow->display, (Window) xWindow->wnd);
	} else {
		XWindowAttributes pwa;
		XGetWindowAttributes(xWindow->display, xWindow->par_wnd, &pwa);
		xWindow->w_width = pwa.width;
		xWindow->w_height = pwa.height;
		xWindow->wnd = XCreateWindow (xWindow->display, xWindow->par_wnd, pwa.x, pwa.y,
					xWindow->w_width, xWindow->w_height, 0,
					   xWindow->depth, InputOutput,
					   xWindow->visual, 0, NULL);
		XMapWindow (xWindow->display, (Window) xWindow->wnd);
	}

	XSync(xWindow->display, False);
	XUnmapWindow (xWindow->display, (Window) xWindow->wnd);
	XSync(xWindow->display, False);
	old_handler = XSetErrorHandler(X11_BadAccess_ByPass);
	selectinput_err = 0;
	XSelectInput(xWindow->display, xWindow->wnd,
		FocusChangeMask | StructureNotifyMask | PropertyChangeMask | ExposureMask |
		PointerMotionMask | ButtonReleaseMask | ButtonPressMask |
		KeyPressMask | KeyReleaseMask);
	XSync(xWindow->display, False);
	XSetErrorHandler(old_handler);
	if (selectinput_err) {
	       	XSelectInput(xWindow->display, xWindow->wnd,
			StructureNotifyMask | PropertyChangeMask | ExposureMask |
			KeyPressMask | KeyReleaseMask);

		GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Cannot select input focus\n"));
	}
	XSync(xWindow->display, False);
	XMapWindow (xWindow->display, (Window) xWindow->wnd);

	XSizeHints *Hints = XAllocSizeHints ();
	Hints->flags = PSize | PMinSize;
	Hints->min_width = 64;
	Hints->min_height = 64;
	Hints->max_height = 4096;
	Hints->max_width = 4096;
	if (!xWindow->par_wnd) {
		XSetWMNormalHints (xWindow->display, xWindow->wnd, Hints);
		XStoreName (xWindow->display, xWindow->wnd, "GPAC X11 Output");
	}
	Hints->x = 0;
	Hints->y = 0;
	Hints->flags |= USPosition;
	XSetWMNormalHints (xWindow->display, xWindow->full_wnd, Hints);

	autorepeat = 1;
	XkbSetDetectableAutoRepeat(xWindow->display, autorepeat, &supported);


	if (xWindow->init_flags & GF_TERM_WINDOW_NO_DECORATION) {
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
#define MWM_HINTS_DECORATIONS (1L << 1)
	  struct {
	    unsigned long flags;
	    unsigned long functions;
	    unsigned long decorations;
	    long inputMode;
	    unsigned long status;
	  } hints = {2, 0, 0, 0, 0};

	  hints.flags = MWM_HINTS_DECORATIONS;
	  hints.decorations = 0;

	  XChangeProperty(xWindow->display, xWindow->wnd, XInternAtom(xWindow->display,"_MOTIF_WM_HINTS", False), XInternAtom(xWindow->display, "_MOTIF_WM_HINTS", False), 32, PropModeReplace, (unsigned char *)&hints, PROP_MOTIF_WM_HINTS_ELEMENTS);

	}

	xWindow->the_gc = XCreateGC (xWindow->display, xWindow->wnd, 0, NULL);
	xWindow->use_shared_memory = 0;

#ifdef GPAC_HAS_X11_SHM
	sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseHardwareMemory");
        if (sOpt && !strcmp(sOpt, "yes")) {
	  int XShmMajor, XShmMinor;
	  Bool XShmPixmaps;
	  if (XShmQueryVersion(xWindow->display, &XShmMajor, &XShmMinor, &XShmPixmaps)) {
		xWindow->use_shared_memory = 1;
		GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using X11 Shared Memory\n"));
		if ((XShmPixmaps==True) && (XShmPixmapFormat(xWindow->display)==ZPixmap)) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] X11 Shared Memory Pixmaps available\n"));
		}
	  }
	}

#endif

#ifdef GPAC_HAS_X11_XV
	sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "DisableColorKeying");
	if (sOpt && !strcmp(sOpt, "yes")) {
		xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0);
	} else {
		xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 1);
		if (xWindow->xvport<0) {
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware has no color keying\n"));
			vout->overlay_color_key = 0;
			xWindow->xvport = X11_GetXVideoPort(vout, GF_PIXEL_I420, 0);
		} else {
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Hardware uses color key %08x\n", vout->overlay_color_key));
		}
	}
	if (xWindow->xvport>=0) {
		XvUngrabPort(xWindow->display, xWindow->xvport, CurrentTime );
		xWindow->xvport = -1;
		vout->yuv_pixel_format = X11_GetPixelFormat(xWindow->xv_pf_format);
		vout->Blit = X11_Blit;
		vout->hw_caps |= GF_VIDEO_HW_HAS_YUV_OVERLAY;
		GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV YUV Overlays\n"));

#ifdef GPAC_HAS_X11_SHM
		/*if user asked for YUV->RGB on offscreen, do it (it may crash the system)*/
		sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "EnableOffscreenYUV");
		if (sOpt && !strcmp(sOpt, "yes")) {
			vout->hw_caps |= GF_VIDEO_HW_HAS_YUV;
			GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using XV Offscreen YUV2RGB acceleration\n"));
		}
#endif
	} 
#endif

	XSetWindowAttributes xsw;
	xsw.border_pixel = WhitePixel (xWindow->display, xWindow->screennum);
	xsw.background_pixel = BlackPixel (xWindow->display, xWindow->screennum);
	xsw.win_gravity = NorthWestGravity;
	XChangeWindowAttributes (xWindow->display, xWindow->wnd, CWBackPixel | CWWinGravity, &xsw);

	xsw.override_redirect = True;
	XChangeWindowAttributes(xWindow->display, xWindow->full_wnd,
				CWOverrideRedirect | CWBackPixel | CWBorderPixel | CWWinGravity, &xsw);

	if (!xWindow->par_wnd) {
		xWindow->WM_DELETE_WINDOW = XInternAtom (xWindow->display, "WM_DELETE_WINDOW", False);
		XSetWMProtocols(xWindow->display, xWindow->wnd, &xWindow->WM_DELETE_WINDOW, 1);
	}


	{
		XEvent ev;
		long mask;

		memset (&ev, 0, sizeof (ev));
		ev.xclient.type = ClientMessage;
		ev.xclient.window = RootWindowOfScreen (xWindow->screenptr);
		ev.xclient.message_type = XInternAtom (xWindow->display, "KWM_KEEP_ON_TOP", False);
		ev.xclient.format = 32;
		ev.xclient.data.l[0] = xWindow->full_wnd;
		ev.xclient.data.l[1] = CurrentTime;
		mask = SubstructureRedirectMask;
		XSendEvent (xWindow->display,RootWindowOfScreen (xWindow->screenptr), False,
			    mask, &ev);
	}

	/*openGL setup*/
#ifdef GPAC_HAS_OPENGL
	{
	  int attribs[64];
	  int i, nb_bits;

	  sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent");
	  /* Most outputs are 24/32 bits these days, use 8 bits per channel instead of 5, works better on MacOS X */
	  nb_bits = sOpt ? atoi(sOpt) : 8;
          if (!sOpt){
             gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsPerComponent", "8");
          }
	  i=0;
	  attribs[i++] = GLX_RGBA;
	  attribs[i++] = GLX_RED_SIZE;
	  attribs[i++] = nb_bits;
	  attribs[i++] = GLX_GREEN_SIZE;
	  attribs[i++] = nb_bits;
	  attribs[i++] = GLX_BLUE_SIZE;
	  attribs[i++] = nb_bits;
	  sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth");
	  nb_bits = sOpt ? atoi(sOpt) : 16;
          if (!sOpt){
             gf_modules_set_option((GF_BaseInterface *)vout, "Video", "GLNbBitsDepth", "16");
          }
	  if (nb_bits) {
		  attribs[i++] = GLX_DEPTH_SIZE;
		  attribs[i++] = nb_bits;
	  }
	  sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering");
          if (!sOpt){
             gf_modules_set_option((GF_BaseInterface *)vout, "Video", "UseGLDoubleBuffering", "yes");
          }
	  if (!sOpt || !strcmp(sOpt, "yes")) attribs[i++] = GLX_DOUBLEBUFFER;
	  attribs[i++] = None;
	  xWindow->glx_visualinfo = glXChooseVisual(xWindow->display, xWindow->screennum, attribs);
	  if (!xWindow->glx_visualinfo) {
		  GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[X11] Error selecting GL display\n"));
	  }
	}

	xWindow->gl_wnd = XCreateWindow (xWindow->display, RootWindowOfScreen (xWindow->screenptr),
								   0,
								   0,
								   200,
								   200, 0,
								   xWindow->depth, InputOutput,
								   xWindow->visual, 0, NULL);

	XSync(xWindow->display, False);
	XUnmapWindow(xWindow->display, (Window) xWindow->gl_wnd);
	XSync(xWindow->display, False);

	sOpt = gf_modules_get_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode");
	if (!sOpt)
		gf_modules_set_option((GF_BaseInterface *)vout, "Video", "X113DOffscreenMode", "Pixmap");
        if (sOpt && !strcmp(sOpt, "Window")) {
		xWindow->offscreen_type = 1;
        } else if (sOpt && !strcmp(sOpt, "VisibleWindow")) {
		xWindow->offscreen_type = 2;
		XSetWMNormalHints (xWindow->display, xWindow->gl_wnd, Hints);
       } else if (sOpt && !strcmp(sOpt, "Pixmap")) {
		xWindow->offscreen_type = 0;
	} else {
		xWindow->offscreen_type = 0;
	}
#endif


	/*turn off xscreensaver*/
	X11_XScreenSaverState(xWindow, 0);

	xWindow->setup_done = 1;
	XFree (Hints);
}
Exemple #26
0
/**
@brief   This function creates the windows which make up the actual frame and its widgets.
@return  void
**/
static void
create_frame_subwindows (Display *display, struct Frame *frame, struct Themes *themes, struct Cursors *cursors) {
  Window root = DefaultRootWindow(display);
  Screen* screen = DefaultScreenOfDisplay(display);
  int black = BlackPixelOfScreen(screen);

  frame->widgets[frame_parent].widget = XCreateSimpleWindow(display, root
  , frame->x, frame->y,  frame->w, frame->h, 0, black, black);
  XFlush(display);
  for(int j = 0; j <= inactive; j++)  frame->widgets[frame_parent].state[j] = 0;

  for(int i = 0; i < frame_parent; i++) {
    frame->widgets[i].widget = 0;
    for(int j = 0; j <= inactive; j++)  frame->widgets[i].state[j] = 0;
  }
  for(int i = 0; i < frame_parent; i++) {
    int x = themes->window_type[frame->theme_type][i].x;
    int y = themes->window_type[frame->theme_type][i].y;
    int w = themes->window_type[frame->theme_type][i].w;
    int h = themes->window_type[frame->theme_type][i].h;

    if(!themes->window_type[frame->theme_type][i].exists) {
      //printf("Skipping window component %d\n", i);
      continue;
    }
    //TODO get the size of the window from somewhere else
    if(x <  0) x += frame->w;
    if(y <  0) y += frame->h;
    if(w <= 0) w += frame->w;
    if(h <= 0) h += frame->h;

    if(themes->window_type[frame->theme_type][i].exists < 0) { //the exists variable is -1 for hotspots
      frame->widgets[i].widget = XCreateWindow(display, frame->widgets[frame_parent].widget
      , x, y, w, h, 0, CopyFromParent, InputOnly, CopyFromParent, 0, NULL);
      XMapWindow(display, frame->widgets[i].widget);
    }
    else if(themes->window_type[frame->theme_type][i].exists) { //otherwise if it isn't an inputonly hotspot
      frame->widgets[i].widget = XCreateSimpleWindow(display, frame->widgets[frame_parent].widget
      , x, y, w, h, 0, black, black);
      XFlush(display);
      if(i != window) { //don't create state windows for the framed window
        //OPTIMIZATION: This makes the cropped state windows large so that they don't need to be resized
        if(themes->window_type[frame->theme_type][i].w <= 0 || i == mode_dropdown_text) w = XWidthOfScreen(screen);
        if(themes->window_type[frame->theme_type][i].h <= 0) h = XWidthOfScreen(screen);
        for(int j = 0; j <= inactive; j++) {
          frame->widgets[i].state[j] = XCreateSimpleWindow(display, frame->widgets[i].widget
          , 0, 0, w, h, 0, black, black);
          XSetWindowBackgroundPixmap(display, frame->widgets[i].state[j]
          , themes->window_type[frame->theme_type][i].state_p[j]);
          XMapWindow(display, frame->widgets[i].state[j]);
        }
      }
      //Map windows
      XMapWindow(display, frame->widgets[i].widget);
    }
  }
  frame->menu.width = 0;
  //select input
  XSelectInput(display, frame->widgets[frame_parent].widget
  , Button1MotionMask | ButtonPressMask | ButtonReleaseMask);

  XDefineCursor(display, frame->widgets[frame_parent].widget, cursors->normal);

  if(themes->window_type[frame->theme_type][close_button_hotspot].exists) {
    XSelectInput(display, frame->widgets[close_button_hotspot].widget
    ,  ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);

    XDefineCursor(display, frame->widgets[close_button_hotspot].widget, cursors->pressable);
  }

  if(themes->window_type[frame->theme_type][mode_dropdown_hotspot].exists) {
    XSelectInput(display, frame->widgets[mode_dropdown_hotspot].widget, ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[mode_dropdown_hotspot].widget, cursors->pressable);
  }

  if(themes->window_type[frame->theme_type][title_menu_hotspot].exists) {
    XSelectInput(display, frame->widgets[title_menu_hotspot].widget, ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[title_menu_hotspot].widget , cursors->pressable);
  }

  if(themes->window_type[frame->theme_type][tl_corner].exists) {
    XSelectInput(display, frame->widgets[tl_corner].widget,  ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[tl_corner].widget, cursors->resize_tl_br);
  }
  if(themes->window_type[frame->theme_type][t_edge].exists) {
    XSelectInput(display, frame->widgets[t_edge].widget,     ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[t_edge].widget , cursors->resize_v);
  }
  if(themes->window_type[frame->theme_type][tr_corner].exists) {
    XSelectInput(display, frame->widgets[tr_corner].widget,  ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[tr_corner].widget, cursors->resize_tr_bl);
  }
  if(themes->window_type[frame->theme_type][l_edge].exists) {
    XSelectInput(display, frame->widgets[l_edge].widget,     ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[l_edge].widget , cursors->resize_h);
  }
  if(themes->window_type[frame->theme_type][bl_corner].exists) {
    XSelectInput(display, frame->widgets[bl_corner].widget,  ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[bl_corner].widget, cursors->resize_tr_bl);
  }
  if(themes->window_type[frame->theme_type][b_edge].exists) {
    XSelectInput(display, frame->widgets[b_edge].widget,     ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[b_edge].widget , cursors->resize_v);
  }
  if(themes->window_type[frame->theme_type][br_corner].exists) {
    XSelectInput(display, frame->widgets[br_corner].widget,  ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[br_corner].widget, cursors->resize_tl_br);
  }
  if(themes->window_type[frame->theme_type][r_edge].exists) {
    XSelectInput(display, frame->widgets[r_edge].widget,     ButtonPressMask | ButtonReleaseMask);
    XDefineCursor(display, frame->widgets[r_edge].widget , cursors->resize_h);
  }
  XFlush(display);
}