/* * savetextfont.c * * Saves and restores the currently loaded font, with auxilliary information * if available, on Linux. * * hpa - 19950930 * * This file is in the public domain. * */ #ifdef __linux__ #include #include #include #include #ifndef PIO_FONTX /* * If we're compiling with old Linux include files, add the following * definitions -- from Linux 1.3.29 */ #define GIO_FONTX 0x4B6B /* get font using struct consolefontdesc */ #define PIO_FONTX 0x4B6C /* set font using struct consolefontdesc */ struct consolefontdesc { unsigned short charcount; /* characters in font (256 or 512) */ unsigned short charheight; /* scan lines per character (1-32) */ char *chardata; /* font data in expanded form */ }; #endif static struct consolefontdesc font_info; static char *font_data = NULL; static int fontx; /* Did we use GIO_FONTX? */ static struct unimapdesc unimap = { 0, NULL }; /* * save_textfont: * * Save the current text font and information; should be called prior * to entering graphics mode. fd should contain a file descriptor pointing * to the console. Return 0 on success, 1 on failure. * */ int save_textfont(int fd) { if ( font_data ) free(font_data); if ( unimap.entries ) free(unimap.entries); font_info.charcount = 0; font_info.chardata = NULL; if ( ioctl(fd, GIO_FONTX, &font_info) == 0 ) { /* If errno is ENOMEM we can use the font_info data to allocate the necessary size array */ fontx = 1; font_info.chardata = font_data = malloc(32*font_info.charcount); if ( !font_data ) return 1; if ( ioctl(fd, GIO_FONTX, &font_info) < 0 ) return 1; } else { /* GIO_FONTX is apparently not available (pre-1.3.1 kernel). Use older GIO_FONT ioctl() */ fontx = 0; font_data = malloc(32*256); if ( !font_data ) return 1; if ( ioctl(fd, GIO_FONT, font_data) < 0 ) return 1; } /* Save Unicode map, if available. */ unimap.entry_ct = 0; unimap.entries = NULL; if ( ioctl(fd, GIO_UNIMAP, &unimap) && errno == ENOMEM ) { unimap.entries = malloc(unimap.entry_ct*sizeof(struct unipair)); if ( !unimap.entries ) { unimap.entry_ct = 0; return -1; } if ( ioctl(fd, GIO_UNIMAP, &unimap) < 0 ) return -1; } return 0; } /* * restore_textfont: * * Restore the console text font. Should be called after return from * graphics mode. Same args/return as save_textfont. * */ int restore_textfont(int fd) { struct unimapinit ui; if ( !font_data ) return 1; if ( fontx ) { if ( ioctl(fd, PIO_FONTX, &font_info) < 0 ) return 1; } else { if ( ioctl(fd, PIO_FONT, font_data) < 0 ) return 1; } if ( unimap.entry_ct ) { ui.advised_hashsize = 0; ui.advised_hashstep = 0; ui.advised_hashlevel = 0; if ( ioctl(fd, PIO_UNIMAPCLR, &ui) < 0 ) return -1; if ( ioctl(fd, PIO_UNIMAP, &unimap) < 0 ) return -1; } return 0; } #else /* These are meaningless on non-Linux OS's */ int save_textfont(int fd) { return 0; } int restore_textfont(int fd) { return 0; } #endif