/***************************************************************************
 * Copyright 1995, Technion, Israel Institute of Technology
 * Electrical Eng, Software Lab.
 * Author:    Michael Veksler.
 ***************************************************************************
 * File:      dde_proc.c
 * Purpose :  DDE signals and processes functionality for DDE
 ***************************************************************************
 */
#ifdef CONFIG_IPC

#if defined(__FreeBSD__) || defined(__NetBSD__)
#define msgbuf mymsg
#endif

#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/msg.h>
#include "wintypes.h"
#include "win.h"
#include "shm_semaph.h"
#include "shm_main_blk.h"
#include "dde_proc.h"
#include "dde_mem.h"
#include "dde.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"

int curr_proc_idx= -1;

enum stop_wait_op stop_wait_op=CONT;
int had_SIGUSR2 = 0;
sigjmp_buf env_get_ack;
sigjmp_buf env_wait_x;

#define IDX_TO_HWND(idx)  (0xfffe - (idx))
#define HWND_TO_IDX(wnd)  (0xfffe - (wnd))
#define DDE_WIN_INFO(win) ( main_block->windows[HWND_TO_IDX(win)] )
#define DDE_WIN2PROC(win) ( DDE_WIN_INFO(win).proc_idx )
#define DDE_IsRemoteWindow(win)	 (  (win)<0xffff && (win)>=(0xffff-DDE_PROCS))
#define DDE_SEND 1
#define DDE_POST 2
#define DDE_ACK	 3
#define DDE_MSG_SIZE   sizeof(MSG)
#define FREE_WND (WORD)(-2)
#define DELETED_WND (WORD)(-3)
#if defined(DEBUG_MSG) || defined(DEBUG_RUNTIME)
static char *msg_type[4]={"********", "DDE_SEND", "DDE_POST", "DDE_ACK"};
#endif

struct msg_dat {
	struct msgbuf dat;
	char filler[DDE_MSG_SIZE];
} ;

typedef struct fifo_element {
	int value;
	struct fifo_element *next;
} fifo_element;

struct fifo {
	fifo_element *first;	   /* first element in the fifo or NULL */
	fifo_element *last;	   /* last element in the fifo or NULL */
};
static struct fifo fifo = {NULL,NULL};

void dde_proc_delete(int proc_idx);

void dde_proc_add_fifo(int val)
{
  fifo_element *created;

  created= (fifo_element*) xmalloc( sizeof(fifo_element) );
  created->value = val;
  created->next = NULL;
  
  if (fifo.first==NULL) 
     fifo.first= created;
  else 
     fifo.last->next= created;
  fifo.last = created;
}

/* get an item from the fifo, and return it.
 * If fifo is empty, return -1
 */
int dde_proc_shift_fifo()
{
  int val;
  fifo_element *deleted;
  
  if (fifo.first == NULL)
     return -1;
  
  deleted= fifo.first;
  val= deleted->value;
  fifo.first= deleted->next;
  if (fifo.first == NULL)
     fifo.last= NULL;

  free(deleted);
  return val;
}

static void print_dde_message(char *desc, MSG *msg);

/* This should be run only when main_block is first allocated.	*/
void dde_proc_init(dde_proc proc)
{
  int proc_num;

  for (proc_num=0 ; proc_num<DDE_PROCS ; proc_num++, proc++) {
     proc->msg=-1;
     proc->sem=-1;
     proc->shmid=-1;
     proc->pid=-1;
  }
}

/* add current process to the list of processes */
void dde_proc_add(dde_proc procs)
{
  dde_proc proc;
  int proc_idx;
  dprintf_dde(stddeb,"dde_proc_add(..)\n");
  shm_write_wait(main_block->sem);

  /* find free proc_idx and allocate it */
  for (proc_idx=0, proc=procs ; proc_idx<DDE_PROCS ; proc_idx++, proc++)
     if (proc->pid==-1)
	break;			   /* found! */

  if (proc_idx<DDE_PROCS) {	   /* got here beacuse a free was found ? */
     dde_msg_setup(&proc->msg);
     proc->pid=getpid();
     curr_proc_idx=proc_idx;
     shm_sem_init(&proc->sem);
  }
  else	{
     fflush(stdout);
     fprintf(stderr,"dde_proc_add: Can't allocate process\n");
  }
  shm_write_signal(main_block->sem);
}

/* wait for dde - acknowledge message - or timout */
static BOOL get_ack()
{
    struct timeval timeout;
    int size;
    struct msg_dat ack_buff;

    /* timeout after exactly one seconf */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    sigsetjmp(env_get_ack, 1);
    /* get here after normal execution, or after siglongjmp */

    do {			   /* loop to wait for DDE_ACK */
       had_SIGUSR2=0;
       stop_wait_op=CONT;	   /*  sensitive code: disallow siglongjmp */
       size= msgrcv( main_block->proc[curr_proc_idx].msg , &ack_buff.dat,
		     1, DDE_ACK, IPC_NOWAIT);
       if (size>=0) {
	  dprintf_msg(stddeb,"get_ack: received DDE_ACK message\n");
	  return TRUE;
       }
       if (DDE_GetRemoteMessage()) {
	     had_SIGUSR2=1;  /* might have recieved SIGUSR2 */
       }
       stop_wait_op=STOP_WAIT_ACK; /* allow siglongjmp */

    } while (had_SIGUSR2);	   /* loop if SIGUSR2 was recieved */

    /* siglongjmp should be enabled at this moment */
    select( 0, NULL, NULL, NULL, &timeout );
    stop_wait_op=CONT;		   /* disallow further siglongjmp */

    /* timeout !! (otherwise there would have been a siglongjmp) */
    return FALSE;
}

/* Transfer one message to a given process */
static BOOL DDE_DoOneMessage (int proc_idx, int size, struct msgbuf *msgbuf)
{
  dde_proc proc= &main_block->proc[ proc_idx ];


  if (proc_idx == curr_proc_idx)
     return FALSE;

  if (kill(proc->pid,0) < 0) {
     /* pid does not exist, or not our */
     dde_proc_delete(proc_idx);
     return FALSE;
  }

  if (debugging_dde) {
     MSG *msg=(MSG*) &msgbuf->mtext;
     char *title;
     if (msgbuf->mtype==DDE_SEND)
	title="sending dde:";
     else if (msgbuf->mtype==DDE_POST)
	title="posting dde:";
     else
	title=NULL;
     if (title)
	 print_dde_message(title, msg);
     else
       fprintf(stddeb,"Unknown message type=0x%lx\n",msgbuf->mtype);
  }
  dprintf_msg(stddeb,
	      "DDE_DoOneMessage: to proc_idx=%d (pid=%d), queue=%u\n",
	      proc_idx, proc->pid, (unsigned)proc->msg);
  if ( proc->msg != -1) {
     dprintf_msg(stddeb, "DDE_DoOneMessage: doing...(type=%s)\n",
		 msg_type[msgbuf->mtype]);
     size=msgsnd (proc->msg, msgbuf, size, 0);

     if (size<0) {
	 fflush(stdout);
	 perror("msgsnd");
     }
     kill(proc->pid,SIGUSR2);	   /* tell the process there is a message */

     dprintf_msg(stddeb,"DDE_DoOneMessage: "
		 "Trying to get acknowledgment from msg queue=%d\n",
		 proc->msg);
     Yield();			/* force task switch, and */
				/* acknowledgment sending */
     if (get_ack()) {
	return TRUE;
     } else {
	fflush(stdout);
	fprintf(stderr,"get_ack: DDE_DoOneMessage: timeout\n");
	return FALSE;
     }
  }
  else {
     dprintf_msg(stddeb,"DDE_DoOneMessage: message not sent, "
		 "target has no message queue\n");
     return FALSE;
  }
}

/* Do some sort of premitive hash table */
static HWND HWND_Local2Remote(HWND orig)
{
  int dde_wnd_idx;
  int deleted_idx= -1;
  WND_DATA *tested;
  WND_DATA *deleted= NULL;
  int i;
  
  dde_wnd_idx= orig % DDE_WINDOWS;
  for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
    if (dde_wnd_idx >= DDE_WINDOWS)
      dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
    
    tested= &main_block->windows[ dde_wnd_idx ];
    if (tested->proc_idx == FREE_WND)
      break;
    
    if (deleted == NULL && tested->proc_idx == DELETED_WND) {
      deleted= tested;
      deleted_idx= dde_wnd_idx;
    } else if (tested->wnd == orig && tested->proc_idx == curr_proc_idx) {
      return IDX_TO_HWND(dde_wnd_idx);
    }
  }
  if (deleted != NULL)	{	/* deleted is preferable */
    /* free item, allocate it */
    deleted->proc_idx= curr_proc_idx;
    deleted->wnd = orig;
    return IDX_TO_HWND(deleted_idx);
  }
  if (tested->proc_idx == FREE_WND) {
    tested->proc_idx= curr_proc_idx;
    tested->wnd = orig;
    return IDX_TO_HWND(dde_wnd_idx);
  }

  fprintf(stderr,
	  "HWND_Local2Remote: Can't map any more windows to DDE windows\n");
  return 0;			
}

static BOOL DDE_DoMessage( MSG *msg, int type )
{
  int proc_idx;

  MSG *remote_message;
  struct msg_dat msg_dat;
  BOOL success;
  
  if (msg->wParam == 0)
      return FALSE;
  
  if (main_block==NULL) {
    if (msg->message >=  WM_DDE_FIRST && msg->message <= WM_DDE_LAST) 
      DDE_IPC_init();
    else 
      return FALSE;
  }


  if (msg->wParam == (HWND)-1)
     return FALSE;

  if ( ! DDE_IsRemoteWindow(msg->hwnd) && msg->hwnd!= (HWND)-1)
     return FALSE;

  dprintf_msg(stddeb, "%s: DDE_DoMessage(hwnd=0x%x,msg=0x%x,..)\n",
	      msg_type[type], (int)msg->hwnd,(int)msg->message);


  dprintf_msg(stddeb,
	      "DDE_DoMessage(hwnd=0x%x,msg=0x%x,..) // HWND_BROADCAST !\n",
	      (int)msg->hwnd,(int)msg->message);
  remote_message=(void*)&msg_dat.dat.mtext;
  
  memcpy(remote_message, msg, sizeof(*msg));
  remote_message->wParam= HWND_Local2Remote(msg->wParam);
  if (remote_message->wParam == 0)
    return FALSE;
  
  msg_dat.dat.mtype=type;

  if (msg->hwnd == (HWND)-1) {
     success= FALSE;
     for ( proc_idx=0; proc_idx < DDE_PROCS ; proc_idx++) {
	if (proc_idx == curr_proc_idx)
	   continue;
	if (main_block->proc[ proc_idx ].msg != -1)
	   success|=DDE_DoOneMessage(proc_idx, DDE_MSG_SIZE, &msg_dat.dat);
     }
     return success;
  } else {
     return DDE_DoOneMessage(DDE_WIN2PROC(msg->hwnd), DDE_MSG_SIZE,
			     &msg_dat.dat);
  }
}

BOOL DDE_SendMessage( MSG *msg)
{
  return DDE_DoMessage(msg, DDE_SEND);
}

BOOL DDE_PostMessage( MSG *msg)
{
  return DDE_DoMessage(msg, DDE_POST);
}


void dde_proc_send_ack(HWND wnd, BOOL val) {
   int proc,msg;

   static struct msgbuf msg_ack={DDE_ACK,{'0'}};

   proc=DDE_WIN2PROC(wnd);
   msg=main_block->proc[proc].msg;
   dprintf_msg(stddeb,"DDE_GetRemoteMessage: sending ACK "
	       "to wnd=%4x, proc=%d,msg=%d, pid=%d\n",wnd,proc,msg,
	       main_block->proc[proc].pid
     );

   msg_ack.mtext[0]=val;
   msgsnd (msg, &msg_ack, 1, 0);
   kill(main_block->proc[proc].pid, SIGUSR2);
}

/* return true (non zero) if had a remote message */
#undef DDE_GetRemoteMessage

int DDE_GetRemoteMessage()
{
  static int nesting=0;		   /* to avoid infinite recursion */

  MSG *remote_message;
  int size;
  struct msg_dat msg_dat;
  BOOL was_sent;		   /* sent/received */
  BOOL passed;
  WND *wndPtr;

  if (curr_proc_idx==-1)	   /* do we have DDE initialized ? */
     return 0;

  if (nesting>10) {
     fflush(stdout);
     fprintf(stderr,"DDE_GetRemoteMessage: suspecting infinite recursion, exiting");
     return 0;
  }

  remote_message=(void*)&msg_dat.dat.mtext;

  /* test for SendMessage */
  size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
		DDE_MSG_SIZE, DDE_SEND, IPC_NOWAIT);

  if (size==DDE_MSG_SIZE) {	   /* is this a correct message (if any) ?*/
     was_sent=TRUE;
     dprintf_msg(stddeb,
		 "DDE:receive sent message. msg=%04x wPar=%04x"
		 " lPar=%08lx\n",
		 remote_message->message, remote_message->wParam,
		 remote_message->lParam);
  } else {
     size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
		   DDE_MSG_SIZE, DDE_POST, IPC_NOWAIT);

     if (size==DDE_MSG_SIZE) {	   /* is this a correct message (if any) ?*/
	was_sent=FALSE;
	dprintf_msg(stddeb,
		    "DDE:receive posted message. "
		    "msg=%04x wPar=%04x lPar=%08lx\n",
		    remote_message->message, remote_message->wParam,
		    remote_message->lParam);
     }
     else
	return 0;		   /* no DDE message found */
  }

  /* At this point we are sure that there is a DDE message,
   * was_sent is TRUE is the message was sent, and false if it was posted
   */

  nesting++;

  if (debugging_dde) {
     char *title;
     if (was_sent)
	title="receive sent dde:";
     else
	title="receive posted dde:";
     print_dde_message(title, remote_message);
  }

  if (remote_message->hwnd != (HWND) -1 ) {
    HWND dde_window= DDE_WIN_INFO(remote_message->hwnd).wnd;
     /* we should know exactly where to send the message (locally)*/
     if (was_sent) {
	dprintf_dde(stddeb,
		    "SendMessage(wnd=0x%04x, msg=0x%04x, wPar=0x%04x,"
		    "lPar=0x%08x\n",
		    dde_window, remote_message->message,
		    remote_message->wParam, (int)remote_message->lParam);

	/* execute the recieved message */
	passed= SendMessage16(dde_window, remote_message->message,
			    remote_message->wParam, remote_message->lParam);

	/* Tell the sended, that the message is here */
	dde_proc_send_ack(remote_message->wParam, passed);
     }
     else {
	passed= PostMessage(dde_window, remote_message->message,
			    remote_message->wParam, remote_message->lParam);
	if (passed == FALSE) {
	   /* Tell the sender, that the message is here, and failed */
	    dde_proc_send_ack(remote_message->wParam, FALSE);
	}
	else {
	   /* ack will be sent later, at the first peek/get message  */
	   dde_proc_add_fifo(remote_message->wParam);
	}
     }
     nesting--;
     return 1;
  }

  /* iterate through all the windows */
  for (wndPtr = WIN_FindWndPtr(GetTopWindow(GetDesktopWindow()));
       wndPtr != NULL;
       wndPtr = wndPtr->next)
  {
     if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION) {
	if (was_sent)
	   SendMessage16( wndPtr->hwndSelf, remote_message->message,
			remote_message->wParam, remote_message->lParam );
	else
	   PostMessage( wndPtr->hwndSelf, remote_message->message,
                        remote_message->wParam, remote_message->lParam );
     } /* if */
  } /* for */

  /* replay with DDE_ACK after broadcasting in DDE_GetRemoteMessage */
  dde_proc_send_ack(remote_message->wParam, TRUE);

  nesting--;
  return 1;
}

int dde_reschedule()
{
    int ack_wnd;
	
    ack_wnd= dde_proc_shift_fifo();
    if (ack_wnd != -1) {
	dde_proc_send_ack(ack_wnd, TRUE);
	usleep(10000);		/* force unix task switch */
	return 1;
    }
    return 0;
}
void dde_msg_setup(int *msg_ptr)
{
  *msg_ptr= msgget (IPC_PRIVATE, IPC_CREAT | 0700);
  if (*msg_ptr==-1)
     perror("dde_msg_setup fails to get message queue");
}

/* do we have dde handling in the window ?
 * If we have, atom usage will make this instance of wine set up
 * it's IPC stuff.
 */
void DDE_TestDDE(HWND hwnd)	   
{

  if (main_block != NULL)
     return;
  dprintf_msg(stddeb,"DDE_TestDDE(0x%04x)\n", hwnd);
  if (hwnd==0)
      hwnd=-1;
  /* just send a message to see how things are going */
  SendMessage16( hwnd, WM_DDE_INITIATE, 0, 0);
}

void dde_proc_delete(int proc_idx)
{
  dde_proc_done(&main_block->proc[proc_idx]);
}
void stop_wait(int a)
{

  had_SIGUSR2=1;
  switch(stop_wait_op) {
    case STOP_WAIT_ACK:
      siglongjmp(env_get_ack,1);
      break;  /* never reached */
    case STOP_WAIT_X:
      siglongjmp(env_wait_x,1);
      break;  /* never reached */
    case CONT:
      /* do nothing */
  }
}

static void print_dde_message(char *desc, MSG *msg)
{
/*    extern const char *MessageTypeNames[];*/
    extern int debug_last_handle_size;
    WORD wStatus,hWord;
    void *ptr;
    DDEACK *ddeack;
    DDEADVISE *ddeadvise;
    DDEDATA *ddedata;
    DDEPOKE *ddepoke;

    if (is_dde_handle(msg->lParam & 0xffff) )
	ptr=DDE_AttachHandle(msg->lParam&0xffff, NULL);
    else
	ptr =NULL;
    wStatus=LOWORD(msg->lParam);
    hWord=HIWORD(msg->lParam);

    fprintf(stddeb,"%s", desc);
    fprintf(stddeb,"%04x %04x==%s %04x %08lx ",
	    msg->hwnd, msg->message,"",/*MessageTypeNames[msg->message],*/
	    msg->wParam, msg->lParam);
    switch(msg->message) {
      case WM_DDE_INITIATE:
      case WM_DDE_REQUEST:
      case WM_DDE_EXECUTE:
      case WM_DDE_TERMINATE:
	/* nothing to do */
	break;
      case WM_DDE_ADVISE:
	/* DDEADVISE: hOptions in WM_DDE_ADVISE message */
	if (ptr) {
	   ddeadvise=ptr;
	   fprintf(stddeb,"fDeferUpd=%d,fAckReq=%d,cfFormat=0x%x",
		   ddeadvise->fDeferUpd, ddeadvise->fAckReq,
		   ddeadvise->cfFormat);
	} else
	   fprintf(stddeb,"NO-DATA");
	fprintf(stddeb," atom=0x%x",hWord);
	break;

      case WM_DDE_UNADVISE:
	fprintf(stddeb,"format=0x%x, atom=0x%x",wStatus,hWord);
	break;
      case WM_DDE_ACK:
	ddeack=(DDEACK*)&wStatus;
	fprintf(stddeb,"bAppReturnCode=%d,fBusy=%d,fAck=%d",
		ddeack->bAppReturnCode, ddeack->fBusy, ddeack->fAck);
	if (ddeack->fAck)
	   fprintf(stddeb,"(True)");
	else
	   fprintf(stddeb,"(False)");
	break;

      case WM_DDE_DATA:
	if (ptr) {
	   ddedata=ptr;
	   fprintf(stddeb,"fResponse=%d,fRelease=%d,"
		   "fAckReq=%d,cfFormat=0x%x,value=\"%.*s\"",
		   ddedata->fResponse, ddedata->fRelease,
		   ddedata->fAckReq, ddedata->cfFormat,
		   debug_last_handle_size- (int)sizeof(*ddedata)+1,
		   ddedata->Value);
	} else
	   fprintf(stddeb,"NO-DATA");
	fprintf(stddeb," atom=0x%04x",hWord);
	break;

      case WM_DDE_POKE:
	if (ptr) {
	   ddepoke=ptr;
	   fprintf(stddeb,"fRelease=%d,cfFormat=0x%x,value[0]='%c'",
		   ddepoke->fRelease, ddepoke->cfFormat, ddepoke->Value[0]);
	} else
	   fprintf(stddeb,"NO-DATA");
	fprintf(stddeb," atom=0x%04x",hWord);
	break;
    }
    fprintf(stddeb,"\n");
}

void dde_proc_done(dde_proc proc)
{
  if (proc->msg != -1)
     msgctl(proc->msg, IPC_RMID, NULL);
  proc->msg=-1;
  proc->pid=-1;
  shm_delete_chain(&proc->shmid);
  shm_sem_done(&proc->sem);
}

/* delete entry, if old junk */
void dde_proc_refresh(dde_proc proc)
{
  if (proc->pid == -1)		  
     return;
  
  if (kill(proc->pid, 0) != -1)
     return;

  /* get here if entry non empty, and the process does not exist */
  dde_proc_done(proc);
}

void dde_wnd_setup()
{
  int i;

  for (i=0 ; i < DDE_WINDOWS ; i++)
    main_block->windows[i].proc_idx = FREE_WND;
}

static BOOL DDE_ProcHasWindows(int proc_idx)
{
  WND_DATA *tested;
  int i;
  
  for ( i=0 ; i < DDE_WINDOWS ; i++) {
    tested= &main_block->windows[ i ];
    
    if (tested->proc_idx == proc_idx) 
      return TRUE;
  }
  return FALSE;
}
/* Look for hwnd in the hash table of DDE windows,
 * Delete it from there. If there are no more windows for this
 * process, remove the process from the DDE data-structure.
 * If there are no more processes - delete the whole DDE struff.
 *
 * This is inefficient, but who cares for the efficiency of this rare
 * operation... 
 */
void DDE_DestroyWindow(HWND hwnd)
{
  int dde_wnd_idx;
  WND_DATA *tested;
  int i;
  
  if (main_block == NULL)
    return;
  
  dde_wnd_idx= hwnd % DDE_WINDOWS;
  
  for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
    if (dde_wnd_idx >= DDE_WINDOWS)
      dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
    
    tested= &main_block->windows[ dde_wnd_idx ];
    if (tested->proc_idx == FREE_WND)
      return;			/* No window will get deleted here */
    
    if (tested->wnd == hwnd && tested->proc_idx == curr_proc_idx) {
      dde_reschedule();
      tested->proc_idx= DELETED_WND;
      if (DDE_ProcHasWindows( curr_proc_idx ))
	return;
      while (dde_reschedule())	/* make sure there are no other */
				/* processes waiting for acknowledgment */
	;
      dde_proc_delete( curr_proc_idx );
      if (DDE_no_of_attached() == 1)
	shm_delete_all(-1);
      else {
	shmdt( (void *) main_block);
	main_block= NULL;
      }
      return;
    }
  }
}

#endif  /* CONFIG_IPC */
