📄 init.c
字号:
// $Id: init.c,v 1.5 2000/11/27 09:09:11 ymwei Exp $//// init.c: The Initialization/Termination routines//// Copyright (C) 1999, 2000, Wei Yongming.//// Current maintainer: Wei Yongming.//// Create date: 2000/11/05/*** This library is free software; you can redistribute it and/or** modify it under the terms of the GNU Library 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** Library General Public License for more details.**** You should have received a copy of the GNU Library 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*///// Modify records://// Who When Where For What Status//-----------------------------------------------------------------------------//// TODO://#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <semaphore.h>#ifndef __ECOS# include <sys/termios.h>#else# include <cyg/kernel/kapi.h>#endif#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "cliprect.h"#include "gal.h"#include "internals.h"#include "ctrlclass.h"#include "cursor.h"#include "event.h"#include "misc.h"#include "menu.h"#include "timer.h"#include "accelkey.h"#ifndef lintstatic char fileid[] = "$Id: init.c,v 1.5 2000/11/27 09:09:11 ymwei Exp $";#endif/******************************* extern data *********************************/char desktop_thread_stack[PTHREAD_STACK_MIN*8];char parsor_thread_stack[PTHREAD_STACK_MIN*8];char timer_thread_stack[PTHREAD_STACK_MIN*8];extern pthread_t desktop, parsor, timer;extern MSGQUEUE DskMsgs;extern void* DesktopMain (void* data);/************************* Entry of the thread of parsor *********************/static BOOL QueueMessage (PMSG msg){ int sem_value; pthread_mutex_lock (&DskMsgs.lock); if ((DskMsgs.writepos + 1) % DskMsgs.len == DskMsgs.readpos) { pthread_mutex_unlock (&DskMsgs.lock); return FALSE; } // Write the data and advance write pointer */ DskMsgs.msg [DskMsgs.writepos] = *msg; DskMsgs.writepos++; if (DskMsgs.writepos >= DskMsgs.len) DskMsgs.writepos = 0; DskMsgs.dwState |= QS_POSTMSG; pthread_mutex_unlock (&DskMsgs.lock); // Signal that the msg queue contains one more element for reading sem_getvalue (&DskMsgs.wait, &sem_value); if (sem_value == 0) sem_post (&DskMsgs.wait); return TRUE;}static void* ParseEvent (void* data){ LWEVENT lwe; PMOUSEEVENT me; PKEYEVENT ke; MSG Msg; static int mouse_x = 0, mouse_y = 0;#ifdef __ECOS cyg_tick_count_t nowtime;#endif ke = &(lwe.data.ke); me = &(lwe.data.me); me->x = 0; me->y = 0; Msg.hwnd = HWND_DESKTOP; Msg.wParam = 0; Msg.lParam = 0; sem_post ((sem_t*)data); while (TRUE) { lwe.status = 0L; if (!GetLWEvent(TRUE, &lwe)) continue; Msg.pt.x = me->x; Msg.pt.y = me->y;#ifdef __ECOS nowtime=cyg_current_time(); Msg.time.tv_sec = nowtime/100; Msg.time.tv_usec = (nowtime%100)*10000; // sys tick is 10ms #else gettimeofday(&Msg.time, NULL);#endif if (lwe.type == LWETYPE_TIMEOUT) { Msg.message = MSG_TIMEOUT; Msg.wParam = (WPARAM)lwe.count; Msg.lParam = 0; QueueMessage (&Msg); } else if (lwe.type == LWETYPE_KEY) { Msg.wParam = ke->scancode; Msg.lParam = ke->status; if(ke->event == KE_KEYDOWN){ Msg.message = MSG_KEYDOWN; } else if(ke->event == KE_KEYUP) { Msg.message = MSG_KEYUP; } QueueMessage (&Msg); } else if(lwe.type == LWETYPE_MOUSE) { Msg.wParam = me->status; Msg.lParam = MAKELONG (me->x, me->y); switch (me->event) { case ME_MOVED: Msg.message = MSG_MOUSEMOVE; break; case ME_LEFTDOWN: Msg.message = MSG_LBUTTONDOWN; break; case ME_LEFTUP: Msg.message = MSG_LBUTTONUP; break; case ME_LEFTDBLCLICK: Msg.message = MSG_LBUTTONDBLCLK; break; case ME_RIGHTDOWN: Msg.message = MSG_RBUTTONDOWN; break; case ME_RIGHTUP: Msg.message = MSG_RBUTTONUP; break; case ME_RIGHTDBLCLICK: Msg.message = MSG_RBUTTONDBLCLK; break; } if (me->event != ME_MOVED && (mouse_x != me->x || mouse_y != me->y)) { int old = Msg.message; Msg.message = MSG_MOUSEMOVE; QueueMessage (&Msg); Msg.message = old; mouse_x = me->x; mouse_y = me->y; } QueueMessage (&Msg); } } return NULL;}/************************* Entry of the thread of timer **********************/static void* TimerEntry (void* data){ if (!InitTimer ()) { fprintf (stderr, "TIMER: Init Timer failure!\n"); TerminateLWEvent(); TerminateGDI(); exit (-1); return NULL; } sem_post ((sem_t*)data); pthread_join (desktop, NULL); TerminateTimer(); return NULL;}/************************** System Initialization ****************************/static BOOL SystemThreads(void){ sem_t wait; pthread_attr_t attr; pthread_attr_init( &attr ); if (!InitDesktop ()) { fprintf (stderr, "DESKTOP: Init Desktop error!\n"); return FALSE; } if (!InitFreeQMSGList ()) { TerminateDesktop (); fprintf (stderr, "DESKTOP: Init free QMSG list error!\n"); return FALSE; } if (!InitMsgQueue(&DskMsgs, 0)) { TerminateDesktop (); DestroyFreeQMSGList (); fprintf (stderr, "DESKTOP: Init MSG queue error!\n"); return FALSE; } sem_init (&wait, 0, 0); // this is the thread for desktop window. // this thread should have a normal priority same as // other main window threads. // if there is no main window can receive the low level events, // this desktop window is the only one can receive the events. // to close a MiniGUI application, we should close the desktop // window. pthread_attr_setstackaddr( &attr, (void *)&desktop_thread_stack[sizeof(desktop_thread_stack)] ); pthread_attr_setstacksize( &attr, sizeof(desktop_thread_stack) ); pthread_create(&desktop, &attr, DesktopMain, &wait); sem_wait (&wait); // this is the thread of timer. // when this thread start, it init timer data and install // a signal handler of SIGPROF, and call setitimer system call // to install an interval timer. // after initialization, this thread wait desktop to terminate, // and then remove the interval timer and free data structs. // the signal handler will alert desktop a MSG_TIMER message. pthread_attr_setstackaddr( &attr, (void *)&timer_thread_stack[sizeof(timer_thread_stack)] ); pthread_attr_setstacksize( &attr, sizeof(timer_thread_stack) ); pthread_create(&timer, &attr, TimerEntry, &wait); sem_wait (&wait); // this thread collect low level event from SVGALib, // if there is no event, this thread will suspend to wait a event. // the events maybe mouse event, keyboard event, or timeout event. // // this thread also parse low level event and translate it to message, // then post the message to the approriate message queue. // this thread should also have a higher priority. // this thread also translate SVGALib events to MiniGUI message, // for example, it translate mouse button event to mouse button // down and mouse button up, as well as mouse double click event. // this thread works as a mouse and keyboard driver. pthread_attr_setstackaddr( &attr, (void *)&parsor_thread_stack[sizeof(parsor_thread_stack)] ); pthread_attr_setstacksize( &attr, sizeof(parsor_thread_stack) ); pthread_create(&parsor, &attr, ParseEvent, &wait); sem_wait (&wait); sem_destroy (&wait); return TRUE;}BOOL GUIAPI ReinitDesktop (void){ return SendMessage (HWND_DESKTOP, MSG_REINITSESSION, 0, 0) == 0;}#ifndef __ECOSstatic struct termios savedtermio;#endifvoid* GUIAPI GetOriginalTermIO (void){#ifndef __ECOS return &savedtermio;#else return NULL; #endif}BOOL GUIAPI InitGUI(void){ // Save original termio#ifndef __ECOS tcgetattr (0, &savedtermio);#endif // Init miscelleous if (!InitMisc ()) { fprintf (stderr, "DESKTOP: Initialization of misc things failure!\n"); return FALSE; } // Init GDI. if(!InitGDI()) { fprintf (stderr, "DESKTOP: Initialization of GDI failure!\n"); return FALSE; } // Init low level event if(!InitLWEvent()) { fprintf(stderr, "DESKTOP: Low level event initialization failure!\n"); TerminateGDI (); TerminateMisc ();#ifndef __ECOS tcsetattr (0, TCSAFLUSH, &savedtermio);#endif return FALSE; } if (!InitFixStr ()) { fprintf (stderr, "DESKTOP: Init Fixed String module failure!\n"); goto failure; } // Init mouse cursor. if( !InitCursor() ) { fprintf (stderr, "DESKTOP: Count not initialize mouse cursor support!\n"); goto failure; } if (!InitMenu ()) { fprintf (stderr, "DESKTOP: Init Menu module failure!\n"); goto failure; } // Init control class if(!InitControlClass()) { fprintf(stderr, "DESKTOP: Init Control Class failure!\n"); goto failure; } // Init accelerator if(!InitAccel()) { fprintf(stderr, "DESKTOP: Init Accelerator failure!\n"); goto failure; } SetCursor (GetDefaultCursor()); if (SystemThreads()) return TRUE;failure: TerminateLWEvent(); TerminateGDI(); TerminateMisc ();#ifndef __ECOS tcsetattr (0, TCSAFLUSH, &savedtermio);#endif return FALSE;}void GUIAPI TerminateGUI (int rcByGUI){ if (rcByGUI >= 0) { pthread_join (timer, NULL); } else {#ifndef __ECOS pthread_kill_other_threads_np ();#endif TerminateTimer (); } TerminateDesktop (); DestroyMsgQueue (&DskMsgs); DestroyFreeQMSGList (); TerminateAccel (); TerminateControlClass(); TerminateCursor(); TerminateMenu(); TerminateFixStr(); TerminateLWEvent(); TerminateGDI(); TerminateMisc (); // Restore original termio#ifndef __ECOS tcsetattr (0, TCSAFLUSH, &savedtermio);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -