/* Copyright 1997 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /***************************************************/ /* File : FromROSLib.c */ /* */ /* Purpose: The original Customer browser sources */ /* used RISC_OSLib heavily and some of */ /* the functions used are handy to have */ /* around. This source file contains */ /* a variety of functions from RISC_OSLib */ /* with modifications where necessary */ /* both to fit into the browser more */ /* naturally, and to function better */ /* under C release 5. */ /* */ /* Authors: Various for original RISC_OSLib source */ /* This source adapted by A.D.Hodgkinson */ /* */ /* History: 06-Dec-96: Created. */ /***************************************************/ #include <stdlib.h> #include <stdarg.h> #include "swis.h" #include "wimp.h" #include "FromROSLib.h" /* Statics */ /* Array of length of sequence for vdu codes, */ /* used by the VDU call-based functions. */ static char Qlen[32] = { 1, /* VDU 0 */ 2, /* Next character to printer only */ 1, /* Printer on */ 1, /* Printer off */ 1, /* Print at text cursor */ 1, /* Print at graphics cursor */ 1, /* Enable VDU driver */ 1, /* Beep */ 1, /* Backspace */ 1, /* Forward space (horizontal tab) */ 1, /* Line feed */ 1, /* Up a line */ 1, /* Clear (text) screen */ 1, /* Carriage return */ 1, /* Page mode on */ 1, /* Page mode off */ 1, /* Clear graphics window */ 2, /* Define text colour */ 3, /* Define graphics colour */ 6, /* Define logical colour */ 1, /* Restore default palette */ 1, /* Disable VDU drivers */ 2, /* Select screen mode */ 10, /* VDU 23,.. */ 9, /* Set graphics window */ 6, /* PLOT ... */ 1, /* Restore default windows */ 1, /* ESCAPE char - no effect */ 5, /* Define text window */ 5, /* Define graphics origin */ 1, /* Home cursor */ 3 /* Tab cursor */ }; /* ...and all the rest are 1. */ /* Cached eigen values */ static int wimpt_xeig = 2; static int wimpt_yeig = 2; /*************************************************/ /* bbc_modevar() */ /* */ /* Returns the value of a mode variable, or -1 */ /* if there was some error. */ /* */ /* Parameters: A mode number or -1 for current; */ /* */ /* A mode variable (for the SWI call */ /* OS_ReadModeVariable). */ /* */ /* Returns: The value of the variable, or -1 */ /* if an error occurs. */ /*************************************************/ int bbc_modevar(int mode, int varno) { int result; if (_swix(OS_ReadModeVariable, _INR(0,1) | _OUT (2), mode, varno, &result)) return -1; return result; } /*************************************************/ /* bbc_vduvar() */ /* */ /* Returns the value of a VDU variable, or -1 to */ /* flag an error - therefore, if the variable */ /* may hold -1 as a valid value, you need to use */ /* bbc_vduvars() instead. */ /* */ /* Parameters: A VDU variable number for the */ /* SWI call OS_ReadVduVariables. */ /* */ /* Returns: The value of the variable, or -1 */ /* if an error occurs. */ /*************************************************/ int bbc_vduvar(int varno) { int vars[2]; int result; vars[0] = varno; vars[1] = -1; /* terminator */ return _swix(OS_ReadVduVariables, _INR(0,1), vars, &result) != NULL ? -1 : result; /* relies on -1 never being valid */ } /*************************************************/ /* bbc_vduvars() */ /* */ /* Returns values of any number of VDU variables */ /* */ /* Parameters: A pointer to a block holding a */ /* list of variable numbers, */ /* termianted by -1; */ /* */ /* A pointer to a block into which */ /* the corresponding variable values */ /* will be placed. This may be the */ /* same block as the one holding the */ /* variable numbers. */ /* */ /* Returns: The block holding the variable */ /* numbers is updated with the */ /* variable values, assuming the */ /* call doesn't return an error. */ /*************************************************/ _kernel_oserror * bbc_vduvars(int * vars, int * values) { return _swix(OS_ReadVduVariables, _INR(0,1), (int) vars, (int) values); } /*************************************************/ /* bbc_vduq() */ /* */ /* Output multiple characters. Runs through an */ /* assembler routine bbc_vdu for speed. */ /* */ /* Parameters: A control character - the number */ /* of further characters to expect */ /* is defined in the static 'Qlen', */ /* defined at the top of this file, */ /* and depends on the char given. */ /*************************************************/ _kernel_oserror * bbc_vduq(int c,...) { _kernel_oserror * e; va_list ap; int n; e = bbc_vdu(c); /* See FromROSLib.s */ if ((c >= ' ') || e) return(e); va_start(ap, c); n = Qlen[c]; while ((--n) && (!e)) e = bbc_vdu(va_arg(ap,int)); va_end(ap); return(e); } /*************************************************/ /* bbc_clg() */ /* */ /* Clears the current graphics window. */ /*************************************************/ _kernel_oserror * bbc_clg(void) { return (bbc_vdu(BBC_ClearGraph)); } /*************************************************/ /* bbc_gwindow() */ /* */ /* Defines a graphics window. */ /* */ /* Parameters: X coordinate of bottom left hand */ /* corner of graphics window in OS */ /* units, inclusive; */ /* */ /* Y coordinate for the same; */ /* */ /* X coordinate of top right hand */ /* corner of graphics window in OS */ /* units, exclusive; */ /* */ /* Y coordinate for the same. */ /*************************************************/ _kernel_oserror * bbc_gwindow(int xmin, int ymin, int xmax, int ymax) { _kernel_oserror * e = bbc_vdu(BBC_DefGraphWindow); if (!e) e = bbc_vduw(xmin); if (!e) e = bbc_vduw(ymin); if (!e) e = bbc_vduw(xmax); if (!e) e = bbc_vduw(ymax); return e; } /*************************************************/ /* bbc_origin() */ /* */ /* Sets the graphics plotting origin. */ /* */ /* Parameters: X coordinate of origin, in OS */ /* units; */ /* */ /* Y coordinate for the same. */ /*************************************************/ _kernel_oserror * bbc_origin(int x, int y) { _kernel_oserror * e = bbc_vdu(BBC_DefGraphOrigin); if (!e) e = bbc_vduw(x); if (!e) e = bbc_vduw(y); return e; } /*************************************************/ /* bbc_gcol() */ /* */ /* Sets a graphics colour and plotting action. */ /* */ /* Graphics plotting actions: */ /* */ /* P is pixel on screen. */ /* N is new colour. */ /* */ /* Action Behaviour */ /* */ /* 0 P = N */ /* 1 P |= N (OR) */ /* 2 P &= N (AND) */ /* 3 P = P ^ N (XOR) */ /* 4 P = !P (NOT) */ /* 5 P = P (no change to screen colour) */ /* 6 P &= (!N) (AND NOT) */ /* 7 P |= (!N) (OR NOT) */ /* 8 -15 As 0-7 but background is transparent */ /* 16-31 Pattern 1, with action 0 - 15 */ /* 32-47 Pattern 2, with action 0 - 15 */ /* 48-63 Pattern 3, with action 0 - 15 */ /* 64-79 Pattern 4, with action 0 - 15 */ /* 80-95 Large pattern, with action 0 - 15 */ /* */ /* Parameters: Plotting action (see above); */ /* */ /* Graphics colour (0-127 for the */ /* foreground, else background is */ /* set to colour - 128). The colour */ /* used is ANDed with the maximum */ /* number of colours for the screen */ /* mode (1,3, 15 or 63 for 2, 4, 16 */ /* or >=256 colour modes). */ /*************************************************/ _kernel_oserror * bbc_gcol(int a, int b) { _kernel_oserror * e = bbc_vdu(BBC_DefGraphColour); if (!e) e = bbc_vdu(a); if (!e) e = bbc_vdu(b); return e; } /*************************************************/ /* bbc_plot() */ /* */ /* Plot something on the screen with OS_Plot. */ /* See PRM volume 1 page 607 for full details. */ /* */ /* Parameters: Plot number; */ /* */ /* X coordinate; */ /* */ /* Y coordinate. */ /*************************************************/ _kernel_oserror * bbc_plot(int n, int x, int y) { return _swix(OS_Plot, _INR(0,2), n, x, y); } /*************************************************/ /* bbc_move() */ /* */ /* Move the graphics cursor to absolute coords. */ /* */ /* Parameters: X coordinate to move to, in OS */ /* units; */ /* */ /* Y coordinate for the same. */ /*************************************************/ _kernel_oserror * bbc_move(int x, int y) { return bbc_plot(BBC_MoveCursorAbs, x, y); } /*************************************************/ /* bbc_moveby() */ /* */ /* Move the graphics cursor to absolute coords. */ /* */ /* Parameters: X offset to move by, in OS units; */ /* */ /* Y coordinate for the same. */ /*************************************************/ _kernel_oserror * bbc_moveby(int x, int y) { return bbc_plot(BBC_MoveCursorRel, x, y); } /*************************************************/ /* bbc_draw() */ /* */ /* Draws a solid line including both end points */ /* to absolute coordinates, starting the line at */ /* the current graphics cursor position. */ /* */ /* Parameters: X coordinate to draw to, in OS */ /* units; */ /* */ /* Y coordinate for the same. */ /*************************************************/ _kernel_oserror * bbc_draw(int x, int y) { return bbc_plot(BBC_SolidBoth + BBC_DrawAbsFore, x, y); } /*************************************************/ /* bbc_drawby() */ /* */ /* Draws a solid line including both end points */ /* to relative coordinates, starting the line at */ /* the current graphics cursor position. */ /* */ /* Parameters: X offset to draw by, in OS units; */ /* */ /* Y coordinate for the same. */ /*************************************************/ _kernel_oserror * bbc_drawby(int x, int y) { return bbc_plot(BBC_SolidBoth + BBC_DrawRelFore, x, y); } /*************************************************/ /* bbc_rectangle() */ /* */ /* Plots a rectangle outline. */ /* */ /* Parameters: X coordinate of bottom left hand */ /* corner, in OS units; */ /* */ /* Y coordinate for the same; */ /* */ /* Rectangle width plus one, in OS */ /* units - this is added to the X */ /* value to produce an *exclusive* */ /* top right hand corner coordinate, */ /* hence for an 8 OS unit wide */ /* rectangle, say, you'd pass in 7; */ /* */ /* Similarly, the rectangle height. */ /*************************************************/ _kernel_oserror * bbc_rectangle(int x, int y, int w, int h) { _kernel_oserror * e = bbc_move(x,y); if (!e) e = bbc_plot(BBC_SolidExFinal + BBC_DrawRelFore, 0, h); if (!e) e = bbc_plot(BBC_SolidExFinal + BBC_DrawRelFore, w, 0); if (!e) e = bbc_plot(BBC_SolidExFinal + BBC_DrawRelFore, 0, -h); if (!e) e = bbc_plot(BBC_SolidExFinal + BBC_DrawRelFore, -w, 0); return e; } /*************************************************/ /* bbc_rectanglefill() */ /* */ /* Plots a filled rectangle. */ /* */ /* Parameters: As bbc_rectangle. */ /*************************************************/ _kernel_oserror * bbc_rectanglefill(int x, int y, int w, int h) { _kernel_oserror * e = bbc_move(x,y); if (!e) e = bbc_plot(BBC_RectangleFill + BBC_DrawRelFore, w, h); return e; } /*************************************************/ /* bbc_circle() */ /* */ /* Plots a circle outline. */ /* */ /* Parameters: X coordinate of midpoint, in OS */ /* units; */ /* */ /* Y coordinate for the same; */ /* */ /* Radius, in OS units. */ /*************************************************/ _kernel_oserror * bbc_circle(int x, int y, int r) { _kernel_oserror * e = bbc_move(x,y); if (!e) e = bbc_plot(BBC_Circle + BBC_DrawAbsFore, x + r, y); return e; } /*************************************************/ /* bbc_circlefill() */ /* */ /* Plots a filled circle. */ /* */ /* Parameters: As bbc_circle. */ /*************************************************/ _kernel_oserror * bbc_circlefill(int x, int y, int r) { _kernel_oserror * e = bbc_move(x,y); if (!e) e = bbc_plot(BBC_CircleFill + BBC_DrawAbsFore, x + r, y); return e; } /*************************************************/ /* bbc_trianglefill() */ /* */ /* Plots a filled triangle. */ /* */ /* Parameters: X coordinate of one corner, in */ /* OS units; */ /* */ /* Y coordinate of one corner, in */ /* OS units; */ /* */ /* X coordinate of another corner, */ /* in OS units; */ /* */ /* Y coordinate of another corner, */ /* in OS units; */ /* */ /* X coordinate of the last corner, */ /* in OS units; */ /* */ /* Y coordinate of the last corner, */ /* in OS units. */ /*************************************************/ _kernel_oserror * bbc_trianglefill(int x1, int y1, int x2, int y2, int x3, int y3) { _kernel_oserror * e = bbc_move(x1, y1); if (!e) e = bbc_move(x2, y2); if (!e) e = bbc_plot(BBC_TriangleFill + BBC_DrawAbsFore, x3, y3); return e; } /*************************************************/ /* bbc_fill() */ /* */ /* Flood-fill an area from absolute */ /* */ /* Parameters: X coordinate to start fill at, in */ /* OS units; */ /* */ /* Y coordinate for the same. */ /*************************************************/ _kernel_oserror * bbc_fill(int x, int y) { return bbc_plot(BBC_FloodToBack + BBC_DrawAbsFore, x, y); } /*************************************************/ /* wimpt_read() */ /* */ /* Finds out the current X and Y eigen values */ /* (desktop scaling). Screen resolution in dots */ /* per inch is thus 180 / eigen value. */ /* */ /* This function is typically called on receipt */ /* of a ModeChange message. */ /*************************************************/ void wimpt_read(void) { wimpt_xeig = 1 << bbc_vduvar(BBC_XEigFactor); wimpt_yeig = 1 << bbc_vduvar(BBC_YEigFactor); } /*************************************************/ /* wimpt_dx() */ /* */ /* Returns the current X eigen value (Desktop */ /* scaling). Screen X resolution in dots per */ /* inch is thus 180/XEig. */ /*************************************************/ int wimpt_dx(void) { return wimpt_xeig; } /*************************************************/ /* wimpt_dy() */ /* */ /* Returns the current Y eigen value (Desktop */ /* scaling). Screen Y resolution in dots per */ /* inch is thus 180/YEig. */ /*************************************************/ int wimpt_dy(void) { return wimpt_yeig; } /*************************************************/ /* coords_x_toscreen() */ /* */ /* Converts a work area X coordinate (0,0 is at */ /* the top left of the window) to a screen */ /* coordinate (0,0 is at the bottom left of the */ /* screen). */ /* */ /* Parameters: The work area X coordinate; */ /* */ /* Pointer to WimpRedrawWindowBlock */ /* holding details about the window */ /* that the X coordinate lies in. */ /* */ /* Returns: The given value converted to a */ /* screen coordinate. */ /*************************************************/ int coords_x_toscreen(int x, WimpRedrawWindowBlock * r) { return (x - r->xscroll + r->visible_area.xmin); } /*************************************************/ /* coords_y_toscreen() */ /* */ /* Converts a work area Y coordinate to a screen */ /* coordinate. */ /* */ /* Parameters: The work area Y coordinate; */ /* */ /* Pointer to WimpRedrawWindowBlock */ /* holding details about the window */ /* that the Y coordinate lies in. */ /* */ /* Returns: The given value converted to a */ /* screen coordinate. */ /*************************************************/ int coords_y_toscreen(int y, WimpRedrawWindowBlock * r) { return (y - r->yscroll + r->visible_area.ymax); } /*************************************************/ /* coords_box_toscreen() */ /* */ /* Converts the contents of a BBox representing */ /* a rectangle in the work area of a window to */ /* screen coordinates. */ /* */ /* Parameters: Pointer to the BBox; */ /* */ /* Pointer to WimpRedrawWindowBlock */ /* holding details about the window */ /* that the BBox retangle lies in. */ /* */ /* Returns: The contents of the BBox are */ /* updated to hold screen */ /* coordinates. */ /*************************************************/ void coords_box_toscreen(BBox * b, WimpRedrawWindowBlock * r) { b->xmax = coords_x_toscreen(b->xmax, r); b->xmin = coords_x_toscreen(b->xmin, r); b->ymin = coords_y_toscreen(b->ymin, r); b->ymax = coords_y_toscreen(b->ymax, r); } /*************************************************/ /* coords_x_toworkarea() */ /* */ /* Converts a screen X coordinate (0,0 is at the */ /* bottom left of the screen) to a work area */ /* coordinate (0,0 is at the top left of the */ /* window). */ /* */ /* Parameters: The screen X coordiante; */ /* */ /* Pointer to WimpRedrawWindowBlock */ /* holding details about the window */ /* that the coordinate is to be */ /* transformed to lie in. */ /* */ /* Returns: The given value converted to */ /* a work area coordinate. */ /*************************************************/ int coords_x_toworkarea(int x, WimpRedrawWindowBlock * r) { return (x + r->xscroll - r->visible_area.xmin); } /*************************************************/ /* coords_y_toworkarea() */ /* */ /* Converts a screen Y coordinate to a work area */ /* coordinate. */ /* */ /* Parameters: The screen Y coordiante; */ /* */ /* Pointer to WimpRedrawWindowBlock */ /* holding details about the window */ /* that the coordinate is to be */ /* transformed to lie in. */ /* */ /* Returns: The given value converted to */ /* a work area coordinate. */ /*************************************************/ int coords_y_toworkarea(int y, WimpRedrawWindowBlock * r) { return (y + r->yscroll - r->visible_area.ymax); } /*************************************************/ /* coords_box_toworkarea() */ /* */ /* Converts the contents of a BBox representing */ /* a rectangle in screen coords to hold work */ /* area coordinates. */ /* */ /* Parameters: Pointer to the BBox; */ /* */ /* Pointer to WimpRedrawWindowBlock */ /* holding details about the window */ /* that the BBox coordinates are to */ /* be transformed to lie in. */ /* */ /* Returns: The contents of the BBox are */ /* updated to hold work area */ /* coordinates. */ /*************************************************/ void coords_box_toworkarea(BBox * b, WimpRedrawWindowBlock * r) { b->xmax = coords_x_toworkarea(b->xmax, r); b->xmin = coords_x_toworkarea(b->xmin, r); b->ymin = coords_y_toworkarea(b->ymin, r); b->ymax = coords_y_toworkarea(b->ymax, r); }