PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/brlcad/branches/bottie/src/libfb/fb_generic.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
C | 442 lines | 280 code | 63 blank | 99 comment | 74 complexity | c58018e09ffeca114511cb42b090a02a MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
  1. /* F B _ G E N E R I C . C
  2. * BRL-CAD
  3. *
  4. * Copyright (c) 1986-2011 United States Government as represented by
  5. * the U.S. Army Research Laboratory.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public License
  9. * version 2.1 as published by the Free Software Foundation.
  10. *
  11. * This library is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this file; see the file named COPYING for more
  18. * information.
  19. */
  20. /** \defgroup fb Framebuffer
  21. * \ingroup libfb */
  22. /** @{ */
  23. /** @file fb_generic.c
  24. *
  25. * The main table where framebuffers are initialized and prioritized
  26. * for run-time access.
  27. *
  28. */
  29. /** @} */
  30. #include "common.h"
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include <string.h>
  34. #ifdef HAVE_STRINGS_H
  35. # include <strings.h>
  36. #endif
  37. #include "fb.h"
  38. extern int X24_close_existing(FBIO *ifp);
  39. extern int ogl_close_existing(FBIO *ifp);
  40. extern int wgl_close_existing(FBIO *ifp);
  41. #define Malloc_Bomb(_bytes_) \
  42. fb_log("\"%s\"(%d) : allocation of %d bytes failed.\n", \
  43. __FILE__, __LINE__, _bytes_)
  44. static int fb_totally_numeric(register char *s);
  45. /**
  46. * Disk interface enable flag. Used so the the remote daemon
  47. * can turn off the disk interface.
  48. */
  49. int _fb_disk_enable = 1;
  50. /**
  51. * f b _ n u l l
  52. *
  53. * Filler for FBIO function slots not used by a particular device
  54. */
  55. int fb_null(FBIO *ifp)
  56. {
  57. if (ifp) {
  58. FB_CK_FBIO(ifp);
  59. }
  60. return 0;
  61. }
  62. /**
  63. * F B _ N U L L _ S E T C U R S O R
  64. *
  65. * Used by if_*.c routines that don't have programmable cursor patterns.
  66. */
  67. int fb_null_setcursor(FBIO *ifp, const unsigned char *UNUSED(bits), int UNUSED(xbits), int UNUSED(ybits), int UNUSED(xorig), int UNUSED(yorig))
  68. {
  69. if (ifp) {
  70. FB_CK_FBIO(ifp);
  71. }
  72. return 0;
  73. }
  74. /**
  75. * First element of list is default device when no name given
  76. */
  77. static
  78. FBIO *_if_list[] = {
  79. #ifdef IF_WGL
  80. &wgl_interface,
  81. #endif
  82. #ifdef IF_OGL
  83. &ogl_interface,
  84. #endif
  85. #ifdef IF_X
  86. &X24_interface,
  87. &X_interface,
  88. #endif
  89. #ifdef IF_TK
  90. &tk_interface,
  91. #endif
  92. &debug_interface,
  93. /* never get any of the following by default */
  94. &stk_interface,
  95. &memory_interface,
  96. &null_interface,
  97. (FBIO *) 0
  98. };
  99. /**
  100. * F B _ O P E N
  101. */
  102. FBIO *
  103. fb_open(char *file, int width, int height)
  104. {
  105. register FBIO *ifp;
  106. int i;
  107. if (width < 0 || height < 0)
  108. return FBIO_NULL;
  109. ifp = (FBIO *) calloc(sizeof(FBIO), 1);
  110. if (ifp == FBIO_NULL) {
  111. Malloc_Bomb(sizeof(FBIO));
  112. return FBIO_NULL;
  113. }
  114. if (file == NULL || *file == '\0') {
  115. /* No name given, check environment variable first. */
  116. if ((file = (char *)getenv("FB_FILE")) == NULL || *file == '\0') {
  117. /* None set, use first device as default */
  118. *ifp = *(_if_list[0]); /* struct copy */
  119. file = ifp->if_name;
  120. goto found_interface;
  121. }
  122. }
  123. /*
  124. * Determine what type of hardware the device name refers to.
  125. *
  126. * "file" can in general look like: hostname:/pathname/devname#
  127. *
  128. * If we have a ':' assume the remote interface
  129. * (We don't check to see if it's us. Good for debugging.)
  130. * else strip out "/path/devname" and try to look it up in the
  131. * device array. If we don't find it assume it's a file.
  132. */
  133. i = 0;
  134. while (_if_list[i] != (FBIO *)NULL) {
  135. if (strncmp(file, _if_list[i]->if_name,
  136. strlen(_if_list[i]->if_name)) == 0) {
  137. /* found it, copy its struct in */
  138. *ifp = *(_if_list[i]);
  139. goto found_interface;
  140. }
  141. i++;
  142. }
  143. /* Not in list, check special interfaces or disk files */
  144. /* "/dev/" protection! */
  145. if (strncmp(file, "/dev/", 5) == 0) {
  146. fb_log("fb_open: no such device \"%s\".\n", file);
  147. free((void *) ifp);
  148. return FBIO_NULL;
  149. }
  150. #ifdef IF_REMOTE
  151. if (fb_totally_numeric(file) || strchr(file, ':') != NULL) {
  152. /* We have a remote file name of the form <host>:<file>
  153. * or a port number (which assumes localhost) */
  154. *ifp = remote_interface;
  155. goto found_interface;
  156. }
  157. #endif /* IF_REMOTE */
  158. /* Assume it's a disk file */
  159. if (_fb_disk_enable) {
  160. *ifp = disk_interface;
  161. } else {
  162. fb_log("fb_open: no such device \"%s\".\n", file);
  163. free((void *) ifp);
  164. return FBIO_NULL;
  165. }
  166. found_interface:
  167. /* Copy over the name it was opened by. */
  168. ifp->if_name = (char*)malloc((unsigned) strlen(file) + 1);
  169. if (ifp->if_name == (char *)NULL) {
  170. Malloc_Bomb(strlen(file) + 1);
  171. free((void *) ifp);
  172. return FBIO_NULL;
  173. }
  174. bu_strlcpy(ifp->if_name, file, strlen(file)+1);
  175. /* Mark OK by filling in magic number */
  176. ifp->if_magic = FB_MAGIC;
  177. if ((i=(*ifp->if_open)(ifp, file, width, height)) <= -1) {
  178. fb_log("fb_open: can't open device \"%s\", ret=%d.\n",
  179. file, i);
  180. ifp->if_magic = 0; /* sanity */
  181. free((void *) ifp->if_name);
  182. free((void *) ifp);
  183. return FBIO_NULL;
  184. }
  185. return ifp;
  186. }
  187. int
  188. fb_close(FBIO *ifp)
  189. {
  190. int i;
  191. FB_CK_FBIO(ifp);
  192. fb_flush(ifp);
  193. if ((i=(*ifp->if_close)(ifp)) <= -1) {
  194. fb_log("fb_close: can not close device \"%s\", ret=%d.\n",
  195. ifp->if_name, i);
  196. return -1;
  197. }
  198. if (ifp->if_pbase != PIXEL_NULL)
  199. free((void *) ifp->if_pbase);
  200. free((void *) ifp->if_name);
  201. free((void *) ifp);
  202. return 0;
  203. }
  204. int
  205. fb_close_existing(FBIO *ifp)
  206. {
  207. if (!ifp)
  208. return 0;
  209. FB_CK_FBIO(ifp);
  210. fb_flush(ifp);
  211. /* FIXME: these should be callbacks, not listed directly */
  212. #ifdef IF_X
  213. {
  214. extern FBIO X24_interface;
  215. if (strcasecmp(ifp->if_name, X24_interface.if_name) == 0) {
  216. int status = -1;
  217. if ((status = X24_close_existing(ifp)) <= -1) {
  218. fb_log("fb_close_existing: cannot close device \"%s\", ret=%d.\n", ifp->if_name, status);
  219. return BRLCAD_ERROR;
  220. }
  221. if (ifp->if_pbase != PIXEL_NULL) {
  222. free((void *)ifp->if_pbase);
  223. }
  224. free((void *)ifp->if_name);
  225. free((void *)ifp);
  226. return BRLCAD_OK;
  227. }
  228. }
  229. #endif /* IF_X */
  230. #ifdef IF_WGL
  231. {
  232. extern FBIO wgl_interface;
  233. if (strcasecmp(ifp->if_name, wgl_interface.if_name) == 0) {
  234. int status = -1;
  235. if ((status = wgl_close_existing(ifp)) <= -1) {
  236. fb_log("fb_close_existing: cannot close device \"%s\", ret=%d.\n", ifp->if_name, status);
  237. return BRLCAD_ERROR;
  238. }
  239. if (ifp->if_pbase != PIXEL_NULL)
  240. free((void *)ifp->if_pbase);
  241. free((void *)ifp->if_name);
  242. free((void *)ifp);
  243. return BRLCAD_OK;
  244. }
  245. }
  246. #endif /* IF_WGL */
  247. #ifdef IF_OGL
  248. {
  249. extern FBIO ogl_interface;
  250. if (strcasecmp(ifp->if_name, ogl_interface.if_name) == 0) {
  251. int status = -1;
  252. if ((status = ogl_close_existing(ifp)) <= -1) {
  253. fb_log("fb_close_existing: cannot close device \"%s\", ret=%d.\n", ifp->if_name, status);
  254. return BRLCAD_ERROR;
  255. }
  256. if (ifp->if_pbase != PIXEL_NULL)
  257. free((void *)ifp->if_pbase);
  258. free((void *)ifp->if_name);
  259. free((void *)ifp);
  260. return BRLCAD_OK;
  261. }
  262. }
  263. #endif /* IF_OGL */
  264. #ifdef IF_RTGL
  265. {
  266. extern FBIO ogl_interface;
  267. if (strcasecmp(ifp->if_name, ogl_interface.if_name) == 0) {
  268. int status = -1;
  269. if ((status = ogl_close_existing(ifp)) <= -1) {
  270. fb_log("fb_close_existing: cannot close device \"%s\", ret=%d.\n", ifp->if_name, status);
  271. return BRLCAD_ERROR;
  272. }
  273. if (ifp->if_pbase != PIXEL_NULL)
  274. free((void *)ifp->if_pbase);
  275. free((void *)ifp->if_name);
  276. free((void *)ifp);
  277. return BRLCAD_OK;
  278. }
  279. }
  280. #endif /* IF_RTGL */
  281. #ifdef IF_TK
  282. {
  283. extern FBIO tk_interface;
  284. if (strcasecmp(ifp->if_name, tk_interface.if_name) == 0) {
  285. /* may need to close_existing here at some point */
  286. if (ifp->if_pbase != PIXEL_NULL)
  287. free((void *)ifp->if_pbase);
  288. free((void *)ifp->if_name);
  289. free((void *)ifp);
  290. return BRLCAD_OK;
  291. }
  292. }
  293. #endif /* IF_TK */
  294. fb_log("fb_close_existing: cannot close device\nifp: %s\n", ifp->if_name);
  295. return BRLCAD_ERROR;
  296. }
  297. /**
  298. * Generic Help.
  299. * Print out the list of available frame buffers.
  300. */
  301. int
  302. fb_genhelp(void)
  303. {
  304. int i;
  305. i = 0;
  306. while (_if_list[i] != (FBIO *)NULL) {
  307. fb_log("%-12s %s\n",
  308. _if_list[i]->if_name,
  309. _if_list[i]->if_type);
  310. i++;
  311. }
  312. /* Print the ones not in the device list */
  313. #ifdef IF_REMOTE
  314. fb_log("%-12s %s\n",
  315. remote_interface.if_name,
  316. remote_interface.if_type);
  317. #endif
  318. if (_fb_disk_enable) {
  319. fb_log("%-12s %s\n",
  320. disk_interface.if_name,
  321. disk_interface.if_type);
  322. }
  323. return 0;
  324. }
  325. /**
  326. * True if the non-null string s is all digits
  327. */
  328. static int
  329. fb_totally_numeric(register char *s)
  330. {
  331. if (s == (char *)0 || *s == 0)
  332. return 0;
  333. while (*s) {
  334. if (*s < '0' || *s > '9')
  335. return 0;
  336. s++;
  337. }
  338. return 1;
  339. }
  340. /**
  341. * F B _ I S _ L I N E A R _ C M A P
  342. *
  343. * Check for a color map being linear in the upper 8 bits of R, G, and
  344. * B. Returns 1 for linear map, 0 for non-linear map (ie,
  345. * non-identity map).
  346. */
  347. int
  348. fb_is_linear_cmap(register const ColorMap *cmap)
  349. {
  350. register int i;
  351. for (i=0; i<256; i++) {
  352. if (cmap->cm_red[i]>>8 != i) return 0;
  353. if (cmap->cm_green[i]>>8 != i) return 0;
  354. if (cmap->cm_blue[i]>>8 != i) return 0;
  355. }
  356. return 1;
  357. }
  358. /**
  359. * F B _ M A K E _ L I N E A R _ C M A P
  360. */
  361. void
  362. fb_make_linear_cmap(register ColorMap *cmap)
  363. {
  364. register int i;
  365. for (i=0; i<256; i++) {
  366. cmap->cm_red[i] = i<<8;
  367. cmap->cm_green[i] = i<<8;
  368. cmap->cm_blue[i] = i<<8;
  369. }
  370. }
  371. /*
  372. * Local Variables:
  373. * mode: C
  374. * tab-width: 8
  375. * indent-tabs-mode: t
  376. * c-file-style: "stroustrup"
  377. * End:
  378. * ex: shiftwidth=4 tabstop=8
  379. */