X-Git-Url: https://git.sesse.net/?p=ccbs;a=blobdiff_plain;f=bigscreen%2Ftinyptc%2Fxdga1.c;fp=bigscreen%2Ftinyptc%2Fxdga1.c;h=97801f436f96aa04cfe2bd2c17ed75d44d17e5c2;hp=0000000000000000000000000000000000000000;hb=140a0aae7299d15459fe9ec74ad5020887e0a960;hpb=fd56777b1051147ba14850b72f1f959cd82a1827 diff --git a/bigscreen/tinyptc/xdga1.c b/bigscreen/tinyptc/xdga1.c new file mode 100644 index 0000000..97801f4 --- /dev/null +++ b/bigscreen/tinyptc/xdga1.c @@ -0,0 +1,411 @@ +/* + * TinyPTC x11 v0.7.3 X Direct Graphics Access Extension v1 target + * Copyright (C) 2000-2002 Alessandro Gatti + * + * http://www.sourceforge.net/projects/tinyptc/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* #includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tinyptc.h" + +#ifdef __PTC_XDGA1__ + +#define __PTC_FROM_SOURCE + +#include "xdga1.h" + +/* Open the screen */ + +int +ptc_open (char *title, int width, int height) +{ + /* Check for the effective UID of the running process */ + if (geteuid ()) + { + return PTC_FAILURE; + } + /* Open a display on the current root window */ + ptc_display = XOpenDisplay (NULL); + if (ptc_display == NULL) + { + return PTC_FAILURE; + } + /* Get the default screen associated with the previously opened display */ + ptc_screen = DefaultScreen (ptc_display); + /* Get the default visual */ + ptc_visual = DefaultVisual (ptc_display, ptc_screen); + /* Get screen bitdepth */ + ptc_depth = DefaultDepth (ptc_display, ptc_screen); + /* Get a pointer to the supported pixmap formats */ + ptc_pixmap_formats = + XListPixmapFormats (ptc_display, &ptc_pixmap_format_count); + /* Check if there's one that's suitable */ + for (ptc_pixmap_counter = 0; ptc_pixmap_counter < ptc_pixmap_format_count; + ptc_pixmap_counter++) + { + if (ptc_depth == ptc_pixmap_formats[ptc_pixmap_counter].depth) + { + /* Set the right value */ + ptc_converter_depth = + ptc_pixmap_formats[ptc_pixmap_counter].bits_per_pixel; + } + } + XFree (ptc_pixmap_formats); +#ifdef __PTC_ENABLE_CONVERSIONS__ + /* Check if a converter is avaliable */ + ptc_convert = + ptc_request_converter (ptc_converter_depth, ptc_visual->red_mask, + ptc_visual->green_mask, ptc_visual->blue_mask); + if (!ptc_convert) + { + /* Close the display */ + XCloseDisplay (ptc_display); + return 0; + } + /* Get the actual bytes-per-pixel value */ + switch (ptc_converter_depth) + { + case 8: + ptc_output_pitch = 1; + break; + case 15: + ptc_output_pitch = 2; + break; + case 16: + ptc_output_pitch = 2; + break; + case 24: + ptc_output_pitch = 3; + break; + case 32: + ptc_output_pitch = 4; + break; + } + /* Allocate the temporary buffer */ + ptc_buffer = (char *) malloc (width * height * ptc_output_pitch); + if (ptc_buffer == NULL) + { + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } +#else + /* It runs only on a 32bpp display if no conversions were activated */ + if (ptc_converter_depth != 32) + { + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } + ptc_output_pitch = sizeof (int); +#endif /* __PTC_ENABLE_CONVERSIONS__ */ + /* Check for DGA extension avaliability */ + if (!XF86DGAQueryExtension (ptc_display, &ptc_event_base, &ptc_error_base)) + { + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } + /* Get framebuffer parameters */ + XF86DGAGetVideo (ptc_display, ptc_screen, &ptc_framebuffer_address, + &ptc_framebuffer_width, &ptc_framebuffer_banksize, + &ptc_framebuffer_memory); + /* Check if the mode is banked */ + if (ptc_framebuffer_banksize < ptc_framebuffer_memory) + { + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } + /* Check for VidMode extension avaliability */ + if (!XF86VidModeQueryExtension + (ptc_display, &ptc_event_base, &ptc_error_base)) + { + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } + /* Get all the mode parameters */ + XF86VidModeGetAllModeLines (ptc_display, ptc_screen, &ptc_totalmodes, + &ptc_modeinfodata); + /* Get current mode parameters */ + XF86VidModeGetModeLine (ptc_display, ptc_screen, &ptc_dotclock, + &ptc_currentmodeline); + /* Search for current mode in parameter list */ + for (ptc_modecounter = 0; ptc_modecounter < ptc_totalmodes; + ptc_modecounter++) + { + if ((ptc_currentmodeline.hdisplay == + ptc_modeinfodata[ptc_modecounter]->hdisplay) + && (ptc_currentmodeline.vdisplay == + ptc_modeinfodata[ptc_modecounter]->vdisplay)) + { + /* Save the parameters */ + ptc_previousmode_number = ptc_modecounter; + ptc_screen_width = ptc_currentmodeline.hdisplay; + ptc_screen_height = ptc_currentmodeline.vdisplay; + break; + } + } + ptc_emulate_fullscreen = True; + /* Search for desired mode in parameter list */ + for (ptc_modecounter = 0; ptc_modecounter < ptc_totalmodes; + ptc_modecounter++) + { + if ((ptc_modeinfodata[ptc_modecounter]->hdisplay == width) + && (ptc_modeinfodata[ptc_modecounter]->vdisplay == height)) + { + /* Try to switch mode */ + if (!XF86VidModeSwitchToMode + (ptc_display, ptc_screen, ptc_modeinfodata[ptc_modecounter])) + { + XFree (ptc_modeinfodata); + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } + ptc_emulate_fullscreen = False; + break; + } + } +#ifdef __PTC_BEST_VIDEOMODE__ + /* It works for fullscreen emulation only */ + if (ptc_emulate_fullscreen) + { + /* Set up loop */ + ptc_best_delta = INT_MAX; + ptc_best_videomode = 0; + /* Check for all avaliable modes */ + for (ptc_modecounter = 0; ptc_modecounter < ptc_totalmodes; + ptc_modecounter++) + { + if ((ptc_modeinfodata[ptc_modecounter]->hdisplay >= width) + && (ptc_modeinfodata[ptc_modecounter]->vdisplay >= height)) + { + /* If it fits, get delta parameters */ + ptc_best_x_delta = + ptc_modeinfodata[ptc_modecounter]->hdisplay - width; + ptc_best_x_delta *= ptc_best_x_delta; + ptc_best_y_delta = + ptc_modeinfodata[ptc_modecounter]->vdisplay - height; + ptc_best_y_delta *= ptc_best_y_delta; + /* Check if the mode was fitting better than the previous one */ + if (ptc_best_x_delta + ptc_best_y_delta < ptc_best_delta) + { + /* Set up next iteration */ + ptc_best_delta = ptc_best_x_delta + ptc_best_y_delta; + ptc_best_videomode = ptc_modecounter; + } + } + } + /* Try to switch mode */ + if (!XF86VidModeSwitchToMode + (ptc_display, ptc_screen, ptc_modeinfodata[ptc_best_videomode])) + { + XFree (ptc_modeinfodata); + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } + } +#endif /* __PTC_BEST_VIDEOMODE__ */ + /* Clear event queue */ + XFlush (ptc_display); + /* Get the root window */ + ptc_root_window = XRootWindow (ptc_display, ptc_screen); + /* Get exclusive keyboard access */ + XGrabKeyboard (ptc_display, ptc_root_window, False, GrabModeAsync, + GrabModeAsync, CurrentTime); + /* Get exclusive mouse access */ + XGrabPointer (ptc_display, ptc_root_window, True, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + /* Leave root mode */ + setuid (getuid ()); + /* Get viewport parameters */ + XF86DGAGetViewPortSize (ptc_display, ptc_screen, + (int *) (&ptc_screen_width), + (int *) (&ptc_screen_height)); + /* Set fullscreen emulation up */ + if (ptc_emulate_fullscreen) + { + /* Get effective framebuffer address */ +#ifdef __PTC_ENABLE_CONVERSIONS__ + ptc_framebuffer_start = + ptc_framebuffer_width * ((ptc_screen_height - height) / 2) * + ptc_output_pitch + + ((ptc_screen_width - width) / 2) * ptc_output_pitch; +#else + ptc_framebuffer_start = + ptc_framebuffer_width * ((ptc_screen_height - height) / 2) * + sizeof (int) + ((ptc_screen_width - width) / 2) * sizeof (int); +#endif /* __PTC_ENABLE_CONVERSIONS__ */ + } + else + { + /* Ignore offsets */ + ptc_framebuffer_start = 0; + } + /* Get the pitch value */ + ptc_framebuffer_pitch = ptc_framebuffer_width * ptc_output_pitch; + /* Do a safety fork */ + if (XF86DGAForkApp (ptc_screen)) + { + /* Exit DGA mode */ + XF86DGADirectVideo (ptc_display, ptc_screen, False); + /* Switch back to the previous video mode */ + XF86VidModeSwitchToMode (ptc_display, ptc_screen, + ptc_modeinfodata[ptc_previousmode_number]); + /* Free modeinfo data */ + XFree (ptc_modeinfodata); + /* Leave exclusive keyboard access */ + XUngrabKeyboard (ptc_display, CurrentTime); + /* Leave exclusive mouse access */ + XUngrabPointer (ptc_display, CurrentTime); + /* Close the display */ + XCloseDisplay (ptc_display); + return PTC_FAILURE; + } + /* Initialize DGA video access */ + XF86DGADirectVideo (ptc_display, ptc_screen, + XF86DGADirectGraphics | XF86DGADirectKeyb | + XF86DGADirectMouse); + /* Clear the screen */ + memset (ptc_framebuffer_address, 0x00, + ptc_framebuffer_width * ptc_screen_height * ptc_output_pitch); + /* Select the input events that should be reported */ + XSelectInput (ptc_display, DefaultRootWindow (ptc_display), + KeyPressMask | KeyReleaseMask); + /* Set the final viewport */ + XF86DGASetViewPort (ptc_display, ptc_screen, 0, 0); + /* Clear event queue */ + XFlush (ptc_display); + /* Save the buffer size */ + ptc_viewport_width = width; + ptc_viewport_height = height; + return PTC_SUCCESS; +} + +/* Update the screen */ + +int +ptc_update (void *buffer) +{ + char *ptc_buffer; + + ptc_buffer=(char *)buffer; + ptc_framebuffer_index = 0; +#ifdef __PTC_ENABLE_CONVERSIONS__ + ptc_source_index = 0; + ptc_destination_index = 0; +#endif /* __PTC_ENABLE_CONVERSIONS__ */ + /* Do the blit line by line */ + for (ptc_blitcounter = 0; ptc_blitcounter < ptc_viewport_height; + ptc_blitcounter++) + { +#ifdef __PTC_ENABLE_CONVERSIONS__ + /* Conversion */ + ptc_convert (ptc_buffer + ptc_source_index, + ptc_framebuffer_address + ptc_framebuffer_start + + ptc_destination_index, ptc_viewport_width); + /* Pointers update */ + ptc_source_index += ptc_viewport_width * sizeof (int); + ptc_destination_index += ptc_framebuffer_pitch; +#else + /* Copy the data */ + memcpy (ptc_framebuffer_address + ptc_framebuffer_start + + ptc_framebuffer_index, ptc_buffer, + ptc_viewport_width * sizeof (int)); + ptc_buffer += ptc_viewport_width * sizeof (int); + /* Set up offsets */ + ptc_framebuffer_index += ptc_framebuffer_pitch; +#endif /* __PTC_ENABLE_CONVERSIONS__ */ + } + /* Process incoming events */ + if (ptc_process_events ()) + { +#ifdef __PTC_CLEANUP_CALLBACK__ + ptc_cleanup_callback (); +#endif /* __PTC_CLEANUP_CALLBACK__ */ + ptc_close (); + exit (0); + } + return PTC_SUCCESS; +} + +/* Process events */ + +int +ptc_process_events (void) +{ + XEvent ptc_xevent; + KeySym ptc_keysym; + /* Check if there are events waiting in the display's queue */ + if (XPending (ptc_display)) + { + /* Get the next event in queue */ + XNextEvent (ptc_display, &ptc_xevent); + /* Check if it's a keypress event */ + if (ptc_xevent.type == KeyPress) + { + /* Get the keysym */ + ptc_keysym = XLookupKeysym (&ptc_xevent.xkey, 0); + /* Check if the key pressed was a function one */ + if ((ptc_keysym >> 8) == __PTC_FUNCTION_KEY__) + { + /* Check if it was the escape key */ + if ((ptc_keysym & 0xFF) == __PTC_ESCAPE_KEY__) + { + return PTC_SUCCESS; + } + } + } + } + return PTC_FAILURE; +} + +/* Close the screen */ + +void +ptc_close (void) +{ + /* Exit from DGA mode */ + XF86DGADirectVideo (ptc_display, ptc_screen, False); + /* Switch back to the previous video mode */ + XF86VidModeSwitchToMode (ptc_display, ptc_screen, + ptc_modeinfodata[ptc_previousmode_number]); + /* Free modeinfo data */ + XFree (ptc_modeinfodata); + /* Leave exclusive keyboard access */ + XUngrabKeyboard (ptc_display, CurrentTime); + /* Leave exclusive mouse access */ + XUngrabPointer (ptc_display, CurrentTime); + /* Close the display */ + XCloseDisplay (ptc_display); + /* Deallocate the buffer */ + if (ptc_buffer) + { + free (ptc_buffer); + } +} + +#endif /* __PTC_XDGA1__ */