⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xdisplay.c

📁 书名:C语言科学与艺术,以前交钱下载的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: xdisplay.c * Version: 3.0 * Last modified on Sat Oct  1 12:25:07 1994 by eroberts * ----------------------------------------------------- * This file implements the xdisplay.h interface, which is * responsible for all of the X windows interaction.  Before * you attempt to understand this implementation, you need to * understand the basics of X11 library. *//* * General implementation notes * ---------------------------- * This implementation creates two X drawables: the graphics * window itself (mainWindow) and an offscreen window (osWindow). * All rendering is done into the offscreen window.  When update * events occur, the graphics window is updated by copying bits * from the offscreen window. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <sys/time.h>#include <sys/types.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include "genlib.h"#include "strlib.h"#include "glibrary.h"#include "extgraph.h"#include "xmanager.h"#include "xdisplay.h"/* * Parameters * ---------- * RequiredMargin -- Minimum margin on each side of screen (inches) * BorderPixels   -- Width of the window border in pixels * MaxFontList    -- Size of the font list we will accept * PStartSize     -- Starting size for polygon (must be greater than 1) * DefaultFont    -- Font that serves as the "Default" font */#define RequiredMargin   0.5#define BorderPixels     1#define MaxFontList    500#define PStartSize      50#define DefaultFont     "courier"/* * Other constants * --------------- * Epsilon -- Small offset used to avoid banding/aliasing * GCFgBg  -- GC mask for both foreground and background */#define Epsilon 0.000000001#define GCFgBg (GCForeground | GCBackground)/* * Static table: grayList * ---------------------- * This table contains the bitmaps for the various gray-scale * values.  Adding more bitmaps to this list increases * the precision at which the client can specify gray scales. */static char grayList[][8] = {    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },    { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },    { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },    { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },};#define NGrays (sizeof grayList / sizeof grayList[0])/* * Type: waitStateT * ---------------- * This type indicates the various conditions for which the * client might be waiting. */typedef enum {    NotWaiting,    WaitingForMouseDown,    WaitingForMouseUp} waitStateT;/* * Private variables * ----------------- * displayIsOpen   -- TRUE if the display has been opened * redraw          -- TRUE if mainWindow needs redrawing * eraseMode       -- TRUE if erase mode has been set * xdpi, ydpi      -- Dots per inch in each coordinate * disp            -- X display containing windows * mainWindow      -- Handle of graphics window * osWindow        -- Handle of offscreen window bitmap * pixelDepth      -- Depth of pixels on the screen * colormap        -- Color map of screen * drawColor       -- Color used for drawing (black) * eraseColor      -- Color used for erasing (white) * mainGC          -- The graphics context (GC) for mainWindow * drawGC          -- The GC used for drawing on osWindow * eraseGC         -- The GC used for erasing on osWindow * grayGC          -- Array of GCs representing gray scales * grayStipple     -- Array of stipples used for gray scales * currentFont     -- Name of current font * currentSize     -- Current point size * currentStyle    -- Current style * fontInfo        -- Font structure pointer for current font * windowWidth     -- Width of the window in inches * windowHeight    -- Height of the window in inches * screenWidth     -- Width of the full screen in inches * screenHeight    -- Height of the full screen in inches * argV, argC      -- Used to set corresponding X window fields * waitState       -- Indicates what mouse event is awaited * regionStarted   -- TRUE is a region is in progress * regionGrayScale -- Gray scale density [0,1] * polygonPoints   -- Array of points used in current region * nPolygonPoints  -- Number of active points * polygonSize     -- Number of allocated points */static bool displayIsOpen = FALSE;static bool redraw = FALSE;static bool eraseMode;static double xdpi, ydpi;static Display *disp;static Window mainWindow;static Pixmap osWindow;static Colormap colormap;static int pixelDepth;static unsigned long drawColor, eraseColor;static GC mainGC, drawGC, eraseGC;static GC grayGC[NGrays];static Pixmap grayStipple[NGrays];static string currentFont;static int currentSize;static int currentStyle;static XFontStruct *fontInfo;static double windowWidth, windowHeight;static double screenWidth, screenHeight;static string argV[] = { "xdisplay" };static int argC = sizeof argV / sizeof argV[0];static waitStateT waitState;static bool regionStarted;static double regionGrayScale;static XPoint *polygonPoints;static int nPolygonPoints;static int polygonSize;/* Private function prototypes */static void StartToOpenDisplay(void);static void InitGC(void);static void ForceRedraw(void);static void RedrawWindow(void);static void StartPolygon(void);static void AddSegment(int x0, int y0, int x1, int y1);static void DisplayPolygon(void);static void RenderArc(double x, double y, double rx, double ry,                      double start, double sweep);static int SizeFromFontName(string fontName);static double InchesX(int x);static double InchesY(int y);static int PixelsX(double x);static int PixelsY(double y);static int ScaleX(double x);static int ScaleY(double y);/* Exported entries *//* * Function: XDOpenDisplay * ----------------------- * The XDOpenDisplay function is relatively long but consists of * little more than a series of X calls to establish the * parameters of the display. */void XDOpenDisplay(string title){    XWMHints xwmh;    XSizeHints xsh;    XFontStruct *font;    Screen *screen;    XSetWindowAttributes xswa;    long width, height;    int bitmask, scnum;    double xScale, yScale, scaleFactor;    char geometry[100];    StartToOpenDisplay();    if ((font = XLoadQueryFont(disp, "fixed")) == NULL) {        Error("Can't create font");    }    scnum = DefaultScreen(disp);    screen = ScreenOfDisplay(disp, scnum);    colormap = DefaultColormap(disp, scnum);    drawColor = BlackPixel(disp, scnum);    eraseColor = WhitePixel(disp, scnum);    xScale = yScale = 1.0;    if (windowWidth > screenWidth - 2 * RequiredMargin) {        xScale = (screenWidth - 2 * RequiredMargin) / windowWidth;    }    if (windowHeight > screenHeight - 2 * RequiredMargin) {        yScale = (screenHeight - 2 * RequiredMargin) / windowHeight;    }    scaleFactor = GLMinF(xScale, yScale);    xdpi *= scaleFactor;    ydpi *= scaleFactor;    width = PixelsX(windowWidth);    height = PixelsY(windowHeight);    sprintf(geometry, "%dx%d+%d+%d", width, height,            (DisplayWidth(disp, scnum) - width) / 2,            (DisplayHeight(disp, scnum) - height) / 2);    bitmask = XGeometry(disp, scnum, geometry, geometry,                        BorderPixels,                        font->max_bounds.width,                        font->max_bounds.ascent + font->max_bounds.descent,                        1, 1, &xsh.x, &xsh.y, &xsh.width, &xsh.height);    if (bitmask & (XValue | YValue)) xsh.flags |= USPosition;    if (bitmask & (WidthValue | HeightValue)) xsh.flags |= USSize;    mainWindow = XCreateSimpleWindow(disp, DefaultRootWindow(disp),                                     xsh.x, xsh.y, xsh.width, xsh.height,                                     BorderPixels, drawColor, eraseColor);    XSetStandardProperties(disp, mainWindow, title, title,                           None, argV, argC, &xsh);    xwmh.flags = (InputHint | StateHint);    xwmh.input = False;    xwmh.initial_state = NormalState;    XSetWMHints(disp, mainWindow, &xwmh);    xswa.colormap = colormap;    xswa.bit_gravity = CenterGravity;    XChangeWindowAttributes(disp, mainWindow,                            CWColormap | CWBitGravity, &xswa);    XSelectInput(disp, mainWindow,                 ExposureMask | ButtonPressMask | ButtonReleaseMask);    XMapWindow(disp, mainWindow);    osWindow = XCreatePixmap(disp, DefaultRootWindow(disp),                             xsh.width, xsh.height, pixelDepth);    fontInfo = NULL;    InitGC();    regionStarted = FALSE;    waitState = NotWaiting;    XDClearDisplay();    XFlush(disp);}/* * Function: XDCloseDisplay * ------------------------ * This function frees the X structures allocated by the package. */void XDCloseDisplay(void){    int i;    XDestroyWindow(disp, mainWindow);    XFreePixmap(disp, osWindow);    XFreeGC(disp, mainGC);    XFreeGC(disp, drawGC);    XFreeGC(disp, eraseGC);    for (i = 0; i < NGrays; i++) {        XFreeGC(disp, grayGC[i]);        XFreePixmap(disp, grayStipple[i]);    }    XCloseDisplay(disp);}/* * Function: XDDisplayFD * --------------------- * This function simply returns the file descriptor for the X * connection.  The client cannot obtain this directly because the * display identified disp is private to this module. */int XDDisplayFD(void){    return (XConnectionNumber(disp));}/* * Function: XDProcessXEvent * ------------------------- * This function is used to read and respond to a pending X event. * It returns TRUE if an event was processed. */bool XDProcessXEvent(void){    XEvent event;    if (!XPending(disp)) return (FALSE);    XNextEvent(disp, &event);    if (event.xany.window == mainWindow) {        switch (event.type) {          case Expose:            if (event.xexpose.count == 0) RedrawWindow();            break;          case ButtonPress:            if (waitState == WaitingForMouseDown) {                waitState = NotWaiting;                XMReleaseClient();            }            break;          case ButtonRelease:            if (waitState == WaitingForMouseUp) {                waitState = NotWaiting;                XMReleaseClient();            }            break;        }    }    return (TRUE);}/* * Function: XDCheckForRedraw * -------------------------- * This function allows the client to specify that a quiescent point * has been achieved and that it would be a good time to redraw the * window.  A redraw occurs only if graphics updates have been made. */void XDCheckForRedraw(void){    if (redraw) ForceRedraw();}/* * Function: XDSetRedrawFlag * ------------------------- * This function allows the client to indicate that the display has * changed and that a redraw operation should be performed when the * next call to XDCheckForRedraw occurs.  This mechanism currently * sets a single flag and should at some point be redesigned to * maintain the update region. */void XDSetRedrawFlag(void){    redraw = TRUE;}/* * Function: XDClearDisplay * ------------------------ * This function erases the entire display by filling with the * erase color. */void XDClearDisplay(void){    int itemp;    unsigned int width, height, utemp;    Window wtemp;    if (XGetGeometry(disp, osWindow, &wtemp, &itemp, &itemp,                     &width, &height, &utemp, &utemp) == 0) return;    XFillRectangle(disp, osWindow, eraseGC, 0, 0, width, height);}/* * Function: XDDrawLine * -------------------- * This function draws the requested line unless a region is in * progress, in which case it adds the line segment to the polygon. */void XDDrawLine(double x, double y, double dx, double dy){    int x0, y0, x1, y1;    x0 = ScaleX(x);    y0 = ScaleY(y);    x1 = ScaleX(x + dx);    y1 = ScaleY(y + dy);    if (regionStarted) {        AddSegment(x0, y0, x1, y1);    } else {        XDrawLine(disp, osWindow, (eraseMode) ? eraseGC : drawGC,                  x0, y0, x1, y1);    }}/* * Function: XDDrawArc * ------------------- * This function ordinarily scales its arguments and uses them * to draw an arc using the standard XDrawArc call.  If, however, * a region has been started, that arc must be rendered using * line segments, which is handled by RenderArc. */void XDDrawArc(double x, double y, double rx, double ry,                double start, double sweep){    int ixc, iyc, irx, iry, istart, isweep;    if (regionStarted) {        RenderArc(x, y, rx, ry, start, sweep);    } else {        ixc = ScaleX(x);        iyc = ScaleY(y);        irx = PixelsX(rx);        iry = PixelsY(ry);        istart = GLRound(start);        isweep = GLRound(sweep);        if (isweep < 0) {            isweep = -isweep;            istart -= isweep;        }        if (istart < 0) {            istart = 360 - (-istart % 360);        }        istart %= 360;        XDrawArc(disp, osWindow, (eraseMode) ? eraseGC : drawGC,                 ixc - irx, iyc - iry, 2 * irx, 2 * iry,                 64 * istart, 64 * isweep);    }}/* * Function: XDDrawText * -------------------- * This function transforms the client arguments and makes the * appropriate X call to display text on the screen. */void XDDrawText(double x, double y, string text){    int ix, iy;    ix = ScaleX(x);    iy = ScaleY(y);    XDrawString(disp, osWindow, (eraseMode) ? eraseGC : drawGC,                ix, iy, text, strlen(text));}/* * Function: XDTextWidth * --------------------- * This function simply calls the XTextWidth function to compute the * width of the displayed text and scales it to the client coordinate * system. */double XDTextWidth(string text){    return (InchesX(XTextWidth(fontInfo, text, strlen(text))));}/* * Function: XDSetFont * ------------------- * This function searches the font names table for a font that matches * the argument characteristics as closely as possible.  As required * by the extgraph.h client interface, the function does not change * the font if no such font exists and selects the closest existing * size. */string XDSetFont(string font, int size, int style){    char fontbuf[MaxFontName + 30];    string fontName, *fontList;    int i, nFonts, bestIndex, bestSize, thisSize;    bool ok;    fontName = ConvertToLowerCase(font);    if (StringEqual(fontName, "default")) {        sprintf(fontbuf, "*-%s-*", DefaultFont);    } else {        sprintf(fontbuf, "*-%s-*", fontName);    }    FreeBlock(fontName);    fontList = XListFonts(disp, fontbuf, MaxFontList, &nFonts);    if (nFonts != 0) {        bestIndex = -1;        for (i = 1; i < nFonts; i++) {            fontName = fontList[i];            ok = TRUE;            if (style & Bold) {                ok &= FindString("-bold-", fontName, 0) != -1;            } else {                ok &= FindString("-medium-", fontName, 0) != -1;            }            if (style & Italic) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -