Graph_set.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /* Changed for truecolor 24bit support by
  2. * Roberto Flor/ITC-Irst, Trento, Italy
  3. * August 1999
  4. *
  5. * Heavily modified by Glynn Clements, May 2001
  6. */
  7. #include <grass/config.h>
  8. /* This driver extensively updated by P. Thompson
  9. * (phils@athena.mit.edu) on 9/13/90 Driver modified to work with
  10. * Decstation X11r3 by David B. Satnik on 8/90 */
  11. #include <stdio.h>
  12. #include <signal.h>
  13. #include <stdlib.h>
  14. #include "includes.h"
  15. #include <X11/Xatom.h>
  16. #include <X11/cursorfont.h>
  17. #include <grass/gis.h>
  18. #include "icon.bit"
  19. #include <grass/winname.h>
  20. #include <grass/glocale.h>
  21. #include "XDRIVER.h"
  22. /* This program is a rewrite of the original Grah_Set from the GRASS
  23. * 3.0 version. All suncore and sunview related stuff (which was the
  24. * bulk of the original code) has been replaced by X11 library calls.
  25. * All non-suncore code has been retained. */
  26. /* declare global variables */
  27. const char *monitor_name;
  28. Display *dpy;
  29. Window grwin;
  30. Visual *use_visual;
  31. int use_bit_depth;
  32. int scrn;
  33. Screen *use_screen;
  34. GC gc;
  35. Colormap fixedcmap;
  36. Cursor cur_xh, cur_clock;
  37. u_long gemask = StructureNotifyMask;
  38. Pixmap bkupmap;
  39. int truecolor;
  40. int external_window;
  41. unsigned long *xpixels; /* lookup table for FIXED color mode */
  42. #ifdef X11R3
  43. /* compatibility functions for X11R3 */
  44. static Status
  45. XSetWMProtocols(Display * dpy, Window w, Atom * protocols, int count)
  46. {
  47. Atom wmProtocols;
  48. wmProtocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
  49. if (!wmProtocols)
  50. return 0;
  51. XChangeProperty(dpy, w, wmProtocols, XA_ATOM, 32, PropModeReplace,
  52. (unsigned char *)protocols, count);
  53. return 1;
  54. }
  55. XSizeHints *XAllocSizeHints(void)
  56. {
  57. return (XSizeHints *) G_malloc(sizeof(XSizeHints));
  58. }
  59. XWMHints *XAllocWMHints(void)
  60. {
  61. return (XWMHints *) G_malloc(sizeof(XWMHints));
  62. }
  63. XClassHint *XAllocClassHint(void)
  64. {
  65. return (XClassHint *) G_malloc(sizeof(XClassHint));
  66. }
  67. #endif
  68. static RETSIGTYPE sigint(int sig)
  69. {
  70. XD_Graph_close();
  71. exit(1);
  72. }
  73. static void find_truecolor_visual(void)
  74. {
  75. static int search_mask = VisualClassMask | VisualScreenMask;
  76. XVisualInfo search_template;
  77. XVisualInfo *mvisual_info;
  78. int num_visuals;
  79. int vis_num;
  80. int highest_bit_depth = 0;
  81. search_template.class = TrueColor;
  82. search_template.screen = scrn;
  83. mvisual_info =
  84. XGetVisualInfo(dpy, search_mask, &search_template, &num_visuals);
  85. G_message(_("found %d visuals of type TrueColor"), num_visuals);
  86. G_message(_("searching for highest bit depth"));
  87. for (vis_num = 0; vis_num < num_visuals; vis_num++) {
  88. if (mvisual_info[vis_num].depth <= highest_bit_depth)
  89. continue;
  90. use_visual = mvisual_info[vis_num].visual;
  91. use_bit_depth = mvisual_info[vis_num].depth;
  92. highest_bit_depth = use_bit_depth;
  93. }
  94. XFree(mvisual_info);
  95. if (highest_bit_depth == 0)
  96. G_warning("unable to find a TrueColor visual\n");
  97. else
  98. G_message(_("selected %d bit depth"), use_bit_depth);
  99. }
  100. static void use_window(int win_id)
  101. {
  102. XWindowAttributes xwa;
  103. external_window = 1;
  104. grwin = (Window) win_id;
  105. XSelectInput(dpy, grwin, gemask);
  106. if (!XGetWindowAttributes(dpy, grwin, &xwa))
  107. G_fatal_error("Graph_Set: cannot get window attributes\n");
  108. use_screen = xwa.screen;
  109. scrn = XScreenNumberOfScreen(xwa.screen);
  110. use_visual = xwa.visual;
  111. use_bit_depth = xwa.depth;
  112. }
  113. static void create_window(int argc, char **argv)
  114. {
  115. static const char *const classname[6] = {
  116. "StaticGray", "GrayScale",
  117. "StaticColor", "PseudoColor",
  118. "TrueColor", "DirectColor"
  119. };
  120. XSetWindowAttributes xswa; /* Set Window Attribute struct */
  121. Atom closedownAtom;
  122. #ifndef X11R3
  123. XTextProperty windowName, iconName;
  124. #endif /* X11R3 */
  125. XSizeHints *szhints;
  126. XClassHint *clshints;
  127. XWMHints *wmhints;
  128. char title[1024];
  129. char *p;
  130. external_window = 0;
  131. /* scrn is the screen number */
  132. scrn = DefaultScreen(dpy);
  133. /* use_screen is a pointer to that screen structure */
  134. use_screen = ScreenOfDisplay(dpy, scrn);
  135. use_visual = NULL;
  136. /* special flag to indicate a search for a True Color Display */
  137. p = getenv("XDRIVER_TRUECOLOR");
  138. if (p && strcmp(p, "TRUE") == 0)
  139. find_truecolor_visual();
  140. /* If we can't find a TrueColor visual then use the default visual */
  141. if (!use_visual) {
  142. use_visual = DefaultVisual(dpy, scrn);
  143. use_bit_depth = DefaultDepth(dpy, scrn);
  144. G_message(_("using default visual which is %s"),
  145. classname[use_visual->class]);
  146. }
  147. /* Deal with providing the window with an initial size.
  148. * Window is resizable */
  149. szhints = XAllocSizeHints();
  150. szhints->flags = USSize;
  151. szhints->height = screen_bottom - screen_top;
  152. szhints->width = screen_right - screen_left;
  153. /* Create the Window with the information in the XSizeHints */
  154. xswa.event_mask = gemask;
  155. xswa.backing_store = NotUseful;
  156. grwin = XCreateWindow(dpy, RootWindow(dpy, scrn),
  157. 0, 0,
  158. (unsigned)szhints->width,
  159. (unsigned)szhints->height,
  160. 0,
  161. use_bit_depth,
  162. InputOutput,
  163. use_visual, (CWEventMask | CWBackingStore), &xswa);
  164. /* properties for window manager */
  165. wmhints = XAllocWMHints();
  166. wmhints->icon_pixmap = XCreateBitmapFromData(dpy, grwin, icon_bits,
  167. icon_width, icon_height);
  168. wmhints->flags |= IconPixmapHint;
  169. clshints = XAllocClassHint();
  170. clshints->res_name = NULL;
  171. clshints->res_class = WIN_NAME;
  172. #ifndef X11R3
  173. sprintf(title, "GRASS %s - Monitor: %s - Location: %s", WIN_NAME,
  174. monitor_name, G_location());
  175. iconName.encoding = XA_STRING;
  176. iconName.format = 8;
  177. iconName.value = (u_char *) title;
  178. iconName.nitems = strlen((char *)iconName.value);
  179. windowName.encoding = iconName.encoding = XA_STRING;
  180. windowName.format = iconName.format = 8;
  181. windowName.value = (u_char *) title;
  182. windowName.nitems = strlen((char *)windowName.value);
  183. XSetWMProperties(dpy, grwin, &windowName, &iconName, argv, argc,
  184. szhints, wmhints, clshints);
  185. #endif
  186. closedownAtom = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  187. XSetWMProtocols(dpy, grwin, &closedownAtom, 1);
  188. /* Map the window to make it visible. This causes an expose event */
  189. XMapWindow(dpy, grwin);
  190. }
  191. static Cursor create_cross_cursor(void)
  192. {
  193. static int width = 16;
  194. static int height = 16;
  195. static int x0 = 7;
  196. static int y0 = 7;
  197. /* Old cursor */
  198. /*
  199. static const unsigned char pix_data[] = {
  200. 0x00, 0x00, 0xa0, 0x02, 0xa0, 0x02, 0xa0, 0x02,
  201. 0xa0, 0x02, 0xbe, 0x3e, 0x80, 0x00, 0x7e, 0x3f,
  202. 0x80, 0x00, 0xbe, 0x3e, 0xa0, 0x02, 0xa0, 0x02,
  203. 0xa0, 0x02, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00
  204. };
  205. static const unsigned char mask_data[] = {
  206. 0x00, 0x00, 0xe0, 0x03, 0xe0, 0x03, 0xe0, 0x03,
  207. 0xe0, 0x03, 0xfe, 0x3f, 0xfe, 0x3f, 0x7e, 0x3f,
  208. 0xfe, 0x3f, 0xfe, 0x3f, 0xe0, 0x03, 0xe0, 0x03,
  209. 0xe0, 0x03, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00
  210. };
  211. */
  212. static const unsigned char pix_data[] = {
  213. 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
  214. 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7c,
  215. 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00,
  216. 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00
  217. };
  218. static const unsigned char mask_data[] = {
  219. 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
  220. 0xc0, 0x01, 0x00, 0x00, 0x1f, 0x7c, 0x1f, 0x7c,
  221. 0x1f, 0x7c, 0x00, 0x00, 0xc0, 0x01, 0xc0, 0x01,
  222. 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00,
  223. };
  224. Pixmap pix, mask;
  225. XColor fg, bg;
  226. fg.pixel = BlackPixel(dpy, scrn);
  227. XQueryColor(dpy, fixedcmap, &fg);
  228. bg.pixel = WhitePixel(dpy, scrn);
  229. XQueryColor(dpy, fixedcmap, &bg);
  230. pix = XCreateBitmapFromData(dpy, grwin, pix_data, width, height);
  231. mask = XCreateBitmapFromData(dpy, grwin, mask_data, width, height);
  232. return XCreatePixmapCursor(dpy, pix, mask, &fg, &bg, x0, y0);
  233. }
  234. int XD_Graph_set(int argc, char **argv)
  235. {
  236. XWindowAttributes xwa; /* Get Window Attribute struct */
  237. const char *privcmap;
  238. char *p;
  239. int win_id;
  240. monitor_name = argv[1];
  241. /* Open the display using the $DISPLAY environment variable to
  242. * locate the X server. Return 0 if cannot open. */
  243. if (!(dpy = XOpenDisplay(NULL)))
  244. G_fatal_error("Graph_Set: can't open Display %s\n",
  245. XDisplayName(NULL));
  246. privcmap = getenv("XDRIVER_PRIVATE_CMAP");
  247. if ((p = getenv("XDRIVER_WINDOW")) && sscanf(p, "%i", &win_id) == 1)
  248. use_window(win_id);
  249. else
  250. create_window(argc, argv);
  251. /* this next bit forces the use of a private colormap */
  252. /* a must have for read only visuals */
  253. /* since we could allow any type to be selected above assume that */
  254. /* if this is not the default visual we must use a private colormap */
  255. if (use_visual != DefaultVisual(dpy, scrn) || (privcmap && privcmap[0]))
  256. fixedcmap = XCreateColormap(dpy, DefaultRootWindow(dpy),
  257. use_visual, AllocNone);
  258. else
  259. fixedcmap = DefaultColormap(dpy, scrn);
  260. fixedcmap = init_color_table(fixedcmap);
  261. G_message("ncolors: %d", NCOLORS);
  262. XSetWindowColormap(dpy, grwin, fixedcmap);
  263. /* Create the cursors to be used later */
  264. cur_xh = create_cross_cursor();
  265. cur_clock = XCreateFontCursor(dpy, XC_watch);
  266. /* Create the GC. */
  267. gc = XCreateGC(dpy, grwin, 0UL, NULL);
  268. /* Find out how big the window really is (in case window manager
  269. * overrides our request) and set the SCREEN values. */
  270. screen_left = screen_top = 0;
  271. if (!XGetWindowAttributes(dpy, grwin, &xwa))
  272. G_fatal_error("Graph_Set: cannot get window attributes\n");
  273. screen_right = xwa.width;
  274. screen_bottom = xwa.height;
  275. /* Now create a pixmap that will contain same contents as the
  276. * window. It will be used to redraw from after expose events */
  277. bkupmap = XCreatePixmap(dpy, grwin, xwa.width, xwa.height, xwa.depth);
  278. XSetWindowBackgroundPixmap(dpy, grwin, bkupmap);
  279. XSetForeground(dpy, gc, WhitePixel(dpy, scrn));
  280. XFillRectangle(dpy, bkupmap, gc, 0, 0, xwa.width, xwa.height);
  281. XSetBackground(dpy, gc, BlackPixel(dpy, scrn));
  282. XSetForeground(dpy, gc, WhitePixel(dpy, scrn));
  283. XClearWindow(dpy, grwin);
  284. /* prepare to catch signals */
  285. signal(SIGHUP, sigint);
  286. signal(SIGINT, sigint);
  287. signal(SIGQUIT, sigint);
  288. signal(SIGILL, sigint);
  289. signal(SIGTSTP, SIG_IGN);
  290. XFlush(dpy);
  291. return 0;
  292. }