Beispiel #1
0
void
JXImage::JXImageFromDrawable
	(
	JXDisplay*		display,
	Drawable		source,
	const JRect&	origRect
	)
{
	JXImageX(display);

	JRect rect = origRect;
	{
	Window rootWindow;
	int x,y;
	unsigned int w,h, bw, depth;
	XGetGeometry(*itsDisplay, source, &rootWindow, &x, &y, &w, &h, &bw, &depth);

	itsDepth = depth;
	if (rect.IsEmpty())
		{
		SetDimensions(w,h);
		rect = GetBounds();
		}
	}

	itsPixmap = XCreatePixmap(*itsDisplay, itsDisplay->GetRootWindow(),
							  GetWidth(), GetHeight(), itsDepth);
	assert( itsPixmap != None );

	if (itsDepth != itsDisplay->GetDepth())
		{
		itsGC = new JXGC(itsDisplay, itsPixmap);
		assert( itsGC != NULL );
		}

	(GetGC())->CopyPixels(source, rect.left, rect.top,
						  rect.width(), rect.height(), itsPixmap, 0,0);
}
Beispiel #2
0
void SliderPanel::OnPaint()
{
    axGC* gc = GetGC();
    axRect rect(GetRect());
    axRect rect0(axPoint(0, 0), rect.size);
    
    gc->SetColor(axColor(1.0, 1.0, 1.0), 1.0);
    gc->DrawRectangle(rect0);
    
    gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
    gc->SetFontSize(12);
    //    gc->DrawStringAlignedCenter("test", rect0);
    gc->DrawString("regular", axPoint(350, 80));
    gc->DrawString("with back slider", axPoint(350, 100));
    gc->DrawString("no slider", axPoint(350, 120));
    gc->DrawString("click anywhere", axPoint(350, 140));
    gc->DrawString("right align", axPoint(350, 160));
    gc->DrawString("no button", axPoint(350, 180));
    gc->DrawString("center align", axPoint(350, 200));
    
    gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
    gc->DrawRectangleContour(rect0);
}
JXImagePainter::JXImagePainter
	(
	JXImage*		image,
	Drawable		drawable,
	const JRect&	defaultClipRect,
	const Region	defaultClipRegion
	)
	:
	JXWindowPainter(new JXGC(image->GetDisplay(), drawable),
					drawable, defaultClipRect, defaultClipRegion)
{
	assert( image != NULL );

#ifndef NDEBUG
	{
	JXGC* gc = GetGC();
	assert( gc != NULL );
	}
#endif

	itsImage = image;
	ClearWhenGoingAway(itsImage, &itsImage);
}
Beispiel #4
0
void FileDialog::OnPaint()
{
	axGC* gc = GetGC();

	axRect rect(GetRect());
	axRect rect0(axPoint(0, 0), rect.size);

	// Background.
	gc->SetColor(axColor(0.9, 0.9, 0.9), 1.0);
	gc->DrawRectangle(rect0);

	// Icon bar.
	axRect iconBarRect(1, 1, rect0.size.x - 1, 31);
	gc->DrawRectangle(iconBarRect);
	gc->DrawRectangleColorFade(iconBarRect, 
							  axColor(0.6, 0.6, 0.6), 1.0, 
							  axColor(0.7, 0.7, 0.7), 1.0);


	gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
	gc->DrawRectangleContour(iconBarRect);

	// Folder name.
	gc->SetColor(axColor(0.2, 0.2, 0.2), 1.0);
	gc->SetFontSize(14);
	gc->DrawString(_dirNavigation->GetCurrentDirectoryName(), axPoint(50, 7));

	axRect buttonBarRect(1, rect0.size.y - 30, rect0.size.x - 1, 30);
	gc->DrawRectangle(buttonBarRect);
	gc->DrawRectangleColorFade(buttonBarRect, 
							  axColor(0.6, 0.6, 0.6), 1.0, 
							  axColor(0.7, 0.7, 0.7), 1.0);

	gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
	gc->DrawRectangleContour(buttonBarRect);
}
/*ARGSUSED*/
static Boolean
XawMultiSinkSetValues(Widget current, Widget request, Widget cnew,
		      ArgList args, Cardinal *num_args)
{
    MultiSinkObject w = (MultiSinkObject)cnew;
    MultiSinkObject old_w = (MultiSinkObject)current;

    /* Font set is not in the GC! Do not make a new GC when font set changes! */

    if (w->multi_sink.fontset != old_w->multi_sink.fontset) {
	((TextWidget)XtParent(cnew))->text.redisplay_needed = True;
#ifndef NO_TAB_FIX
	SetTabs((Widget)w, w->text_sink.tab_count, w->text_sink.char_tabs);
#endif
    }

    if (w->text_sink.background != old_w->text_sink.background
	|| w->text_sink.foreground != old_w->text_sink.foreground
#ifndef OLDXAW
	|| w->text_sink.cursor_color != old_w->text_sink.cursor_color
#endif
	) {
	XtReleaseGC(cnew, w->multi_sink.normgc);
	XtReleaseGC(cnew, w->multi_sink.invgc);
	if (w->multi_sink.xorgc)
	    XtReleaseGC(cnew, w->multi_sink.xorgc);
	GetGC(w);
	((TextWidget)XtParent(cnew))->text.redisplay_needed = True;
    }
    else if (w->multi_sink.echo != old_w->multi_sink.echo
	     || w->multi_sink.display_nonprinting
	     != old_w->multi_sink.display_nonprinting)
      ((TextWidget)XtParent(cnew))->text.redisplay_needed = True;

    return (False);
}
Beispiel #6
0
void PaintPanel::OnPaint()
{
    axGC* gc = GetGC();
    axRect rect(GetRect());
    axRect rect0(axPoint(0, 0), rect.size);
    
    gc->SetColor(axColor(0.4, 0.4, 0.4), 1.0);
    gc->DrawRectangle(rect0);
    
    
    
    gc->SetColor(axColor(0.9, 0.4, 0.4, 0.5));
    gc->DrawRectangle(axRect(2, 2, 10, 10));
    
    gc->BlockDrawing(axRect(40, 40, 50, 50));
    gc->SetColor(axColor(0.9, 0.4, 0.4), 1.0);
    gc->DrawRectangle(axRect(40, 40, 50, 50));
    
    
    gc->SetColor(axColor(0.9, 0.4, 0.9), 1.0);
    gc->DrawRectangle(axRect(100, 40, 50, 50));
    gc->SetColor(axColor(0.0, 1.0, 0.0), 1.0);
    gc->DrawRectangleContour(axRect(100, 40, 50, 50));
    

    gc->SetColor(axColor(0.9, 0.9, 0.4), 1.0);
    gc->DrawRectangleContour(axRect(160, 40, 50, 50));
    
    
    gc->DrawRectangleColorFade(axRect(220, 40, 50, 50),
                               axColor(0.3, 0.8, 0.2),
                               1.0,
                               axColor(0.3, 0.8, 0.8),
                               1.0);
    
    gc->SetLineWidth(0.5);
    gc->SetColor(axColor(0.0, 0.0, 1.0), 1.0);
    gc->DrawCircle(axPoint(305, 65), 25.0, 3);
    
    gc->SetLineWidth(1.0);
    gc->SetColor(axColor(1.0, 0.0, 1.0), 1.0);
    gc->DrawCircle(axPoint(365, 65), 25.0, 4);
    
    gc->SetLineWidth(2.0);
    gc->SetColor(axColor(0.0, 1.0, 1.0), 1.0);
    gc->DrawCircle(axPoint(425, 65), 25.0, 5);

    gc->SetLineWidth(3.0);
    gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
    gc->DrawCircle(axPoint(485, 65), 25.0, 40);
    
    gc->DrawImage(dog_cat_img, axPoint(40, 100));
    gc->DrawImageResize(dog_cat_img,
                        axPoint(250, 100),
                        axSize(90, 70),
                        1.0);
    
    gc->DrawImageResize(dog_cat_img,
                        axPoint(340, 100),
                        axSize(90, 70),
                        0.35);
    
    gc->DrawPartOfImage(dog_cat_img,
                        axPoint(0, 0),
                        axSize(60, 45),
                        axPoint(430, 100));
    
    gc->SetLineWidth(3.0);
    gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
    
    int y1 = 350, y2 = 250;
    double w = 1.0;
    for(int i = 0; i < 6; i++, y1 += 10, y2 += 10, w += 1.0)
    {
        gc->DrawLine(axPoint(40, y1), axPoint(300, y2), w);
    }
    
    gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
    gc->SetFontSize(12);
    gc->DrawString("Default 12", axPoint(350, 190));
    
    gc->SetFontSize(14);
    gc->DrawString("Default 14", axPoint(350, 205));
    
    gc->SetColor(axColor(0.0, 1.0, 0.0), 1.0);
    gc->SetFontSize(20);
    gc->DrawString("Default 20", axPoint(350, 220));

    
    gc->SeDefaultLine();
    gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
    
    gc->DrawRoundedRectangle(axRect(350, 350, 50, 20));
    gc->DrawRectangleContour(rect0);
    
    
    gc->UnBlockDrawing();
    

}
Beispiel #7
0
//static int nDraw = 0;
void axWaveform::OnPaint()
{
//    nDraw++;
//    std::cout << "nDraw : " << nDraw << std::endl;

    axGC* gc = GetGC();
    axRect rect(GetRect());
    axRect rect0(axPoint(0, 0), rect.size);
    
    gc->SetColor(axColor(0.5, 0.5, 0.5), 1.0);
    gc->DrawRectangle(rect0);
    
    if(_audioBuffer != nullptr)
    {
        axBufferInfo b_info = _audioBuffer->GetBufferInfo();
        float* buffer = _audioBuffer->GetBuffer();
        int middle_y = rect.size.y * 0.5;
        
        gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);

        double nSamplesToProcess = double(b_info.frames) * _zoom;
        
        // Not a 100% sure about 1 + ..
        int index = 1 + b_info.frames * _leftPos;
        
        int changing_pixel = 0; // Just for debugging.
        int nSamplePerPixel = 0;
        
        double min_value_pixel = 1000.0;
        double max_value_pixel = -1000.0;
        
        // Ratio of number of pixel over number of sample to draw.
        double r = double(rect.size.x-2) / nSamplesToProcess;
        
        for(int i = 1; i < floor(nSamplesToProcess); i++, index++)
        {
            // Pixel position.
            double x_pos_left = double(i-1) * r;
            double x_pos_right = double(i) * r;
            
            double l_value = buffer[index - 1];
            double r_value = buffer[index];
            
            if(l_value < min_value_pixel) min_value_pixel = l_value;
            if(l_value > max_value_pixel) max_value_pixel = l_value;
            if(r_value < min_value_pixel) min_value_pixel = r_value;
            if(r_value > max_value_pixel) max_value_pixel = r_value;
            
            // Increment sample at each iteration.
            nSamplePerPixel++;
            
            // If pixel has change.
            if(int(x_pos_left) != int(x_pos_right))
            {
                if(nSamplePerPixel > 1)
                {
                    // Pixel value.
                    int y_pixel_left = middle_y - min_value_pixel * 0.9 * middle_y;
                    int y_pixel_right = middle_y - max_value_pixel * 0.9 * middle_y;
                    
                    // Draw min to max line on the left pixel.
                    gc->DrawLine(axPoint(x_pos_left, y_pixel_left),
                                 axPoint(x_pos_left, y_pixel_right));
                    
                    // Draw last value of left pixel and first value of right
                    // pixel. This is to make sure that horizontal lines will be
                    // drawn if necessary. A liason between each vertical lines.
                    y_pixel_left = middle_y - l_value * 0.9 * middle_y;
                    y_pixel_right = middle_y - r_value * 0.9 * middle_y;
                    
                    gc->DrawLine(axPoint(x_pos_left, y_pixel_left),
                                 axPoint(x_pos_right, y_pixel_right));
                }
                // One sample or less per pixel.
                else
                {
                    // Pixel value.
                    int y_pixel_left = middle_y - l_value * 0.9 * middle_y;
                    int y_pixel_right = middle_y - r_value * 0.9 * middle_y;
                    
                    gc->DrawLine(axPoint(x_pos_left, y_pixel_left),
                                 axPoint(x_pos_right, y_pixel_right));
                }
                
                changing_pixel++;
                nSamplePerPixel = 0;
                min_value_pixel = 1000.0;
                max_value_pixel = -1000.0;
            }
        }
        
        // Draw middle line.
        gc->SetColor(axColor(0.7, 0.7, 0.7), 0.4);
        gc->DrawLine(axPoint(1, middle_y), axPoint(rect.size.x - 2, middle_y));
    }
    
    //--------------------------------------------------------------------------
    if(_envBuffer != nullptr)
    {
        if((*_envBuffer).size() && _showEnv)
        {
            //        axBufferInfo b_info = _audioBuffer->GetBufferInfo();
            //        float* buffer = _audioBuffer->GetBuffer();
            int middle_y = rect.size.y * 0.5;
            
            gc->SetColor(axColor(1.0, 0.0, 0.0), 1.0);
            
            double nSamplesToProcess = double((*_envBuffer).size()) * _zoom;
            
            // Not a 100% sure about 1 + ..
            int index = 1 + (*_envBuffer).size() * _leftPos;
            
            int changing_pixel = 0; // Just for debugging.
            int nSamplePerPixel = 0;
            
            double min_value_pixel = 1000.0;
            double max_value_pixel = -1000.0;
            
            // Ratio of number of pixel over number of sample to draw.
            double r = double(rect.size.x-2) / nSamplesToProcess;
            
            for(int i = 1; i < floor(nSamplesToProcess); i++, index++)
            {
                // Pixel position.
                double x_pos_left = double(i-1) * r;
                double x_pos_right = double(i) * r;
                
                double l_value = (*_envBuffer)[index - 1];
                double r_value = (*_envBuffer)[index];
                
                if(l_value < min_value_pixel) min_value_pixel = l_value;
                if(l_value > max_value_pixel) max_value_pixel = l_value;
                if(r_value < min_value_pixel) min_value_pixel = r_value;
                if(r_value > max_value_pixel) max_value_pixel = r_value;
                
                // Increment sample at each iteration.
                nSamplePerPixel++;
                
                // If pixel has change.
                if(int(x_pos_left) != int(x_pos_right))
                {
                    if(nSamplePerPixel > 1)
                    {
                        // Pixel value.
                        int y_pixel_left = middle_y - min_value_pixel * 0.9 * middle_y;
                        int y_pixel_right = middle_y - max_value_pixel * 0.9 * middle_y;
                        
                        // Draw min to max line on the left pixel.
                        gc->DrawLine(axPoint(x_pos_left, y_pixel_left),
                                     axPoint(x_pos_left, y_pixel_right));
                        
                        // Draw last value of left pixel and first value of right
                        // pixel. This is to make sure that horizontal lines will be
                        // drawn if necessary. A liason between each vertical lines.
                        y_pixel_left = middle_y - l_value * 0.9 * middle_y;
                        y_pixel_right = middle_y - r_value * 0.9 * middle_y;
                        
                        gc->DrawLine(axPoint(x_pos_left, y_pixel_left),
                                     axPoint(x_pos_right, y_pixel_right));
                    }
                    // One sample or less per pixel.
                    else
                    {
                        // Pixel value.
                        int y_pixel_left = middle_y - l_value * 0.9 * middle_y;
                        int y_pixel_right = middle_y - r_value * 0.9 * middle_y;
                        
                        gc->DrawLine(axPoint(x_pos_left, y_pixel_left),
                                     axPoint(x_pos_right, y_pixel_right));
                    }
                    
                    changing_pixel++;
                    nSamplePerPixel = 0;
                    min_value_pixel = 1000.0;
                    max_value_pixel = -1000.0;
                }
            }
            
        }
    }
    
    if(_envPoints != nullptr)
    {
        if((*_envPoints).size() && _showEnv)
        {
            int middle_y = rect.size.y * 0.5;
            
//            gc->SetColor(axColor(0.0, 1.0, 0.0), 1.0);
//            
//            for(auto& n : *_envPoints)
//            {
//                double x_pos = n.x * GetRect().size.x;
//                gc->DrawLine(axPoint(x_pos, middle_y),
//                             axPoint(x_pos, middle_y - n.y * 0.9 * middle_y));
//                
////                std::cout << n.x << " " << n.y << std::endl;
//            }
            
            gc->SetColor(axColor(0.0, 0.0, 1.0), 1.0);
            
            for(int i = 1; i < (*_envPoints).size(); i++)
            {
                double x_pos_left = (*_envPoints)[i-1].x * GetRect().size.x;
                double x_pos_right = (*_envPoints)[i].x * GetRect().size.x;
                int y_pixel_left = middle_y - (*_envPoints)[i-1].y * 0.9 * middle_y;
                int y_pixel_right = middle_y - (*_envPoints)[i].y * 0.9 * middle_y;
                
                gc->DrawLine(axPoint(x_pos_left, y_pixel_left),
                             axPoint(x_pos_right, y_pixel_right));
//                gc->DrawLine(axPoint(x_pos, middle_y),
//                             axPoint(x_pos, middle_y - n.y * 0.9 * middle_y));
                
                //                std::cout << n.x << " " << n.y << std::endl;
            }
        }
    }
    

    // Draw contour.
    gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
    gc->DrawRectangleContour(rect0);
}
Beispiel #8
0
void FolderContent::OnPaint()
{
	BlockDrawing();

	axGC* gc = GetGC();
	axRect rect0(axPoint(0, 0), GetRect().size);

	gc->SetColor(axColor(0.9, 0.9, 0.9), 1.0);
	gc->DrawRectangle(axRect(1, 1, rect0.size.x - 2, rect0.size.y -1));

	// Folder Content.
	axColor col1(0.7, 0.7, 0.7);
	axColor col2(0.8, 0.8, 0.8);

	int y = 0;
	int x = 40;
	gc->SetFontSize(12);

	deque<DirectoryNavigation::FileInfo>& dirNames = *_dirNavigation->GetFileInfoDeque();

	for(int i = 0; i < dirNames.size(); i++)
	{
		if(i % 2) gc->SetColor(col1);
		else gc->SetColor(col2);
		
		// Draw file background.
		axRect backfileRect(1, y, rect0.size.x - 1, 24);
		gc->DrawRectangle(backfileRect);

		// Draw file highlight.
		if(_selected_file == i)
		{
			gc->SetColor(axColor(0.7, 0.7, 1.0), 0.5);

			axRect selected_rect(1, y, rect0.size.x - 2, 24);
			gc->DrawRectangle(selected_rect);
			gc->DrawRectangleColorFade(selected_rect, 
						  			   axColor(0.7, 0.7, 0.7), 0.5, 
						 			   axColor(0.8, 0.8, 0.8), 0.5);
		}

		// Draw file icon.
		if(dirNames[i].second != DirectoryNavigation::ICON_NONE)
		{
			gc->DrawImageResize(_icons[dirNames[i].second], axPoint(3, y), axSize(24, 24));
		}

		// Draw file name.
		gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
		gc->DrawString(dirNames[i].first, axPoint(x, y+4));

		y += 24;
	
		if(i > 30)
		{
			break;
		}
	}

	gc->SetColor(axColor(0.0, 0.0, 0.0), 1.0);
	gc->DrawRectangleContour(axRect(1, 1, rect0.size.x - 1, rect0.size.y - 1));

	UnBlockDrawing();
}
JXDragPainter::~JXDragPainter()
{
	JXGC* gc = GetGC();
	delete gc;
}
Beispiel #10
0
void
JXImage::JXImageFromDrawable
	(
	JXDisplay*		display,
	JXColormap*		colormap,
	Drawable		source,
	const JRect&	origRect
	)
{
	JXImageX(display, colormap);

	JRect rect = origRect;
	{
	Window rootWindow;
	int x,y;
	unsigned int w,h, bw, depth;
	XGetGeometry(*itsDisplay, source, &rootWindow, &x, &y, &w, &h, &bw, &depth);

	itsDepth = depth;
	if (rect.IsEmpty())
		{
		SetDimensions(w,h);
		rect = GetBounds();
		}
	}

	itsPixmap = XCreatePixmap(*itsDisplay, itsDisplay->GetRootWindow(),
							  GetWidth(), GetHeight(), itsDepth);
	assert( itsPixmap != None );

	if (itsDepth != itsDisplay->GetDepth())
		{
		itsGC = new JXGC(itsDisplay, itsColormap, itsPixmap);
		assert( itsGC != NULL );
		}

	(GetGC())->CopyPixels(source, rect.left, rect.top,
						  rect.width(), rect.height(), itsPixmap, 0,0);

	// register the colors that are used in the drawable

	const JBoolean needRegister =
		JConvertToBoolean( itsDepth > 1 && !itsColormap->AllColorsPreallocated() );

	if (needRegister && itsColormap->GetVisualClass() == DirectColor)
		{
		// With DirectColor, there could be just as many colors as pixels,
		// so we actually waste time (and memory!) by building a list of
		// X pixel values before converting them to JColorIndices.

		ConvertToImage();

		const JCoordinate w = GetWidth();
		const JCoordinate h = GetHeight();
		for (JCoordinate y=0; y<=h; y++)
			{
			for (JCoordinate x=0; x<=w; x++)
				{
				JColorIndex color;
				const unsigned long xPixel = XGetPixel(itsImage, x,y);
				itsColormap->AllocateStaticColor(xPixel, &color);
				RegisterColor(color, kJFalse);
				}
			}
		}
	else if (needRegister)	// using PseudoColor => small # of X pixels
		{
		// By building a list of unique X pixel values and then converting
		// each once, we reduce O(W H (alloc)) to O(W H) + O(P (alloc)),
		// where W=width, H=height, P=# of distinct pixels in Drawable.
		// Typically, W*H is much larger than P.  Alloc usually requires
		// a server call.

		JIndex i;

		// build boolean array telling which X pixel values are used

		ConvertToImage();

		const JSize maxColorCount = itsColormap->GetMaxColorCount();
		char* pixelUsed = new char [ maxColorCount ];
		assert( pixelUsed != NULL );
		for (i=0; i<maxColorCount; i++)
			{
			pixelUsed[i] = 0;
			}

		const JCoordinate w = GetWidth();
		const JCoordinate h = GetHeight();
		for (JCoordinate y=0; y<=h; y++)
			{
			for (JCoordinate x=0; x<=w; x++)
				{
				const unsigned long xPixel = XGetPixel(itsImage, x,y);
				assert( xPixel < maxColorCount );
				pixelUsed [ xPixel ] = 1;
				}
			}

		// register each X pixel value that is used

		JColorIndex color;
		for (i=0; i<maxColorCount; i++)
			{
			if (pixelUsed[i])
				{
				itsColormap->AllocateStaticColor(i, &color);
				RegisterColor(color, kJFalse);
				}
			}

		delete [] pixelUsed;
		}
}
Beispiel #11
0
t_x11 *GetX11(int *argc, char *argv[])
{
    static const char *v_name[] = {
        "DirectColor", "TrueColor", "PseudoColor",
        "StaticColor", "GrayScale", "StaticGray"
    };
    static int         v_class[] = {
        DirectColor, TrueColor, PseudoColor,
        StaticColor, GrayScale, StaticGray
    };
#define NCLASS (sizeof(v_class)/sizeof(v_class[0]))

    XVisualInfo     v_info;
    t_x11          *x11;
    int             ARGC;
    char          **ARGV;
    char           *display;
    char           *fontname;
    char           *title, *FG = NULL, *BG = NULL;
    gmx_bool        bVerbose = FALSE;
    int             i;

    title = strdup(argv[0]);

    /* First check environment */
    fontname = getenv("GMXFONT");
    display  = getenv("DISPLAY");

    snew(ARGV, *argc);
    ARGC = 1;
    for (i = 1; (i < *argc); i++)
    {
        if (argv[i][0] == '-')
        {
            if (strlen(argv[i]) > 1)
            {
                if ((*argc) > i+1)
                {
                    switch (argv[i][1])
                    {
                        case 'b':
                            BG = argv[++i];
                            break;
                        case 'd':
                            display = argv[++i];
                            break;
                        case 'f':
                            switch (argv[i][2])
                            {
                                case 'o':
                                    fontname = argv[++i];
                                    break;
                                case 'g':
                                    FG = argv[++i];
                                    break;
                            }
                            break;
                        case 't':
                            sfree(title);
                            title = strdup(argv[++i]);
                            break;
                        case 'v':
                            bVerbose = TRUE;
                            break;
                        default:
                            ARGV[ARGC++] = argv[i];
                            break;
                    }
                }
            }
        }
        else
        {
            ARGV[ARGC++] = argv[i];
        }
    }
    for (i = 1; (i < ARGC); i++)
    {
        argv[i] = ARGV[i];
    }
    *argc      = ARGC;
    argv[ARGC] = NULL;

    snew(x11, 1);
    x11->dispname = display;
    if (bVerbose)
    {
        x11->console = stderr;
    }
    else
    if ((x11->console = fopen("/dev/null", "w")) == NULL)
    {
        x11->console = stderr;
    }

    if ((x11->disp = XOpenDisplay(display)) == NULL)
    {
        if (bVerbose)
        {
            fprintf(x11->console, "Display %s invalid\n", display);
        }
        return NULL;
    }

    if ((x11->font = GetFont(x11->console, x11->disp, fontname)) == NULL)
    {
        return NULL;
    }
    if ((x11->gc = GetGC(x11->disp, x11->font)) == NULL)
    {
        return NULL;
    }

    x11->root   = DefaultRootWindow(x11->disp);
    x11->screen = DefaultScreen(x11->disp);
    x11->depth  = DefaultDepth(x11->disp, x11->screen);
    x11->cmap   = DefaultColormap(x11->disp, x11->screen);

    /* These colours will be mapped to black on a monochrome screen */
    x11->fg = BLACK = BLUE = GREEN = CYAN = RED = BROWN = GREY = DARKGREY =
                                        BlackPixel(x11->disp, x11->screen);

    /* These colours will be mapped to white on a monochrome screen */
    x11->bg       =
        LIGHTBLUE = LIGHTGREY = LIGHTGREEN = LIGHTCYAN = LIGHTRED = VIOLET = YELLOW = WHITE =
                                        WhitePixel(x11->disp, x11->screen);

    if (x11->depth > 1)
    {
        /* Not B & W, Look what kind of screen we've got... */
        for (i = 0; (i < NCLASS); i++)
        {
            if (!XMatchVisualInfo(x11->disp, x11->screen, x11->depth,
                                  v_class[i], &v_info))
            {
                break;
            }
        }
        if ((i == 4) || (i == 5))
        {
            fprintf(x11->console, "Greyscale screen, using B & W only\n");
        }
        else
        {
            /* We have real color! */
            fprintf(x11->console, "%s screen with depth %d.\n",
                    (i == NCLASS) ? "Unknown" : v_name[i], x11->depth);
            GetNamedColor(x11, "midnight blue", &BLUE);
            GetNamedColor(x11, "DarkGreen", &GREEN);
            GetNamedColor(x11, "SeaGreen", &CYAN);
            GetNamedColor(x11, "red4", &RED);
            GetNamedColor(x11, "Gray", &GREY);
            GetNamedColor(x11, "Gray", &DARKGREY);
            GetNamedColor(x11, "LightGray", &LIGHTGREY);
            GetNamedColor(x11, "green", &LIGHTGREEN);
            GetNamedColor(x11, "cyan", &LIGHTCYAN);
            GetNamedColor(x11, "tomato1", &LIGHTRED);
            GetNamedColor(x11, "violet", &VIOLET);
            GetNamedColor(x11, "yellow", &YELLOW);
            GetNamedColor(x11, "brown", &BROWN);
            GetNamedColor(x11, "CornFlowerBlue", &LIGHTBLUE);
        }
    }
    else
    {
        fprintf(x11->console, "Monochrome screen.\n");
    }

    /* We should use Xrm here... */
    if (FG)
    {
        GetNamedColor(x11, FG, &(x11->fg));
    }
    else
    {
        x11->fg = BLACK;
    }
    if (BG)
    {
        GetNamedColor(x11, BG, &(x11->bg));
    }
    else
    {
        x11->bg = LIGHTGREY;
    }
    x11->title = strdup(title);
    sfree(title);
    x11->wlist              = NULL;
    x11->GetNamedColor      = &GetNamedColor;
    x11->MainLoop           = &MainLoop;
    x11->RegisterCallback   = &RegisterCallback;
    x11->UnRegisterCallback = &UnRegisterCallback;
    x11->SetInputMask       = &SetInputMask;
    x11->GetInputMask       = &GetInputMask;
    x11->CleanUp            = &CleanUp;
    x11->Flush              = &Flush;

    x11->Flush(x11);

    return x11;
}