#include #include #include #include #include #include "window.h" #include "_window.h" windowtype *windowchain = NULL; static unsigned int xpos, ypos; enum {TopLine, BottomLine, TopLeft, TopRight, BotLeft, BotRight, RightLine, LeftLine } _box; static unsigned char style[][8] = { { '-', '-', '+' , '+' , '+' , '+' , '|', '|' }, { '\xC4', '\xC4', '\xDA', '\xBF', '\xC0', '\xD9', '\xB3', '\xB3' }, { '\xCD', '\xCD', '\xC9', '\xBB', '\xC8', '\xBC', '\xBA', '\xBA' }, { '\xC4', '\xCD', '\xDA', '\xB7', '\xD4', '\xBC', '\xB3', '\xBA' } }; extern enum windowerrtype windowerr = WE_OK; /* box() -------------------------------------------------------- * Routine to draw a box around a window. * -------------------------------------------------------------- */ static void box( unsigned char left, unsigned char top, unsigned char right, unsigned char bottom, char pattr, unsigned char *boxchars) { unsigned int tmp1, tmp2, attr = pattr << 8; int width, size, i; unsigned int *box; if ( (box = malloc( (size = (right-left+1)*(bottom-top+1))*2 )) == NULL ) return; box[0] = ' ' | attr; /* Ripple move the space with current attribute to the entire block */ /* This routine depends on memcpy not copying overlapping blocks * correctly in the forward direction and two bytes at a time. */ memcpy(&box[1],box,size<<1); /* Top line */ box[0] = boxchars[TopLeft] | attr; box[ ((width = right - left + 1) - 1) ] = boxchars[TopRight] | attr; box[1] = boxchars[TopLine] | attr; /* Ripple move - see above */ memcpy(&box[2],&box[1],(width-3)<<1); tmp1 = boxchars[LeftLine] | attr; tmp2 = boxchars[RightLine] | attr; for (i = width; i 24 || left < 2 || right > 79 || top > bottom || left > right) { windowerr = WE_BADC; return NULL; } /* Allocate the memory for the window */ if ( (current = malloc(sizeof(windowtype))) == NULL ) { windowerr = WE_OMEM; return NULL; } /* Store the coorinates (including the border) */ current->top = --top; current->bottom = ++bottom; current->left = --left; current->right = ++right; /* Calculate the size of the back-buffer */ current->size = size = ((bottom-top+1)*(right-left+1)) << 1; /* Allocate the memory for the back buffer */ if ( (current->backbuffer = malloc(size)) == NULL ) { windowerr = WE_OMEM; return NULL; } /* Store the cursor position for the current window */ if (windowchain) { windowchain->xpos = wherex(); windowchain->ypos = wherey(); } else { xpos = wherex(); ypos = wherey(); } /* Store the screen image that we are going to write over */ gettext(left,top,right,bottom,current->backbuffer); /* Draw the border */ window(1,1,80,25); box(left,top,right,bottom,attr,style[the_style]); /* Set the writting attribute */ textattr(attr); current->attr = attr; /* Center the title on the border */ /* If the title is too big for the border or it * is empty, don't write it */ if ( (len = strlen(title)) <= (right - left) || len == 0 ) { gotoxy( (right + left - len + 1) >> 1, top); cputs(title); } /* Section of the screen for the window */ window(left+1,top+1,right-1,bottom-1); /* Register the window in the window chain, it becomes current */ if (windowchain != NULL) windowchain->previous = current; current->next = windowchain; current->previous = NULL; windowchain = current; /* Return the window */ return current; } /* deletewindow() ---------------------------------------------- * Delete a window. * RETURN: 0 Success, -1 Failure. * ------------------------------------------------------------- */ int deletewindow(windowtype *current) { if (windowchain != current) return -1; invalidate_backimage(); puttext(current->left,current->top,current->right,current->bottom, current->backbuffer); windowchain = current->next; free(current->backbuffer); free(current); if (windowchain != NULL) windowchain->previous = NULL; if (windowchain) { window(windowchain->left+1,windowchain->top+1,windowchain->right-1, windowchain->bottom-1); gotoxy(windowchain->xpos, windowchain->ypos); } else { window(1,1,80,25); gotoxy(xpos,ypos); } return 0; }