// ############################################################################### // ### C O N S T R U C T I O N A N D I N I T I A L I Z A T I O N // ############################################################################### #region Construction /// <summary>Initializing constructor.</summary> /// <param name="display">The display pointer, that specifies the connection to the X server.<see cref="System.IntPtr"/></param> /// <param name="screenNumber">The appropriate screen number on the host server.<see cref="System.Int32"/></param> /// <param name="colormap">The X11 colormap pointer.<see cref="IntPtr"/></param> /// <param name="graphicDepth">The depth (number of planes) of the graphic - that holds color pixel information.<see cref="System.Int32"/></para> /// <param name="width">The width of the image to create.<see cref="System.Int32"/></param> /// <param name="height">The height of the image to create.<see cref="System.Int32"/></param> public X11Image(IntPtr display, int screenNumber, IntPtr colormap, int graphicDepth, int width, int height) { if (display == IntPtr.Zero) { throw new ArgumentNullException("display"); } if (colormap == IntPtr.Zero) { throw new ArgumentNullException("colormap"); } IntPtr rootWindow = X11lib.XRootWindow(display, (X11.TInt)screenNumber); IntPtr rootVisual = X11lib.XDefaultVisual(display, (X11.TInt)screenNumber); if (rootVisual == IntPtr.Zero) { throw new NullReferenceException("rootVisual"); } IntPtr imageXPixmap = X11lib.XCreatePixmap(display, rootWindow, (X11.TUint)width, (X11.TUint)height, (X11.TUint)graphicDepth); if (imageXPixmap == IntPtr.Zero) { throw new NullReferenceException("imageXPixmap"); } _size.Width = width; _size.Height = height; _imageSurface = new X11Surface(display, screenNumber, imageXPixmap, rootVisual, graphicDepth, colormap); }
/// <summary>Calculate the average character width of indicated font data.</summary> /// <param name="x11display">The display pointer, that specifies the connection to the X server.<see cref="IntPtr"/></param> /// <param name="x11gc">The crapchics context to use for drawing.<see cref="IntPtr"/></param> /// <param name="fontData">The font data to calculate the average character width for.<see cref="X11FontData"/></param> /// <returns>The average character width of indicated font data.<see cref="System.Int32"/></returns> public static int AverageCharacterWidth(IntPtr x11display, IntPtr x11gc, X11FontData fontData) { if (fontData == null) { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::AverageCharacterWidth () Argument null: fontData"); return(0); } if (fontData.UseFontset) { X11lib.XRectangle overallInc = new X11lib.XRectangle(); X11lib.XRectangle overallLogical = new X11lib.XRectangle(); X11.TWchar[] text = new X11.TWchar[] { (X11.TWchar) 'X', (X11.TWchar) ' ', (X11.TWchar) 'i' }; X11lib.XwcTextExtents(fontData.FontResourceId, text, (X11.TInt)text.Length, ref overallInc, ref overallLogical); return((int)(((int)overallLogical.width + 2) / 3)); } else { TInt direction = 0; TInt fontAscent = 0; TInt fontDescent = 0; X11lib.XCharStruct xCharStruct = new X11lib.XCharStruct(); X11lib.XChar2b[] text = new X11lib.XChar2b[] { new X11lib.XChar2b('X'), new X11lib.XChar2b(' '), new X11lib.XChar2b('i') }; X11lib.XSetFont(x11display, x11gc, fontData.FontResourceId); X11lib.XQueryTextExtents16(x11display, fontData.FontResourceId, text, (X11.TInt)text.Length, ref direction, ref fontAscent, ref fontDescent, ref xCharStruct); return((int)(((int)xCharStruct.width + 2) / 3)); } }
// ############################################################################### // ### D E S T R U C T I O N // ############################################################################### #region Destruction /// <summary>IDisposable implementation.</summary> public void Dispose() { // SimpleLog.LogLine (TraceEventType.Verbose, CLASS_NAME + "::Dispose ()"); if (_imageSurface.Drawable != IntPtr.Zero) { X11lib.XFreePixmap(_imageSurface.Display, _imageSurface.Drawable); _imageSurface.SetDrawable(IntPtr.Zero); } }
/// <summary> Draw the image in the indicated window, using the indicated graphics context. </summary> /// <param name="window"> The window to draw the pitmap on. <see cref="System.IntPtr"/> </param> /// <param name="gc"> The crapchics context to use for drawing. <see cref="System.IntPtr"/> </param> /// <param name="destX"> The x coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> /// <param name="destY"> The y coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> public void Draw(IntPtr window, IntPtr gc, TInt dstX, TInt dstY) { // Possible optimization: Keep the graphicGc between the exposure events. // Problem: Every graphic allocates a graphics context (limited server resource). if (_transpXImage != IntPtr.Zero) { // Prepare the clip mask (for transparency) that must be a XPixmap. if (_transpXPixmap == IntPtr.Zero) { // Server side storage. _transpXPixmap = X11lib.XCreatePixmap(_display, window, (TUint)_width, (TUint)_height, (TUint)_clipDepth); IntPtr maskGc = X11lib.XCreateGC(_display, _transpXPixmap, (TUlong)0, IntPtr.Zero); if (maskGc != IntPtr.Zero) { X11lib.XPutImage(_display, _transpXPixmap, maskGc, _transpXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Console.WriteLine (CLASS_NAME + "::Draw () Delete transparency mask image GC."); X11lib.XFreeGC(_display, maskGc); maskGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::Draw () ERROR: Can not create graphics context for mask pixmap."); } } // Prepare the clipping graphics context. IntPtr graphicGc = X11lib.XCreateGC(_display, window, (TUlong)0, IntPtr.Zero); if (graphicGc != IntPtr.Zero) { X11lib.XSetClipMask(_display, graphicGc, _transpXPixmap); X11lib.XSetClipOrigin(_display, graphicGc, dstX, dstY); // Draw graphic using the clipping graphics context. X11lib.XPutImage(_display, window, graphicGc, _graphicXImage, (TInt)0, (TInt)0, (TInt)dstX, (TInt)dstY, (TUint)_width, (TUint)_height); // Restore previous behaviour and clean up. X11lib.XSetClipMask(_display, graphicGc, IntPtr.Zero); X11lib.XSetClipOrigin(_display, graphicGc, (TInt)0, (TInt)0); // Console.WriteLine (CLASS_NAME + "::Draw () Delete clipping image GC."); X11lib.XFreeGC(_display, graphicGc); graphicGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::Draw () ERROR: Can not create graphics context for transparency application."); } } else { X11lib.XPutImage(_display, window, gc, _graphicXImage, 0, 0, dstX, dstY, (TUint)_width, (TUint)_height); } }
// ############################################################################### // ### M E T H O D S // ############################################################################### #region Methods /// <summary> Draw the image in the indicated window, using the indicated graphics context. </summary> /// <param name="window"> The window to draw the pitmap on. <see cref="System.IntPtr"/> </param> /// <param name="gc"> The crapchics context to use for drawing. <see cref="System.IntPtr"/> </param> /// <param name="destX"> The x coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> /// <param name="destY"> The y coordinate, which is relative to the origin of the window and is the coordinate of the subimage. <see cref="TInt"/> </param> private void DrawUnfinished(IntPtr window, IntPtr gc, TInt dstX, TInt dstY) { // This is an alternative drawing approach, but i didn't get it working. IntPtr clipPixmap = X11lib.XCreatePixmap(_display, window, (TUint)_width, (TUint)_height, (TUint)_clipDepth); IntPtr clipGc = X11lib.XCreateGC(_display, clipPixmap, (TUlong)0, IntPtr.Zero); X11lib.XPutImage(_display, clipPixmap, clipGc, _transpXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); X11lib.XSetFunction(_display, gc, X11lib.XGCFunction.GXand); X11lib.XSetBackground(_display, gc, (TPixel)1); X11lib.XSetForeground(_display, gc, (TPixel)0); X11lib.XCopyPlane(_display, clipPixmap, window, gc, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height, (TInt)dstX, (TInt)dstY, (TUlong)1); }
static void SendFakeEventToStop(IntPtr w) { var d = X11lib.XOpenDisplay(null); if (d == IntPtr.Zero) { return; } var e = new XEvent { type = XEventName.PropertyNotify }; X11lib.XSendEvent(d, w, true, EventMask.PropertyChangeMask, ref e); X11lib.XCloseDisplay(d); }
/// <summary> Determines whether visual supports true color (32 or 24 bit depth). </summary> /// <param name='display'> The display pointer, that specifies the connection to the X server </param> /// <param name='scrnID'> The screen number, that specifies the appropriate screen on the host server. </param> /// <returns> <c>true</c> if visual supports direct color, otherwise, <c>false</c>. </returns> public static bool IsTrueColorVisual (IntPtr display, TInt scrnID) { X11lib.XVisualInfo visInfo = new X11lib.XVisualInfo(); if (X11lib.XMatchVisualInfo (display, scrnID, (TInt)32, TrueColor, ref visInfo) != 0) { //X11lib.XFree (visInfo); return true; } else if (X11lib.XMatchVisualInfo (display, scrnID, (TInt)24, TrueColor, ref visInfo) != 0) { //X11lib.XFree (visInfo); return true; } else return false; }
/// <summary>Free the resource.</summary> public void Unload() { if (_display != IntPtr.Zero && _fontResourceId != (X11.XID) 0) { if (!_useFontset && _fontResourceId != (X11.XID) 0) { X11lib.XUnloadFont(_display, _fontResourceId); } else if (_useFontset && _fontResourceId != (X11.XID) 0) { X11lib.XFreeFontSet(_display, _fontResourceId); } _display = IntPtr.Zero; _fontResourceId = (X11.XID) 0; } }
/// <summary> Determines whether visual supports direct color (32 or 24 bit depth). </summary> /// <param name='display'> The display pointer, that specifies the connection to the X server </param> /// <param name='scrnID'> The screen number, that specifies the appropriate screen on the host server. </param> /// <returns> <c>true</c> if visual supports direct color, otherwise, <c>false</c>. </returns> public static bool IsDirectColorVisual(IntPtr display, TInt scrnID) { X11lib.XVisualInfo visInfo = new X11lib.XVisualInfo(); if (X11lib.XMatchVisualInfo(display, scrnID, (TInt)32, DirectColor, ref visInfo) != 0) { //X11lib.XFree (visInfo); return(true); } else if (X11lib.XMatchVisualInfo(display, scrnID, (TInt)24, DirectColor, ref visInfo) != 0) { //X11lib.XFree (visInfo); return(true); } else { return(false); } }
// ############################################################################### // ### M E T H O D S // ############################################################################### #region Methods /// <summary>Get the image as System.Drawing.Bitmap.</summary> /// <returns>The image as bitmap on success, or null otherwise.<see cref="System.Drawing.Bitmap"/></returns> public System.Drawing.Bitmap GetBitmap() { if (_imageSurface == null || _imageSurface.Drawable == IntPtr.Zero) { return(null); } IntPtr image = X11lib.XGetImage(_imageSurface.Display, _imageSurface.Drawable, 0, 0, (X11.TUint)_size.Width, (X11.TUint)_size.Height, (X11.TUlong)(UInt32.MaxValue), (X11.TInt) 2); if (image == IntPtr.Zero) { return(null); } System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(_size.Width, _size.Height); System.Drawing.Color color = System.Drawing.Color.Black; for (int scanLine = 0; scanLine < _size.Height; scanLine++) { for (int scanCol = 0; scanCol < _size.Width; scanCol++) { X11.TPixel pixel = X11lib.XGetPixel(image, (X11.TInt)scanCol, (X11.TInt)scanLine); if (_imageSurface.Depth >= 24) { color = System.Drawing.Color.FromArgb((int)pixel); } else { color = System.Drawing.Color.FromArgb(_imageSurface.RgbForColor(pixel)); } bmp.SetPixel(scanCol, scanLine, color); } } X11lib.XDestroyImage(image); return(bmp); }
/// <summary> Provide a bitmap, containing the transparency mask, that can be used independent from this class. </summary> /// <param name="display"> The display pointer, that specifies the connection to the X server. <see cref="System.IntPtr"/> </param> /// <param name="window"> The target window to create the pixmap for. <see cref="IntPtr"/> </param> /// <returns> The (server side) pixmap (that must be feed) on success, or IntPtr.Zero otherwise. <see cref="IntPtr"/> </returns> public IntPtr CreateIndependentMaskPixmap(IntPtr display, IntPtr window) { if (_transpXImage == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr pixmap = X11lib.XCreatePixmap(display, window, (TUint)_width, (TUint)_height, (TUint)_clipDepth); IntPtr pixmapGc = X11lib.XCreateGC(display, pixmap, (TUlong)0, IntPtr.Zero); if (pixmapGc != IntPtr.Zero) { X11lib.XPutImage(display, pixmap, pixmapGc, _transpXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Console.WriteLine (CLASS_NAME + "::CreateIndependentMaskPixmap () Delete transparency mask image GC."); X11lib.XFreeGC(display, pixmapGc); pixmapGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::CreateIndependentMaskPixmap () ERROR: Can not create graphics context for mask pixmap."); } return(pixmap); }
// ############################################################################### // ### D E S T R U C T I O N // ############################################################################### #region Destruction /// <summary> IDisposable implementation. </summary> public void Dispose() { // Console.WriteLine (CLASS_NAME + "::Dispose ()"); if (_graphicXImage != IntPtr.Zero) { // Note: The destroy procedure (_XImage.f.destroy_image), that this macro calls, // frees both - the image structure and the data pointed to by the image structure. X11lib.XDestroyImage(_graphicXImage); _graphicXImage = IntPtr.Zero; } if (_transpXImage != IntPtr.Zero) { // Note: The destroy procedure (_XImage.f.destroy_image), that this macro calls, // frees both - the image structure and the data pointed to by the image structure. X11lib.XDestroyImage(_transpXImage); _transpXImage = IntPtr.Zero; } if (_transpXPixmap != IntPtr.Zero) { X11lib.XFreePixmap(_display, _transpXPixmap); _transpXPixmap = IntPtr.Zero; } }
// ############################################################################### // ### M E T H O D S // ############################################################################### #region Methods /// <summary>Prepare a font or fonteset for utilization with Xrw.</summary> /// <param name="fontSpecification">The font specification, that identifies a font/fontset.<see cref="System.String"/></param> /// <param name="x11display">The display pointer, that specifies the connection to the X server.<see cref="IntPtr"/></param> /// <param name="useFontset">The flag defining whether to use a fontset or a single font.<see cref="System.Boolean"/></param> /// <param name="fontData">The resulting font data on success, or null otherwise.<see cref="X11.X11FontData"/></param> /// <returns>True on success, or false otherwise.<see cref="System.Boolean"/></returns> public static bool PrepareFont(string fontSpecification, IntPtr x11display, bool useFontset, ref X11.X11FontData fontData) { fontData = null; foreach (KeyValuePair <FontDataKey, X11FontData> loadedFont in _loadedFonts) { if (loadedFont.Key.FontSpecification == fontSpecification && loadedFont.Key.X11Display == x11display && loadedFont.Key.UseFontset) { fontData = loadedFont.Value; return(true); } } FontDataKey key = new FontDataKey(fontSpecification, x11display, useFontset); if (useFontset) { IntPtr missingCharsetList; TInt missingCharsetCount; X11.XID fontsetResourceId = X11lib.XCreateFontSet(x11display, fontSpecification, out missingCharsetList, out missingCharsetCount, IntPtr.Zero); // Check whether directly matching fontset has been loaded, and - if not - load the most similar fontset (fuzzy). int fuzzyFactor = 0; string fuzzyFontSpecification = (fontsetResourceId == (X11.XID) 0 ? fontSpecification : null); while (fontsetResourceId == (X11.XID) 0 && fuzzyFactor < 3) { string lastFuzzyFontSpecification = fuzzyFontSpecification; if (fuzzyFactor == 0) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationStretch(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 1) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationWieght(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 2) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationSlant(fuzzyFontSpecification, "*"); } fuzzyFactor++; // Safe time if no change has been made. if (lastFuzzyFontSpecification == fuzzyFontSpecification) { continue; } if (!string.IsNullOrEmpty(lastFuzzyFontSpecification) && lastFuzzyFontSpecification.Trim() != "") { fontsetResourceId = X11lib.XCreateFontSet(x11display, fuzzyFontSpecification, out missingCharsetList, out missingCharsetCount, IntPtr.Zero); if (fontsetResourceId != (X11.XID) 0) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Fuzzy load fontset with specification '" + fuzzyFontSpecification + "' " + "instead of '" + fontSpecification + "' succeeded."); } } } // Check whether directly matching or most similar fontset has been loaded, and - if not - load a fallback fontset. string extFontSpecification = null; if (fontsetResourceId == (X11.XID) 0) { // Let the font server guess a fallback fontset. if (!string.IsNullOrEmpty(fontSpecification) && fontSpecification.Trim() != "" && !fontSpecification.Trim().EndsWith(",*")) { extFontSpecification = fontSpecification + ",*"; SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + fontSpecification + "'."); SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Retry to load a fontset with specification '" + extFontSpecification + "'."); fontsetResourceId = X11lib.XCreateFontSet(x11display, extFontSpecification, out missingCharsetList, out missingCharsetCount, IntPtr.Zero); } // The font specification already includs a joker to guess a fallback fontset. else { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + fontSpecification + "'."); // No success at all - even with a guess of a fallback fontset! return(false); } } // Check whether matching fontset has been loaded. if (fontsetResourceId == (X11.XID) 0) { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + extFontSpecification + "'."); // No success at all - even with a guess of a fallback fontset! return(false); } if (!string.IsNullOrEmpty(extFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching fontset for specification '" + fontSpecification + "' " + "using specification '" + extFontSpecification + "'."); } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching fontset for specification '" + fontSpecification + "' " + "using specification '" + fuzzyFontSpecification + "'."); } else { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching fontset for specification '" + fontSpecification + "'."); } for (int countCharSet = 0; countCharSet < (int)missingCharsetCount; countCharSet++) { IntPtr p = Marshal.ReadIntPtr(missingCharsetList, countCharSet * Marshal.SizeOf(typeof(IntPtr))); string s = Marshal.PtrToStringAuto(p); if (!string.IsNullOrEmpty(extFontSpecification)) { SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Fontset for specification '" + extFontSpecification + "' is missing font for charset '" + s + "'."); } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Fontset for specification '" + fuzzyFontSpecification + "' is missing font for charset '" + s + "'."); } else { SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Fontset for specification '" + fontSpecification + "' is missing font for charset '" + s + "'."); } } // Calculate maximum font height, ascent and descent. int ascent = 0; int descent = 0; X11lib.XFontSetExtents extents = X11lib.XExtentsOfFontSet(fontsetResourceId); X11lib.XFontStruct[] fontStructArray; string[] fontNameArray; int maxFonts; maxFonts = X11lib.XFontsOfFontSet(fontsetResourceId, out fontStructArray, out fontNameArray); for (int countFonts = 0; countFonts < maxFonts; countFonts++) { if (ascent < (int)fontStructArray[countFonts].ascent) { ascent = (int)fontStructArray[countFonts].ascent; } if (descent < (int)fontStructArray[countFonts].descent) { descent = (int)fontStructArray[countFonts].descent; } } string finalFontSpecification = null; if (!string.IsNullOrEmpty(extFontSpecification)) { finalFontSpecification = extFontSpecification; } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { finalFontSpecification = fuzzyFontSpecification; } else { finalFontSpecification = fontSpecification; } // Maximum font height, ascent and descent might be frequently used for calculation. fontData = X11FontData.NewFontSetData(finalFontSpecification, x11display, fontsetResourceId, (int)extents.max_logical_extent.height, ascent, descent); IntPtr gc = X11lib.XCreateGC(x11display, X11lib.XDefaultRootWindow(x11display), 0, IntPtr.Zero); if (gc != IntPtr.Zero) { fontData.SetTypicalCharWidth(AverageCharacterWidth(x11display, gc, fontData)); X11lib.XFreeGC(x11display, gc); } _loadedFonts.Add(key, fontData); return(true); } // Use font, if fontset isn't supported. else // of (useFontset) { // Load font and query font structure (to get maximum font height, ascent and descent). IntPtr fontStructure = X11lib.XLoadQueryFont(x11display, fontSpecification); // Check whether directly matching font has been loaded, and - if not - load the most similar font (fuzzy). int fuzzyFactor = 0; string fuzzyFontSpecification = (fontStructure == IntPtr.Zero ? fontSpecification : null); while (fontStructure == IntPtr.Zero && fuzzyFactor < 3) { string lastFuzzyFontSpecification = fuzzyFontSpecification; if (fuzzyFactor == 0) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationStretch(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 1) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationWieght(fuzzyFontSpecification, "*"); } if (fuzzyFactor == 2) { fuzzyFontSpecification = X11FontData.ModifyFontSpecificationSlant(fuzzyFontSpecification, "*"); } fuzzyFactor++; // Safe time if no change has been made. if (lastFuzzyFontSpecification == fuzzyFontSpecification) { continue; } if (!string.IsNullOrEmpty(lastFuzzyFontSpecification) && lastFuzzyFontSpecification.Trim() != "") { fontStructure = X11lib.XLoadQueryFont(x11display, lastFuzzyFontSpecification); if (fontStructure != IntPtr.Zero) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Fuzzy load font with specification '" + fuzzyFontSpecification + "' " + "instead of '" + fontSpecification + "' succeeded."); } } } // Check whether directly matching or most similar font has been loaded, and - if not - load a fallback font. string extFontSpecification = null; if (fontStructure != IntPtr.Zero) { // Let the font server guess a fallback fontset. if (!string.IsNullOrEmpty(fontSpecification) && fontSpecification.Trim() != "" && !fontSpecification.Trim().EndsWith(",*")) { extFontSpecification = fontSpecification + ",*"; SimpleLog.LogLine(TraceEventType.Warning, CLASS_NAME + "::PrepareFont () Can not load a fontset with specification '" + fontSpecification + "'."); SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Retry to load a fontset with specification '" + extFontSpecification + "'."); fontStructure = X11lib.XLoadQueryFont(x11display, extFontSpecification); } // The font specification already includs a joker to guess a fallback fontset. else { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a font with specification '" + fontSpecification + "'."); // No success at all - even with a guess of a fallback font! return(false); } } // Check whether matching font has been loaded. if (fontStructure == IntPtr.Zero) { SimpleLog.LogLine(TraceEventType.Error, CLASS_NAME + "::PrepareFont () Can not load a font with specification '" + fontSpecification + "'."); // No success at all - even with a guess of a fallback font! return(false); } if (!string.IsNullOrEmpty(extFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching font for specification '" + fontSpecification + "' " + "using specification '" + extFontSpecification + "'."); } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching font for specification '" + fontSpecification + "' " + "using specification '" + fuzzyFontSpecification + "'."); } else { SimpleLog.LogLine(TraceEventType.Information, CLASS_NAME + "::PrepareFont () Successfully loaded best matching font for specification '" + fontSpecification + "'."); } X11lib.XFontStruct fs = (X11lib.XFontStruct)Marshal.PtrToStructure(fontStructure, typeof(X11lib.XFontStruct)); string finalFontSpecification = null; if (!string.IsNullOrEmpty(extFontSpecification)) { finalFontSpecification = extFontSpecification; } else if (!string.IsNullOrEmpty(fuzzyFontSpecification)) { finalFontSpecification = fuzzyFontSpecification; } else { finalFontSpecification = fontSpecification; } // Maximum font height, ascent and descent might be frequently used for calculation. fontData = X11FontData.NewSingleFontData(finalFontSpecification, x11display, fs.fid, (int)fs.ascent + (int)fs.descent, (int)fs.ascent, (int)fs.descent); IntPtr gc = X11lib.XCreateGC(x11display, X11lib.XDefaultRootWindow(x11display), 0, IntPtr.Zero); if (gc != IntPtr.Zero) { fontData.SetTypicalCharWidth(AverageCharacterWidth(x11display, gc, fontData)); X11lib.XFreeGC(x11display, gc); } _loadedFonts.Add(key, fontData); return(true); } }
/// <summary> Handle the ButtonPress event. </summary> /// <param name="source"> The widget, the ButtonPress event is assigned to. <see cref="XrwRectObj"/> </param> /// <param name="e"> The event data. <see cref="XawButtonEvent"/> </param> /// <remarks> Set XawButtonEvent. Set result to nonzero to stop further event processing. </remarks> void HandleCloseMenuButtonPress(XrwRectObj source, XrwButtonEvent e) { X11lib.XSetInputFocus(_display, _window, X11lib.TRevertTo.RevertToParent, (TInt)0); e.Result = 1; }
public void Run() { InitializeApplicationShellResources(); X11.TPixel pixel = X11lib.XAllocParsedColorByName(_display, _screenNumber, "plum"); X11lib.XSetForeground(_display, _gc, pixel); // Clear the window and bring it on top of the other windows. X11lib.XClearWindow(_display, _window); X11lib.XMapRaised(_display, _window); XrwBox vboxMain = XrwBox.NewVBox(_display, _screenNumber, _window); vboxMain.BorderColor = vboxMain.BackgroundColor; vboxMain.VertSpacing = 0; vboxMain.FrameWidth = 2; vboxMain.Show(); XrwBox hboxFileRibbon = XrwBox.NewHBox(_display, _screenNumber, _window); hboxFileRibbon.BorderWidth = 0; hboxFileRibbon.FrameType = XrwTheme.NonInteractingFrameType; hboxFileRibbon.ChildAlign = 0.0F; hboxFileRibbon.ExpandToAvailableHeight = true; // ---- TPoint origin = new TPoint(20, 20); _fileMenuShell = new XrwSimpleMenu(this, ref origin); X11Graphic menuEntryGraphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.Information16TrueColor); XrwSme menuEntry1 = new XrwSme(_fileMenuShell.Display, _fileMenuShell.Screen, _fileMenuShell.Window, "File menu entry 1", menuEntryGraphic, true, null, false); menuEntry1.ButtonRelease += HandleMenuEntry1ButtonRelease; _fileMenuShell.AddChild(menuEntry1); XrwSme menuEntry2 = new XrwSme(_fileMenuShell.Display, _fileMenuShell.Screen, _fileMenuShell.Window, "File menu entry 2", menuEntryGraphic, true, null, false); menuEntry2.ButtonRelease += HandleMenuEntry2ButtonRelease; _fileMenuShell.AddChild(menuEntry2); _fileMenuShell.CalculateChildLayout(); _fileMenuShell.SetFixedWidth(_fileMenuShell.AssignedSize.Width); _fileMenuShell.SetFixedHeight(_fileMenuShell.AssignedSize.Height); // ---- XrwMenuButton commandFileMenu = new XrwMenuButton(_display, _screenNumber, _window, "File"); commandFileMenu.FrameType = XrwTheme.NonInteractingFrameType; commandFileMenu.FrameWidth = XrwTheme.NonInteractingFrameWidth; commandFileMenu.ExpandToAvailableHeight = true; commandFileMenu.Menu = _fileMenuShell; hboxFileRibbon.AddChild(commandFileMenu); X11Graphic cbw1Graphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.Error16TrueColor); XrwCommand cbw1 = new XrwCommand(_display, _screenNumber, _window, "Close menu", cbw1Graphic, true, null, false); cbw1.FrameType = XrwTheme.NonInteractingFrameType; cbw1.FrameWidth = XrwTheme.NonInteractingFrameWidth; cbw1.ExpandToAvailableHeight = true; cbw1.ButtonPress += HandleCloseMenuButtonPress; hboxFileRibbon.AddChild(cbw1); X11Graphic cbw2Graphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.Question16TrueColor); XrwCommand cbw2 = new XrwCommand(_display, _screenNumber, _window, "Message box", cbw2Graphic, true, null, false); cbw2.FrameType = XrwTheme.NonInteractingFrameType; cbw2.FrameWidth = XrwTheme.NonInteractingFrameWidth; cbw2.ExpandToAvailableHeight = true; cbw2.ButtonRelease += HandleMessageBoxButtonRelease; hboxFileRibbon.AddChild(cbw2); X11Graphic cbw3Graphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.Warning16TrueColor); XrwCommand cbw3 = new XrwCommand(_display, _screenNumber, _window, "Close app", cbw3Graphic, true, null, false); cbw3.FrameType = XrwTheme.NonInteractingFrameType; cbw3.FrameWidth = XrwTheme.NonInteractingFrameWidth; cbw3.ExpandToAvailableHeight = true; cbw3.ButtonRelease += HandleCloseButtonRelease; hboxFileRibbon.AddChild(cbw3); // ---- XrwBox hboxToggleRibbon = XrwBox.NewHBox(_display, _screenNumber, _window); hboxToggleRibbon.BorderWidth = 0; hboxToggleRibbon.ChildAlign = 0.0F; hboxToggleRibbon.VertSpacing = 0; X11Graphic toggleOffGraphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.ToggleOff16TrueColor); X11Graphic toggleOnGraphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.ToggleOn16TrueColor); XrwToggle toggle1 = new XrwToggle(_display, _screenNumber, _window, "Toggle test 1", toggleOffGraphic, true, toggleOnGraphic, true); toggle1.ExpandToAvailableWidth = false; toggle1.FrameWidth = XrwTheme.InteractingFrameWidth; hboxToggleRibbon.AddChild(toggle1); XrwToggle toggle2 = new XrwToggle(_display, _screenNumber, _window, "Toggle test 2", toggleOffGraphic, true, toggleOnGraphic, true); toggle2.ExpandToAvailableWidth = false; toggle2.FrameWidth = XrwTheme.InteractingFrameWidth; hboxToggleRibbon.AddChild(toggle2); XrwToggle toggle3 = new XrwToggle(_display, _screenNumber, _window, "Toggle test 3", toggleOffGraphic, true, toggleOnGraphic, true); toggle3.ExpandToAvailableWidth = false; toggle3.FrameWidth = XrwTheme.InteractingFrameWidth; hboxToggleRibbon.AddChild(toggle3); // ---- XrwRadioBox hboxRadioRibbon = XrwRadioBox.NewHRadioBox(_display, _screenNumber, _window); hboxRadioRibbon.BorderWidth = 0; hboxRadioRibbon.ChildAlign = 0.0F; hboxRadioRibbon.VertSpacing = 0; X11Graphic radioOffGraphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.RadioOff16TrueColor); X11Graphic radioOnGraphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.RadioOn16TrueColor); XrwRadio radio1 = new XrwRadio(_display, _screenNumber, _window, "Radio test 1", radioOffGraphic, true, radioOnGraphic, true); radio1.ExpandToAvailableWidth = false; radio1.FrameType = XrwTheme.InteractingFrameType; radio1.FrameWidth = XrwTheme.InteractingFrameWidth; hboxRadioRibbon.AddChild(radio1); XrwRadio radio2 = new XrwRadio(_display, _screenNumber, _window, "Radio test 2", radioOffGraphic, true, radioOnGraphic, true); radio2.ExpandToAvailableWidth = false; radio2.FrameType = XrwTheme.InteractingFrameType; radio2.FrameWidth = XrwTheme.InteractingFrameWidth; hboxRadioRibbon.AddChild(radio2); XrwRadio radio3 = new XrwRadio(_display, _screenNumber, _window, "Radio test 3", radioOffGraphic, true, radioOnGraphic, true); radio3.ExpandToAvailableWidth = false; radio3.FrameType = XrwTheme.InteractingFrameType; radio3.FrameWidth = XrwTheme.InteractingFrameWidth; hboxRadioRibbon.AddChild(radio3); // ---- XrwNotebook ribbonBar = XrwNotebook.NewTopTabedNotebook(_display, _screenNumber, _window); ribbonBar.FrameType = TFrameType.Sunken; ribbonBar.FrameWidth = 1; ribbonBar.AddChild(hboxFileRibbon); (ribbonBar.TabWidget(ribbonBar.CountPages - 1) as XrwRadio).Label = "File"; ribbonBar.AddChild(hboxRadioRibbon); (ribbonBar.TabWidget(ribbonBar.CountPages - 1) as XrwRadio).Label = "Radio test"; ribbonBar.AddChild(hboxToggleRibbon); (ribbonBar.TabWidget(ribbonBar.CountPages - 1) as XrwRadio).Label = "Toggle test"; vboxMain.AddChild(ribbonBar); ribbonBar.Show(); /* * // A panel is windowless! All expose events are routed to the parent widget. * XrwPanel panel1 = new XrwPanel (_display, _screenNumber, _window); * panel1.FrameType = TFrameType.Sunken; * panel1.FrameWidth = XrwTheme.FrameWidth; * vboxMain.AddChild (panel1); * panel1.Show (); */ // Simple is windowed! No expose events are routed to the parent widget. XrwSimple simple1 = new XrwSimple(_display, _screenNumber, _window); simple1.FrameType = TFrameType.Sunken; simple1.FrameWidth = 1; // XrwTheme.FrameWidth; simple1.ExpandToAvailableHeight = true; simple1.ExpandToAvailableWidth = true; vboxMain.AddChild(simple1); simple1.Show(); X11Graphic labelGraphic = XrwTheme.GetGraphic(_display, _screenNumber, X11Graphic.StockIcon.Information16TrueColor); _labelStatus = new XrwLabel(_display, _screenNumber, _window, "Hallo App!", labelGraphic, true, labelGraphic, true); _labelStatus.FrameType = TFrameType.Sunken; _labelStatus.FrameWidth = 1; // XrwTheme.FrameWidth; _labelStatus.HorzTextAlign = 0.0F; _labelStatus.BorderWidth = 0; _labelStatus.VertTextAlign = 0.5F; _labelStatus.ExpandToAvailableWidth = true; vboxMain.AddChild(_labelStatus); _labelStatus.Show(); this.AddChild(vboxMain); // Register close event. this.WmShellClose += HandleApplicationClose; ApplicationFramework.WriteStatusText += HandleWriteStatus; X11lib.XSetWMName(_display, _window, "Hallo X11 from C#!"); X11lib.XSetWMIconName(_display, _window, "X11 from C#"); ApplicationFramework.SetWmShellIcon(this, APPICON_FILEPATH); Show(); RunMessageLoop(); }
/// <summary> Provide a bitmap, containing the transparent graphic, that can be used independent from this class. </summary> /// <param name="display"> The display pointer, that specifies the connection to the X server. <see cref="System.IntPtr"/> </param> /// <param name="window"> The target window to create the pixmap for. <see cref="IntPtr"/> </param> /// <param name="backgroundColorPixel"> The background color behind any transparent pixel. <see cref="TPixel"/> </param> /// <param name="maskPixmap"> The mask pixmap to distinguish transparent from intransparent pixel. <see cref="IntPtr"/> </param> /// <returns> The (server side) pixmap (that must be feed) on success, or IntPtr.Zero otherwise. <see cref="IntPtr"/> </returns> public IntPtr CreateIndependentPixmap(IntPtr display, IntPtr window, TPixel backgroundColorPixel, IntPtr maskPixmap) { if (_graphicXImage == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr pixmap = X11lib.XCreatePixmap(display, window, (TUint)_width, (TUint)_height, (TUint)_graphicDepth); // Fill pixmap with background color. IntPtr bgGc = X11lib.XCreateGC(display, window, (TUlong)0, IntPtr.Zero); X11lib.XSetForeground(display, bgGc, backgroundColorPixel); X11lib.XFillRectangle(display, pixmap, bgGc, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); X11lib.XFreeGC(display, bgGc); bgGc = IntPtr.Zero; // Overlay the image. IntPtr pixmapGc = X11lib.XCreateGC(display, window, (TUlong)0, IntPtr.Zero); if (pixmapGc != IntPtr.Zero) { if (maskPixmap != IntPtr.Zero) { // Prepare the clipping graphics context. IntPtr graphicGc = X11lib.XCreateGC(display, window, (TUlong)0, IntPtr.Zero); if (graphicGc != IntPtr.Zero) { X11lib.XSetClipMask(display, graphicGc, maskPixmap); X11lib.XSetClipOrigin(display, graphicGc, (TInt)0, (TInt)0); // Draw graphic using the clipping graphics context. X11lib.XPutImage(display, pixmap, graphicGc, _graphicXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Restore previous behaviour and clean up. X11lib.XSetClipMask(display, graphicGc, IntPtr.Zero); X11lib.XSetClipOrigin(display, graphicGc, (TInt)0, (TInt)0); // Console.WriteLine (CLASS_NAME + "::Draw () Delete clipping image GC."); X11lib.XFreeGC(display, graphicGc); graphicGc = IntPtr.Zero; } else { Console.WriteLine(CLASS_NAME + "::Draw () ERROR: Can not create graphics context for transparency application."); } } else { X11lib.XPutImage(display, pixmap, pixmapGc, _graphicXImage, (TInt)0, (TInt)0, (TInt)0, (TInt)0, (TUint)_width, (TUint)_height); // Console.WriteLine (CLASS_NAME + "::CreateIndependentGraphicPixmap () Delete graphic image GC."); X11lib.XFreeGC(display, pixmapGc); pixmapGc = IntPtr.Zero; } } else { Console.WriteLine(CLASS_NAME + "::CreateIndependentGraphicPixmap () ERROR: Can not create graphics context for graphic pixmap."); } return(pixmap); }
/// <summary> Initialize local ressources for all constructors. </summary> /// <param name="bmp"> The bitmap associated with this graphic. <see cref="Bitmap"/> </param> private void InitializeGraphicRessources(Bitmap bmp) { IntPtr visual = X11lib.XDefaultVisual(_display, _screenNumber); if (visual == IntPtr.Zero) { throw new OperationCanceledException("Failed to investigate default visual."); } _width = bmp.Width; _height = bmp.Height; // Prepare bitmap conversion. int colorPixelBytes = 4; int maskLineBytes = (int)((_width + (int)IMAGE_PADDING - 1) / (int)IMAGE_PADDING); _graphicDepth = (int)X11lib.XDefaultDepth(_display, _screenNumber); if (_graphicDepth > 16) { colorPixelBytes = 4; } else if (_graphicDepth > 8) { colorPixelBytes = 2; } else { colorPixelBytes = 1; } // ### Allocate bitmap conversion data. // The bitmap color data. Use a temporary managed byte array for speed. byte[] graphicData = new byte[_height * _width * colorPixelBytes]; // The bitmap transparency data. Use a temporary managed byte array for speed. byte[] maskData = new byte[_height * maskLineBytes]; // Quick access to current line's color pixel. int graphicPixelIndex = 0; // Quick access to current line's mask pixel. int maskPixelIndex = 0; // Reduce slow calls to bmp.GetPixel (x,y). Color pixelColor = Color.Black; // Determine whether transparency is required. bool transparency = false; // ### Convert bitmap. for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { graphicPixelIndex = (y * _width + x) << 2; maskPixelIndex = y * maskLineBytes + (x >> 3); pixelColor = bmp.GetPixel(x, y); graphicData[graphicPixelIndex + 0] = pixelColor.B; // B graphicData[graphicPixelIndex + 1] = pixelColor.G; // G graphicData[graphicPixelIndex + 2] = pixelColor.R; // R graphicData[graphicPixelIndex + 3] = pixelColor.A; // A if (pixelColor.B == 255 && pixelColor.G == 255 && pixelColor.R == 255) { byte summand = (byte)(1 << (x % 8)); maskData[maskPixelIndex] = (byte)(maskData[maskPixelIndex] + summand); transparency = true; } } } // ### Create XImage. // The bitmap color data. IntPtr graphicDataHandle = Marshal.AllocHGlobal(graphicData.Length); // Allocate not movable memory. Marshal.Copy(graphicData, 0, graphicDataHandle, graphicData.Length); // Client side XImage storage. _graphicXImage = X11lib.XCreateImage(_display, visual, (TUint)_graphicDepth, X11lib.TImageFormat.ZPixmap, (TInt)0, graphicDataHandle, (TUint)_width, (TUint)_height, IMAGE_PADDING, ASSUME_CONTIGUOUS); if (_graphicXImage == IntPtr.Zero) { throw new OperationCanceledException("Image creation for graphic failed."); } if (transparency == true) { IntPtr maskDataHandle = Marshal.AllocHGlobal(maskData.Length); // The bitmap bitmap transparency data. Marshal.Copy(maskData, 0, maskDataHandle, maskData.Length); // Allocate not movable memory. // Client side storage. _transpXImage = X11lib.XCreateImage(_display, visual, (TUint)_clipDepth, X11lib.TImageFormat.XYBitmap, (TInt)0, maskDataHandle, (TUint)_width, (TUint)_height, IMAGE_PADDING, ASSUME_CONTIGUOUS); if (_transpXImage == IntPtr.Zero) { throw new OperationCanceledException("Image creation for transparency mask failed."); } } }
/// <summary>Draw the image in the indicated window, using the indicated graphics context.</summary> /// <param name="window">The window to draw the pitmap on.<see cref="System.IntPtr"/></param> /// <param name="gc">The crapchics context to use for drawing.<see cref="System.IntPtr"/></param> /// <param name="destX">The x coordinate, which is relative to the origin of the window and is the coordinate of the subimage.<see cref="TInt"/></param> /// <param name="destY">The y coordinate, which is relative to the origin of the window and is the coordinate of the subimage.<see cref="TInt"/></param> public void Draw(IntPtr window, IntPtr gc, TInt destX, TInt destY) { X11lib.XCopyArea(_imageSurface.Display, _imageSurface.Drawable, window, gc, (X11.TInt) 0, (X11.TInt) 0, (X11.TUint)_size.Width, (X11.TUint)_size.Height, destX, destY); }
private void Loop() { display = X11lib.XOpenDisplay(null); if (display == IntPtr.Zero) { return; } if (window == IntPtr.Zero) { int res = 0; X11lib.XGetInputFocus(display, ref window, ref res); if (window == IntPtr.Zero) { return; } } // TODO: move grabkeyboard to separate class bool grabKeyboard = false; if (grabKeyboard) { var rootWindow = X11lib.XDefaultRootWindow(display); window = X11lib.XCreateSimpleWindow(display, rootWindow, -1, -1, 1, 1, 0, X11lib.XBlackPixel(display, 0), X11lib.XWhitePixel(display, 0)); X11lib.XLowerWindow(display, window); } X11lib.XSelectInput(display, window, EventMask.StructureNotifyMask | EventMask.ExposureMask | EventMask.KeyPressMask | EventMask.KeyReleaseMask | EventMask.EnterWindowMask | EventMask.LeaveWindowMask | EventMask.FocusChangeMask | EventMask.PropertyChangeMask | EventMask.VisibilityChangeMask ); X11lib.XMapWindow(display, window); if (grabKeyboard) { var e2 = new XEvent { type = XEventName.None }; do { X11lib.XNextEvent(display, ref e2); } while (e2.type != XEventName.MapNotify); X11lib.XGrabKeyboard(display, window, false, 1, 1, 0); X11lib.XLowerWindow(display, window); } var e = new XEvent { type = XEventName.None }; do { switch (e.type) { case XEventName.ConfigureNotify: OnConfigure(); break; case XEventName.Expose: // The count member is set to the number of Expose events that are to follow. // If count is zero, no more Expose events follow for this window. // However, if count is nonzero, at least that number of Expose events (and possibly more) follow for this window. // Simple applications that do not want to optimize redisplay by distinguishing between subareas of its window // can just ignore all Expose events with nonzero counts and perform full redisplays on events with zero counts. if (e.ExposeEvent.count == 0) { OnExpose(); } break; case XEventName.KeyPress: //var mod = (Modifier) X.XkbKeysymToModifiers(display, X.XKeycodeToKeysym(display, e.KeyEvent.keycode, 0)); OnKeyPress((Key)X11lib.XKeycodeToKeysym(display, e.KeyEvent.keycode, 0)); break; case XEventName.KeyRelease: OnKeyRelease((Key)X11lib.XKeycodeToKeysym(display, e.KeyEvent.keycode, 0)); break; case XEventName.EnterNotify: OnEnterLeave(true); break; case XEventName.LeaveNotify: OnEnterLeave(false); break; case XEventName.FocusIn: OnFocus(true); break; case XEventName.FocusOut: OnFocus(false); break; case XEventName.PropertyNotify: // state - PropertyNewValue or PropertyDelete OnProperty(e.PropertyEvent.state); break; case XEventName.VisibilityNotify: OnVisibility(); break; case XEventName.ClientMessage: OnClientMessage(); break; } X11lib.XNextEvent(display, ref e); } while (!stop); X11lib.XCloseDisplay(display); display = IntPtr.Zero; window = IntPtr.Zero; }
// ############################################################################### // ### C O N S T R U C T I O N A N D I N I T I A L I Z A T I O N // ############################################################################### #region Construction /// <summary>Initializing constructor.</summary> /// <param name="display">The display to initialize the font specifications for.<see cref="IntPtr"/></param> /// <param name="preferredCharSet">The preferred charset or empty string for no preference. /// Sort fonts with this charset to the top. <see cref="System.String"/> </param> public FontSpecificationList(IntPtr display, string preferredCharSet) { _preferredCharSet = preferredCharSet; TInt numFonts = 0; string fontFilter = "-*-*-*-*-*-*-*-*-*-*-*-*-*"; //string fontFilter = "-*-*-*-*-*-*-0-0-0-0-*-*-*"; // -1-2-3-4-5-6-7-8-9-A-B-C-D // 1 = Foundry // 2 = Family // 3 = Weight // 4 = Slant // 5 = Width // 6 = Extra // 7 = Pixel // 8 = TenthOfPoint // 9 = Horz resolution // A = Vert resolution // B = Spacing // C = TenthOfAveragePixelWidth // D = Characterset IntPtr fontNameArray = X11lib.XListFonts(display, fontFilter, (TInt)20000, ref numFonts); for (int countFont = 0; countFont < (int)numFonts; countFont++) { IntPtr fontNameDeref = System.Runtime.InteropServices.Marshal.ReadIntPtr(fontNameArray, IntPtr.Size * countFont); string fontName = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(fontNameDeref); if (!string.IsNullOrEmpty(fontName)) { _qualifiedFontNames.Add(fontName); this.AddFontSpecification(fontName); // This takes a lot of time!!! /* * IntPtr fontResourceId = X11lib.XLoadFont (display, fontName); * if (fontResourceId != IntPtr.Zero) * { * IntPtr fontStruct = X11lib.XQueryFont (display, fontResourceId); * if (fontStruct != IntPtr.Zero) * { * string name = ""; * TUlong val = (TUlong)0; * TBoolean res = X11lib.XGetFontProperty (fontStruct, X11atoms.XA_FAMILY_NAME, ref val); * if (res == (TBoolean)1) * { * IntPtr nameRef = X11lib.XGetAtomName (display, (IntPtr)val); * if (nameRef != IntPtr.Zero) * { * name = System.Runtime.InteropServices.Marshal.PtrToStringAuto (nameRef); * X11lib.XFree (nameRef); * } * } * X11lib.XFreeFontInfo (IntPtr.Zero, fontStruct, (TInt)0); * } * //X11lib.XFreeFont (display, fontResourceId); * } */ } } X11lib.XFreeFontNames(fontNameArray); fontNameArray = IntPtr.Zero; // http://coot.googlecode.com/svn/trunk/ccp4mg-utils/pygl/x11_font.cc _qualifiedFontNames.Sort(); this.Sort(); }