gdevsco.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  4. distributor accepts any responsibility for the consequences of using it, or
  5. for whether it serves any particular purpose or works at all, unless he or
  6. she says so in writing. Refer to the Aladdin Free Public License (the
  7. "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. in a plain ASCII text file named PUBLIC. The License grants you the right
  10. to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. conditions described in the License. Among other things, the License
  12. requires that the copyright notice and this notice be preserved on all
  13. copies.
  14. */
  15. /*$Id: gdevsco.c,v 1.3 2000/09/19 19:00:22 lpd Exp $ */
  16. /* 17Jul91 - wb - based on gdevpcfb.c */
  17. /* 31Jul91 - Rick Calder rick@rick.att.com - ifdefs for AT&T UNIX 4.0 2.1 */
  18. /* 13Sep91 - wb - modify for gs24b2 */
  19. /* 9Mar92 - wb - modify for gs24b4 */
  20. /* generate SCO Xenix/Unix style memory mapped ioctl output */
  21. #include "memory_.h"
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gxdevice.h"
  25. #include "gdevpcfb.h"
  26. #include <signal.h>
  27. #ifdef M_XENIX
  28. #include <sys/console.h> /* SCO Xenix and SCO UNIX */
  29. #ifndef CONSIO
  30. #include <sys/machdep.h> /* Xenix needs this also */
  31. #endif
  32. #else
  33. #include <sys/kd.h> /* AT&T SVR4 */
  34. #endif
  35. #if defined(__STDC__)
  36. #include <stdlib.h>
  37. #else
  38. extern char *getenv(P1(const char *));
  39. #endif
  40. #if defined(M_XENIX)
  41. #include <prototypes.h>
  42. #include <fcntl.h>
  43. #else
  44. extern int ioctl(P3(int, int,...));
  45. extern int open(P3(const char *, int,...));
  46. #endif
  47. private int console_fd = -1; /* file descriptor of console */
  48. fb_ptr fb_addr; /* address of frame buffer for unix */
  49. private int cur_mode = -1; /* current video mode */
  50. /* open the console */
  51. /* possible files to open:
  52. * /dev/console = current system console
  53. * /dev/vga = vga monitor
  54. * /dev/tty = current terminal
  55. */
  56. private void open_console(P1(void));
  57. private void
  58. open_console()
  59. {
  60. const char *dev;
  61. if (console_fd != -1)
  62. return;
  63. dev = getenv("GSDEVICE");
  64. if (dev == NULL || *dev == '\0')
  65. dev = "/dev/tty";
  66. console_fd = open(dev, 0);
  67. if (console_fd == -1) {
  68. ega_close((gx_device *) NULL);
  69. eprintf1("unable to map display '%s'\n", dev);
  70. perror("open_console");
  71. exit(1);
  72. }
  73. }
  74. #if defined(__GNUC__)
  75. /* Done with inline assembly in gdevpcfb.h */
  76. #else
  77. /* Output to a port */
  78. void
  79. outportb(uint port, byte data)
  80. {
  81. int i;
  82. struct port_io_arg pio;
  83. if (console_fd == -1)
  84. open_console();
  85. pio.args[0].dir = OUT_ON_PORT;
  86. pio.args[0].port = port;
  87. pio.args[0].data = data;
  88. pio.args[1].port = 0;
  89. pio.args[2].port = 0;
  90. pio.args[3].port = 0;
  91. i = ioctl(console_fd, CONSIO, (long)(&pio));
  92. if (i == -1) {
  93. ega_close((gx_device *) NULL);
  94. eprintf("error setting device register\n");
  95. perror("outportb");
  96. exit(1);
  97. }
  98. }
  99. /* Output to 2 consecutive ports */
  100. void
  101. outport2(uint port, byte index, byte data)
  102. {
  103. int i;
  104. struct port_io_arg pio;
  105. if (console_fd == -1)
  106. open_console();
  107. pio.args[0].dir = OUT_ON_PORT;
  108. pio.args[0].port = port;
  109. pio.args[0].data = index;
  110. pio.args[1].dir = OUT_ON_PORT;
  111. pio.args[1].port = port + 1;
  112. pio.args[1].data = data;
  113. pio.args[2].port = 0;
  114. pio.args[3].port = 0;
  115. i = ioctl(console_fd, CONSIO, (long)(&pio));
  116. if (i == -1) {
  117. ega_close((gx_device *) NULL);
  118. eprintf("error setting device register\n");
  119. perror("outport2");
  120. exit(1);
  121. }
  122. }
  123. #endif
  124. /* interrupt signal handler */
  125. /* restore the video mode and exit */
  126. private void
  127. ega_int_handler(int sig)
  128. {
  129. ega_close((gx_device *) NULL);
  130. eprintf("GS exiting...\n");
  131. exit(1);
  132. }
  133. /*
  134. * FIXME to make this work, the SIGCONT handler must restore the
  135. * the video state, including all the registers.
  136. * For now, I made the SIGSTOP handler exit just call the SIGINT handler
  137. */
  138. #ifdef SIGTSTP
  139. /* user tried to stop us. restore video and stop */
  140. private void
  141. ega_tstp_handler(int sig)
  142. {
  143. #if 1
  144. ega_int_handler(sig);
  145. #else
  146. /* Preferable, but sco does not restore the monitor corretly */
  147. signal(SIGTSTP, ega_tstp_handler);
  148. ega_close((gx_device *) NULL);
  149. eprintf("GS stopping...\n");
  150. signal(SIGSTOP, SIG_DFL);
  151. kill(getpid(), SIGSTOP);
  152. #endif
  153. }
  154. #endif /* SIGTSTP */
  155. #ifdef SIGCONT
  156. /* we were unstopped. reopen video */
  157. private void
  158. ega_cont_handler(int sig)
  159. {
  160. #if 1
  161. ega_int_handler(sig);
  162. #else
  163. signal(SIGCONT, ega_cont_handler);
  164. ega_set_mode(cur_mode);
  165. #endif
  166. }
  167. #endif /* SIGCONT */
  168. /* ------ Internal routines ------ */
  169. /* Catch signals so we can restore the video mode on exit. */
  170. void
  171. pcfb_set_signals(gx_device * dev)
  172. {
  173. signal(SIGINT, ega_int_handler);
  174. signal(SIGTERM, ega_int_handler);
  175. #ifdef SIGTSTP
  176. signal(SIGTSTP, ega_tstp_handler);
  177. #endif
  178. #ifdef SIGCONT
  179. signal(SIGCONT, ega_cont_handler);
  180. #endif
  181. }
  182. /* Read the device mode */
  183. void
  184. pcfb_get_state(pcfb_bios_state * pbs)
  185. {
  186. int mode;
  187. open_console();
  188. mode = ioctl(console_fd, CONS_CURRENT, 0L);
  189. if (mode == -1) {
  190. #ifdef __linux__
  191. mode = M_ENH_C80x25;
  192. #else
  193. ega_close((gx_device *) NULL);
  194. eprintf("unable to get current console mode\n");
  195. perror("pcfb_get_state");
  196. exit(1);
  197. #endif
  198. }
  199. pbs->display_mode =
  200. (mode == M_ENH_CG640 || mode == M_CG640x350 ? 0x10 :
  201. #ifdef M_VGA12
  202. mode == M_VGA12 ? 0x12 :
  203. #endif
  204. 0x03);
  205. }
  206. /* Set the device mode */
  207. void
  208. pcfb_set_mode(int mode)
  209. {
  210. int i, mode1;
  211. open_console();
  212. cur_mode = mode;
  213. mode1 = -1;
  214. if (mode == 0x10)
  215. mode = SW_ENH_CG640;
  216. #ifdef SW_VGA12
  217. else if (mode == 0x12)
  218. mode = SW_VGA12;
  219. #endif
  220. else if (mode == 0x03) {
  221. #ifdef SW_VGA80x25
  222. mode = SW_VGA80x25;
  223. mode1 = SW_ENHC80x25;
  224. #else
  225. mode = SW_ENHC80x25;
  226. #endif
  227. } else {
  228. eprintf1("can not set to video mode %d\n", mode);
  229. exit(1);
  230. }
  231. i = ioctl(console_fd, mode, 0L);
  232. if (i == -1 && mode1 != -1)
  233. i = ioctl(console_fd, mode1, 0L);
  234. if (i == -1) {
  235. ega_close((gx_device *) NULL);
  236. eprintf("unable to set console mode\n");
  237. perror("pcfb_set_mode");
  238. exit(1);
  239. }
  240. #ifdef VGA_IOPRIVL
  241. if (ioctl(console_fd, VGA_IOPRIVL, 1) == -1) {
  242. ega_close((gx_device *) NULL);
  243. eprintf("unable to get I/O privilege\n");
  244. perror("pcfb_set_mode");
  245. exit(1);
  246. }
  247. #endif
  248. i = ioctl(console_fd, MAPCONS, 0L);
  249. if (i == -1) {
  250. ega_close((gx_device *) NULL);
  251. eprintf("unable to map console adaptor's display memory\n");
  252. perror("pcfb_set_mode");
  253. exit(1);
  254. }
  255. fb_addr = (fb_ptr) (i);
  256. }
  257. /* Restore the device state */
  258. void
  259. pcfb_set_state(const pcfb_bios_state * pbs)
  260. {
  261. pcfb_set_mode(pbs->display_mode);
  262. }